Bug 440687 - [compiler][batch][null] improve command line option for
external annotations
Change-Id: I710ec106a8dae968d03fb8ce4375c23de76b0672
Signed-off-by: Stephan Herrmann <stephan.herrmann@berlin.de>
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
index 72c3430..d47c9cc 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -25,6 +25,7 @@
* bug 383368 - [compiler][null] syntactic null analysis for field references
* Bug 392099 - [1.8][compiler][null] Apply null annotation on types for null analysis
* Bug 440477 - [null] Infrastructure for feeding external annotations into compilation
+ * Bug 440687 - [compiler][batch][null] improve command line option for external annotations
* Jesper Steen Moller - Contributions for
* bug 404146 - [1.7][compiler] nested try-catch-finally-blocks leads to unrunnable Java byte code
* bug 407297 - [1.8][compiler] Control generation of parameter names by option
@@ -111,6 +112,14 @@
"@Target({ ElementType.TYPE_USE })\n" +
"public @interface NonNull{\n" +
"}\n";
+ private static final String NULLABLE_ANNOTATION_18_CONTENT = "package org.eclipse.jdt.annotation;\n" +
+ "import java.lang.annotation.ElementType;\n" +
+ "import java.lang.annotation.*;\n" +
+ "@Documented\n" +
+ "@Retention(RetentionPolicy.CLASS)\n" +
+ "@Target({ ElementType.TYPE_USE })\n" +
+ "public @interface Nullable{\n" +
+ "}\n";
private static final String NONNULL_BY_DEFAULT_ANNOTATION_18_CONTENT = "package org.eclipse.jdt.annotation;\n" +
"import java.lang.annotation.ElementType;\n" +
"import static org.eclipse.jdt.annotation.DefaultLocation.*;\n" +
@@ -1704,9 +1713,11 @@
" -Xemacs used to enable emacs-style output in the console.\n" +
" It does not affect the xml log output\n" +
" -missingNullDefault report missing default nullness annotation\n" +
- " -annotationpath <path>\n" +
- " Path to a base directory or zip file holding external\n" +
- " annotations to support annotation-based null analysis\n" +
+ " -annotationpath <directories and ZIP archives separated by " + File.pathSeparator + ">\n" +
+ " specify locations where to find external annotations\n" +
+ " to support annotation-based null analysis.\n" +
+ " The special name CLASSPATH will cause lookup of\n" +
+ " external annotations from the classpath and sourcepath.\n" +
" \n" +
" -? -help print this help message\n" +
" -v -version print compiler version\n" +
@@ -14105,18 +14116,7 @@
new File(annots_java_util).mkdirs();
Util.createFile(
annots_java_util + File.separator + "Map.eea",
- "class java/util/Map\n" +
- " <K:V:>\n" +
- "\n" +
- "get\n" +
- " (Ljava/lang/Object;)TV;\n" +
- " (Ljava/lang/Object;)T0V;\n" +
- "put\n" +
- " (TK;TV;)TV;\n" +
- " (TK;TV;)T0V;\n" +
- "remove\n" +
- " (Ljava/lang/Object;)TV;\n" +
- " (Ljava/lang/Object;)T0V;\n");
+ TEST_440687_MAP_EEA_CONTENT);
String o_e_j_annotation_dir = OUTPUT_DIR + File.separator +
"org" + File.separator + "eclipse" + File.separator + "jdt" + File.separator + "annotation";
@@ -14128,6 +14128,8 @@
ELEMENT_TYPE_18_CONTENT,
"org/eclipse/jdt/annotation/NonNull.java",
NONNULL_ANNOTATION_18_CONTENT,
+ "org/eclipse/jdt/annotation/Nullable.java",
+ NULLABLE_ANNOTATION_18_CONTENT,
"org/eclipse/jdt/annotation/DefaultLocation.java",
DEFAULT_LOCATION_CONTENT,
"org/eclipse/jdt/annotation/NonNullByDefault.java",
@@ -14159,6 +14161,160 @@
"",
true);
}
+// file content for tests below:
+private static final String TEST_440687_MAP_EEA_CONTENT =
+ "class java/util/Map\n" +
+ " <K:V:>\n" +
+ "\n" +
+ "get\n" +
+ " (Ljava/lang/Object;)TV;\n" +
+ " (Ljava/lang/Object;)T0V;\n" +
+ "put\n" +
+ " (TK;TV;)TV;\n" +
+ " (TK;TV;)T0V;\n" +
+ "remove\n" +
+ " (Ljava/lang/Object;)TV;\n" +
+ " (Ljava/lang/Object;)T0V;\n";
+private static final String TEST_440687_OBJECT_EEA_CONTENT =
+ "class java/lang/Object\n" +
+ "\n" +
+ "equals\n" +
+ " (Ljava/lang/Object;)Z\n" +
+ " (L0java/lang/Object;)Z\n";
+// Bug 440687 - [compiler][batch][null] improve command line option for external annotations
+// work horse for tests below
+void runTest440687(String compilerPathArgs, String extraSourcePaths, String expectedCompilerMessage, boolean isSuccess) {
+
+ String[] testFiles = new String[] {
+ "java/lang/annotation/ElementType.java",
+ ELEMENT_TYPE_18_CONTENT,
+ "org/eclipse/jdt/annotation/NonNull.java",
+ NONNULL_ANNOTATION_18_CONTENT,
+ "org/eclipse/jdt/annotation/Nullable.java",
+ NULLABLE_ANNOTATION_18_CONTENT,
+ "org/eclipse/jdt/annotation/DefaultLocation.java",
+ DEFAULT_LOCATION_CONTENT,
+ "org/eclipse/jdt/annotation/NonNullByDefault.java",
+ NONNULL_BY_DEFAULT_ANNOTATION_18_CONTENT,
+ "test1/Test1.java",
+ "package test1;\n" +
+ "\n" +
+ "import java.util.Map;\n" +
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "\n" +
+ "@NonNullByDefault\n" +
+ "public class Test1 {\n" +
+ " void test(Map<String,Test1> map, String key) {\n" +
+ " Test1 v = map.get(key);\n" +
+ " if (v == null)\n" +
+ " throw new RuntimeException(); // should not be reported as dead code, although V is a '@NonNull Test1'\n" +
+ " }\n" +
+ " public boolean equals(@NonNull Object other) { return false; }\n" +
+ "}\n"
+ };
+
+ String o_e_j_annotation_dir = OUTPUT_DIR + File.separator +
+ "org" + File.separator + "eclipse" + File.separator + "jdt" + File.separator + "annotation";
+ String j_l_annotation_dir = OUTPUT_DIR + File.separator +
+ "java" + File.separator + "lang" + File.separator + "annotation";
+
+ String commandLine = " -1.8 -proc:none -d none -warn:+nullAnnot " + compilerPathArgs +
+ " -sourcepath \"" + OUTPUT_DIR + extraSourcePaths + "\" " +
+ // explicitly mention all files to ensure a good order, cannot pull in source of NNBD on demand
+ "\"" + j_l_annotation_dir + File.separator + "ElementType.java\" " +
+ "\"" + o_e_j_annotation_dir + File.separator + "NonNull.java\" " +
+ "\"" + o_e_j_annotation_dir + File.separator + "DefaultLocation.java\" " +
+ "\"" + o_e_j_annotation_dir + File.separator + "NonNullByDefault.java\" " +
+ "\"" + OUTPUT_DIR + File.separator + "test1" + File.separator + "Test1.java\"";
+
+ if (expectedCompilerMessage == null)
+ expectedCompilerMessage =
+ "----------\n" +
+ "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/test1/Test1.java (at line 13)\n" +
+ " public boolean equals(@NonNull Object other) { return false; }\n" +
+ " ^^^^^^^^^^^^^^^\n" +
+ "Illegal redefinition of parameter other, inherited method from Object declares this parameter as @Nullable\n" +
+ "----------\n" +
+ "1 problem (1 warning)\n";
+
+ if (isSuccess)
+ this.runConformTest(testFiles, commandLine, "", expectedCompilerMessage, true);
+ else
+ this.runNegativeTest(testFiles, commandLine, "", expectedCompilerMessage, true);
+}
+// Bug 440687 - [compiler][batch][null] improve command line option for external annotations
+// - two external annotation directories as part of the sourcepath/classpath
+public void test440687a() throws IOException {
+
+ String annots_dir1 = Util.getOutputDirectory() + File.separator + "annots1";
+ String annots_java_util = annots_dir1 + File.separator + "java/util";
+ new File(annots_java_util).mkdirs();
+ Util.createFile(annots_java_util + File.separator + "Map.eea",
+ TEST_440687_MAP_EEA_CONTENT);
+
+ String annots_dir2 = Util.getOutputDirectory() + File.separator + "annots2";
+ String annots_java_lang = annots_dir2 + File.separator + "java/lang";
+ new File(annots_java_lang).mkdirs();
+ Util.createFile(annots_java_lang + File.separator + "Object.eea",
+ TEST_440687_OBJECT_EEA_CONTENT);
+
+ runTest440687("-annotationpath CLASSPATH -classpath \"" + annots_dir2 + "\"",
+ File.pathSeparator + annots_dir1, // extra source path
+ null, // expect normal error
+ true);
+}
+// Bug 440687 - [compiler][batch][null] improve command line option for external annotations
+// - two external annotation directories specifically configured.
+public void test440687b() throws IOException {
+
+ String annots_dir = Util.getOutputDirectory() + File.separator + "annots1";
+ String annots_java_util = annots_dir + File.separator + "java/util";
+ new File(annots_java_util).mkdirs();
+ Util.createFile(
+ annots_java_util + File.separator + "Map.eea",
+ TEST_440687_MAP_EEA_CONTENT);
+
+ String annots_dir2 = Util.getOutputDirectory() + File.separator + "annots2";
+ String annots_java_lang = annots_dir2 + File.separator + "java/lang";
+ new File(annots_java_lang).mkdirs();
+ Util.createFile(
+ annots_java_lang + File.separator + "Object.eea",
+ TEST_440687_OBJECT_EEA_CONTENT);
+
+ runTest440687("-annotationpath \"" + annots_dir + File.pathSeparator + annots_dir2 + "\" ",
+ "", // no extra source path
+ null, // expect normal error
+ true);
+}
+// Bug 440687 - [compiler][batch][null] improve command line option for external annotations
+// - single external annotation zip with 2 entries
+public void test440687c() throws IOException {
+
+ String annots_dir = Util.getOutputDirectory() + File.separator + "annots";
+ new File(annots_dir).mkdirs();
+ String annotsZipFile = annots_dir+ File.separator + "jre-annots.zip";
+ Util.createSourceZip(
+ new String[] {
+ "java/util/Map.eea",
+ TEST_440687_MAP_EEA_CONTENT,
+ "java/lang/Object.eea",
+ TEST_440687_OBJECT_EEA_CONTENT
+ },
+ annotsZipFile);
+
+ runTest440687("-annotationpath CLASSPATH -classpath \"" + annotsZipFile + "\"",
+ "", // no extra source path
+ null, // expect normal error
+ true);
+}
+// Bug 440687 - [compiler][batch][null] improve command line option for external annotations
+// - missing argument after -annotationpath
+public void test440687d() throws IOException {
+ runTest440687("-annotationpath", // missing argument
+ "",
+ "Missing argument to -annotationpath at \'-sourcepath\'\n",
+ false);
+}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=439750
public void test439750() {
this.runConformTest(
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathDirectory.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathDirectory.java
index af49bb5..27c067b 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathDirectory.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathDirectory.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -7,6 +7,8 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for
+ * Bug 440687 - [compiler][batch][null] improve command line option for external annotations
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.batch;
@@ -19,6 +21,7 @@
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
+import org.eclipse.jdt.internal.compiler.classfmt.ExternalAnnotationProvider;
import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
@@ -135,6 +138,15 @@
}
return null;
}
+@Override
+public boolean hasAnnotationFileFor(String qualifiedTypeName) {
+ int pos = qualifiedTypeName.lastIndexOf('/');
+ if (pos != -1 && (pos + 1 < qualifiedTypeName.length())) {
+ String fileName = qualifiedTypeName.substring(pos + 1) + '.' + ExternalAnnotationProvider.ANNOTION_FILE_EXTENSION;
+ return doesFileExist(fileName, qualifiedTypeName.substring(0, pos));
+ }
+ return false;
+}
public char[][][] findTypeNames(String qualifiedPackageName) {
if (!isPackage(qualifiedPackageName)) {
return null; // most common case
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJar.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJar.java
index 181ad0e..8d56c0a 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJar.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJar.java
@@ -9,6 +9,7 @@
* IBM Corporation - initial API and implementation
* Stephan Herrmann - Contribution for
* Bug 440477 - [null] Infrastructure for feeding external annotations into compilation
+ * Bug 440687 - [compiler][batch][null] improve command line option for external annotations
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.batch;
@@ -26,6 +27,7 @@
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
+import org.eclipse.jdt.internal.compiler.classfmt.ExternalAnnotationProvider;
import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
import org.eclipse.jdt.internal.compiler.util.ManifestAnalyzer;
@@ -40,7 +42,7 @@
protected ZipFile annotationZipFile;
protected boolean closeZipFileAtEnd;
protected Hashtable packageCache;
-protected String annotationPath;
+protected List<String> annotationPaths;
public ClasspathJar(File file, boolean closeZipFileAtEnd,
AccessRuleSet accessRuleSet, String destinationPath) {
@@ -102,12 +104,16 @@
try {
ClassFileReader reader = ClassFileReader.read(this.zipFile, qualifiedBinaryFileName);
if (reader != null) {
- if (this.annotationPath != null) {
+ if (this.annotationPaths != null) {
String qualifiedClassName = qualifiedBinaryFileName.substring(0, qualifiedBinaryFileName.length()-SuffixConstants.EXTENSION_CLASS.length()-1);
- try {
- this.annotationZipFile = reader.setExternalAnnotationProvider(this.annotationPath, qualifiedClassName, this.annotationZipFile, null);
- } catch (IOException e) {
- // don't let error on annotations fail class reading
+ for (String annotationPath : this.annotationPaths) {
+ try {
+ this.annotationZipFile = reader.setExternalAnnotationProvider(annotationPath, qualifiedClassName, this.annotationZipFile, null);
+ if (reader.hasAnnotationProvider())
+ break;
+ } catch (IOException e) {
+ // don't let error on annotations fail class reading
+ }
}
}
return new NameEnvironmentAnswer(reader, fetchAccessRestriction(qualifiedBinaryFileName));
@@ -119,6 +125,10 @@
}
return null;
}
+@Override
+public boolean hasAnnotationFileFor(String qualifiedTypeName) {
+ return this.zipFile.getEntry(qualifiedTypeName+'.'+ExternalAnnotationProvider.ANNOTION_FILE_EXTENSION) != null;
+}
public char[][][] findTypeNames(String qualifiedPackageName) {
if (!isPackage(qualifiedPackageName))
return null; // most common case
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 69f26d2..bcc420b 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -7,6 +7,8 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for
+ * Bug 440687 - [compiler][batch][null] improve command line option for external annotations
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.batch;
@@ -17,8 +19,10 @@
import java.util.Iterator;
import java.util.List;
import java.util.Set;
+import java.util.zip.ZipFile;
import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
@@ -68,6 +72,11 @@
* Initialize the entry
*/
void initialize() throws IOException;
+ /**
+ * Can the current location provide an external annotation file for the given type?
+ * @param qualifiedTypeName type name in qualified /-separated notation.
+ */
+ boolean hasAnnotationFileFor(String qualifiedTypeName);
}
public interface ClasspathSectionProblemReporter {
void invalidClasspathSection(String jarFilePath);
@@ -103,6 +112,7 @@
protected Classpath[] classpaths;
Set knownFileNames;
+ protected boolean annotationsFromClasspath; // should annotation files be read from the classpath (vs. explicit separate path)?
/*
classPathNames is a collection is Strings representing the full path of each class path
@@ -126,7 +136,7 @@
}
initializeKnownFileNames(initialFileNames);
}
-protected FileSystem(Classpath[] paths, String[] initialFileNames) {
+protected FileSystem(Classpath[] paths, String[] initialFileNames, boolean annotationsFromClasspath) {
final int length = paths.length;
int counter = 0;
this.classpaths = new FileSystem.Classpath[length];
@@ -144,6 +154,7 @@
System.arraycopy(this.classpaths, 0, (this.classpaths = new FileSystem.Classpath[counter]), 0, counter);
}
initializeKnownFileNames(initialFileNames);
+ this.annotationsFromClasspath = annotationsFromClasspath;
}
public static Classpath getClasspath(String classpathName, String encoding, AccessRuleSet accessRuleSet) {
return getClasspath(classpathName, encoding, false, accessRuleSet, null);
@@ -248,6 +259,24 @@
: path.replace('/', '\\');
}
private NameEnvironmentAnswer findClass(String qualifiedTypeName, char[] typeName, boolean asBinaryOnly){
+ NameEnvironmentAnswer answer = internalFindClass(qualifiedTypeName, typeName, asBinaryOnly);
+ if (this.annotationsFromClasspath && answer != null && answer.getBinaryType() instanceof ClassFileReader) {
+ for (int i = 0, length = this.classpaths.length; i < length; i++) {
+ Classpath classpathEntry = this.classpaths[i];
+ if (classpathEntry.hasAnnotationFileFor(qualifiedTypeName)) {
+ ZipFile zip = classpathEntry instanceof ClasspathJar ? ((ClasspathJar) classpathEntry).zipFile : null;
+ try {
+ ((ClassFileReader) answer.getBinaryType()).setExternalAnnotationProvider(classpathEntry.getPath(), qualifiedTypeName, zip, null);
+ break;
+ } catch (IOException e) {
+ // ignore broken entry, keep searching
+ }
+ }
+ }
+ }
+ return answer;
+}
+private NameEnvironmentAnswer internalFindClass(String qualifiedTypeName, char[] typeName, boolean asBinaryOnly){
if (this.knownFileNames.contains(qualifiedTypeName)) return null; // looking for a file which we know was provided at the beginning of the compilation
String qualifiedBinaryFileName = qualifiedTypeName + SUFFIX_STRING_class;
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 93554e9..5abfda0 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
@@ -20,6 +20,7 @@
* bug 388281 - [compiler][null] inheritance of null annotations as an option
* bug 381443 - [compiler][null] Allow parameter widening from @NonNull to unannotated
* Bug 440477 - [null] Infrastructure for feeding external annotations into compilation
+ * Bug 440687 - [compiler][batch][null] improve command line option for external annotations
* Jesper S Moller - Contributions for
* bug 407297 - [1.8][compiler] Control generation of parameter names by option
* Mat Booth - Contribution for bug 405176
@@ -1287,6 +1288,10 @@
return bundle;
}
}
+
+ // used with -annotationpath to declare that annotations should be read from the classpath:
+ private static final String ANNOTATION_SOURCE_CLASSPATH = "CLASSPATH"; //$NON-NLS-1$
+
// javadoc analysis tuning
boolean enableJavadocOn;
@@ -1297,8 +1302,9 @@
/* Bundle containing messages */
public ResourceBundle bundle;
protected FileSystem.Classpath[] checkedClasspaths;
- // path to external annotations:
- protected String annotationPath;
+ // paths to external annotations:
+ protected List<String> annotationPaths;
+ protected boolean annotationsFromClasspath;
public Locale compilerLocale;
public CompilerOptions compilerOptions; // read-only
@@ -1769,7 +1775,8 @@
ArrayList classpaths = new ArrayList(DEFAULT_SIZE_CLASSPATH);
ArrayList extdirsClasspaths = null;
ArrayList endorsedDirClasspaths = null;
- this.annotationPath = null;
+ this.annotationPaths = null;
+ this.annotationsFromClasspath = false;
int index = -1;
int filesCount = 0;
@@ -2660,7 +2667,17 @@
continue;
case INSIDE_ANNOTATIONPATH_start:
mode = DEFAULT;
- this.annotationPath = currentArg;
+ if (currentArg.isEmpty() || currentArg.charAt(0) == '-')
+ throw new IllegalArgumentException(this.bind("configure.missingAnnotationPath", currentArg)); //$NON-NLS-1$
+ if (ANNOTATION_SOURCE_CLASSPATH.equals(currentArg)) {
+ this.annotationsFromClasspath = true;
+ } else {
+ if (this.annotationPaths == null)
+ this.annotationPaths = new ArrayList<String>();
+ StringTokenizer tokens = new StringTokenizer(currentArg, File.pathSeparator);
+ while (tokens.hasMoreTokens())
+ this.annotationPaths.add(tokens.nextToken());
+ }
continue;
}
@@ -3060,7 +3077,8 @@
}
public FileSystem getLibraryAccess() {
- return new FileSystem(this.checkedClasspaths, this.filenames);
+ return new FileSystem(this.checkedClasspaths, this.filenames,
+ this.annotationsFromClasspath && CompilerOptions.ENABLED.equals(this.options.get(CompilerOptions.OPTION_AnnotationBasedNullAnalysis)));
}
/*
@@ -4572,10 +4590,10 @@
classpaths.toArray(this.checkedClasspaths);
this.logger.logClasspath(this.checkedClasspaths);
- if (this.annotationPath != null) {
+ if (this.annotationPaths != null && CompilerOptions.ENABLED.equals(this.options.get(CompilerOptions.OPTION_AnnotationBasedNullAnalysis))) {
for (FileSystem.Classpath cp : this.checkedClasspaths) {
if (cp instanceof ClasspathJar)
- ((ClasspathJar) cp).annotationPath = this.annotationPath;
+ ((ClasspathJar) cp).annotationPaths = this.annotationPaths;
}
}
}
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
index 905f39f..5f6a1d9 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
@@ -15,6 +15,7 @@
# bug 365208 - [compiler][batch] command line options for annotation based null analysis
# bug 374605 - Unreasonable warning for enum-based switch statements
# bug 388281 - [compiler][null] inheritance of null annotations as an option
+# bug 440687 - [compiler][batch][null] improve command line option for external annotations
# Alan Moraes <alan@kelon.org> - Contribution for bug 383644
# Jesper S Moller - Contribution for bug 407297 - [1.8][compiler] Control generation of parameter names by option
###############################################################################
@@ -111,6 +112,7 @@
### null annotations
configure.invalidNullAnnot = Token {0} is not in the expected format "nullAnnot(<non null annotation name> | <nullable annotation name> | <non-null by default annotation name>)"
+configure.missingAnnotationPath = Missing argument to -annotationpath at ''{0}''
### requestor
requestor.error = {0}. ERROR in {1}
@@ -263,9 +265,11 @@
\ -Xemacs used to enable emacs-style output in the console.\n\
\ It does not affect the xml log output\n\
\ -missingNullDefault report missing default nullness annotation\n\
-\ -annotationpath <path>\n\
-\ Path to a base directory or zip file holding external\n\
-\ annotations to support annotation-based null analysis\n\
+\ -annotationpath <directories and ZIP archives separated by {0}>\n\
+\ specify locations where to find external annotations\n\
+\ to support annotation-based null analysis.\n\
+\ The special name CLASSPATH will cause lookup of\n\
+\ external annotations from the classpath and sourcepath.\n\
\ \n\
\ -? -help print this help message\n\
\ -v -version print compiler version\n\
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java
index 9fbcb34..0e7bb06 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java
@@ -10,6 +10,7 @@
* Stephan Herrmann - Contribution for
* Bug 365992 - [builder] [null] Change of nullness for a parameter doesn't trigger a build for the files that call the method
* Bug 440477 - [null] Infrastructure for feeding external annotations into compilation
+ * Bug 440687 - [compiler][batch][null] improve command line option for external annotations
* Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
* bug 407191 - [1.8] Binary access support for type annotations
*******************************************************************************/
@@ -446,6 +447,9 @@
this.annotationProvider = new ExternalAnnotationProvider(zipFile.getInputStream(entry), String.valueOf(getName()));
return zipFile;
}
+public boolean hasAnnotationProvider() {
+ return this.annotationProvider != null;
+}
/**
* Conditionally add external annotations to the mix.
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NameEnvironmentWithProgress.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NameEnvironmentWithProgress.java
index f5bc4e8..e907680 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NameEnvironmentWithProgress.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NameEnvironmentWithProgress.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010 IBM Corporation and others.
+ * Copyright (c) 2010, 2015 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
@@ -7,6 +7,8 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for
+ * Bug 440687 - [compiler][batch][null] improve command line option for external annotations
*******************************************************************************/
package org.eclipse.jdt.core.dom;
@@ -26,7 +28,7 @@
IProgressMonitor monitor;
public NameEnvironmentWithProgress(Classpath[] paths, String[] initialFileNames, IProgressMonitor monitor) {
- super(paths, initialFileNames);
+ super(paths, initialFileNames, false);
setMonitor(monitor);
}
private void checkCanceled() {