Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Herrmann2018-11-04 16:14:47 +0000
committerStephan Herrmann2018-11-04 16:14:47 +0000
commit7bc42c0482b92818d18e57075fb11b5b56879406 (patch)
tree03614fb46a91ea7511ab904d60ab23fedc26f096
parente2be43953bc2de1c94661fffef56df58576b4cbe (diff)
downloadorg.eclipse.objectteams-7bc42c0482b92818d18e57075fb11b5b56879406.tar.gz
org.eclipse.objectteams-7bc42c0482b92818d18e57075fb11b5b56879406.tar.xz
org.eclipse.objectteams-7bc42c0482b92818d18e57075fb11b5b56879406.zip
Update jdt.core to I20181031-1800 for 4.10M2
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest2.java167
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java101
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java33
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java104
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java33
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java24
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java32
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugs9Tests.java2
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests9.java158
-rw-r--r--org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java8
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java7
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java3
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java5
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/IntersectionTypeBinding18.java2
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java2
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java42
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java8
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SplitPackageBinding.java2
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java12
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java3
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatusConstants.java12
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageFragmentRoot.java6
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java46
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Annotation.java2
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java56
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalFoldersManager.java10
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java3
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java2
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java9
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JrtPackageFragmentRoot.java5
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java21
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java1
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties1
-rw-r--r--org.eclipse.jdt.core/scripts/source/META-INF/MANIFEST.MF2
34 files changed, 859 insertions, 65 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest2.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest2.java
index 435318871..8d21da270 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest2.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest2.java
@@ -196,4 +196,169 @@ public void test006() throws Exception {
String expectedOutput = "// Compiled from X.java (version 11 : 55.0, super bit)";
checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput);
}
-} \ No newline at end of file
+public void testBug540123a() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "SecurePrefs.java",
+ "public class SecurePrefs {\n" +
+ " public SecurePrefs node (String s) {\n" +
+ " System.out.println(s);\n" +
+ " return null;\n" +
+ " }\n" +
+ "}",
+ "SecurePrefsRoot.java",
+ "public class SecurePrefsRoot extends SecurePrefs {\n" +
+ "\n" +
+ " public void foo() {\n" +
+ " SecurePrefs node = node(\"Hello\");\n" +
+ " if (node != null)\n" +
+ " System.out.println(node.toString());\n" +
+ " }\n" +
+ " \n" +
+ " public static void main(String[] args) {\n" +
+ " new SecurePrefsRoot().foo();\n" +
+ " }\n" +
+ "}"
+ },
+ "\"" + OUTPUT_DIR + File.separator + "SecurePrefsRoot.java\""
+ +" \"" + OUTPUT_DIR + File.separator + "SecurePrefs.java\""
+ + " -source 1.3 -target 1.2",
+ "",
+ "",
+ true);
+ String expectedOutput = "invokevirtual SecurePrefsRoot.node(java.lang.String) : SecurePrefs [14]";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "SecurePrefsRoot.class", "SecurePrefsRoot", expectedOutput);
+}
+public void testBug540123b() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "SecurePrefs.java",
+ "public class SecurePrefs {\n" +
+ " public SecurePrefs node (String s) {\n" +
+ " System.out.println(s);\n" +
+ " return null;\n" +
+ " }\n" +
+ "}",
+ "SecurePrefsRoot.java",
+ "public class SecurePrefsRoot extends SecurePrefs {\n" +
+ "\n" +
+ " public void foo() {\n" +
+ " SecurePrefs node = node(\"Hello\");\n" +
+ " if (node != null)\n" +
+ " System.out.println(node.toString());\n" +
+ " }\n" +
+ " \n" +
+ " public static void main(String[] args) {\n" +
+ " new SecurePrefsRoot().foo();\n" +
+ " }\n" +
+ "}"
+ },
+ "\"" + OUTPUT_DIR + File.separator + "SecurePrefsRoot.java\""
+ +" \"" + OUTPUT_DIR + File.separator + "SecurePrefs.java\""
+ + " -source 1.3",
+ "",
+ "",
+ true);
+ String expectedOutput = "invokevirtual SecurePrefsRoot.node(java.lang.String) : SecurePrefs [14]";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "SecurePrefsRoot.class", "SecurePrefsRoot", expectedOutput);
+}
+public void testBug540123c() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "SecurePrefs.java",
+ "public class SecurePrefs {\n" +
+ " public SecurePrefs node (String s) {\n" +
+ " System.out.println(s);\n" +
+ " return null;\n" +
+ " }\n" +
+ "}",
+ "SecurePrefsRoot.java",
+ "public class SecurePrefsRoot extends SecurePrefs {\n" +
+ "\n" +
+ " public void foo() {\n" +
+ " SecurePrefs node = node(\"Hello\");\n" +
+ " if (node != null)\n" +
+ " System.out.println(node.toString());\n" +
+ " }\n" +
+ " \n" +
+ " public static void main(String[] args) {\n" +
+ " new SecurePrefsRoot().foo();\n" +
+ " }\n" +
+ "}"
+ },
+ "\"" + OUTPUT_DIR + File.separator + "SecurePrefsRoot.java\""
+ +" \"" + OUTPUT_DIR + File.separator + "SecurePrefs.java\""
+ + " -target 1.3",
+ "",
+ "",
+ true);
+ String expectedOutput = "invokevirtual SecurePrefsRoot.node(java.lang.String) : SecurePrefs [14]";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "SecurePrefsRoot.class", "SecurePrefsRoot", expectedOutput);
+}
+public void testBug540123d() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "SecurePrefs.java",
+ "public class SecurePrefs {\n" +
+ " public SecurePrefs node (String s) {\n" +
+ " System.out.println(s);\n" +
+ " return null;\n" +
+ " }\n" +
+ "}",
+ "SecurePrefsRoot.java",
+ "public class SecurePrefsRoot extends SecurePrefs {\n" +
+ "\n" +
+ " public void foo() {\n" +
+ " SecurePrefs node = node(\"Hello\");\n" +
+ " if (node != null)\n" +
+ " System.out.println(node.toString());\n" +
+ " }\n" +
+ " \n" +
+ " public static void main(String[] args) {\n" +
+ " new SecurePrefsRoot().foo();\n" +
+ " }\n" +
+ "}"
+ },
+ "\"" + OUTPUT_DIR + File.separator + "SecurePrefsRoot.java\""
+ +" \"" + OUTPUT_DIR + File.separator + "SecurePrefs.java\""
+ + " -1.4",
+ "",
+ "",
+ true);
+ String expectedOutput = "invokevirtual SecurePrefsRoot.node(java.lang.String) : SecurePrefs [14]";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "SecurePrefsRoot.class", "SecurePrefsRoot", expectedOutput);
+}
+public void testBug540123e() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "SecurePrefs.java",
+ "public class SecurePrefs {\n" +
+ " public SecurePrefs node (String s) {\n" +
+ " System.out.println(s);\n" +
+ " return null;\n" +
+ " }\n" +
+ "}",
+ "SecurePrefsRoot.java",
+ "public class SecurePrefsRoot extends SecurePrefs {\n" +
+ "\n" +
+ " public void foo() {\n" +
+ " SecurePrefs node = node(\"Hello\");\n" +
+ " if (node != null)\n" +
+ " System.out.println(node.toString());\n" +
+ " }\n" +
+ " \n" +
+ " public static void main(String[] args) {\n" +
+ " new SecurePrefsRoot().foo();\n" +
+ " }\n" +
+ "}"
+ },
+ "\"" + OUTPUT_DIR + File.separator + "SecurePrefsRoot.java\""
+ +" \"" + OUTPUT_DIR + File.separator + "SecurePrefs.java\""
+ + " -1.3",
+ "",
+ "",
+ true);
+ String expectedOutput = "invokevirtual SecurePrefs.node(java.lang.String) : SecurePrefs [14]";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "SecurePrefsRoot.class", "SecurePrefsRoot", expectedOutput);
+}
+}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java
index dce0bd85b..99da258d2 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java
@@ -6375,5 +6375,106 @@ public void testBug532137() {
false
);
}
+
+public void testBug540313() {
+ Runner runner = new Runner();
+ runner.testFiles = new String[] {
+ "X/C120644mr.java",
+ "package X;\n" +
+ "\n" +
+ "public class C120644mr<V, X extends java.lang.Exception> extends X.C16280iv<V> {\n" +
+ "}\n"
+ };
+ runner.expectedCompilerLog =
+ "----------\n" +
+ "1. ERROR in X\\C120644mr.java (at line 3)\n" +
+ " public class C120644mr<V, X extends java.lang.Exception> extends X.C16280iv<V> {\n" +
+ " ^^^^^^^^^^\n" +
+ "X.C16280iv cannot be resolved to a type\n" +
+ "----------\n";
+ runner.runNegativeTest();
+}
+
+public void testBug540313a() {
+ Runner runner = new Runner();
+ runner.testFiles = new String[] {
+ "X/C120644mr.java",
+ "package X;\n" +
+ "\n" +
+ "class Outer {\n" +
+ " class Inner<Z> {}\n" +
+ "}\n" +
+ "public class C120644mr<V, X extends Outer> extends X.Inner<V> {\n" +
+ "}\n"
+ };
+ runner.expectedCompilerLog =
+ "----------\n" +
+ "1. ERROR in X\\C120644mr.java (at line 6)\n" +
+ " public class C120644mr<V, X extends Outer> extends X.Inner<V> {\n" +
+ " ^^^^^^^\n" +
+ "X.Inner cannot be resolved to a type\n" +
+ "----------\n";
+ runner.runNegativeTest();
+}
+
+public void testBug540313b() {
+ Runner runner = new Runner();
+ runner.testFiles = new String[] {
+ "X/C120644mr.java",
+ "package X;\n" +
+ "\n" +
+ "class Outer {\n" +
+ " class Inner<Z> {}\n" +
+ "}\n" +
+ "public class C120644mr<X extends Outer, V> {\n" +
+ " X.Inner<V> inner;\n" + // is this backed by JLS?
+ "}\n"
+ };
+ runner.runConformTest();
+}
+public void testBug478708() {
+ Runner runner = new Runner();
+ runner.testFiles = new String[] {
+ "bug/IInterface.java",
+ "package bug;\n" +
+ "\n" +
+ "public class IInterface {\n" +
+ "\n" +
+ "}\n",
+ "bug/AbstractA.java",
+ "package bug;\n" +
+ "\n" +
+ "public abstract class AbstractA<T extends IInterface> {\n" +
+ "\n" +
+ " public abstract class AbstractD<U> {\n" +
+ "\n" +
+ " }\n" +
+ "}\n",
+ "bug/AbstractC.java",
+ "package bug;\n" +
+ "\n" +
+ "\n" +
+ "public abstract class AbstractC<T extends IInterface> extends T.AbstractD<E> {\n" +
+ "\n" +
+ " public AbstractC(AbstractA<T> a) {\n" +
+ " a.super();\n" +
+ " }\n" +
+ "}\n",
+ "bug/E.java",
+ "package bug;\n" +
+ "\n" +
+ "public class E {\n" +
+ "\n" +
+ "}\n"
+ };
+ runner.expectedCompilerLog =
+ "----------\n" +
+ "1. ERROR in bug\\AbstractC.java (at line 4)\n" +
+ " public abstract class AbstractC<T extends IInterface> extends T.AbstractD<E> {\n" +
+ " ^^^^^^^^^^^\n" +
+ "T.AbstractD cannot be resolved to a type\n" +
+ "----------\n";
+ runner.runNegativeTest();
+}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
index f35658641..120b628ff 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
@@ -5536,7 +5536,7 @@ public void testBug470542() {
"1. ERROR in X.java (at line 5)\n" +
" process(missing::new);\n" +
" ^^^^^^^\n" +
- "missing cannot be resolved\n" +
+ "missing cannot be resolved to a type\n" +
"----------\n");
}
public void testBug471280_comment0() {
@@ -9424,4 +9424,35 @@ public void testBug508834_comment0() {
"}\n"
});
}
+ public void testBug539329() {
+ Runner runner = new Runner();
+ runner.testFiles = new String[] {
+ "Bug539329.java",
+ " import java.util.*;\n" +
+ " \n" +
+ " public class Bug539329 {\n" +
+ "\n" +
+ " public static Collection<Class<? extends Interface>> getClasses() {\n" +
+ " // This yields a compile error in 2018-09, but works in Photon.\n" +
+ " return Arrays.asList(One.class, Two.class, Three.class);\n" +
+ " }\n" +
+ "\n" +
+ " public static Collection<Class<? extends Interface>> getClassesThatWorks() {\n" +
+ " // This works surprisinly in both versions\n" +
+ " return Arrays.asList(One.class, Two.class);\n" +
+ " }\n" +
+ " }\n" +
+ "\n" +
+ " class One extends Parent<String> implements Interface { }\n" +
+ "\n" +
+ " class Two extends Parent<Integer> implements Interface { }\n" +
+ "\n" +
+ " class Three extends Parent<Object> implements Interface { }\n" +
+ "\n" +
+ " class Parent<T> { }\n" +
+ "\n" +
+ " interface Interface { }\n"
+ };
+ runner.runConformTest();
+ }
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java
index 2ac9f09d4..da0ddf9b4 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java
@@ -39,7 +39,7 @@ import junit.framework.Test;
public class LambdaExpressionsTest extends AbstractRegressionTest {
static {
- TESTS_NAMES = new String[] { "test449063"};
+// TESTS_NAMES = new String[] { "testBug540520"};
// TESTS_NUMBERS = new int[] { 50 };
// TESTS_RANGE = new int[] { 11, -1 };
}
@@ -1277,8 +1277,8 @@ public void test045() {
"----------\n" +
"5. ERROR in X.java (at line 15)\n" +
" i = X.Y::new;\n" +
- " ^\n" +
- "Y cannot be resolved or is not a field\n" +
+ " ^^^\n" +
+ "X.Y cannot be resolved to a type\n" +
"----------\n" +
"6. ERROR in X.java (at line 27)\n" +
" new X().new Y().f();\n" +
@@ -6997,6 +6997,104 @@ public void testBug531093() {
""
);
}
+public void testBug540520() {
+ Runner runner = new Runner();
+ runner.testFiles = new String[] {
+ "Run.java",
+ "import java.util.ArrayList;\n" +
+ "import java.util.HashMap;\n" +
+ "import java.util.List;\n" +
+ "import java.util.Map;\n" +
+ "import java.util.stream.Collectors;\n" +
+ "\n" +
+ "public class Run {\n" +
+ "\n" +
+ " public static void main(String[] args) {\n" +
+ " \n" +
+ " List<TypeDeptCount> list = new ArrayList<>();\n" +
+ " for(int i=0;i<10;i++) {\n" +
+ " TypeDeptCount ty = new TypeDeptCount();\n" +
+ " ty.setCykbbm(\"10\"+i);\n" +
+ " ty.setCount(i);\n" +
+ " }\n" +
+ " List<Map<String, Object>> datas = list.stream().collect(Collectors.groupingBy(TypeDeptCount::getType))\n" +
+ " .entrySet().stream().map(item -> item.getValue().stream().reduce(new HashMap<String, Object>() {\n" +
+ " private static final long serialVersionUID = 1L;\n" +
+ " {\n" +
+ " put(\"count\", 0);\n" +
+ " put(\"type\", item.getKey());\n" +
+ " }\n" +
+ " }, (data1, val) -> {\n" +
+ " data1.put(val.getCykbbm(), val.getCount());\n" +
+ " data1.put(\"count\", (Integer) data1.get(\"count\") + val.getCount());\n" +
+ " return data1;\n" +
+ " }, (data1, data2) -> {\n" +
+ " data2.put(\"count\", (Integer) data1.get(\"count\") + (Integer) data2.get(\"count\"));\n" +
+ " data1.putAll(data2);\n" +
+ " return data1;\n" +
+ " })).sorted((item1, item2) -> (Integer) item2.get(\"count\") - (Integer) item1.get(\"count\"))\n" +
+ " .collect(Collectors.toList());\n" +
+ " System.out.println(datas);\n" +
+ " }\n" +
+ "}\n",
+ "TypeDeptCount.java",
+ "public class TypeDeptCount {\n" +
+ "\n" +
+ " private String type;\n" +
+ " private String cykbbm;\n" +
+ " private Integer count;\n" +
+ " \n" +
+ " public String getType() {\n" +
+ " return type;\n" +
+ " }\n" +
+ " public void setType(String type) {\n" +
+ " this.type = type;\n" +
+ " }\n" +
+ " public String getCykbbm() {\n" +
+ " return cykbbm;\n" +
+ " }\n" +
+ " public void setCykbbm(String cykbbm) {\n" +
+ " this.cykbbm = cykbbm;\n" +
+ " }\n" +
+ " public Integer getCount() {\n" +
+ " return count;\n" +
+ " }\n" +
+ " public void setCount(Integer count) {\n" +
+ " this.count = count;\n" +
+ " }\n" +
+ "}\n"
+ };
+ runner.runConformTest();
+}
+public void testBug540631() {
+ Runner runner = new Runner();
+ runner.testFiles = new String[] {
+ "EclipseCompileBug.java",
+ "public enum EclipseCompileBug {\n" +
+ " /*\n" +
+ " * Next line fails with these errors in Eclipse, works with javac:\n" +
+ " * <li>Test cannot be resolved to a type\n" +
+ " * <li>Cannot reference a field before it is defined\n" +
+ " */\n" +
+ " Test(Test::new);\n" +
+ "\n" +
+ " @FunctionalInterface\n" +
+ " public interface IConstructor<T extends Object> {\n" +
+ " T apply();\n" +
+ " }\n" +
+ "\n" +
+ " private final IConstructor<?> constructor;\n" +
+ " private EclipseCompileBug (IConstructor<?> newObj) {\n" +
+ " constructor = newObj;\n" +
+ " }\n" +
+ " \n" +
+ " public static class Test {\n" +
+ " \n" +
+ " }\n" +
+ "}\n"
+ };
+ runner.runConformTest();
+}
public static Class testClass() {
return LambdaExpressionsTest.class;
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
index dea338945..0e9cab5c5 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
@@ -17738,4 +17738,37 @@ public void testBug536555() {
runner.javacTestOptions = JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings;
runner.runWarningTest();
}
+public void testBug540264() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "example/Example.java",
+ "package example;\n" +
+ "\n" +
+ "public abstract class Example {\n" +
+ " void f() {\n" +
+ " for (X.Y<Z> entry : x) {\n" +
+ " }\n" +
+ " }\n" +
+ "}\n" +
+ "",
+ },
+ getCompilerOptions(),
+ "----------\n" +
+ "1. ERROR in example\\Example.java (at line 5)\n" +
+ " for (X.Y<Z> entry : x) {\n" +
+ " ^\n" +
+ "X cannot be resolved to a type\n" +
+ "----------\n" +
+ "2. ERROR in example\\Example.java (at line 5)\n" +
+ " for (X.Y<Z> entry : x) {\n" +
+ " ^\n" +
+ "Z cannot be resolved to a type\n" +
+ "----------\n" +
+ "3. ERROR in example\\Example.java (at line 5)\n" +
+ " for (X.Y<Z> entry : x) {\n" +
+ " ^\n" +
+ "x cannot be resolved to a variable\n" +
+ "----------\n"
+ );
+}
}
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 f8253068a..3a4270269 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
@@ -11912,4 +11912,28 @@ public class ASTConverter15Test extends ConverterTestSetup {
assertTrue("Bad field definition", fields != null && fields.length == 1);
assertEquals("Type binding mismatch", elem, fields[0].getType());
}
+
+ public void testBug540313() throws JavaModelException {
+ this.workingCopy = getWorkingCopy("/Converter15/src/X/C120644mr.java", true/*resolve*/);
+ String contents =
+ "package X;\n" +
+ "\n" +
+ "/* renamed from: X.4mr */\n" +
+ "public class C120644mr<V, X extends java.lang.Exception> extends X.C16280iv<V> {\n" +
+ "}\n";
+ ASTNode node = buildAST(
+ contents,
+ this.workingCopy,
+ false);
+ assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
+ CompilationUnit unit = (CompilationUnit) node;
+ String expectedError = "X.C16280iv cannot be resolved to a type";
+ assertProblemsSize(unit, 1, expectedError);
+ node = (ASTNode) unit.types().get(0);
+ assertEquals("Not a type declaration", ASTNode.TYPE_DECLARATION, node.getNodeType());
+ Type superclassType = ((TypeDeclaration) node).getSuperclassType();
+ ITypeBinding typeBinding = superclassType.resolveBinding();
+ assertNull("Binding", typeBinding);
+ }
+
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java
index 1fed55bda..1ebb8cb05 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2018 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -49,6 +49,7 @@ import org.eclipse.core.runtime.ILogListener;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.content.IContentDescription;
@@ -7400,4 +7401,33 @@ public void testClasspathTestSourceValidation5() throws CoreException {
this.deleteProject("P");
}
}
+
+public void testBug539998() throws CoreException {
+ try {
+ IJavaProject proj1TestOnly = this.createJavaProject("P1", new String[] {}, "bin-tests");
+ IClasspathEntry[] originalCP1 = proj1TestOnly.getRawClasspath();
+
+ IClasspathEntry[] newCP1 = new IClasspathEntry[originalCP1.length + 1];
+ System.arraycopy(originalCP1, 0, newCP1, 0, originalCP1.length);
+ newCP1[originalCP1.length] = JavaCore.newSourceEntry(new Path("/P1/src-tests"), null, null, null,
+ new IClasspathAttribute[] { JavaCore.newClasspathAttribute(IClasspathAttribute.TEST, "true") });
+ proj1TestOnly.setRawClasspath(newCP1, new NullProgressMonitor());
+ IJavaProject proj = this.createJavaProject("P2", new String[] {}, "bin");
+ IClasspathEntry[] originalCP = proj.getRawClasspath();
+
+ IClasspathEntry[] newCP = new IClasspathEntry[originalCP.length + 2];
+ System.arraycopy(originalCP, 0, newCP, 0, originalCP.length);
+ newCP[originalCP.length] = JavaCore.newSourceEntry(new Path("/P2/src"), null, null, null,
+ new IClasspathAttribute[] {});
+ newCP[originalCP.length + 1] = JavaCore.newProjectEntry(new Path("/P1/"));
+
+ IJavaModelStatus status = JavaConventions.validateClasspath(proj, newCP, proj.getOutputLocation());
+
+ assertStatus("should complain",
+ "Project has only main sources but depends on project 'P1' which has only test sources.",
+ status);
+ } finally {
+ this.deleteProjects(new String[] { "P1", "P2" });
+ }
+}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugs9Tests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugs9Tests.java
index 4e6d0c39a..39240b754 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugs9Tests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugs9Tests.java
@@ -3500,7 +3500,7 @@ public void testBug519151_023() throws Exception {
project1.open(null);
waitUntilIndexesReady();
SearchPattern pattern = SearchPattern.createPattern("module519151/pack519151.X519151", IJavaSearchConstants.TYPE, DECLARATIONS, ERASURE_RULE);
- IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaProject[] {project1, project2});
+ IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaProject[] {project2, project1});
search(pattern, scope, this.resultCollector);
assertSearchResults(
"lib/lib519151.jar pack519151.X519151 EXACT_MATCH",
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests9.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests9.java
index 8200653c4..9e769451b 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests9.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests9.java
@@ -16,6 +16,8 @@ package org.eclipse.jdt.core.tests.model;
import java.io.File;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
@@ -23,6 +25,7 @@ import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IClasspathAttribute;
@@ -43,6 +46,10 @@ import org.eclipse.jdt.internal.core.search.indexing.IndexRequest;
import junit.framework.Test;
public class ResolveTests9 extends AbstractJavaModelTests {
+ private static final int MODULE = 1;
+ private static final int WITHOUT_TEST = 2;
+ private static final int TEST = 4;
+
ICompilationUnit wc = null;
static {
@@ -91,6 +98,30 @@ public class ResolveTests9 extends AbstractJavaModelTests {
}
super.tearDown();
}
+
+ void addProjectEntry(IJavaProject thisProject, IJavaProject otherProject, int flags) throws JavaModelException {
+ addClasspathEntry(thisProject,
+ JavaCore.newProjectEntry(otherProject.getPath(), null, false, attributes(flags), false));
+ }
+ IClasspathAttribute[] attributes(int flags) {
+ List<IClasspathAttribute> attrs = new ArrayList<>();
+ if ((flags & MODULE) != 0)
+ attrs.add(JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true"));
+ if ((flags & WITHOUT_TEST) != 0)
+ attrs.add(JavaCore.newClasspathAttribute(IClasspathAttribute.WITHOUT_TEST_CODE, "true"));
+ if ((flags & TEST) != 0)
+ attrs.add(JavaCore.newClasspathAttribute(IClasspathAttribute.TEST, "true"));
+ return attrs.toArray(new IClasspathAttribute[attrs.size()]);
+ }
+ void addTestSrc(IJavaProject prj) throws CoreException {
+ IPath path = prj.getProject().getFullPath();
+ IClasspathEntry testSrc = JavaCore.newSourceEntry(path.append(new Path("src-test")),
+ null, null, path.append(new Path("bin-test")),
+ new IClasspathAttribute[] {JavaCore.newClasspathAttribute(IClasspathAttribute.TEST, "true")});
+ addClasspathEntry(prj, testSrc);
+ createFolder(prj.getElementName() + "/src-test");
+ }
+
public void testModuleInfo_serviceImplementation_OK() throws CoreException {
IFile modInfo = null;
try {
@@ -399,4 +430,131 @@ public class ResolveTests9 extends AbstractJavaModelTests {
deleteProject(mod);
}
}
+
+ public void testBug537934() throws Exception {
+ if (!isJRE9) {
+ System.err.println("Test "+getName()+" requires a JRE 9");
+ return;
+ }
+ IJavaProject gui = null;
+ IJavaProject model = null;
+ IJavaProject type = null;
+ IJavaProject logg = null;
+ try {
+ // ---- module log:
+ // - has log4j on the module path
+ logg = createJava9ProjectWithJREAttributes("com.igorion.log", new String[] {"src"}, attributes(MODULE));
+ String jarAbsPath = logg.getProject().getLocation()+"/log4j.jar";
+ createJar(new String[] {
+ "log4j/Dummy.java",
+ "package log4j;\n" +
+ "public class Dummy {}\n"
+ },
+ jarAbsPath);
+ addLibraryEntry(logg, new Path(jarAbsPath), null, null, null, null, attributes(MODULE), false);
+ createFolder("com.igorion.log/src/com/igorion/log");
+ createFile("com.igorion.log/src/com/igorion/log/ILog.java",
+ "package com.igorion.log;\n public interface ILog {}\n");
+ createFile("com.igorion.log/src/module-info.java",
+ "module com.igorion.log {\n" +
+ " requires log4j;\n" +
+ " exports com.igorion.log;\n" +
+ "}\n");
+ logg.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
+ IMarker[] markers = logg.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+ assertMarkers("markers in com.igorion.log",
+ "Name of automatic module \'log4j\' is unstable, it is derived from the module\'s file name.",
+ markers);
+
+ // ---- module type:
+ // - has test sources
+ type = createJava9Project("com.igorion.type");
+ createFolder("com.igorion.type/src/com/igorion/type");
+ createFile("com.igorion.type/src/com/igorion/type/IOther.java",
+ "package com.igorion.type;\n public interface IOther {}\n");
+ createFile("com.igorion.type/src/module-info.java",
+ "module com.igorion.type {\n" +
+ " exports com.igorion.type;\n" +
+ "}\n");
+ addTestSrc(type);
+ type.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
+ markers = type.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+ assertMarkers("markers in com.igorion.type", "", markers);
+
+ // ---- module model:
+ // - has test sources
+ // - has log4j on the module path
+ // - has modules log & type on the module path without_test_code
+ model = createJava9ProjectWithJREAttributes("com.igorion.model", new String[] {"src"}, attributes(MODULE));
+ createFolder("com.igorion.model/src/com/igorion/model/define");
+ createFile("com.igorion.model/src/com/igorion/model/IModel.java",
+ "package com.igorion.model;\n public interface IModel {}\n");
+ createFile("com.igorion.model/src/com/igorion/model/define/Model.java",
+ "package com.igorion.model.define;\n" +
+ "import com.igorion.model.IModel;\n" +
+ "import java.util.Optional;\n" +
+ "public class Model {\n" +
+ " public static synchronized Optional<IModel> instance() { return Optional.empty(); }\n" +
+ "}\n");
+ createFile("com.igorion.model/src/module-info.java",
+ "module com.igorion.model {\n" +
+ " requires com.igorion.log;\n" +
+ " exports com.igorion.model;\n" +
+ " exports com.igorion.model.define;\n" +
+ "}\n");
+ addTestSrc(model);
+ addLibraryEntry(model, new Path(jarAbsPath), null, null, null, null, attributes(MODULE), false);
+ addProjectEntry(model, logg, MODULE|WITHOUT_TEST);
+ addProjectEntry(model, type, MODULE|WITHOUT_TEST);
+ model.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
+ markers = model.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+ assertMarkers("markers in com.igorion.model", "", markers);
+
+ // ---- module gui:
+ // - has log4j on the module path for test code
+ // - has modules type, model, log on the module path without_test_code (order is significant)
+ gui = createJava9ProjectWithJREAttributes("com.igorion.gui", new String[] {"src"}, attributes(MODULE));
+ addTestSrc(gui);
+ createFolder("com.igorion.gui/src/com/igorion/gui");
+ String source =
+ "package com.igorion.gui;\n" +
+ "import com.igorion.model.IModel;\n" +
+ "import com.igorion.model.define.Model;\n" +
+ "import java.util.Optional;\n" +
+ "public class Reproduce {\n" +
+ " static void meth() {\n" +
+ " Optional<IModel> oModel = Model.instance();\n" +
+ " if (oModel.isPresent())\n" +
+ " oModel.get();\n" +
+ " }\n" +
+ "}\n";
+ createFile("com.igorion.gui/src/com/igorion/gui/Reproduce.java", source);
+ createFile("com.igorion.gui/src/module-info.java",
+ "module com.igorion.gui {\n" +
+ " requires com.igorion.type;\n" +
+ " requires com.igorion.model;\n" +
+ "}\n");
+ addLibraryEntry(gui, new Path(jarAbsPath), null, null, null, null, attributes(MODULE|TEST), false);
+ addProjectEntry(gui, type, MODULE|WITHOUT_TEST);
+ addProjectEntry(gui, model, MODULE|WITHOUT_TEST);
+ addProjectEntry(gui, logg, MODULE|WITHOUT_TEST);
+ gui.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
+ markers = gui.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+ assertMarkers("markers in com.igorion.gui", "", markers);
+
+ // test that selection finds a fully resolved type Optional<IModel>:
+ ICompilationUnit unit = getCompilationUnit("com.igorion.gui/src/com/igorion/gui/Reproduce.java");
+ int start = source.indexOf("get(");
+ IJavaElement[] selected = unit.codeSelect(start, 3);
+ assertElementsEqual(
+ "Unexpected elements",
+ "get() [in Optional [in Optional.class [in java.util [in <module:java.base>]]]]",
+ selected);
+ } finally {
+ deleteProject(gui);
+ deleteProject(model);
+ deleteProject(type);
+ deleteProject(logg);
+ }
+ }
}
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 9986bdb1c..d1030b9b6 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
@@ -5583,11 +5583,13 @@ protected void validateOptions(boolean didSpecifyCompliance) {
|| CompilerOptions.VERSION_1_6.equals(source)) {
this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
} else {
- if (CompilerOptions.versionToJdkLevel(source) > 0)
+ // 1.3 is the lowest version that can be specified as -source
+ // The following check will ensure '0' is ignored.
+ if (CompilerOptions.versionToJdkLevel(source) >= ClassFileConstants.JDK1_7)
this.options.put(CompilerOptions.OPTION_TargetPlatform, source);
}
} else {
- if (CompilerOptions.versionToJdkLevel(version) > 0) {
+ if (CompilerOptions.versionToJdkLevel(version) > ClassFileConstants.JDK10) {
this.options.put(CompilerOptions.OPTION_Source, version);
this.options.put(CompilerOptions.OPTION_TargetPlatform, version);
}
@@ -5620,7 +5622,7 @@ protected void validateOptions(boolean didSpecifyCompliance) {
if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_10);
if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_10);
} else {
- if (CompilerOptions.versionToJdkLevel(version) > 0) {
+ if (CompilerOptions.versionToJdkLevel(version) > ClassFileConstants.JDK10) {
if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, version);
if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, version);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
index 5bb5fa732..0e0790c20 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
@@ -1495,7 +1495,7 @@ public class LambdaExpression extends FunctionalExpression implements IPolyExpre
if (((LambdaExpression) lambdaScope2.referenceContext).sourceStart == LambdaExpression.this.sourceStart) {
// local type within this lambda needs replacement:
TypeBinding substType = this.localTypes2.get(orgLocal.sourceStart);
- if (substType != null) {
+ if (substType != null && substType != orgLocal) { //$IDENTITY-COMPARISON$
orgLocal.transferConstantPoolNameTo(substType);
return substType;
}
@@ -1521,10 +1521,11 @@ public class LambdaExpression extends FunctionalExpression implements IPolyExpre
/**
* Perform substitution with a {@link LocalTypeSubstitutor} on all types mentioned in the given method binding.
*/
- void updateLocalTypesInMethod(MethodBinding method) {
+ boolean updateLocalTypesInMethod(MethodBinding method) {
if (this.localTypes == null)
- return;
+ return false;
updateLocalTypesInMethod(method, new LocalTypeSubstitutor(this.localTypes), new NullSubstitution(this.scope.environment()));
+ return true;
}
private void updateLocalTypesInMethod(MethodBinding method, Substitutor substor, Substitution subst) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
index ae5b3f49e..2634ce355 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
@@ -424,11 +424,10 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl
if (variableTypeInferenceError) {
return;
}
-
boolean resolveAnnotationsEarly = false;
if (scope.environment().usesNullTypeAnnotations()
&& !isTypeNameVar // 'var' does not provide a target type
- && variableType.isValidBinding()) {
+ && variableType != null && variableType.isValidBinding()) {
resolveAnnotationsEarly = this.initialization instanceof Invocation
|| this.initialization instanceof ConditionalExpression
|| this.initialization instanceof ArrayInitializer;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
index 26f75ffb0..62c16d28b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
@@ -372,6 +372,11 @@ public void resolve(BlockScope scope) {
if (methodType == null)
return;
+ if (methodType.isProperType(true) && lambda != null) {
+ // ensure that type conversions don't leak a preliminary local type:
+ if (lambda.updateLocalTypesInMethod(lambda.descriptor))
+ methodType = lambda.expectedResultType();
+ }
if (TypeBinding.notEquals(methodType, expressionType)) // must call before computeConversion() and typeMismatchError()
scope.compilationUnitScope().recordTypeConversion(methodType, expressionType);
if (this.expression.isConstantValueOfTypeAssignableToType(expressionType, methodType)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/IntersectionTypeBinding18.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/IntersectionTypeBinding18.java
index ff1de21bf..135747305 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/IntersectionTypeBinding18.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/IntersectionTypeBinding18.java
@@ -238,7 +238,7 @@ public class IntersectionTypeBinding18 extends ReferenceBinding {
}
}
if (classIdx > -1 && classIdx < Integer.MAX_VALUE)
- return this.intersectingTypes[classIdx];
+ return this.intersectingTypes[classIdx].erasure();
return this;
}
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 c8ebc6922..d0f230d80 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
@@ -992,7 +992,7 @@ private PackageBinding computePackageFrom(char[][] constantPoolName, boolean isM
}
}
} else {
- packageBinding = this.module.getVisiblePackage(parent, constantPoolName[i]);
+ packageBinding = this.module.getVisiblePackage(parent, constantPoolName[i], true);
}
}
if (packageBinding == null || packageBinding == TheNotFoundPackage) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java
index 455058cdb..7cf8b0ed0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java
@@ -487,7 +487,7 @@ public class ModuleBinding extends Binding implements IUpdatableModule {
binding = this.environment.getPackage0(name);
if (binding != null)
return binding;
- binding = getVisiblePackage(null, name);
+ binding = getVisiblePackage(null, name, true);
// remember:
if (binding != null) {
this.environment.knownPackages.put(name, binding);
@@ -515,7 +515,7 @@ public class ModuleBinding extends Binding implements IUpdatableModule {
return binding;
}
// Given parent is visible in this module, see if there is sub package named name visible in this module
- PackageBinding getVisiblePackage(PackageBinding parent, char[] name) {
+ PackageBinding getVisiblePackage(PackageBinding parent, char[] name, boolean considerRequiredModules) {
// check caches:
char[][] parentName = parent == null ? CharOperation.NO_CHAR_CHAR : parent.compoundName;
char[][] subPkgCompoundName = CharOperation.arrayConcat(parentName, name);
@@ -535,6 +535,7 @@ public class ModuleBinding extends Binding implements IUpdatableModule {
}
PackageBinding binding = null;
+ boolean packageMayBeIncomplete = !considerRequiredModules;
if (this.environment.useModuleSystem) {
IModuleAwareNameEnvironment moduleEnv = (IModuleAwareNameEnvironment) this.environment.nameEnvironment;
char[][] declaringModuleNames = moduleEnv.getModulesDeclaringPackage(parentName, name, nameForLookup());
@@ -542,19 +543,23 @@ public class ModuleBinding extends Binding implements IUpdatableModule {
if (!this.isUnnamed() && CharOperation.containsEqual(declaringModuleNames, this.moduleName)) {
// declared here, not yet known, so create it now:
binding = new PackageBinding(subPkgCompoundName, parent, this.environment, this);
- } else {
+ } else if (considerRequiredModules) {
// visible but foreign (when current is unnamed or auto):
for (char[] declaringModuleName : declaringModuleNames) {
ModuleBinding declaringModule = this.environment.root.getModule(declaringModuleName);
- if (declaringModule != null && !declaringModule.isPackageLookupActive) {
- PackageBinding declaredPackage = declaringModule.getDeclaredPackage(parentName, name);
- if (declaredPackage != null) {
- // don't add foreign package to 'parent' (below), but to its own parent:
- if (declaredPackage.parent != null)
- declaredPackage.parent.addPackage(declaredPackage, declaringModule, true);
- parent = null;
- //
- binding = SplitPackageBinding.combine(declaredPackage, binding, this);
+ if (declaringModule != null) {
+ if (declaringModule.isPackageLookupActive) {
+ packageMayBeIncomplete = true;
+ } else {
+ PackageBinding declaredPackage = declaringModule.getDeclaredPackage(parentName, name);
+ if (declaredPackage != null) {
+ // don't add foreign package to 'parent' (below), but to its own parent:
+ if (declaredPackage.parent != null)
+ declaredPackage.parent.addPackage(declaredPackage, declaringModule, true);
+ parent = null;
+ //
+ binding = SplitPackageBinding.combine(declaredPackage, binding, this);
+ }
}
}
}
@@ -566,11 +571,14 @@ public class ModuleBinding extends Binding implements IUpdatableModule {
}
// enrich with split-siblings from visible modules:
- if (!isUnnamed()) {
+ if (!isUnnamed() && considerRequiredModules) {
binding = combineWithPackagesFromRequired(binding, subPkgCompoundName);
}
- if (binding == null || !binding.isValidBinding())
+ if (binding == null || !binding.isValidBinding()) {
+ if (parent != null && !packageMayBeIncomplete) // don't remember package that may still lack some siblings
+ parent.knownPackages.put(name, binding == null ? LookupEnvironment.TheNotFoundPackage : binding);
return null;
+ }
// remember
if (parentName.length == 0)
binding.environment.knownPackages.put(name, binding);
@@ -598,7 +606,7 @@ public class ModuleBinding extends Binding implements IUpdatableModule {
// check each sub package
for (int i = 1; i < qualifiedPackageName.length; i++) {
- PackageBinding binding = getVisiblePackage(parent, qualifiedPackageName[i]);
+ PackageBinding binding = getVisiblePackage(parent, qualifiedPackageName[i], true);
if (binding == null || binding == LookupEnvironment.TheNotFoundPackage) {
return null;
}
@@ -619,12 +627,12 @@ public class ModuleBinding extends Binding implements IUpdatableModule {
// Returns a package binding if there exists such a package in the context of this module and it is observable
// A package is observable if it is declared in this module or it is exported by some required module
if (parentPackageName == null || parentPackageName.length == 0) {
- return getVisiblePackage(null, packageName);
+ return getVisiblePackage(null, packageName, true);
}
PackageBinding binding = null;
PackageBinding parent = getVisiblePackage(parentPackageName);
if (parent != null && parent != LookupEnvironment.TheNotFoundPackage) {
- binding = getVisiblePackage(parent, packageName);
+ binding = getVisiblePackage(parent, packageName, true);
}
if (binding != null)
return addPackage(binding, false);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
index fd1c51a91..4b691535c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
@@ -1703,9 +1703,11 @@ public abstract class Scope {
ReferenceBinding sourceType = currentType.isParameterizedType()
? ((ParameterizedTypeBinding) currentType).genericType()
: currentType;
- if (sourceType.isHierarchyBeingConnected())
- return null; // looking for an undefined member type in its own superclass ref
- ((SourceTypeBinding) sourceType).scope.connectTypeHierarchy();
+ if (sourceType instanceof SourceTypeBinding) { // could be TypeVariableBinding
+ if (sourceType.isHierarchyBeingConnected())
+ return null; // looking for an undefined member type in its own superclass ref
+ ((SourceTypeBinding) sourceType).scope.connectTypeHierarchy();
+ }
itsInterfaces = currentType.superInterfaces();
}
if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SplitPackageBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SplitPackageBinding.java
index f6133e895..ee2f19134 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SplitPackageBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SplitPackageBinding.java
@@ -112,7 +112,7 @@ public class SplitPackageBinding extends PackageBinding {
ModuleBinding moduleBinding = incarnation.enclosingModule;
if (moduleBinding == module)
continue;
- PackageBinding next = moduleBinding.getVisiblePackage(incarnation, name); // TODO(SHMOD): reduce split-package work during this invocation?
+ PackageBinding next = moduleBinding.getVisiblePackage(incarnation, name, false);
childPackage = combine(next, childPackage, primaryModule);
}
return childPackage;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java
index 2327fcc57..a75bb883e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java
@@ -26,6 +26,10 @@ import org.eclipse.jdt.internal.compiler.util.Util;
* Parser specialized for decoding javadoc comments
*/
public class JavadocParser extends AbstractCommentParser {
+ private static final JavadocSingleNameReference[] NO_SINGLE_NAME_REFERENCE = new JavadocSingleNameReference[0];
+ private static final JavadocSingleTypeReference[] NO_SINGLE_TYPE_REFERENCE = new JavadocSingleTypeReference[0];
+ private static final TypeReference[] NO_TYPE_REFERENCE = new TypeReference[0];
+ private static final Expression[] NO_EXPRESSION = new Expression[0];
// Public fields
public Javadoc docComment;
@@ -1001,12 +1005,12 @@ public class JavadocParser extends AbstractCommentParser {
//{ObjectTeams: role references:
this.docComment.roleReferences = new JavadocSingleTypeReference[sizes[ROLE_TAG_EXPECTED_ORDER]];
// SH}
- this.docComment.seeReferences = new Expression[sizes[SEE_TAG_EXPECTED_ORDER]];
- this.docComment.exceptionReferences = new TypeReference[sizes[THROWS_TAG_EXPECTED_ORDER]];
+ this.docComment.seeReferences = sizes[SEE_TAG_EXPECTED_ORDER] > 0 ? new Expression[sizes[SEE_TAG_EXPECTED_ORDER]] : NO_EXPRESSION;
+ this.docComment.exceptionReferences = sizes[THROWS_TAG_EXPECTED_ORDER] > 0 ? new TypeReference[sizes[THROWS_TAG_EXPECTED_ORDER]] : NO_TYPE_REFERENCE;
int paramRefPtr = sizes[PARAM_TAG_EXPECTED_ORDER];
- this.docComment.paramReferences = new JavadocSingleNameReference[paramRefPtr];
+ this.docComment.paramReferences = paramRefPtr > 0 ? new JavadocSingleNameReference[paramRefPtr] : NO_SINGLE_NAME_REFERENCE;
int paramTypeParamPtr = sizes[PARAM_TAG_EXPECTED_ORDER];
- this.docComment.paramTypeParameters = new JavadocSingleTypeReference[paramTypeParamPtr];
+ this.docComment.paramTypeParameters = paramTypeParamPtr > 0 ? new JavadocSingleTypeReference[paramTypeParamPtr] : NO_SINGLE_TYPE_REFERENCE;
// Store nodes in arrays
while (this.astLengthPtr >= 0) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
index 5ee4eb31b..8c661ac91 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
@@ -10994,6 +10994,9 @@ protected void consumeReferenceExpressionTypeForm(boolean isPrimitive) { // actu
} else {
referenceExpression.initialize(this.compilationUnit.compilationResult, getUnspecifiedReference(), typeArguments, selector, sourceEnd);
}
+ if (CharOperation.equals(selector, TypeConstants.INIT) && referenceExpression.lhs instanceof NameReference) {
+ referenceExpression.lhs.bits &= ~Binding.VARIABLE;
+ }
consumeReferenceExpression(referenceExpression);
}
protected void consumeReferenceExpressionPrimaryForm() {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatusConstants.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatusConstants.java
index 505da26ba..1604a57d4 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatusConstants.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatusConstants.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2018 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -375,4 +375,14 @@ public interface IJavaModelStatusConstants {
*/
public static final int TEST_OUTPUT_FOLDER_MUST_BE_SEPARATE_FROM_MAIN_OUTPUT_FOLDERS = 1016;
+ /**
+ * <p>
+ * Status constant indicating that the project has only main source folders but depends on a project that has only
+ * test source folders.
+ * </p>
+ *
+ * @since 3.16
+ */
+ public static final int MAIN_ONLY_PROJECT_DEPENDS_ON_TEST_ONLY_PROJECT = 1017;
+
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageFragmentRoot.java
index 6b8f47281..20b09a0d6 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageFragmentRoot.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageFragmentRoot.java
@@ -451,9 +451,9 @@ public interface IPackageFragmentRoot
void move(IPath destination, int updateResourceFlags, int updateModelFlags, IClasspathEntry sibling, IProgressMonitor monitor) throws JavaModelException;
/**
- * Returns the <code>IModuleDescription</code> that this package fragment root contains
- * or <code>null</code> if the root doesn't contain any named module. If present the module
- * descriptor is found as a child of the package fragment representing the default package.
+ * Returns the <code>IModuleDescription</code> that this package fragment root contains.
+ * Returns <code>null</code> if the root doesn't contain any named module or if the project compiler compliance is 1.8 or lower.
+ * If present the module descriptor is found as a child of the package fragment representing the default package.
*
* Note that only one of the source package fragment roots in a Java Project can legally
* contain a module descriptor.
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
index fb4fb3a77..68bdc8255 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
@@ -2579,6 +2579,21 @@ public final class JavaCore extends Plugin {
* @since 3.6.4
*/
public static final String CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE = PLUGIN_ID + ".classpath.outputOverlappingAnotherSource"; //$NON-NLS-1$
+
+ /**
+ * Core option ID: Reporting if a project which has only main sources depends on a project with only test sources.
+ * <p> Indicate the severity of the problem reported when a project that has one or more main source folders but
+ * no test source folders has a project on its build path that only has one or more test source folders, but no main source folders.</p>
+ *
+ * <dl>
+ * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.classpath.mainOnlyProjectHasTestOnlyDependency"</code></dd>
+ * <dt>Possible values:</dt><dd><code>{ "error", "ignore" }</code></dd>
+ * <dt>Default:</dt><dd><code>"error"</code></dd>
+ * </dl>
+ * @since 3.16
+ */
+ public static final String CORE_MAIN_ONLY_PROJECT_HAS_TEST_ONLY_DEPENDENCY = PLUGIN_ID + ".classpath.mainOnlyProjectHasTestOnlyDependency"; //$NON-NLS-1$
+
/**
* Core option ID: Set the timeout value for retrieving the method's parameter names from javadoc.
* <p>Timeout in milliseconds to retrieve the method's parameter names from javadoc.</p>
@@ -4285,6 +4300,37 @@ public final class JavaCore extends Plugin {
}
/**
+ * Returns the option that can be used to configure the severity of the
+ * compiler build path problem identified by <code>id</code> if any,
+ * <code>null</code> otherwise. Non-null return values are taken from the
+ * constants defined by this class whose names start with
+ * <code>CORE_</code> and for which the possible values of the
+ * option are defined by <code>{ "error", "warning", "info", "ignore" }</code>. A
+ * null return value means that the provided id is unknown or that
+ * it matches a problem whose severity cannot be configured.
+ * @param id one of the build path problems defined in IJavaModelStatusConstants
+ * @return the option that can be used to configure the severity of the
+ * compiler problem identified by <code>id</code> if any,
+ * <code>null</code> otherwise
+ * @since 3.16
+ */
+ public static String getOptionForConfigurableBuildPathProblemSeverity(int id) {
+ switch (id) {
+ case IJavaModelStatusConstants.CLASSPATH_CYCLE:
+ return JavaCore.CORE_CIRCULAR_CLASSPATH;
+ case IJavaModelStatusConstants.INCOMPATIBLE_JDK_LEVEL:
+ return JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL;
+ case IJavaModelStatusConstants.OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE:
+ return JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE;
+ case IJavaModelStatusConstants.MAIN_ONLY_PROJECT_DEPENDS_ON_TEST_ONLY_PROJECT:
+ return JavaCore.CORE_MAIN_ONLY_PROJECT_HAS_TEST_ONLY_DEPENDENCY;
+ case IJavaModelStatusConstants.INVALID_CLASSPATH:
+ return JavaCore.CORE_INCOMPLETE_CLASSPATH;
+ }
+ return null;
+ }
+
+ /**
* Returns the table of the current options. Initially, all options have their default values,
* and this method returns a table that includes all known options.
* <p>
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Annotation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Annotation.java
index 277edc5fc..fd01fd524 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Annotation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Annotation.java
@@ -39,7 +39,7 @@ public class Annotation extends SourceRefElement implements IAnnotation {
public Annotation(JavaElement parent, String name, String memberValuePairName) {
super(parent);
- this.name = name;
+ this.name = name.intern();
this.memberValuePairName = memberValuePairName;
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java
index 428a0c4fc..284fb648f 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java
@@ -1870,11 +1870,10 @@ public class ClasspathEntry implements IClasspathEntry {
} catch(JavaModelException e){
return e.getJavaModelStatus();
}
- int length = classpath.length;
int outputCount = 1;
- IPath[] outputLocations = new IPath[length+1];
- boolean[] allowNestingInOutputLocations = new boolean[length+1];
+ IPath[] outputLocations = new IPath[classpath.length+1];
+ boolean[] allowNestingInOutputLocations = new boolean[classpath.length+1];
outputLocations[0] = projectOutputLocation;
// retrieve and check output locations
@@ -1964,8 +1963,7 @@ public class ClasspathEntry implements IClasspathEntry {
}
}
- for (int i = 0 ; i < length; i++) {
- IClasspathEntry resolvedEntry = classpath[i];
+ for (IClasspathEntry resolvedEntry : classpath) {
IPath path = resolvedEntry.getPath();
int index;
switch(resolvedEntry.getEntryKind()){
@@ -1991,8 +1989,7 @@ public class ClasspathEntry implements IClasspathEntry {
}
// check all entries
- for (int i = 0 ; i < length; i++) {
- IClasspathEntry entry = classpath[i];
+ for (IClasspathEntry entry : classpath) {
if (entry == null) continue;
IPath entryPath = entry.getPath();
int kind = entry.getEntryKind();
@@ -2010,8 +2007,7 @@ public class ClasspathEntry implements IClasspathEntry {
// allow nesting source entries in each other as long as the outer entry excludes the inner one
if (kind == IClasspathEntry.CPE_SOURCE
|| (kind == IClasspathEntry.CPE_LIBRARY && (JavaModel.getTarget(entryPath, false/*don't check existence*/) instanceof IContainer))) {
- for (int j = 0; j < classpath.length; j++){
- IClasspathEntry otherEntry = classpath[j];
+ for (IClasspathEntry otherEntry : classpath) {
if (otherEntry == null) continue;
int otherKind = otherEntry.getEntryKind();
IPath otherPath = otherEntry.getPath();
@@ -2071,8 +2067,7 @@ public class ClasspathEntry implements IClasspathEntry {
// diagnose nesting source folder issue before this one, for example, [src]"Project/", [src]"Project/source/" and output="Project/" should
// first complain about missing exclusion pattern
IJavaModelStatus cachedStatus = null;
- for (int i = 0 ; i < length; i++) {
- IClasspathEntry entry = classpath[i];
+ for (IClasspathEntry entry : classpath) {
if (entry == null) continue;
IPath entryPath = entry.getPath();
int kind = entry.getEntryKind();
@@ -2084,8 +2079,7 @@ public class ClasspathEntry implements IClasspathEntry {
if (kind == IClasspathEntry.CPE_SOURCE) {
IPath output = entry.getOutputLocation();
if (output == null) output = projectOutputLocation; // if no specific output, still need to check using default output (this line would check default output)
- for (int j = 0; j < length; j++) {
- IClasspathEntry otherEntry = classpath[j];
+ for (IClasspathEntry otherEntry : classpath) {
if (otherEntry == entry) continue;
switch (otherEntry.getEntryKind()) {
@@ -2126,6 +2120,42 @@ public class ClasspathEntry implements IClasspathEntry {
}
}
+ if (hasSource && testSourcesFolders.size() == 0 && !JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.CORE_MAIN_ONLY_PROJECT_HAS_TEST_ONLY_DEPENDENCY, true))) {
+ for (IClasspathEntry entry : classpath) {
+ if (entry == null)
+ continue;
+ IPath entryPath = entry.getPath();
+ if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) {
+ if (entryPath.isAbsolute() && entryPath.segmentCount() == 1) {
+ IProject prereqProjectRsc = workspaceRoot.getProject(entryPath.segment(0));
+ IJavaProject prereqProject = JavaCore.create(prereqProjectRsc);
+ boolean hasMain = false;
+ boolean hasTest = false;
+ try {
+ for (IClasspathEntry nested : prereqProject.getRawClasspath()) {
+ if (nested.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
+ if (nested.isTest()) {
+ hasTest = true;
+ } else {
+ hasMain = true;
+ }
+ if (hasTest && hasMain)
+ break;
+ }
+ }
+ } catch (JavaModelException e) {
+ // is reported elsewhere
+ }
+ if (hasTest && !hasMain) {
+ return new JavaModelStatus(IJavaModelStatusConstants.MAIN_ONLY_PROJECT_DEPENDS_ON_TEST_ONLY_PROJECT,
+ Messages.bind(Messages.classpath_main_only_project_depends_on_test_only_project,
+ new String[] { prereqProject.getElementName() }));
+ }
+ }
+ }
+ }
+ }
+
// NOTE: The above code that checks for IJavaModelStatusConstants.OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, can be configured to return
// a WARNING status and hence should be at the end of this validation method. Any other code that might return a more severe ERROR should be
// inserted before the mentioned code.
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalFoldersManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalFoldersManager.java
index 1fb75315a..9c13682bd 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalFoldersManager.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalFoldersManager.java
@@ -57,6 +57,7 @@ import org.eclipse.jdt.internal.core.util.Messages;
import org.eclipse.jdt.internal.core.util.Util;
public class ExternalFoldersManager {
+ private static final boolean WINDOWS = System.getProperty("os.name").toLowerCase().contains("windows"); //$NON-NLS-1$//$NON-NLS-2$
private static final String EXTERNAL_PROJECT_NAME = ".org.eclipse.jdt.core.external.folders"; //$NON-NLS-1$
private static final String LINKED_FOLDER_NAME = ".link"; //$NON-NLS-1$
private Map<IPath, IFolder> folders;
@@ -118,11 +119,12 @@ public class ExternalFoldersManager {
if (externalPath == null || externalPath.isEmpty()) {
return false;
}
+
JavaModelManager manager = JavaModelManager.getJavaModelManager();
if (manager.isExternalFile(externalPath) || manager.isAssumedExternalFile(externalPath)) {
return false;
}
- if (!externalPath.isAbsolute()) {
+ if (!externalPath.isAbsolute() || (WINDOWS && externalPath.getDevice() == null)) {
// can be only project relative path
return false;
}
@@ -142,12 +144,14 @@ public class ExternalFoldersManager {
if (isInternalContainerPath(externalPath)) {
return false;
}
+ // From here on the legacy code assumes that not existing resource must be external.
+ // We just follow the old assumption.
if (externalPath.getFileExtension() != null/*likely a .jar, .zip, .rar or other file*/) {
manager.addAssumedExternalFile(externalPath);
- // not existing external file
+ // assume not existing external (?) file (?) (can also be a folder with dotted name!)
return false;
}
- // not existing external folder
+ // assume not existing external (?) folder (?)
return true;
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java
index dfebdb8d1..ed85f3b54 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2018 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -79,6 +79,7 @@ public class JavaCorePreferenceInitializer extends AbstractPreferenceInitializer
//{ObjectTeams: one more setting:
defaultOptionsMap.put(JavaCore.AST_INCLUDES_ROLE_FILES, JavaCore.DISABLED);
// SH}
+ defaultOptionsMap.put(JavaCore.CORE_MAIN_ONLY_PROJECT_HAS_TEST_ONLY_DEPENDENCY, JavaCore.ERROR);
// encoding setting comes from resource plug-in
optionNames.add(JavaCore.CORE_ENCODING);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
index 648cee83e..09250fcc7 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
@@ -1708,6 +1708,7 @@ public class JavaModelManager implements ISaveParticipant, IContentTypeChangeLis
propertyName.equals(JavaCore.CORE_INCOMPLETE_CLASSPATH) ||
propertyName.equals(JavaCore.CORE_CIRCULAR_CLASSPATH) ||
propertyName.equals(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL) ||
+ propertyName.equals(JavaCore.CORE_MAIN_ONLY_PROJECT_HAS_TEST_ONLY_DEPENDENCY) ||
propertyName.equals(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM) ||
propertyName.equals(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE)) {
JavaModelManager manager = JavaModelManager.getJavaModelManager();
@@ -2470,6 +2471,7 @@ public class JavaModelManager implements ISaveParticipant, IContentTypeChangeLis
defaultOptionsMap.put(JavaCore.CORE_INCOMPLETE_CLASSPATH, JavaCore.ERROR);
defaultOptionsMap.put(JavaCore.CORE_CIRCULAR_CLASSPATH, JavaCore.ERROR);
defaultOptionsMap.put(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL, JavaCore.IGNORE);
+ defaultOptionsMap.put(JavaCore.CORE_MAIN_ONLY_PROJECT_HAS_TEST_ONLY_DEPENDENCY, JavaCore.ERROR);
defaultOptionsMap.put(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, JavaCore.ERROR);
defaultOptionsMap.put(JavaCore.CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS, JavaCore.ENABLED);
defaultOptionsMap.put(JavaCore.CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS, JavaCore.ENABLED);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
index c170620af..abe02ffe9 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
@@ -1186,6 +1186,14 @@ public class JavaProject
return; // setting == IGNORE
}
break;
+ case IJavaModelStatusConstants.MAIN_ONLY_PROJECT_DEPENDS_ON_TEST_ONLY_PROJECT:
+ setting = getOption(JavaCore.CORE_MAIN_ONLY_PROJECT_HAS_TEST_ONLY_DEPENDENCY, true);
+ if (JavaCore.ERROR.equals(setting)) {
+ severity = IMarker.SEVERITY_ERROR;
+ } else {
+ return; // setting == IGNORE
+ }
+ break;
default:
IPath path = status.getPath();
if (path != null) arguments = new String[] { path.toString() };
@@ -1945,6 +1953,7 @@ public class JavaProject
propertyName.equals(JavaCore.CORE_CIRCULAR_CLASSPATH) ||
propertyName.equals(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE) ||
propertyName.equals(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL) ||
+ propertyName.equals(JavaCore.CORE_MAIN_ONLY_PROJECT_HAS_TEST_ONLY_DEPENDENCY) ||
propertyName.equals(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM))
{
manager.deltaState.addClasspathValidation(JavaProject.this);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JrtPackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JrtPackageFragmentRoot.java
index 702e50730..cd3e8158c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JrtPackageFragmentRoot.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JrtPackageFragmentRoot.java
@@ -151,6 +151,11 @@ public class JrtPackageFragmentRoot extends JarPackageFragmentRoot implements IM
}
return null;
}
+
+ @Override
+ protected boolean isComplianceJava9OrHigher() {
+ return true;
+ }
@Override
public char[][] getModulesDeclaringPackage(String qualifiedPackageName, String requestedModuleName) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
index 519c2c8e4..5d8f782c3 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
@@ -22,7 +22,9 @@ import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.env.AutomaticModuleNaming;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.core.util.MementoTokenizer;
import org.eclipse.jdt.internal.core.util.Messages;
@@ -884,6 +886,13 @@ public String getClassFilePath(String classname) {
}
@Override
public IModuleDescription getModuleDescription() {
+ if (isComplianceJava9OrHigher()) {
+ return getSourceModuleDescription();
+ }
+ return null;
+}
+
+private IModuleDescription getSourceModuleDescription() {
try {
IJavaElement[] pkgs = getChildren();
for (int j = 0, length = pkgs.length; j < length; j++) {
@@ -959,4 +968,16 @@ public boolean hasCompilationUnit(String qualifiedPackageName, String moduleName
public Manifest getManifest() {
return null;
}
+
+protected boolean isComplianceJava9OrHigher() {
+ IJavaProject javaProject = getJavaProject();
+ return isComplianceJava9OrHigher(javaProject);
+}
+
+private static boolean isComplianceJava9OrHigher(IJavaProject javaProject) {
+ if (javaProject == null) {
+ return false;
+ }
+ return CompilerOptions.versionToJdkLevel(javaProject.getOption(JavaCore.COMPILER_COMPLIANCE, true)) >= ClassFileConstants.JDK9;
+}
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java
index 82e9c0243..f1fe4d648 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java
@@ -192,6 +192,7 @@ public final class Messages extends NLS {
public static String classpath_invalidExternalAnnotationPath;
public static String classpath_testSourceRequiresSeparateOutputFolder;
public static String classpath_testOutputFolderMustBeSeparateFromMainOutputFolders;
+ public static String classpath_main_only_project_depends_on_test_only_project;
public static String file_notFound;
public static String file_badFormat;
public static String path_nullPath;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties
index 7d00a513b..305dbb823 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties
@@ -188,6 +188,7 @@ classpath_deprecated_variable = Classpath variable ''{0}'' in project ''{1}'' is
classpath_invalidExternalAnnotationPath = Invalid external annotation path: ''{0}'' in project ''{1}'', for classpath entry ''{2}''
classpath_testSourceRequiresSeparateOutputFolder=Test source folder ''{0}'' in project ''{1}'' must have a separate output folder
classpath_testOutputFolderMustBeSeparateFromMainOutputFolders=Test source folder ''{0}'' in project ''{1}'' must have an output folder that is not also used for main sources
+classpath_main_only_project_depends_on_test_only_project=Project has only main sources but depends on project ''{0}'' which has only test sources.
### miscellaneous
buffer_closed=Buffer is closed
diff --git a/org.eclipse.jdt.core/scripts/source/META-INF/MANIFEST.MF b/org.eclipse.jdt.core/scripts/source/META-INF/MANIFEST.MF
index 783aecc66..c6ce1807f 100644
--- a/org.eclipse.jdt.core/scripts/source/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core/scripts/source/META-INF/MANIFEST.MF
@@ -3,4 +3,4 @@ Bundle-Name: Source of Eclipse Compiler for Java(TM)
Bundle-SymbolicName: org.eclipse.jdt.core.compiler.batch.source
Bundle-Version: 3.11.0.qualifier
Bundle-Vendor: Eclipse.org
-Eclipse-SourceBundle: org.eclipse.jdt.core.compiler.batch;version="3.11.0.${buildQualifier}";roots:="."
+Eclipse-SourceBundle: org.eclipse.jdt.core.compiler.batch;version="${unqualifiedVersion}.${buildQualifier}";roots:="."

Back to the top