Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Thomann2007-07-05 13:54:21 +0000
committerOlivier Thomann2007-07-05 13:54:21 +0000
commitccd12469d7fc21a8e1a0a597451a059df56002ad (patch)
tree523e581ca9d698174267a2280a1922d10a03788c
parent4b460199498c48cda44ce10125aa5901a10bff62 (diff)
downloadeclipse.jdt.core-ccd12469d7fc21a8e1a0a597451a059df56002ad.tar.gz
eclipse.jdt.core-ccd12469d7fc21a8e1a0a597451a059df56002ad.tar.xz
eclipse.jdt.core-ccd12469d7fc21a8e1a0a597451a059df56002ad.zip
HEAD - Fixes for 192774, 189799 and 191082
-rw-r--r--org.eclipse.jdt.apt.tests/src/org/eclipse/jdt/apt/tests/annotations/mirrortest/MirrorDeclarationCodeExample.java35
-rw-r--r--org.eclipse.jdt.apt.tests/src/org/eclipse/jdt/apt/tests/annotations/mirrortest/MirrorDeclarationTestAnnotationProcessor.java12
-rw-r--r--org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors.jarbin97631 -> 98650 bytes
-rw-r--r--org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/elementutils/ElementUtilsProc.java35
-rw-r--r--org.eclipse.jdt.compiler.apt.tests/resources/targets/model/pc/F.java74
-rw-r--r--org.eclipse.jdt.compiler.apt/META-INF/MANIFEST.MF2
-rw-r--r--org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchProcessingEnvImpl.java4
-rw-r--r--org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/AnnotationMirrorImpl.java33
-rw-r--r--org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ElementsImpl.java164
-rw-r--r--org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/EclipseFileManager.java338
-rw-r--r--org.eclipse.jdt.compiler.tool/META-INF/MANIFEST.MF2
-rw-r--r--org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompiler.java425
-rw-r--r--org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompilerImpl.java410
-rw-r--r--org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseFileManager.java338
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java40
-rw-r--r--org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java2
-rw-r--r--org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java116
-rw-r--r--org.eclipse.jdt.core/buildnotes_jdt-core.html8
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ElementValuePair.java4
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java58
20 files changed, 1490 insertions, 610 deletions
diff --git a/org.eclipse.jdt.apt.tests/src/org/eclipse/jdt/apt/tests/annotations/mirrortest/MirrorDeclarationCodeExample.java b/org.eclipse.jdt.apt.tests/src/org/eclipse/jdt/apt/tests/annotations/mirrortest/MirrorDeclarationCodeExample.java
index 92086784d7..a1048b0e63 100644
--- a/org.eclipse.jdt.apt.tests/src/org/eclipse/jdt/apt/tests/annotations/mirrortest/MirrorDeclarationCodeExample.java
+++ b/org.eclipse.jdt.apt.tests/src/org/eclipse/jdt/apt/tests/annotations/mirrortest/MirrorDeclarationCodeExample.java
@@ -24,18 +24,27 @@ public class MirrorDeclarationCodeExample
"import org.eclipse.jdt.apt.tests.annotations.mirrortest.MirrorDeclarationTestAnnotation;" + "\n" +
"@MirrorDeclarationTestAnnotation(s=\"fred\", value=5)" + "\n" +
"public class DeclarationTestClass {" + "\n" +
- " public class ClassDec {" + "\n" +
- " public ClassDec() {}" + "\n" +
- " public ClassDec(int j) {}" + "\n" +
- " public static final int i = 1;" + "\n" +
- " public float f;" + "\n" +
- " public static final String s = \"hello\";" + "\n" +
- " public java.util.GregorianCalendar gc;" + "\n" +
- " public void methodDec(int k, String... t) throws Exception {}" + "\n" +
- " public void methodDecNoArg(){}" + "\n" +
- " }" + "\n" +
- " public enum EnumDec {" + "\n" +
- " aardvark, anteater" + "\n" +
- " }" + "\n" +
+ " public class ClassDec {" + "\n" +
+ " public ClassDec() {}" + "\n" +
+ " public ClassDec(int j) {}" + "\n" +
+ " public static final int i = 1;" + "\n" +
+ " public float f;" + "\n" +
+ " public static final String s = \"hello\";" + "\n" +
+ " public java.util.GregorianCalendar gc;" + "\n" +
+ " public void methodDec(int k, String... t) throws Exception {}" + "\n" +
+ " public void methodDecNoArg(){}" + "\n" +
+ " @MirrorDeclarationTestAnnotation() public Object foo(Object o) throws Exception {\n" +
+ " return null;\n" +
+ " }\n" +
+ " @MirrorDeclarationTestAnnotation() public Object foo2(Object o) throws Exception {\n" +
+ " return null;\n" +
+ " }\n" +
+ " @MirrorDeclarationTestAnnotation() public Object foo3(Object o) throws Exception {\n" +
+ " return null;\n" +
+ " }\n" +
+ " }" + "\n" +
+ " public enum EnumDec {" + "\n" +
+ " aardvark, anteater" + "\n" +
+ " }" + "\n" +
"}";
}
diff --git a/org.eclipse.jdt.apt.tests/src/org/eclipse/jdt/apt/tests/annotations/mirrortest/MirrorDeclarationTestAnnotationProcessor.java b/org.eclipse.jdt.apt.tests/src/org/eclipse/jdt/apt/tests/annotations/mirrortest/MirrorDeclarationTestAnnotationProcessor.java
index e5887a90ff..ab76849d76 100644
--- a/org.eclipse.jdt.apt.tests/src/org/eclipse/jdt/apt/tests/annotations/mirrortest/MirrorDeclarationTestAnnotationProcessor.java
+++ b/org.eclipse.jdt.apt.tests/src/org/eclipse/jdt/apt/tests/annotations/mirrortest/MirrorDeclarationTestAnnotationProcessor.java
@@ -25,6 +25,7 @@
package org.eclipse.jdt.apt.tests.annotations.mirrortest;
import java.util.Collection;
+import java.util.HashSet;
import org.eclipse.jdt.apt.tests.annotations.BaseProcessor;
import org.eclipse.jdt.apt.tests.annotations.ProcessorTestStatus;
@@ -159,14 +160,21 @@ public class MirrorDeclarationTestAnnotationProcessor extends BaseProcessor {
ProcessorTestStatus.assertTrue("constructor with one (int) arg", constructIntArg != null);
Collection<MethodDeclaration> methodDecls = testClassDec.getMethods();
- ProcessorTestStatus.assertEquals("Number of methods", 2, methodDecls.size());
+ ProcessorTestStatus.assertEquals("Number of methods", 5, methodDecls.size());
+ HashSet<AnnotationMirror> annotationMirrors = new HashSet<AnnotationMirror>();
+ for (MethodDeclaration methodDeclaration : methodDecls) {
+ Collection<AnnotationMirror> mirrors = methodDeclaration.getAnnotationMirrors();
+ annotationMirrors.addAll(mirrors);
+ }
+ ProcessorTestStatus.assertEquals("Wrong size for annotation mirrors", 3, annotationMirrors.size());
+
MethodDeclaration methodDecl = null;
methodDecl = methodDecls.iterator().next();
ProcessorTestStatus.assertTrue("method declaration exists", methodDecl != null);
ClassType superClass = testClassDec.getSuperclass();
- ProcessorTestStatus.assertEquals("Object is only super", "java.lang.Object", superClass.toString());
+ ProcessorTestStatus.assertEquals("Object is only super", "java.lang.Object", superClass.toString());
}
/**
diff --git a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors.jar b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors.jar
index 6681fff6b2..cec6739166 100644
--- a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors.jar
+++ b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors.jar
Binary files differ
diff --git a/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/elementutils/ElementUtilsProc.java b/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/elementutils/ElementUtilsProc.java
index ace386f43b..cebde2e875 100644
--- a/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/elementutils/ElementUtilsProc.java
+++ b/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/elementutils/ElementUtilsProc.java
@@ -452,13 +452,40 @@ public class ElementUtilsProc extends BaseProcessor
nameToDoc.put("F", " Javadoc on element F\n @param <T1> a type parameter\n");
nameToDoc.put("FChild", " Javadoc on nested element FChild\n");
nameToDoc.put("FEnum", " Javadoc on nested enum FEnum\n Two lines long\n");
- nameToDoc.put("FChildI", " Javadoc on nested interface FChildI\n");
+ nameToDoc.put("FChildI",
+ " Javadoc on nested interface FChildI\n" +
+ "\tthis line has tab after asterisk and ends with another tab\t\n" +
+ "\tthis one too\t\n" +
+ " this line has three spaces after asterisk and ends with three spaces \n" +
+ " this line has only one space before the asterisk\n");
nameToDoc.put("_fieldT1_protected", "Javadoc on field _fieldT1_protected, inline format ");
+ nameToDoc.put("_fieldT1_private",
+ "\n" +
+ " Javadoc on _fieldT1_private\n" +
+ " this line starts with two spaces, no asterisk\n" +
+ " This line starts, contains\tand ends with a tab\t\n" +
+ " This line starts with a space, tab, space, tab, space\n");
nameToDoc.put("fieldInt", null);
nameToDoc.put("method_T1", " Javadoc on F.method_T1\n");
nameToDoc.put("method_String", null);
+ nameToDoc.put("getAnonymousObjectAbstract", "");
+ nameToDoc.put("add", "\n @add(int)\n");
+ nameToDoc.put("foo", "\n Creates a new instance of AllChecks \n");
+ nameToDoc.put("bar", " @bar\t(int)\n");
+ nameToDoc.put("bar2", "\t@bar2(int)\n");
+ nameToDoc.put("m", " Method\tm\n");
+ nameToDoc.put("m1", "This is a comment for the method m1,\n" +
+ " it is on two lines\n");
+ nameToDoc.put("m2", "Another comment - starts on first line and\n" +
+ " continue on the second line ");
+ nameToDoc.put("m3", " One more test case that.\n" +
+ " needs\n" +
+ " to be verified.\n" +
+ "\n" +
+ " An empty line with no spaces need to be seen as an empty line.\n" +
+ "\n" +
+ " End of the comment.\n");
-
String actual = _elementUtils.getDocComment(_elementF);
String expected = nameToDoc.get("F");
if (!expected.equals(actual)) {
@@ -471,12 +498,12 @@ public class ElementUtilsProc extends BaseProcessor
actual = _elementUtils.getDocComment(e);
expected = nameToDoc.get(name);
if (expected == null && actual != null) {
- reportError("examineGetDocComment: Expected getDocComment(" + name + ") to return null, but got " + actual);
+ reportError("examineGetDocComment: Expected getDocComment(" + name + ") to return null, but got " + _elementUtils.getDocComment(e));
return false;
}
else if (expected != null) {
if (!expected.equals(actual)) {
- reportError("examineGetDocComment: Unexpected result from getDocComment(" + name + "): " + actual);
+ reportError("examineGetDocComment: Unexpected result from getDocComment(" + name + "): " + _elementUtils.getDocComment(e));
return false;
}
}
diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/targets/model/pc/F.java b/org.eclipse.jdt.compiler.apt.tests/resources/targets/model/pc/F.java
index b4f7299fa1..bd736cdd34 100644
--- a/org.eclipse.jdt.compiler.apt.tests/resources/targets/model/pc/F.java
+++ b/org.eclipse.jdt.compiler.apt.tests/resources/targets/model/pc/F.java
@@ -5,6 +5,13 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
+
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+// CAUTION! THIS FILE CONTAINS SPECIFIC COMBINATIONS OF TABS AND SPACES,
+// FOR TESTING WHITESPACE HANDLING IN JAVADOC. DO NOT REFORMAT OR MODIFY
+// WHITESPACE IN ANY JAVADOC IN THIS FILE.
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
package targets.model.pc;
/**
@@ -27,12 +34,23 @@ public class F<T1> {
/**
* Javadoc on nested interface FChildI
+ * this line has tab after asterisk and ends with another tab
+ * this one too
+ * this line has three spaces after asterisk and ends with three spaces
+ * this line has only one space before the asterisk
*/
public interface FChildI {}
/** Javadoc on field _fieldT1_protected, inline format */
protected T1 _fieldT1_protected;
+ // Next line has a space at the end, after the double asterisks
+ /**
+ * Javadoc on _fieldT1_private
+ this line starts with two spaces, no asterisk
+ This line starts, contains and ends with a tab
+ This line starts with a space, tab, space, tab, space
+ */
private T1 _fieldT1_private;
int fieldInt;
@@ -70,4 +88,60 @@ public class F<T1> {
// unrelated to the same-signature methods in Overriding.java
void f() {}
+
+ /************************/
+ /*** Abstract methods ***/
+ /************************/
+
+ public Object getAnonymousObjectAbstract() {
+ return null;
+ }
+
+ /**
+ * @add(int)
+ */
+ int add (int j) {
+ return j + j;
+ }
+
+ /**
+ * Creates a new instance of AllChecks
+ */
+ public void foo() {
+ }
+
+ /**
+ * @bar (int)
+ */
+ int bar(int i) { return i; }
+
+ /**
+ * @bar2(int)
+ */
+ int bar2(int i) { return i; }
+
+/**
+ Method m
+ */
+ void m() {}
+
+ /** This is a comment for the method m1,
+ * it is on two lines
+ */
+ void m1() {}
+
+ /** Another comment - starts on first line and
+ continue on the second line */
+ void m2() {}
+
+ /**
+ * One more test case that.
+ * needs
+ * to be verified.
+ *
+ * An empty line with no spaces need to be seen as an empty line.
+ *
+ * End of the comment.
+ */
+ void m3() {}
} \ No newline at end of file
diff --git a/org.eclipse.jdt.compiler.apt/META-INF/MANIFEST.MF b/org.eclipse.jdt.compiler.apt/META-INF/MANIFEST.MF
index 777b6d6983..2d0602ba67 100644
--- a/org.eclipse.jdt.compiler.apt/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.compiler.apt/META-INF/MANIFEST.MF
@@ -5,7 +5,7 @@ Bundle-SymbolicName: org.eclipse.jdt.compiler.apt
Bundle-Version: 1.0.0.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-Vendor: %providerName
-Fragment-Host: org.eclipse.jdt.core;bundle-version="3.3.0"
+Fragment-Host: org.eclipse.jdt.core;bundle-version="[3.3.0,4.0.0)"
Bundle-Localization: compiler_apt_fragment
Eclipse-LazyStart: true
Export-Package: org.eclipse.jdt.internal.compiler.apt.dispatch;x-friends:="org.eclipse.jdt.apt.pluggable.core",
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchProcessingEnvImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchProcessingEnvImpl.java
index 8366a6117a..a466bcdab6 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchProcessingEnvImpl.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchProcessingEnvImpl.java
@@ -48,7 +48,7 @@ public class BatchProcessingEnvImpl extends BaseProcessingEnvImpl {
_dispatchManager = dispatchManager;
Class<?> c = null;
try {
- c = Class.forName("org.eclipse.jdt.internal.compiler.tool.EclipseCompiler"); //$NON-NLS-1$
+ c = Class.forName("org.eclipse.jdt.internal.compiler.tool.EclipseCompilerImpl"); //$NON-NLS-1$
} catch (ClassNotFoundException e) {
// ignore
}
@@ -79,7 +79,7 @@ public class BatchProcessingEnvImpl extends BaseProcessingEnvImpl {
} else {
String encoding = (String) batchCompiler.options.get(CompilerOptions.OPTION_Encoding);
Charset charset = encoding != null ? Charset.forName(encoding) : null;
- JavaFileManager manager = new EclipseFileManager(batchCompiler, batchCompiler.compilerLocale, charset);
+ JavaFileManager manager = new EclipseFileManager(batchCompiler.compilerLocale, charset);
ArrayList<String> options = new ArrayList<String>();
for (String argument : commandLineArguments) {
options.add(argument);
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/AnnotationMirrorImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/AnnotationMirrorImpl.java
index f03c090fef..71568bb63e 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/AnnotationMirrorImpl.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/AnnotationMirrorImpl.java
@@ -56,11 +56,42 @@ public class AnnotationMirrorImpl implements AnnotationMirror, InvocationHandler
if (this._binding == null) {
return ((AnnotationMirrorImpl) obj)._binding == null;
}
- return this._binding.equals(((AnnotationMirrorImpl) obj)._binding);
+ return equals(this._binding, ((AnnotationMirrorImpl) obj)._binding);
}
return false;
}
+ private static boolean equals(AnnotationBinding annotationBinding, AnnotationBinding annotationBinding2) {
+ if (annotationBinding.getAnnotationType() != annotationBinding2.getAnnotationType()) return false;
+ final ElementValuePair[] elementValuePairs = annotationBinding.getElementValuePairs();
+ final ElementValuePair[] elementValuePairs2 = annotationBinding2.getElementValuePairs();
+ final int length = elementValuePairs.length;
+ if (length != elementValuePairs2.length) return false;
+ loop: for (int i = 0; i < length; i++) {
+ ElementValuePair pair = elementValuePairs[i];
+ // loop on the given pair to make sure one will match
+ for (int j = 0; j < length; j++) {
+ ElementValuePair pair2 = elementValuePairs2[j];
+ if (pair.binding == pair2.binding) {
+ if (pair.value == null) {
+ if (pair2.value == null) {
+ continue loop;
+ }
+ return false;
+ } else {
+ if (pair2.value == null
+ || !pair2.value.equals(pair.value)) {
+ return false;
+ }
+ }
+ continue loop;
+ }
+ }
+ return false;
+ }
+ return true;
+ }
+
public DeclaredType getAnnotationType() {
if (this._binding == null) {
return _env.getFactory().getErrorType();
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ElementsImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ElementsImpl.java
index 22a03bf464..559872c4ae 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ElementsImpl.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ElementsImpl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2007 BEA Systems, Inc.
+ * Copyright (c) 2006, 2007 BEA Systems, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,7 +7,7 @@
*
* Contributors:
* wharley@bea.com - initial API and implementation
- *
+ *
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.apt.model;
@@ -61,13 +61,10 @@ import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
public class ElementsImpl implements Elements {
// Used for parsing Javadoc comments: matches initial delimiter, followed by whitespace
- private static final Pattern INITIAL_DELIMITER = Pattern.compile("^\\s*/\\*\\*\\s*"); //$NON-NLS-1$
- // Used for parsing Javadoc comments: matches initial whitespace followed by one or more stars
- private static final Pattern INITIAL_WHITESPACE_STARS = Pattern.compile("^\\s*\\*+"); //$NON-NLS-1$
+ private static final Pattern INITIAL_DELIMITER = Pattern.compile("^\\s*/\\*+"); //$NON-NLS-1$
-
private final BaseProcessingEnvImpl _env;
-
+
/*
* The processing env creates and caches an ElementsImpl. Other clients should
* not create their own; they should ask the env for it.
@@ -93,7 +90,7 @@ public class ElementsImpl implements Elements {
while (null != binding) {
for (AnnotationBinding annotation : binding.getAnnotations()) {
if (annotation == null) continue;
- ReferenceBinding annotationType = annotation.getAnnotationType();
+ ReferenceBinding annotationType = annotation.getAnnotationType();
if (!annotationTypes.contains(annotationType)) {
annotationTypes.add(annotationType);
annotations.add(annotation);
@@ -116,14 +113,14 @@ public class ElementsImpl implements Elements {
* Compute a list of all the visible entities in this type. Specifically:
* <ul>
* <li>All nested types declared in this type, including interfaces and enums</li>
- * <li>All protected or public nested types declared in this type's superclasses
+ * <li>All protected or public nested types declared in this type's superclasses
* and superinterfaces, that are not hidden by a name collision</li>
* <li>All methods declared in this type, including constructors but not
* including static or instance initializers, and including abstract
* methods and unimplemented methods declared in interfaces</li>
* <li>All protected or public methods declared in this type's superclasses,
* that are not overridden by another method, but not including constructors
- * or initializers. Includes abstract methods and methods declared in
+ * or initializers. Includes abstract methods and methods declared in
* superinterfaces but not implemented</li>
* <li>All fields declared in this type, including constants</li>
* <li>All non-private fields declared in this type's superclasses and
@@ -169,7 +166,7 @@ public class ElementsImpl implements Elements {
}
return allMembers;
}
-
+
/**
* Recursively depth-first walk the tree of superinterfaces of a type, collecting
* all the unique superinterface bindings. (Note that because of generics, a type may
@@ -178,7 +175,7 @@ public class ElementsImpl implements Elements {
* @param existing bindings already in this set will not be re-added or recursed into
* @param newfound newly found bindings will be added to this set
*/
- private void collectSuperInterfaces(ReferenceBinding type,
+ private void collectSuperInterfaces(ReferenceBinding type,
Set<ReferenceBinding> existing, Set<ReferenceBinding> newfound) {
for (ReferenceBinding superinterface : type.superInterfaces()) {
if (!existing.contains(superinterface) && !newfound.contains(superinterface)) {
@@ -190,7 +187,7 @@ public class ElementsImpl implements Elements {
/**
* Add the members of a type to the maps of subtypes, fields, and methods. Add only those
- * which are non-private and which are not overridden by an already-discovered member.
+ * which are non-private and which are not overridden by an already-discovered member.
* For fields, add them all; javac implementation does not take field hiding into account.
* @param binding the type whose members will be added to the lists
* @param ignoreVisibility if true, all members will be added regardless of whether they
@@ -222,7 +219,7 @@ public class ElementsImpl implements Elements {
if (null == sameNamedMethods) {
// New method name. Create a set for it and add it to the list.
// We don't expect many methods with same name, so only 4 slots:
- sameNamedMethods = new HashSet<MethodBinding>(4);
+ sameNamedMethods = new HashSet<MethodBinding>(4);
methods.put(methodName, sameNamedMethods);
sameNamedMethods.add(method);
}
@@ -359,7 +356,7 @@ public class ElementsImpl implements Elements {
/**
* Strip the comment characters from a javadoc comment. Assume the comment is already
* missing its closing delimiter.
- *
+ *
* We mainly do not attempt to emulate the baroque behavior of javac with respect to
* treatment of whitespace. The rules here are simpler: eliminate the opening and
* closing delimiter, and eliminate [whitespace plus stars] at the beginning of each
@@ -369,12 +366,12 @@ public class ElementsImpl implements Elements {
* after the delimiter, but no non-whitespace chars, then delete the whitespace but
* preserve the newline; and so forth.
*/
- public static String formatJavadoc(char[] unparsed)
+ private static String formatJavadoc(char[] unparsed)
{
if (unparsed == null || unparsed.length < 5) { // delimiters take 5 chars
return null;
}
-
+
String[] lines = new String(unparsed).split("\n"); //$NON-NLS-1$
Matcher delimiterMatcher = INITIAL_DELIMITER.matcher(lines[0]);
if (!delimiterMatcher.find()) {
@@ -384,44 +381,129 @@ public class ElementsImpl implements Elements {
lines[0] = lines[0].substring(iOpener);
if (lines.length == 1) {
// single-line comment. Should trim(), but javac doesn't.
- return lines[0];
- }
-
- int firstLine = lines[0].trim().length() > 0 ? 0 : 1;
-
- // for each line after the first, including the last, if it starts with whitespace
- // followed by stars, skip all that.
- for (int line = 1; line < lines.length; ++line) {
- Matcher whitespaceMatcher = INITIAL_WHITESPACE_STARS.matcher(lines[line]);
- if (whitespaceMatcher.find()) {
- int firstAfterStars = whitespaceMatcher.end();
- lines[line] = lines[line].substring(firstAfterStars);
+ // we should however remove the starting whitespaces
+ StringBuilder sb = new StringBuilder();
+ char[] chars = lines[0].toCharArray();
+ boolean startingWhitespaces = true;
+ for (char c : chars) {
+ if (Character.isWhitespace(c))
+ if (startingWhitespaces) {
+ continue;
+ } else {
+ sb.append(c);
+ } else {
+ startingWhitespaces = false;
+ sb.append(c);
+ }
}
+ return sb.toString();
}
-
+
+ // if the first line ends with spaces after the /** then we want to insert a line separator
+ int firstLine = lines[0].trim().length() > 0 ? 0 : 1;
+
// If the last line is now empty, skip it
int lastLine = lines[lines.length - 1].trim().length() > 0 ? lines.length - 1 : lines.length - 2;
-
+
StringBuilder sb = new StringBuilder();
+ if (lines[0].length() != 0 && firstLine == 1) {
+ // insert a line separator only if the remaining chars on the line are whitespaces
+ sb.append('\n');
+ }
+ boolean preserveLineSeparator = lines[0].length() == 0;
for (int line = firstLine; line <= lastLine; ++line) {
char[] chars = lines[line].toCharArray();
- for (char c : chars) {
- if (c == '\t') {
- for (int i = 0; i < 8; i++) {
- sb.append(' ');
- }
- } else {
- sb.append(c);
+ int starsIndex = getStars(chars);
+ int leadingWhitespaces = 0;
+ boolean recordLeadingWhitespaces = true;
+ for (int i = 0, max = chars.length; i < max; i++) {
+ char c = chars[i];
+ switch(c) {
+ case '\t' :
+ if (starsIndex == -1) {
+ if (recordLeadingWhitespaces) {
+ leadingWhitespaces += 8;
+ } else {
+ sb.append(c);
+ }
+ } else if (i >= starsIndex) {
+ sb.append(c);
+ }
+ break;
+ case ' ' :
+ if (starsIndex == -1) {
+ if (recordLeadingWhitespaces) {
+ leadingWhitespaces++;
+ } else {
+ sb.append(c);
+ }
+ } else if (i >= starsIndex) {
+ sb.append(c);
+ }
+ break;
+ default :
+ // convert leadingwhitespaces to spaces
+ recordLeadingWhitespaces = false;
+ if (leadingWhitespaces != 0) {
+ int numberOfTabs = leadingWhitespaces / 8;
+ if (numberOfTabs != 0) {
+ for (int j = 0, max2 = numberOfTabs; j < max2; j++) {
+ sb.append(" "); //$NON-NLS-1$
+ }
+ if ((leadingWhitespaces % 8) >= 1) {
+ sb.append(' ');
+ }
+ } else if (line != 0) {
+ // we don't want to preserve the leading spaces for the first line
+ for (int j = 0, max2 = leadingWhitespaces; j < max2; j++) {
+ sb.append(' ');
+ }
+ }
+ leadingWhitespaces = 0;
+ sb.append(c);
+ } else if (c != '*' || i > starsIndex) {
+ sb.append(c);
+ }
}
}
+
// append a newline at the end of each line except the last, even if we skipped the last entirely
- if (line < lines.length - 1) {
+ int end = lines.length - 1;
+ if (line < end) {
+ sb.append('\n');
+ } else if (preserveLineSeparator && line == end) {
sb.append('\n');
}
}
return sb.toString();
}
-
+
+ /**
+ * Returns the index of the last leading stars on this line, -1 if none.
+ *
+ * @param line the given line
+ * @return the computed index
+ */
+ private static int getStars(char[] line) {
+ loop: for (int i = 0, max = line.length; i < max; i++) {
+ char c = line[i];
+ if (!Character.isWhitespace(c)) {
+ if (c == '*') {
+ // only whitespaces before the first star
+ // consume all stars and return the last index
+ for (int j = i + 1; j < max; j++) {
+ if (line[j] != '*') {
+ return j;
+ }
+ }
+ return max - 1;
+ }
+ // no need to continue
+ break loop;
+ }
+ }
+ return -1;
+ }
/**
* @return all the annotation instance's explicitly set values, plus default values
* for all the annotation members that are not explicitly set but that have
@@ -507,7 +589,7 @@ public class ElementsImpl implements Elements {
// try finding the top-level type and then working downwards.
if (null == binding) {
ReferenceBinding topLevelBinding = null;
- int topLevelSegments = compoundName.length;
+ int topLevelSegments = compoundName.length;
while (--topLevelSegments > 0) {
char[][] topLevelName = new char[topLevelSegments][];
for (int i = 0; i < topLevelSegments; ++i) {
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/EclipseFileManager.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/EclipseFileManager.java
index 8885910ade..f61911aba9 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/EclipseFileManager.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/EclipseFileManager.java
@@ -18,12 +18,15 @@ import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.Charset;
+import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.zip.ZipException;
@@ -34,9 +37,13 @@ import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.JavaFileObject.Kind;
+import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.compiler.InvalidInputException;
import org.eclipse.jdt.internal.compiler.batch.FileSystem;
import org.eclipse.jdt.internal.compiler.batch.Main;
+import org.eclipse.jdt.internal.compiler.batch.Main.ResourceBundleFactory;
+import org.eclipse.jdt.internal.compiler.env.AccessRule;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
/**
* Implementation of the Standard Java File Manager
@@ -52,18 +59,14 @@ public class EclipseFileManager implements StandardJavaFileManager {
Charset charset;
Locale locale;
Map<String, Iterable<? extends File>> locations;
- Main compiler;
int flags;
+ public ResourceBundle bundle;
- public EclipseFileManager(Main eclipseCompiler, Locale locale, Charset charset) {
- this.compiler = eclipseCompiler;
+ public EclipseFileManager(Locale locale, Charset charset) {
this.locale = locale == null ? Locale.getDefault() : locale;
this.charset = charset == null ? Charset.defaultCharset() : charset;
this.locations = new HashMap<String, Iterable<? extends File>>();
this.archivesCache = new HashMap<File, Archive>();
- if (locale != null) {
- this.compiler.setLocale(locale);
- }
try {
this.setLocation(StandardLocation.PLATFORM_CLASS_PATH, getDefaultBootclasspath());
Iterable<? extends File> defaultClasspath = getDefaultClasspath();
@@ -72,6 +75,11 @@ public class EclipseFileManager implements StandardJavaFileManager {
} catch (IOException e) {
// ignore
}
+ try {
+ this.bundle = ResourceBundleFactory.getBundle(this.locale);
+ } catch(MissingResourceException e) {
+ System.out.println("Missing resource : " + Main.bundleName.replace('.', '/') + ".properties for locale " + locale); //$NON-NLS-1$//$NON-NLS-2$
+ }
}
private void addFiles(File[][] jars, ArrayList<File> files) {
@@ -266,7 +274,7 @@ public class EclipseFileManager implements StandardJavaFileManager {
ArrayList<FileSystem.Classpath> paths = new ArrayList<FileSystem.Classpath>();
ArrayList<File> files = new ArrayList<File>();
try {
- this.compiler.processPathEntries(Main.DEFAULT_SIZE_CLASSPATH, paths, path, this.charset.toString(), false, false);
+ this.processPathEntries(Main.DEFAULT_SIZE_CLASSPATH, paths, path, this.charset.toString(), false, false);
} catch (InvalidInputException e) {
return null;
}
@@ -287,21 +295,28 @@ public class EclipseFileManager implements StandardJavaFileManager {
/*
* Handle >= JDK 1.6
*/
- File javaHome = this.compiler.getJavaHome();
- addFilesFrom(javaHome, "java.endorsed.dirs", "/lib/endorsed", files);//$NON-NLS-1$//$NON-NLS-2$
+ String javaHome = System.getProperty("java.home"); //$NON-NLS-1$
+ File javaHomeFile = null;
if (javaHome != null) {
+ javaHomeFile = new File(javaHome);
+ if (!javaHomeFile.exists())
+ javaHomeFile = null;
+ }
+
+ addFilesFrom(javaHomeFile, "java.endorsed.dirs", "/lib/endorsed", files);//$NON-NLS-1$//$NON-NLS-2$
+ if (javaHomeFile != null) {
File[] directoriesToCheck = null;
if (System.getProperty("os.name").startsWith("Mac")) {//$NON-NLS-1$//$NON-NLS-2$
- directoriesToCheck = new File[] { new File(javaHome, "../Classes"), //$NON-NLS-1$
+ directoriesToCheck = new File[] { new File(javaHomeFile, "../Classes"), //$NON-NLS-1$
};
} else {
- directoriesToCheck = new File[] { new File(javaHome, "lib") //$NON-NLS-1$
+ directoriesToCheck = new File[] { new File(javaHomeFile, "lib") //$NON-NLS-1$
};
}
File[][] jars = Main.getLibrariesFiles(directoriesToCheck);
addFiles(jars, files);
}
- addFilesFrom(javaHome, "java.ext.dirs", "/lib/ext", files);//$NON-NLS-1$//$NON-NLS-2$
+ addFilesFrom(javaHomeFile, "java.ext.dirs", "/lib/ext", files);//$NON-NLS-1$//$NON-NLS-2$
return files;
}
@@ -329,7 +344,7 @@ public class EclipseFileManager implements StandardJavaFileManager {
ArrayList<FileSystem.Classpath> paths = new ArrayList<FileSystem.Classpath>();
ArrayList<File> files = new ArrayList<File>();
try {
- this.compiler.processPathEntries(Main.DEFAULT_SIZE_CLASSPATH, paths, path, this.charset.toString(), false, false);
+ this.processPathEntries(Main.DEFAULT_SIZE_CLASSPATH, paths, path, this.charset.toString(), false, false);
} catch (InvalidInputException e) {
return null;
}
@@ -343,7 +358,7 @@ public class EclipseFileManager implements StandardJavaFileManager {
ArrayList<FileSystem.Classpath> paths = new ArrayList<FileSystem.Classpath>();
ArrayList<File> files = new ArrayList<File>();
try {
- this.compiler.processPathEntries(Main.DEFAULT_SIZE_CLASSPATH, paths, path, this.charset.toString(), false, false);
+ this.processPathEntries(Main.DEFAULT_SIZE_CLASSPATH, paths, path, this.charset.toString(), false, false);
} catch (InvalidInputException e) {
return null;
}
@@ -838,6 +853,299 @@ public class EclipseFileManager implements StandardJavaFileManager {
}
public void setLocale(Locale locale) {
- this.locale = locale;
+ this.locale = locale == null ? Locale.getDefault() : locale;
+ try {
+ this.bundle = ResourceBundleFactory.getBundle(this.locale);
+ } catch(MissingResourceException e) {
+ System.out.println("Missing resource : " + Main.bundleName.replace('.', '/') + ".properties for locale " + locale); //$NON-NLS-1$//$NON-NLS-2$
+ throw e;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void processPathEntries(final int defaultSize, final ArrayList paths,
+ final String currentPath, String customEncoding, boolean isSourceOnly,
+ boolean rejectDestinationPathOnJars)
+ throws InvalidInputException {
+ String currentClasspathName = null;
+ String currentDestinationPath = null;
+ ArrayList currentRuleSpecs = new ArrayList(defaultSize);
+ StringTokenizer tokenizer = new StringTokenizer(currentPath,
+ File.pathSeparator + "[]", true); //$NON-NLS-1$
+ ArrayList tokens = new ArrayList();
+ while (tokenizer.hasMoreTokens()) {
+ tokens.add(tokenizer.nextToken());
+ }
+ // state machine
+ final int start = 0;
+ final int readyToClose = 1;
+ // 'path' 'path1[rule];path2'
+ final int readyToCloseEndingWithRules = 2;
+ // 'path[rule]' 'path1;path2[rule]'
+ final int readyToCloseOrOtherEntry = 3;
+ // 'path[rule];' 'path;' 'path1;path2;'
+ final int rulesNeedAnotherRule = 4;
+ // 'path[rule1;'
+ final int rulesStart = 5;
+ // 'path[' 'path1;path2['
+ final int rulesReadyToClose = 6;
+ // 'path[rule' 'path[rule1;rule2'
+ final int destinationPathReadyToClose = 7;
+ // 'path[-d bin'
+ final int readyToCloseEndingWithDestinationPath = 8;
+ // 'path[-d bin]' 'path[rule][-d bin]'
+ final int destinationPathStart = 9;
+ // 'path[rule]['
+ final int bracketOpened = 10;
+ // '.*[.*'
+ final int bracketClosed = 11;
+ // '.*([.*])+'
+
+ final int error = 99;
+ int state = start;
+ String token = null;
+ int cursor = 0, tokensNb = tokens.size(), bracket = -1;
+ while (cursor < tokensNb && state != error) {
+ token = (String) tokens.get(cursor++);
+ if (token.equals(File.pathSeparator)) {
+ switch (state) {
+ case start:
+ case readyToCloseOrOtherEntry:
+ case bracketOpened:
+ break;
+ case readyToClose:
+ case readyToCloseEndingWithRules:
+ case readyToCloseEndingWithDestinationPath:
+ state = readyToCloseOrOtherEntry;
+ addNewEntry(paths, currentClasspathName, currentRuleSpecs,
+ customEncoding, currentDestinationPath, isSourceOnly,
+ rejectDestinationPathOnJars);
+ currentRuleSpecs.clear();
+ break;
+ case rulesReadyToClose:
+ state = rulesNeedAnotherRule;
+ break;
+ case destinationPathReadyToClose:
+ throw new InvalidInputException(
+ this.bind("configure.incorrectDestinationPathEntry", //$NON-NLS-1$
+ currentPath));
+ case bracketClosed:
+ cursor = bracket + 1;
+ state = rulesStart;
+ break;
+ default:
+ state = error;
+ }
+ } else if (token.equals("[")) { //$NON-NLS-1$
+ switch (state) {
+ case start:
+ currentClasspathName = ""; //$NON-NLS-1$
+ case readyToClose:
+ bracket = cursor - 1;
+ case bracketClosed:
+ state = bracketOpened;
+ break;
+ case readyToCloseEndingWithRules:
+ state = destinationPathStart;
+ break;
+ case readyToCloseEndingWithDestinationPath:
+ state = rulesStart;
+ break;
+ case bracketOpened:
+ default:
+ state = error;
+ }
+ } else if (token.equals("]")) { //$NON-NLS-1$
+ switch (state) {
+ case rulesReadyToClose:
+ state = readyToCloseEndingWithRules;
+ break;
+ case destinationPathReadyToClose:
+ state = readyToCloseEndingWithDestinationPath;
+ break;
+ case bracketOpened:
+ state = bracketClosed;
+ break;
+ case bracketClosed:
+ default:
+ state = error;
+ }
+ } else {
+ // regular word
+ switch (state) {
+ case start:
+ case readyToCloseOrOtherEntry:
+ state = readyToClose;
+ currentClasspathName = token;
+ break;
+ case rulesStart:
+ if (token.startsWith("-d ")) { //$NON-NLS-1$
+ if (currentDestinationPath != null) {
+ throw new InvalidInputException(
+ this.bind("configure.duplicateDestinationPathEntry", //$NON-NLS-1$
+ currentPath));
+ }
+ currentDestinationPath = token.substring(3).trim();
+ state = destinationPathReadyToClose;
+ break;
+ } // else we proceed with a rule
+ case rulesNeedAnotherRule:
+ if (currentDestinationPath != null) {
+ throw new InvalidInputException(
+ this.bind("configure.accessRuleAfterDestinationPath", //$NON-NLS-1$
+ currentPath));
+ }
+ state = rulesReadyToClose;
+ currentRuleSpecs.add(token);
+ break;
+ case destinationPathStart:
+ if (!token.startsWith("-d ")) { //$NON-NLS-1$
+ state = error;
+ } else {
+ currentDestinationPath = token.substring(3).trim();
+ state = destinationPathReadyToClose;
+ }
+ break;
+ case bracketClosed:
+ for (int i = bracket; i < cursor ; i++) {
+ currentClasspathName += (String) tokens.get(i);
+ }
+ state = readyToClose;
+ break;
+ case bracketOpened:
+ break;
+ default:
+ state = error;
+ }
+ }
+ if (state == bracketClosed && cursor == tokensNb) {
+ cursor = bracket + 1;
+ state = rulesStart;
+ }
+ }
+ switch(state) {
+ case readyToCloseOrOtherEntry:
+ break;
+ case readyToClose:
+ case readyToCloseEndingWithRules:
+ case readyToCloseEndingWithDestinationPath:
+ addNewEntry(paths, currentClasspathName, currentRuleSpecs,
+ customEncoding, currentDestinationPath, isSourceOnly,
+ rejectDestinationPathOnJars);
+ break;
+ case bracketOpened:
+ case bracketClosed:
+ default :
+ // we go on anyway
+ }
+ }
+ @SuppressWarnings("unchecked")
+ protected void addNewEntry(ArrayList paths, String currentClasspathName,
+ ArrayList currentRuleSpecs, String customEncoding,
+ String destPath, boolean isSourceOnly,
+ boolean rejectDestinationPathOnJars) throws InvalidInputException {
+
+ int rulesSpecsSize = currentRuleSpecs.size();
+ AccessRuleSet accessRuleSet = null;
+ if (rulesSpecsSize != 0) {
+ AccessRule[] accessRules = new AccessRule[currentRuleSpecs.size()];
+ boolean rulesOK = true;
+ Iterator i = currentRuleSpecs.iterator();
+ int j = 0;
+ while (i.hasNext()) {
+ String ruleSpec = (String) i.next();
+ char key = ruleSpec.charAt(0);
+ String pattern = ruleSpec.substring(1);
+ if (pattern.length() > 0) {
+ switch (key) {
+ case '+':
+ accessRules[j++] = new AccessRule(pattern
+ .toCharArray(), 0);
+ break;
+ case '~':
+ accessRules[j++] = new AccessRule(pattern
+ .toCharArray(),
+ IProblem.DiscouragedReference);
+ break;
+ case '-':
+ accessRules[j++] = new AccessRule(pattern
+ .toCharArray(),
+ IProblem.ForbiddenReference);
+ break;
+ case '?':
+ accessRules[j++] = new AccessRule(pattern
+ .toCharArray(),
+ IProblem.ForbiddenReference, true/*keep looking for accessible type*/);
+ break;
+ default:
+ rulesOK = false;
+ }
+ } else {
+ rulesOK = false;
+ }
+ }
+ if (rulesOK) {
+ String templates[] = new String[AccessRuleSet.MESSAGE_TEMPLATES_LENGTH];
+ templates[0] = this.bind(
+ "template.restrictedAccess.type", //$NON-NLS-1$
+ new String[] {"{0}", currentClasspathName}); //$NON-NLS-1$
+ templates[1] = this.bind(
+ "template.restrictedAccess.constructor", //$NON-NLS-1$
+ new String[] {"{0}", currentClasspathName}); //$NON-NLS-1$
+ templates[2] = this.bind(
+ "template.restrictedAccess.method", //$NON-NLS-1$
+ new String[] {"{0}", "{1}", currentClasspathName}); //$NON-NLS-1$ //$NON-NLS-2$
+ templates[3] = this.bind(
+ "template.restrictedAccess.field", //$NON-NLS-1$
+ new String[] {"{0}", "{1}", currentClasspathName}); //$NON-NLS-1$ //$NON-NLS-2$
+ accessRuleSet = new AccessRuleSet(accessRules, templates);
+ } else {
+ return;
+ }
+ }
+ if (Main.NONE.equals(destPath)) {
+ destPath = Main.NONE; // keep == comparison valid
+ }
+ if (rejectDestinationPathOnJars && destPath != null &&
+ (currentClasspathName.endsWith(".jar") || //$NON-NLS-1$
+ currentClasspathName.endsWith(".zip"))) { //$NON-NLS-1$
+ throw new InvalidInputException(
+ this.bind("configure.unexpectedDestinationPathEntryFile", //$NON-NLS-1$
+ currentClasspathName));
+ }
+ FileSystem.Classpath currentClasspath = FileSystem.getClasspath(
+ currentClasspathName,
+ customEncoding,
+ isSourceOnly,
+ accessRuleSet,
+ destPath);
+ if (currentClasspath != null) {
+ paths.add(currentClasspath);
+ }
+ }
+ /*
+ * Lookup the message with the given ID in this catalog and bind its
+ * substitution locations with the given string.
+ */
+ private String bind(String id, String binding) {
+ return bind(id, new String[] { binding });
+ }
+
+ /*
+ * Lookup the message with the given ID in this catalog and bind its
+ * substitution locations with the given string values.
+ */
+ private String bind(String id, String[] arguments) {
+ if (id == null)
+ return "No message available"; //$NON-NLS-1$
+ String message = null;
+ try {
+ message = this.bundle.getString(id);
+ } catch (MissingResourceException e) {
+ // If we got an exception looking for the message, fail gracefully by just returning
+ // the id we were looking for. In most cases this is semi-informative so is not too bad.
+ return "Missing message: " + id + " in: " + Main.bundleName; //$NON-NLS-2$ //$NON-NLS-1$
+ }
+ return MessageFormat.format(message, (Object[]) arguments);
}
}
diff --git a/org.eclipse.jdt.compiler.tool/META-INF/MANIFEST.MF b/org.eclipse.jdt.compiler.tool/META-INF/MANIFEST.MF
index 6519d9450b..cd38e6f1cd 100644
--- a/org.eclipse.jdt.compiler.tool/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.compiler.tool/META-INF/MANIFEST.MF
@@ -8,4 +8,4 @@ Bundle-Localization: compiler_tool_fragment
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Export-Package: META-INF.services,
org.eclipse.jdt.internal.compiler.tool
-Fragment-Host: org.eclipse.jdt.core;bundle-version="3.3.0"
+Fragment-Host: org.eclipse.jdt.core;bundle-version="[3.3.0,4.0.0)"
diff --git a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompiler.java b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompiler.java
index 5d1bfdc6e8..fee67028e1 100644
--- a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompiler.java
+++ b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompiler.java
@@ -10,9 +10,7 @@
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.tool;
-import java.io.BufferedOutputStream;
import java.io.File;
-import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
@@ -22,48 +20,29 @@ import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
-import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
-import java.util.Map;
import java.util.Set;
+import java.util.WeakHashMap;
import javax.annotation.processing.Processor;
import javax.lang.model.SourceVersion;
import javax.tools.DiagnosticListener;
-import javax.tools.Diagnostic;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
-import org.eclipse.jdt.core.compiler.CategorizedProblem;
-import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.compiler.InvalidInputException;
-import org.eclipse.jdt.internal.compiler.ClassFile;
-import org.eclipse.jdt.internal.compiler.CompilationResult;
-import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
-import org.eclipse.jdt.internal.compiler.IProblemFactory;
-import org.eclipse.jdt.internal.compiler.batch.CompilationUnit;
-import org.eclipse.jdt.internal.compiler.batch.FileSystem;
import org.eclipse.jdt.internal.compiler.batch.Main;
-import org.eclipse.jdt.internal.compiler.batch.FileSystem.Classpath;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
-import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
-import org.eclipse.jdt.internal.compiler.problem.AbortCompilationUnit;
-import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
-import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
-import org.eclipse.jdt.internal.compiler.util.Messages;
-import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
/**
* Implementation of a batch compiler that supports the jsr199
*/
-public class EclipseCompiler extends Main implements JavaCompiler {
+public class EclipseCompiler implements JavaCompiler {
- private static final CompilationUnit[] NO_UNITS = new CompilationUnit[0];
- private HashMap<CompilationUnit, JavaFileObject> javaFileObjectMap;
private static Set<SourceVersion> SupportedSourceVersions;
static {
// Eclipse compiler supports all possible versions from version 0 to
@@ -74,180 +53,13 @@ public class EclipseCompiler extends Main implements JavaCompiler {
SupportedSourceVersions = Collections.unmodifiableSet(enumSet);
}
- Iterable<? extends JavaFileObject> compilationUnits;
+ WeakHashMap<Thread, EclipseCompilerImpl> threadCache;
public DiagnosticListener<? super JavaFileObject> diagnosticListener;
- public JavaFileManager fileManager;
- protected Processor[] processors;
-
- public EclipseCompiler(PrintWriter out, PrintWriter err, boolean systemExitWhenFinished) {
- super(out, err, systemExitWhenFinished);
- }
public EclipseCompiler() {
- super(null, null, false);
- }
-
- public boolean call() {
- try {
- if (this.proceed) {
- this.globalProblemsCount = 0;
- this.globalErrorsCount = 0;
- this.globalWarningsCount = 0;
- this.globalTasksCount = 0;
- this.lineCount = 0;
- this.exportedClassFilesCounter = 0;
- // request compilation
- performCompilation();
- }
- } catch (InvalidInputException e) {
- this.logger.logException(e);
- if (this.systemExitWhenFinished) {
- cleanup();
- System.exit(-1);
- }
- return false;
- } catch(IllegalArgumentException e) {
- throw e;
- } catch (RuntimeException e) { // internal compiler failure
- this.logger.logException(e);
- return false;
- } finally {
- cleanup();
- }
- if (this.globalErrorsCount == 0)
- return true;
- return false;
- }
-
- private void cleanup() {
- this.logger.flush();
- this.logger.close();
- this.processors = null;
- try {
- if (this.fileManager != null) {
- this.fileManager.flush();
- }
- } catch (IOException e) {
- // ignore
- }
- }
-
- public CompilationUnit[] getCompilationUnits() {
- if (this.compilationUnits == null) return NO_UNITS;
- ArrayList<CompilationUnit> units = new ArrayList<CompilationUnit>();
- for (final JavaFileObject javaFileObject : this.compilationUnits) {
- if (javaFileObject.getKind() != JavaFileObject.Kind.SOURCE) {
- throw new IllegalArgumentException();
- }
- String name = javaFileObject.getName();
- name = name.replace('\\', '/');
- CompilationUnit compilationUnit = new CompilationUnit(null,
- name,
- null) {
-
- public char[] getContents() {
- try {
- return javaFileObject.getCharContent(true).toString().toCharArray();
- } catch(IOException e) {
- e.printStackTrace();
- throw new AbortCompilationUnit(null, e, null);
- }
- }
- };
- units.add(compilationUnit);
- this.javaFileObjectMap.put(compilationUnit, javaFileObject);
- }
- CompilationUnit[] result = new CompilationUnit[units.size()];
- units.toArray(result);
- return result;
+ this.threadCache = new WeakHashMap<Thread, EclipseCompilerImpl>();
}
/*
- * Low-level API performing the actual compilation
- */
- public IErrorHandlingPolicy getHandlingPolicy() {
- // passes the initial set of files to the batch oracle (to avoid finding more than once the same units when case insensitive match)
- return new IErrorHandlingPolicy() {
- public boolean proceedOnErrors() {
- return false; // stop if there are some errors
- }
- public boolean stopOnFirstError() {
- return false;
- }
- };
- }
-
- public IProblemFactory getProblemFactory() {
- return new DefaultProblemFactory() {
- @Override
- public CategorizedProblem createProblem(
- final char[] originatingFileName,
- final int problemId,
- final String[] problemArguments,
- final String[] messageArguments,
- final int severity,
- final int startPosition,
- final int endPosition,
- final int lineNumber,
- final int columnNumber) {
-
- DiagnosticListener<? super JavaFileObject> diagnosticListener = EclipseCompiler.this.diagnosticListener;
- if (diagnosticListener != null) {
- diagnosticListener.report(new Diagnostic<JavaFileObject>() {
- public String getCode() {
- return Integer.toString(problemId);
- }
- public long getColumnNumber() {
- return columnNumber;
- }
- public long getEndPosition() {
- return endPosition;
- }
- public Kind getKind() {
- if ((severity & ProblemSeverities.Error) != 0) {
- return Diagnostic.Kind.ERROR;
- }
- if ((severity & ProblemSeverities.Optional) != 0) {
- return Diagnostic.Kind.WARNING;
- }
- if ((severity & ProblemSeverities.Warning) != 0) {
- return Diagnostic.Kind.MANDATORY_WARNING;
- }
- return Diagnostic.Kind.OTHER;
- }
- public long getLineNumber() {
- return lineNumber;
- }
- public String getMessage(Locale locale) {
- setLocale(locale);
- return getLocalizedMessage(problemId, problemArguments);
- }
- public long getPosition() {
- return startPosition;
- }
- public JavaFileObject getSource() {
- try {
- if (EclipseCompiler.this.fileManager.hasLocation(StandardLocation.SOURCE_PATH)) {
- return EclipseCompiler.this.fileManager.getJavaFileForInput(
- StandardLocation.SOURCE_PATH,
- new String(originatingFileName),
- JavaFileObject.Kind.SOURCE);
- }
- } catch (IOException e) {
- // ignore
- }
- return null;
- }
- public long getStartPosition() {
- return startPosition;
- }
- });
- }
- return super.createProblem(originatingFileName, problemId, problemArguments, messageArguments, severity, startPosition, endPosition, lineNumber, columnNumber);
- }
- };
- }
-
- /*
* (non-Javadoc)
*
* @see javax.tools.Tool#getSourceVersions()
@@ -265,7 +77,7 @@ public class EclipseCompiler extends Main implements JavaCompiler {
Locale locale,
Charset charset) {
this.diagnosticListener = diagnosticListener;
- return new EclipseFileManager(this, locale, charset);
+ return new EclipseFileManager(locale, charset);
}
/*
* (non-Javadoc)
@@ -291,23 +103,31 @@ public class EclipseCompiler extends Main implements JavaCompiler {
writerOut = new PrintWriter(out);
writerErr = new PrintWriter(out);
}
- this.compilationUnits = compilationUnits;
- this.diagnosticListener = diagnosticListener;
+ final Thread currentThread = Thread.currentThread();
+ EclipseCompilerImpl eclipseCompiler = this.threadCache.get(currentThread);
+ if (eclipseCompiler == null) {
+ eclipseCompiler = new EclipseCompilerImpl(writerOut, writerErr, false);
+ this.threadCache.put(currentThread, eclipseCompiler);
+ } else {
+ eclipseCompiler.initialize(writerOut, writerErr, false, null);
+ }
+ final EclipseCompilerImpl eclipseCompiler2 = new EclipseCompilerImpl(writerOut, writerErr, false);
+ eclipseCompiler2.compilationUnits = compilationUnits;
+ eclipseCompiler2.diagnosticListener = diagnosticListener;
if (fileManager != null) {
- this.fileManager = fileManager;
+ eclipseCompiler2.fileManager = fileManager;
} else {
- this.fileManager = this.getStandardFileManager(diagnosticListener, null, null);
+ eclipseCompiler2.fileManager = this.getStandardFileManager(diagnosticListener, null, null);
}
- initialize(writerOut, writerErr, false);
- this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_6);
- this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_6);
- this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
+ eclipseCompiler2.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_6);
+ eclipseCompiler2.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_6);
+ eclipseCompiler2.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
ArrayList<String> allOptions = new ArrayList<String>();
if (options != null) {
for (Iterator<String> iterator = options.iterator(); iterator.hasNext(); ) {
- this.fileManager.handleOption(iterator.next(), iterator);
+ eclipseCompiler2.fileManager.handleOption(iterator.next(), iterator);
}
for (String option : options) {
allOptions.add(option);
@@ -337,17 +157,17 @@ public class EclipseCompiler extends Main implements JavaCompiler {
final String[] optionsToProcess = new String[allOptions.size()];
allOptions.toArray(optionsToProcess);
try {
- this.configure(optionsToProcess);
+ eclipseCompiler2.configure(optionsToProcess);
} catch (InvalidInputException e) {
throw new RuntimeException(e);
}
- if (this.fileManager instanceof StandardJavaFileManager) {
- StandardJavaFileManager javaFileManager = (StandardJavaFileManager) this.fileManager;
+ if (eclipseCompiler2.fileManager instanceof StandardJavaFileManager) {
+ StandardJavaFileManager javaFileManager = (StandardJavaFileManager) eclipseCompiler2.fileManager;
Iterable<? extends File> location = javaFileManager.getLocation(StandardLocation.CLASS_OUTPUT);
if (location != null) {
- this.setDestinationPath(location.iterator().next().getAbsolutePath());
+ eclipseCompiler2.setDestinationPath(location.iterator().next().getAbsolutePath());
}
}
@@ -358,12 +178,12 @@ public class EclipseCompiler extends Main implements JavaCompiler {
if (this.hasRun) {
throw new IllegalStateException("This task has already been run"); //$NON-NLS-1$
}
- Boolean value = EclipseCompiler.this.call() ? Boolean.TRUE : Boolean.FALSE;
+ Boolean value = eclipseCompiler2.call() ? Boolean.TRUE : Boolean.FALSE;
this.hasRun = true;
return value;
}
public void setLocale(Locale locale) {
- EclipseCompiler.this.setLocale(locale);
+ eclipseCompiler2.setLocale(locale);
}
public void setProcessors(Iterable<? extends Processor> processors) {
ArrayList<Processor> temp = new ArrayList<Processor>();
@@ -372,28 +192,10 @@ public class EclipseCompiler extends Main implements JavaCompiler {
}
Processor[] processors2 = new Processor[temp.size()];
temp.toArray(processors2);
- EclipseCompiler.this.processors = processors2;
+ eclipseCompiler2.processors = processors2;
}
};
}
-
- @Override
- @SuppressWarnings("unchecked")
- protected void initialize(PrintWriter outWriter, PrintWriter errWriter, boolean systemExit, Map customDefaultOptions) {
- super.initialize(outWriter, errWriter, systemExit, customDefaultOptions);
- this.javaFileObjectMap = new HashMap<CompilationUnit, JavaFileObject>();
- }
-
- @Override
- protected void initializeAnnotationProcessorManager() {
- super.initializeAnnotationProcessorManager();
- if (this.batchCompiler.annotationProcessorManager != null && this.processors != null) {
- this.batchCompiler.annotationProcessorManager.setProcessors(this.processors);
- } else if (this.processors != null) {
- throw new UnsupportedOperationException("Cannot handle annotation processing"); //$NON-NLS-1$
- }
- }
-
/*
* (non-Javadoc)
*
@@ -403,84 +205,6 @@ public class EclipseCompiler extends Main implements JavaCompiler {
return Options.processOptions(option);
}
- // Dump classfiles onto disk for all compilation units that where successful
- // and do not carry a -d none spec, either directly or inherited from Main.
- public void outputClassFiles(CompilationResult unitResult) {
- if (!((unitResult == null) || (unitResult.hasErrors() && !this.proceedOnError))) {
- ClassFile[] classFiles = unitResult.getClassFiles();
- boolean generateClasspathStructure = this.fileManager.hasLocation(StandardLocation.CLASS_OUTPUT);
- String currentDestinationPath = this.destinationPath;
- File outputLocation = null;
- if (currentDestinationPath != null) {
- outputLocation = new File(currentDestinationPath);
- outputLocation.mkdirs();
- }
- for (int i = 0, fileCount = classFiles.length; i < fileCount; i++) {
- // retrieve the key and the corresponding classfile
- ClassFile classFile = classFiles[i];
- char[] filename = classFile.fileName();
- int length = filename.length;
- char[] relativeName = new char[length + 6];
- System.arraycopy(filename, 0, relativeName, 0, length);
- System.arraycopy(SuffixConstants.SUFFIX_class, 0, relativeName, length, 6);
- CharOperation.replace(relativeName, '/', File.separatorChar);
- String relativeStringName = new String(relativeName);
- if (this.compilerOptions.verbose) {
- EclipseCompiler.this.out.println(
- Messages.bind(
- Messages.compilation_write,
- new String[] {
- String.valueOf(this.exportedClassFilesCounter+1),
- relativeStringName
- }));
- }
- try {
- JavaFileObject javaFileForOutput =
- this.fileManager.getJavaFileForOutput(
- StandardLocation.CLASS_OUTPUT,
- new String(filename),
- JavaFileObject.Kind.CLASS,
- this.javaFileObjectMap.get(unitResult.compilationUnit));
-
- if (generateClasspathStructure) {
- if (currentDestinationPath != null) {
- int index = CharOperation.lastIndexOf(File.separatorChar, relativeName);
- if (index != -1) {
- File currentFolder = new File(currentDestinationPath, relativeStringName.substring(0, index));
- currentFolder.mkdirs();
- }
- } else {
- // create the subfolfers is necessary
- // need a way to retrieve the folders to create
- String path = javaFileForOutput.toUri().getPath();
- int index = path.lastIndexOf('/');
- if (index != -1) {
- File file = new File(path.substring(0, index));
- file.mkdirs();
- }
- }
- }
-
- OutputStream openOutputStream = javaFileForOutput.openOutputStream();
- BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(openOutputStream);
- bufferedOutputStream.write(classFile.header, 0, classFile.headerOffset);
- bufferedOutputStream.write(classFile.contents, 0, classFile.contentsOffset);
- bufferedOutputStream.flush();
- bufferedOutputStream.close();
- } catch (IOException e) {
- this.logger.logNoClassFileCreated(currentDestinationPath, relativeStringName, e);
- }
- LookupEnvironment env = EclipseCompiler.this.batchCompiler.lookupEnvironment;
- if (classFile.isShared) env.classFilePool.release(classFile);
- this.logger.logClassFile(
- generateClasspathStructure,
- currentDestinationPath,
- relativeStringName);
- this.exportedClassFilesCounter++;
- }
- }
- }
-
/*
* (non-Javadoc)
*
@@ -491,95 +215,4 @@ public class EclipseCompiler extends Main implements JavaCompiler {
boolean succeed = new Main(new PrintWriter(new OutputStreamWriter(out)), new PrintWriter(new OutputStreamWriter(err)), true).compile(arguments);
return succeed ? 0 : -1;
}
-
- @Override
- @SuppressWarnings("unchecked")
- protected void setPaths(ArrayList bootclasspaths,
- String sourcepathClasspathArg,
- ArrayList sourcepathClasspaths,
- ArrayList classpaths,
- ArrayList extdirsClasspaths,
- ArrayList endorsedDirClasspaths,
- String customEncoding) throws InvalidInputException {
-
- ArrayList<FileSystem.Classpath> fileSystemClasspaths = new ArrayList<FileSystem.Classpath>();
- EclipseFileManager javaFileManager = null;
- StandardJavaFileManager standardJavaFileManager = null;
- if (this.fileManager instanceof EclipseFileManager) {
- javaFileManager = (EclipseFileManager) this.fileManager;
- }
- if (this.fileManager instanceof StandardJavaFileManager) {
- standardJavaFileManager = (StandardJavaFileManager) this.fileManager;
- }
-
- if (javaFileManager != null) {
- if ((javaFileManager.flags & EclipseFileManager.HAS_ENDORSED_DIRS) == 0
- && (javaFileManager.flags & EclipseFileManager.HAS_BOOTCLASSPATH) != 0) {
- fileSystemClasspaths.addAll((ArrayList<? extends FileSystem.Classpath>) this.handleEndorseddirs(null));
- }
- }
- Iterable<? extends File> location = null;
- if (standardJavaFileManager != null) {
- location = standardJavaFileManager.getLocation(StandardLocation.PLATFORM_CLASS_PATH);
- }
- if (location != null) {
- for (File file : location) {
- Classpath classpath = FileSystem.getClasspath(
- file.getAbsolutePath(),
- null,
- null);
- if (classpath != null) {
- fileSystemClasspaths.add(classpath);
- }
- }
- }
- if (javaFileManager != null) {
- if ((javaFileManager.flags & EclipseFileManager.HAS_EXT_DIRS) == 0
- && (javaFileManager.flags & EclipseFileManager.HAS_BOOTCLASSPATH) != 0) {
- fileSystemClasspaths.addAll((ArrayList<? extends FileSystem.Classpath>) this.handleExtdirs(null));
- }
- }
- if (standardJavaFileManager != null) {
- location = standardJavaFileManager.getLocation(StandardLocation.SOURCE_PATH);
- } else {
- location = null;
- }
- if (location != null) {
- for (File file : location) {
- fileSystemClasspaths.add(FileSystem.getClasspath(
- file.getAbsolutePath(),
- null,
- null));
- }
- }
- if (standardJavaFileManager != null) {
- location = standardJavaFileManager.getLocation(StandardLocation.CLASS_PATH);
- } else {
- location = null;
- }
- if (location != null) {
- for (File file : location) {
- Classpath classpath = FileSystem.getClasspath(
- file.getAbsolutePath(),
- null,
- null);
- if (classpath != null) {
- fileSystemClasspaths.add(classpath);
- }
- }
- }
- if (this.checkedClasspaths == null) {
- fileSystemClasspaths.addAll((ArrayList<? extends FileSystem.Classpath>) this.handleBootclasspath(null, null));
- fileSystemClasspaths.addAll((ArrayList<? extends FileSystem.Classpath>) this.handleClasspath(null, null));
- }
- fileSystemClasspaths = FileSystem.ClasspathNormalizer.normalize(fileSystemClasspaths);
- final int size = fileSystemClasspaths.size();
- if (size != 0) {
- this.checkedClasspaths = new FileSystem.Classpath[size];
- int i = 0;
- for (FileSystem.Classpath classpath : fileSystemClasspaths) {
- this.checkedClasspaths[i++] = classpath;
- }
- }
- }
}
diff --git a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompilerImpl.java b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompilerImpl.java
new file mode 100644
index 0000000000..ae1f8a22f8
--- /dev/null
+++ b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompilerImpl.java
@@ -0,0 +1,410 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.tool;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.annotation.processing.Processor;
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticListener;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
+import org.eclipse.jdt.internal.compiler.IProblemFactory;
+import org.eclipse.jdt.internal.compiler.batch.CompilationUnit;
+import org.eclipse.jdt.internal.compiler.batch.FileSystem;
+import org.eclipse.jdt.internal.compiler.batch.Main;
+import org.eclipse.jdt.internal.compiler.batch.FileSystem.Classpath;
+import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilationUnit;
+import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+import org.eclipse.jdt.internal.compiler.util.Messages;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+
+public class EclipseCompilerImpl extends Main {
+ private static final CompilationUnit[] NO_UNITS = new CompilationUnit[0];
+ private HashMap<CompilationUnit, JavaFileObject> javaFileObjectMap;
+ Iterable<? extends JavaFileObject> compilationUnits;
+ public JavaFileManager fileManager;
+ protected Processor[] processors;
+ public DiagnosticListener<? super JavaFileObject> diagnosticListener;
+
+ public EclipseCompilerImpl(PrintWriter out, PrintWriter err, boolean systemExitWhenFinished) {
+ super(out, err, systemExitWhenFinished);
+ }
+
+ public boolean call() {
+ try {
+ if (this.proceed) {
+ this.globalProblemsCount = 0;
+ this.globalErrorsCount = 0;
+ this.globalWarningsCount = 0;
+ this.globalTasksCount = 0;
+ this.lineCount = 0;
+ this.exportedClassFilesCounter = 0;
+ // request compilation
+ performCompilation();
+ }
+ } catch (InvalidInputException e) {
+ this.logger.logException(e);
+ if (this.systemExitWhenFinished) {
+ cleanup();
+ System.exit(-1);
+ }
+ return false;
+ } catch(IllegalArgumentException e) {
+ throw e;
+ } catch (RuntimeException e) { // internal compiler failure
+ this.logger.logException(e);
+ return false;
+ } finally {
+ cleanup();
+ }
+ if (this.globalErrorsCount == 0)
+ return true;
+ return false;
+ }
+
+ private void cleanup() {
+ this.logger.flush();
+ this.logger.close();
+ this.processors = null;
+ try {
+ if (this.fileManager != null) {
+ this.fileManager.flush();
+ }
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+
+ public CompilationUnit[] getCompilationUnits() {
+ if (this.compilationUnits == null) return NO_UNITS;
+ ArrayList<CompilationUnit> units = new ArrayList<CompilationUnit>();
+ for (final JavaFileObject javaFileObject : this.compilationUnits) {
+ if (javaFileObject.getKind() != JavaFileObject.Kind.SOURCE) {
+ throw new IllegalArgumentException();
+ }
+ String name = javaFileObject.getName();
+ name = name.replace('\\', '/');
+ CompilationUnit compilationUnit = new CompilationUnit(null,
+ name,
+ null) {
+
+ public char[] getContents() {
+ try {
+ return javaFileObject.getCharContent(true).toString().toCharArray();
+ } catch(IOException e) {
+ e.printStackTrace();
+ throw new AbortCompilationUnit(null, e, null);
+ }
+ }
+ };
+ units.add(compilationUnit);
+ this.javaFileObjectMap.put(compilationUnit, javaFileObject);
+ }
+ CompilationUnit[] result = new CompilationUnit[units.size()];
+ units.toArray(result);
+ return result;
+ }
+ /*
+ * Low-level API performing the actual compilation
+ */
+ public IErrorHandlingPolicy getHandlingPolicy() {
+ // passes the initial set of files to the batch oracle (to avoid finding more than once the same units when case insensitive match)
+ return new IErrorHandlingPolicy() {
+ public boolean proceedOnErrors() {
+ return false; // stop if there are some errors
+ }
+ public boolean stopOnFirstError() {
+ return false;
+ }
+ };
+ }
+
+ public IProblemFactory getProblemFactory() {
+ return new DefaultProblemFactory() {
+ @Override
+ public CategorizedProblem createProblem(
+ final char[] originatingFileName,
+ final int problemId,
+ final String[] problemArguments,
+ final String[] messageArguments,
+ final int severity,
+ final int startPosition,
+ final int endPosition,
+ final int lineNumber,
+ final int columnNumber) {
+
+ DiagnosticListener<? super JavaFileObject> diagnosticListener = EclipseCompilerImpl.this.diagnosticListener;
+ if (diagnosticListener != null) {
+ diagnosticListener.report(new Diagnostic<JavaFileObject>() {
+ public String getCode() {
+ return Integer.toString(problemId);
+ }
+ public long getColumnNumber() {
+ return columnNumber;
+ }
+ public long getEndPosition() {
+ return endPosition;
+ }
+ public Kind getKind() {
+ if ((severity & ProblemSeverities.Error) != 0) {
+ return Diagnostic.Kind.ERROR;
+ }
+ if ((severity & ProblemSeverities.Optional) != 0) {
+ return Diagnostic.Kind.WARNING;
+ }
+ if ((severity & ProblemSeverities.Warning) != 0) {
+ return Diagnostic.Kind.MANDATORY_WARNING;
+ }
+ return Diagnostic.Kind.OTHER;
+ }
+ public long getLineNumber() {
+ return lineNumber;
+ }
+ public String getMessage(Locale locale) {
+ setLocale(locale);
+ return getLocalizedMessage(problemId, problemArguments);
+ }
+ public long getPosition() {
+ return startPosition;
+ }
+ public JavaFileObject getSource() {
+ try {
+ if (EclipseCompilerImpl.this.fileManager.hasLocation(StandardLocation.SOURCE_PATH)) {
+ return EclipseCompilerImpl.this.fileManager.getJavaFileForInput(
+ StandardLocation.SOURCE_PATH,
+ new String(originatingFileName),
+ JavaFileObject.Kind.SOURCE);
+ }
+ } catch (IOException e) {
+ // ignore
+ }
+ return null;
+ }
+ public long getStartPosition() {
+ return startPosition;
+ }
+ });
+ }
+ return super.createProblem(originatingFileName, problemId, problemArguments, messageArguments, severity, startPosition, endPosition, lineNumber, columnNumber);
+ }
+ };
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ protected void initialize(PrintWriter outWriter, PrintWriter errWriter, boolean systemExit, Map customDefaultOptions) {
+ super.initialize(outWriter, errWriter, systemExit, customDefaultOptions);
+ this.javaFileObjectMap = new HashMap<CompilationUnit, JavaFileObject>();
+ }
+
+ @Override
+ protected void initializeAnnotationProcessorManager() {
+ super.initializeAnnotationProcessorManager();
+ if (this.batchCompiler.annotationProcessorManager != null && this.processors != null) {
+ this.batchCompiler.annotationProcessorManager.setProcessors(this.processors);
+ } else if (this.processors != null) {
+ throw new UnsupportedOperationException("Cannot handle annotation processing"); //$NON-NLS-1$
+ }
+ }
+
+ // Dump classfiles onto disk for all compilation units that where successful
+ // and do not carry a -d none spec, either directly or inherited from Main.
+ public void outputClassFiles(CompilationResult unitResult) {
+ if (!((unitResult == null) || (unitResult.hasErrors() && !this.proceedOnError))) {
+ ClassFile[] classFiles = unitResult.getClassFiles();
+ boolean generateClasspathStructure = this.fileManager.hasLocation(StandardLocation.CLASS_OUTPUT);
+ String currentDestinationPath = this.destinationPath;
+ File outputLocation = null;
+ if (currentDestinationPath != null) {
+ outputLocation = new File(currentDestinationPath);
+ outputLocation.mkdirs();
+ }
+ for (int i = 0, fileCount = classFiles.length; i < fileCount; i++) {
+ // retrieve the key and the corresponding classfile
+ ClassFile classFile = classFiles[i];
+ char[] filename = classFile.fileName();
+ int length = filename.length;
+ char[] relativeName = new char[length + 6];
+ System.arraycopy(filename, 0, relativeName, 0, length);
+ System.arraycopy(SuffixConstants.SUFFIX_class, 0, relativeName, length, 6);
+ CharOperation.replace(relativeName, '/', File.separatorChar);
+ String relativeStringName = new String(relativeName);
+ if (this.compilerOptions.verbose) {
+ EclipseCompilerImpl.this.out.println(
+ Messages.bind(
+ Messages.compilation_write,
+ new String[] {
+ String.valueOf(this.exportedClassFilesCounter+1),
+ relativeStringName
+ }));
+ }
+ try {
+ JavaFileObject javaFileForOutput =
+ this.fileManager.getJavaFileForOutput(
+ StandardLocation.CLASS_OUTPUT,
+ new String(filename),
+ JavaFileObject.Kind.CLASS,
+ this.javaFileObjectMap.get(unitResult.compilationUnit));
+
+ if (generateClasspathStructure) {
+ if (currentDestinationPath != null) {
+ int index = CharOperation.lastIndexOf(File.separatorChar, relativeName);
+ if (index != -1) {
+ File currentFolder = new File(currentDestinationPath, relativeStringName.substring(0, index));
+ currentFolder.mkdirs();
+ }
+ } else {
+ // create the subfolfers is necessary
+ // need a way to retrieve the folders to create
+ String path = javaFileForOutput.toUri().getPath();
+ int index = path.lastIndexOf('/');
+ if (index != -1) {
+ File file = new File(path.substring(0, index));
+ file.mkdirs();
+ }
+ }
+ }
+
+ OutputStream openOutputStream = javaFileForOutput.openOutputStream();
+ BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(openOutputStream);
+ bufferedOutputStream.write(classFile.header, 0, classFile.headerOffset);
+ bufferedOutputStream.write(classFile.contents, 0, classFile.contentsOffset);
+ bufferedOutputStream.flush();
+ bufferedOutputStream.close();
+ } catch (IOException e) {
+ this.logger.logNoClassFileCreated(currentDestinationPath, relativeStringName, e);
+ }
+ LookupEnvironment env = EclipseCompilerImpl.this.batchCompiler.lookupEnvironment;
+ if (classFile.isShared) {
+ synchronized (env.classFilePool) {
+ env.classFilePool.release(classFile);
+ }
+ }
+ this.logger.logClassFile(
+ generateClasspathStructure,
+ currentDestinationPath,
+ relativeStringName);
+ this.exportedClassFilesCounter++;
+ }
+ }
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ protected void setPaths(ArrayList bootclasspaths,
+ String sourcepathClasspathArg,
+ ArrayList sourcepathClasspaths,
+ ArrayList classpaths,
+ ArrayList extdirsClasspaths,
+ ArrayList endorsedDirClasspaths,
+ String customEncoding) throws InvalidInputException {
+
+ ArrayList<FileSystem.Classpath> fileSystemClasspaths = new ArrayList<FileSystem.Classpath>();
+ EclipseFileManager javaFileManager = null;
+ StandardJavaFileManager standardJavaFileManager = null;
+ if (this.fileManager instanceof EclipseFileManager) {
+ javaFileManager = (EclipseFileManager) this.fileManager;
+ }
+ if (this.fileManager instanceof StandardJavaFileManager) {
+ standardJavaFileManager = (StandardJavaFileManager) this.fileManager;
+ }
+
+ if (javaFileManager != null) {
+ if ((javaFileManager.flags & EclipseFileManager.HAS_ENDORSED_DIRS) == 0
+ && (javaFileManager.flags & EclipseFileManager.HAS_BOOTCLASSPATH) != 0) {
+ fileSystemClasspaths.addAll((ArrayList<? extends FileSystem.Classpath>) this.handleEndorseddirs(null));
+ }
+ }
+ Iterable<? extends File> location = null;
+ if (standardJavaFileManager != null) {
+ location = standardJavaFileManager.getLocation(StandardLocation.PLATFORM_CLASS_PATH);
+ }
+ if (location != null) {
+ for (File file : location) {
+ Classpath classpath = FileSystem.getClasspath(
+ file.getAbsolutePath(),
+ null,
+ null);
+ if (classpath != null) {
+ fileSystemClasspaths.add(classpath);
+ }
+ }
+ }
+ if (javaFileManager != null) {
+ if ((javaFileManager.flags & EclipseFileManager.HAS_EXT_DIRS) == 0
+ && (javaFileManager.flags & EclipseFileManager.HAS_BOOTCLASSPATH) != 0) {
+ fileSystemClasspaths.addAll((ArrayList<? extends FileSystem.Classpath>) this.handleExtdirs(null));
+ }
+ }
+ if (standardJavaFileManager != null) {
+ location = standardJavaFileManager.getLocation(StandardLocation.SOURCE_PATH);
+ } else {
+ location = null;
+ }
+ if (location != null) {
+ for (File file : location) {
+ fileSystemClasspaths.add(FileSystem.getClasspath(
+ file.getAbsolutePath(),
+ null,
+ null));
+ }
+ }
+ if (standardJavaFileManager != null) {
+ location = standardJavaFileManager.getLocation(StandardLocation.CLASS_PATH);
+ } else {
+ location = null;
+ }
+ if (location != null) {
+ for (File file : location) {
+ Classpath classpath = FileSystem.getClasspath(
+ file.getAbsolutePath(),
+ null,
+ null);
+ if (classpath != null) {
+ fileSystemClasspaths.add(classpath);
+ }
+ }
+ }
+ if (this.checkedClasspaths == null) {
+ fileSystemClasspaths.addAll((ArrayList<? extends FileSystem.Classpath>) this.handleBootclasspath(null, null));
+ fileSystemClasspaths.addAll((ArrayList<? extends FileSystem.Classpath>) this.handleClasspath(null, null));
+ }
+ fileSystemClasspaths = FileSystem.ClasspathNormalizer.normalize(fileSystemClasspaths);
+ final int size = fileSystemClasspaths.size();
+ if (size != 0) {
+ this.checkedClasspaths = new FileSystem.Classpath[size];
+ int i = 0;
+ for (FileSystem.Classpath classpath : fileSystemClasspaths) {
+ this.checkedClasspaths[i++] = classpath;
+ }
+ }
+ }
+}
diff --git a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseFileManager.java b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseFileManager.java
index 17f96f692e..c220a1a0d3 100644
--- a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseFileManager.java
+++ b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseFileManager.java
@@ -18,12 +18,15 @@ import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.Charset;
+import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.zip.ZipException;
@@ -34,9 +37,13 @@ import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.JavaFileObject.Kind;
+import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.compiler.InvalidInputException;
import org.eclipse.jdt.internal.compiler.batch.FileSystem;
import org.eclipse.jdt.internal.compiler.batch.Main;
+import org.eclipse.jdt.internal.compiler.batch.Main.ResourceBundleFactory;
+import org.eclipse.jdt.internal.compiler.env.AccessRule;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
/**
* Implementation of the Standard Java File Manager
@@ -52,18 +59,14 @@ public class EclipseFileManager implements StandardJavaFileManager {
Charset charset;
Locale locale;
Map<String, Iterable<? extends File>> locations;
- Main compiler;
int flags;
+ public ResourceBundle bundle;
- public EclipseFileManager(Main eclipseCompiler, Locale locale, Charset charset) {
- this.compiler = eclipseCompiler;
+ public EclipseFileManager(Locale locale, Charset charset) {
this.locale = locale == null ? Locale.getDefault() : locale;
this.charset = charset == null ? Charset.defaultCharset() : charset;
this.locations = new HashMap<String, Iterable<? extends File>>();
this.archivesCache = new HashMap<File, Archive>();
- if (locale != null) {
- this.compiler.setLocale(locale);
- }
try {
this.setLocation(StandardLocation.PLATFORM_CLASS_PATH, getDefaultBootclasspath());
Iterable<? extends File> defaultClasspath = getDefaultClasspath();
@@ -72,6 +75,11 @@ public class EclipseFileManager implements StandardJavaFileManager {
} catch (IOException e) {
// ignore
}
+ try {
+ this.bundle = ResourceBundleFactory.getBundle(this.locale);
+ } catch(MissingResourceException e) {
+ System.out.println("Missing resource : " + Main.bundleName.replace('.', '/') + ".properties for locale " + locale); //$NON-NLS-1$//$NON-NLS-2$
+ }
}
private void addFiles(File[][] jars, ArrayList<File> files) {
@@ -266,7 +274,7 @@ public class EclipseFileManager implements StandardJavaFileManager {
ArrayList<FileSystem.Classpath> paths = new ArrayList<FileSystem.Classpath>();
ArrayList<File> files = new ArrayList<File>();
try {
- this.compiler.processPathEntries(Main.DEFAULT_SIZE_CLASSPATH, paths, path, this.charset.toString(), false, false);
+ this.processPathEntries(Main.DEFAULT_SIZE_CLASSPATH, paths, path, this.charset.toString(), false, false);
} catch (InvalidInputException e) {
return null;
}
@@ -287,21 +295,28 @@ public class EclipseFileManager implements StandardJavaFileManager {
/*
* Handle >= JDK 1.6
*/
- File javaHome = this.compiler.getJavaHome();
- addFilesFrom(javaHome, "java.endorsed.dirs", "/lib/endorsed", files);//$NON-NLS-1$//$NON-NLS-2$
+ String javaHome = System.getProperty("java.home"); //$NON-NLS-1$
+ File javaHomeFile = null;
if (javaHome != null) {
+ javaHomeFile = new File(javaHome);
+ if (!javaHomeFile.exists())
+ javaHomeFile = null;
+ }
+
+ addFilesFrom(javaHomeFile, "java.endorsed.dirs", "/lib/endorsed", files);//$NON-NLS-1$//$NON-NLS-2$
+ if (javaHomeFile != null) {
File[] directoriesToCheck = null;
if (System.getProperty("os.name").startsWith("Mac")) {//$NON-NLS-1$//$NON-NLS-2$
- directoriesToCheck = new File[] { new File(javaHome, "../Classes"), //$NON-NLS-1$
+ directoriesToCheck = new File[] { new File(javaHomeFile, "../Classes"), //$NON-NLS-1$
};
} else {
- directoriesToCheck = new File[] { new File(javaHome, "lib") //$NON-NLS-1$
+ directoriesToCheck = new File[] { new File(javaHomeFile, "lib") //$NON-NLS-1$
};
}
File[][] jars = Main.getLibrariesFiles(directoriesToCheck);
addFiles(jars, files);
}
- addFilesFrom(javaHome, "java.ext.dirs", "/lib/ext", files);//$NON-NLS-1$//$NON-NLS-2$
+ addFilesFrom(javaHomeFile, "java.ext.dirs", "/lib/ext", files);//$NON-NLS-1$//$NON-NLS-2$
return files;
}
@@ -329,7 +344,7 @@ public class EclipseFileManager implements StandardJavaFileManager {
ArrayList<FileSystem.Classpath> paths = new ArrayList<FileSystem.Classpath>();
ArrayList<File> files = new ArrayList<File>();
try {
- this.compiler.processPathEntries(Main.DEFAULT_SIZE_CLASSPATH, paths, path, this.charset.toString(), false, false);
+ this.processPathEntries(Main.DEFAULT_SIZE_CLASSPATH, paths, path, this.charset.toString(), false, false);
} catch (InvalidInputException e) {
return null;
}
@@ -343,7 +358,7 @@ public class EclipseFileManager implements StandardJavaFileManager {
ArrayList<FileSystem.Classpath> paths = new ArrayList<FileSystem.Classpath>();
ArrayList<File> files = new ArrayList<File>();
try {
- this.compiler.processPathEntries(Main.DEFAULT_SIZE_CLASSPATH, paths, path, this.charset.toString(), false, false);
+ this.processPathEntries(Main.DEFAULT_SIZE_CLASSPATH, paths, path, this.charset.toString(), false, false);
} catch (InvalidInputException e) {
return null;
}
@@ -838,6 +853,299 @@ public class EclipseFileManager implements StandardJavaFileManager {
}
public void setLocale(Locale locale) {
- this.locale = locale;
+ this.locale = locale == null ? Locale.getDefault() : locale;
+ try {
+ this.bundle = ResourceBundleFactory.getBundle(this.locale);
+ } catch(MissingResourceException e) {
+ System.out.println("Missing resource : " + Main.bundleName.replace('.', '/') + ".properties for locale " + locale); //$NON-NLS-1$//$NON-NLS-2$
+ throw e;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void processPathEntries(final int defaultSize, final ArrayList paths,
+ final String currentPath, String customEncoding, boolean isSourceOnly,
+ boolean rejectDestinationPathOnJars)
+ throws InvalidInputException {
+ String currentClasspathName = null;
+ String currentDestinationPath = null;
+ ArrayList currentRuleSpecs = new ArrayList(defaultSize);
+ StringTokenizer tokenizer = new StringTokenizer(currentPath,
+ File.pathSeparator + "[]", true); //$NON-NLS-1$
+ ArrayList tokens = new ArrayList();
+ while (tokenizer.hasMoreTokens()) {
+ tokens.add(tokenizer.nextToken());
+ }
+ // state machine
+ final int start = 0;
+ final int readyToClose = 1;
+ // 'path' 'path1[rule];path2'
+ final int readyToCloseEndingWithRules = 2;
+ // 'path[rule]' 'path1;path2[rule]'
+ final int readyToCloseOrOtherEntry = 3;
+ // 'path[rule];' 'path;' 'path1;path2;'
+ final int rulesNeedAnotherRule = 4;
+ // 'path[rule1;'
+ final int rulesStart = 5;
+ // 'path[' 'path1;path2['
+ final int rulesReadyToClose = 6;
+ // 'path[rule' 'path[rule1;rule2'
+ final int destinationPathReadyToClose = 7;
+ // 'path[-d bin'
+ final int readyToCloseEndingWithDestinationPath = 8;
+ // 'path[-d bin]' 'path[rule][-d bin]'
+ final int destinationPathStart = 9;
+ // 'path[rule]['
+ final int bracketOpened = 10;
+ // '.*[.*'
+ final int bracketClosed = 11;
+ // '.*([.*])+'
+
+ final int error = 99;
+ int state = start;
+ String token = null;
+ int cursor = 0, tokensNb = tokens.size(), bracket = -1;
+ while (cursor < tokensNb && state != error) {
+ token = (String) tokens.get(cursor++);
+ if (token.equals(File.pathSeparator)) {
+ switch (state) {
+ case start:
+ case readyToCloseOrOtherEntry:
+ case bracketOpened:
+ break;
+ case readyToClose:
+ case readyToCloseEndingWithRules:
+ case readyToCloseEndingWithDestinationPath:
+ state = readyToCloseOrOtherEntry;
+ addNewEntry(paths, currentClasspathName, currentRuleSpecs,
+ customEncoding, currentDestinationPath, isSourceOnly,
+ rejectDestinationPathOnJars);
+ currentRuleSpecs.clear();
+ break;
+ case rulesReadyToClose:
+ state = rulesNeedAnotherRule;
+ break;
+ case destinationPathReadyToClose:
+ throw new InvalidInputException(
+ this.bind("configure.incorrectDestinationPathEntry", //$NON-NLS-1$
+ currentPath));
+ case bracketClosed:
+ cursor = bracket + 1;
+ state = rulesStart;
+ break;
+ default:
+ state = error;
+ }
+ } else if (token.equals("[")) { //$NON-NLS-1$
+ switch (state) {
+ case start:
+ currentClasspathName = ""; //$NON-NLS-1$
+ case readyToClose:
+ bracket = cursor - 1;
+ case bracketClosed:
+ state = bracketOpened;
+ break;
+ case readyToCloseEndingWithRules:
+ state = destinationPathStart;
+ break;
+ case readyToCloseEndingWithDestinationPath:
+ state = rulesStart;
+ break;
+ case bracketOpened:
+ default:
+ state = error;
+ }
+ } else if (token.equals("]")) { //$NON-NLS-1$
+ switch (state) {
+ case rulesReadyToClose:
+ state = readyToCloseEndingWithRules;
+ break;
+ case destinationPathReadyToClose:
+ state = readyToCloseEndingWithDestinationPath;
+ break;
+ case bracketOpened:
+ state = bracketClosed;
+ break;
+ case bracketClosed:
+ default:
+ state = error;
+ }
+ } else {
+ // regular word
+ switch (state) {
+ case start:
+ case readyToCloseOrOtherEntry:
+ state = readyToClose;
+ currentClasspathName = token;
+ break;
+ case rulesStart:
+ if (token.startsWith("-d ")) { //$NON-NLS-1$
+ if (currentDestinationPath != null) {
+ throw new InvalidInputException(
+ this.bind("configure.duplicateDestinationPathEntry", //$NON-NLS-1$
+ currentPath));
+ }
+ currentDestinationPath = token.substring(3).trim();
+ state = destinationPathReadyToClose;
+ break;
+ } // else we proceed with a rule
+ case rulesNeedAnotherRule:
+ if (currentDestinationPath != null) {
+ throw new InvalidInputException(
+ this.bind("configure.accessRuleAfterDestinationPath", //$NON-NLS-1$
+ currentPath));
+ }
+ state = rulesReadyToClose;
+ currentRuleSpecs.add(token);
+ break;
+ case destinationPathStart:
+ if (!token.startsWith("-d ")) { //$NON-NLS-1$
+ state = error;
+ } else {
+ currentDestinationPath = token.substring(3).trim();
+ state = destinationPathReadyToClose;
+ }
+ break;
+ case bracketClosed:
+ for (int i = bracket; i < cursor ; i++) {
+ currentClasspathName += (String) tokens.get(i);
+ }
+ state = readyToClose;
+ break;
+ case bracketOpened:
+ break;
+ default:
+ state = error;
+ }
+ }
+ if (state == bracketClosed && cursor == tokensNb) {
+ cursor = bracket + 1;
+ state = rulesStart;
+ }
+ }
+ switch(state) {
+ case readyToCloseOrOtherEntry:
+ break;
+ case readyToClose:
+ case readyToCloseEndingWithRules:
+ case readyToCloseEndingWithDestinationPath:
+ addNewEntry(paths, currentClasspathName, currentRuleSpecs,
+ customEncoding, currentDestinationPath, isSourceOnly,
+ rejectDestinationPathOnJars);
+ break;
+ case bracketOpened:
+ case bracketClosed:
+ default :
+ // we go on anyway
+ }
+ }
+ @SuppressWarnings("unchecked")
+ protected void addNewEntry(ArrayList paths, String currentClasspathName,
+ ArrayList currentRuleSpecs, String customEncoding,
+ String destPath, boolean isSourceOnly,
+ boolean rejectDestinationPathOnJars) throws InvalidInputException {
+
+ int rulesSpecsSize = currentRuleSpecs.size();
+ AccessRuleSet accessRuleSet = null;
+ if (rulesSpecsSize != 0) {
+ AccessRule[] accessRules = new AccessRule[currentRuleSpecs.size()];
+ boolean rulesOK = true;
+ Iterator i = currentRuleSpecs.iterator();
+ int j = 0;
+ while (i.hasNext()) {
+ String ruleSpec = (String) i.next();
+ char key = ruleSpec.charAt(0);
+ String pattern = ruleSpec.substring(1);
+ if (pattern.length() > 0) {
+ switch (key) {
+ case '+':
+ accessRules[j++] = new AccessRule(pattern
+ .toCharArray(), 0);
+ break;
+ case '~':
+ accessRules[j++] = new AccessRule(pattern
+ .toCharArray(),
+ IProblem.DiscouragedReference);
+ break;
+ case '-':
+ accessRules[j++] = new AccessRule(pattern
+ .toCharArray(),
+ IProblem.ForbiddenReference);
+ break;
+ case '?':
+ accessRules[j++] = new AccessRule(pattern
+ .toCharArray(),
+ IProblem.ForbiddenReference, true/*keep looking for accessible type*/);
+ break;
+ default:
+ rulesOK = false;
+ }
+ } else {
+ rulesOK = false;
+ }
+ }
+ if (rulesOK) {
+ String templates[] = new String[AccessRuleSet.MESSAGE_TEMPLATES_LENGTH];
+ templates[0] = this.bind(
+ "template.restrictedAccess.type", //$NON-NLS-1$
+ new String[] {"{0}", currentClasspathName}); //$NON-NLS-1$
+ templates[1] = this.bind(
+ "template.restrictedAccess.constructor", //$NON-NLS-1$
+ new String[] {"{0}", currentClasspathName}); //$NON-NLS-1$
+ templates[2] = this.bind(
+ "template.restrictedAccess.method", //$NON-NLS-1$
+ new String[] {"{0}", "{1}", currentClasspathName}); //$NON-NLS-1$ //$NON-NLS-2$
+ templates[3] = this.bind(
+ "template.restrictedAccess.field", //$NON-NLS-1$
+ new String[] {"{0}", "{1}", currentClasspathName}); //$NON-NLS-1$ //$NON-NLS-2$
+ accessRuleSet = new AccessRuleSet(accessRules, templates);
+ } else {
+ return;
+ }
+ }
+ if (Main.NONE.equals(destPath)) {
+ destPath = Main.NONE; // keep == comparison valid
+ }
+ if (rejectDestinationPathOnJars && destPath != null &&
+ (currentClasspathName.endsWith(".jar") || //$NON-NLS-1$
+ currentClasspathName.endsWith(".zip"))) { //$NON-NLS-1$
+ throw new InvalidInputException(
+ this.bind("configure.unexpectedDestinationPathEntryFile", //$NON-NLS-1$
+ currentClasspathName));
+ }
+ FileSystem.Classpath currentClasspath = FileSystem.getClasspath(
+ currentClasspathName,
+ customEncoding,
+ isSourceOnly,
+ accessRuleSet,
+ destPath);
+ if (currentClasspath != null) {
+ paths.add(currentClasspath);
+ }
+ }
+ /*
+ * Lookup the message with the given ID in this catalog and bind its
+ * substitution locations with the given string.
+ */
+ private String bind(String id, String binding) {
+ return bind(id, new String[] { binding });
+ }
+
+ /*
+ * Lookup the message with the given ID in this catalog and bind its
+ * substitution locations with the given string values.
+ */
+ private String bind(String id, String[] arguments) {
+ if (id == null)
+ return "No message available"; //$NON-NLS-1$
+ String message = null;
+ try {
+ message = this.bundle.getString(id);
+ } catch (MissingResourceException e) {
+ // If we got an exception looking for the message, fail gracefully by just returning
+ // the id we were looking for. In most cases this is semi-informative so is not too bad.
+ return "Missing message: " + id + " in: " + Main.bundleName; //$NON-NLS-2$ //$NON-NLS-1$
+ }
+ return MessageFormat.format(message, (Object[]) arguments);
}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java
index 060b2fa060..3dbe398a09 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java
@@ -9156,4 +9156,44 @@ public class ASTConverter15Test extends ConverterTestSetup {
annotations = binding.getAnnotations();
assertEquals("Wrong size", 1, annotations.length);
}
+
+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=192774
+ //Test ability to distinguish AST nodes of multiple similar annotations.
+ public void test0276() throws JavaModelException {
+ this.workingCopy = getWorkingCopy("/Converter15/src/X.java", true/*resolve*/);
+ String contents =
+ "@interface Annot {\n" +
+ " public int value();\n" +
+ "}\n" +
+ "\n" +
+ "public class X {\n" +
+ " @Annot(1) String foo1() { return null; }\n" +
+ " @Annot(1) String foo2() { return null; }\n" +
+ "}";
+ this.workingCopy.getBuffer().setContents(contents);
+
+ class CompilationUnitRequestor extends ASTRequestor {
+ public void acceptAST(ICompilationUnit source, CompilationUnit node) {
+ MethodDeclaration methodDeclaration = (MethodDeclaration)getASTNode(node, 1, 0);
+ IMethodBinding methodBinding = methodDeclaration.resolveBinding();
+ IAnnotationBinding annoBinding = methodBinding.getAnnotations()[0];
+ ASTNode annoNode = node.findDeclaringNode(annoBinding);
+ int position1 = annoNode.getStartPosition();
+
+ methodDeclaration = (MethodDeclaration)getASTNode(node, 1, 1);
+ methodBinding = methodDeclaration.resolveBinding();
+ IAnnotationBinding annoBinding2 = methodBinding.getAnnotations()[0];
+ annoNode = node.findDeclaringNode(annoBinding2);
+ int position2 = annoNode.getStartPosition();
+ assertTrue("Anno 2 position <= anno 1 position", position2 > position1);
+ }
+ }
+
+ CompilationUnitRequestor requestor = new CompilationUnitRequestor();
+ ASTParser parser = ASTParser.newParser(AST.JLS3);
+ parser.setResolveBindings(true);
+ parser.setProject(this.getJavaProject("Converter15"));
+ parser.setKind(ASTParser.K_COMPILATION_UNIT);
+ parser.createASTs(new ICompilationUnit[]{this.workingCopy}, new String[0], requestor, null);
+ }
}
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java
index dc07ff336a..68544f8cf5 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java
@@ -130,7 +130,7 @@ FileSystem(Classpath[] paths, String[] initialFileNames) {
public static Classpath getClasspath(String classpathName, String encoding, AccessRuleSet accessRuleSet) {
return getClasspath(classpathName, encoding, false, accessRuleSet, null);
}
-static Classpath getClasspath(String classpathName, String encoding,
+public static Classpath getClasspath(String classpathName, String encoding,
boolean isSourceOnly, AccessRuleSet accessRuleSet,
String destinationPath) {
Classpath result = null;
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
index 7e0b298720..fd18dbcbea 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
@@ -1403,63 +1403,63 @@ protected void addNewEntry(ArrayList paths, String currentClasspathName,
AccessRuleSet accessRuleSet = null;
if (rulesSpecsSize != 0) {
AccessRule[] accessRules = new AccessRule[currentRuleSpecs.size()];
- boolean rulesOK = true;
- Iterator i = currentRuleSpecs.iterator();
- int j = 0;
- while (i.hasNext()) {
- String ruleSpec = (String) i.next();
- char key = ruleSpec.charAt(0);
- String pattern = ruleSpec.substring(1);
- if (pattern.length() > 0) {
- switch (key) {
- case '+':
- accessRules[j++] = new AccessRule(pattern
- .toCharArray(), 0);
- break;
- case '~':
- accessRules[j++] = new AccessRule(pattern
- .toCharArray(),
- IProblem.DiscouragedReference);
- break;
- case '-':
- accessRules[j++] = new AccessRule(pattern
- .toCharArray(),
- IProblem.ForbiddenReference);
- break;
- case '?':
- accessRules[j++] = new AccessRule(pattern
- .toCharArray(),
- IProblem.ForbiddenReference, true/*keep looking for accessible type*/);
- break;
- default:
- rulesOK = false;
- }
- } else {
- rulesOK = false;
- }
- }
- if (rulesOK) {
- String templates[] = new String[AccessRuleSet.MESSAGE_TEMPLATES_LENGTH];
- templates[0] = this.bind(
- "template.restrictedAccess.type", //$NON-NLS-1$
- new String[] {"{0}", currentClasspathName}); //$NON-NLS-1$
- templates[1] = this.bind(
- "template.restrictedAccess.constructor", //$NON-NLS-1$
- new String[] {"{0}", currentClasspathName}); //$NON-NLS-1$
- templates[2] = this.bind(
- "template.restrictedAccess.method", //$NON-NLS-1$
- new String[] {"{0}", "{1}", currentClasspathName}); //$NON-NLS-1$ //$NON-NLS-2$
- templates[3] = this.bind(
- "template.restrictedAccess.field", //$NON-NLS-1$
- new String[] {"{0}", "{1}", currentClasspathName}); //$NON-NLS-1$ //$NON-NLS-2$
- accessRuleSet = new AccessRuleSet(accessRules, templates);
- } else {
- if (currentClasspathName.length() != 0) {
- // we go on anyway
- this.logger.logIncorrectClasspath(currentClasspathName);
- }
- return;
- }
+ boolean rulesOK = true;
+ Iterator i = currentRuleSpecs.iterator();
+ int j = 0;
+ while (i.hasNext()) {
+ String ruleSpec = (String) i.next();
+ char key = ruleSpec.charAt(0);
+ String pattern = ruleSpec.substring(1);
+ if (pattern.length() > 0) {
+ switch (key) {
+ case '+':
+ accessRules[j++] = new AccessRule(pattern
+ .toCharArray(), 0);
+ break;
+ case '~':
+ accessRules[j++] = new AccessRule(pattern
+ .toCharArray(),
+ IProblem.DiscouragedReference);
+ break;
+ case '-':
+ accessRules[j++] = new AccessRule(pattern
+ .toCharArray(),
+ IProblem.ForbiddenReference);
+ break;
+ case '?':
+ accessRules[j++] = new AccessRule(pattern
+ .toCharArray(),
+ IProblem.ForbiddenReference, true/*keep looking for accessible type*/);
+ break;
+ default:
+ rulesOK = false;
+ }
+ } else {
+ rulesOK = false;
+ }
+ }
+ if (rulesOK) {
+ String templates[] = new String[AccessRuleSet.MESSAGE_TEMPLATES_LENGTH];
+ templates[0] = this.bind(
+ "template.restrictedAccess.type", //$NON-NLS-1$
+ new String[] {"{0}", currentClasspathName}); //$NON-NLS-1$
+ templates[1] = this.bind(
+ "template.restrictedAccess.constructor", //$NON-NLS-1$
+ new String[] {"{0}", currentClasspathName}); //$NON-NLS-1$
+ templates[2] = this.bind(
+ "template.restrictedAccess.method", //$NON-NLS-1$
+ new String[] {"{0}", "{1}", currentClasspathName}); //$NON-NLS-1$ //$NON-NLS-2$
+ templates[3] = this.bind(
+ "template.restrictedAccess.field", //$NON-NLS-1$
+ new String[] {"{0}", "{1}", currentClasspathName}); //$NON-NLS-1$ //$NON-NLS-2$
+ accessRuleSet = new AccessRuleSet(accessRules, templates);
+ } else {
+ if (currentClasspathName.length() != 0) {
+ // we go on anyway
+ this.logger.logIncorrectClasspath(currentClasspathName);
+ }
+ return;
+ }
}
if (NONE.equals(destPath)) {
destPath = NONE; // keep == comparison valid
@@ -3811,7 +3811,7 @@ public void setLocale(Locale locale) {
/*
* External API
*/
-protected void setDestinationPath(String dest) {
+public void setDestinationPath(String dest) {
this.destinationPath = dest;
}
/*
diff --git a/org.eclipse.jdt.core/buildnotes_jdt-core.html b/org.eclipse.jdt.core/buildnotes_jdt-core.html
index 5581c10143..2b0316cb57 100644
--- a/org.eclipse.jdt.core/buildnotes_jdt-core.html
+++ b/org.eclipse.jdt.core/buildnotes_jdt-core.html
@@ -52,7 +52,13 @@ Eclipse SDK 3.4M1 - %date% - 3.4 MILESTONE 1
</ul>
<h3>Problem Reports Fixed</h3>
-<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=171703">171703</a>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=191082">191082</a>
+AnnotationMirror.getPosition() returns wrong value
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=189799">189799</a>
+[jsr269] Make getDocComment() behave more like javac
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=192774">192774</a>
+Annotation AST nodes should have unique IAnnotationBindings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=171703">171703</a>
Eclipse cannot find source for *.class files
<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=193979">193979</a>
AST parser generates wrong AST
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ElementValuePair.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ElementValuePair.java
index 2f0aed6c34..3d72759801 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ElementValuePair.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ElementValuePair.java
@@ -16,8 +16,8 @@ import org.eclipse.jdt.internal.compiler.impl.Constant;
public class ElementValuePair {
char[] name;
- Object value;
- MethodBinding binding;
+ public Object value;
+ public MethodBinding binding;
public static Object getValue(Expression expression) {
if (expression == null)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
index 5e52670598..e59270a033 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
@@ -62,7 +62,6 @@ public class LookupEnvironment implements ProblemReasons, TypeConstants {
private SimpleLookupTable uniqueRawTypeBindings;
private SimpleLookupTable uniqueWildcardBindings;
private SimpleLookupTable uniqueParameterizedGenericMethodBindings;
- private SimpleLookupTable uniqueAnnotationBindings;
public CompilationUnitDeclaration unitBeingCompleted = null; // only set while completing units
public Object missingClassFileLocation = null; // only set when resolving certain references, to help locating problems
@@ -82,7 +81,6 @@ public LookupEnvironment(ITypeRequestor typeRequestor, CompilerOptions globalOpt
this.uniqueArrayBindings[0] = new ArrayBinding[50]; // start off the most common 1 dimension array @ 50
this.uniqueParameterizedTypeBindings = new SimpleLookupTable(3);
this.uniqueRawTypeBindings = new SimpleLookupTable(3);
- this.uniqueAnnotationBindings = new SimpleLookupTable(3);
this.uniqueWildcardBindings = new SimpleLookupTable(3);
this.uniqueParameterizedGenericMethodBindings = new SimpleLookupTable(3);
this.accessRestrictions = new HashMap(3);
@@ -539,63 +537,10 @@ public TypeBinding convertUnresolvedBinaryToRawType(TypeBinding type) {
* Used to guarantee annotation identity.
*/
public AnnotationBinding createAnnotation(ReferenceBinding annotationType, ElementValuePair[] pairs) {
- // cached info is array of already created annotation binding for this type
- AnnotationBinding[] cachedInfo = (AnnotationBinding[])this.uniqueAnnotationBindings.get(annotationType);
- boolean needToGrow = false;
- int index = 0;
if (pairs.length != 0) {
AnnotationBinding.setMethodBindings(annotationType, pairs);
}
- if (cachedInfo != null){
- nextCachedType :
- // iterate existing parameterized for reusing one with same type arguments if any
- for (int max = cachedInfo.length; index < max; index++){
- AnnotationBinding cachedType = cachedInfo[index];
- if (cachedType == null) break nextCachedType;
- ElementValuePair[] elementValuePairs = cachedType.pairs;
- int length2 = pairs.length;
- if (length2 != elementValuePairs.length) continue nextCachedType;
- loop: for (int i = 0; i < length2; i++) {
- ElementValuePair pair = elementValuePairs[i];
- // loop on the given pair to make sure one will match
- for (int j = 0; j < length2; j++) {
- ElementValuePair pair2 = pairs[j];
- if (pair.binding == pair2.binding) {
- if (pair.value == null) {
- if (pair2.value == null) {
- continue loop;
- }
- continue nextCachedType;
- } else {
- if (pair2.value == null
- || !pair2.value.equals(pair.value)) {
- continue nextCachedType;
- }
- }
- continue loop;
- }
- }
- // no match found for pair so we create a new annotation binding
- continue nextCachedType;
- }
- // cached type match, reuse current
- return cachedType;
- }
- needToGrow = true;
- } else {
- cachedInfo = new AnnotationBinding[1];
- this.uniqueAnnotationBindings.put(annotationType, cachedInfo);
- }
- // grow cache ?
- int length = cachedInfo.length;
- if (needToGrow && index == length){
- System.arraycopy(cachedInfo, 0, cachedInfo = new AnnotationBinding[length*2], 0, length);
- this.uniqueAnnotationBindings.put(annotationType, cachedInfo);
- }
- // add new binding
- AnnotationBinding annotationBinding = new AnnotationBinding(annotationType, pairs);
- cachedInfo[index] = annotationBinding;
- return annotationBinding;
+ return new AnnotationBinding(annotationType, pairs);
}
/*
@@ -1248,7 +1193,6 @@ public void reset() {
this.uniqueRawTypeBindings = new SimpleLookupTable(3);
this.uniqueWildcardBindings = new SimpleLookupTable(3);
this.uniqueParameterizedGenericMethodBindings = new SimpleLookupTable(3);
- this.uniqueAnnotationBindings = new SimpleLookupTable(3);
for (int i = this.units.length; --i >= 0;)
this.units[i] = null;

Back to the top