Merge branch 'master' into BETA_JAVA16 plus fixing minor version error
Signed-off-by: Manoj Palat <manpalat@in.ibm.com>
diff --git a/org.eclipse.jdt.core.tests.builder/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.tests.builder/META-INF/MANIFEST.MF
index df66395..c8aae87 100644
--- a/org.eclipse.jdt.core.tests.builder/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core.tests.builder/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.jdt.core.tests.builder; singleton:=true
-Bundle-Version: 3.10.1000.qualifier
+Bundle-Version: 3.10.1100.qualifier
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Export-Package: org.eclipse.jdt.core.tests.builder
diff --git a/org.eclipse.jdt.core.tests.builder/pom.xml b/org.eclipse.jdt.core.tests.builder/pom.xml
index c2afdbf..26f479c 100644
--- a/org.eclipse.jdt.core.tests.builder/pom.xml
+++ b/org.eclipse.jdt.core.tests.builder/pom.xml
@@ -19,7 +19,7 @@
</parent>
<groupId>org.eclipse.jdt</groupId>
<artifactId>org.eclipse.jdt.core.tests.builder</artifactId>
- <version>3.10.1000-SNAPSHOT</version>
+ <version>3.10.1100-SNAPSHOT</version>
<packaging>eclipse-test-plugin</packaging>
<properties>
diff --git a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/StateTest.java b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/StateTest.java
index fed6380..3a54ae9 100644
--- a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/StateTest.java
+++ b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/StateTest.java
@@ -28,11 +28,16 @@
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.IAccessRule;
+import org.eclipse.jdt.core.IClasspathAttribute;
+import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.tests.util.Util;
import org.eclipse.jdt.internal.core.JavaModelManager;
import org.eclipse.jdt.internal.core.JavaModelManager.PerProjectInfo;
+import org.eclipse.jdt.internal.core.builder.ClasspathLocation;
import org.eclipse.jdt.internal.core.builder.JavaBuilder;
import org.eclipse.jdt.internal.core.builder.ReferenceCollection;
import org.eclipse.jdt.internal.core.builder.State;
@@ -108,6 +113,56 @@
writeReadAndCompareReferences(project);
}
+ public void testBug567532() throws JavaModelException, Exception {
+ IPath project = env.addProject("Bug567532"); //$NON-NLS-1$
+ String[] classLibs = Util.getJavaClassLibs();
+ for (String jar : classLibs) {
+ env.addEntry(project,
+ JavaCore.newLibraryEntry(
+ new Path(jar),
+ null,
+ null,
+ new IAccessRule[0],
+ new IClasspathAttribute[] {
+ JavaCore.newClasspathAttribute(IClasspathAttribute.TEST, "true"),
+ JavaCore.newClasspathAttribute(IClasspathAttribute.ADD_EXPORTS,
+ "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED") },
+ false));
+ }
+
+ env.addClass(project, "a", "WithOther", //$NON-NLS-1$ //$NON-NLS-2$
+ "package a;\n" +
+ "class Other {\n" +
+ "}\n" +
+ "public class WithOther {\n" +
+ "}" //$NON-NLS-1$
+ );
+ fullBuild();
+ env.removePackage(project, "a");
+ incrementalBuild();
+
+ writeReadAndCompareTestBinaryLocations(project);
+ }
+
+ private void writeReadAndCompareTestBinaryLocations(IPath projectPath)
+ throws JavaModelException, IOException, CoreException {
+ JavaModelManager javaModelManager = JavaModelManager.getJavaModelManager();
+ IProject project = env.getProject(projectPath);
+ PerProjectInfo info = javaModelManager.getPerProjectInfoCheckExistence(project);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ State savedState = (State) info.savedState;
+ JavaBuilder.writeState(savedState, new DataOutputStream(outputStream));
+ byte[] bytes = outputStream.toByteArray();
+ State readState = JavaBuilder.readState(project, new DataInputStream(new ByteArrayInputStream(bytes)));
+ assertEqualBinaryLocations(savedState.testBinaryLocations, readState.testBinaryLocations);
+ }
+
+ private void assertEqualBinaryLocations(ClasspathLocation[] a,
+ ClasspathLocation[] b) {
+ assertEquals(a.length, b.length);
+ assertArrayEquals(a, b);
+ }
+
private void writeReadAndCompareReferences(IPath projectPath)
throws JavaModelException, IOException, CoreException {
JavaModelManager javaModelManager = JavaModelManager.getJavaModelManager();
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/ComplianceDiagnoseTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/ComplianceDiagnoseTest.java
index 41978bd..2d77b89 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/ComplianceDiagnoseTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/ComplianceDiagnoseTest.java
@@ -3232,17 +3232,18 @@
"}\n",
};
String usLevel = this.complianceLevel < ClassFileConstants.JDK9 ? "WARNING" : "ERROR";
+ String errorMessage = this.complianceLevel < ClassFileConstants.JDK9 ? "\'_\' should not be used as an identifier, since it is a reserved keyword from source level 1.8 on\n" : "\'_\' is a keyword from source level 9 onwards, cannot be used as identifier\n";
String expectedProblemLog =
"----------\n" +
"1. " + usLevel +" in X.java (at line 2)\n" +
" int _;\n" +
" ^\n" +
- "\'_\' should not be used as an identifier, since it is a reserved keyword from source level 1.8 on\n" +
+ errorMessage +
"----------\n" +
"2. " + usLevel +" in X.java (at line 4)\n" +
" int _ = 3;\n" +
" ^\n" +
- "\'_\' should not be used as an identifier, since it is a reserved keyword from source level 1.8 on\n" +
+ errorMessage +
"----------\n" +
"3. WARNING in X.java (at line 4)\n" +
" int _ = 3;\n" +
@@ -3252,7 +3253,7 @@
"4. " + usLevel +" in X.java (at line 8)\n" +
" void goo(int _) {}\n" +
" ^\n" +
- "\'_\' should not be used as an identifier, since it is a reserved keyword from source level 1.8 on\n" +
+ errorMessage +
"----------\n" +
"5. WARNING in X.java (at line 8)\n" +
" void goo(int _) {}\n" +
@@ -3262,7 +3263,7 @@
"6. " + usLevel +" in X.java (at line 11)\n" +
" } catch (Exception _) {\n" +
" ^\n" +
- "\'_\' should not be used as an identifier, since it is a reserved keyword from source level 1.8 on\n" +
+ errorMessage +
"----------\n" +
"7. WARNING in X.java (at line 11)\n" +
" } catch (Exception _) {\n" +
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 1f5c855..cf0fa27 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
@@ -14,7 +14,10 @@
package org.eclipse.jdt.core.tests.compiler.regression;
import java.io.File;
+import java.io.IOException;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.tests.util.Util;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import junit.framework.Test;
@@ -379,4 +382,41 @@
"",
true);
}
+public void testBug568802() {
+ String currentWorkingDirectoryPath = System.getProperty("user.dir");
+ String libPath = currentWorkingDirectoryPath + File.separator + "lib568802.jar";
+ try {
+ Util.createJar(
+ new String[] {
+ "hello/World.java;\n",
+ "package hello;\n"
+ + "public class World {}\n",
+ "module-info.java;\n",
+ "module HelloModule {}\n"
+ },
+ libPath,
+ JavaCore.VERSION_11,
+ false);
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import hello.World;\n"
+ + "public class X {\n"
+ + " World field = new World();\n"
+ + "}\n"
+ },
+ "\"" + OUTPUT_DIR + File.separator + "X.java\"" +
+ " -cp " + libPath + // relative
+ " -source " + CompilerOptions.getLatestVersion() +
+ " -target " + CompilerOptions.getLatestVersion() + " ",
+ "",
+ "",
+ true);
+ } catch (IOException e) {
+ System.err.println("BatchCompilerTest2#testBug568802 could not write to current working directory " + currentWorkingDirectoryPath);
+ } finally {
+ new File(libPath).delete();
+ }
+}
+
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CastTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CastTest.java
index 45f4e9e..c979cdf 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CastTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CastTest.java
@@ -3532,6 +3532,44 @@
runner.runWarningTest();
}
+public void testBug561167() {
+ if (this.complianceLevel < ClassFileConstants.JDK10)
+ return;
+ Map customOptions = getCompilerOptions();
+ customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR);
+ runNegativeTest(
+ // test directory preparation
+ true /* flush output directory */,
+ new String[] { /* test files */
+ "X.java",
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " var s = (String) null; // Necessary\n" +
+ " var t = (String) \"hello\"; // UNnecessary\n" +
+ " var f = (float) 12; // Necessary\n" +
+ " var g = (float)f; // UNnecessary\n" +
+ " }\n" +
+ "}\n"
+ },
+ // compiler options
+ null /* no class libraries */,
+ customOptions /* custom options */,
+ // compiler results
+ "----------\n" +
+ "1. ERROR in X.java (at line 4)\n" +
+ " var t = (String) \"hello\"; // UNnecessary\n" +
+ " ^^^^^^^^^^^^^^^^\n" +
+ "Unnecessary cast from String to String\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 6)\n" +
+ " var g = (float)f; // UNnecessary\n" +
+ " ^^^^^^^^\n" +
+ "Unnecessary cast from float to float\n" +
+ "----------\n",
+ // javac options
+ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */);
+}
+
public static Class testClass() {
return CastTest.class;
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
index ff5f727..9cfe8a8 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
@@ -1130,6 +1130,7 @@
expectedProblemAttributes.put("UseAssertAsAnIdentifier", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
expectedProblemAttributes.put("UseEnumAsAnIdentifier", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
expectedProblemAttributes.put("IllegalUseOfUnderscoreAsAnIdentifier", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
+ expectedProblemAttributes.put("ErrorUseOfUnderscoreAsAnIdentifier", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
expectedProblemAttributes.put("UsingDeprecatedConstructor", new ProblemAttributes(CategorizedProblem.CAT_DEPRECATION));
expectedProblemAttributes.put("UsingDeprecatedField", new ProblemAttributes(CategorizedProblem.CAT_DEPRECATION));
expectedProblemAttributes.put("UsingDeprecatedMethod", new ProblemAttributes(CategorizedProblem.CAT_DEPRECATION));
@@ -1263,6 +1264,7 @@
expectedProblemAttributes.put("RecordIllegalStaticModifierForLocalClassOrInterface", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
expectedProblemAttributes.put("RecordIllegalModifierForLocalRecord", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
expectedProblemAttributes.put("LocalStaticsIllegalVisibilityModifierForInterfaceLocalType", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
+ expectedProblemAttributes.put("IllegalModifierForLocalEnumDeclaration", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
expectedProblemAttributes.put("SealedMissingClassModifier", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
expectedProblemAttributes.put("SealedDisAllowedNonSealedModifierInClass", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
expectedProblemAttributes.put("SealedSuperClassDoesNotPermit", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
@@ -2182,6 +2184,7 @@
expectedProblemAttributes.put("UseAssertAsAnIdentifier", new ProblemAttributes(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER));
expectedProblemAttributes.put("UseEnumAsAnIdentifier", new ProblemAttributes(JavaCore.COMPILER_PB_ENUM_IDENTIFIER));
expectedProblemAttributes.put("IllegalUseOfUnderscoreAsAnIdentifier", SKIP);
+ expectedProblemAttributes.put("ErrorUseOfUnderscoreAsAnIdentifier", SKIP);
expectedProblemAttributes.put("UsingDeprecatedConstructor", new ProblemAttributes(JavaCore.COMPILER_PB_DEPRECATION));
expectedProblemAttributes.put("UsingDeprecatedField", new ProblemAttributes(JavaCore.COMPILER_PB_DEPRECATION));
expectedProblemAttributes.put("UsingDeprecatedMethod", new ProblemAttributes(JavaCore.COMPILER_PB_DEPRECATION));
@@ -2314,6 +2317,7 @@
expectedProblemAttributes.put("RecordIllegalParameterNameInCanonicalConstructor",SKIP);
expectedProblemAttributes.put("RecordIllegalExplicitFinalFieldAssignInCompactConstructor",SKIP);
expectedProblemAttributes.put("LocalStaticsIllegalVisibilityModifierForInterfaceLocalType",SKIP);
+ expectedProblemAttributes.put("IllegalModifierForLocalEnumDeclaration",SKIP);
expectedProblemAttributes.put("SealedMissingClassModifier", SKIP);
expectedProblemAttributes.put("SealedDisAllowedNonSealedModifierInClass", SKIP);
expectedProblemAttributes.put("SealedSuperClassDoesNotPermit", SKIP);
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FieldAccessTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FieldAccessTest.java
index 2a09e1b..bd8fd95 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FieldAccessTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FieldAccessTest.java
@@ -794,6 +794,31 @@
"f cannot be resolved or is not a field\n" +
"----------\n");
}
+public void testBug568959_001() {
+ if (this.complianceLevel < ClassFileConstants.JDK1_8) return; // lambda
+ runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n"+
+ " public void foo(Object o) {\n"+
+ " I i = () -> {\n"+
+ " while (o.eq) {\n"+
+ " // nothing\n"+
+ " }\n"+
+ " };\n"+
+ " }\n"+
+ "}\n"+
+ "interface I { \n"+
+ " public abstract void run();\n"+
+ "}"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 4)\n" +
+ " while (o.eq) {\n" +
+ " ^^\n" +
+ "eq cannot be resolved or is not a field\n" +
+ "----------\n");
+}
public static Class testClass() {
return FieldAccessTest.class;
}
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 d5ce778..f71d4bd 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -6614,5 +6614,48 @@
},
output);
}
+public void testBug561544() {
+ if (this.complianceLevel < ClassFileConstants.JDK11)
+ return;
+ Map customOptions = getCompilerOptions();
+ customOptions.put(JavaCore.COMPILER_PB_UNAVOIDABLE_GENERIC_TYPE_PROBLEMS, JavaCore.DISABLED);
+ runNegativeTest(false,
+ new String[] {
+ "com/bsbportal/music/C2193c.java",
+ "package com.bsbportal.music;\n"
+ + "\n"
+ + "public class C2193c {\n"
+ + " java.util.List f6088b;\n"
+ + " public void onResponse(p594x.C14183r<java.lang.String> rVar) {\n"
+ + " mo12821b((java.util.List<java.lang.String>) this.f6088b);\n"
+ + " }\n"
+ + "}\n"
+ },
+ null,
+ customOptions,
+ "----------\n" +
+ "1. WARNING in com\\bsbportal\\music\\C2193c.java (at line 4)\n" +
+ " java.util.List f6088b;\n" +
+ " ^^^^^^^^^^^^^^\n" +
+ "List is a raw type. References to generic type List<E> should be parameterized\n" +
+ "----------\n" +
+ "2. ERROR in com\\bsbportal\\music\\C2193c.java (at line 5)\n" +
+ " public void onResponse(p594x.C14183r<java.lang.String> rVar) {\n" +
+ " ^^^^^\n" +
+ "p594x cannot be resolved to a type\n" +
+ "----------\n" +
+ "3. ERROR in com\\bsbportal\\music\\C2193c.java (at line 6)\n" +
+ " mo12821b((java.util.List<java.lang.String>) this.f6088b);\n" +
+ " ^^^^^^^^\n" +
+ "The method mo12821b(List<String>) is undefined for the type C2193c\n" +
+ "----------\n" +
+ "4. WARNING in com\\bsbportal\\music\\C2193c.java (at line 6)\n" +
+ " mo12821b((java.util.List<java.lang.String>) this.f6088b);\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Type safety: Unchecked cast from List to List<String>\n" +
+ "----------\n",
+ "", "", null
+ );
+}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTest_15.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTest_15.java
index b3d9f6d..3932bbe 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTest_15.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTest_15.java
@@ -352,5 +352,123 @@
new String[] {"module-info.java", moduleInfo }, errorMsg,
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
}
+
+public void test007() {
+ File outputDirectory = new File(OUTPUT_DIR);
+ Util.flushDirectoryContent(outputDirectory);
+
+ String moduleInfo = "" +
+ "/**\n" +
+ " */\n" +
+ "module mod.one { \n" +
+ " exports p;\n" +
+ "}";
+ String I1 = "" +
+ "package p;\n" +
+ "/**\n" +
+ " * interface I1\n" +
+ " * @see mod.one/ abc\n" +
+ " */\n" +
+ "interface I1 {\n" +
+ " /**\n" +
+ " * Method foo\n" +
+ " * @return int\n" +
+ " */\n" +
+ " public int foo();\n" +
+ "}";
+
+ String P1 = "" +
+ "package p;\n" +
+ "/**\n" +
+ " * class P1\n" +
+ " * @see mod.one/p.I1 xyz\n" +
+ " */\n" +
+ "public class P1 implements I1 {\n" +
+ " @Override\n" +
+ " public int foo() { return 0; }\n" +
+ "}";
+
+ this.runConformTest(new String[] {"p/I1.java", I1 ,"p/P1.java" , P1 } ,
+ new String[] {"module-info.java", moduleInfo }, "" );
+}
+
+public void test008() {
+ File outputDirectory = new File(OUTPUT_DIR);
+ Util.flushDirectoryContent(outputDirectory);
+
+ String moduleInfo = "" +
+ "/**\n" +
+ " */\n" +
+ "module mod.one { \n" +
+ " exports p;\n" +
+ "}";
+ String I1 = "" +
+ "package p;\n" +
+ "/**\n" +
+ " * interface I1\n" +
+ " * {@link mod.one/ abc}\n" +
+ " */\n" +
+ "interface I1 {\n" +
+ " /**\n" +
+ " * Method foo\n" +
+ " * @return int\n" +
+ " */\n" +
+ " public int foo();\n" +
+ "}";
+
+ String P1 = "" +
+ "package p;\n" +
+ "/**\n" +
+ " * class P1\n" +
+ " * {@link mod.one/p.I1 xyz}\n" +
+ " */\n" +
+ "public class P1 implements I1 {\n" +
+ " @Override\n" +
+ " public int foo() { return 0; }\n" +
+ "}";
+
+ this.runConformTest(new String[] {"p/I1.java", I1 ,"p/P1.java" , P1 } ,
+ new String[] {"module-info.java", moduleInfo }, "" );
+}
+
+public void test009() {
+ File outputDirectory = new File(OUTPUT_DIR);
+ Util.flushDirectoryContent(outputDirectory);
+
+ String moduleInfo = "" +
+ "/**\n" +
+ " */\n" +
+ "module mod.one { \n" +
+ " exports p;\n" +
+ "}";
+ String I1 = "" +
+ "package p;\n" +
+ "/**\n" +
+ " * interface I1\n" +
+ " * {@linkplain mod.one/ abc}\n" +
+ " */\n" +
+ "interface I1 {\n" +
+ " /**\n" +
+ " * Method foo\n" +
+ " * @return int\n" +
+ " */\n" +
+ " public int foo();\n" +
+ "}";
+
+ String P1 = "" +
+ "package p;\n" +
+ "/**\n" +
+ " * class P1\n" +
+ " * {@linkplain mod.one/p.I1 xyz}\n" +
+ " */\n" +
+ "public class P1 implements I1 {\n" +
+ " @Override\n" +
+ " public int foo() { return 0; }\n" +
+ "}";
+
+ this.runConformTest(new String[] {"p/I1.java", I1 ,"p/P1.java" , P1 } ,
+ new String[] {"module-info.java", moduleInfo }, "" );
+}
+
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LocalStaticsTest_15.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LocalStaticsTest_15.java
index 9df92de..748c06d 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LocalStaticsTest_15.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LocalStaticsTest_15.java
@@ -930,4 +930,83 @@
"----------\n"
);
}
+ public void testBug568514LocalEnums_001() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "class X {\n"+
+ " public void foo() {\n" +
+ " public enum I {}\n"+
+ " }\n"+
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 3)\n" +
+ " public enum I {}\n" +
+ " ^\n" +
+ "Illegal modifier for local enum I; no explicit modifier is permitted\n" +
+ "----------\n"
+ );
+ }
+ public void testBug568514LocalEnums_002() {
+ Map<String, String> options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.DISABLED);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "class X {\n"+
+ " public void foo() {\n" +
+ " public enum I {}\n"+
+ " }\n"+
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 3)\n" +
+ " public enum I {}\n" +
+ " ^\n" +
+ "The member enum I can only be defined inside a top-level class or interface or in a static context\n" +
+ "----------\n",
+ null,
+ true,
+ options
+ );
+ }
+ public void testBug568514LocalEnums_003() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "class X {\n"+
+ " public void foo() {\n" +
+ " public enum I {}\n"+
+ " Zork;\n"+
+ " }\n"+
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 4)\n" +
+ " Zork;\n" +
+ " ^^^^\n" +
+ "Syntax error, insert \"VariableDeclarators\" to complete LocalVariableDeclaration\n" +
+ "----------\n"
+ );
+ }
+ public void testBug568514LocalEnums_004() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "class X {\n"+
+ " public void foo() {\n" +
+ " public strictfp enum I {}\n"+
+ " Zork;\n"+
+ " }\n"+
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 4)\n" +
+ " Zork;\n" +
+ " ^^^^\n" +
+ "Syntax error, insert \"VariableDeclarators\" to complete LocalVariableDeclaration\n" +
+ "----------\n"
+ );
+ }
}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java
index 248e45d..9ac6d83 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java
@@ -46,7 +46,7 @@
public class ModuleCompilationTests extends AbstractBatchCompilerTest {
static {
-// TESTS_NAMES = new String[] { "test001" };
+// TESTS_NAMES = new String[] { "testRelease565930" };
// TESTS_NUMBERS = new int[] { 1 };
// TESTS_RANGE = new int[] { 298, -1 };
}
@@ -4066,8 +4066,8 @@
"----------\n" +
"1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 3)\n" +
" public java.util.stream.Stream<String> emptyStream() {\n" +
- " ^^^^^^^^^^^^^^^^\n" +
- "java.util.stream cannot be resolved to a type\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "java.util.stream.Stream cannot be resolved to a type\n" +
"----------\n" +
"1 problem (1 error)\n",
true);
@@ -5477,4 +5477,40 @@
false,
"");
}
+ public void testRelease565930_1() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "Dummy.java",
+ "public class Dummy {\n"
+ + " boolean b = new String(\"a\").contains(\"b\");\n"
+ + "}",
+ },
+ "\"" + OUTPUT_DIR + File.separator + "Dummy.java\""
+ + " --release 9 -d \"" + OUTPUT_DIR + "\"",
+ "",
+ "",
+ true);
+ }
+ public void testRelease565930_2() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "Main.java",
+ "public final class Main<T extends Object> {\n"
+ + " public void test() {\n"
+ + " final ClassLoader classLoader = this.getClass().getClassLoader();\n"
+ + " } \n"
+ + "}",
+ },
+ "\"" + OUTPUT_DIR + File.separator + "Main.java\""
+ + " --release 9 -d \"" + OUTPUT_DIR + "\"",
+ "",
+ "----------\n" +
+ "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/Main.java (at line 3)\n" +
+ " final ClassLoader classLoader = this.getClass().getClassLoader();\n" +
+ " ^^^^^^^^^^^\n" +
+ "The value of the local variable classLoader is not used\n" +
+ "----------\n" +
+ "1 problem (1 warning)\n",
+ true);
+ }
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java
index 8a5b888..20800c7 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java
@@ -7362,6 +7362,7 @@
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=421711, [1.8][compiler] '_' as identifier for a lambda parameter should be rejected.
public void testUnderScoreParameter() {
String level = this.complianceLevel >= ClassFileConstants.JDK9 ? "ERROR" : "WARNING";
+ String errorMessage = this.complianceLevel >= ClassFileConstants.JDK9 ? "\'_\' is a keyword from source level 9 onwards, cannot be used as identifier\n" : "\'_\' should not be used as an identifier, since it is a reserved keyword from source level 1.8 on\n";
this.runNegativeTest(
new String[] {
"X.java",
@@ -7380,17 +7381,17 @@
"1. ERROR in X.java (at line 6)\n" +
" F f = (int _) -> {\n" +
" ^\n" +
- "\'_\' should not be used as an identifier, since it is a reserved keyword from source level 1.8 on\n" +
+ "\'_\' is a keyword from source level 9 onwards, cannot be used as identifier\n" +
"----------\n" +
"2. "+ level +" in X.java (at line 8)\n" +
" F f2 = _ -> {};\n" +
" ^\n" +
- "\'_\' should not be used as an identifier, since it is a reserved keyword from source level 1.8 on\n" +
+ errorMessage +
"----------\n" +
"3. ERROR in X.java (at line 8)\n" +
" F f2 = _ -> {};\n" +
" ^\n" +
- "\'_\' should not be used as an identifier, since it is a reserved keyword from source level 1.8 on\n" +
+ "\'_\' is a keyword from source level 9 onwards, cannot be used as identifier\n" +
"----------\n"
);
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java
index 33d955d..07ff8d7 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java
@@ -70,7 +70,7 @@
runner.expectedOutputString = expectedOutput;
runner.vmArguments = new String[] {"--enable-preview"};
runner.customOptions = customOptions;
- runner.javacTestOptions = JavacTestOptions.forReleaseWithPreview("15");
+ runner.javacTestOptions = JavacTestOptions.forReleaseWithPreview("16");
runner.runConformTest();
}
@Override
@@ -2382,7 +2382,7 @@
"1. ERROR in X.java (at line 1)\n" +
" record R() {}\n" +
" ^^^^^^\n" +
- "Syntax error on token \"record\", record expected\n" +
+ "Records is a preview feature and disabled by default. Use --enable-preview to enable\n" +
"----------\n",
null,
true,
@@ -2415,6 +2415,27 @@
options
);
}
+@SuppressWarnings({ "unchecked", "rawtypes" })
+public void testBug558718_003() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_14);
+ options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.DISABLED);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "record R() {}\n",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 1)\n" +
+ " record R() {}\n" +
+ " ^^^^^^\n" +
+ "The preview feature Records is only available with source level 16 and above\n" +
+ "----------\n",
+ null,
+ true,
+ options
+ );
+}
public void testBug56180_001() throws Exception {
runConformTest(
new String[] {
@@ -6874,7 +6895,7 @@
"1. ERROR in X.java (at line 1)\n" +
" record Point(record x, int i) { }\n" +
" ^^^^^^\n" +
- "Syntax error on token \"record\", record expected\n" +
+ "Records is a preview feature and disabled by default. Use --enable-preview to enable\n" +
"----------\n" +
"2. WARNING in X.java (at line 7)\n" +
" class record {}\n" +
@@ -7667,7 +7688,7 @@
"1. ERROR in X.java (at line 3)\n" +
" static enum E {\n" +
" ^\n" +
- "A local interface, enum or record E is implicitly static; cannot have explicit static declaration\n" +
+ "Illegal modifier for local enum E; no explicit modifier is permitted\n" +
"----------\n");
}
public void testBug566063_003() {
@@ -7694,12 +7715,12 @@
"1. ERROR in X.java (at line 3)\n" +
" static enum E {\n" +
" ^\n" +
- "A local interface, enum or record E is implicitly static; cannot have explicit static declaration\n" +
+ "Illegal modifier for local enum E; no explicit modifier is permitted\n" +
"----------\n" +
"2. ERROR in X.java (at line 8)\n" +
" static record Bar(E x) implements I{}\n" +
" ^^^\n" +
- "A local interface, enum or record Bar is implicitly static; cannot have explicit static declaration\n" +
+ "A local class or interface Bar is implicitly static; cannot have explicit static declaration\n" +
"----------\n");
}
public void testBug566063_004() {
@@ -7976,4 +7997,71 @@
new String[] {"--enable-preview"},
getCompilerOptions());
}
+public void testBug561199_001() {
+ Map<String, String> options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.ERROR);
+ runNegativeTest(
+ new String[] {
+ "R.java",
+ "record R() implements java.io.Serializable {}\n",
+ "X.java",
+ "class X implements java.io.Serializable {}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 1)\n" +
+ " class X implements java.io.Serializable {}\n" +
+ " ^\n" +
+ "The serializable class X does not declare a static final serialVersionUID field of type long\n" +
+ "----------\n",
+ null,
+ true,
+ new String[] {"--enable-preview"},
+ options);
+}
+public void testBug568922_001() {
+ runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n"+
+ " public static void main(String[] args) {\n"+
+ " @SuppressWarnings(\"preview\")\n"+
+ " record R() {\n"+
+ " R {\n"+
+ " super();\n"+
+ " System.out.println(\"helo\");\n"+
+ " }\n"+
+ " }\n"+
+ " new R();\n"+
+ " }\n"+
+ "}"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 6)\n" +
+ " super();\n" +
+ " ^^^^^^^^\n" +
+ "The body of a compact constructor must not contain an explicit constructor call\n" +
+ "----------\n",
+ null,
+ true,
+ new String[] {"--enable-preview"},
+ getCompilerOptions());
+}
+public void testBug568922_002() {
+ runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n"+
+ " public static void main(String[] args) {\n"+
+ " @SuppressWarnings(\"preview\")\n"+
+ " record R() {\n"+
+ " R {\n"+
+ " System.out.println(\"helo\");\n"+
+ " }\n"+
+ " }\n"+
+ " new R();\n"+
+ " }\n"+
+ "}"
+ },
+ "helo");
+}
}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java
index 138f7eb..d51b717 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java
@@ -6591,4 +6591,382 @@
"The type SQLiteDatabase must implement the inherited abstract method Closeable.close()\n" +
"----------\n");
}
+public void testBug499037_001_since_9() {
+ if (this.complianceLevel < ClassFileConstants.JDK9) return;
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportSyntheticAccessEmulation, CompilerOptions.IGNORE);
+ options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
+ runLeakTest(
+ new String[] {
+ "X.java",
+ "import java.io.Closeable;\n" +
+ "import java.io.IOException;\n" +
+ "\n" +
+ "class Y implements Closeable {\n" +
+ " @Override\n" +
+ " public void close() throws IOException {\n" +
+ " // nothing\n" +
+ " }\n" +
+ "}\n" +
+ "public class X {\n" +
+ "\n" +
+ " public void foo() throws IOException {\n" +
+ " final Y y1 = new Y();\n" +
+ " try (y1) { \n" +
+ " //\n" +
+ " }\n" +
+ " } \n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(\"Done\");\n" +
+ " }\n" +
+ "} \n"
+ },
+ "",
+ options);
+}
+public void testBug499037_002_since_9() {
+ if (this.complianceLevel < ClassFileConstants.JDK9) return;
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportSyntheticAccessEmulation, CompilerOptions.IGNORE);
+ options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
+ runLeakTest(
+ new String[] {
+ "X.java",
+ "import java.io.Closeable;\n" +
+ "import java.io.IOException;\n" +
+ "\n" +
+ "class Y implements Closeable {\n" +
+ " @Override\n" +
+ " public void close() throws IOException {\n" +
+ " // nothing\n" +
+ " }\n" +
+ "}\n" +
+ "public class X {\n" +
+ "\n" +
+ " public void foo() throws IOException {\n" +
+ " Y y1 = new Y();\n" +
+ " try (y1; final Y y2 = new Y()) { \n" +
+ " //\n" +
+ " }\n" +
+ " } \n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(\"Done\");\n" +
+ " }\n" +
+ "} \n"
+ },
+ "",
+ options);
+}
+public void testBug499037_003_since_9() {
+ if (this.complianceLevel < ClassFileConstants.JDK9) return;
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportSyntheticAccessEmulation, CompilerOptions.IGNORE);
+ runLeakTest(
+ new String[] {
+ "X.java",
+ "import java.io.Closeable;\n" +
+ "import java.io.IOException;\n" +
+ "\n" +
+ "public class X { \n" +
+ " public void foo() throws IOException {\n" +
+ " Y y1 = new Y();\n" +
+ " try(y1) { \n" +
+ " return;\n" +
+ " }\n" +
+ " } \n" +
+ "} \n" +
+ "\n" +
+ "class Y implements Closeable {\n" +
+ " final int x = 10;\n" +
+ " @Override\n" +
+ " public void close() throws IOException {\n" +
+ " // nothing\n" +
+ " }\n" +
+ "}"
+ },
+ "",
+ options);
+}
+public void testBug499037_004_since_9() {
+ if (this.complianceLevel < ClassFileConstants.JDK9) return;
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportSyntheticAccessEmulation, CompilerOptions.IGNORE);
+ options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
+ runLeakTest(
+ new String[] {
+ "X.java",
+ "import java.io.IOException;\n" +
+ "\n" +
+ "class Z {\n" +
+ " final Y yz = new Y();\n" +
+ "}\n" +
+ "public class X extends Z {\n" +
+ " final Y y2 = new Y();\n" +
+ " \n" +
+ " public void foo() {\n" +
+ " try (super.yz; y2) {\n" +
+ " System.out.println(\"In Try\");\n" +
+ " } catch (IOException e) {\n" +
+ " \n" +
+ " }finally { \n" +
+ " }\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " new X().foo();\n" +
+ " }\n" +
+ "}\n" +
+ "class Y implements AutoCloseable {\n" +
+ " @Override\n" +
+ " public void close() throws IOException {\n" +
+ " System.out.println(\"Closed\");\n" +
+ " } \n" +
+ "} \n"
+ },
+ "",
+ options);
+}
+public void testBug499037_005_since_9() {
+ if (this.complianceLevel < ClassFileConstants.JDK9) return;
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportSyntheticAccessEmulation, CompilerOptions.IGNORE);
+ options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
+ runLeakTest(
+ new String[] {
+ "X.java",
+ "import java.io.IOException;\n"+
+ "\n"+
+ "public class X {\n"+
+ " void test(boolean b) throws IOException {\n"+
+ " Y y = new Y();\n"+
+ " if (b) {\n"+
+ " try (y) {}\n"+
+ " }\n"+
+ " }\n"+
+ "}\n"+
+ "\n"+
+ "class Y implements AutoCloseable {\n"+
+ " @Override\n"+
+ " public void close() throws IOException {\n"+
+ " }\n"+
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 5)\n" +
+ " Y y = new Y();\n" +
+ " ^\n" +
+ "Potential resource leak: \'y\' may not be closed\n" +
+ "----------\n",
+ options);
+}
+// non-empty finally block - takes a different route
+public void testBug499037_006_since_9() {
+ if (this.complianceLevel < ClassFileConstants.JDK9) return;
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportSyntheticAccessEmulation, CompilerOptions.IGNORE);
+ options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
+ runLeakTest(
+ new String[] {
+ "X.java",
+ "import java.io.IOException;\n"+
+ "\n"+
+ "public class X {\n"+
+ " void test(boolean b) throws IOException {\n"+
+ " Y y = new Y();\n"+
+ " if (b) {\n"+
+ " try (y;Y y2 = new Y();) { \n"+
+ " } finally {\n"+
+ " System.out.println(\"hello\");\n"+
+ " }\n"+
+ " }\n"+
+ " }\n"+
+ "}\n"+
+ "\n"+
+ "class Y implements AutoCloseable {\n"+
+ " @Override\n"+
+ " public void close() throws IOException {\n"+
+ " }\n"+
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 5)\n" +
+ " Y y = new Y();\n" +
+ " ^\n" +
+ "Potential resource leak: \'y\' may not be closed\n" +
+ "----------\n",
+ options);
+}
+public void testBug499037_007_since_9() {
+ if (this.complianceLevel < ClassFileConstants.JDK9) return;
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportSyntheticAccessEmulation, CompilerOptions.IGNORE);
+ options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
+ runLeakTest(
+ new String[] {
+ "X.java",
+ "import java.io.IOException;\n"+
+ "\n"+
+ "public class X {\n"+
+ " void test(boolean b) throws IOException {\n"+
+ " Y y = new Y();\n"+
+ " if (b) {\n"+
+ " try (y) { \n"+
+ " // nothing \n"+
+ " }\n"+
+ " }\n"+
+ " else {\n"+
+ " y.close();\n"+
+ " }\n"+
+ " }\n"+
+ "}\n"+
+ "\n"+
+ "class Y implements AutoCloseable {\n"+
+ " @Override\n"+
+ " public void close() throws IOException {\n"+
+ " }\n"+
+ "}\n"
+ },
+ "",
+ options);
+}
+public void testBug499037_008_since_9() {
+ if (this.complianceLevel < ClassFileConstants.JDK9) return;
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportSyntheticAccessEmulation, CompilerOptions.IGNORE);
+ options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
+ runLeakTest(
+ new String[] {
+ "X.java",
+ "import java.io.IOException;\n"+
+ "\n"+
+ "public class X {\n"+
+ " void test(boolean b, Y yDash) throws IOException {\n"+
+ " Y y = new Y();\n"+
+ " if (b) {\n"+
+ " try (y; yDash) { \n"+
+ " // nothing \n"+
+ " }\n"+
+ " }\n"+
+ " else {\n"+
+ " }\n"+
+ " }\n"+
+ "}\n"+
+ "\n"+
+ "class Y implements AutoCloseable {\n"+
+ " @Override\n"+
+ " public void close() throws IOException {\n"+
+ " }\n"+
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 5)\n" +
+ " Y y = new Y();\n" +
+ " ^\n" +
+ "Potential resource leak: \'y\' may not be closed\n" +
+ "----------\n",
+ options);
+}
+public void testBug499037_009_since_9() {
+ if (this.complianceLevel < ClassFileConstants.JDK9) return;
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportSyntheticAccessEmulation, CompilerOptions.IGNORE);
+ options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
+ runLeakTest(
+ new String[] {
+ "X.java",
+ "import java.io.IOException;\n"+
+ "\n"+
+ "public class X {\n"+
+ "private void foo(Y y) {}\n" +
+ " void test(boolean b) throws IOException {\n"+
+ " Y y = new Y();\n"+
+ " if (b) {\n"+
+ " try (y) { \n"+
+ " // nothing \n"+
+ " }\n"+
+ " }\n"+
+ " else {\n"+
+ " foo(y);\n"+
+ " }\n"+
+ " }\n"+
+ "}\n"+
+ "\n"+
+ "class Y implements AutoCloseable {\n"+
+ " @Override\n"+
+ " public void close() throws IOException {\n"+
+ " }\n"+
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 6)\n" +
+ " Y y = new Y();\n" +
+ " ^\n" +
+ "Potential resource leak: \'y\' may not be closed\n" +
+ "----------\n",
+ options);
+}
+public void testBug499037_010_since_9() {
+ if (this.complianceLevel < ClassFileConstants.JDK9) return;
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportSyntheticAccessEmulation, CompilerOptions.IGNORE);
+ options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
+ runLeakTest(
+ new String[] {
+ "X.java",
+ "import java.io.IOException;\n"+
+ "\n"+
+ "public class X {\n"+
+ "private Y foo(Y y) {return y;}\n" +
+ " void test(boolean b) throws IOException {\n"+
+ " Y y = new Y();\n"+
+ " Y yy = foo(y);\n"+
+ " if (b) {\n"+
+ " try (y;yy) { \n"+
+ " // do nothing \n"+
+ " }\n"+
+ " }\n"+
+ " else {\n"+
+ " // do nothing\n"+
+ " }\n"+
+ " }\n"+
+ "}\n"+
+ "\n"+
+ "class Y implements AutoCloseable {\n"+
+ " @Override\n"+
+ " public void close() throws IOException {\n"+
+ " }\n"+
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 6)\n" +
+ " Y y = new Y();\n" +
+ " ^\n" +
+ "Potential resource leak: \'y\' may not be closed\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 7)\n" +
+ " Y yy = foo(y);\n" +
+ " ^^\n" +
+ "Potential resource leak: \'yy\' may not be closed\n" +
+ "----------\n",
+ options);
+}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SealedTypes15Tests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SealedTypes15Tests.java
index 1b8d662..ffd36f3 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SealedTypes15Tests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SealedTypes15Tests.java
@@ -35,7 +35,7 @@
static {
// TESTS_NUMBERS = new int [] { 40 };
// TESTS_RANGE = new int[] { 1, -1 };
-// TESTS_NAMES = new String[] { "testBug566979","testBug566980", "testBug566846"};
+// TESTS_NAMES = new String[] { "testBug568428"};
}
public static Class<?> testClass() {
@@ -73,7 +73,7 @@
runner.expectedOutputString = expectedOutput;
runner.vmArguments = new String[] {"--enable-preview"};
runner.customOptions = customOptions;
- runner.javacTestOptions = JavacTestOptions.forReleaseWithPreview("15");
+ runner.javacTestOptions = JavacTestOptions.forReleaseWithPreview("16");
runner.runConformTest();
}
@Override
@@ -249,7 +249,7 @@
"2. ERROR in X.java (at line 1)\n" +
" sealed public sealed class X {\n" +
" ^\n" +
- "Sealed class lacks the permits clause and no top level or nested class from the same compilation unit declares X as its direct superclass\n" +
+ "Sealed class or interface lacks the permits clause and no class or interface from the same compilation unit declares X as its direct superclass or superinterface\n" +
"----------\n");
}
public void testBug562715_006() {
@@ -266,7 +266,7 @@
"1. ERROR in X.java (at line 1)\n" +
" public sealed class X {\n" +
" ^\n" +
- "Sealed class lacks the permits clause and no top level or nested class from the same compilation unit declares X as its direct superclass\n" +
+ "Sealed class or interface lacks the permits clause and no class or interface from the same compilation unit declares X as its direct superclass or superinterface\n" +
"----------\n" +
"2. ERROR in X.java (at line 2)\n" +
" public static sealed void main(String[] args){\n" +
@@ -331,7 +331,7 @@
"1. ERROR in X.java (at line 1)\n" +
" public sealed class X permits {\n" +
" ^\n" +
- "Sealed class lacks the permits clause and no top level or nested class from the same compilation unit declares X as its direct superclass\n" +
+ "Sealed class or interface lacks the permits clause and no class or interface from the same compilation unit declares X as its direct superclass or superinterface\n" +
"----------\n" +
"2. ERROR in X.java (at line 1)\n" +
" public sealed class X permits {\n" +
@@ -345,7 +345,7 @@
"----------\n");
}
// TODO : Enable after error flag code implemented
- public void _testBug562715_011() {
+ public void testBug562715_011() {
this.runNegativeTest(
new String[] {
"X.java",
@@ -357,13 +357,23 @@
"}",
},
"----------\n" +
- "1. ERROR in X.java (at line 2)\n" +
- " EXPECTED ERROR IN RECORD\n" +
+ "1. ERROR in X.java (at line 1)\n" +
+ " sealed enum Natural {ONE, TWO}\n" +
+ " ^^^^^^^\n" +
+ "Illegal modifier for the enum Natural; only public is permitted\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 2)\n" +
+ " public sealed class X {\n" +
+ " ^\n" +
+ "Sealed class or interface lacks the permits clause and no class or interface from the same compilation unit declares X as its direct superclass or superinterface\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 3)\n" +
+ " public static sealed void main(String[] args){\n" +
" ^^^^^^\n" +
"Syntax error on token \"sealed\", static expected\n" +
"----------\n");
}
- public void _testBug562715_xxx() {
+ public void testBug562715_xxx() {
this.runNegativeTest(
new String[] {
"X.java",
@@ -375,8 +385,18 @@
"}",
},
"----------\n" +
- "1. ERROR in X.java (at line 2)\n" +
- " EXPECTED ERROR IN RECORD\n" +
+ "1. ERROR in X.java (at line 1)\n" +
+ " sealed record R() {}\n" +
+ " ^\n" +
+ "Illegal modifier for the record R; only public, final and strictfp are permitted\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 2)\n" +
+ " public sealed class X {\n" +
+ " ^\n" +
+ "Sealed class or interface lacks the permits clause and no class or interface from the same compilation unit declares X as its direct superclass or superinterface\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 3)\n" +
+ " public static sealed void main(String[] args){\n" +
" ^^^^^^\n" +
"Syntax error on token \"sealed\", static expected\n" +
"----------\n");
@@ -435,7 +455,7 @@
"1. ERROR in p1\\A.java (at line 2)\n" +
" public sealed class A extends X{}\n" +
" ^\n" +
- "Sealed class lacks the permits clause and no top level or nested class from the same compilation unit declares A as its direct superclass\n" +
+ "Sealed class or interface lacks the permits clause and no class or interface from the same compilation unit declares A as its direct superclass or superinterface\n" +
"----------\n" +
"2. ERROR in p1\\A.java (at line 2)\n" +
" public sealed class A extends X{}\n" +
@@ -635,7 +655,7 @@
"1. ERROR in p2\\Y.java (at line 2)\n" +
" public final class Y implements p1.X{}\n" +
" ^^^^\n" +
- "The type Y extending a sealed class X should be a permitted subtype of X\n" +
+ "The type Y that implements a sealed interface X should be a permitted subtype of X\n" +
"----------\n");
}
public void testBug563806_013() {
@@ -680,7 +700,7 @@
"2. ERROR in p2\\Y.java (at line 2)\n" +
" public interface Y extends p1.X{}\n" +
" ^^^^\n" +
- "The type Y extending a sealed interface X should be a permitted subtype of X\n" +
+ "The type Y that extends a sealed interface X should be a permitted subtype of X\n" +
"----------\n");
}
public void testBug563806_015() {
@@ -1040,7 +1060,7 @@
"1. ERROR in p1\\X.java (at line 2)\n" +
" public sealed non-sealed interface X {\n" +
" ^\n" +
- "Sealed class lacks the permits clause and no top level or nested class from the same compilation unit declares X as its direct superclass\n" +
+ "Sealed class or interface lacks the permits clause and no class or interface from the same compilation unit declares X as its direct superclass or superinterface\n" +
"----------\n" +
"2. ERROR in p1\\X.java (at line 2)\n" +
" public sealed non-sealed interface X {\n" +
@@ -1109,11 +1129,6 @@
" sealed class Y{}\n" +
" ^\n" +
"Illegal modifier for the local class Y; only abstract or final is permitted\n" +
- "----------\n" +
- "2. ERROR in p1\\X.java (at line 4)\n" +
- " sealed class Y{}\n" +
- " ^\n" +
- "Sealed class lacks the permits clause and no top level or nested class from the same compilation unit declares Y as its direct superclass\n" +
"----------\n");
}
public void testBug563806_037() {
@@ -1150,11 +1165,6 @@
" non-sealed sealed class Y{}\n" +
" ^\n" +
"Illegal modifier for the local class Y; only abstract or final is permitted\n" +
- "----------\n" +
- "2. ERROR in p1\\X.java (at line 4)\n" +
- " non-sealed sealed class Y{}\n" +
- " ^\n" +
- "Sealed class lacks the permits clause and no top level or nested class from the same compilation unit declares Y as its direct superclass\n" +
"----------\n");
}
public void testBug563806_039() {
@@ -1173,7 +1183,7 @@
"1. ERROR in p1\\X.java (at line 2)\n" +
" sealed class A{}\n" +
" ^\n" +
- "Sealed class lacks the permits clause and no top level or nested class from the same compilation unit declares A as its direct superclass\n" +
+ "Sealed class or interface lacks the permits clause and no class or interface from the same compilation unit declares A as its direct superclass or superinterface\n" +
"----------\n" +
"2. ERROR in p1\\X.java (at line 5)\n" +
" class Y extends A{}\n" +
@@ -1302,7 +1312,7 @@
"1. ERROR in p1\\X.java (at line 3)\n" +
" sealed class Y extends X {}\n" +
" ^\n" +
- "Sealed class lacks the permits clause and no top level or nested class from the same compilation unit declares Y as its direct superclass\n" +
+ "Sealed class or interface lacks the permits clause and no class or interface from the same compilation unit declares Y as its direct superclass or superinterface\n" +
"----------\n");
}
// Test that implicit permitted member type with explicit permits clause
@@ -1337,7 +1347,7 @@
"1. ERROR in p1\\X.java (at line 2)\n" +
" sealed interface SI {}\n" +
" ^^\n" +
- "Sealed class lacks the permits clause and no top level or nested class from the same compilation unit declares SI as its direct superclass\n" +
+ "Sealed class or interface lacks the permits clause and no class or interface from the same compilation unit declares SI as its direct superclass or superinterface\n" +
"----------\n");
}
public void testBug564450_001() throws IOException, ClassFormatException {
@@ -2851,7 +2861,7 @@
"1. ERROR in X.java (at line 1)\n" +
" record X(permits p) {\n" +
" ^^^^^^\n" +
- "Syntax error on token \"record\", record expected\n" +
+ "Records is a preview feature and disabled by default. Use --enable-preview to enable\n" +
"----------\n",
null,
true,
@@ -4574,7 +4584,7 @@
"1. ERROR in X.java (at line 1)\n" +
" record X(sealed p) {\n" +
" ^^^^^^\n" +
- "Syntax error on token \"record\", record expected\n" +
+ "Records is a preview feature and disabled by default. Use --enable-preview to enable\n" +
"----------\n",
null,
true,
@@ -5414,4 +5424,97 @@
options
);
}
+ public void testBug568428_001() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "class X {\n"+
+ " public void foo() {\n" +
+ " sealed interface I {}\n"+
+ " }\n"+
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 3)\n" +
+ " sealed interface I {}\n" +
+ " ^\n" +
+ "Illegal modifier for the local interface I; abstract and strictfp are the only modifiers allowed explicitly \n" +
+ "----------\n"
+ );
+ }
+ public void testBug568428_002() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "class X {\n"+
+ " public void foo() {\n" +
+ " non-sealed interface I {}\n"+
+ " }\n"+
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 3)\n" +
+ " non-sealed interface I {}\n" +
+ " ^\n" +
+ "Illegal modifier for the local interface I; abstract and strictfp are the only modifiers allowed explicitly \n" +
+ "----------\n"
+ );
+ }
+ public void testBug568514_001() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "class X {\n"+
+ " public void foo() {\n" +
+ " sealed enum I {}\n"+
+ " }\n"+
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 3)\n" +
+ " sealed enum I {}\n" +
+ " ^\n" +
+ "Illegal modifier for local enum I; no explicit modifier is permitted\n" +
+ "----------\n"
+ );
+ }
+ public void testBug568514_002() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "class X {\n"+
+ " public void foo() {\n" +
+ " non-sealed enum I {}\n"+
+ " }\n"+
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 3)\n" +
+ " non-sealed enum I {}\n" +
+ " ^\n" +
+ "Illegal modifier for local enum I; no explicit modifier is permitted\n" +
+ "----------\n"
+ );
+ }
+ public void testBug568758_001() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public sealed interface X{}\n",
+ "Y.java",
+ "public final class Y implements X{}",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 1)\n" +
+ " public sealed interface X{}\n" +
+ " ^\n" +
+ "Sealed class or interface lacks the permits clause and no class or interface from the same compilation unit declares X as its direct superclass or superinterface\n" +
+ "----------\n" +
+ "----------\n" +
+ "1. ERROR in Y.java (at line 1)\n" +
+ " public final class Y implements X{}\n" +
+ " ^\n" +
+ "The type Y that implements a sealed interface X should be a permitted subtype of X\n" +
+ "----------\n");
+ }
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter_15Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter_15Test.java
index a7e1d89..92b8520 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter_15Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter_15Test.java
@@ -557,6 +557,54 @@
}
}
+ public void testRecord012() throws CoreException {
+ if (!isJRE15) {
+ System.err.println("Test "+getName()+" requires a JRE 15");
+ return;
+ }
+ String contents =
+ "public record X(int myComp) {\n" +
+ " public void foo() {\n" +
+ " System.out.println(\"no error\");\n" +
+ " }\n" +
+ "\n" +
+ "}\n";
+ this.workingCopy = getWorkingCopy("/Converter_15/src/X.java", true/*resolve*/);
+ IJavaProject javaProject = this.workingCopy.getJavaProject();
+ String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true);
+ try {
+ javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
+ javaProject.setOption(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);
+ ASTNode node = buildAST(
+ contents,
+ this.workingCopy);
+ assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
+ CompilationUnit compilationUnit = (CompilationUnit) node;
+ assertProblemsSize(compilationUnit, 0);
+ List<AbstractTypeDeclaration> types = compilationUnit.types();
+ assertEquals("No. of Types is not 1", types.size(), 1);
+ AbstractTypeDeclaration type = types.get(0);
+ assertTrue("type not a Record", type instanceof RecordDeclaration);
+ RecordDeclaration recDecl = (RecordDeclaration)type;
+ MethodDeclaration[] methods = recDecl.getMethods();
+ assertEquals("No. of methods is not 1", methods.length, 1);
+ ITypeBinding typeBinding = type.resolveBinding();
+ assertNotNull("typeBinding is null", typeBinding);
+ IMethodBinding[] mBindings = typeBinding.getDeclaredMethods();
+ assertEquals("No. of declared methods is not 6", mBindings.length, 6);
+ for (IMethodBinding mBinding : mBindings) {
+ if (mBinding.getName().equals("X") || mBinding.getName().equals("foo")) {
+ assertFalse("foo is not a synthetic method", mBinding.isSyntheticRecordMethod());
+ } else {
+ assertTrue("expected a synthetic method", mBinding.isSyntheticRecordMethod());
+ }
+ }
+
+ } finally {
+ javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old);
+ }
+ }
+
public void testClass001() throws CoreException {
if (!isJRE15) {
System.err.println("Test "+getName()+" requires a JRE 15");
@@ -762,7 +810,7 @@
assertEquals("wrong line number", 9, compilationUnit.getLineNumber(node.getStartPosition()));
}
- public void _testPatternInstanceOfExpression001() throws JavaModelException {
+ public void testPatternInstanceOfExpression001() throws JavaModelException {
if (!isJRE15) {
System.err.println("Test "+getName()+" requires a JRE 15");
return;
@@ -797,14 +845,14 @@
checkSourceRange(expression, "o instanceof String s", contents);
assertEquals("Not an instanceof expression", ASTNode.INSTANCEOF_EXPRESSION, expression.getNodeType());
InstanceofExpression instanceofExpression = (InstanceofExpression) expression;
- SingleVariableDeclaration var = instanceofExpression.getPatternVariable();
- checkSourceRange(var, "String s", contents);
+ SimpleName var = instanceofExpression.getPatternVariable();
+ checkSourceRange(var, "s", contents);
}finally {
javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old);
}
}
- public void _testPatternInstanceOfExpression002() throws JavaModelException {
+ public void testPatternInstanceOfExpression002() throws JavaModelException {
if (!isJRE15) {
System.err.println("Test "+getName()+" requires a JRE 15");
return;
@@ -840,13 +888,57 @@
checkSourceRange(expression, "o instanceof String", contents);
assertEquals("Not an instanceof expression", ASTNode.INSTANCEOF_EXPRESSION, expression.getNodeType());
InstanceofExpression instanceofExpression = (InstanceofExpression) expression;
- SingleVariableDeclaration var = instanceofExpression.getPatternVariable();
+ SimpleName var = instanceofExpression.getPatternVariable();
assertNull(var);
}finally {
javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old);
}
}
+ public void testPatternInstanceOfExpression003() throws JavaModelException {
+ if (!isJRE15) {
+ System.err.println("Test "+getName()+" requires a JRE 15");
+ return;
+ }
+ String contents =
+ "public class X {\n" +
+ " public String test001(Object o) {\n" +
+ " if (o instanceof String s){\n" +
+ " System.out.println(s);\n" +
+ " return s;\n" +
+ " }\n" +
+ " return null;\n" +
+ " }\n" +
+ "}" ;
+ this.workingCopy = getWorkingCopy("/Converter_15/src/X.java", true/*resolve*/);
+ IJavaProject javaProject = this.workingCopy.getJavaProject();
+ String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true);
+ try {
+ javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
+ javaProject.setOption(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);
+
+ ASTNode node = buildAST(
+ contents,
+ this.workingCopy);
+ assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
+ CompilationUnit compilationUnit = (CompilationUnit) node;
+ assertProblemsSize(compilationUnit, 0);
+ node = getASTNode(compilationUnit, 0, 0, 0);
+ assertEquals("Not an if statement", ASTNode.IF_STATEMENT, node.getNodeType());
+ IfStatement ifStatement = (IfStatement) node;
+ Expression expression = ifStatement.getExpression();
+ checkSourceRange(expression, "o instanceof String s", contents);
+ assertEquals("Not an instanceof expression", ASTNode.INSTANCEOF_EXPRESSION, expression.getNodeType());
+ InstanceofExpression instanceofExpression = (InstanceofExpression) expression;
+ SimpleName var = instanceofExpression.getPatternVariable();
+ checkSourceRange(var, "s", contents);
+ String instanceofExpressionString = instanceofExpression.toString();
+ assertEquals("o instanceof String s", instanceofExpressionString);
+ }finally {
+ javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old);
+ }
+ }
+
public void testSealed001() throws CoreException {
if (!isJRE15) {
System.err.println("Test "+getName()+" requires a JRE 15");
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaElementDeltaTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaElementDeltaTests.java
index bad8abb..0c3cf05 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaElementDeltaTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaElementDeltaTests.java
@@ -226,7 +226,7 @@
/*
* Ensures that adding a library entry for an existing external library folder triggers the correct delta
*/
-public void testAddExternalLibFolder1() throws CoreException {
+public void _testAddExternalLibFolder1() throws CoreException {
try {
IJavaProject p = createJavaProject("P");
createExternalFolder("externalLib");
@@ -251,7 +251,7 @@
/*
* Ensures that adding a library entry for a non-existing external library folder triggers the correct delta
*/
-public void testAddExternalLibFolder2() throws CoreException {
+public void _testAddExternalLibFolder2() throws CoreException {
try {
IJavaProject p = createJavaProject("P");
refresh(p);
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchNameEnvironmentTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchNameEnvironmentTest.java
new file mode 100644
index 0000000..0ad2678
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchNameEnvironmentTest.java
@@ -0,0 +1,137 @@
+package org.eclipse.jdt.core.tests.model;
+
+import static java.util.stream.Collectors.toCollection;
+
+import java.util.Collection;
+import java.util.LinkedHashSet;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.internal.core.JavaProject;
+import org.eclipse.jdt.internal.core.builder.ClasspathLocation;
+import org.eclipse.jdt.internal.core.search.matching.ClasspathSourceDirectory;
+import org.eclipse.jdt.internal.core.search.matching.JavaSearchNameEnvironment;
+
+import junit.framework.Test;
+
+public class JavaSearchNameEnvironmentTest extends ModifyingResourceTests {
+
+ static {
+ //NameLookup.VERBOSE = true;
+ }
+
+ static class JavaSearchNameEnvironmentUnderTest extends JavaSearchNameEnvironment {
+ public JavaSearchNameEnvironmentUnderTest(IJavaProject javaProject, ICompilationUnit[] copies) {
+ super(javaProject, copies);
+ }
+ public LinkedHashSet<ClasspathLocation> getLocationSet() {
+ return super.locationSet;
+ }
+ @Override
+ public Iterable<ClasspathLocation> getLocationsFor(String moduleName, String qualifiedPackageName) {
+ return super.getLocationsFor(moduleName, qualifiedPackageName);
+ }
+ public LinkedHashSet<ClasspathLocation> getAllIndexedLocations() {
+ return super.packageNameToClassPathLocations.values().stream().flatMap(Collection::stream).collect(toCollection(LinkedHashSet::new));
+ }
+ @Override
+ public void addProjectClassPath(JavaProject javaProject) {
+ super.addProjectClassPath(javaProject);
+ }
+ }
+
+ private IJavaProject p1;
+ private IJavaProject p2;
+
+ public JavaSearchNameEnvironmentTest(String name) {
+ super(name);
+ this.endChar = "";
+ }
+
+ public static Test suite() {
+ return buildModelTestSuite(JavaSearchNameEnvironmentTest.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ this.p1 = setUpJavaProject("JavaSearchMultipleProjects1");
+ this.p2 = setUpJavaProject("JavaSearchMultipleProjects2");
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ try {
+ deleteProject(this.p1.getElementName());
+ deleteProject(this.p2.getElementName());
+ } finally {
+ super.tearDown();
+ }
+ }
+
+ public void testLocationsAreEqual() throws CoreException {
+ JavaSearchNameEnvironmentUnderTest nameEnvironment = newJavaSearchEnvironment(this.p1, this.p2);
+
+ LinkedHashSet<ClasspathLocation> locationSet = nameEnvironment.getLocationSet();
+ LinkedHashSet<ClasspathLocation> allIndexedLocations = nameEnvironment.getAllIndexedLocations();
+
+ for (ClasspathLocation cp : locationSet) {
+ assertTrue("index must contain: " + cp, allIndexedLocations.contains(cp));
+ }
+ }
+
+ public void testWorkingCopies() throws CoreException {
+
+ this.workingCopies = new ICompilationUnit[3];
+ this.workingCopies[0] = getWorkingCopy("/JavaSearchMultipleProjects2/src/b88300/SubClass.java",
+ "package b88300;\n" +
+ "public class SubClass extends SuperClass {\n" +
+ " private void aMethod(String x) {\n" +
+ " }\n" +
+ " public void aMethod(Object x) {\n" +
+ " }\n" +
+ "}\n"
+ );
+ this.workingCopies[1] = getWorkingCopy("/JavaSearchMultipleProjects2/src/b88300/SuperClass.java",
+ "package b88300;\n" +
+ "public class SuperClass {\n" +
+ " public void aMethod(Object x) {\n" +
+ " }\n" +
+ "}\n"
+ );
+ this.workingCopies[2] = getWorkingCopy("/JavaSearchMultipleProjects2/src/b88300/User.java",
+ "package b88300;\n" +
+ "public class User {\n" +
+ " public void methodUsingSubClassMethod() {\n" +
+ " SuperClass user = new SubClass();\n" +
+ " user.aMethod(new Object());\n" +
+ " }\n" +
+ "}\n"
+ );
+
+ JavaSearchNameEnvironmentUnderTest nameEnvironment = newJavaSearchEnvironment(this.p2, this.p1);
+
+ Iterable<ClasspathLocation> locationsForPackage = nameEnvironment.getLocationsFor(null, "b88300");
+ assertNotNull(locationsForPackage);
+ assertTrue(locationsForPackage.iterator().hasNext());
+ ClasspathLocation cp = locationsForPackage.iterator().next();
+ assertTrue(cp instanceof ClasspathSourceDirectory);
+
+ char[][] packageName = new char[][] { "b88300".toCharArray() };
+ assertNotNull("Type User not found!", nameEnvironment.findType("User".toCharArray(), packageName));
+ assertNotNull("Type SuperClass not found!", nameEnvironment.findType("SuperClass".toCharArray(), packageName));
+ assertNotNull("Type SubClass not found!", nameEnvironment.findType("SubClass".toCharArray(), packageName));
+ }
+
+ private JavaSearchNameEnvironmentUnderTest newJavaSearchEnvironment(IJavaProject first, IJavaProject... remaining) {
+ JavaSearchNameEnvironmentUnderTest env = new JavaSearchNameEnvironmentUnderTest(first, this.workingCopies);
+ if(remaining != null) {
+ for (int i = 0; i < remaining.length; i++) {
+ env.addProjectClassPath((JavaProject) remaining[i]);
+ }
+ }
+ return env;
+ }
+}
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 9ac6153..0bad63d 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
@@ -706,9 +706,9 @@
IJavaProject project = setUpJavaProject("ConvertToModule");
Map<String, String> options = new HashMap<>();
// Make sure the new options map doesn't reset.
- options.put(CompilerOptions.OPTION_Compliance, "9");
- options.put(CompilerOptions.OPTION_Source, "9");
- options.put(CompilerOptions.OPTION_TargetPlatform, "9");
+ options.put(CompilerOptions.OPTION_Compliance, "10");
+ options.put(CompilerOptions.OPTION_Source, "10");
+ options.put(CompilerOptions.OPTION_TargetPlatform, "10");
options.put(CompilerOptions.OPTION_Release, "enabled");
project.setOptions(options);
project.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchTests.java
index bb234e8..6eec1fb 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchTests.java
@@ -74,6 +74,7 @@
allClasses.add(MatchingRegionsTest.class);
allClasses.add(JavaIndexTests.class);
allClasses.add(Bug376673Test.class);
+ allClasses.add(JavaSearchNameEnvironmentTest.class);
// Reset forgotten subsets of tests
TestCase.TESTS_PREFIX = null;
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingInstanceOfPatternExpressionTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingInstanceOfPatternExpressionTest.java
index ce33099..6d74c17 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingInstanceOfPatternExpressionTest.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingInstanceOfPatternExpressionTest.java
@@ -26,7 +26,6 @@
import org.eclipse.jdt.core.dom.InstanceofExpression;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.SimpleType;
-import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
@@ -90,10 +89,7 @@
instanceOfExpression.setLeftOperand(ast.newSimpleName("o"));//$NON-NLS-1$
SimpleType simpleType = ast.newSimpleType(ast.newSimpleName("String"));//$NON-NLS-1$
instanceOfExpression.setRightOperand(simpleType);
- SingleVariableDeclaration patternVariable = ast.newSingleVariableDeclaration();
- patternVariable.setName(ast.newSimpleName("s"));
- patternVariable.setType(ast.newSimpleType(ast.newSimpleName("String")));//$NON-NLS-1$
- instanceOfExpression.setPatternVariable(patternVariable);
+ instanceOfExpression.setPatternVariable(ast.newSimpleName("s"));
ifStatement.setExpression(instanceOfExpression);
ifStatement.setThenStatement(ast.newEmptyStatement());
rewrite.getListRewrite(block, Block.STATEMENTS_PROPERTY).insertLast(ifStatement, null);
@@ -113,4 +109,56 @@
assertEqualString(preview, buf.toString());
}
+
+ @SuppressWarnings({ "rawtypes", "deprecation" })
+ public void test002() throws Exception {
+ if (this.apiLevel != 15) {
+ System.err.println("Test "+getName()+" requires a JRE 15");
+ return;
+ }
+ IPackageFragment pack1= this.sourceFolder.createPackageFragment("test1", false, null);
+ StringBuffer buf= new StringBuffer();
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("public class X {\n");
+ buf.append(" void foo(Object o) {\n");
+ buf.append(" if (o instanceof String s)\n");
+ buf.append(" ;\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ ICompilationUnit cu= pack1.createCompilationUnit("X.java", buf.toString(), false, null);
+
+ CompilationUnit astRoot= createAST(cu);
+ ASTRewrite rewrite= ASTRewrite.create(astRoot.getAST());
+
+ AST ast= astRoot.getAST();
+
+ assertTrue("Parse errors", (astRoot.getFlags() & ASTNode.MALFORMED) == 0);
+ TypeDeclaration type= findTypeDeclaration(astRoot, "X");
+ MethodDeclaration methodDecl= findMethodDeclaration(type, "foo");
+ Block block= methodDecl.getBody();
+ List blockStatements= block.statements();
+ assertTrue("Number of statements not 1", blockStatements.size() == 1);
+ { // add InstanceOfPattern expression
+
+ IfStatement ifStatement = (IfStatement)blockStatements.get(0);
+ InstanceofExpression instanceOfExpression = (InstanceofExpression)ifStatement.getExpression();
+ rewrite.set(instanceOfExpression, InstanceofExpression.PATTERN_VARIABLE_PROPERTY, ast.newSimpleName("str1"), null);
+
+ }
+
+ String preview= evaluateRewrite(cu, rewrite);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("public class X {\n");
+ buf.append(" void foo(Object o) {\n");
+ buf.append(" if (o instanceof String str1)\n");
+ buf.append(" ;\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+
+ assertEqualString(preview, buf.toString());
+
+ }
}
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247.java
index a848b11..3e67ec9 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2018, 2019 IBM Corporation.
+ * Copyright (c) 2018, 2020 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
@@ -210,52 +210,55 @@
}
@Override
public synchronized char[][] getModulesDeclaringPackage(String qualifiedPackageName, String moduleName) {
- // Ignore moduleName as this has nothing to do with modules (as of now)
- if (this.packageCache != null)
- return singletonModuleNameIf(this.packageCache.contains(qualifiedPackageName));
-
- this.packageCache = new HashSet<>(41);
- this.packageCache.add(Util.EMPTY_STRING);
- List<String> sub = new ArrayList<>();
- try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(this.releasePath)) {
- for (final java.nio.file.Path subdir: stream) {
- String rel = JRTUtil.sanitizedFileName(subdir);
- if (rel.contains(this.releaseInHex)) {
- sub.add(rel);
- } else {
- continue;
- }
- Files.walkFileTree(subdir, new FileVisitor<java.nio.file.Path>() {
- @Override
- public FileVisitResult preVisitDirectory(java.nio.file.Path dir, BasicFileAttributes attrs) throws IOException {
- if (dir.getNameCount() <= 1)
+ if (this.packageCache == null) {
+ this.packageCache = new HashSet<>(41);
+ this.packageCache.add(Util.EMPTY_STRING);
+ List<String> sub = new ArrayList<>();
+ try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(this.releasePath)) {
+ for (final java.nio.file.Path subdir: stream) {
+ String rel = JRTUtil.sanitizedFileName(subdir);
+ if (rel.contains(this.releaseInHex)) {
+ sub.add(rel);
+ } else {
+ continue;
+ }
+ Files.walkFileTree(subdir, new FileVisitor<java.nio.file.Path>() {
+ @Override
+ public FileVisitResult preVisitDirectory(java.nio.file.Path dir, BasicFileAttributes attrs) throws IOException {
+ if (dir.getNameCount() <= 1)
+ return FileVisitResult.CONTINUE;
+ Path relative = dir.subpath(1, dir.getNameCount());
+ addToPackageCache(relative.toString(), false);
return FileVisitResult.CONTINUE;
- Path relative = dir.subpath(1, dir.getNameCount());
- addToPackageCache(relative.toString(), false);
- return FileVisitResult.CONTINUE;
- }
+ }
- @Override
- public FileVisitResult visitFile(java.nio.file.Path f, BasicFileAttributes attrs) throws IOException {
- return FileVisitResult.CONTINUE;
- }
+ @Override
+ public FileVisitResult visitFile(java.nio.file.Path f, BasicFileAttributes attrs) throws IOException {
+ return FileVisitResult.CONTINUE;
+ }
- @Override
- public FileVisitResult visitFileFailed(java.nio.file.Path f, IOException exc) throws IOException {
- return FileVisitResult.CONTINUE;
- }
+ @Override
+ public FileVisitResult visitFileFailed(java.nio.file.Path f, IOException exc) throws IOException {
+ return FileVisitResult.CONTINUE;
+ }
- @Override
- public FileVisitResult postVisitDirectory(java.nio.file.Path dir, IOException exc) throws IOException {
- return FileVisitResult.CONTINUE;
- }
- });
+ @Override
+ public FileVisitResult postVisitDirectory(java.nio.file.Path dir, IOException exc) throws IOException {
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ // Rethrow
}
- } catch (IOException e) {
- e.printStackTrace();
- // Rethrow
+ this.subReleases = sub.toArray(new String[sub.size()]);
}
- this.subReleases = sub.toArray(new String[sub.size()]);
+ if (moduleName == null) {
+ // Delegate to the boss, even if it means inaccurate error reporting at times
+ List<String> mods = JRTUtil.getModulesDeclaringPackage(this.file, qualifiedPackageName, moduleName);
+ return CharOperation.toCharArrays(mods);
+ }
return singletonModuleNameIf(this.packageCache.contains(qualifiedPackageName));
}
@Override
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247Jdk12.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247Jdk12.java
index d49d5f7..a4ba1c0 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247Jdk12.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247Jdk12.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2019 IBM Corporation.
+ * Copyright (c) 2019, 2020 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
@@ -30,6 +30,7 @@
import java.util.Map;
import java.util.function.Function;
+import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.batch.FileSystem.Classpath;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
@@ -254,51 +255,54 @@
}
@Override
public synchronized char[][] getModulesDeclaringPackage(String qualifiedPackageName, String moduleName) {
- // Ignore moduleName as this has nothing to do with modules (as of now)
- if (this.packageCache != null)
- return singletonModuleNameIf(this.packageCache.contains(qualifiedPackageName));
-
- this.packageCache = new HashSet<>(41);
- this.packageCache.add(Util.EMPTY_STRING);
- try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(this.releasePath)) {
- for (final java.nio.file.Path subdir: stream) {
- String rel = JRTUtil.sanitizedFileName(subdir);
- if (!rel.contains(this.releaseInHex)) {
- continue;
- }
- try (DirectoryStream<java.nio.file.Path> stream2 = Files.newDirectoryStream(subdir)) {
- for (final java.nio.file.Path subdir2: stream2) {
- Files.walkFileTree(subdir2, new FileVisitor<java.nio.file.Path>() {
- @Override
- public FileVisitResult preVisitDirectory(java.nio.file.Path dir, BasicFileAttributes attrs) throws IOException {
- if (dir.getNameCount() <= 2)
+ if (this.packageCache == null) {
+ this.packageCache = new HashSet<>(41);
+ this.packageCache.add(Util.EMPTY_STRING);
+ try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(this.releasePath)) {
+ for (final java.nio.file.Path subdir: stream) {
+ String rel = JRTUtil.sanitizedFileName(subdir);
+ if (!rel.contains(this.releaseInHex)) {
+ continue;
+ }
+ try (DirectoryStream<java.nio.file.Path> stream2 = Files.newDirectoryStream(subdir)) {
+ for (final java.nio.file.Path subdir2: stream2) {
+ Files.walkFileTree(subdir2, new FileVisitor<java.nio.file.Path>() {
+ @Override
+ public FileVisitResult preVisitDirectory(java.nio.file.Path dir, BasicFileAttributes attrs) throws IOException {
+ if (dir.getNameCount() <= 2)
+ return FileVisitResult.CONTINUE;
+ Path relative = dir.subpath(2, dir.getNameCount());
+ addToPackageCache(relative.toString(), false);
return FileVisitResult.CONTINUE;
- Path relative = dir.subpath(2, dir.getNameCount());
- addToPackageCache(relative.toString(), false);
- return FileVisitResult.CONTINUE;
- }
+ }
- @Override
- public FileVisitResult visitFile(java.nio.file.Path f, BasicFileAttributes attrs) throws IOException {
- return FileVisitResult.CONTINUE;
- }
+ @Override
+ public FileVisitResult visitFile(java.nio.file.Path f, BasicFileAttributes attrs) throws IOException {
+ return FileVisitResult.CONTINUE;
+ }
- @Override
- public FileVisitResult visitFileFailed(java.nio.file.Path f, IOException exc) throws IOException {
- return FileVisitResult.CONTINUE;
- }
+ @Override
+ public FileVisitResult visitFileFailed(java.nio.file.Path f, IOException exc) throws IOException {
+ return FileVisitResult.CONTINUE;
+ }
- @Override
- public FileVisitResult postVisitDirectory(java.nio.file.Path dir, IOException exc) throws IOException {
- return FileVisitResult.CONTINUE;
- }
- });
+ @Override
+ public FileVisitResult postVisitDirectory(java.nio.file.Path dir, IOException exc) throws IOException {
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ }
}
}
+ } catch (IOException e) {
+ e.printStackTrace();
+ // Rethrow
}
- } catch (IOException e) {
- e.printStackTrace();
- // Rethrow
+ }
+ if (moduleName == null) {
+ // Delegate to the boss, even if it means inaccurate error reporting at times
+ List<String> mods = JRTUtil.getModulesDeclaringPackage(this.file, qualifiedPackageName, moduleName);
+ return CharOperation.toCharArrays(mods);
}
return singletonModuleNameIf(this.packageCache.contains(qualifiedPackageName));
}
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 2c91339..74a2906 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -128,7 +128,6 @@
private PrintWriter log;
private Main main;
private PrintWriter out;
- private HashMap<String, Object> parameters;
int tagBits;
private static final String CLASS = "class"; //$NON-NLS-1$
private static final String CLASS_FILE = "classfile"; //$NON-NLS-1$
@@ -220,7 +219,6 @@
public Logger(Main main, PrintWriter out, PrintWriter err) {
this.out = out;
this.err = err;
- this.parameters = new HashMap<>();
this.main = main;
}
@@ -384,10 +382,11 @@
|| (unitSource == null)
|| ((length = unitSource.length) <= 0)
|| (endPosition > length)) {
- this.parameters.put(Logger.VALUE, Messages.problem_noSourceInformation);
- this.parameters.put(Logger.SOURCE_START, "-1"); //$NON-NLS-1$
- this.parameters.put(Logger.SOURCE_END, "-1"); //$NON-NLS-1$
- printTag(Logger.SOURCE_CONTEXT, this.parameters, true, true);
+ HashMap<String, Object> parameters = new HashMap<>();
+ parameters.put(Logger.VALUE, Messages.problem_noSourceInformation);
+ parameters.put(Logger.SOURCE_START, "-1"); //$NON-NLS-1$
+ parameters.put(Logger.SOURCE_END, "-1"); //$NON-NLS-1$
+ printTag(Logger.SOURCE_CONTEXT, parameters, true, true);
return;
}
@@ -413,11 +412,11 @@
// copy source
StringBuffer buffer = new StringBuffer();
buffer.append(unitSource, begin, end - begin + 1);
-
- this.parameters.put(Logger.VALUE, String.valueOf(buffer));
- this.parameters.put(Logger.SOURCE_START, Integer.toString(startPosition - begin));
- this.parameters.put(Logger.SOURCE_END, Integer.toString(endPosition - begin));
- printTag(Logger.SOURCE_CONTEXT, this.parameters, true, true);
+ HashMap<String, Object> parameters = new HashMap<>();
+ parameters.put(Logger.VALUE, String.valueOf(buffer));
+ parameters.put(Logger.SOURCE_START, Integer.toString(startPosition - begin));
+ parameters.put(Logger.SOURCE_END, Integer.toString(endPosition - begin));
+ printTag(Logger.SOURCE_CONTEXT, parameters, true, true);
}
public void flush() {
this.out.flush();
@@ -511,8 +510,9 @@
}
File f = new File(fileName);
try {
- this.parameters.put(Logger.PATH, f.getCanonicalPath());
- printTag(Logger.CLASS_FILE, this.parameters, true, true);
+ HashMap<String, Object> parameters = new HashMap<>();
+ parameters.put(Logger.PATH, f.getCanonicalPath());
+ printTag(Logger.CLASS_FILE, parameters, true, true);
} catch (IOException e) {
logNoClassFileCreated(outputPath, relativeFileName, e);
}
@@ -524,10 +524,11 @@
final int length = classpaths.length;
if (length != 0) {
// generate xml output
- printTag(Logger.CLASSPATHS, null, true, false);
+ printTag(Logger.CLASSPATHS, new HashMap<>(), true, false);
+ HashMap<String, Object> parameters = new HashMap<>();
for (int i = 0; i < length; i++) {
String classpath = classpaths[i].getPath();
- this.parameters.put(Logger.PATH, classpath);
+ parameters.put(Logger.PATH, classpath);
File f = new File(classpath);
String id = null;
if (f.isFile()) {
@@ -544,8 +545,8 @@
id = Logger.CLASSPATH_FOLDER;
}
if (id != null) {
- this.parameters.put(Logger.CLASSPATH_ID, id);
- printTag(Logger.CLASSPATH, this.parameters, true, true);
+ parameters.put(Logger.CLASSPATH_ID, id);
+ printTag(Logger.CLASSPATH, parameters, true, true);
}
}
endTag(Logger.CLASSPATHS);
@@ -560,10 +561,11 @@
final int length = commandLineArguments.length;
if (length != 0) {
// generate xml output
- printTag(Logger.COMMAND_LINE_ARGUMENTS, null, true, false);
+ printTag(Logger.COMMAND_LINE_ARGUMENTS, new HashMap<>(), true, false);
for (int i = 0; i < length; i++) {
- this.parameters.put(Logger.VALUE, commandLineArguments[i]);
- printTag(Logger.COMMAND_LINE_ARGUMENT, this.parameters, true, true);
+ HashMap<String, Object> parameters = new HashMap<>();
+ parameters.put(Logger.VALUE, commandLineArguments[i]);
+ printTag(Logger.COMMAND_LINE_ARGUMENT, parameters, true, true);
}
endTag(Logger.COMMAND_LINE_ARGUMENTS);
}
@@ -599,9 +601,10 @@
// ignore
}
message = buffer.toString();
- this.parameters.put(Logger.MESSAGE, message);
- this.parameters.put(Logger.CLASS, e.getClass());
- printTag(Logger.EXCEPTION, this.parameters, true, true);
+ HashMap<String, Object> parameters = new HashMap<>();
+ parameters.put(Logger.MESSAGE, message);
+ parameters.put(Logger.CLASS, e.getClass());
+ printTag(Logger.EXCEPTION, parameters, true, true);
}
String message = e.getMessage();
if (message == null) {
@@ -701,16 +704,18 @@
public void logUnavaibleAPT(String className) {
if ((this.tagBits & Logger.XML) != 0) {
- this.parameters.put(Logger.MESSAGE, this.main.bind("configure.unavailableAPT", className)); //$NON-NLS-1$
- printTag(Logger.ERROR_TAG, this.parameters, true, true);
+ HashMap<String, Object> parameters = new HashMap<>();
+ parameters.put(Logger.MESSAGE, this.main.bind("configure.unavailableAPT", className)); //$NON-NLS-1$
+ printTag(Logger.ERROR_TAG, parameters, true, true);
}
this.printlnErr(this.main.bind("configure.unavailableAPT", className)); //$NON-NLS-1$
}
public void logIncorrectVMVersionForAnnotationProcessing() {
if ((this.tagBits & Logger.XML) != 0) {
- this.parameters.put(Logger.MESSAGE, this.main.bind("configure.incorrectVMVersionforAPT")); //$NON-NLS-1$
- printTag(Logger.ERROR_TAG, this.parameters, true, true);
+ HashMap<String, Object> parameters = new HashMap<>();
+ parameters.put(Logger.MESSAGE, this.main.bind("configure.incorrectVMVersionforAPT")); //$NON-NLS-1$
+ printTag(Logger.ERROR_TAG, parameters, true, true);
}
this.printlnErr(this.main.bind("configure.incorrectVMVersionforAPT")); //$NON-NLS-1$
}
@@ -720,13 +725,14 @@
*/
public void logNoClassFileCreated(String outputDir, String relativeFileName, IOException e) {
if ((this.tagBits & Logger.XML) != 0) {
- this.parameters.put(Logger.MESSAGE, this.main.bind("output.noClassFileCreated", //$NON-NLS-1$
+ HashMap<String, Object> parameters = new HashMap<>();
+ parameters.put(Logger.MESSAGE, this.main.bind("output.noClassFileCreated", //$NON-NLS-1$
new String[] {
outputDir,
relativeFileName,
e.getMessage()
}));
- printTag(Logger.ERROR_TAG, this.parameters, true, true);
+ printTag(Logger.ERROR_TAG, parameters, true, true);
}
this.printlnErr(this.main.bind("output.noClassFileCreated", //$NON-NLS-1$
new String[] {
@@ -741,8 +747,9 @@
*/
public void logNumberOfClassFilesGenerated(int exportedClassFilesCounter) {
if ((this.tagBits & Logger.XML) != 0) {
- this.parameters.put(Logger.VALUE, Integer.valueOf(exportedClassFilesCounter));
- printTag(Logger.NUMBER_OF_CLASSFILES, this.parameters, true, true);
+ HashMap<String, Object> parameters = new HashMap<>();
+ parameters.put(Logger.VALUE, Integer.valueOf(exportedClassFilesCounter));
+ printTag(Logger.NUMBER_OF_CLASSFILES, parameters, true, true);
}
if (exportedClassFilesCounter == 1) {
printlnOut(this.main.bind("compile.oneClassFileGenerated")); //$NON-NLS-1$
@@ -757,7 +764,7 @@
*/
public void logOptions(Map<String, String> options) {
if ((this.tagBits & Logger.XML) != 0) {
- printTag(Logger.OPTIONS, null, true, false);
+ printTag(Logger.OPTIONS, new HashMap<>(), true, false);
final Set<Map.Entry<String, String>> entriesSet = options.entrySet();
Map.Entry<String, String>[] entries = entriesSet.toArray(new Map.Entry[entriesSet.size()]);
Arrays.sort(entries, new Comparator<Map.Entry<String, String>>() {
@@ -768,12 +775,13 @@
return entry1.getKey().compareTo(entry2.getKey());
}
});
+ HashMap<String, Object> parameters = new HashMap<>();
for (int i = 0, max = entries.length; i < max; i++) {
Map.Entry<String, String> entry = entries[i];
String key = entry.getKey();
- this.parameters.put(Logger.KEY, key);
- this.parameters.put(Logger.VALUE, entry.getValue());
- printTag(Logger.OPTION, this.parameters, true, true);
+ parameters.put(Logger.KEY, key);
+ parameters.put(Logger.VALUE, entry.getValue());
+ printTag(Logger.OPTION, parameters, true, true);
}
endTag(Logger.OPTIONS);
}
@@ -784,8 +792,9 @@
*/
public void logPendingError(String error) {
if ((this.tagBits & Logger.XML) != 0) {
- this.parameters.put(Logger.MESSAGE, error);
- printTag(Logger.ERROR_TAG, this.parameters, true, true);
+ HashMap<String, Object> parameters = new HashMap<>();
+ parameters.put(Logger.MESSAGE, error);
+ printTag(Logger.ERROR_TAG, parameters, true, true);
}
this.printlnErr(error);
}
@@ -795,8 +804,9 @@
*/
public void logWarning(String message) {
if ((this.tagBits & Logger.XML) != 0) {
- this.parameters.put(Logger.MESSAGE, message);
- printTag(Logger.WARNING_TAG, this.parameters, true, true);
+ HashMap<String, Object> parameters = new HashMap<>();
+ parameters.put(Logger.MESSAGE, message);
+ printTag(Logger.WARNING_TAG, parameters, true, true);
}
this.printlnOut(message);
}
@@ -910,12 +920,13 @@
int globalErrorsCount, int globalWarningsCount, int globalInfoCount, int globalTasksCount) {
if ((this.tagBits & Logger.XML) != 0) {
// generate xml
- this.parameters.put(Logger.NUMBER_OF_PROBLEMS, Integer.valueOf(globalProblemsCount));
- this.parameters.put(Logger.NUMBER_OF_ERRORS, Integer.valueOf(globalErrorsCount));
- this.parameters.put(Logger.NUMBER_OF_WARNINGS, Integer.valueOf(globalWarningsCount));
- this.parameters.put(Logger.NUMBER_OF_INFOS, Integer.valueOf(globalInfoCount));
- this.parameters.put(Logger.NUMBER_OF_TASKS, Integer.valueOf(globalTasksCount));
- printTag(Logger.PROBLEM_SUMMARY, this.parameters, true, true);
+ HashMap<String, Object> parameters = new HashMap<>();
+ parameters.put(Logger.NUMBER_OF_PROBLEMS, Integer.valueOf(globalProblemsCount));
+ parameters.put(Logger.NUMBER_OF_ERRORS, Integer.valueOf(globalErrorsCount));
+ parameters.put(Logger.NUMBER_OF_WARNINGS, Integer.valueOf(globalWarningsCount));
+ parameters.put(Logger.NUMBER_OF_INFOS, Integer.valueOf(globalInfoCount));
+ parameters.put(Logger.NUMBER_OF_TASKS, Integer.valueOf(globalTasksCount));
+ printTag(Logger.PROBLEM_SUMMARY, parameters, true, true);
}
if (globalProblemsCount == 1) {
String message = null;
@@ -1017,10 +1028,11 @@
long time = compilerStats.elapsedTime();
long lineCount = compilerStats.lineCount;
if ((this.tagBits & Logger.XML) != 0) {
- this.parameters.put(Logger.VALUE, Long.valueOf(time));
- printTag(Logger.TIME, this.parameters, true, true);
- this.parameters.put(Logger.VALUE, Long.valueOf(lineCount));
- printTag(Logger.NUMBER_OF_LINES, this.parameters, true, true);
+ HashMap<String, Object> parameters = new HashMap<>();
+ parameters.put(Logger.VALUE, Long.valueOf(time));
+ printTag(Logger.TIME, parameters, true, true);
+ parameters.put(Logger.VALUE, Long.valueOf(lineCount));
+ printTag(Logger.NUMBER_OF_LINES, parameters, true, true);
}
if (lineCount != 0) {
printlnOut(
@@ -1096,8 +1108,9 @@
*/
public void logWrongJDK() {
if ((this.tagBits & Logger.XML) != 0) {
- this.parameters.put(Logger.MESSAGE, this.main.bind("configure.requiresJDK1.2orAbove")); //$NON-NLS-1$
- printTag(Logger.ERROR, this.parameters, true, true);
+ HashMap<String, Object> parameters = new HashMap<>();
+ parameters.put(Logger.MESSAGE, this.main.bind("configure.requiresJDK1.2orAbove")); //$NON-NLS-1$
+ printTag(Logger.ERROR, parameters, true, true);
}
this.printlnErr(this.main.bind("configure.requiresJDK1.2orAbove")); //$NON-NLS-1$
}
@@ -1106,13 +1119,14 @@
final int sourceStart = problem.getSourceStart();
final int sourceEnd = problem.getSourceEnd();
boolean isError = problem.isError();
- this.parameters.put(Logger.PROBLEM_SEVERITY, isError ? Logger.ERROR : (problem.isInfo() ? Logger.INFO : Logger.WARNING));
- this.parameters.put(Logger.PROBLEM_LINE, Integer.valueOf(problem.getSourceLineNumber()));
- this.parameters.put(Logger.PROBLEM_SOURCE_START, Integer.valueOf(sourceStart));
- this.parameters.put(Logger.PROBLEM_SOURCE_END, Integer.valueOf(sourceEnd));
- printTag(Logger.EXTRA_PROBLEM_TAG, this.parameters, true, false);
- this.parameters.put(Logger.VALUE, problem.getMessage());
- printTag(Logger.PROBLEM_MESSAGE, this.parameters, true, true);
+ HashMap<String, Object> parameters = new HashMap<>();
+ parameters.put(Logger.PROBLEM_SEVERITY, isError ? Logger.ERROR : (problem.isInfo() ? Logger.INFO : Logger.WARNING));
+ parameters.put(Logger.PROBLEM_LINE, Integer.valueOf(problem.getSourceLineNumber()));
+ parameters.put(Logger.PROBLEM_SOURCE_START, Integer.valueOf(sourceStart));
+ parameters.put(Logger.PROBLEM_SOURCE_END, Integer.valueOf(sourceEnd));
+ printTag(Logger.EXTRA_PROBLEM_TAG, parameters, true, false);
+ parameters.put(Logger.VALUE, problem.getMessage());
+ printTag(Logger.PROBLEM_MESSAGE, parameters, true, true);
extractContext(problem, null);
endTag(Logger.EXTRA_PROBLEM_TAG);
}
@@ -1126,31 +1140,34 @@
final int sourceStart = problem.getSourceStart();
final int sourceEnd = problem.getSourceEnd();
final int id = problem.getID();
- this.parameters.put(Logger.ID, getFieldName(id)); // ID as field name
- this.parameters.put(Logger.PROBLEM_ID, Integer.valueOf(id)); // ID as numeric value
+ HashMap<String, Object> parameters = new HashMap<>();
+ parameters.put(Logger.ID, getFieldName(id)); // ID as field name
+ parameters.put(Logger.PROBLEM_ID, Integer.valueOf(id)); // ID as numeric value
boolean isError = problem.isError();
int severity = isError ? ProblemSeverities.Error : ProblemSeverities.Warning;
- this.parameters.put(Logger.PROBLEM_SEVERITY, isError ? Logger.ERROR : (problem.isInfo() ? Logger.INFO : Logger.WARNING));
- this.parameters.put(Logger.PROBLEM_LINE, Integer.valueOf(problem.getSourceLineNumber()));
- this.parameters.put(Logger.PROBLEM_SOURCE_START, Integer.valueOf(sourceStart));
- this.parameters.put(Logger.PROBLEM_SOURCE_END, Integer.valueOf(sourceEnd));
+ parameters.put(Logger.PROBLEM_SEVERITY, isError ? Logger.ERROR : (problem.isInfo() ? Logger.INFO : Logger.WARNING));
+ parameters.put(Logger.PROBLEM_LINE, Integer.valueOf(problem.getSourceLineNumber()));
+ parameters.put(Logger.PROBLEM_SOURCE_START, Integer.valueOf(sourceStart));
+ parameters.put(Logger.PROBLEM_SOURCE_END, Integer.valueOf(sourceEnd));
String problemOptionKey = getProblemOptionKey(id);
if (problemOptionKey != null) {
- this.parameters.put(Logger.PROBLEM_OPTION_KEY, problemOptionKey);
+ parameters.put(Logger.PROBLEM_OPTION_KEY, problemOptionKey);
}
int categoryID = ProblemReporter.getProblemCategory(severity, id);
- this.parameters.put(Logger.PROBLEM_CATEGORY_ID, Integer.valueOf(categoryID));
- printTag(Logger.PROBLEM_TAG, this.parameters, true, false);
- this.parameters.put(Logger.VALUE, problem.getMessage());
- printTag(Logger.PROBLEM_MESSAGE, this.parameters, true, true);
+ parameters.put(Logger.PROBLEM_CATEGORY_ID, Integer.valueOf(categoryID));
+ printTag(Logger.PROBLEM_TAG, parameters, true, false);
+ parameters.put(Logger.VALUE, problem.getMessage());
+ printTag(Logger.PROBLEM_MESSAGE, parameters, true, true);
extractContext(problem, unitSource);
String[] arguments = problem.getArguments();
final int length = arguments.length;
if (length != 0) {
- printTag(Logger.PROBLEM_ARGUMENTS, null, true, false);
+ parameters = new HashMap<>();
+ printTag(Logger.PROBLEM_ARGUMENTS, parameters, true, false);
for (int i = 0; i < length; i++) {
- this.parameters.put(Logger.PROBLEM_ARGUMENT_VALUE, arguments[i]);
- printTag(Logger.PROBLEM_ARGUMENT, this.parameters, true, true);
+ parameters = new HashMap<>();
+ parameters.put(Logger.PROBLEM_ARGUMENT_VALUE, arguments[i]);
+ printTag(Logger.PROBLEM_ARGUMENT, parameters, true, true);
}
endTag(Logger.PROBLEM_ARGUMENTS);
}
@@ -1163,16 +1180,17 @@
* the given unit source
*/
private void logXmlTask(CategorizedProblem problem, char[] unitSource) {
- this.parameters.put(Logger.PROBLEM_LINE, Integer.valueOf(problem.getSourceLineNumber()));
- this.parameters.put(Logger.PROBLEM_SOURCE_START, Integer.valueOf(problem.getSourceStart()));
- this.parameters.put(Logger.PROBLEM_SOURCE_END, Integer.valueOf(problem.getSourceEnd()));
+ HashMap<String, Object> parameters = new HashMap<>();
+ parameters.put(Logger.PROBLEM_LINE, Integer.valueOf(problem.getSourceLineNumber()));
+ parameters.put(Logger.PROBLEM_SOURCE_START, Integer.valueOf(problem.getSourceStart()));
+ parameters.put(Logger.PROBLEM_SOURCE_END, Integer.valueOf(problem.getSourceEnd()));
String problemOptionKey = getProblemOptionKey(problem.getID());
if (problemOptionKey != null) {
- this.parameters.put(Logger.PROBLEM_OPTION_KEY, problemOptionKey);
+ parameters.put(Logger.PROBLEM_OPTION_KEY, problemOptionKey);
}
- printTag(Logger.TASK, this.parameters, true, false);
- this.parameters.put(Logger.VALUE, problem.getMessage());
- printTag(Logger.PROBLEM_MESSAGE, this.parameters, true, true);
+ printTag(Logger.TASK, parameters, true, false);
+ parameters.put(Logger.VALUE, problem.getMessage());
+ printTag(Logger.PROBLEM_MESSAGE, parameters, true, true);
extractContext(problem, unitSource);
endTag(Logger.TASK);
}
@@ -1219,7 +1237,7 @@
public void printStats() {
final boolean isTimed = (this.main.timing & TIMING_ENABLED) != 0;
if ((this.tagBits & Logger.XML) != 0) {
- printTag(Logger.STATS, null, true, false);
+ printTag(Logger.STATS, new HashMap<>(), true, false);
}
if (isTimed) {
CompilerStats compilerStats = this.main.batchCompiler.stats;
@@ -1242,9 +1260,9 @@
private void printTag(String name, HashMap<String, Object> params, boolean insertNewLine, boolean closeTag) {
if (this.log != null) {
- ((GenericXMLWriter) this.log).printTag(name, this.parameters, true, insertNewLine, closeTag);
+ ((GenericXMLWriter) this.log).printTag(name, params, true, insertNewLine, closeTag);
}
- this.parameters.clear();
+ if (params != null) params.clear();
}
public void setEmacs() {
@@ -1262,10 +1280,11 @@
// insert time stamp as comment
this.log.println("<!-- " + dateFormat.format(date) + " -->");//$NON-NLS-1$//$NON-NLS-2$
this.log.println(Logger.XML_DTD_DECLARATION);
- this.parameters.put(Logger.COMPILER_NAME, this.main.bind("compiler.name")); //$NON-NLS-1$
- this.parameters.put(Logger.COMPILER_VERSION, this.main.bind("compiler.version")); //$NON-NLS-1$
- this.parameters.put(Logger.COMPILER_COPYRIGHT, this.main.bind("compiler.copyright")); //$NON-NLS-1$
- printTag(Logger.COMPILER, this.parameters, true, false);
+ HashMap<String, Object> parameters = new HashMap<>();
+ parameters.put(Logger.COMPILER_NAME, this.main.bind("compiler.name")); //$NON-NLS-1$
+ parameters.put(Logger.COMPILER_VERSION, this.main.bind("compiler.version")); //$NON-NLS-1$
+ parameters.put(Logger.COMPILER_COPYRIGHT, this.main.bind("compiler.copyright")); //$NON-NLS-1$
+ printTag(Logger.COMPILER, parameters, true, false);
} else {
this.log = new PrintWriter(new FileOutputStream(logFileName, false));
this.log.println("# " + dateFormat.format(date));//$NON-NLS-1$
@@ -1281,8 +1300,9 @@
}
}
private void startLoggingExtraProblems(int count) {
- this.parameters.put(Logger.NUMBER_OF_PROBLEMS, Integer.valueOf(count));
- printTag(Logger.EXTRA_PROBLEMS, this.parameters, true, false);
+ HashMap<String, Object> parameters = new HashMap<>();
+ parameters.put(Logger.NUMBER_OF_PROBLEMS, Integer.valueOf(count));
+ printTag(Logger.EXTRA_PROBLEMS, parameters, true, false);
}
/**
@@ -1290,25 +1310,27 @@
* Only use in xml mode.
*/
private void startLoggingProblems(int errors, int warnings, int infos) {
- this.parameters.put(Logger.NUMBER_OF_PROBLEMS, Integer.valueOf(errors + warnings));
- this.parameters.put(Logger.NUMBER_OF_ERRORS, Integer.valueOf(errors));
- this.parameters.put(Logger.NUMBER_OF_WARNINGS, Integer.valueOf(warnings));
- this.parameters.put(Logger.NUMBER_OF_INFOS, Integer.valueOf(infos));
- printTag(Logger.PROBLEMS, this.parameters, true, false);
+ HashMap<String, Object> parameters = new HashMap<>();
+ parameters.put(Logger.NUMBER_OF_PROBLEMS, Integer.valueOf(errors + warnings));
+ parameters.put(Logger.NUMBER_OF_ERRORS, Integer.valueOf(errors));
+ parameters.put(Logger.NUMBER_OF_WARNINGS, Integer.valueOf(warnings));
+ parameters.put(Logger.NUMBER_OF_INFOS, Integer.valueOf(infos));
+ printTag(Logger.PROBLEMS, parameters, true, false);
}
public void startLoggingSource(CompilationResult compilationResult) {
if ((this.tagBits & Logger.XML) != 0) {
ICompilationUnit compilationUnit = compilationResult.compilationUnit;
+ HashMap<String, Object> parameters = new HashMap<>();
if (compilationUnit != null) {
char[] fileName = compilationUnit.getFileName();
File f = new File(new String(fileName));
if (fileName != null) {
- this.parameters.put(Logger.PATH, f.getAbsolutePath());
+ parameters.put(Logger.PATH, f.getAbsolutePath());
}
char[][] packageName = compilationResult.packageName;
if (packageName != null) {
- this.parameters.put(
+ parameters.put(
Logger.PACKAGE,
new String(CharOperation.concatWith(packageName, File.separatorChar)));
}
@@ -1319,26 +1341,27 @@
}
if (destinationPath != null && destinationPath != NONE) {
if (File.separatorChar == '/') {
- this.parameters.put(Logger.OUTPUT, destinationPath);
+ parameters.put(Logger.OUTPUT, destinationPath);
} else {
- this.parameters.put(Logger.OUTPUT, destinationPath.replace('/', File.separatorChar));
+ parameters.put(Logger.OUTPUT, destinationPath.replace('/', File.separatorChar));
}
}
}
- printTag(Logger.SOURCE, this.parameters, true, false);
+ printTag(Logger.SOURCE, parameters, true, false);
}
}
public void startLoggingSources() {
if ((this.tagBits & Logger.XML) != 0) {
- printTag(Logger.SOURCES, null, true, false);
+ printTag(Logger.SOURCES, new HashMap<>(), true, false);
}
}
public void startLoggingTasks(int tasks) {
if ((this.tagBits & Logger.XML) != 0) {
- this.parameters.put(Logger.NUMBER_OF_TASKS, Integer.valueOf(tasks));
- printTag(Logger.TASKS, this.parameters, true, false);
+ HashMap<String, Object> parameters = new HashMap<>();
+ parameters.put(Logger.NUMBER_OF_TASKS, Integer.valueOf(tasks));
+ printTag(Logger.TASKS, parameters, true, false);
}
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
index 1f4172c..38e4acc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
@@ -1012,6 +1012,8 @@
int IllegalUseOfUnderscoreAsAnIdentifier = Syntax + Internal + 443;
/** @since 3.10 */
int UninternedIdentityComparison = Syntax + Internal + 444;
+ /** @since 3.24 */
+ int ErrorUseOfUnderscoreAsAnIdentifier = Syntax + Internal + 445;
// detected task
/** @since 2.1 */
@@ -2359,9 +2361,14 @@
* @noreference preview feature error */
int RecordIllegalModifierForLocalRecord = PreviewRelated + 1762;
+ /* records - end */
+ /* Local and Nested Static Declarations - Begin */
/** @since 3.24
* @noreference preview feature error */
int LocalStaticsIllegalVisibilityModifierForInterfaceLocalType = PreviewRelated + 1765;
+ /** @since 3.24
+ * @noreference preview feature error */
+ int IllegalModifierForLocalEnumDeclaration = PreviewRelated + 1766;
/* records - end */
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
index 38fa4fc..0344823 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
@@ -65,6 +65,7 @@
public TypeReference type;
public TypeBinding expectedType; // when assignment conversion to a given expected type: String s = (String) t;
public TypeBinding instanceofType; // set by InstanceofExpression to ensure we don't flag a necessary cast unnecessary
+ public boolean isVarTypeDeclaration; // set by LocalDeclaration to indicate we are initializing a var type declaration
//expression.implicitConversion holds the cast for baseType casting
public CastExpression(Expression expression, TypeReference type) {
@@ -646,6 +647,9 @@
&& expressionType.isProvablyDistinct(this.instanceofType)) {
this.bits |= ASTNode.DisableUnnecessaryCastCheck;
}
+ if (this.isVarTypeDeclaration && TypeBinding.notEquals(expressionType, castType)) {
+ this.bits |= ASTNode.DisableUnnecessaryCastCheck;
+ }
boolean isLegal = checkCastTypesCompatibility(scope, castType, expressionType, this.expression, true);
if (isLegal) {
this.expression.computeConversion(scope, castType, expressionType);
@@ -731,6 +735,10 @@
this.instanceofType = instanceofTypeBinding;
}
+public void setVarTypeDeclaration(boolean value) {
+ this.isVarTypeDeclaration = value;
+}
+
@Override
public void traverse(ASTVisitor visitor, BlockScope blockScope) {
if (visitor.visit(this, blockScope)) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
index 0c85305..d5687d0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
@@ -310,7 +310,8 @@
if (methodDeclaration == null
|| !methodDeclaration.isConstructor()
|| ((ConstructorDeclaration) methodDeclaration).constructorCall != this) {
- scope.problemReporter().invalidExplicitConstructorCall(this);
+ if (!(methodDeclaration instanceof CompactConstructorDeclaration)) // already flagged for CCD
+ scope.problemReporter().invalidExplicitConstructorCall(this);
// fault-tolerance
if (this.qualification != null) {
this.qualification.resolveType(scope);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
index 6497127..db10305 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
@@ -1206,7 +1206,10 @@
if (field.type.isRawType()) {
if (referenceContext instanceof AbstractMethodDeclaration) {
AbstractMethodDeclaration methodDecl = (AbstractMethodDeclaration) referenceContext;
- if (TypeBinding.notEquals(field.declaringClass, methodDecl.binding.declaringClass)) { // inherited raw field, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=337962
+ ReferenceBinding declaringClass = methodDecl.binding != null
+ ? methodDecl.binding.declaringClass
+ : methodDecl.scope.enclosingReceiverType();
+ if (TypeBinding.notEquals(field.declaringClass, declaringClass)) { // inherited raw field, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=337962
return true;
}
} else if (referenceContext instanceof TypeDeclaration) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
index ff213b9..9dcd98b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
@@ -82,6 +82,8 @@
private static final int REPORTED_DEFINITIVE_LEAK = 64;
// a local declarations that acts as the element variable of a foreach loop (should never suggest to use t-w-r):
private static final int FOREACH_ELEMENT_VAR = 128;
+ // - passed as an effectively final resource in t-w-r JDK 9 and above
+ private static final int TWR_EFFECTIVELY_FINAL = 256;
public MessageSend acquisition;
public static boolean TEST_372319 = false; // see https://bugs.eclipse.org/372319
@@ -871,6 +873,10 @@
this.globalClosingState |= CLOSED_IN_NESTED_METHOD;
}
+ /** Mark that this resource is closed from a try-with-resource with the tracking variable being effectively final). */
+ public void markClosedEffectivelyFinal() {
+ this.globalClosingState |= TWR_EFFECTIVELY_FINAL;
+ }
/**
* Mark that this resource is passed to some outside code
* (as argument to a method/ctor call or as a return value from the current method),
@@ -1143,7 +1149,7 @@
}
public void reportExplicitClosing(ProblemReporter problemReporter) {
- if ((this.globalClosingState & (OWNED_BY_OUTSIDE|REPORTED_EXPLICIT_CLOSE|FOREACH_ELEMENT_VAR)) == 0) { // can't use t-w-r for OWNED_BY_OUTSIDE
+ if ((this.globalClosingState & (TWR_EFFECTIVELY_FINAL|OWNED_BY_OUTSIDE|REPORTED_EXPLICIT_CLOSE|FOREACH_ELEMENT_VAR)) == 0) { // can't use t-w-r for OWNED_BY_OUTSIDE
this.globalClosingState |= REPORTED_EXPLICIT_CLOSE;
problemReporter.explicitlyClosedAutoCloseable(this);
}
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 0b6454b..64c1c9a 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
@@ -340,6 +340,9 @@
if (variableType == null) {
if (this.initialization != null) {
+ if (this.initialization instanceof CastExpression) {
+ ((CastExpression)this.initialization).setVarTypeDeclaration(true);
+ }
this.initialization.resolveType(scope); // want to report all possible errors
if (isTypeNameVar && this.initialization.resolvedType != null) {
if (TypeBinding.equalsEquals(TypeBinding.NULL, this.initialization.resolvedType)) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java
index bf9d869..b1bf2cd 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java
@@ -928,7 +928,7 @@
@Override
public Constant optimizedBooleanConstant() {
- if (this.binding.isValidBinding()) {
+ if (this.binding.isValidBinding() && this.resolvedType != null) {
switch (this.resolvedType.id) {
case T_boolean :
case T_JavaLangBoolean :
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
index 1bd8198..36843c4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
@@ -157,19 +157,20 @@
if (resource instanceof LocalDeclaration) {
localVariableBinding = ((LocalDeclaration) resource).binding;
resolvedType = localVariableBinding.type;
- } else { //expression
- if (resource instanceof NameReference && ((NameReference) resource).binding instanceof LocalVariableBinding) {
- localVariableBinding = (LocalVariableBinding) ((NameReference) resource).binding;
- }
- resolvedType = ((Expression) resource).resolvedType;
- }
- if (localVariableBinding != null) {
- localVariableBinding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
if (localVariableBinding.closeTracker != null) {
// this was false alarm, we don't need to track the resource
localVariableBinding.closeTracker.withdraw();
localVariableBinding.closeTracker = null;
}
+ } else { //expression
+ if (resource instanceof NameReference && ((NameReference) resource).binding instanceof LocalVariableBinding) {
+ localVariableBinding = (LocalVariableBinding) ((NameReference) resource).binding;
+ }
+ resolvedType = ((Expression) resource).resolvedType;
+ recordCallingClose(currentScope, flowContext, tryInfo, (Expression)resource);
+ }
+ if (localVariableBinding != null) {
+ localVariableBinding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
}
MethodBinding closeMethod = findCloseMethod(resource, resolvedType);
if (closeMethod != null && closeMethod.isValidBinding() && closeMethod.returnType.id == TypeIds.T_void) {
@@ -284,19 +285,20 @@
if (resource instanceof LocalDeclaration) {
localVariableBinding = ((LocalDeclaration) this.resources[i]).binding;
resolvedType = localVariableBinding.type;
- } else { // Expression
- if (resource instanceof NameReference && ((NameReference) resource).binding instanceof LocalVariableBinding) {
- localVariableBinding = (LocalVariableBinding)((NameReference) resource).binding;
- }
- resolvedType = ((Expression) resource).resolvedType;
- }
- if (localVariableBinding != null) {
- localVariableBinding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
if (localVariableBinding.closeTracker != null) {
// this was false alarm, we don't need to track the resource
localVariableBinding.closeTracker.withdraw();
// keep the tracking variable in the resourceBinding in order to prevent creating a new one while analyzing the try block
}
+ } else { // Expression
+ if (resource instanceof NameReference && ((NameReference) resource).binding instanceof LocalVariableBinding) {
+ localVariableBinding = (LocalVariableBinding)((NameReference) resource).binding;
+ }
+ recordCallingClose(currentScope, flowContext, tryInfo, (Expression)resource);
+ resolvedType = ((Expression) resource).resolvedType;
+ }
+ if (localVariableBinding != null) {
+ localVariableBinding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
}
MethodBinding closeMethod = findCloseMethod(resource, resolvedType);
if (closeMethod != null && closeMethod.isValidBinding() && closeMethod.returnType.id == TypeIds.T_void) {
@@ -375,6 +377,17 @@
}
}
}
+private void recordCallingClose(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, Expression closeTarget) {
+ FakedTrackingVariable trackingVariable = FakedTrackingVariable.getCloseTrackingVariable(closeTarget, flowInfo, flowContext);
+ if (trackingVariable != null) { // null happens if target is not a local variable or not an AutoCloseable
+ if (trackingVariable.methodScope == currentScope.methodScope()) {
+ trackingVariable.markClose(flowInfo, flowContext);
+ } else {
+ trackingVariable.markClosedInNestedMethod();
+ }
+ trackingVariable.markClosedEffectivelyFinal();
+ }
+}
private MethodBinding findCloseMethod(final ASTNode resource, TypeBinding type) {
MethodBinding closeMethod = null;
if (type != null && type.isValidBinding() && type instanceof ReferenceBinding) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
index af9e108..124ccb2 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
@@ -1316,6 +1316,7 @@
boolean needSerialVersion =
this.scope.compilerOptions().getSeverity(CompilerOptions.MissingSerialVersion) != ProblemSeverities.Ignore
&& sourceType.isClass()
+ && !sourceType.isRecord()
&& sourceType.findSuperTypeOriginatingFrom(TypeIds.T_JavaIoExternalizable, false /*Externalizable is not a class*/) == null
&& sourceType.findSuperTypeOriginatingFrom(TypeIds.T_JavaIoSerializable, false /*Serializable is not a class*/) != null;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IUpdatableModule.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IUpdatableModule.java
index 82e3bd1..ed99f5c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IUpdatableModule.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IUpdatableModule.java
@@ -79,6 +79,11 @@
}
return hash;
}
+ @Override
+ public String toString() {
+ return "add-exports " + CharOperation.charToString(this.name) + "=" + CharOperation.charToString(CharOperation.concatWith(this.targets, ',')); //$NON-NLS-1$//$NON-NLS-2$
+ }
+
}
class AddReads implements Consumer<IUpdatableModule> {
@@ -113,6 +118,10 @@
public int hashCode() {
return CharOperation.hashCode(this.targetModule);
}
+ @Override
+ public String toString() {
+ return "add-read " + CharOperation.charToString(this.targetModule); //$NON-NLS-1$
+ }
}
/** Structure for update operations, sorted by {@link UpdateKind}. */
class UpdatesByKind {
@@ -132,6 +141,21 @@
throw new IllegalArgumentException("Unknown enum value "+kind); //$NON-NLS-1$
}
}
+ @Override
+ public String toString() {
+ StringBuilder result = new StringBuilder();
+ for (Consumer<IUpdatableModule> consumer : this.moduleUpdates) {
+ if(result.length() > 0)
+ result.append("\n"); //$NON-NLS-1$
+ result.append(consumer);
+ }
+ for (Consumer<IUpdatableModule> consumer : this.packageUpdates) {
+ if(result.length() > 0)
+ result.append("\n"); //$NON-NLS-1$
+ result.append(consumer);
+ }
+ return result.toString();
+ }
}
/** Answer the name of the module to update. */
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
index 9923990..fafd05d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
@@ -562,6 +562,8 @@
int modifiers = sourceType.modifiers;
boolean isPreviewEnabled = compilerOptions().sourceLevel == ClassFileConstants.getLatestJDKLevel() &&
compilerOptions().enablePreviewFeatures;
+ boolean flagSealedNonModifiers = isPreviewEnabled &&
+ (modifiers & (ExtraCompilerModifiers.AccSealed | ExtraCompilerModifiers.AccNonSealed)) != 0;
if (sourceType.isRecord()) {
/* JLS 14 Records Sec 8.10 - A record declaration is implicitly final. */
modifiers |= ClassFileConstants.AccFinal;
@@ -595,8 +597,10 @@
sourceType.modifiers = 0;
return;
}
- if ((modifiers & ClassFileConstants.AccStatic) != 0) {
- problemReporter().recordIllegalStaticModifierForLocalClassOrInterface(sourceType);
+ final int UNEXPECTED_MODIFIERS =~(ClassFileConstants.AccEnum | ClassFileConstants.AccStrictfp);
+ if ((modifiers & ExtraCompilerModifiers.AccJustFlag & UNEXPECTED_MODIFIERS) != 0
+ || flagSealedNonModifiers) {
+ problemReporter().illegalModifierForLocalEnumDeclaration(sourceType);
return;
}
modifiers |= ClassFileConstants.AccStatic;
@@ -686,7 +690,7 @@
} else if (isPreviewEnabled && sourceType.isLocalType()) {
final int UNEXPECTED_MODIFIERS = ~(ClassFileConstants.AccAbstract | ClassFileConstants.AccInterface
| ClassFileConstants.AccStrictfp | ClassFileConstants.AccAnnotation);
- if ((realModifiers & UNEXPECTED_MODIFIERS) != 0)
+ if ((realModifiers & UNEXPECTED_MODIFIERS) != 0 || flagSealedNonModifiers)
problemReporter().localStaticsIllegalVisibilityModifierForInterfaceLocalType(sourceType);
// if ((modifiers & ClassFileConstants.AccStatic) != 0) {
// problemReporter().recordIllegalStaticModifierForLocalClassOrInterface(sourceType);
@@ -709,8 +713,6 @@
}
modifiers |= ClassFileConstants.AccAbstract;
} else if ((realModifiers & ClassFileConstants.AccEnum) != 0) {
- boolean flagSealedNonModifiers = isPreviewEnabled &&
- (modifiers & (ExtraCompilerModifiers.AccSealed | ExtraCompilerModifiers.AccNonSealed)) != 0;
// detect abnormal cases for enums
if (isMemberType) { // includes member types defined inside local types
final int UNEXPECTED_MODIFIERS = ~(ClassFileConstants.AccPublic | ClassFileConstants.AccPrivate | ClassFileConstants.AccProtected | ClassFileConstants.AccStatic | ClassFileConstants.AccStrictfp | ClassFileConstants.AccEnum);
@@ -722,6 +724,8 @@
// realModifiers = modifiers & ExtraCompilerModifiers.AccJustFlag;
}
} else if (sourceType.isLocalType()) {
+// if (flagSealedNonModifiers)
+// problemReporter().illegalModifierForLocalEnum(sourceType);
// each enum constant is an anonymous local type and its modifiers were already checked as an enum constant field
} else {
final int UNEXPECTED_MODIFIERS = ~(ClassFileConstants.AccPublic | ClassFileConstants.AccStrictfp | ClassFileConstants.AccEnum);
@@ -823,9 +827,6 @@
if ((realModifiers & UNEXPECTED_MODIFIERS) != 0)
problemReporter().illegalModifierForMemberClass(sourceType);
} else if (sourceType.isLocalType()) {
- boolean flagSealedNonModifiers = compilerOptions().sourceLevel >= ClassFileConstants.JDK15 &&
- compilerOptions().enablePreviewFeatures &&
- (modifiers & (ExtraCompilerModifiers.AccSealed | ExtraCompilerModifiers.AccNonSealed)) != 0;
final int UNEXPECTED_MODIFIERS = ~(ClassFileConstants.AccAbstract | ClassFileConstants.AccFinal | ClassFileConstants.AccStrictfp);
if ((realModifiers & UNEXPECTED_MODIFIERS) != 0 || flagSealedNonModifiers)
problemReporter().illegalModifierForLocalClass(sourceType);
@@ -1219,8 +1220,12 @@
permSubTypes.add(type);
}
}
+ if (sourceType.isSealed() && sourceType.isLocalType()) {
+ // bug xxxx flag Error and return;
+ }
if (permSubTypes.size() == 0) {
- problemReporter().sealedSealedTypeMissingPermits(sourceType, this.referenceContext);
+ if (!sourceType.isLocalType()) // error flagged already
+ problemReporter().sealedSealedTypeMissingPermits(sourceType, this.referenceContext);
return;
}
sourceType.setPermittedTypes(permSubTypes.toArray(new ReferenceBinding[0]));
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
index 58fcc42..867fcf9 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
@@ -82,6 +82,7 @@
import org.eclipse.jdt.internal.compiler.ast.RecordComponent;
import org.eclipse.jdt.internal.compiler.ast.ReferenceExpression;
import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
+import org.eclipse.jdt.internal.compiler.ast.SuperReference;
import org.eclipse.jdt.internal.compiler.ast.SwitchStatement;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
@@ -1163,10 +1164,7 @@
ReferenceBinding superInterface = this.superInterfaces[i];
if (superInterface != null && !checkPermitsAndAdd(superInterface, typesInCU)) {
TypeReference superInterfaceRef = typeDecl.superInterfaces[i];
- if (this.isClass())
- this.scope.problemReporter().sealedSuperClassDoesNotPermit(this, superInterfaceRef, superInterface);
- else if (this.isInterface())
- this.scope.problemReporter().sealedSuperInterfaceDoesNotPermit(this, superInterfaceRef, superInterface);
+ this.scope.problemReporter().sealedSuperInterfaceDoesNotPermit(this, superInterfaceRef, superInterface);
}
}
}
@@ -2449,6 +2447,12 @@
return true;
}
};
+ if ( methodDecl instanceof CompactConstructorDeclaration) {
+ CompactConstructorDeclaration ccd = (CompactConstructorDeclaration) methodDecl;
+ if (ccd.constructorCall == null) { // local traverse - super not set yet.
+ ccd.constructorCall = SuperReference.implicitSuperConstructorCall();
+ }
+ }
methodDecl.traverse(visitor, this.scope);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java
index 1dd1f4f..dc4bab3 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java
@@ -123,6 +123,8 @@
// JEP 360 Sealed
char[] PERMITS = "permits".toCharArray(); //$NON-NLS-1$
char[] SEALED = "sealed".toCharArray(); //$NON-NLS-1$
+ String KEYWORD_EXTENDS = "extends"; //$NON-NLS-1$
+ String IMPLEMENTS = "implements"; //$NON-NLS-1$
// jsr308
char[] TYPE_USE_TARGET = "TYPE_USE".toCharArray(); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java
index 26dc831..937e392 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java
@@ -1095,6 +1095,7 @@
int moduleRefTokenCount = 0;
boolean lookForModule = false;
boolean parsingJava15Plus = this.scanner != null ? this.scanner.sourceLevel >= ClassFileConstants.JDK15 : false;
+ boolean stop = false;
nextToken : for (int iToken = 0; ; iToken++) {
if (iToken == 0) {
lookForModule = false;
@@ -1102,6 +1103,9 @@
} else {
prevToken = curToken;
}
+ if (stop) {
+ break;
+ }
int token = readTokenSafely();
curToken= token;
switch (token) {
@@ -1193,6 +1197,9 @@
moduleRefTokenCount = (iToken+1) / 2;
consumeToken();
lookForModule = false;
+ if (!considerNextChar()) {
+ stop = true;
+ }
break;
} // else fall through
// Note: Add other cases before this case.
@@ -1621,6 +1628,15 @@
return c;
}
+ private boolean considerNextChar() {
+ boolean consider = true;
+ char ch = getChar();
+ if (ch == ' ' || (System.lineSeparator().indexOf(ch) == 0)) {
+ consider = false;
+ }
+ return consider;
+ }
+
/*
* Read token only if previous was consumed
*/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
index 57044ac..8ffc3bf 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
@@ -81,9 +81,11 @@
import java.io.CharConversionException;
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
+import java.util.Map;
import java.util.function.Supplier;
import java.util.stream.Collectors;
@@ -231,6 +233,17 @@
private static String SEALED = "sealed"; //$NON-NLS-1$
private static String RESTRICTED_IDENTIFIER_PERMITS = "RestrictedIdentifierpermits"; //$NON-NLS-1$
private static String PERMITS = "permits"; //$NON-NLS-1$
+ private static String PREVIEW_KEYWORD_NON_SEALED = "non-sealed"; //$NON-NLS-1$
+
+ private static Map<String, String> permittedRestrictedKeyWordMap;
+
+ static {
+ permittedRestrictedKeyWordMap = new HashMap<>();
+ permittedRestrictedKeyWordMap.put(RECORD, RESTRICTED_IDENTIFIER_RECORD);
+ permittedRestrictedKeyWordMap.put(SEALED, RESTRICTED_IDENTIFIER_SEALED);
+ permittedRestrictedKeyWordMap.put(PERMITS, RESTRICTED_IDENTIFIER_PERMITS);
+ permittedRestrictedKeyWordMap.put(PREVIEW_KEYWORD_NON_SEALED, PREVIEW_KEYWORD_NON_SEALED);
+ }
public ProblemReporter(IErrorHandlingPolicy policy, CompilerOptions options, IProblemFactory problemFactory) {
super(policy, options, problemFactory);
@@ -8256,7 +8269,7 @@
String errorTokenName,
String expectedToken) {
if (isIdentifier(currentKind)) {
- return validateRestrictedKeywords(errorTokenSource, start, end, true);
+ return validateRestrictedKeywords(errorTokenSource, expectedToken, start, end, true);
}
return false;
}
@@ -9535,13 +9548,23 @@
}
//Returns true if the problem is handled and reported (only errors considered and not warnings)
public boolean validateRestrictedKeywords(char[] name, int start, int end, boolean reportSyntaxError) {
+ return validateRestrictedKeywords(name, null, start, end, reportSyntaxError);
+}
+private boolean validateRestrictedKeywords(char[] name, String expectedToken, int start, int end, boolean reportSyntaxError) {
boolean isPreviewEnabled = this.options.enablePreviewFeatures;
+ if (expectedToken != null) {
+ String tokenName= new String(name);
+ String restrictedIdentifier= permittedRestrictedKeyWordMap.get(tokenName);
+ if (restrictedIdentifier == null || !restrictedIdentifier.equals(expectedToken)) {
+ return false;
+ }
+ }
for (JavaFeature feature : JavaFeature.values()) {
char[][] restrictedKeywords = feature.getRestrictedKeywords();
for (char[] k : restrictedKeywords) {
if (CharOperation.equals(name, k)) {
if (reportSyntaxError) {
-// return validateJavaFeatureSupport(feature, start, end);
+ return validateJavaFeatureSupport(feature, start, end);
} else {
if (feature.isPreview()) {
int severity = isPreviewEnabled ? ProblemSeverities.Error | ProblemSeverities.Fatal : ProblemSeverities.Warning;
@@ -9606,9 +9629,10 @@
}
public void illegalUseOfUnderscoreAsAnIdentifier(int sourceStart, int sourceEnd, boolean reportError) {
this.underScoreIsError = reportError;
+ int problemId = (reportError) ? IProblem.ErrorUseOfUnderscoreAsAnIdentifier : IProblem.IllegalUseOfUnderscoreAsAnIdentifier;
try {
this.handle(
- IProblem.IllegalUseOfUnderscoreAsAnIdentifier,
+ problemId,
NoArgument,
NoArgument,
sourceStart,
@@ -11908,6 +11932,15 @@
type.sourceStart(),
type.sourceEnd());
}
+public void illegalModifierForLocalEnumDeclaration(SourceTypeBinding type) {
+ String[] arguments = new String[] {new String(type.sourceName())};
+ this.handle(
+ IProblem.IllegalModifierForLocalEnumDeclaration,
+ arguments,
+ arguments,
+ type.sourceStart(),
+ type.sourceEnd());
+}
private void sealedMissingModifier(int problem, SourceTypeBinding type, TypeDeclaration typeDecl, TypeBinding superTypeBinding) {
if (!this.options.enablePreviewFeatures)
return;
@@ -11960,7 +11993,19 @@
sealedSuperTypeDoesNotPermit(IProblem.SealedSuperClassDoesNotPermit, type, superType, superTypeBinding);
}
public void sealedSuperInterfaceDoesNotPermit(SourceTypeBinding type, TypeReference superType, TypeBinding superTypeBinding) {
- sealedSuperTypeDoesNotPermit(IProblem.SealedSuperInterfaceDoesNotPermit, type, superType, superTypeBinding);
+ if (!this.options.enablePreviewFeatures)
+ return;
+ String name = new String(type.sourceName());
+ String superTypeFullName = new String(superTypeBinding.readableName());
+ String superTypeShortName = new String(superTypeBinding.shortReadableName());
+ String keyword = type.isClass() ? new String(TypeConstants.IMPLEMENTS) : new String(TypeConstants.KEYWORD_EXTENDS);
+ if (superTypeShortName.equals(name)) superTypeShortName = superTypeFullName;
+ this.handle(
+ IProblem.SealedSuperInterfaceDoesNotPermit,
+ new String[] {name, superTypeFullName, keyword},
+ new String[] {name, superTypeShortName, keyword},
+ superType.sourceStart,
+ superType.sourceEnd);
}
public void sealedMissingSealedModifier(SourceTypeBinding type, ASTNode node) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
index f2f39b3..94dd76f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
@@ -441,6 +441,7 @@
442 = Enum constants cannot be surrounded by parenthesis
443 = '_' should not be used as an identifier, since it is a reserved keyword from source level 1.8 on
444 = The uninterned types {0} and {1} should not be compared using ==/!= operators.
+445 = '_' is a keyword from source level 9 onwards, cannot be used as identifier
450 = {0}{1}
@@ -1056,13 +1057,15 @@
1758 = Illegal parameter name {0} in canonical constructor, expected {1}, the corresponding component name
1759 = Illegal explicit assignment of a final field {0} in compact constructor
1760 = A non-canonical constructor must start with an explicit invocation to a constructor
-1761 = A local interface, enum or record {0} is implicitly static; cannot have explicit static declaration
+1761 = A local class or interface {0} is implicitly static; cannot have explicit static declaration
1762 = Illegal modifier for the local record {0}; only final and strictfp are permitted
1765 = Illegal modifier for the local interface {0}; abstract and strictfp are the only modifiers allowed explicitly
+1766 = Illegal modifier for local enum {0}; no explicit modifier is permitted
1780 = The pattern variable {0} is not in scope in this location
+
# Java 15 Preview - cont.
# Additional doc
@@ -1083,14 +1086,14 @@
1850 = The class {1} with a sealed direct superclass or a sealed direct superinterface {0} should be declared either final, sealed, or non-sealed
1851 = A class {0} declared as non-sealed should have either a sealed direct superclass or a sealed direct superinterface
1852 = The type {0} extending a sealed class {1} should be a permitted subtype of {1}
-1853 = The type {0} extending a sealed interface {1} should be a permitted subtype of {1}
+1853 = The type {0} that {2} a sealed interface {1} should be a permitted subtype of {1}
1854 = A type declaration {0} that has a permits clause should have a sealed modifier
1855 = The interface {1} with a sealed direct superinterface {0} should be declared either sealed or non-sealed
1856 = Duplicate type {0} for the type {1} in the permits clause
1857 = Permitted class {0} does not declare {1} as direct super class
1858 = Permitted type {0} in a named module {1} should be declared in the same module {1} of declaring type {2}
1859 = Permitted type {0} in an unnamed module should be declared in the same package {1} of declaring type {2}
-1860 = Sealed class lacks the permits clause and no top level or nested class from the same compilation unit declares {0} as its direct superclass
+1860 = Sealed class or interface lacks the permits clause and no class or interface from the same compilation unit declares {0} as its direct superclass or superinterface
1861 = An interface {0} is declared both sealed and non-sealed
1862 = An interface {0} declared as non-sealed should have a sealed direct superinterface
1863 = Permitted type {0} does not declare {1} as direct super interface
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/CtSym.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/CtSym.java
index d0dc2c9..7c38c6a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/CtSym.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/CtSym.java
@@ -252,7 +252,7 @@
// Without this, org.eclipse.jdt.core.tests.model.ModuleBuilderTests.testConvertToModule() fails on 12+ JRE
path = releasePaths.get(moduleName + sep + qualifiedSignatureFileName);
- // Special handling of broken module shema in java 11 for compilation with --release 10
+ // Special handling of broken module schema in java 11 for compilation with --release 10
if(path == null && !this.isJRE12Plus() && "A".equals(releaseCode)){ //$NON-NLS-1$
path = releasePaths.get(qualifiedSignatureFileName);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java
index 58e0d5b..981828d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java
@@ -48,7 +48,7 @@
public static final boolean DISABLE_CACHE = Boolean.getBoolean("org.eclipse.jdt.disable_JRT_cache"); //$NON-NLS-1$
- public static final String JAVA_BASE = "java.base"; //$NON-NLS-1$
+ public static final String JAVA_BASE = "java.base".intern(); //$NON-NLS-1$
public static final char[] JAVA_BASE_CHAR = JAVA_BASE.toCharArray();
static final String MODULES_SUBDIR = "/modules"; //$NON-NLS-1$
static final String[] DEFAULT_MODULE = new String[]{JAVA_BASE};
@@ -160,7 +160,7 @@
* /modules/$MODULE/$PATH
* /packages/$PACKAGE/$MODULE
* The latter provides quick look up of the module that contains a particular package. However,
- * this method only notifies its clients of the entries within the modules (latter) sub-directory.
+ * this method only notifies its clients of the entries within the modules (former) sub-directory.
* Clients can decide which notifications they want to receive. See {@link JRTUtil#NOTIFY_ALL},
* {@link JRTUtil#NOTIFY_FILES}, {@link JRTUtil#NOTIFY_PACKAGES} and {@link JRTUtil#NOTIFY_MODULES}.
*
@@ -612,37 +612,44 @@
});
}
- void cachePackage(String packageName, String module) {
- packageName = packageName.intern();
- module = module.intern();
+ synchronized void cachePackage(String packageName, String module) {
packageName = packageName.replace('.', '/');
- Object current = this.packageToModule.get(packageName);
- if (current == null) {
- this.packageToModule.put(packageName, module);
- } else if(current == module || current.equals(module)) {
+ String currentModule = this.packageToModule.get(packageName);
+ if (currentModule == null) {
+ // Nothing found? Cache and return
+ this.packageToModule.put(packageName.intern(), module.intern());
return;
- } else if (current == JRTUtil.MULTIPLE) {
+ }
+ if(currentModule.equals(module)) {
+ // Same module found? Just return
+ return;
+ }
+
+ // We observe an additional module containing package
+ if (currentModule == JRTUtil.MULTIPLE) {
+ // We have already a list => update it
List<String> list = this.packageToModules.get(packageName);
if (!list.contains(module)) {
- if (JRTUtil.JAVA_BASE == module || JRTUtil.JAVA_BASE.equals(module)) {
+ if (JRTUtil.JAVA_BASE.equals(module)) {
list.add(0, JRTUtil.JAVA_BASE);
} else {
- list.add(module);
+ list.add(module.intern());
}
}
} else {
- String first = (String) current;
- this.packageToModule.put(packageName, JRTUtil.MULTIPLE);
+ // We found a second module => create a list
List<String> list = new ArrayList<String>();
// Just do this as comparator might be overkill
- if (JRTUtil.JAVA_BASE == current || JRTUtil.JAVA_BASE.equals(current)) {
- list.add(first);
- list.add(module);
+ if (JRTUtil.JAVA_BASE == currentModule || JRTUtil.JAVA_BASE.equals(currentModule)) {
+ list.add(currentModule.intern());
+ list.add(module.intern());
} else {
- list.add(module);
- list.add(first);
+ list.add(module.intern());
+ list.add(currentModule.intern());
}
+ packageName = packageName.intern();
this.packageToModules.put(packageName, list);
+ this.packageToModule.put(packageName, JRTUtil.MULTIPLE);
}
}
}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
index 430be8a..d4cc8ef 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
@@ -2225,7 +2225,7 @@
int startPosition = leftExpression.getStartPosition();
int sourceEnd = convertType.getStartPosition() + convertType.getLength() - 1;
if (DOMASTUtil.isInstanceofExpressionPatternSupported(this.ast) && expression.elementVariable != null) {
- instanceOfExpression.setPatternVariable(convertToSingleVariableDeclaration(expression.elementVariable));
+ instanceOfExpression.setPatternVariable(convertToSimpleName(expression.elementVariable));
sourceEnd= expression.elementVariable.sourceEnd;
}
instanceOfExpression.setSourceRange(startPosition, sourceEnd - startPosition + 1);
@@ -3819,6 +3819,18 @@
return variableDecl;
}
+ protected SimpleName convertToSimpleName(LocalDeclaration localDeclaration) {
+ final SimpleName name = new SimpleName(this.ast);
+ name.internalSetIdentifier(new String(localDeclaration.name));
+ int start = localDeclaration.sourceStart;
+ int nameEnd = localDeclaration.sourceEnd;
+ name.setSourceRange(start, nameEnd - start + 1);
+ if (this.resolveBindings) {
+ recordNodes(name, localDeclaration);
+ }
+ return name;
+ }
+
private Dimension convertToDimensions(int start, int end, org.eclipse.jdt.internal.compiler.ast.Annotation[] annotation) {
int length = annotation == null ? 0 : annotation.length;
Dimension dimension = this.ast.newDimension();
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IMethodBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IMethodBinding.java
index f5f8f71..d6ed09e 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IMethodBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IMethodBinding.java
@@ -438,4 +438,18 @@
*/
public IVariableBinding[] getSyntheticOuterLocals();
+ /**
+ * Returns if this is a compiler generated equals(), hashCode(), toString() or any accessor
+ * method of a Record or not.
+ * Methods equals(), hashCode() and toString() and accessor methods of a Record do not have
+ * AccSynthetic flag set for them even if they are compiler generated methods. To differentiate
+ * between these above compiler generated methods and user created methods equals(), hashCode()
+ * and toString() or accessor methods in a Record, this function can be used.
+ *
+ * @return <code>true</code> for compiler generated equals(), hashCode() and toString() or any
+ * accessor method of a Record, else it returns <code>false</code>.
+ * @noreference This method is not intended to be referenced by clients.
+ */
+ public boolean isSyntheticRecordMethod();
+
}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InstanceofExpression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InstanceofExpression.java
index 12ea6c7..9bd4ef8 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InstanceofExpression.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InstanceofExpression.java
@@ -47,12 +47,13 @@
new ChildPropertyDescriptor(InstanceofExpression.class, "rightOperand", Type.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
/**
- * The "patternVariable" structural property of this node type (child type: {@link SingleVariableDeclaration}) (added in JLS14 API).
+ * The "patternVariable" structural property of this node type (child type: {@link SimpleName}) (added in JLS14 API).
+ * This contains the name of the instance variable.
* @noreference This property is not intended to be referenced by clients as it is a part of Java preview feature.
* @since 3.22
*/
public static final ChildPropertyDescriptor PATTERN_VARIABLE_PROPERTY =
- new ChildPropertyDescriptor(InstanceofExpression.class, "patternVariable", SingleVariableDeclaration.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
+ new ChildPropertyDescriptor(InstanceofExpression.class, "patternVariable", SimpleName.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
/**
* A list of property descriptors (element type:
* {@link StructuralPropertyDescriptor}),
@@ -129,7 +130,7 @@
/**
* The patternVariable declaration.
*/
- private SingleVariableDeclaration patternVariable = null;
+ private SimpleName patternVariable = null;
/**
* Creates a new AST node for an instanceof expression owned by the given
@@ -174,7 +175,7 @@
if (get) {
return getPatternVariable();
} else {
- setPatternVariable((SingleVariableDeclaration) child);
+ setPatternVariable((SimpleName) child);
return null;
}
}
@@ -194,9 +195,9 @@
result.setLeftOperand((Expression) getLeftOperand().clone(target));
result.setRightOperand((Type) getRightOperand().clone(target));
if (DOMASTUtil.isInstanceofExpressionPatternSupported(target)) {
- SingleVariableDeclaration pv = getPatternVariable();
+ SimpleName pv = getPatternVariable();
if (pv != null) {
- result.setPatternVariable((SingleVariableDeclaration) pv.clone(target));
+ result.setPatternVariable((SimpleName) pv.clone(target));
}
}
return result;
@@ -311,7 +312,7 @@
* @noreference This method is not intended to be referenced by clients as it is a part of Java preview feature.
* @nooverride This method is not intended to be re-implemented or extended by clients as it is a part of Java preview feature.
*/
- public SingleVariableDeclaration getPatternVariable() {
+ public SimpleName getPatternVariable() {
supportedOnlyIn15();
unsupportedWithoutPreviewError();
return this.patternVariable;
@@ -327,7 +328,7 @@
* @noreference This method is not intended to be referenced by clients as it is a part of Java preview feature.
* @nooverride This method is not intended to be re-implemented or extended by clients as it is a part of Java preview feature.
*/
- public void setPatternVariable(SingleVariableDeclaration referencePatternVariable) {
+ public void setPatternVariable(SimpleName referencePatternVariable) {
supportedOnlyIn15();
unsupportedWithoutPreviewError();
if (referencePatternVariable == null) {
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodBinding.java
index 7d938bf..585f650 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodBinding.java
@@ -24,6 +24,7 @@
import org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.RawTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.SyntheticMethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.TagBits;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
@@ -607,4 +608,10 @@
public IVariableBinding[] getSyntheticOuterLocals() {
return NO_VARIABLE_BINDINGS;
}
+
+ @Override
+ public boolean isSyntheticRecordMethod() {
+ return ((getDeclaringClass().isRecord()) &&
+ (this.binding instanceof SyntheticMethodBinding));
+ }
}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java
index 06575f5..adfd67b 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java
@@ -874,10 +874,10 @@
public boolean visit(InstanceofExpression node) {
node.getLeftOperand().accept(this);
this.buffer.append(" instanceof ");//$NON-NLS-1$
+ node.getRightOperand().accept(this);
if (DOMASTUtil.isInstanceofExpressionPatternSupported(node.getAST()) && node.getPatternVariable()!= null) {
+ this.buffer.append(" "); //$NON-NLS-1$
node.getPatternVariable().accept(this);
- } else {
- node.getRightOperand().accept(this);
}
return false;
}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java
index 7474baa..35eeaeb 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java
@@ -632,10 +632,10 @@
public boolean visit(InstanceofExpression node) {
getChildNode(node, InstanceofExpression.LEFT_OPERAND_PROPERTY).accept(this);
this.result.append(" instanceof "); //$NON-NLS-1$
+ getChildNode(node, InstanceofExpression.RIGHT_OPERAND_PROPERTY).accept(this);
if (DOMASTUtil.isInstanceofExpressionPatternSupported(node.getAST()) && node.getPatternVariable()!= null) {
+ this.result.append(" "); //$NON-NLS-1$
getChildNode(node, InstanceofExpression.PATTERN_VARIABLE_PROPERTY).accept(this);
- } else {
- getChildNode(node, InstanceofExpression.RIGHT_OPERAND_PROPERTY).accept(this);
}
return false;
}
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 0028c34..2168da4 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
@@ -132,7 +132,11 @@
}
@Override
public int hashCode() {
- return this.jarPath.hashCode() + this.moduleName.hashCode() + Arrays.hashCode(this.extraAttributes);
+ int hash = 31;
+ hash = Util.combineHashCodes(hash, this.jarPath.hashCode());
+ hash = Util.combineHashCodes(hash, this.moduleName.hashCode());
+ hash = Util.combineHashCodes(hash, Arrays.hashCode(this.extraAttributes));
+ return hash;
}
@Override
protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ModularClassFile.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ModularClassFile.java
index 14addc3..7751e9a 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ModularClassFile.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ModularClassFile.java
@@ -36,8 +36,6 @@
*/
public class ModularClassFile extends AbstractClassFile implements IModularClassFile {
- private BinaryModule binaryModule;
-
protected ModularClassFile(PackageFragment parent) {
super(parent, TypeConstants.MODULE_INFO_NAME_STRING);
}
@@ -64,10 +62,7 @@
BinaryModule module = new BinaryModule(this, moduleInfo);
newElements.put(module, moduleInfo);
info.setChildren(new IJavaElement[] {module});
- this.binaryModule = module;
- if (info instanceof ClassFileInfo) {
- ((ClassFileInfo) info).setModule(module);
- }
+ ((ClassFileInfo) info).setModule(module);
((PackageFragmentRootInfo) getPackageFragmentRoot().getElementInfo()).setModule(module);
return true;
}
@@ -294,11 +289,10 @@
@Override
public IModuleDescription getModule() throws JavaModelException {
- if (this.binaryModule == null) {
- openWhenClosed(createElementInfo(), false, null);
- if (this.binaryModule == null)
- throw newNotPresentException();
+ BinaryModule module = (BinaryModule) ((ClassFileInfo) getElementInfo()).getModule();
+ if (module == null) {
+ throw newNotPresentException();
}
- return this.binaryModule;
+ return module;
}
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java
index 86feac3..5da4e51 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java
@@ -77,6 +77,7 @@
private Map<IPackageFragmentRoot,IModuleDescription> rootToModule;
private long timeSpentInGetModulesDeclaringPackage;
+ private long timeSpentInFindTypes;
@Deprecated
public SearchableEnvironment(JavaProject project, org.eclipse.jdt.core.ICompilationUnit[] workingCopies) throws JavaModelException {
@@ -520,6 +521,10 @@
* types are found relative to their enclosing type.
*/
public void findTypes(char[] prefix, final boolean findMembers, int matchRule, int searchFor, final ISearchRequestor storage, IProgressMonitor monitor) {
+ long start = -1;
+ if (NameLookup.VERBOSE)
+ start = System.currentTimeMillis();
+
boolean camelCaseMatch = (matchRule & SearchPattern.R_CAMELCASE_MATCH) != 0;
/*
if (true){
@@ -676,6 +681,9 @@
new String(prefix),
storage,
convertSearchFilterToModelFilter(searchFor));
+ } finally {
+ if (NameLookup.VERBOSE)
+ this.timeSpentInFindTypes += System.currentTimeMillis()-start;
}
}
@@ -1178,7 +1186,8 @@
return;
Util.verbose(" TIME SPENT SearchableEnvironment"); //$NON-NLS-1$
- Util.verbose(" -> getModulesDeclaringPackage: " + this.timeSpentInGetModulesDeclaringPackage + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
+ Util.verbose(" -> getModulesDeclaringPackage..." + this.timeSpentInGetModulesDeclaringPackage + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
+ Util.verbose(" -> findTypes...................." + this.timeSpentInFindTypes + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
this.nameLookup.printTimeSpent();
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java
index 1976040..84fbc59 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java
@@ -580,14 +580,14 @@
for (n = o = 0; n < newLength && o < oldLength; n++, o++) {
if (newBinaryLocations[n].equals(oldBinaryLocations[o])) continue;
if (DEBUG) {
- System.out.println("JavaBuilder: New location: " + newBinaryLocations[n] + "\n!= old location: " + oldBinaryLocations[o]); //$NON-NLS-1$ //$NON-NLS-2$
+ System.out.println("JavaBuilder: New test location: " + newBinaryLocations[n] + "\n!= old test location: " + oldBinaryLocations[o]); //$NON-NLS-1$ //$NON-NLS-2$
printLocations(newBinaryLocations, oldBinaryLocations);
}
return true;
}
if (n < newLength || o < oldLength) {
if (DEBUG) {
- System.out.println("JavaBuilder: Number of binary folders/jar files has changed:"); //$NON-NLS-1$
+ System.out.println("JavaBuilder: Number of test binary folders/jar files has changed:"); //$NON-NLS-1$
printLocations(newBinaryLocations, oldBinaryLocations);
}
return true;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java
index 4447a90..eb188d4 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java
@@ -59,8 +59,8 @@
String javaProjectName;
public ClasspathMultiDirectory[] sourceLocations;
public ClasspathMultiDirectory[] testSourceLocations;
-ClasspathLocation[] binaryLocations;
-ClasspathLocation[] testBinaryLocations;
+public ClasspathLocation[] binaryLocations;
+public ClasspathLocation[] testBinaryLocations;
// keyed by the project relative path of the type (i.e. "src1/p1/p2/A.java"), value is a ReferenceCollection or an AdditionalTypeCollection
Map<String, ReferenceCollection> references;
// keyed by qualified type name "p1/p2/A", value is the project relative path which defines this type "src1/p1/p2/A.java"
@@ -76,7 +76,7 @@
private StringSet structurallyChangedTypes;
public static int MaxStructurallyChangedTypes = 100; // keep track of ? structurally changed types, otherwise consider all to be changed
-public static final byte VERSION = 0x0022;
+public static final byte VERSION = 0x0023;
static final byte SOURCE_FOLDER = 1;
static final byte BINARY_FOLDER = 2;
@@ -256,129 +256,13 @@
newState.buildNumber = in.readInt();
newState.lastStructuralBuildTime = in.readLong();
- int length = in.readInt();
- newState.sourceLocations = new ClasspathMultiDirectory[length];
- for (int i = 0; i < length; i++) {
- IContainer sourceFolder = project, outputFolder = project;
- String folderName;
- if ((folderName = in.readUTF()).length() > 0) sourceFolder = project.getFolder(folderName);
- if ((folderName = in.readUTF()).length() > 0) outputFolder = project.getFolder(folderName);
- ClasspathMultiDirectory md =
- (ClasspathMultiDirectory) ClasspathLocation.forSourceFolder(sourceFolder, outputFolder, readNames(in), readNames(in), in.readBoolean());
- if (in.readBoolean())
- md.hasIndependentOutputFolder = true;
- newState.sourceLocations[i] = md;
- }
+ newState.sourceLocations = readSourceLocations(project, in);
+ newState.binaryLocations = readBinaryLocations(project, in, newState.sourceLocations);
- length = in.readInt();
- newState.binaryLocations = new ClasspathLocation[length];
- IWorkspaceRoot root = project.getWorkspace().getRoot();
- for (int i = 0; i < length; i++) {
- switch (in.readByte()) {
- case SOURCE_FOLDER :
- newState.binaryLocations[i] = newState.sourceLocations[in.readInt()];
- break;
- case BINARY_FOLDER :
- IPath path = new Path(in.readUTF());
- IContainer outputFolder = path.segmentCount() == 1
- ? (IContainer) root.getProject(path.toString())
- : (IContainer) root.getFolder(path);
- newState.binaryLocations[i] = ClasspathLocation.forBinaryFolder(outputFolder, in.readBoolean(),
- readRestriction(in), new Path(in.readUTF()), in.readBoolean());
- break;
- case EXTERNAL_JAR :
- String jarPath = in.readUTF();
- if (Util.isJrt(jarPath)) {
- newState.binaryLocations[i] = ClasspathLocation.forJrtSystem(jarPath, readRestriction(in), new Path(in.readUTF()), in.readUTF());
- } else {
- newState.binaryLocations[i] = ClasspathLocation.forLibrary(jarPath, in.readLong(),
- readRestriction(in), new Path(in.readUTF()), in.readBoolean(), in.readUTF());
- }
- break;
- case INTERNAL_JAR :
- newState.binaryLocations[i] = ClasspathLocation.forLibrary(root.getFile(new Path(in.readUTF())),
- readRestriction(in), new Path(in.readUTF()), in.readBoolean(), in.readUTF());
- break;
- }
- ClasspathLocation loc = newState.binaryLocations[i];
- char[] patchName = readName(in);
- loc.patchModuleName = patchName.length > 0 ? new String(patchName) : null;
- int limitSize = in.readInt();
- if (limitSize != 0) {
- loc.limitModuleNames = new LinkedHashSet<>(limitSize);
- for (int j = 0; j < limitSize; j++) {
- loc.limitModuleNames.add(in.readUTF());
- }
- } else {
- loc.limitModuleNames = null;
- }
- IUpdatableModule.UpdatesByKind updates = new IUpdatableModule.UpdatesByKind();
- List<Consumer<IUpdatableModule>> packageUpdates = null;
- int packageUpdatesSize = in.readInt();
- if (packageUpdatesSize != 0) {
- packageUpdates = updates.getList(UpdateKind.PACKAGE, true);
- for (int j = 0; j < packageUpdatesSize; j++) {
- char[] pkgName = readName(in);
- char[][] targets = readNames(in);
- packageUpdates.add(new AddExports(pkgName, targets));
- }
- }
- List<Consumer<IUpdatableModule>> moduleUpdates = null;
- int moduleUpdatesSize = in.readInt();
- if (moduleUpdatesSize != 0) {
- moduleUpdates = updates.getList(UpdateKind.MODULE, true);
- char[] modName = readName(in);
- moduleUpdates.add(new AddReads(modName));
- }
- if (packageUpdates != null || moduleUpdates != null)
- loc.updates = updates;
- }
+ newState.testSourceLocations = readSourceLocations(project, in);
+ newState.testBinaryLocations = readBinaryLocations(project, in, newState.testSourceLocations);
- length = in.readInt();
- newState.testSourceLocations = new ClasspathMultiDirectory[length];
- for (int i = 0; i < length; i++) {
- IContainer sourceFolder = project, outputFolder = project;
- String folderName;
- if ((folderName = in.readUTF()).length() > 0) sourceFolder = project.getFolder(folderName);
- if ((folderName = in.readUTF()).length() > 0) outputFolder = project.getFolder(folderName);
- ClasspathMultiDirectory md =
- (ClasspathMultiDirectory) ClasspathLocation.forSourceFolder(sourceFolder, outputFolder, readNames(in), readNames(in), in.readBoolean());
- if (in.readBoolean())
- md.hasIndependentOutputFolder = true;
- newState.testSourceLocations[i] = md;
- }
-
- length = in.readInt();
- newState.testBinaryLocations = new ClasspathLocation[length];
- for (int i = 0; i < length; i++) {
- switch (in.readByte()) {
- case SOURCE_FOLDER :
- newState.testBinaryLocations[i] = newState.testSourceLocations[in.readInt()];
- break;
- case BINARY_FOLDER :
- IPath path = new Path(in.readUTF());
- IContainer outputFolder = path.segmentCount() == 1
- ? (IContainer) root.getProject(path.toString())
- : (IContainer) root.getFolder(path);
- newState.testBinaryLocations[i] = ClasspathLocation.forBinaryFolder(outputFolder, in.readBoolean(),
- readRestriction(in), new Path(in.readUTF()), in.readBoolean());
- break;
- case EXTERNAL_JAR :
- String jarPath = in.readUTF();
- if (Util.isJrt(jarPath)) {
- newState.testBinaryLocations[i] = ClasspathLocation.forJrtSystem(jarPath, readRestriction(in), new Path(in.readUTF()), in.readUTF());
- } else {
- newState.testBinaryLocations[i] = ClasspathLocation.forLibrary(jarPath, in.readLong(),
- readRestriction(in), new Path(in.readUTF()), in.readBoolean(), in.readUTF());
- }
- break;
- case INTERNAL_JAR :
- newState.testBinaryLocations[i] = ClasspathLocation.forLibrary(root.getFile(new Path(in.readUTF())),
- readRestriction(in), new Path(in.readUTF()), in.readBoolean(), in.readUTF());
- break;
- }
- }
-
+ int length;
newState.structuralBuildTimes = new SimpleLookupTable(length = in.readInt());
for (int i = 0; i < length; i++)
newState.structuralBuildTimes.put(in.readUTF(), Long.valueOf(in.readLong()));
@@ -445,6 +329,90 @@
return newState;
}
+private static ClasspathMultiDirectory[] readSourceLocations(IProject project, DataInputStream in) throws IOException {
+ int length = in.readInt();
+ ClasspathMultiDirectory[] sourceLocations = new ClasspathMultiDirectory[length];
+ for (int i = 0; i < length; i++) {
+ IContainer sourceFolder = project, outputFolder = project;
+ String folderName;
+ if ((folderName = in.readUTF()).length() > 0) sourceFolder = project.getFolder(folderName);
+ if ((folderName = in.readUTF()).length() > 0) outputFolder = project.getFolder(folderName);
+ ClasspathMultiDirectory md =
+ (ClasspathMultiDirectory) ClasspathLocation.forSourceFolder(sourceFolder, outputFolder, readNames(in), readNames(in), in.readBoolean());
+ if (in.readBoolean())
+ md.hasIndependentOutputFolder = true;
+ sourceLocations[i] = md;
+ }
+ return sourceLocations;
+}
+
+private static ClasspathLocation[] readBinaryLocations(IProject project, DataInputStream in, ClasspathMultiDirectory[] sourceLocations) throws IOException, CoreException {
+ int length = in.readInt();
+ ClasspathLocation[] locations = new ClasspathLocation[length];
+ IWorkspaceRoot root = project.getWorkspace().getRoot();
+ for (int i = 0; i < length; i++) {
+ switch (in.readByte()) {
+ case SOURCE_FOLDER :
+ locations[i] = sourceLocations[in.readInt()];
+ break;
+ case BINARY_FOLDER :
+ IPath path = new Path(in.readUTF());
+ IContainer outputFolder = path.segmentCount() == 1
+ ? (IContainer) root.getProject(path.toString())
+ : (IContainer) root.getFolder(path);
+ locations[i] = ClasspathLocation.forBinaryFolder(outputFolder, in.readBoolean(),
+ readRestriction(in), new Path(in.readUTF()), in.readBoolean());
+ break;
+ case EXTERNAL_JAR :
+ String jarPath = in.readUTF();
+ if (Util.isJrt(jarPath)) {
+ locations[i] = ClasspathLocation.forJrtSystem(jarPath, readRestriction(in), new Path(in.readUTF()), in.readUTF());
+ } else {
+ locations[i] = ClasspathLocation.forLibrary(jarPath, in.readLong(),
+ readRestriction(in), new Path(in.readUTF()), in.readBoolean(), in.readUTF());
+ }
+ break;
+ case INTERNAL_JAR :
+ locations[i] = ClasspathLocation.forLibrary(root.getFile(new Path(in.readUTF())),
+ readRestriction(in), new Path(in.readUTF()), in.readBoolean(), in.readUTF());
+ break;
+ }
+ ClasspathLocation loc = locations[i];
+ char[] patchName = readName(in);
+ loc.patchModuleName = patchName.length > 0 ? new String(patchName) : null;
+ int limitSize = in.readInt();
+ if (limitSize != 0) {
+ loc.limitModuleNames = new LinkedHashSet<>(limitSize);
+ for (int j = 0; j < limitSize; j++) {
+ loc.limitModuleNames.add(in.readUTF());
+ }
+ } else {
+ loc.limitModuleNames = null;
+ }
+ IUpdatableModule.UpdatesByKind updates = new IUpdatableModule.UpdatesByKind();
+ List<Consumer<IUpdatableModule>> packageUpdates = null;
+ int packageUpdatesSize = in.readInt();
+ if (packageUpdatesSize != 0) {
+ packageUpdates = updates.getList(UpdateKind.PACKAGE, true);
+ for (int j = 0; j < packageUpdatesSize; j++) {
+ char[] pkgName = readName(in);
+ char[][] targets = readNames(in);
+ packageUpdates.add(new AddExports(pkgName, targets));
+ }
+ }
+ List<Consumer<IUpdatableModule>> moduleUpdates = null;
+ int moduleUpdatesSize = in.readInt();
+ if (moduleUpdatesSize != 0) {
+ moduleUpdates = updates.getList(UpdateKind.MODULE, true);
+ char[] modName = readName(in);
+ moduleUpdates.add(new AddReads(modName));
+ }
+ if (packageUpdates != null || moduleUpdates != null)
+ loc.updates = updates;
+ }
+ return locations;
+}
+
private static char[] readName(DataInputStream in) throws IOException {
int nLength = in.readInt();
char[] name = new char[nLength];
@@ -526,184 +494,29 @@
* ClasspathMultiDirectory[]
* int id
* String path(s)
-*/
- out.writeInt(length = this.sourceLocations.length);
- for (int i = 0; i < length; i++) {
- ClasspathMultiDirectory md = this.sourceLocations[i];
- out.writeUTF(md.sourceFolder.getProjectRelativePath().toString());
- out.writeUTF(md.binaryFolder.getProjectRelativePath().toString());
- writeNames(md.inclusionPatterns, out);
- writeNames(md.exclusionPatterns, out);
- out.writeBoolean(md.ignoreOptionalProblems);
- out.writeBoolean(md.hasIndependentOutputFolder);
- }
+ */
+ writeSourceLocations(out, this.sourceLocations);
/*
* ClasspathLocation[]
* int id
* String path(s)
-*/
- out.writeInt(length = this.binaryLocations.length);
- for (int i = 0; i < length; i++) {
- ClasspathLocation c = this.binaryLocations[i];
- if (c instanceof ClasspathMultiDirectory) {
- out.writeByte(SOURCE_FOLDER);
- for (int j = 0, m = this.sourceLocations.length; j < m; j++) {
- if (this.sourceLocations[j] == c) {
- out.writeInt(j);
- //continue next;
- }
- }
- } else if (c instanceof ClasspathDirectory) {
- out.writeByte(BINARY_FOLDER);
- ClasspathDirectory cd = (ClasspathDirectory) c;
- out.writeUTF(cd.binaryFolder.getFullPath().toString());
- out.writeBoolean(cd.isOutputFolder);
- writeRestriction(cd.accessRuleSet, out);
- out.writeUTF(cd.externalAnnotationPath != null ? cd.externalAnnotationPath : ""); //$NON-NLS-1$
- out.writeBoolean(cd.isOnModulePath);
- } else if (c instanceof ClasspathJar) {
- ClasspathJar jar = (ClasspathJar) c;
- if (jar.resource == null) {
- out.writeByte(EXTERNAL_JAR);
- out.writeUTF(jar.zipFilename);
- out.writeLong(jar.lastModified());
- } else {
- out.writeByte(INTERNAL_JAR);
- out.writeUTF(jar.resource.getFullPath().toString());
- }
- writeRestriction(jar.accessRuleSet, out);
- out.writeUTF(jar.externalAnnotationPath != null ? jar.externalAnnotationPath : ""); //$NON-NLS-1$
- out.writeBoolean(jar.isOnModulePath);
- out.writeUTF(jar.compliance == null ? "" : jar.compliance); //$NON-NLS-1$
+ */
+ writeBinaryLocations(out, this.binaryLocations, this.sourceLocations);
- } else if (c instanceof ClasspathJrt) {
- ClasspathJrt jrt = (ClasspathJrt) c;
- out.writeByte(EXTERNAL_JAR);
- out.writeUTF(jrt.zipFilename);
- writeRestriction(jrt.accessRuleSet, out);
- out.writeUTF(jrt.externalAnnotationPath != null ? jrt.externalAnnotationPath : ""); //$NON-NLS-1$
- if (jrt instanceof ClasspathJrtWithReleaseOption)
- out.writeUTF(((ClasspathJrtWithReleaseOption) jrt).release);
- else
- out.writeUTF(""); //$NON-NLS-1$
- }
- char[] patchName = c.patchModuleName == null ? CharOperation.NO_CHAR : c.patchModuleName.toCharArray();
- writeName(patchName, out);
- if (c.limitModuleNames != null) {
- out.writeInt(c.limitModuleNames.size());
- for (String name : c.limitModuleNames) {
- out.writeUTF(name);
- }
- } else {
- out.writeInt(0);
- }
- if (c.updates != null) {
- List<Consumer<IUpdatableModule>> pu = c.updates.getList(UpdateKind.PACKAGE, false);
- if (pu != null) {
- Map<String, List<Consumer<IUpdatableModule>>> map = pu.stream().
- collect(Collectors.groupingBy(
- update -> CharOperation.charToString(((IUpdatableModule.AddExports)update).getName())));
- out.writeInt(map.size());
- map.entrySet().stream().forEach(entry -> {
- String pkgName = entry.getKey();
- try {
- writeName(pkgName.toCharArray(), out);
- char[][] targetModules = entry.getValue().stream()
- .map(consumer -> ((IUpdatableModule.AddExports) consumer).getTargetModules())
- .filter(targets -> targets != null)
- .reduce((f,s) -> CharOperation.arrayConcat(f,s))
- .orElse(null);
- writeNames(targetModules, out);
- } catch (IOException e) {
- // ignore
- }
+/*
+ * ClasspathMultiDirectory[]
+ * int id
+ * String path(s)
+ */
+ writeSourceLocations(out, this.testSourceLocations);
- });
- } else {
- out.writeInt(0);
- }
- List<Consumer<IUpdatableModule>> mu = c.updates.getList(UpdateKind.MODULE, false);
- if (mu != null) {
- out.writeInt(mu.size());
- for (Consumer<IUpdatableModule> cons : mu) {
- AddReads m = (AddReads) cons;
- writeName(m.getTarget(), out);
- }
- } else {
- out.writeInt(0);
- }
- } else {
- out.writeInt(0);
- out.writeInt(0);
- }
- }
- /*
- * ClasspathMultiDirectory[]
- * int id
- * String path(s)
- */
- out.writeInt(length = this.testSourceLocations.length);
- for (int i = 0; i < length; i++) {
- ClasspathMultiDirectory md = this.testSourceLocations[i];
- out.writeUTF(md.sourceFolder.getProjectRelativePath().toString());
- out.writeUTF(md.binaryFolder.getProjectRelativePath().toString());
- writeNames(md.inclusionPatterns, out);
- writeNames(md.exclusionPatterns, out);
- out.writeBoolean(md.ignoreOptionalProblems);
- out.writeBoolean(md.hasIndependentOutputFolder);
- }
-
- /*
- * ClasspathLocation[]
- * int id
- * String path(s)
- */
- out.writeInt(length = this.testBinaryLocations.length);
- next : for (int i = 0; i < length; i++) {
- ClasspathLocation c = this.testBinaryLocations[i];
- if (c instanceof ClasspathMultiDirectory) {
- out.writeByte(SOURCE_FOLDER);
- for (int j = 0, m = this.testSourceLocations.length; j < m; j++) {
- if (this.testSourceLocations[j] == c) {
- out.writeInt(j);
- continue next;
- }
- }
- } else if (c instanceof ClasspathDirectory) {
- out.writeByte(BINARY_FOLDER);
- ClasspathDirectory cd = (ClasspathDirectory) c;
- out.writeUTF(cd.binaryFolder.getFullPath().toString());
- out.writeBoolean(cd.isOutputFolder);
- writeRestriction(cd.accessRuleSet, out);
- out.writeUTF(cd.externalAnnotationPath != null ? cd.externalAnnotationPath : ""); //$NON-NLS-1$
- out.writeBoolean(cd.isOnModulePath);
- } else if (c instanceof ClasspathJar) {
- ClasspathJar jar = (ClasspathJar) c;
- if (jar.resource == null) {
- out.writeByte(EXTERNAL_JAR);
- out.writeUTF(jar.zipFilename);
- out.writeLong(jar.lastModified());
- } else {
- out.writeByte(INTERNAL_JAR);
- out.writeUTF(jar.resource.getFullPath().toString());
- }
- writeRestriction(jar.accessRuleSet, out);
- out.writeUTF(jar.externalAnnotationPath != null ? jar.externalAnnotationPath : ""); //$NON-NLS-1$
- out.writeBoolean(jar.isOnModulePath);
- out.writeUTF(jar.compliance != null ? jar.compliance : ""); //$NON-NLS-1$
- } else if (c instanceof ClasspathJrt) {
- ClasspathJrt jrt = (ClasspathJrt) c;
- out.writeByte(EXTERNAL_JAR);
- out.writeUTF(jrt.zipFilename);
- writeRestriction(jrt.accessRuleSet, out);
- out.writeUTF(jrt.externalAnnotationPath != null ? jrt.externalAnnotationPath : ""); //$NON-NLS-1$
- if (jrt instanceof ClasspathJrtWithReleaseOption)
- out.writeUTF(((ClasspathJrtWithReleaseOption) jrt).release);
- else
- out.writeUTF(""); //$NON-NLS-1$
- }
- }
+/*
+ * ClasspathLocation[]
+ * int id
+ * String path(s)
+ */
+ writeBinaryLocations(out, this.testBinaryLocations, this.testSourceLocations);
/*
* Structural build numbers table
@@ -888,6 +701,126 @@
}
}
+private void writeSourceLocations(DataOutputStream out, ClasspathMultiDirectory[] srcLocations) throws IOException {
+ int length;
+ out.writeInt(length = srcLocations.length);
+ for (int i = 0; i < length; i++) {
+ ClasspathMultiDirectory md = srcLocations[i];
+ out.writeUTF(md.sourceFolder.getProjectRelativePath().toString());
+ out.writeUTF(md.binaryFolder.getProjectRelativePath().toString());
+ writeNames(md.inclusionPatterns, out);
+ writeNames(md.exclusionPatterns, out);
+ out.writeBoolean(md.ignoreOptionalProblems);
+ out.writeBoolean(md.hasIndependentOutputFolder);
+ }
+}
+
+private void writeBinaryLocations(DataOutputStream out, ClasspathLocation[] locations, ClasspathMultiDirectory[] srcLocations)
+ throws IOException {
+ /*
+ * ClasspathLocation[]
+ * int id
+ * String path(s)
+ * String module updates
+ */
+
+ out.writeInt(locations.length);
+ for (int i = 0; i < locations.length; i++) {
+ ClasspathLocation c = locations[i];
+ if (c instanceof ClasspathMultiDirectory) {
+ out.writeByte(SOURCE_FOLDER);
+ for (int j = 0, m = srcLocations.length; j < m; j++) {
+ if (srcLocations[j] == c) {
+ out.writeInt(j);
+ //continue next;
+ }
+ }
+ } else if (c instanceof ClasspathDirectory) {
+ out.writeByte(BINARY_FOLDER);
+ ClasspathDirectory cd = (ClasspathDirectory) c;
+ out.writeUTF(cd.binaryFolder.getFullPath().toString());
+ out.writeBoolean(cd.isOutputFolder);
+ writeRestriction(cd.accessRuleSet, out);
+ out.writeUTF(cd.externalAnnotationPath != null ? cd.externalAnnotationPath : ""); //$NON-NLS-1$
+ out.writeBoolean(cd.isOnModulePath);
+ } else if (c instanceof ClasspathJar) {
+ ClasspathJar jar = (ClasspathJar) c;
+ if (jar.resource == null) {
+ out.writeByte(EXTERNAL_JAR);
+ out.writeUTF(jar.zipFilename);
+ out.writeLong(jar.lastModified());
+ } else {
+ out.writeByte(INTERNAL_JAR);
+ out.writeUTF(jar.resource.getFullPath().toString());
+ }
+ writeRestriction(jar.accessRuleSet, out);
+ out.writeUTF(jar.externalAnnotationPath != null ? jar.externalAnnotationPath : ""); //$NON-NLS-1$
+ out.writeBoolean(jar.isOnModulePath);
+ out.writeUTF(jar.compliance == null ? "" : jar.compliance); //$NON-NLS-1$
+
+ } else if (c instanceof ClasspathJrt) {
+ ClasspathJrt jrt = (ClasspathJrt) c;
+ out.writeByte(EXTERNAL_JAR);
+ out.writeUTF(jrt.zipFilename);
+ writeRestriction(jrt.accessRuleSet, out);
+ out.writeUTF(jrt.externalAnnotationPath != null ? jrt.externalAnnotationPath : ""); //$NON-NLS-1$
+ if (jrt instanceof ClasspathJrtWithReleaseOption)
+ out.writeUTF(((ClasspathJrtWithReleaseOption) jrt).release);
+ else
+ out.writeUTF(""); //$NON-NLS-1$
+ }
+ char[] patchName = c.patchModuleName == null ? CharOperation.NO_CHAR : c.patchModuleName.toCharArray();
+ writeName(patchName, out);
+ if (c.limitModuleNames != null) {
+ out.writeInt(c.limitModuleNames.size());
+ for (String name : c.limitModuleNames) {
+ out.writeUTF(name);
+ }
+ } else {
+ out.writeInt(0);
+ }
+ if (c.updates != null) {
+ List<Consumer<IUpdatableModule>> pu = c.updates.getList(UpdateKind.PACKAGE, false);
+ if (pu != null) {
+ Map<String, List<Consumer<IUpdatableModule>>> map = pu.stream().
+ collect(Collectors.groupingBy(
+ update -> CharOperation.charToString(((IUpdatableModule.AddExports)update).getName())));
+ out.writeInt(map.size());
+ map.entrySet().stream().forEach(entry -> {
+ String pkgName = entry.getKey();
+ try {
+ writeName(pkgName.toCharArray(), out);
+ char[][] targetModules = entry.getValue().stream()
+ .map(consumer -> ((IUpdatableModule.AddExports) consumer).getTargetModules())
+ .filter(targets -> targets != null)
+ .reduce((f,s) -> CharOperation.arrayConcat(f,s))
+ .orElse(null);
+ writeNames(targetModules, out);
+ } catch (IOException e) {
+ // ignore
+ }
+
+ });
+ } else {
+ out.writeInt(0);
+ }
+ List<Consumer<IUpdatableModule>> mu = c.updates.getList(UpdateKind.MODULE, false);
+ if (mu != null) {
+ out.writeInt(mu.size());
+ for (Consumer<IUpdatableModule> cons : mu) {
+ AddReads m = (AddReads) cons;
+ writeName(m.getTarget(), out);
+ }
+ } else {
+ out.writeInt(0);
+ }
+ } else {
+ out.writeInt(0);
+ out.writeInt(0);
+ }
+ }
+}
+
private void writeName(char[] name, DataOutputStream out) throws IOException {
int nLength = name.length;
out.writeInt(nLength);
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java
index d5e7eb6..d5ba2b9 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java
@@ -19,6 +19,7 @@
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.search.*;
import org.eclipse.jdt.internal.core.util.*;
+import org.eclipse.osgi.util.NLS;
import org.eclipse.jdt.internal.compiler.util.HashtableOfIntValues;
import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
@@ -753,6 +754,10 @@
for (int i = 1; i < size; i++) {
if (stream != null && this.bufferIndex + 2 >= this.bufferEnd)
readStreamBuffer(stream);
+ // bug 566262: check if the index file was deleted in parallel, if so throw an IOException instead of risking to run into index OOB exceptions
+ if (this.bufferEnd == -1 && stream.available() == 0) {
+ throw new IOException(NLS.bind("Stream was closed for index location \"{0}\"", this.indexLocation)); //$NON-NLS-1$
+ }
int start = this.streamBuffer[this.bufferIndex++] & 0xFF;
int end = this.streamBuffer[this.bufferIndex++] & 0xFF;
String next = new String(readStreamChars(stream));
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/Index.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/Index.java
index 93cb3e7..11c9edd 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/Index.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/Index.java
@@ -32,7 +32,7 @@
public class Index {
public String containerPath;
-public ReadWriteMonitor monitor;
+public volatile ReadWriteMonitor monitor;
// Separator to use after the container path
static final char DEFAULT_SEPARATOR = '/';
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java
index 41efb7e..37666c7 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java
@@ -593,8 +593,7 @@
// check if the same request is not already in the queue
IndexRequest request = new IndexAllProject(project, this);
- if (!isJobWaiting(request))
- request(request);
+ requestIfNotWaiting(request);
} finally {
// Enable index manager after adding all new index requests to the queue.
enable();
@@ -652,8 +651,7 @@
}
// check if the same request is not already in the queue
- if (!isJobWaiting(request))
- request(request);
+ requestIfNotWaiting(request);
}
synchronized boolean addIndex(IPath containerPath, IndexLocation indexFile) {
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexRequest.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexRequest.java
index 3391fec..0ffda9d 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexRequest.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexRequest.java
@@ -17,7 +17,7 @@
import org.eclipse.jdt.internal.core.search.processing.IJob;
public abstract class IndexRequest implements IJob {
- protected boolean isCancelled = false;
+ protected volatile boolean isCancelled;
protected IPath containerPath;
protected IndexManager manager;
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/IndexBasedJavaSearchEnvironment.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/IndexBasedJavaSearchEnvironment.java
index 59177b5..dbbaaf7 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/IndexBasedJavaSearchEnvironment.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/IndexBasedJavaSearchEnvironment.java
@@ -13,6 +13,11 @@
*******************************************************************************/
package org.eclipse.jdt.internal.core.search.matching;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Platform;
@@ -31,6 +36,7 @@
import org.eclipse.jdt.internal.core.ClasspathEntry;
import org.eclipse.jdt.internal.core.JavaModel;
import org.eclipse.jdt.internal.core.JavaProject;
+import org.eclipse.jdt.internal.core.NameLookup;
import org.eclipse.jdt.internal.core.PackageFragmentRoot;
import org.eclipse.jdt.internal.core.builder.ClasspathLocation;
import org.eclipse.jdt.internal.core.nd.IReader;
@@ -45,11 +51,7 @@
import org.eclipse.jdt.internal.core.nd.java.model.IndexBinaryType;
import org.eclipse.jdt.internal.core.nd.util.CharArrayUtils;
import org.eclipse.jdt.internal.core.nd.util.PathMap;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
+import org.eclipse.jdt.internal.core.util.Util;
public class IndexBasedJavaSearchEnvironment implements INameEnvironment, SuffixConstants {
@@ -58,6 +60,8 @@
private IPackageFragmentRoot[] roots;
private int sourceEntryPosition;
private List<ClasspathLocation> unindexedEntries = new ArrayList<>();
+ private long timeSpentInFindClassInUnindexedLocations;
+ private long timeSpentInFindType;
public IndexBasedJavaSearchEnvironment(List<IJavaProject> javaProject, org.eclipse.jdt.core.ICompilationUnit[] copies) {
this.workingCopies = JavaSearchNameEnvironment.getWorkingCopyMap(copies);
@@ -127,41 +131,49 @@
bestEntryPosition = this.sourceEntryPosition;
}
- char[] fieldDescriptor = JavaNames.binaryNameToFieldDescriptor(binaryName);
- JavaIndex index = JavaIndex.getIndex();
- Nd nd = index.getNd();
- try (IReader lock = nd.acquireReadLock()) {
- NdTypeId typeId = index.findType(fieldDescriptor);
+ long start = -1;
+ if (NameLookup.VERBOSE)
+ start = System.currentTimeMillis();
+ try {
+ char[] fieldDescriptor = JavaNames.binaryNameToFieldDescriptor(binaryName);
+ JavaIndex index = JavaIndex.getIndex();
+ Nd nd = index.getNd();
+ try (IReader lock = nd.acquireReadLock()) {
+ NdTypeId typeId = index.findType(fieldDescriptor);
- if (typeId != null) {
- List<NdType> types = typeId.getTypes();
- for (NdType next : types) {
- NdResourceFile resource = next.getFile();
+ if (typeId != null) {
+ List<NdType> types = typeId.getTypes();
+ for (NdType next : types) {
+ NdResourceFile resource = next.getFile();
- IPath path = resource.getPath();
- Integer nextRoot = this.mapPathsToRoots.getMostSpecific(path);
- if (nextRoot != null) {
- IPackageFragmentRoot root = this.roots[nextRoot];
+ IPath path = resource.getPath();
+ Integer nextRoot = this.mapPathsToRoots.getMostSpecific(path);
+ if (nextRoot != null) {
+ IPackageFragmentRoot root = this.roots[nextRoot];
- ClasspathEntry classpathEntry = (ClasspathEntry)root.getRawClasspathEntry();
- AccessRuleSet ruleSet = classpathEntry.getAccessRuleSet();
- AccessRestriction accessRestriction = ruleSet == null? null : ruleSet.getViolatedRestriction(binaryName);
- TypeRef typeRef = TypeRef.create(next);
- String fileName = new String(binaryName) + ".class"; //$NON-NLS-1$
- IBinaryType binaryType = new IndexBinaryType(typeRef, fileName.toCharArray());
- NameEnvironmentAnswer nextAnswer = new NameEnvironmentAnswer(binaryType, accessRestriction);
+ ClasspathEntry classpathEntry = (ClasspathEntry)root.getRawClasspathEntry();
+ AccessRuleSet ruleSet = classpathEntry.getAccessRuleSet();
+ AccessRestriction accessRestriction = ruleSet == null? null : ruleSet.getViolatedRestriction(binaryName);
+ TypeRef typeRef = TypeRef.create(next);
+ String fileName = new String(binaryName) + ".class"; //$NON-NLS-1$
+ IBinaryType binaryType = new IndexBinaryType(typeRef, fileName.toCharArray());
+ NameEnvironmentAnswer nextAnswer = new NameEnvironmentAnswer(binaryType, accessRestriction);
- boolean useNewAnswer = isBetter(result, bestEntryPosition, nextAnswer, nextRoot);
+ boolean useNewAnswer = isBetter(result, bestEntryPosition, nextAnswer, nextRoot);
- if (useNewAnswer) {
- bestEntryPosition = nextRoot;
- result = nextAnswer;
+ if (useNewAnswer) {
+ bestEntryPosition = nextRoot;
+ result = nextAnswer;
+ }
}
}
}
+ } catch (JavaModelException e) {
+ // project doesn't exist
}
- } catch (JavaModelException e) {
- // project doesn't exist
+ } finally {
+ if (NameLookup.VERBOSE)
+ this.timeSpentInFindType += System.currentTimeMillis()-start;
}
return result;
@@ -171,71 +183,79 @@
* Search unindexed locations on the classpath for the given class
*/
private NameEnvironmentAnswer findClassInUnindexedLocations(String qualifiedTypeName, char[] typeName) {
- String
- binaryFileName = null, qBinaryFileName = null,
- sourceFileName = null, qSourceFileName = null,
- qPackageName = null;
- NameEnvironmentAnswer suggestedAnswer = null;
- Iterator <ClasspathLocation> iter = this.unindexedEntries.iterator();
- while (iter.hasNext()) {
- ClasspathLocation location = iter.next();
- NameEnvironmentAnswer answer;
- if (location instanceof ClasspathSourceDirectory) {
- if (sourceFileName == null) {
- qSourceFileName = qualifiedTypeName; // doesn't include the file extension
- sourceFileName = qSourceFileName;
- qPackageName = ""; //$NON-NLS-1$
- if (qualifiedTypeName.length() > typeName.length) {
- int typeNameStart = qSourceFileName.length() - typeName.length;
- qPackageName = qSourceFileName.substring(0, typeNameStart - 1);
- sourceFileName = qSourceFileName.substring(typeNameStart);
+ long start = -1;
+ if (NameLookup.VERBOSE)
+ start = System.currentTimeMillis();
+ try {
+ String
+ binaryFileName = null, qBinaryFileName = null,
+ sourceFileName = null, qSourceFileName = null,
+ qPackageName = null;
+ NameEnvironmentAnswer suggestedAnswer = null;
+ Iterator <ClasspathLocation> iter = this.unindexedEntries.iterator();
+ while (iter.hasNext()) {
+ ClasspathLocation location = iter.next();
+ NameEnvironmentAnswer answer;
+ if (location instanceof ClasspathSourceDirectory) {
+ if (sourceFileName == null) {
+ qSourceFileName = qualifiedTypeName; // doesn't include the file extension
+ sourceFileName = qSourceFileName;
+ qPackageName = ""; //$NON-NLS-1$
+ if (qualifiedTypeName.length() > typeName.length) {
+ int typeNameStart = qSourceFileName.length() - typeName.length;
+ qPackageName = qSourceFileName.substring(0, typeNameStart - 1);
+ sourceFileName = qSourceFileName.substring(typeNameStart);
+ }
}
- }
- org.eclipse.jdt.internal.compiler.env.ICompilationUnit workingCopy = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) this.workingCopies.get(qualifiedTypeName);
- if (workingCopy != null) {
- answer = new NameEnvironmentAnswer(workingCopy, null /*no access restriction*/);
+ org.eclipse.jdt.internal.compiler.env.ICompilationUnit workingCopy = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) this.workingCopies.get(qualifiedTypeName);
+ if (workingCopy != null) {
+ answer = new NameEnvironmentAnswer(workingCopy, null /*no access restriction*/);
+ } else {
+ answer = location.findClass(
+ sourceFileName, // doesn't include the file extension
+ qPackageName,
+ null, // TODO(SHMOD): don't have a module name, but while looking in unindexed classpath locations, this is probably OK
+ qSourceFileName, // doesn't include the file extension
+ false,
+ null /*no module filtering on source dir*/);
+ }
} else {
- answer = location.findClass(
- sourceFileName, // doesn't include the file extension
- qPackageName,
- null, // TODO(SHMOD): don't have a module name, but while looking in unindexed classpath locations, this is probably OK
- qSourceFileName, // doesn't include the file extension
- false,
- null /*no module filtering on source dir*/);
- }
- } else {
- if (binaryFileName == null) {
- qBinaryFileName = qualifiedTypeName + SUFFIX_STRING_class;
- binaryFileName = qBinaryFileName;
- qPackageName = ""; //$NON-NLS-1$
- if (qualifiedTypeName.length() > typeName.length) {
- int typeNameStart = qBinaryFileName.length() - typeName.length - 6; // size of ".class"
- qPackageName = qBinaryFileName.substring(0, typeNameStart - 1);
- binaryFileName = qBinaryFileName.substring(typeNameStart);
+ if (binaryFileName == null) {
+ qBinaryFileName = qualifiedTypeName + SUFFIX_STRING_class;
+ binaryFileName = qBinaryFileName;
+ qPackageName = ""; //$NON-NLS-1$
+ if (qualifiedTypeName.length() > typeName.length) {
+ int typeNameStart = qBinaryFileName.length() - typeName.length - 6; // size of ".class"
+ qPackageName = qBinaryFileName.substring(0, typeNameStart - 1);
+ binaryFileName = qBinaryFileName.substring(typeNameStart);
+ }
}
+ answer =
+ location.findClass(
+ binaryFileName,
+ qPackageName,
+ null, // TODO(SHMOD): don't have a module name, but while looking in unindexed classpath locations, this is probably OK
+ qBinaryFileName,
+ false,
+ null /*no module filtering, this env is not module aware*/);
}
- answer =
- location.findClass(
- binaryFileName,
- qPackageName,
- null, // TODO(SHMOD): don't have a module name, but while looking in unindexed classpath locations, this is probably OK
- qBinaryFileName,
- false,
- null /*no module filtering, this env is not module aware*/);
+ if (answer != null) {
+ if (!answer.ignoreIfBetter()) {
+ if (answer.isBetter(suggestedAnswer))
+ return answer;
+ } else if (answer.isBetter(suggestedAnswer))
+ // remember suggestion and keep looking
+ suggestedAnswer = answer;
+ }
}
- if (answer != null) {
- if (!answer.ignoreIfBetter()) {
- if (answer.isBetter(suggestedAnswer))
- return answer;
- } else if (answer.isBetter(suggestedAnswer))
- // remember suggestion and keep looking
- suggestedAnswer = answer;
- }
+ if (suggestedAnswer != null)
+ // no better answer was found
+ return suggestedAnswer;
+ return null;
+ } finally {
+ if (NameLookup.VERBOSE)
+ this.timeSpentInFindClassInUnindexedLocations += System.currentTimeMillis()-start;
}
- if (suggestedAnswer != null)
- // no better answer was found
- return suggestedAnswer;
- return null;
}
public boolean isBetter(NameEnvironmentAnswer currentBest, int currentBestClasspathPosition,
@@ -324,6 +344,15 @@
// No explicit cleanup required for this class
}
+ public void printTimeSpent() {
+ if(!NameLookup.VERBOSE)
+ return;
+
+ Util.verbose(" TIME SPENT IndexBasedJavaSearchEnvironment"); //$NON-NLS-1$
+ Util.verbose(" -> findClassInUnindexedLocations..." + this.timeSpentInFindClassInUnindexedLocations + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
+ Util.verbose(" -> findType........................" + this.timeSpentInFindType + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
public static INameEnvironment create(List<IJavaProject> javaProjects, org.eclipse.jdt.core.ICompilationUnit[] copies) {
if (JavaIndex.isEnabled() && isEnabled()) {
return new IndexBasedJavaSearchEnvironment(javaProjects, copies);
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java
index 30fd398..a80c55a 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java
@@ -15,20 +15,24 @@
*******************************************************************************/
package org.eclipse.jdt.internal.core.search.matching;
+import static java.util.stream.Collectors.joining;
+
+import java.util.Collections;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.LinkedHashSet;
-import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IModuleDescription;
import org.eclipse.jdt.core.IPackageDeclaration;
+import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
@@ -57,11 +61,13 @@
*/
public class JavaSearchNameEnvironment implements IModuleAwareNameEnvironment, SuffixConstants {
- LinkedHashSet<ClasspathLocation> locationSet;
+ protected /* visible for testing only */ LinkedHashSet<ClasspathLocation> locationSet;
Map<String, IModuleDescription> modules;
private boolean modulesComputed = false;
Map<String,ClasspathLocation> moduleLocations;
Map<String,LinkedHashSet<ClasspathLocation>> moduleToClassPathLocations;
+ /** an index of qualified package names (separated by / not .) to classpath locations */
+ protected /* visible for testing only */ Map<String,LinkedHashSet<ClasspathLocation>> packageNameToClassPathLocations;
/*
* A map from the fully qualified slash-separated name of the main type (String) to the working copy
@@ -74,8 +80,54 @@
this.moduleToClassPathLocations = new HashMap<>();
}
this.modules = new HashMap<>();
+ this.packageNameToClassPathLocations = new HashMap<>();
+
+ long start = 0;
+ if (NameLookup.VERBOSE) {
+ Util.verbose(" BUILDING JavaSearchNameEnvironment"); //$NON-NLS-1$
+ Util.verbose(" -> project: " + javaProject); //$NON-NLS-1$
+ Util.verbose(" -> working copy size: " + (copies == null ? 0 : copies.length)); //$NON-NLS-1$
+ start = System.currentTimeMillis();
+ }
+
this.locationSet = computeClasspathLocations((JavaProject) javaProject);
this.workingCopies = getWorkingCopyMap(copies);
+
+ // if there are working copies, we need to index their packages too
+ if(this.workingCopies.size() > 0) {
+ Optional<ClasspathLocation> firstSrcLocation = this.locationSet.stream().filter(cp -> cp instanceof ClasspathSourceDirectory).findFirst();
+ if(!firstSrcLocation.isPresent()) {
+ /*
+ * Specifying working copies but not providing a project with a source folder is not supported by the current implementation.
+ * I'm not sure if this is valid use case, though.
+ *
+ * However, there is one test that (potentially) relies on this behavior. At lease it expects this constructor to NOT fail.
+ *
+ * org.eclipse.jdt.core.tests.model.ClassFileTests.testWorkingCopy11()
+ */
+ //throw new IllegalArgumentException("Missing source folder for searching working copies: " + javaProject); //$NON-NLS-1$
+ if (NameLookup.VERBOSE) {
+ Util.verbose(" -> ignoring working copies; no ClasspathSourceDirectory on project classpath "); //$NON-NLS-1$
+ }
+ } else {
+ for (String qualifiedMainTypeName : this.workingCopies.keySet()) {
+ int typeNameStart = qualifiedMainTypeName.lastIndexOf('/');
+ if(typeNameStart > 0) {
+ String pkgName = qualifiedMainTypeName.substring(0, typeNameStart);
+ addPackageNameToIndex(firstSrcLocation.get(), pkgName);
+ } else {
+ addPackageNameToIndex(firstSrcLocation.get(), IPackageFragment.DEFAULT_PACKAGE_NAME);
+ }
+ }
+ }
+ }
+
+
+ if (NameLookup.VERBOSE) {
+ Util.verbose(" -> pkg roots size: " + (this.locationSet == null ? 0 : this.locationSet.size())); //$NON-NLS-1$
+ Util.verbose(" -> pkgs size: " + this.packageNameToClassPathLocations.size()); //$NON-NLS-1$
+ Util.verbose(" -> spent: " + (System.currentTimeMillis() - start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
}
public static Map<String, org.eclipse.jdt.core.ICompilationUnit> getWorkingCopyMap(
@@ -104,11 +156,25 @@
@Override
public void cleanup() {
this.locationSet.clear();
+ this.packageNameToClassPathLocations.clear();
}
-void addProjectClassPath(JavaProject javaProject) {
+protected /* visible for testing only */ void addProjectClassPath(JavaProject javaProject) {
+ long start = 0;
+ if (NameLookup.VERBOSE) {
+ Util.verbose(" EXTENDING JavaSearchNameEnvironment"); //$NON-NLS-1$
+ Util.verbose(" -> project: " + javaProject); //$NON-NLS-1$
+ start = System.currentTimeMillis();
+ }
+
LinkedHashSet<ClasspathLocation> locations = computeClasspathLocations(javaProject);
if (locations != null) this.locationSet.addAll(locations);
+
+ if (NameLookup.VERBOSE) {
+ Util.verbose(" -> pkg roots size: " + (this.locationSet == null ? 0 : this.locationSet.size())); //$NON-NLS-1$
+ Util.verbose(" -> pkgs size: " + this.packageNameToClassPathLocations.size()); //$NON-NLS-1$
+ Util.verbose(" -> spent: " + (System.currentTimeMillis() - start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
}
private LinkedHashSet<ClasspathLocation> computeClasspathLocations(JavaProject javaProject) {
@@ -131,11 +197,47 @@
JavaModelManager manager = JavaModelManager.getJavaModelManager();
for (int i = 0; i < length; i++) {
ClasspathLocation cp = mapToClassPathLocation(manager, (PackageFragmentRoot) roots[i], imd);
- if (cp != null) locations.add(cp);
+ if (cp != null) {
+ try {
+ indexPackageNames(cp, roots[i]);
+ locations.add(cp);
+ } catch (JavaModelException e) {
+ Util.log(e, "Error indexing package names!"); //$NON-NLS-1$
+ }
+ }
}
return locations;
}
+private void indexPackageNames(ClasspathLocation cp, IPackageFragmentRoot root) throws JavaModelException {
+ for (IJavaElement c : root.getChildren()) {
+ String qualifiedPackageName = c.getElementName().replace('.', '/');
+ addPackageNameToIndex(cp, qualifiedPackageName);
+ }
+ /* In theory IPackageFragmentRoot#getChildren should contain all. It always returns
+ * the default package (no matter what). However, for some reason only JarPackageFragmentRoot#getChildren
+ * really returns all children. PackageFragmentRoot#getChildren returns ONLY the default package for binary class folders.
+ *
+ * We therefore also go through listPackages as well
+ */
+ char[][] packages = cp.listPackages();
+ if(packages != null) {
+ for (char[] packageName : packages) {
+ String qualifiedPackageName = CharOperation.charToString(packageName).replace('.', '/');
+ addPackageNameToIndex(cp, qualifiedPackageName);
+ }
+ }
+
+}
+
+private void addPackageNameToIndex(ClasspathLocation cp, String qualifiedPackageName) {
+ LinkedHashSet<ClasspathLocation> cpl = this.packageNameToClassPathLocations.get(qualifiedPackageName);
+ if(cpl == null) {
+ this.packageNameToClassPathLocations.put(qualifiedPackageName, cpl = new LinkedHashSet<>());
+ }
+ cpl.add(cp);
+}
+
private void computeModules() {
if (!this.modulesComputed) {
this.modulesComputed = true;
@@ -229,12 +331,20 @@
private NameEnvironmentAnswer findClass(String qualifiedTypeName, char[] typeName, LookupStrategy strategy, /*@Nullable*/String moduleName) {
String
binaryFileName = null, qBinaryFileName = null,
- sourceFileName = null, qSourceFileName = null,
- qPackageName = null;
+ sourceFileName = null, qSourceFileName = null;
+
+ final String qPackageName;
+ final int typeNameStart;
+ if (qualifiedTypeName.length() > typeName.length) {
+ typeNameStart = qualifiedTypeName.length() - typeName.length;
+ qPackageName = qualifiedTypeName.substring(0, typeNameStart - 1);
+ } else {
+ typeNameStart = 0;
+ qPackageName = ""; //$NON-NLS-1$
+ }
+
NameEnvironmentAnswer suggestedAnswer = null;
- Iterator<ClasspathLocation> iter = getLocationsFor(moduleName);
- while (iter.hasNext()) {
- ClasspathLocation location = iter.next();
+ for (ClasspathLocation location : getLocationsFor(moduleName, qPackageName)) {
if (!strategy.matches(location, ClasspathLocation::hasModule))
continue;
NameEnvironmentAnswer answer;
@@ -242,10 +352,7 @@
if (sourceFileName == null) {
qSourceFileName = qualifiedTypeName; // doesn't include the file extension
sourceFileName = qSourceFileName;
- qPackageName = ""; //$NON-NLS-1$
- if (qualifiedTypeName.length() > typeName.length) {
- int typeNameStart = qSourceFileName.length() - typeName.length;
- qPackageName = qSourceFileName.substring(0, typeNameStart - 1);
+ if (typeNameStart > 0) {
sourceFileName = qSourceFileName.substring(typeNameStart);
}
}
@@ -265,10 +372,7 @@
if (binaryFileName == null) {
qBinaryFileName = qualifiedTypeName + SUFFIX_STRING_class;
binaryFileName = qBinaryFileName;
- qPackageName = ""; //$NON-NLS-1$
- if (qualifiedTypeName.length() > typeName.length) {
- int typeNameStart = qBinaryFileName.length() - typeName.length - 6; // size of ".class"
- qPackageName = qBinaryFileName.substring(0, typeNameStart - 1);
+ if (typeNameStart > 0) {
binaryFileName = qBinaryFileName.substring(typeNameStart);
}
}
@@ -283,26 +387,59 @@
}
if (answer != null) {
if (!answer.ignoreIfBetter()) {
- if (answer.isBetter(suggestedAnswer))
+ if (answer.isBetter(suggestedAnswer)) {
+ if(NameLookup.VERBOSE) {
+ Util.verbose(" Result for JavaSearchNameEnvironment#findClass( " + qualifiedTypeName + ", " + CharOperation.charToString(typeName) + ", " + strategy + ", " + moduleName + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+ Util.verbose(" -> answer: " + answer); //$NON-NLS-1$
+ Util.verbose(" -> location: " + location); //$NON-NLS-1$
+ }
return answer;
- } else if (answer.isBetter(suggestedAnswer))
+ }
+ } else if (answer.isBetter(suggestedAnswer)) {
// remember suggestion and keep looking
suggestedAnswer = answer;
+ if(NameLookup.VERBOSE) {
+ Util.verbose(" Potential answer for JavaSearchNameEnvironment#findClass( " + qualifiedTypeName + ", " + CharOperation.charToString(typeName) + ", " + strategy + ", " + moduleName + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+ Util.verbose(" -> answer: " + answer); //$NON-NLS-1$
+ Util.verbose(" -> location: " + location); //$NON-NLS-1$
+ }
+ }
}
}
if (suggestedAnswer != null)
// no better answer was found
return suggestedAnswer;
+ if(NameLookup.VERBOSE) {
+ Util.verbose(" NO result for JavaSearchNameEnvironment#findClass( " + qualifiedTypeName + ", " + CharOperation.charToString(typeName) + ", " + strategy + ", " + moduleName + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+ }
return null;
}
-private Iterator<ClasspathLocation> getLocationsFor(/*@Nullable*/String moduleName) {
+protected /* visible for testing only */ Iterable<ClasspathLocation> getLocationsFor(/*@Nullable*/String moduleName, String qualifiedPackageName) {
if (moduleName != null) {
LinkedHashSet<ClasspathLocation> l = this.moduleToClassPathLocations.get(moduleName);
- if (l != null && l.size() > 0)
- return l.iterator();
+ if (l != null)
+ return l;
+ // FIXME: this seems bogus ... if we are searching with a module name and there is NONE, an empty set should be returned, shouldn't it?
}
- return this.locationSet.iterator();
+ if(qualifiedPackageName != null) {
+ LinkedHashSet<ClasspathLocation> cpls = this.packageNameToClassPathLocations.get(qualifiedPackageName);
+ if(cpls == null) {
+ if(NameLookup.VERBOSE) {
+ Util.verbose(" No result for JavaSearchNameEnvironment#getLocationsFor( " + moduleName + ", " + qualifiedPackageName + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+ return Collections.emptySet();
+ }
+ if(NameLookup.VERBOSE) {
+ Util.verbose(" Result for JavaSearchNameEnvironment#getLocationsFor( " + moduleName + ", " + qualifiedPackageName + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ Util.verbose(" -> " + cpls.stream().map(Object::toString).collect(joining(" | "))); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ return cpls;
+ }
+ if(NameLookup.VERBOSE) {
+ Util.verbose(" Potentially expensive search in JavaSearchNameEnvironment#getLocationsFor( " + moduleName + ", " + qualifiedPackageName + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+ return this.locationSet;
}
@Override
@@ -335,9 +472,8 @@
if (this.moduleToClassPathLocations != null) {
String moduleNameString = String.valueOf(moduleName);
LinkedHashSet<ClasspathLocation> cpl = this.moduleToClassPathLocations.get(moduleNameString);
- List<ClasspathLocation> l = cpl != null ? cpl.stream().collect(Collectors.toList()): null;
- if (l != null) {
- for (ClasspathLocation cp : l) {
+ if (cpl != null) {
+ for (ClasspathLocation cp : cpl) {
if (cp.isPackage(qualifiedPackageName, moduleNameString))
return new char[][] { moduleName };
}
@@ -346,7 +482,7 @@
return null;
}
char[][] moduleNames = CharOperation.NO_CHAR_CHAR;
- for (ClasspathLocation location : this.locationSet) {
+ for (ClasspathLocation location : getLocationsFor(null /* ignore module */, qualifiedPackageName)) {
if (strategy.matches(location, ClasspathLocation::hasModule) ) {
if (location.isPackage(qualifiedPackageName, null)) {
char[][] mNames = location.getModulesDeclaringPackage(qualifiedPackageName, null);
@@ -355,6 +491,10 @@
}
}
}
+ if(NameLookup.VERBOSE) {
+ Util.verbose(" Result for JavaSearchNameEnvironment#getModulesDeclaringPackage( " + qualifiedPackageName + ", " + CharOperation.charToString(moduleName) + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ Util.verbose(" -> " + CharOperation.toString(moduleNames)); //$NON-NLS-1$
+ }
return moduleNames == CharOperation.NO_CHAR_CHAR ? null : moduleNames;
}
@@ -386,10 +526,15 @@
return location.hasCompilationUnit(qualifiedPackageNameString, moduleNameString);
}
} else {
- for (ClasspathLocation location : this.locationSet) {
+ for (ClasspathLocation location : getLocationsFor(null /* ignore module */, qualifiedPackageNameString)) {
if (strategy.matches(location, ClasspathLocation::hasModule) )
- if (location.hasCompilationUnit(qualifiedPackageNameString, moduleNameString))
+ if (location.hasCompilationUnit(qualifiedPackageNameString, moduleNameString)) {
+ if(NameLookup.VERBOSE) {
+ Util.verbose(" Result for JavaSearchNameEnvironment#hasCompilationUnit( " + qualifiedPackageNameString + ", " + moduleNameString + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ Util.verbose(" -> " + location); //$NON-NLS-1$
+ }
return true;
+ }
}
}
return false;
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
index 8c436b4..95eaf0d 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
@@ -1215,7 +1215,7 @@
projects.add(project);
if (this.pattern.focus != null) {
IJavaProject focusProject = this.pattern.focus.getJavaProject();
- if (focusProject != project) {
+ if (!project.equals(focusProject)) {
projects.add(focusProject);
}
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/processing/JobManager.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/processing/JobManager.java
index 1ccc768..20dd9e4 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/processing/JobManager.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/processing/JobManager.java
@@ -24,10 +24,10 @@
protected IJob[] awaitingJobs = new IJob[10];
protected int jobStart = 0;
protected int jobEnd = -1;
- protected boolean executing = false;
+ protected volatile boolean executing;
/* background processing */
- protected Thread processingThread;
+ protected volatile Thread processingThread;
protected Job progressJob;
/* counter indicating whether job execution is enabled or not, disabled if <= 0
@@ -272,6 +272,19 @@
}
public abstract String processName();
+ /**
+ * Schedules given job for execution is there is no equal jobs waiting in the queue already
+ *
+ * @see JobManager#isJobWaiting(IJob)
+ * @param job
+ * a job to schedule (or not)
+ */
+ public synchronized void requestIfNotWaiting(IJob job) {
+ if(!isJobWaiting(job)) {
+ request(job);
+ }
+ }
+
public synchronized void request(IJob job) {
job.ensureReadyToRun();