Bug 522401 - [9][null] make external annotations work with modules
- also make sure projects get deleted in testBug522503, and only execute
if on jre9
Change-Id: I9401bafbd4ef29e5836e04d1d7f3b43df980f72b
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java
index de8f39a..b7b8c48 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java
@@ -208,6 +208,7 @@
NullAnnotationModelTests.class,
ExternalAnnotations17Test.class,
ExternalAnnotations18Test.class,
+ ExternalAnnotations9Test.class,
// Java model changes related to Java 8
JavaElement8Tests.class,
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations9Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations9Test.java
new file mode 100644
index 0000000..e3b20f1
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations9Test.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Till Brychcy 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:
+ * Till Brychcy - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.model;
+
+import java.util.Hashtable;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.jdt.core.IJavaModelMarker;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.tests.util.AbstractCompilerTest;
+
+import junit.framework.Test;
+
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class ExternalAnnotations9Test extends ExternalAnnotations18Test {
+
+ public ExternalAnnotations9Test(String name) {
+ super(name, "9", "JCL19_LIB");
+ }
+
+ // Static initializer to specify tests subset using TESTS_* static variables
+ // All specified tests which do not belong to the class are skipped...
+ static {
+// TESTS_NAMES = new String[] {"testBug522401"};
+ }
+
+ public static Test suite() {
+ return buildModelTestSuite(ExternalAnnotations9Test.class, BYTECODE_DECLARATION_ORDER);
+ }
+
+ public String getSourceWorkspacePath() {
+ // we read individual projects from within this folder:
+ return super.getSourceWorkspacePathBase()+"/ExternalAnnotations9";
+ }
+
+ protected boolean hasJRE19() {
+ return ((AbstractCompilerTest.getPossibleComplianceLevels() & AbstractCompilerTest.F_9) != 0);
+ }
+
+ /** Project with real JRE. */
+ public void testBug522401() throws Exception {
+ if (!hasJRE19()) {
+ System.out.println("Skipping ExternalAnnotations9Test.testBug522401(), needs JRE9");
+ return;
+ }
+ Hashtable options = JavaCore.getOptions();
+ try {
+ setupJavaProject("Test2");
+ this.project.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
+ IMarker[] markers = this.project.getProject().findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
+ assertNoMarkers(markers);
+ } finally {
+ JavaCore.setOptions(options);
+ }
+ }
+}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java
index c43096f..1bacd96 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java
@@ -5720,42 +5720,48 @@
}
public void testBug522503() throws Exception {
- IJavaProject p1 = setupModuleProject("mod.one",
- new String[] {
+ if (!isJRE9) return;
+ try {
+ IJavaProject p1 = setupModuleProject("mod.one",
+ new String[] {
+ "src/module-info.java",
+ "module mod.one {\n" +
+ " exports p1;\n" +
+ "}\n",
+ "src/p1/API.java",
+ "package p1;\n" +
+ "public class API {}\n"
+ });
+ IClasspathAttribute[] attr = { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") };
+ IClasspathEntry[] deps = { JavaCore.newLibraryEntry(p1.getOutputLocation(), null, null, null, attr, false) };
+ String[] sources2 = new String[] {
"src/module-info.java",
- "module mod.one {\n" +
- " exports p1;\n" +
+ "module mod.two {\n" +
+ " requires mod.one;\n" +
"}\n",
- "src/p1/API.java",
- "package p1;\n" +
- "public class API {}\n"
- });
- IClasspathAttribute[] attr = { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") };
- IClasspathEntry[] deps = { JavaCore.newLibraryEntry(p1.getOutputLocation(), null, null, null, attr, false) };
- String[] sources2 = new String[] {
- "src/module-info.java",
- "module mod.two {\n" +
- " requires mod.one;\n" +
- "}\n",
- "src/client/Client.java",
- "package client;\n" +
- "import p1.API;\n" +
- "public class Client {\n" +
- " API api;\n" +
- "}\n"
- };
- IJavaProject p2 = setupModuleProject("mod.two", sources2, deps);
- p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
- assertNoErrors();
-
- this.problemRequestor.reset();
- ICompilationUnit cu = getCompilationUnit("/mod.two/src/client/Client.java");
- cu.getWorkingCopy(this.wcOwner, null);
- assertProblems(
- "Unexpected problems",
- "----------\n" +
- "----------\n",
- this.problemRequestor);
+ "src/client/Client.java",
+ "package client;\n" +
+ "import p1.API;\n" +
+ "public class Client {\n" +
+ " API api;\n" +
+ "}\n"
+ };
+ IJavaProject p2 = setupModuleProject("mod.two", sources2, deps);
+ p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
+ assertNoErrors();
+
+ this.problemRequestor.reset();
+ ICompilationUnit cu = getCompilationUnit("/mod.two/src/client/Client.java");
+ cu.getWorkingCopy(this.wcOwner, null);
+ assertProblems(
+ "Unexpected problems",
+ "----------\n" +
+ "----------\n",
+ this.problemRequestor);
+ } finally {
+ deleteProject("mod.one");
+ deleteProject("mod.two");
+ }
}
protected void assertNoErrors() throws CoreException {
diff --git a/org.eclipse.jdt.core.tests.model/workspace/ExternalAnnotations9/Test2/.classpath b/org.eclipse.jdt.core.tests.model/workspace/ExternalAnnotations9/Test2/.classpath
new file mode 100644
index 0000000..611bff8
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/ExternalAnnotations9/Test2/.classpath
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.core.tests.model.TEST_CONTAINER">
+ <attributes>
+ <attribute name="annotationpath" value="annots"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.jdt.core.tests.model/workspace/ExternalAnnotations9/Test2/.project b/org.eclipse.jdt.core.tests.model/workspace/ExternalAnnotations9/Test2/.project
new file mode 100644
index 0000000..1b369ff
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/ExternalAnnotations9/Test2/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>Test2</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/org.eclipse.jdt.core.tests.model/workspace/ExternalAnnotations9/Test2/annots/java/util/Map.eea b/org.eclipse.jdt.core.tests.model/workspace/ExternalAnnotations9/Test2/annots/java/util/Map.eea
new file mode 100644
index 0000000..bf24983
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/ExternalAnnotations9/Test2/annots/java/util/Map.eea
@@ -0,0 +1,4 @@
+class java/util/Map
+get
+ (Ljava/lang/Object;)TV;
+ (Ljava/lang/Object;)T0V;
diff --git a/org.eclipse.jdt.core.tests.model/workspace/ExternalAnnotations9/Test2/src/test1/Test1.java b/org.eclipse.jdt.core.tests.model/workspace/ExternalAnnotations9/Test2/src/test1/Test1.java
new file mode 100644
index 0000000..a2da2b3
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/ExternalAnnotations9/Test2/src/test1/Test1.java
@@ -0,0 +1,13 @@
+package test1;
+
+import java.util.Map;
+import org.eclipse.jdt.annotation.NonNullByDefault; // note: if org.eclipse.jdt.annotation.* was used, no problem appeared
+
+@NonNullByDefault
+public class Test1 {
+ void test(Map<String,Test1> map, String key) {
+ Test1 v = map.get(key);
+ if (v == null)
+ throw new RuntimeException(); // should not be reported as dead code, although V is a '@NonNull Test1'
+ }
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ExternalAnnotationProvider.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ExternalAnnotationProvider.java
index 4dffadf..5787889 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ExternalAnnotationProvider.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ExternalAnnotationProvider.java
@@ -213,6 +213,10 @@
public IBinaryElementValuePair[] getElementValuePairs() {
return ElementValuePairInfo.NoMembers;
}
+ @Override
+ public boolean isExternalAnnotation() {
+ return true;
+ }
protected char[] getBinaryTypeName(char[][] name) {
return CharOperation.concat('L', CharOperation.concatWith(name, '/'), ';');
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryAnnotation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryAnnotation.java
index 7388428..36b1a17 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryAnnotation.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryAnnotation.java
@@ -24,4 +24,12 @@
* @return the list of element value pairs of the annotation
*/
IBinaryElementValuePair[] getElementValuePairs();
+
+/**
+ * @return true, if this an external annotation
+ */
+default boolean isExternalAnnotation() {
+ return false;
}
+}
+
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
index 13dc33f..da599ef 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
@@ -170,8 +170,10 @@
pairs[i] = new ElementValuePair(binaryPairs[i].getName(), convertMemberValue(binaryPairs[i].getValue(), env, missingTypeNames, false), null);
char[] typeName = annotationInfo.getTypeName();
- ReferenceBinding annotationType = env.getTypeFromConstantPoolName(typeName, 1, typeName.length - 1, false, missingTypeNames);
- return env.createUnresolvedAnnotation(annotationType, pairs);
+ LookupEnvironment env2 = annotationInfo.isExternalAnnotation() ? env.root : env;
+ ReferenceBinding annotationType = env2.getTypeFromConstantPoolName(typeName, 1, typeName.length - 1, false,
+ missingTypeNames);
+ return env2.createUnresolvedAnnotation(annotationType, pairs);
}
public static AnnotationBinding[] createAnnotations(IBinaryAnnotation[] annotationInfos, LookupEnvironment env, char[][][] missingTypeNames) {
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 22e32e4..0d7e0b3 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
@@ -1429,6 +1429,9 @@
public AnnotationBinding getNullableAnnotation() {
if (this.nullableAnnotation != null)
return this.nullableAnnotation;
+ if (this.root != this) {
+ return this.nullableAnnotation = this.root.getNullableAnnotation();
+ }
ReferenceBinding nullable = getResolvedType(this.globalOptions.nullableAnnotationName, null);
return this.nullableAnnotation = this.typeSystem.getAnnotationType(nullable, true);
}
@@ -1440,6 +1443,9 @@
public AnnotationBinding getNonNullAnnotation() {
if (this.nonNullAnnotation != null)
return this.nonNullAnnotation;
+ if (this.root != this) {
+ return this.nonNullAnnotation = this.root.getNonNullAnnotation();
+ }
ReferenceBinding nonNull = getResolvedType(this.globalOptions.nonNullAnnotationName, null);
return this.nonNullAnnotation = this.typeSystem.getAnnotationType(nonNull, true);
}
@@ -1482,6 +1488,9 @@
}
public boolean usesNullTypeAnnotations() {
+ if(this.root != this) {
+ return this.root.usesNullTypeAnnotations();
+ }
if (this.globalOptions.useNullTypeAnnotations != null)
return this.globalOptions.useNullTypeAnnotations;