View | Details | Raw Unified | Return to bug 92398 | Differences between
and this patch

Collapse All | Expand All

(-)batch/org/eclipse/jdt/internal/compiler/batch/ClasspathDirectory.java (-10 / +35 lines)
Lines 14-19 Link Here
14
import java.util.Hashtable;
14
import java.util.Hashtable;
15
15
16
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
16
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
17
import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
18
import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
17
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
19
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
18
import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
20
import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
19
21
Lines 24-46 Link Here
24
String[] missingPackageHolder = new String[1];
26
String[] missingPackageHolder = new String[1];
25
String encoding;
27
String encoding;
26
public int mode; // ability to only consider one kind of files (source vs. binaries), by default use both
28
public int mode; // ability to only consider one kind of files (source vs. binaries), by default use both
29
AccessRuleSet accessRuleSet;
27
30
28
public static final int SOURCE = 1;
31
public static final int SOURCE = 1;
29
public static final int BINARY = 2;
32
public static final int BINARY = 2;
30
33
31
ClasspathDirectory(File directory, String encoding, int mode) {
34
ClasspathDirectory(File directory, String encoding, int mode, AccessRuleSet accessRuleSet) {
32
	this.mode = mode;
35
	if (mode == 0){
36
		this.mode = SOURCE | BINARY;
37
	}
38
	else {
39
	    this.mode = mode;
40
	}
33
	this.path = directory.getAbsolutePath();
41
	this.path = directory.getAbsolutePath();
34
	if (!this.path.endsWith(File.separator))
42
	if (!this.path.endsWith(File.separator))
35
		this.path += File.separator;
43
		this.path += File.separator;
36
	this.directoryCache = new Hashtable(11);
44
	this.directoryCache = new Hashtable(11);
37
	this.encoding = encoding;
45
	this.encoding = encoding;
46
	this.accessRuleSet = accessRuleSet;
38
}
47
}
39
48
40
ClasspathDirectory(File directory, String encoding) {
49
ClasspathDirectory(File directory, String encoding) {
41
	this(directory, encoding, SOURCE | BINARY); // by default consider both sources and binaries
50
	this(directory, encoding, SOURCE | BINARY, null); // by default consider both sources and binaries
51
}
52
// TODO factorize common parts of ClasspathJar and ClasspathDirectory
53
AccessRestriction fetchAccessRestriction(String qualifiedBinaryFileName){
54
	if (this.accessRuleSet == null)
55
		return null;
56
	return this.accessRuleSet.getViolatedRestriction((qualifiedBinaryFileName.substring(0, 
57
			qualifiedBinaryFileName.length() - 6) + SUFFIX_STRING_java).toCharArray());
42
}
58
}
43
44
String[] directoryList(String qualifiedPackageName) {
59
String[] directoryList(String qualifiedPackageName) {
45
	String[] dirList = (String[]) this.directoryCache.get(qualifiedPackageName);
60
	String[] dirList = (String[]) this.directoryCache.get(qualifiedPackageName);
46
	if (dirList == this.missingPackageHolder) return null; // package exists in another classpath directory or jar
61
	if (dirList == this.missingPackageHolder) return null; // package exists in another classpath directory or jar
Lines 90-108 Link Here
90
	if (sourceExists) {
105
	if (sourceExists) {
91
		String fullSourcePath = this.path + qualifiedBinaryFileName.substring(0, qualifiedBinaryFileName.length() - 6)  + SUFFIX_STRING_java;
106
		String fullSourcePath = this.path + qualifiedBinaryFileName.substring(0, qualifiedBinaryFileName.length() - 6)  + SUFFIX_STRING_java;
92
		if (!binaryExists)
107
		if (!binaryExists)
93
			return new NameEnvironmentAnswer(new CompilationUnit(null, fullSourcePath, this.encoding), null/* TODO no access restriction*/);
108
			return new NameEnvironmentAnswer(new CompilationUnit(null,
94
109
					fullSourcePath, this.encoding),
110
					fetchAccessRestriction(qualifiedBinaryFileName));
95
		String fullBinaryPath = this.path + qualifiedBinaryFileName;
111
		String fullBinaryPath = this.path + qualifiedBinaryFileName;
96
		long binaryModified = new File(fullBinaryPath).lastModified();
112
		long binaryModified = new File(fullBinaryPath).lastModified();
97
		long sourceModified = new File(fullSourcePath).lastModified();
113
		long sourceModified = new File(fullSourcePath).lastModified();
98
		if (sourceModified > binaryModified)
114
		if (sourceModified > binaryModified)
99
			return new NameEnvironmentAnswer(new CompilationUnit(null, fullSourcePath, this.encoding), null/* TODO no access restriction*/);
115
			return new NameEnvironmentAnswer(new CompilationUnit(null,
116
					fullSourcePath, this.encoding),
117
					fetchAccessRestriction(qualifiedBinaryFileName));
100
	}
118
	}
101
	if (binaryExists) {
119
	if (binaryExists) {
102
		try {
120
		try {
103
			ClassFileReader reader = ClassFileReader.read(this.path + qualifiedBinaryFileName);
121
			ClassFileReader reader = ClassFileReader.read(this.path
104
			if (reader != null) return new NameEnvironmentAnswer(reader, null/* TODO no access restriction*/);
122
					+ qualifiedBinaryFileName);
105
		} catch (Exception e) { 
123
			if (reader != null)
124
				return new NameEnvironmentAnswer(
125
						reader,
126
						fetchAccessRestriction(qualifiedBinaryFileName));
127
		} catch (Exception e) {
106
			// treat as if file is missing
128
			// treat as if file is missing
107
		}
129
		}
108
	}
130
	}
Lines 117-120 Link Here
117
public String toString() {
139
public String toString() {
118
	return "ClasspathDirectory " + this.path; //$NON-NLS-1$
140
	return "ClasspathDirectory " + this.path; //$NON-NLS-1$
119
}
141
}
142
public String normalizedPath() {
143
	return this.path;
144
}
120
}
145
}
(-)batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJar.java (-5 / +22 lines)
Lines 18-46 Link Here
18
import java.util.zip.ZipFile;
18
import java.util.zip.ZipFile;
19
19
20
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
20
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
21
import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
22
import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
21
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
23
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
24
import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
22
25
23
public class ClasspathJar implements FileSystem.Classpath {
26
public class ClasspathJar implements FileSystem.Classpath, SuffixConstants {
24
	
27
	
25
ZipFile zipFile;
28
ZipFile zipFile;
26
Hashtable packageCache;
29
Hashtable packageCache;
27
boolean closeZipFileAtEnd;
30
boolean closeZipFileAtEnd;
31
AccessRuleSet accessRuleSet;
28
32
29
public ClasspathJar(File file) throws IOException {
33
public ClasspathJar(File file) throws IOException {
30
	this(new ZipFile(file), true);
34
	this(new ZipFile(file), true, null);
31
}
35
}
32
public ClasspathJar(ZipFile zipFile, boolean closeZipFileAtEnd) {
36
public ClasspathJar(ZipFile zipFile, boolean closeZipFileAtEnd, AccessRuleSet accessRuleSet) {
33
	this.zipFile = zipFile;
37
	this.zipFile = zipFile;
34
	this.packageCache = null;
38
	this.packageCache = null;
35
	this.closeZipFileAtEnd = closeZipFileAtEnd;
39
	this.closeZipFileAtEnd = closeZipFileAtEnd;
36
}	
40
	this.accessRuleSet = accessRuleSet;
41
}
42
// TODO factorize common parts of ClasspathJar and ClasspathDirectory
43
AccessRestriction fetchAccessRestriction(String qualifiedBinaryFileName){
44
	if (this.accessRuleSet == null)
45
		return null;
46
	return this.accessRuleSet.getViolatedRestriction((qualifiedBinaryFileName.substring(0, 
47
			qualifiedBinaryFileName.length() - 6) + SUFFIX_STRING_java).toCharArray());
48
}
37
public NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName) {
49
public NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName) {
38
	if (!isPackage(qualifiedPackageName)) 
50
	if (!isPackage(qualifiedPackageName)) 
39
		return null; // most common case
51
		return null; // most common case
40
52
41
	try {
53
	try {
42
		ClassFileReader reader = ClassFileReader.read(this.zipFile, qualifiedBinaryFileName);
54
		ClassFileReader reader = ClassFileReader.read(this.zipFile, qualifiedBinaryFileName);
43
		if (reader != null) return new NameEnvironmentAnswer(reader, null /*no access restriction*/);
55
		if (reader != null) return new NameEnvironmentAnswer(reader, 
56
				fetchAccessRestriction(qualifiedBinaryFileName));
44
	} catch (Exception e) {
57
	} catch (Exception e) {
45
		// treat as if class file is missing
58
		// treat as if class file is missing
46
	}
59
	}
Lines 82-85 Link Here
82
public String toString() {
95
public String toString() {
83
	return "Classpath for jar file " + this.zipFile.getName(); //$NON-NLS-1$
96
	return "Classpath for jar file " + this.zipFile.getName(); //$NON-NLS-1$
84
}
97
}
98
public String normalizedPath(){
99
	String rawName = this.zipFile.getName();
100
	return rawName.substring(0, rawName.lastIndexOf('.'));
101
}
85
}
102
}
(-)batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java (-32 / +54 lines)
Lines 15-20 Link Here
15
import java.util.zip.ZipFile;
15
import java.util.zip.ZipFile;
16
16
17
import org.eclipse.jdt.core.compiler.CharOperation;
17
import org.eclipse.jdt.core.compiler.CharOperation;
18
import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
18
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
19
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
19
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
20
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
20
import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
21
import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
Lines 31-36 Link Here
31
		 * a new name environment without creating a new object.
32
		 * a new name environment without creating a new object.
32
		 */
33
		 */
33
		void reset();
34
		void reset();
35
		/**
36
		 * Return a normalized path for file based classpath entries. This is an absolute path
37
		 * ending with a file separator for directories, an absolute path deprived from the '.jar'
38
		 * (resp. '.zip') extension for jar (resp. zip) files.
39
		 * @return a normalized path for file based classpath entries
40
		 */
41
		String normalizedPath();
34
	}
42
	}
35
/*
43
/*
36
	classPathNames is a collection is Strings representing the full path of each class path
44
	classPathNames is a collection is Strings representing the full path of each class path
Lines 40-89 Link Here
40
public FileSystem(String[] classpathNames, String[] initialFileNames, String encoding) {
48
public FileSystem(String[] classpathNames, String[] initialFileNames, String encoding) {
41
	this(classpathNames, initialFileNames, encoding, null);
49
	this(classpathNames, initialFileNames, encoding, null);
42
}
50
}
51
// WORK suppress in favor of the constructor that takes a classpath array
43
public FileSystem(String[] classpathNames, String[] initialFileNames, String encoding, int[] classpathDirectoryModes) {
52
public FileSystem(String[] classpathNames, String[] initialFileNames, String encoding, int[] classpathDirectoryModes) {
44
	int classpathSize = classpathNames.length;
53
	int classpathSize = classpathNames.length;
45
	this.classpaths = new Classpath[classpathSize];
54
	this.classpaths = new Classpath[classpathSize];
46
	String[] pathNames = new String[classpathSize];
47
	int problemsOccured = 0;
55
	int problemsOccured = 0;
48
	for (int i = 0; i < classpathSize; i++) {
56
	for (int i = 0; i < classpathSize; i++) {
49
		try {
57
		this.classpaths[i] = getClasspath(classpathNames[i], encoding,
50
			File file = new File(convertPathSeparators(classpathNames[i]));
58
					classpathDirectoryModes == null ? 0
51
			if (file.isDirectory()) {
59
							: classpathDirectoryModes[i], null);
52
				if (file.exists()) {
53
					if (classpathDirectoryModes == null){
54
						this.classpaths[i] = new ClasspathDirectory(file, encoding);
55
					} else {
56
						this.classpaths[i] = new ClasspathDirectory(file, encoding, classpathDirectoryModes[i]);
57
					}
58
					pathNames[i] = ((ClasspathDirectory) this.classpaths[i]).path;
59
				}
60
			} else {
61
				String lowercaseClasspathName = classpathNames[i].toLowerCase();
62
				if (lowercaseClasspathName.endsWith(SUFFIX_STRING_jar)
63
					  || lowercaseClasspathName.endsWith(SUFFIX_STRING_zip)) {
64
					this.classpaths[i] = this.getClasspathJar(file); // will throw an IOException if file does not exist
65
					pathNames[i] = classpathNames[i].substring(0, classpathNames[i].lastIndexOf('.'));
66
				}
67
			}
68
		} catch (IOException e) {
69
			this.classpaths[i] = null;
70
		}
71
		if (this.classpaths[i] == null)
60
		if (this.classpaths[i] == null)
72
			problemsOccured++;
61
			problemsOccured++;
73
	}
62
	}
74
	if (problemsOccured > 0) {
63
	if (problemsOccured > 0) {
75
		Classpath[] newPaths = new Classpath[classpathSize - problemsOccured];
64
		Classpath[] newPaths = new Classpath[classpathSize - problemsOccured];
76
		String[] newNames = new String[classpathSize - problemsOccured];
77
		for (int i = 0, current = 0; i < classpathSize; i++)
65
		for (int i = 0, current = 0; i < classpathSize; i++)
78
			if (this.classpaths[i] != null) {
66
			if (this.classpaths[i] != null) {
79
				newPaths[current] = this.classpaths[i];
67
				newPaths[current] = this.classpaths[i];
80
				newNames[current++] = pathNames[i];
81
			}
68
			}
82
		classpathSize = newPaths.length;
69
		classpathSize = newPaths.length;
83
		this.classpaths = newPaths;
70
		this.classpaths = newPaths;
84
		pathNames = newNames;
85
	}
71
	}
86
72
	initializeKnownFileNames(initialFileNames);
73
}
74
FileSystem(Classpath[] classpaths, String[] initialFileNames) {
75
	this.classpaths = classpaths;
76
	initializeKnownFileNames(initialFileNames);
77
}
78
static Classpath getClasspath(String classpathName, String encoding,
79
		int classpathDirectoryMode, AccessRuleSet accessRuleSet) {
80
	Classpath result = null;
81
	try {
82
			File file = new File(convertPathSeparators(classpathName));
83
			if (file.isDirectory()) {
84
				if (file.exists()) {
85
					result = new ClasspathDirectory(file, encoding,
86
							classpathDirectoryMode, accessRuleSet);
87
				}
88
			} else {
89
				String lowercaseClasspathName = classpathName.toLowerCase();
90
				if (lowercaseClasspathName.endsWith(SUFFIX_STRING_jar)
91
						|| lowercaseClasspathName.endsWith(SUFFIX_STRING_zip)) {
92
					result = new ClasspathJar(new ZipFile(file), true,
93
							accessRuleSet);
94
					// will throw an IOException if file does not exist
95
				}
96
			}
97
		} catch (IOException e) {
98
			// result = null; -- this is already the case
99
		}
100
	return result;
101
}
102
private void initializeKnownFileNames(String[] initialFileNames) {
87
	this.knownFileNames = new String[initialFileNames.length];
103
	this.knownFileNames = new String[initialFileNames.length];
88
	for (int i = initialFileNames.length; --i >= 0;) {
104
	for (int i = initialFileNames.length; --i >= 0;) {
89
		String fileName = initialFileNames[i];
105
		String fileName = initialFileNames[i];
Lines 92-111 Link Here
92
			fileName = fileName.substring(0, fileName.lastIndexOf('.')); // remove trailing ".java"
108
			fileName = fileName.substring(0, fileName.lastIndexOf('.')); // remove trailing ".java"
93
109
94
		fileName = convertPathSeparators(fileName);
110
		fileName = convertPathSeparators(fileName);
95
		for (int j = 0; j < classpathSize; j++)
111
		for (int j = 0; j < classpaths.length; j++){
96
			if (fileName.startsWith(pathNames[j]))
112
			String matchCandidate = this.classpaths[j].normalizedPath();
97
				matchingPathName = pathNames[j];
113
			if (this.classpaths[j] instanceof  ClasspathDirectory && 
114
					fileName.startsWith(matchCandidate) && 
115
					(matchingPathName == null || 
116
							matchCandidate.length() < matchingPathName.length()))
117
				matchingPathName = matchCandidate;
118
		}
98
		if (matchingPathName == null)
119
		if (matchingPathName == null)
99
			this.knownFileNames[i] = fileName; // leave as is...
120
			this.knownFileNames[i] = fileName; // leave as is...
100
		else
121
		else
101
			this.knownFileNames[i] = fileName.substring(matchingPathName.length());
122
			this.knownFileNames[i] = fileName.substring(matchingPathName.length());
123
		matchingPathName = null;
102
	}
124
	}
103
}
125
}
104
public void cleanup() {
126
public void cleanup() {
105
	for (int i = 0, max = this.classpaths.length; i < max; i++)
127
	for (int i = 0, max = this.classpaths.length; i < max; i++)
106
		this.classpaths[i].reset();
128
		this.classpaths[i].reset();
107
}
129
}
108
private String convertPathSeparators(String path) {
130
private static String convertPathSeparators(String path) {
109
	return File.separatorChar == '/'
131
	return File.separatorChar == '/'
110
		? path.replace('\\', '/')
132
		? path.replace('\\', '/')
111
		 : path.replace('/', '\\');
133
		 : path.replace('/', '\\');
Lines 153-159 Link Here
153
	return null;
175
	return null;
154
}
176
}
155
public ClasspathJar getClasspathJar(File file) throws IOException {
177
public ClasspathJar getClasspathJar(File file) throws IOException {
156
	return new ClasspathJar(new ZipFile(file), true);
178
	return new ClasspathJar(new ZipFile(file), true, null);
157
}
179
}
158
public boolean isPackage(char[][] compoundName, char[] packageName) {
180
public boolean isPackage(char[][] compoundName, char[] packageName) {
159
	String qualifiedPackageName = new String(CharOperation.concatWith(compoundName, packageName, '/'));
181
	String qualifiedPackageName = new String(CharOperation.concatWith(compoundName, packageName, '/'));
(-)batch/org/eclipse/jdt/internal/compiler/batch/Main.java (-51 / +206 lines)
Lines 23-28 Link Here
23
import java.io.UnsupportedEncodingException;
23
import java.io.UnsupportedEncodingException;
24
import java.lang.reflect.Field;
24
import java.lang.reflect.Field;
25
import java.text.MessageFormat;
25
import java.text.MessageFormat;
26
import java.util.ArrayList;
26
import java.util.Arrays;
27
import java.util.Arrays;
27
import java.util.Collections;
28
import java.util.Collections;
28
import java.util.Enumeration;
29
import java.util.Enumeration;
Lines 45-50 Link Here
45
import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
46
import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
46
import org.eclipse.jdt.internal.compiler.IProblemFactory;
47
import org.eclipse.jdt.internal.compiler.IProblemFactory;
47
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
48
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
49
import org.eclipse.jdt.internal.compiler.env.AccessRule;
50
import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
48
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
51
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
49
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
52
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
50
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
53
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
Lines 926-931 Link Here
926
		"org.eclipse.jdt.internal.compiler.batch.messages"; 	//$NON-NLS-1$
929
		"org.eclipse.jdt.internal.compiler.batch.messages"; 	//$NON-NLS-1$
927
930
928
	public String[] classpaths;
931
	public String[] classpaths;
932
	// WORK suppress (if not used)
933
	FileSystem.Classpath[] checkedClasspaths;
934
	// WORK consider the use of an ArrayList instead
929
	public String destinationPath;
935
	public String destinationPath;
930
	public String[] encodings;
936
	public String[] encodings;
931
	public Logger logger;
937
	public Logger logger;
Lines 1185-1193 Link Here
1185
		final int InsideBootClasspath = 128;
1191
		final int InsideBootClasspath = 128;
1186
		final int InsideMaxProblems = 256;
1192
		final int InsideMaxProblems = 256;
1187
		final int Default = 0;
1193
		final int Default = 0;
1188
		String[] bootclasspaths = null;
1194
		FileSystem.Classpath[] bootclasspaths = null;
1189
		int DEFAULT_SIZE_CLASSPATH = 4;
1195
		int DEFAULT_SIZE_CLASSPATH = 4;
1190
		int pathCount = 0;
1196
		int pathCount = 0;
1197
		int checkedClasspathsCount = 0;
1198
		// FileSystem.Classpath currentClasspath = null;
1199
		String currentClasspathName = null;
1200
		ArrayList currentRuleSpecs = new ArrayList(DEFAULT_SIZE_CLASSPATH);
1191
		int bootclasspathCount = 0;
1201
		int bootclasspathCount = 0;
1192
		int index = -1, filesCount = 0, argCount = argv.length;
1202
		int index = -1, filesCount = 0, argCount = argv.length;
1193
		int mode = Default;
1203
		int mode = Default;
Lines 1264-1270 Link Here
1264
			currentArg = newCommandLineArgs[index];
1274
			currentArg = newCommandLineArgs[index];
1265
1275
1266
			customEncoding = null;
1276
			customEncoding = null;
1267
			if (currentArg.endsWith("]")) { //$NON-NLS-1$ 
1277
			if (currentArg.endsWith("]") && !(mode == InsideBootClasspath || mode == InsideClasspath) ) { //$NON-NLS-1$ 
1268
				// look for encoding specification
1278
				// look for encoding specification
1269
				int encodingStart = currentArg.indexOf('[') + 1;
1279
				int encodingStart = currentArg.indexOf('[') + 1;
1270
				int encodingEnd = currentArg.length() - 1;
1280
				int encodingEnd = currentArg.length() - 1;
Lines 1378-1383 Link Here
1378
				|| currentArg.equals("-cp")) { //$NON-NLS-1$ //$NON-NLS-2$
1388
				|| currentArg.equals("-cp")) { //$NON-NLS-1$ //$NON-NLS-2$
1379
				if (pathCount == 0) {
1389
				if (pathCount == 0) {
1380
					this.classpaths = new String[DEFAULT_SIZE_CLASSPATH];
1390
					this.classpaths = new String[DEFAULT_SIZE_CLASSPATH];
1391
					this.checkedClasspaths = new FileSystem.Classpath[DEFAULT_SIZE_CLASSPATH];
1381
				}
1392
				}
1382
				mode = InsideClasspath;
1393
				mode = InsideClasspath;
1383
				continue;
1394
				continue;
Lines 1386-1392 Link Here
1386
				if (bootclasspathCount > 0)
1397
				if (bootclasspathCount > 0)
1387
					throw new InvalidInputException(
1398
					throw new InvalidInputException(
1388
						Main.bind("configure.duplicateBootClasspath", currentArg)); //$NON-NLS-1$
1399
						Main.bind("configure.duplicateBootClasspath", currentArg)); //$NON-NLS-1$
1389
				bootclasspaths = new String[DEFAULT_SIZE_CLASSPATH];
1400
				bootclasspaths = new FileSystem.Classpath[DEFAULT_SIZE_CLASSPATH];
1390
				mode = InsideBootClasspath;
1401
				mode = InsideBootClasspath;
1391
				continue;
1402
				continue;
1392
			}
1403
			}
Lines 1921-1960 Link Here
1921
				mode = Default;
1932
				mode = Default;
1922
				continue;
1933
				continue;
1923
			}
1934
			}
1924
			if (mode == InsideClasspath) {
1935
			if (mode == InsideClasspath || mode == InsideBootClasspath) {
1925
				StringTokenizer tokenizer = new StringTokenizer(currentArg, File.pathSeparator);
1936
				StringTokenizer tokenizer = new StringTokenizer(currentArg,
1937
						File.pathSeparator + "[]", true); //$NON-NLS-1$
1938
				// state machine
1939
				final int start = 0; 
1940
				final int readyToClose = 1;
1941
				// 'path' 'path1[rule];path2'
1942
				final int readyToCloseEndingWithRules = 2;
1943
				// 'path[rule]' 'path1;path2[rule]'
1944
				final int needAnotherEntry = 3;
1945
				// 'path[rule];' 'path;' 'path1;path2;'
1946
				final int rulesNeedAnotherRule = 4;
1947
				// 'path[rule1;'
1948
				final int rulesStart = 5;
1949
				// 'path[' 'path1;path2['
1950
				final int rulesReadyToClose = 6;
1951
				// 'path[rule' 'path[rule1;rule2'
1952
				final int error = 99;
1953
				int state = start;
1954
				String token = null;
1926
				while (tokenizer.hasMoreTokens()) {
1955
				while (tokenizer.hasMoreTokens()) {
1927
					int length;
1956
					token = tokenizer.nextToken();
1928
					if ((length = this.classpaths.length) <= pathCount) {
1957
					if (token.equals(File.pathSeparator)) {
1929
						System.arraycopy(
1958
						switch (state) {
1930
							this.classpaths,
1959
						case readyToClose:
1931
							0,
1960
						case readyToCloseEndingWithRules:
1932
							(this.classpaths = new String[length * 2]),
1961
							state = needAnotherEntry;
1933
							0,
1962
							break;
1934
							length);
1963
						case rulesReadyToClose:
1964
							state = rulesNeedAnotherRule;
1965
							break;
1966
						default:
1967
							state = error;
1968
						}
1969
					} else if (token.equals("[")) { //$NON-NLS-1$
1970
						switch (state) {
1971
						case readyToClose:
1972
							state = rulesStart;
1973
							break;
1974
						default:
1975
							state = error;
1976
						}
1977
					} else if (token.equals("]")) { //$NON-NLS-1$
1978
						switch (state) {
1979
						case rulesReadyToClose:
1980
							state = readyToCloseEndingWithRules;
1981
							break;
1982
						default:
1983
							state = error;
1984
						}
1985
1986
					} else // regular word
1987
					{
1988
						switch (state) {
1989
						case start:
1990
						case needAnotherEntry:
1991
							state = readyToClose;
1992
							if (mode == InsideClasspath) {
1993
								int length;
1994
								if ((length = this.classpaths.length) <= pathCount) {
1995
									System
1996
											.arraycopy(
1997
													this.classpaths,
1998
													0,
1999
													(this.classpaths = new String[length * 2]),
2000
													0, length);
2001
								}
2002
								this.classpaths[pathCount++] = token;
2003
								currentClasspathName = token;
2004
							} else { // inside bootclasspath
2005
								currentClasspathName = token;
2006
							}
2007
							break;
2008
						case rulesNeedAnotherRule:
2009
						case rulesStart:
2010
							state = rulesReadyToClose;
2011
							currentRuleSpecs.add(token);
2012
							break;
2013
						default:
2014
							state = error;
2015
						}
1935
					}
2016
					}
1936
					this.classpaths[pathCount++] = tokenizer.nextToken();
1937
				}
2017
				}
1938
				mode = Default;
2018
				if (state == readyToClose
1939
				continue;
2019
						|| state == readyToCloseEndingWithRules) {
1940
			}
2020
					AccessRule[] accessRules = new AccessRule[currentRuleSpecs
1941
			if (mode == InsideBootClasspath) {
2021
							.size()];
1942
				StringTokenizer tokenizer = new StringTokenizer(currentArg, File.pathSeparator);
2022
					boolean rulesOK = true;
1943
				while (tokenizer.hasMoreTokens()) {
2023
					Iterator i = currentRuleSpecs.iterator();
1944
					int length;
2024
					int j = 0;
1945
					if ((length = bootclasspaths.length) <= bootclasspathCount) {
2025
					while (i.hasNext()) {
1946
						System.arraycopy(
2026
						String ruleSpec = (String) i.next();
1947
							bootclasspaths,
2027
						char key = ruleSpec.charAt(0);
1948
							0,
2028
						String pattern = ruleSpec.substring(1);
1949
							(bootclasspaths = new String[length * 2]),
2029
						if (pattern.length() > 0) {
1950
							0,
2030
							switch (key) {
1951
							length);
2031
							case '+':
2032
								accessRules[j++] = new AccessRule(pattern
2033
										.toCharArray(), -1);
2034
								break;
2035
							case '~':
2036
								accessRules[j++] = new AccessRule(pattern
2037
										.toCharArray(),
2038
										IProblem.DiscouragedReference);
2039
								break;
2040
							case '-':
2041
								accessRules[j++] = new AccessRule(pattern
2042
										.toCharArray(),
2043
										IProblem.ForbiddenReference);
2044
								break;
2045
							default:
2046
								rulesOK = false;
2047
							}
2048
						} else {
2049
							rulesOK = false;
2050
						}
2051
					}
2052
					if (rulesOK) {
2053
						AccessRuleSet accessRuleSet = new AccessRuleSet(
2054
								accessRules, "{0}"); //$NON-NLS-1$
2055
						FileSystem.Classpath currentClasspath = FileSystem
2056
								.getClasspath(currentClasspathName,
2057
										customEncoding, 0, accessRuleSet);
2058
						if (currentClasspath != null) {
2059
							int length;
2060
							if (mode == InsideClasspath) {
2061
								if ((length = this.checkedClasspaths.length) <= checkedClasspathsCount) {
2062
									System
2063
											.arraycopy(
2064
													this.checkedClasspaths,
2065
													0,
2066
													(this.checkedClasspaths = new FileSystem.Classpath[length * 2]),
2067
													0, length);
2068
								}
2069
								this.checkedClasspaths[checkedClasspathsCount++] = currentClasspath;
2070
							} else { // inside bootclasspath
2071
								if ((length = bootclasspaths.length) <= bootclasspathCount) {
2072
									System
2073
											.arraycopy(
2074
													bootclasspaths,
2075
													0,
2076
													(bootclasspaths = new FileSystem.Classpath[length * 2]),
2077
													0, length);
2078
								}
2079
								bootclasspaths[bootclasspathCount++] = currentClasspath;
2080
							}
2081
						} else {
2082
							this.logger.logIncorrectClasspath(currentArg);
2083
							// WORK refine diagnostic
2084
						}
2085
					} else {
2086
						this.logger.logIncorrectClasspath(currentArg);
2087
						// we go on anyway
1952
					}
2088
					}
1953
					bootclasspaths[bootclasspathCount++] = tokenizer.nextToken();
2089
2090
				} else {
2091
					this.logger.logIncorrectClasspath(currentArg);
2092
					// we go on anyway
1954
				}
2093
				}
1955
				mode = Default;
2094
				mode = Default;
1956
				continue;
2095
				continue;
1957
			}			
2096
			}
1958
			//default is input directory
2097
			//default is input directory
1959
			currentArg = currentArg.replace('/', File.separatorChar);
2098
			currentArg = currentArg.replace('/', File.separatorChar);
1960
			if (currentArg.endsWith(File.separator))
2099
			if (currentArg.endsWith(File.separator))
Lines 2025-2036 Link Here
2025
			String classProp = System.getProperty("java.class.path"); //$NON-NLS-1$
2164
			String classProp = System.getProperty("java.class.path"); //$NON-NLS-1$
2026
			if ((classProp == null) || (classProp.length() == 0)) {
2165
			if ((classProp == null) || (classProp.length() == 0)) {
2027
				this.logger.logNoClasspath(); //$NON-NLS-1$
2166
				this.logger.logNoClasspath(); //$NON-NLS-1$
2028
				classProp = System.getProperty("user.dir"); //$NON-NLS-1$
2167
				this.classpaths = new String[1];
2029
			}
2168
			}
2030
			StringTokenizer tokenizer = new StringTokenizer(classProp, File.pathSeparator);
2169
			else {
2031
			this.classpaths = new String[tokenizer.countTokens() + 1];
2170
				StringTokenizer tokenizer = new StringTokenizer(classProp, File.pathSeparator);
2032
			while (tokenizer.hasMoreTokens()) {
2171
				String token;
2033
				this.classpaths[pathCount++] = tokenizer.nextToken();
2172
				this.classpaths = new String[tokenizer.countTokens() + 1];
2173
				this.checkedClasspaths = new FileSystem.Classpath[this.classpaths.length];
2174
				while (tokenizer.hasMoreTokens()) {
2175
					token = tokenizer.nextToken();
2176
					this.classpaths[pathCount++] = token;
2177
					FileSystem.Classpath currentClasspath = FileSystem
2178
							.getClasspath(token, customEncoding, 0, null);
2179
					if (currentClasspath != null) {
2180
						this.checkedClasspaths[checkedClasspathsCount++] = currentClasspath;
2181
					} else {
2182
						this.logger.logIncorrectClasspath(token);
2183
						// should not happen - we go on anyway
2184
					}
2185
				}
2034
			}
2186
			}
2035
			this.classpaths[pathCount++] = System.getProperty("user.dir");//$NON-NLS-1$
2187
			this.classpaths[pathCount++] = System.getProperty("user.dir");//$NON-NLS-1$
2036
		}
2188
		}
Lines 2061-2072 Link Here
2061
						File[][] systemLibrariesJars = getLibrariesFiles(directoriesToCheck);
2213
						File[][] systemLibrariesJars = getLibrariesFiles(directoriesToCheck);
2062
						if (systemLibrariesJars != null) {
2214
						if (systemLibrariesJars != null) {
2063
							int length = getLength(systemLibrariesJars);
2215
							int length = getLength(systemLibrariesJars);
2064
							bootclasspaths = new String[length];
2216
							bootclasspaths = new FileSystem.Classpath[length];
2065
							for (int i = 0, max = systemLibrariesJars.length; i < max; i++) {
2217
							for (int i = 0, max = systemLibrariesJars.length; i < max; i++) {
2066
								File[] current = systemLibrariesJars[i];
2218
								File[] current = systemLibrariesJars[i];
2067
								if (current != null) {
2219
								if (current != null) {
2068
									for (int j = 0, max2 = current.length; j < max2; j++) {
2220
									for (int j = 0, max2 = current.length; j < max2; j++) {
2069
										bootclasspaths[bootclasspathCount++] = current[j].getAbsolutePath();
2221
										if ((bootclasspaths[bootclasspathCount] = FileSystem
2222
												.getClasspath(current[j]
2223
														.getAbsolutePath(),
2224
														null, 0, null)) != null) {
2225
											bootclasspathCount++;
2226
										}
2070
									}
2227
									}
2071
								}
2228
								}
2072
							}
2229
							}
Lines 2102-2123 Link Here
2102
			newclasspaths,
2259
			newclasspaths,
2103
			bootclasspathCount,
2260
			bootclasspathCount,
2104
			pathCount);
2261
			pathCount);
2105
2262
		FileSystem.Classpath [] trimmedClasspaths = new FileSystem.Classpath[bootclasspathCount
2106
		if (bootclasspathCount != 0) {
2263
				+ checkedClasspathsCount];
2107
			System.arraycopy(
2264
		System.arraycopy(
2108
				bootclasspaths,
2265
				this.checkedClasspaths,
2109
				0,
2110
				newclasspaths,
2111
				0,
2266
				0,
2112
				bootclasspathCount);
2267
				trimmedClasspaths,
2268
				bootclasspathCount,
2269
				checkedClasspathsCount);
2270
		for (int i = 0; i < bootclasspathCount;i++){
2271
			trimmedClasspaths[i] = bootclasspaths[i];
2272
			newclasspaths[i]  = bootclasspaths[i].normalizedPath();
2113
		}
2273
		}
2114
		this.classpaths = newclasspaths;
2274
		this.classpaths = newclasspaths;
2115
		for (int i = 0, max = this.classpaths.length; i < max; i++) {
2275
		this.checkedClasspaths = trimmedClasspaths;
2116
			File file = new File(this.classpaths[i]);
2117
			if (!file.exists()) { // signal missing classpath entry file
2118
				this.logger.logIncorrectClasspath(this.classpaths[i]); //$NON-NLS-1$
2119
			}
2120
		}
2121
		if (this.destinationPath == null) {
2276
		if (this.destinationPath == null) {
2122
			this.generatePackagesStructure = false;
2277
			this.generatePackagesStructure = false;
2123
		} else if ("none".equals(this.destinationPath)) { //$NON-NLS-1$
2278
		} else if ("none".equals(this.destinationPath)) { //$NON-NLS-1$
Lines 2351-2357 Link Here
2351
		String defaultEncoding = (String) this.options.get(CompilerOptions.OPTION_Encoding);
2506
		String defaultEncoding = (String) this.options.get(CompilerOptions.OPTION_Encoding);
2352
		if ("".equals(defaultEncoding)) //$NON-NLS-1$
2507
		if ("".equals(defaultEncoding)) //$NON-NLS-1$
2353
			defaultEncoding = null; //$NON-NLS-1$	
2508
			defaultEncoding = null; //$NON-NLS-1$	
2354
		return new FileSystem(this.classpaths, this.filenames, defaultEncoding);
2509
		return new FileSystem(this.checkedClasspaths, this.filenames);
2355
	}
2510
	}
2356
	/*
2511
	/*
2357
	 *  Low-level API performing the actual compilation
2512
	 *  Low-level API performing the actual compilation
(-)batch/org/eclipse/jdt/internal/compiler/batch/messages.properties (-2 / +6 lines)
Lines 92-100 Link Here
92
\ \n\
92
\ \n\
93
\ Classpath options:\n\
93
\ Classpath options:\n\
94
\    -cp -classpath <directories and zip/jar files separated by {0}>\n\
94
\    -cp -classpath <directories and zip/jar files separated by {0}>\n\
95
\                       specify location for application classes and sources\n\
95
\                       specify location for application classes and sources. Each\n\
96
\                       directory or file can specify access rules for types between\n\
97
\                       ''['' and '']'' (e.g. [-X.java] to deny access to type X)\n\
96
\    -bootclasspath <directories and zip/jar files separated by {0}>\n\
98
\    -bootclasspath <directories and zip/jar files separated by {0}>\n\
97
\                       specify location for system classes\n\
99
\                       specify location for system classes. Each directory or file can\n\
100
\                       specify access rules for types between ''['' and '']'' (e.g. [-X.java]\n\
101
\                       to deny access to type X)\n\
98
\    -d <dir>           destination directory (if omitted, no directory is created)\n\
102
\    -d <dir>           destination directory (if omitted, no directory is created)\n\
99
\    -d none            generate no .class files\n\
103
\    -d none            generate no .class files\n\
100
\    -encoding <enc>    specify custom encoding for all sources. Each file/directory can override it\n\
104
\    -encoding <enc>    specify custom encoding for all sources. Each file/directory can override it\n\
(-)compiler/org/eclipse/jdt/internal/compiler/env/AccessRuleSet.java (+4 lines)
Lines 25-30 Link Here
25
	public AccessRuleSet(AccessRule[] accessRules) {
25
	public AccessRuleSet(AccessRule[] accessRules) {
26
		this.accessRules = accessRules;
26
		this.accessRules = accessRules;
27
	}
27
	}
28
	public AccessRuleSet(AccessRule[] accessRules, String messageTemplate) {
29
		this.accessRules = accessRules;
30
		this.messageTemplate = messageTemplate;
31
	}
28
	/**
32
	/**
29
	 * @see java.lang.Object#equals(java.lang.Object)
33
	 * @see java.lang.Object#equals(java.lang.Object)
30
	 */
34
	 */

Return to bug 92398