Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Herrmann2016-11-26 23:25:43 +0000
committerStephan Herrmann2016-11-26 23:25:43 +0000
commitb889cf00f2d36c22c848ae67ad0deb08734d7780 (patch)
tree1349f2e2818a8da6f87b263c39f325ce97a39861
parent02944c35e14fd9fc46bb9f58ae0fbd467d91cbd6 (diff)
downloadorg.eclipse.objectteams-b889cf00f2d36c22c848ae67ad0deb08734d7780.tar.gz
org.eclipse.objectteams-b889cf00f2d36c22c848ae67ad0deb08734d7780.tar.xz
org.eclipse.objectteams-b889cf00f2d36c22c848ae67ad0deb08734d7780.zip
update jdt.core to I20161124-2000
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java52
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java142
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java21
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java6
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExpressionContextTests.java11
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java56
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GrammarCoverageTests308.java42
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JSR308SpecSnippetTests.java4
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java32
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeTypeAnnotationTest.java42
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java66
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java205
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SerializableLambdaTest.java27
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java15
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavadocMethodCompletionModelTest.java8
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests2.java4
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CharOperation.java17
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java8
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java5
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java71
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java3
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java68
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java7
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java11
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java2
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java2
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java16
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java4
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java4
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java4
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java10
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java54
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceSubstitution.java2
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceVariable.java86
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java8
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java1
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeSystem.java14
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java9
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java35
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties5
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java137
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/BatchImageBuilder.java12
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/Nd.java4
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/indexer/Indexer.java27
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/JavaIndex.java4
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/model/BinaryTypeFactory.java5
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/model/Package.java48
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java31
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/processing/JobManager.java29
49 files changed, 1158 insertions, 318 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
index 0a6984c69..141b2d2d3 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
@@ -36,12 +36,15 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Processor;
@@ -89,8 +92,6 @@ import org.eclipse.jdt.internal.core.search.indexing.BinaryIndexer;
import org.eclipse.jdt.internal.core.util.Messages;
import org.osgi.framework.Bundle;
-import java.util.regex.Pattern;
-
@SuppressWarnings({ "unchecked", "rawtypes" })
public abstract class AbstractRegressionTest extends AbstractCompilerTest implements StopableTestCase {
@@ -953,10 +954,11 @@ protected static class JavacTestOptions {
String computedProblemLog = Util.convertToIndependantLineDelimiter(requestor.problemLog.toString());
if (this.shouldSwallowCaptureId)
computedProblemLog = Pattern.compile("capture#(\\d+)").matcher(computedProblemLog).replaceAll("capture");
-
+
+ ProblemLog problemLog = new ProblemLog(computedProblemLog);
int i;
for (i = 0; i < alternatePlatformIndependantExpectedLogs.length; i++) {
- if (alternatePlatformIndependantExpectedLogs[i].equals(computedProblemLog))
+ if (problemLog.sameAs(alternatePlatformIndependantExpectedLogs[i]))
return; // OK
}
logTestTitle();
@@ -967,6 +969,48 @@ protected static class JavacTestOptions {
}
}
+ /**
+ * Used for performing order-independent log comparisons.
+ */
+ private static final class ProblemLog {
+ final Set<String> logEntry = new HashSet<>();
+
+ public ProblemLog(String log) {
+ String[] entries = log.split("----------\n");
+ Pattern pattern = Pattern.compile("\\A(\\d*\\. )");
+
+ for (String entry : entries) {
+ Matcher matcher = pattern.matcher(entry);
+ if (matcher.find()) {
+ entry = entry.substring(matcher.end());
+ }
+ this.logEntry.add(entry);
+ }
+ }
+
+ public boolean sameAs(String toTest) {
+ ProblemLog log = new ProblemLog(toTest);
+ return equals(log);
+ }
+
+ @Override
+ public int hashCode() {
+ return this.logEntry.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ ProblemLog other = (ProblemLog) obj;
+ return this.logEntry.equals(other.logEntry);
+ }
+ }
+
protected void dualPrintln(String message) {
System.out.println(message);
javacFullLog.println(message);
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java
index cecfb2f02..a7fa3ea2a 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2016 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -59,7 +59,7 @@ public class AnnotationTest extends AbstractComparableTest {
// Static initializer to specify tests subset using TESTS_* static variables
// All specified tests which do not belong to the class are skipped...
static {
-// TESTS_NAMES = new String[] { "testBug384663" };
+// TESTS_NAMES = new String[] { "testBug506888c" };
// TESTS_NUMBERS = new int[] { 297 };
// TESTS_RANGE = new int[] { 294, -1 };
}
@@ -4902,7 +4902,7 @@ public void test143() {
public void test153() {
Map options = getCompilerOptions();
options.put(CompilerOptions.OPTION_ReportIncompleteEnumSwitch, CompilerOptions.WARNING);
- this.runNegativeTest(
+ this.runConformTest(
new String[] {
"X.java",
"enum E { A, B, C }\n" +
@@ -4919,9 +4919,6 @@ public void test143() {
" }\n" +
"}",
},
- "",
- null,
- true,
options
);
}
@@ -8135,11 +8132,16 @@ public void test245() {
"} \n",
},
null, options,
- "----------\n" +
- "1. ERROR in X.java (at line 3)\n" +
- " @SuppressWarnings({\"unchecked\",\"unused\"})\n" +
- " ^^^^^^^^\n" +
- "Unnecessary @SuppressWarnings(\"unused\")\n" +
+ "----------\n" +
+ "1. INFO in X.java (at line 3)\n" +
+ " @SuppressWarnings({\"unchecked\",\"unused\"})\n" +
+ " ^^^^^^^^^^^\n" +
+ "At least one of the problems in category \'unchecked\' is not analysed due to a compiler option being ignored\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 3)\n" +
+ " @SuppressWarnings({\"unchecked\",\"unused\"})\n" +
+ " ^^^^^^^^\n" +
+ "Unnecessary @SuppressWarnings(\"unused\")\n" +
"----------\n",
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
}
@@ -11683,4 +11685,122 @@ public void testBug470665() throws Exception {
this.enableAPT = apt;
}
}
+public void testBug506888a() throws Exception {
+ if (this.complianceLevel <= ClassFileConstants.JDK1_5) {
+ return;
+ }
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnusedWarningToken, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportIncompleteEnumSwitch, CompilerOptions.IGNORE);
+ options.put(CompilerOptions.OPTION_ReportMissingDefaultCase, CompilerOptions.WARNING);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " \n" +
+ " @SuppressWarnings({\"incomplete-switch\"})\n" +
+ " void foo() {\n" +
+ " }\n" +
+ "} \n",
+ },
+ "----------\n" +
+ "1. INFO in X.java (at line 3)\n" +
+ " @SuppressWarnings({\"incomplete-switch\"})\n" +
+ " ^^^^^^^^^^^^^^^^^^^\n" +
+ "At least one of the problems in category \'incomplete-switch\' is not analysed due to a compiler option being ignored\n" +
+ "----------\n",
+ null, true, options);
+}
+public void testBug506888b() throws Exception {
+ if (this.complianceLevel <= ClassFileConstants.JDK1_5) {
+ return;
+ }
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnusedWarningToken, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportIncompleteEnumSwitch, CompilerOptions.WARNING);
+ options.put(CompilerOptions.OPTION_ReportMissingDefaultCase, CompilerOptions.IGNORE);
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " \n" +
+ " @SuppressWarnings({\"incomplete-switch\"})\n" +
+ " void foo(Color c) {\n" +
+ " switch(c) {\n" +
+ " }\n" +
+ " }\n" +
+ " enum Color { BLUE, RED; } \n" +
+ "} \n",
+ },
+ options);
+}
+public void testBug506888c() throws Exception {
+ if (this.complianceLevel <= ClassFileConstants.JDK1_5) {
+ return;
+ }
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnusedWarningToken, CompilerOptions.WARNING);
+ options.put(CompilerOptions.OPTION_ReportIncompleteEnumSwitch, CompilerOptions.WARNING);
+ options.put(CompilerOptions.OPTION_ReportMissingDefaultCase, CompilerOptions.WARNING);
+ options.put(CompilerOptions.OPTION_ReportUncheckedTypeOperation, CompilerOptions.WARNING);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " \n" +
+ " @SuppressWarnings({\"incomplete-switch\", \"unchecked\"})\n" +
+ " void foo(Color c) {\n" +
+ " switch(c) {\n" +
+ " }\n" +
+ " }\n" +
+ " enum Color { BLUE, RED; } \n" +
+ "} \n",
+ },
+ "----------\n" +
+ "1. WARNING in X.java (at line 3)\n" +
+ " @SuppressWarnings({\"incomplete-switch\", \"unchecked\"})\n" +
+ " ^^^^^^^^^^^\n" +
+ "Unnecessary @SuppressWarnings(\"unchecked\")\n" +
+ "----------\n",
+ null, true, options);
+}
+public void testBug506888d() throws Exception {
+ if (this.complianceLevel <= ClassFileConstants.JDK1_5) {
+ return;
+ }
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnusedWarningToken, CompilerOptions.IGNORE);
+ options.put(CompilerOptions.OPTION_ReportIncompleteEnumSwitch, CompilerOptions.IGNORE);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " \n" +
+ " @SuppressWarnings({\"incomplete-switch\"})\n" +
+ " void foo() {\n" +
+ " }\n" +
+ "} \n",
+ },
+ "",
+ null, true, options);
+}
+public void testBug506888e() throws Exception {
+ if (this.complianceLevel <= ClassFileConstants.JDK1_5) {
+ return;
+ }
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnusedWarningToken, CompilerOptions.IGNORE);
+ options.put(CompilerOptions.OPTION_ReportUnusedLabel, CompilerOptions.WARNING);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " \n" +
+ " @SuppressWarnings({\"unused\"})\n" +
+ " void foo() {}\n" +
+ "} \n",
+ },
+ "",
+ null, true, options);
+}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
index e48c9235c..2e44cd42e 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
@@ -14393,6 +14393,27 @@ public void testBug419351() {
new File(lib1Path).delete();
}
}
+
+public void test501457() throws IOException {
+ this.runConformTest(new String[] {
+ "FailingClass.java",
+ "import java.lang.invoke.MethodHandle;\n" +
+ "import java.util.ArrayList;\n" +
+ "public class FailingClass {\n" +
+ " protected void test(MethodHandle handle) throws Throwable {\n" +
+ " handle.invoke(null, new ArrayList<>());\n" +
+ " }\n" +
+ "}\n"
+ },
+ " -1.8 " +
+ " -sourcepath \"" + OUTPUT_DIR + "\" " +
+ "\"" + OUTPUT_DIR + File.separator + "FailingClass.java",
+ "",
+ "",
+ true
+ );
+}
+
// Bug 440477 - [null] Infrastructure for feeding external annotations into compilation
// - single external annotation directory
public void test440477() throws IOException {
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 5171ae970..4ba47f95e 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
@@ -860,6 +860,7 @@ public void _test011_problem_categories() {
expectedProblemAttributes.put("NotVisibleMethod", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
expectedProblemAttributes.put("NotVisibleType", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
expectedProblemAttributes.put("NullableFieldReference", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
+ expectedProblemAttributes.put("NullAnnotationAtQualifyingType", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
expectedProblemAttributes.put("NullAnnotationUnsupportedLocation", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
expectedProblemAttributes.put("NullAnnotationUnsupportedLocationAtType", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
expectedProblemAttributes.put("NullExpressionReference", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
@@ -1004,6 +1005,7 @@ public void _test011_problem_categories() {
expectedProblemAttributes.put("TooManyMethods", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
expectedProblemAttributes.put("TooManyParametersForSyntheticMethod", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
expectedProblemAttributes.put("TooManySyntheticArgumentSlots", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
+ expectedProblemAttributes.put("TypeAnnotationAtQualifiedName", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
expectedProblemAttributes.put("TypeArgumentMismatch", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
expectedProblemAttributes.put("TypeArgumentsForRawGenericConstructor", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
expectedProblemAttributes.put("TypeArgumentsForRawGenericMethod", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
@@ -1102,6 +1104,7 @@ public void _test011_problem_categories() {
expectedProblemAttributes.put("lambdaSignatureMismatched", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
expectedProblemAttributes.put("IllegalArrayOfUnionType", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
expectedProblemAttributes.put("IllegalArrayTypeInIntersectionCast", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
+ expectedProblemAttributes.put("ProblemNotAnalysed", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
//{ObjectTeams: new problems (incomplete list):
//expectedProblemAttributes.put("", new ProblemAttributes(CategorizedProblem.CAT_UNSPECIFIED));
expectedProblemAttributes.put("OTJ_RELATED", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
@@ -1781,6 +1784,7 @@ public void test012_compiler_problems_tuning() {
expectedProblemAttributes.put("NotVisibleMethod", SKIP);
expectedProblemAttributes.put("NotVisibleType", SKIP);
expectedProblemAttributes.put("NullableFieldReference", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_REFERENCE));
+ expectedProblemAttributes.put("NullAnnotationAtQualifyingType", SKIP);
expectedProblemAttributes.put("NullAnnotationUnsupportedLocation", SKIP);
expectedProblemAttributes.put("NullAnnotationUnsupportedLocationAtType", SKIP);
expectedProblemAttributes.put("NullityMismatchAgainstFreeTypeVariable", new ProblemAttributes(JavaCore.COMPILER_PB_PESSIMISTIC_NULL_ANALYSIS_FOR_FREE_TYPE_VARIABLES));
@@ -1925,6 +1929,7 @@ public void test012_compiler_problems_tuning() {
expectedProblemAttributes.put("TooManyMethods", SKIP);
expectedProblemAttributes.put("TooManyParametersForSyntheticMethod", SKIP);
expectedProblemAttributes.put("TooManySyntheticArgumentSlots", SKIP);
+ expectedProblemAttributes.put("TypeAnnotationAtQualifiedName", SKIP);
expectedProblemAttributes.put("TypeArgumentMismatch", SKIP);
expectedProblemAttributes.put("TypeArgumentsForRawGenericConstructor", SKIP);
expectedProblemAttributes.put("TypeArgumentsForRawGenericMethod", SKIP);
@@ -2024,6 +2029,7 @@ public void test012_compiler_problems_tuning() {
expectedProblemAttributes.put("DisallowedExplicitThisParameter", SKIP);
expectedProblemAttributes.put("IllegalArrayOfUnionType", SKIP);
expectedProblemAttributes.put("IllegalArrayTypeInIntersectionCast", SKIP);
+ expectedProblemAttributes.put("ProblemNotAnalysed", SKIP);
//{ObjectTeams: new constants:
expectedProblemAttributes.put("OTJ_RELATED", SKIP);
expectedProblemAttributes.put("OTCHAP", SKIP);
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExpressionContextTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExpressionContextTests.java
index 6392ec83c..71484d010 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExpressionContextTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExpressionContextTests.java
@@ -241,16 +241,21 @@ public void test008() {
"1. ERROR in X.java (at line 10)\n" +
" Object p = (@Marker java.lang. @Readonly String & I & J) () -> {};\n" +
" ^^^^^^^\n" +
- "Syntax error, type annotations are illegal here\n" +
+ "Illegally placed annotation: type annotations must directly precede the simple name of the type they are meant to affect (or the [] for arrays)\n" +
"----------\n" +
"2. ERROR in X.java (at line 10)\n" +
" Object p = (@Marker java.lang. @Readonly String & I & J) () -> {};\n" +
+ " ^^^^^^\n" +
+ "Marker cannot be resolved to a type\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 10)\n" +
+ " Object p = (@Marker java.lang. @Readonly String & I & J) () -> {};\n" +
" ^^^^^^^^\n" +
"Readonly cannot be resolved to a type\n" +
"----------\n" +
- "3. ERROR in X.java (at line 10)\n" +
+ "4. ERROR in X.java (at line 10)\n" +
" Object p = (@Marker java.lang. @Readonly String & I & J) () -> {};\n" +
- " ^^^^^\n" +
+ " ^^^^^\n" +
"The target type of this expression must be a functional interface\n" +
"----------\n");
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
index 5b965903c..8e25ab964 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
@@ -7309,4 +7309,60 @@ public void testBug499725() {
"}\n"
});
}
+public void testBug499725a() {
+ runConformTest(
+ new String[] {
+ "Try22.java",
+ "import java.rmi.RemoteException;\n" +
+ "import java.util.Arrays;\n" +
+ "import java.util.Collection;\n" +
+ "import java.util.Collections;\n" +
+ "import java.util.List;\n" +
+ "import java.util.function.Function;\n" +
+ "import java.util.stream.Collectors;\n" +
+ "\n" +
+ "\n" +
+ "public class Try22 {\n" +
+ " public static class RemoteExceptionWrapper {\n" +
+ " @FunctionalInterface\n" +
+ " public static interface FunctionRemote<T, R> {\n" +
+ " R apply(T t) throws RemoteException;\n" +
+ " }\n" +
+ " \n" +
+ " public static <T, R> Function<T, R> wrapFunction(FunctionRemote<T, R> f) {\n" +
+ " return x -> {\n" +
+ " try {\n" +
+ " return f.apply(x);\n" +
+ " }\n" +
+ " catch(RemoteException e) {\n" +
+ " throw new RuntimeException(e);\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ " }\n" +
+ "\n" +
+ "\n" +
+ " private static class ThrowingThingy {\n" +
+ " public Collection<String> listStuff(String in) throws RemoteException {\n" +
+ " return Collections.emptyList();\n" +
+ " }\n" +
+ " }\n" +
+ "\n" +
+ " \n" +
+ " public static void main(String[] args) {\n" +
+ " List<String> stagedNodes = Arrays.asList(\"a\", \"b\", \"c\");\n" +
+ " ThrowingThingy remoteThing = new ThrowingThingy(); // simulation of a rmi remote, hence the exceptio\n" +
+ " \n" +
+ " List<String> resultingStuff = stagedNodes.stream()\n" +
+ " .flatMap(RemoteExceptionWrapper.wrapFunction(\n" +
+ " (String node) -> remoteThing.listStuff(node) // HERE\n" +
+ " .stream()\n" +
+ " .map(sub -> node + \"/\" + sub)))\n" +
+ " .collect(Collectors.toList());\n" +
+ " \n" +
+ " System.out.println(resultingStuff);\n" +
+ " }\n" +
+ "}\n"
+ });
+}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GrammarCoverageTests308.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GrammarCoverageTests308.java
index aaeded828..38199bdae 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GrammarCoverageTests308.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GrammarCoverageTests308.java
@@ -1565,64 +1565,74 @@ public class GrammarCoverageTests308 extends AbstractRegressionTest {
"4. ERROR in X.java (at line 4)\n" +
" Object q = (@Marker java. @Marker util. @Marker List<@Marker String> []) null;\n" +
" ^^^^^^^\n" +
- "Syntax error, type annotations are illegal here\n" +
+ "Illegally placed annotation: type annotations must directly precede the simple name of the type they are meant to affect (or the [] for arrays)\n" +
"----------\n" +
"5. ERROR in X.java (at line 4)\n" +
" Object q = (@Marker java. @Marker util. @Marker List<@Marker String> []) null;\n" +
+ " ^^^^^^\n" +
+ "Marker cannot be resolved to a type\n" +
+ "----------\n" +
+ "6. ERROR in X.java (at line 4)\n" +
+ " Object q = (@Marker java. @Marker util. @Marker List<@Marker String> []) null;\n" +
" ^^^^^^^\n" +
"Syntax error, type annotations are illegal here\n" +
"----------\n" +
- "6. ERROR in X.java (at line 4)\n" +
+ "7. ERROR in X.java (at line 4)\n" +
" Object q = (@Marker java. @Marker util. @Marker List<@Marker String> []) null;\n" +
" ^^^^^^\n" +
"Marker cannot be resolved to a type\n" +
"----------\n" +
- "7. ERROR in X.java (at line 4)\n" +
+ "8. ERROR in X.java (at line 4)\n" +
" Object q = (@Marker java. @Marker util. @Marker List<@Marker String> []) null;\n" +
" ^^^^^^\n" +
"Marker cannot be resolved to a type\n" +
"----------\n" +
- "8. ERROR in X.java (at line 5)\n" +
+ "9. ERROR in X.java (at line 5)\n" +
" Object r = (@Marker java. @Marker util.@Marker Map<@Marker String, @Marker String>.@Marker Entry @Marker []) null;\n" +
" ^^^^^^^\n" +
- "Syntax error, type annotations are illegal here\n" +
+ "Illegally placed annotation: type annotations must directly precede the simple name of the type they are meant to affect (or the [] for arrays)\n" +
"----------\n" +
- "9. ERROR in X.java (at line 5)\n" +
+ "10. ERROR in X.java (at line 5)\n" +
" Object r = (@Marker java. @Marker util.@Marker Map<@Marker String, @Marker String>.@Marker Entry @Marker []) null;\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"The member type Map.Entry<K,V> cannot be qualified with a parameterized type, since it is static. Remove arguments from qualifying type Map<String,String>\n" +
"----------\n" +
- "10. ERROR in X.java (at line 5)\n" +
+ "11. ERROR in X.java (at line 5)\n" +
+ " Object r = (@Marker java. @Marker util.@Marker Map<@Marker String, @Marker String>.@Marker Entry @Marker []) null;\n" +
+ " ^^^^^^\n" +
+ "Marker cannot be resolved to a type\n" +
+ "----------\n" +
+ "12. ERROR in X.java (at line 5)\n" +
" Object r = (@Marker java. @Marker util.@Marker Map<@Marker String, @Marker String>.@Marker Entry @Marker []) null;\n" +
" ^^^^^^^\n" +
"Syntax error, type annotations are illegal here\n" +
"----------\n" +
- "11. ERROR in X.java (at line 5)\n" +
- " Object r = (@Marker java. @Marker util.@Marker Map<@Marker String, @Marker String>.@Marker Entry @Marker []) null;\n" +
- " ^^^^^^^\n" +
- "Type annotations are not allowed on type names used to access static members\n" +
+ "13. ERROR in X.java (at line 5)\n" +
+ " Object r = (@Marker java. @Marker util.@Marker Map<@Marker String, @Marker String>.@Marker Entry @Marker []) null;\n" +
+ " ^^^^^^^\n" +
+ "Type annotations are not allowed on type names used to access static members\n" +
"----------\n" +
- "12. ERROR in X.java (at line 5)\n" +
+ "14. ERROR in X.java (at line 5)\n" +
" Object r = (@Marker java. @Marker util.@Marker Map<@Marker String, @Marker String>.@Marker Entry @Marker []) null;\n" +
" ^^^^^^\n" +
"Marker cannot be resolved to a type\n" +
"----------\n" +
- "13. ERROR in X.java (at line 5)\n" +
+ "15. ERROR in X.java (at line 5)\n" +
" Object r = (@Marker java. @Marker util.@Marker Map<@Marker String, @Marker String>.@Marker Entry @Marker []) null;\n" +
" ^^^^^^\n" +
"Marker cannot be resolved to a type\n" +
"----------\n" +
- "14. ERROR in X.java (at line 5)\n" +
+ "16. ERROR in X.java (at line 5)\n" +
" Object r = (@Marker java. @Marker util.@Marker Map<@Marker String, @Marker String>.@Marker Entry @Marker []) null;\n" +
" ^^^^^^\n" +
"Marker cannot be resolved to a type\n" +
"----------\n" +
- "15. ERROR in X.java (at line 5)\n" +
+ "17. ERROR in X.java (at line 5)\n" +
" Object r = (@Marker java. @Marker util.@Marker Map<@Marker String, @Marker String>.@Marker Entry @Marker []) null;\n" +
" ^^^^^^\n" +
"Marker cannot be resolved to a type\n" +
"----------\n" +
- "16. ERROR in X.java (at line 5)\n" +
+ "18. ERROR in X.java (at line 5)\n" +
" Object r = (@Marker java. @Marker util.@Marker Map<@Marker String, @Marker String>.@Marker Entry @Marker []) null;\n" +
" ^^^^^^\n" +
"Marker cannot be resolved to a type\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JSR308SpecSnippetTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JSR308SpecSnippetTests.java
index 01503f4ff..84297888f 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JSR308SpecSnippetTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JSR308SpecSnippetTests.java
@@ -1402,7 +1402,7 @@ public class JSR308SpecSnippetTests extends AbstractRegressionTest {
"1. ERROR in X.java (at line 13)\n" +
" @TAnno java.lang.Object field8; // illegal\n" +
" ^^^^^^\n" +
- "The annotation @TAnno is disallowed for this location\n" +
+ "Illegally placed annotation: type annotations must directly precede the simple name of the type they are meant to affect (or the [] for arrays)\n" +
"----------\n" +
"2. ERROR in X.java (at line 15)\n" +
" java.lang. @FAnno Object field10; // illegal\n" +
@@ -1417,7 +1417,7 @@ public class JSR308SpecSnippetTests extends AbstractRegressionTest {
"4. ERROR in X.java (at line 25)\n" +
" @TAnno java.lang.Object myMethod8() { } // illegal\n" +
" ^^^^^^\n" +
- "The annotation @TAnno is disallowed for this location\n" +
+ "Illegally placed annotation: type annotations must directly precede the simple name of the type they are meant to affect (or the [] for arrays)\n" +
"----------\n" +
"5. ERROR in X.java (at line 27)\n" +
" java.lang. @MAnno Object myMethod10() { } // illegal\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java
index 69bda64da..f156721fa 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java
@@ -6339,6 +6339,38 @@ public void testBug502871() {
"----------\n"
);
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=490469 Internal compiler error: java.lang.NullPointerException at org.eclipse.jdt.internal.compiler.ast.LambdaExpression.analyseCode(LambdaExpression.java:512)
+public void testBUg490469() {
+ this.runConformTest(
+ new String[] {
+ "AbstractClientProxy.java",
+ "import java.util.function.Supplier;\n" +
+ "public abstract class AbstractClientProxy {\n" +
+ " protected <T> T getRemoteObject(String url, Class<T> responseType, Object... urlVariables) {\n" +
+ " return handleException(this.bindGet(REST::getForObject, url, responseType, urlVariables));\n" +
+ " }\n" +
+ " private <T> T handleException(Supplier<T> s){\n" +
+ " T t = null;\n" +
+ " try{\n" +
+ " t= s.get();\n" +
+ " }catch(Exception e){\n" +
+ " }\n" +
+ " return t;\n" +
+ " }\n" +
+ " private <T> Supplier<T> bindGet(GetFunc fn, String url, Class<T> responseType, Object... uriVariables) {\n" +
+ " return () -> fn.invoke(url, responseType, uriVariables);\n" +
+ " }\n" +
+ "}\n" +
+ "class REST {\n" +
+ " static <T> T getForObject(String url, Class<T> respType, Object... vars) {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n" +
+ "interface GetFunc {\n" +
+ " <T> T invoke(String url, Class<T> responseType, Object... uriVariables);\n" +
+ "}\n"
+ });
+}
public static Class testClass() {
return LambdaExpressionsTest.class;
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeTypeAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeTypeAnnotationTest.java
index c212f51ad..4910611a9 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeTypeAnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeTypeAnnotationTest.java
@@ -2408,7 +2408,7 @@ public class NegativeTypeAnnotationTest extends AbstractRegressionTest {
"1. ERROR in X.java (at line 4)\n" +
" Object o1 = (@Marker java.lang.Integer) null; // 1. Right.\n" +
" ^^^^^^^\n" +
- "Syntax error, type annotations are illegal here\n" +
+ "Illegally placed annotation: type annotations must directly precede the simple name of the type they are meant to affect (or the [] for arrays)\n" +
"----------\n" +
"2. ERROR in X.java (at line 5)\n" +
" Object o2 = (java. @Marker lang.Integer) null; // 2. Wrong.\n" +
@@ -2423,7 +2423,7 @@ public class NegativeTypeAnnotationTest extends AbstractRegressionTest {
"4. ERROR in X.java (at line 9)\n" +
" public void foobar(@Marker java.lang.Integer arg) {}\n" +
" ^^^^^^^\n" +
- "The annotation @Marker is disallowed for this location\n" +
+ "Illegally placed annotation: type annotations must directly precede the simple name of the type they are meant to affect (or the [] for arrays)\n" +
"----------\n");
}
public void test0390882a() {
@@ -2505,18 +2505,28 @@ public class NegativeTypeAnnotationTest extends AbstractRegressionTest {
"----------\n" +
"1. ERROR in X.java (at line 4)\n" +
" Object o1 = (@Marker @Annot java.util.List<String>) null; // 1. Wrong.\n" +
- " ^^^^^^^^^^^^^^\n" +
- "Syntax error, type annotations are illegal here\n" +
+ " ^^^^^^^\n" +
+ "Illegally placed annotation: type annotations must directly precede the simple name of the type they are meant to affect (or the [] for arrays)\n" +
"----------\n" +
- "2. ERROR in X.java (at line 5)\n" +
+ "2. ERROR in X.java (at line 4)\n" +
+ " Object o1 = (@Marker @Annot java.util.List<String>) null; // 1. Wrong.\n" +
+ " ^^^^^^\n" +
+ "Illegally placed annotation: type annotations must directly precede the simple name of the type they are meant to affect (or the [] for arrays)\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 5)\n" +
" Object o2 = (java. @Marker @Annot lang.Integer[]) null; // 2. Wrong.\n" +
" ^^^^^^^^^^^^^^\n" +
"Syntax error, type annotations are illegal here\n" +
"----------\n" +
- "3. ERROR in X.java (at line 6)\n" +
+ "4. ERROR in X.java (at line 6)\n" +
" Object o3 = (@Marker @Annot java.util.List<String>[]) null; // 3. Wrong.\n" +
- " ^^^^^^^^^^^^^^\n" +
- "Syntax error, type annotations are illegal here\n" +
+ " ^^^^^^^\n" +
+ "Illegally placed annotation: type annotations must directly precede the simple name of the type they are meant to affect (or the [] for arrays)\n" +
+ "----------\n" +
+ "5. ERROR in X.java (at line 6)\n" +
+ " Object o3 = (@Marker @Annot java.util.List<String>[]) null; // 3. Wrong.\n" +
+ " ^^^^^^\n" +
+ "Illegally placed annotation: type annotations must directly precede the simple name of the type they are meant to affect (or the [] for arrays)\n" +
"----------\n");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=385137
@@ -2574,7 +2584,7 @@ public class NegativeTypeAnnotationTest extends AbstractRegressionTest {
"4. ERROR in A.java (at line 7)\n" +
" Object o2 = (@Marker p.@Marker A.@Marker B.@Marker C) null;\n" +
" ^^^^^^^\n" +
- "Syntax error, type annotations are illegal here\n" +
+ "Illegally placed annotation: type annotations must directly precede the simple name of the type they are meant to affect (or the [] for arrays)\n" +
"----------\n" +
"5. WARNING in A.java (at line 7)\n" +
" Object o2 = (@Marker p.@Marker A.@Marker B.@Marker C) null;\n" +
@@ -2633,7 +2643,7 @@ public class NegativeTypeAnnotationTest extends AbstractRegressionTest {
"1. ERROR in A.java (at line 6)\n" +
" Object o1 = (@Marker p.@Marker A.@Marker B.@Marker C[]) null;\n" +
" ^^^^^^^\n" +
- "Syntax error, type annotations are illegal here\n" +
+ "Illegally placed annotation: type annotations must directly precede the simple name of the type they are meant to affect (or the [] for arrays)\n" +
"----------\n" +
"2. ERROR in A.java (at line 6)\n" +
" Object o1 = (@Marker p.@Marker A.@Marker B.@Marker C[]) null;\n" +
@@ -3389,12 +3399,12 @@ public class NegativeTypeAnnotationTest extends AbstractRegressionTest {
"1. ERROR in p\\X.java (at line 6)\n" +
" @A @B p.X.Y field4;\n" +
" ^^\n" +
- "The annotation @B is disallowed for this location\n" +
+ "Illegally placed annotation: type annotations must directly precede the simple name of the type they are meant to affect (or the [] for arrays)\n" +
"----------\n" +
"2. ERROR in p\\X.java (at line 7)\n" +
" @B(1) @A(1) java.lang.@A(1) @B(1) String field2;\n" +
" ^^\n" +
- "The annotation @B is disallowed for this location\n" +
+ "Illegally placed annotation: type annotations must directly precede the simple name of the type they are meant to affect (or the [] for arrays)\n" +
"----------\n" +
"3. ERROR in p\\X.java (at line 7)\n" +
" @B(1) @A(1) java.lang.@A(1) @B(1) String field2;\n" +
@@ -3404,7 +3414,7 @@ public class NegativeTypeAnnotationTest extends AbstractRegressionTest {
"4. ERROR in p\\X.java (at line 8)\n" +
" public @B(1) @A(1) java.lang. @A(1) @B(1) String foo(@A(1) @B(1) java.lang. @A(1) @B(1) String str1) {\n" +
" ^^\n" +
- "The annotation @B is disallowed for this location\n" +
+ "Illegally placed annotation: type annotations must directly precede the simple name of the type they are meant to affect (or the [] for arrays)\n" +
"----------\n" +
"5. ERROR in p\\X.java (at line 8)\n" +
" public @B(1) @A(1) java.lang. @A(1) @B(1) String foo(@A(1) @B(1) java.lang. @A(1) @B(1) String str1) {\n" +
@@ -3414,7 +3424,7 @@ public class NegativeTypeAnnotationTest extends AbstractRegressionTest {
"6. ERROR in p\\X.java (at line 8)\n" +
" public @B(1) @A(1) java.lang. @A(1) @B(1) String foo(@A(1) @B(1) java.lang. @A(1) @B(1) String str1) {\n" +
" ^^\n" +
- "The annotation @B is disallowed for this location\n" +
+ "Illegally placed annotation: type annotations must directly precede the simple name of the type they are meant to affect (or the [] for arrays)\n" +
"----------\n" +
"7. ERROR in p\\X.java (at line 8)\n" +
" public @B(1) @A(1) java.lang. @A(1) @B(1) String foo(@A(1) @B(1) java.lang. @A(1) @B(1) String str1) {\n" +
@@ -3424,7 +3434,7 @@ public class NegativeTypeAnnotationTest extends AbstractRegressionTest {
"8. ERROR in p\\X.java (at line 10)\n" +
" @A(1) @B(1) java.lang. @B(1) @A(1) String local2;\n" +
" ^^\n" +
- "The annotation @B is disallowed for this location\n" +
+ "Illegally placed annotation: type annotations must directly precede the simple name of the type they are meant to affect (or the [] for arrays)\n" +
"----------\n" +
"9. ERROR in p\\X.java (at line 10)\n" +
" @A(1) @B(1) java.lang. @B(1) @A(1) String local2;\n" +
@@ -3434,7 +3444,7 @@ public class NegativeTypeAnnotationTest extends AbstractRegressionTest {
"10. ERROR in p\\X.java (at line 12)\n" +
" @B @A p.X.Y local4;\n" +
" ^^\n" +
- "The annotation @B is disallowed for this location\n" +
+ "Illegally placed annotation: type annotations must directly precede the simple name of the type they are meant to affect (or the [] for arrays)\n" +
"----------\n" +
"11. ERROR in p\\X.java (at line 13)\n" +
" @B @A p.q.X local5;\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java
index 2ef578a0b..1a835b6cc 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java
@@ -6940,17 +6940,17 @@ public void testTypeAnnotationProblemNotIn17() {
"1. ERROR in X.java (at line 3)\n" +
" public @NonNull java.lang.String test(@NonNull java.lang.String arg) {\n" +
" ^^^^^^^^\n" +
- "The annotation @NonNull is disallowed for this location\n" +
+ "Illegally placed annotation: type annotations must directly precede the simple name of the type they are meant to affect (or the [] for arrays)\n" +
"----------\n" +
"2. ERROR in X.java (at line 3)\n" +
" public @NonNull java.lang.String test(@NonNull java.lang.String arg) {\n" +
" ^^^^^^^^\n" +
- "The annotation @NonNull is disallowed for this location\n" +
+ "Illegally placed annotation: type annotations must directly precede the simple name of the type they are meant to affect (or the [] for arrays)\n" +
"----------\n" +
"3. ERROR in X.java (at line 4)\n" +
" @NonNull java.lang.String local = arg;\n" +
" ^^^^^^^^\n" +
- "The annotation @NonNull is disallowed for this location\n" +
+ "Illegally placed annotation: type annotations must directly precede the simple name of the type they are meant to affect (or the [] for arrays)\n" +
"----------\n");
}
public void testBug420313() {
@@ -8974,4 +8974,64 @@ public void testBug502113b() {
"----------\n"
);
}
+public void testBug502214() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "test/X.java",
+ "package test;\n" +
+ "\n" +
+ "import org.eclipse.jdt.annotation.NonNull;\n" +
+ "import org.eclipse.jdt.annotation.Nullable;\n" +
+ "\n" +
+ "class A {\n" +
+ " public boolean m1(Object obj) {\n" +
+ " return this == obj;\n" +
+ " }\n" +
+ " public @Nullable String m2() {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n" +
+ "\n" +
+ "interface I {\n" +
+ " public boolean m1(@Nullable Object obj);\n" +
+ " public @NonNull String m2(); \n" +
+ "}\n" +
+ "\n" +
+ "public class X {\n" +
+ " I f() {\n" +
+ " class Y extends A implements I {\n" +
+ " }\n" +
+ " return new Y();\n" +
+ " }\n" +
+ "}\n" +
+ "",
+ },
+ getCompilerOptions(),
+ (this.complianceLevel < ClassFileConstants.JDK1_8 ?
+ "----------\n" +
+ "1. ERROR in test\\X.java (at line 22)\n" +
+ " class Y extends A implements I {\n" +
+ " ^\n" +
+ "The method m2() from A cannot implement the corresponding method from I due to incompatible nullness constraints\n" +
+ "----------\n" +
+ "2. ERROR in test\\X.java (at line 22)\n" +
+ " class Y extends A implements I {\n" +
+ " ^\n" +
+ "The method m1(Object) from A cannot implement the corresponding method from I due to incompatible nullness constraints\n" +
+ "----------\n"
+ :
+ "----------\n" +
+ "1. ERROR in test\\X.java (at line 22)\n" +
+ " class Y extends A implements I {\n" +
+ " ^\n" +
+ "The method @Nullable String m2() from A cannot implement the corresponding method from I due to incompatible nullness constraints\n" +
+ "----------\n" +
+ "2. ERROR in test\\X.java (at line 22)\n" +
+ " class Y extends A implements I {\n" +
+ " ^\n" +
+ "The method m1(Object) from A cannot implement the corresponding method from I due to incompatible nullness constraints\n" +
+ "----------\n"
+ )
+ );
+}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
index aac500093..d43b03721 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
@@ -2189,22 +2189,22 @@ public class NullTypeAnnotationTest extends AbstractNullAnnotationTest {
"1. ERROR in X.java (at line 4)\n" +
" @NonNull X.Inner f;\n" +
" ^^^^^^^^\n" +
- "The nullness annotation \'NonNull\' is not applicable at this location\n" +
+ "The nullness annotation \'NonNull\' is not applicable at this location, it must be placed directly before the nested type name.\n" +
"----------\n" +
"2. ERROR in X.java (at line 5)\n" +
" @NonNull X.Inner foo(@NonNull X.Inner arg) {\n" +
" ^^^^^^^^\n" +
- "The nullness annotation \'NonNull\' is not applicable at this location\n" +
+ "The nullness annotation \'NonNull\' is not applicable at this location, it must be placed directly before the nested type name.\n" +
"----------\n" +
"3. ERROR in X.java (at line 5)\n" +
" @NonNull X.Inner foo(@NonNull X.Inner arg) {\n" +
" ^^^^^^^^\n" +
- "The nullness annotation \'NonNull\' is not applicable at this location\n" +
+ "The nullness annotation \'NonNull\' is not applicable at this location, it must be placed directly before the nested type name.\n" +
"----------\n" +
"4. ERROR in X.java (at line 6)\n" +
" @NonNull X.Inner local = arg;\n" +
" ^^^^^^^^\n" +
- "The nullness annotation \'NonNull\' is not applicable at this location\n" +
+ "The nullness annotation \'NonNull\' is not applicable at this location, it must be placed directly before the nested type name.\n" +
"----------\n");
}
@@ -13161,4 +13161,201 @@ public void testBug502112b() {
"----------\n"
);
}
+public void testBug500885() {
+ runConformTest(
+ new String[] {
+ "annot/NonNull.java",
+ "package annot;\n" +
+ "@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)\n" +
+ "public @interface NonNull {}\n",
+ "annot/NonNullByDefault.java",
+ "package annot;\n" +
+ "@annot.NonNull\n" +
+ "@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)\n" +
+ "public @interface NonNullByDefault {}\n",
+ "annot/package-info.java",
+ "@annot.NonNullByDefault package annot;\n",
+ "test/package-info.java",
+ "@annot.NonNullByDefault package test;\n",
+ "test/X.java",
+ "package test;\n" +
+ "public interface X {\n" +
+ " public String get();\n" +
+ "}\n"
+ },
+ getCompilerOptions(),
+ "");
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_NONNULL_BY_DEFAULT_ANNOTATION_SECONDARY_NAMES, "annot.NonNullByDefault");
+ options.put(JavaCore.COMPILER_NONNULL_ANNOTATION_SECONDARY_NAMES, "annot.NonNull");
+ runConformTestWithLibs(
+ new String[] {
+ "test2/package-info.java",
+ "@org.eclipse.jdt.annotation.NonNullByDefault package test2;\n",
+ "test2/Y.java",
+ "package test2;\n" +
+ "import test.X;\n" +
+ "public class Y implements X {\n" +
+ " public String get() {\n" +
+ " return \"\";\n" +
+ " }\n" +
+ "}\n"
+ },
+ options,
+ "");
+}
+public void testBug505671() {
+ runConformTestWithLibs(
+ new String[] {
+ "snippet/Pair.java",
+ "package snippet;\n" +
+ "\n" +
+ "import org.eclipse.jdt.annotation.NonNullByDefault;\n" +
+ "\n" +
+ "@NonNullByDefault\n" +
+ "public class Pair {\n" +
+ " public static <S, T> S make(S left, T right, Object x) {\n" +
+ " throw new RuntimeException();\n" +
+ " }\n" +
+ "}\n" +
+ "",
+ },
+ getCompilerOptions(),
+ ""
+ );
+ runNegativeTestWithLibs(
+ new String[] {
+ "snippet/Snippet.java",
+ "package snippet;\n" +
+ "\n" +
+ "import org.eclipse.jdt.annotation.NonNull;\n" +
+ "\n" +
+ "public class Snippet {\n" +
+ " public static final @NonNull Object FALSE = new Object();\n" +
+ "\n" +
+ " public static @NonNull Object abbreviateExplained0() {\n" +
+ " return Pair.<String, @NonNull Object>make(null, FALSE, null);\n" +
+ " }\n" +
+ "}\n" +
+ "",
+ },
+ getCompilerOptions(),
+ "----------\n" +
+ "1. WARNING in snippet\\Snippet.java (at line 9)\n" +
+ " return Pair.<String, @NonNull Object>make(null, FALSE, null);\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Null type safety (type annotations): The expression of type \'String\' needs unchecked conversion to conform to \'@NonNull Object\'\n" +
+ "----------\n" +
+ "2. ERROR in snippet\\Snippet.java (at line 9)\n" +
+ " return Pair.<String, @NonNull Object>make(null, FALSE, null);\n" +
+ " ^^^^\n" +
+ "Null type mismatch: required \'@NonNull Object\' but the provided value is null\n" +
+ "----------\n"
+ );
+}
+public void testBug501564() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "xxx/Foo.java",
+ "package xxx;\n" +
+ "import org.eclipse.jdt.annotation.NonNullByDefault;\n" +
+ "import org.eclipse.jdt.annotation.DefaultLocation;\n" +
+ "\n" +
+ "class Generic<E1 extends Generic<E1>> { \n" +
+ "}\n" +
+ "class Foo { \n" +
+ " static <E2 extends Generic<E2>> Bar<E2> foo() {\n" +
+ " return new Bar<>();\n" +
+ " }\n" +
+ "\n" +
+ " @NonNullByDefault(DefaultLocation.TYPE_PARAMETER)\n" +
+ " static class Bar<E3 extends Generic<E3>> { }\n" +
+ "}\n" +
+ "",
+ },
+ getCompilerOptions(),
+ "----------\n" +
+ "1. ERROR in xxx\\Foo.java (at line 8)\n" +
+ " static <E2 extends Generic<E2>> Bar<E2> foo() {\n" +
+ " ^^\n" +
+ "Null constraint mismatch: The type \'E2 extends Generic<E2>\' is not a valid substitute for the type parameter \'@NonNull E3 extends Generic<E3 extends Generic<E3>>\'\n" +
+ "----------\n"
+ );
+}
+public void testBug501564interface() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "xxx/Foo.java",
+ "package xxx;\n" +
+ "import org.eclipse.jdt.annotation.NonNullByDefault;\n" +
+ "import org.eclipse.jdt.annotation.DefaultLocation;\n" +
+ "\n" +
+ "interface Generic<E1 extends Generic<E1>> { \n" +
+ "}\n" +
+ "class Foo { \n" +
+ " static <E2 extends Generic<E2>> Bar<E2> foo() {\n" +
+ " return new Bar<>();\n" +
+ " }\n" +
+ "\n" +
+ " @NonNullByDefault(DefaultLocation.TYPE_PARAMETER)\n" +
+ " static class Bar<E3 extends Generic<E3>> { }\n" +
+ "}\n" +
+ "",
+ },
+ getCompilerOptions(),
+ "----------\n" +
+ "1. ERROR in xxx\\Foo.java (at line 8)\n" +
+ " static <E2 extends Generic<E2>> Bar<E2> foo() {\n" +
+ " ^^\n" +
+ "Null constraint mismatch: The type \'E2 extends Generic<E2>\' is not a valid substitute for the type parameter \'@NonNull E3 extends Generic<E3 extends Generic<E3>>\'\n" +
+ "----------\n"
+ );
+}
+public void testBug501464() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "Foo.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "\n" +
+ "interface MyList<T> { @NonNull T getAny(); }\n" +
+ "\n" +
+ "@NonNullByDefault({})\n" +
+ "class Foo {\n" +
+ " @Nullable Object b;\n" +
+ " \n" +
+ " void foo() {\n" +
+ " @Nullable Object f = b;\n" +
+ " ((@NonNull Object)f).hashCode(); // Error (unexpected): Potential null pointer access: this expression has a '@Nullable' type\n" +
+ " }\n" +
+ " \n" +
+ " void workaround() {\n" +
+ " @Nullable Object f = b;\n" +
+ " @NonNull Object g = (@NonNull Object)f; // Warning (expected): Null type safety: Unchecked cast from @Nullable Object to @NonNull Object\n" +
+ " g.hashCode();\n" +
+ " }\n" +
+ " String three(@NonNull MyList<@Nullable String> list) {\n" +
+ " return ((@NonNull MyList<@NonNull String>) list).getAny().toUpperCase();\n" +
+ " }\n" +
+ "}\n" +
+ "",
+ },
+ getCompilerOptions(),
+ "----------\n" +
+ "1. WARNING in Foo.java (at line 11)\n" +
+ " ((@NonNull Object)f).hashCode(); // Error (unexpected): Potential null pointer access: this expression has a \'@Nullable\' type\n" +
+ " ^^^^^^^^^^^^^^^^^^^^\n" +
+ "Null type safety: Unchecked cast from @Nullable Object to @NonNull Object\n" +
+ "----------\n" +
+ "2. WARNING in Foo.java (at line 16)\n" +
+ " @NonNull Object g = (@NonNull Object)f; // Warning (expected): Null type safety: Unchecked cast from @Nullable Object to @NonNull Object\n" +
+ " ^^^^^^^^^^^^^^^^^^\n" +
+ "Null type safety: Unchecked cast from @Nullable Object to @NonNull Object\n" +
+ "----------\n" +
+ "3. WARNING in Foo.java (at line 20)\n" +
+ " return ((@NonNull MyList<@NonNull String>) list).getAny().toUpperCase();\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Null type safety: Unchecked cast from @NonNull MyList<@Nullable String> to @NonNull MyList<@NonNull String>\n" +
+ "----------\n"
+ );
+}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SerializableLambdaTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SerializableLambdaTest.java
index 30541d602..269fc338f 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SerializableLambdaTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SerializableLambdaTest.java
@@ -2199,6 +2199,33 @@ public class SerializableLambdaTest extends AbstractRegressionTest {
null,true,
new String[]{"-Ddummy"});
}
+ public void testbug507011() {
+ this.runConformTest(
+ new String[]{
+ "VerifyErrorDerived.java",
+ "import java.io.Serializable;\n" +
+ "import java.util.function.Function;\n" +
+ "public class VerifyErrorDerived extends VerifyErrorBase {\n" +
+ " public static void main(String [] args) {\n" +
+ " System.out.println(\"hello world\");\n" +
+ " }\n" +
+ " public int derivedMethod(String param) {\n" +
+ " SerializableFunction<String, Integer> f = super::baseMethod;\n" +
+ " return f.apply(param);\n" +
+ " }\n" +
+ "}\n" +
+ "interface SerializableFunction<T, R> extends Function<T, R>, Serializable {}",
+ "VerifyErrorBase.java",
+ "public class VerifyErrorBase {\n" +
+ " public int baseMethod(String param) {\n" +
+ " return 7;\n" +
+ " }\n" +
+ "}\n"
+ },
+ "hello world",
+ null,true,
+ new String[]{"-Ddummy"});
+ }
// ---
private void checkExpected(String expected, String actual) {
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java
index 2659d9960..74db7db79 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java
@@ -13,6 +13,7 @@ package org.eclipse.jdt.core.tests.model;
import java.io.*;
import java.net.URL;
import java.util.*;
+import java.util.stream.*;
import junit.framework.Test;
import junit.framework.TestSuite;
@@ -369,8 +370,12 @@ public abstract class AbstractJavaModelTests extends SuiteOfTestCases {
protected void assertSearchResults(String message, String expected, Object collector) {
assertSearchResults(message, expected, collector, true /* assertion */);
}
- protected void assertSearchResults(String message, String expected, Object collector, boolean assertion) {
- String actual = collector.toString();
+ private static String sortLines(String toSplit) {
+ return Arrays.stream(toSplit.split("\n")).sorted().collect(Collectors.joining("\n"));
+ }
+ protected void assertSearchResults(String message, String expectedString, Object collector, boolean assertion) {
+ String expected = sortLines(expectedString);
+ String actual = sortLines(collector.toString());
if (!expected.equals(actual)) {
if (this.displayName) System.out.println(getName()+" actual result is:");
System.out.print(displayString(actual, this.tabs));
@@ -660,6 +665,9 @@ public abstract class AbstractJavaModelTests extends SuiteOfTestCases {
assertElementsEqual(message, expected, elements, false/*don't show key*/);
}
protected void assertElementsEqual(String message, String expected, IJavaElement[] elements, boolean showResolvedInfo) {
+ assertElementsEqual(message, expected, elements, showResolvedInfo, false);
+ }
+ protected void assertElementsEqual(String message, String expected, IJavaElement[] elements, boolean showResolvedInfo, boolean sorted) {
StringBuffer buffer = new StringBuffer();
if (elements != null) {
for (int i = 0, length = elements.length; i < length; i++){
@@ -675,6 +683,9 @@ public abstract class AbstractJavaModelTests extends SuiteOfTestCases {
buffer.append("<null>");
}
String actual = buffer.toString();
+ if (sorted) {
+ actual = sortLines(actual);
+ }
if (!expected.equals(actual)) {
if (this.displayName) System.out.println(getName()+" actual result is:");
System.out.println(displayString(actual, this.tabs) + this.endChar);
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavadocMethodCompletionModelTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavadocMethodCompletionModelTest.java
index eeae0e816..198ec49a6 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavadocMethodCompletionModelTest.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavadocMethodCompletionModelTest.java
@@ -338,7 +338,7 @@ public void test015() throws JavaModelException {
" }\n" +
"}\n";
completeInJavadoc("/Completion/src/javadoc/methods/tags/BasicTestMethods.java", source, true, "I");
- assertResults(
+ assertSortedResults(
"IllegalMonitorStateException[TYPE_REF]{IllegalMonitorStateException, java.lang, Ljava.lang.IllegalMonitorStateException;, null, null, "+this.positions+R_DRICUNRE+"}\n" +
"InterruptedException[TYPE_REF]{InterruptedException, java.lang, Ljava.lang.InterruptedException;, null, null, "+this.positions+R_DRICUNRE+"}"
);
@@ -357,9 +357,9 @@ public void test016() throws JavaModelException {
" }\n" +
"}\n";
completeInJavadoc("/Completion/src/javadoc/methods/tags/BasicTestMethods.java", source, true, "java.lang.I");
- assertResults(
- "IllegalMonitorStateException[TYPE_REF]{IllegalMonitorStateException, java.lang, Ljava.lang.IllegalMonitorStateException;, null, null, "+this.positions+R_DRICNRE+"}\n" +
- "InterruptedException[TYPE_REF]{InterruptedException, java.lang, Ljava.lang.InterruptedException;, null, null, "+this.positions+R_DRICNREEET+"}"
+ assertSortedResults(
+ "InterruptedException[TYPE_REF]{InterruptedException, java.lang, Ljava.lang.InterruptedException;, null, null, "+this.positions+R_DRICNREEET+"}\n" +
+ "IllegalMonitorStateException[TYPE_REF]{IllegalMonitorStateException, java.lang, Ljava.lang.IllegalMonitorStateException;, null, null, "+this.positions+R_DRICNRE+"}"
);
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests2.java
index fc42448c2..0c82ecdee 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests2.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests2.java
@@ -926,7 +926,9 @@ public void testBug232880i() throws Exception {
"Unexpected elements",
"IResource [in IResource.class [in test1 [in "+outputDirectory+File.separator+"bug232880a.jar]]]\n" +
"IResource [in IResource.class [in test2 [in "+outputDirectory+File.separator+"bug232880a.jar]]]",
- elements
+ elements,
+ false,
+ true
);
} finally {
this.deleteExternalFile(externalJar1);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CharOperation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CharOperation.java
index e62e8e210..40c728273 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CharOperation.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CharOperation.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2016 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -9,9 +9,12 @@
* IBM Corporation - initial API and implementation
* Luiz-Otavio Zorzella <zorzella at gmail dot com> - Improve CamelCase algorithm
* Gábor Kövesdán - Contribution for Bug 350000 - [content assist] Include non-prefix matches in auto-complete suggestions
+ * Stefan Xenos <sxenos@gmail.com> (Google) - Bug 501283 - Lots of hash collisions during indexing
*******************************************************************************/
package org.eclipse.jdt.core.compiler;
+import java.util.Arrays;
+
import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
/**
@@ -2281,19 +2284,9 @@ public static final boolean fragmentEquals(
*
* @param array the array for which a hashcode is required
* @return the hashcode
- * @throws NullPointerException if array is null
*/
public static final int hashCode(char[] array) {
- int length = array.length;
- int hash = length == 0 ? 31 : array[0];
- if (length < 8) {
- for (int i = length; --i > 0;)
- hash = (hash * 31) + array[i];
- } else {
- // 8 characters is enough to compute a decent hash code, don't waste time examining every character
- for (int i = length - 1, last = i > 16 ? i - 16 : 0; i > last; i -= 2)
- hash = (hash * 31) + array[i];
- }
+ int hash = Arrays.hashCode(array);
return hash & 0x7FFFFFFF;
}
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 96ac0a2e3..fa8ee852a 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
@@ -1873,6 +1873,12 @@ void setSourceStart(int sourceStart);
int IllegalDefaultModifierSpecification = MethodRelated + 1058;
/** @since 3.13 */
int CannotInferInvocationType = TypeRelated + 1059;
+
+ /** @since 3.13 */
+ int TypeAnnotationAtQualifiedName = Internal + Syntax + 1060;
+
+ /** @since 3.13 */
+ int NullAnnotationAtQualifyingType = Internal + Syntax + 1061;
/** @since 3.10 */
int GenericInferenceError = 1100; // FIXME: This is just a stop-gap measure, be more specific via https://bugs.eclipse.org/404675
@@ -1880,6 +1886,8 @@ void setSourceStart(int sourceStart);
/** @deprecated - problem is no longer generated (implementation issue has been resolved)
* @since 3.10 */
int LambdaShapeComputationError = 1101;
+ /** @since 3.13 */
+ int ProblemNotAnalysed = 1102;
//{ObjectTeams:
int OTJ_RELATED = 1000000;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
index 80e2e1b9c..9fc88ae55 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
@@ -750,8 +750,11 @@ public abstract class ASTNode implements TypeConstants, TypeIds {
} else {
updatedArgumentType = argument.resolveType(scope);
}
- if (updatedArgumentType != null && updatedArgumentType.kind() != Binding.POLY_TYPE)
+ if (updatedArgumentType != null && updatedArgumentType.kind() != Binding.POLY_TYPE) {
argumentTypes[i] = updatedArgumentType;
+ if (candidateMethod.isPolymorphic())
+ candidateMethod.parameters[i] = updatedArgumentType;
+ }
}
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java
index 828fa15f1..dfb613a58 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java
@@ -654,7 +654,7 @@ public abstract class Annotation extends Expression {
// no need to check annotation usage if missing
return;
}
- if (! isAnnotationTargetAllowed(repeatingAnnotation, scope, containerAnnotationType, repeatingAnnotation.recipient.kind())) {
+ if (isAnnotationTargetAllowed(repeatingAnnotation, scope, containerAnnotationType, repeatingAnnotation.recipient.kind()) != AnnotationTargetAllowed.YES) {
scope.problemReporter().disallowedTargetForContainerAnnotation(repeatingAnnotation, containerAnnotationType);
}
}
@@ -987,75 +987,83 @@ public abstract class Annotation extends Expression {
return this.resolvedType;
}
- private static boolean isAnnotationTargetAllowed(Binding recipient, BlockScope scope, TypeBinding annotationType, int kind, long metaTagBits) {
+ public enum AnnotationTargetAllowed {
+ YES, TYPE_ANNOTATION_ON_QUALIFIED_NAME, NO;
+ }
+
+ private static AnnotationTargetAllowed isAnnotationTargetAllowed(Binding recipient, BlockScope scope, TypeBinding annotationType, int kind, long metaTagBits) {
switch (kind) {
case Binding.PACKAGE :
if ((metaTagBits & TagBits.AnnotationForPackage) != 0)
- return true;
+ return AnnotationTargetAllowed.YES;
else if (scope.compilerOptions().sourceLevel <= ClassFileConstants.JDK1_6) {
SourceTypeBinding sourceType = (SourceTypeBinding) recipient;
if (CharOperation.equals(sourceType.sourceName, TypeConstants.PACKAGE_INFO_NAME))
- return true;
+ return AnnotationTargetAllowed.YES;
}
break;
case Binding.TYPE_USE :
if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) {
// jsr 308
- return true;
+ return AnnotationTargetAllowed.YES;
}
if (scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_8) {
// already reported as syntax error; don't report secondary problems
- return true;
+ return AnnotationTargetAllowed.YES;
}
break;
case Binding.TYPE :
case Binding.GENERIC_TYPE :
if (((ReferenceBinding)recipient).isAnnotationType()) {
if ((metaTagBits & (TagBits.AnnotationForAnnotationType | TagBits.AnnotationForType | TagBits.AnnotationForTypeUse)) != 0)
- return true;
+ return AnnotationTargetAllowed.YES;
} else if ((metaTagBits & (TagBits.AnnotationForType | TagBits.AnnotationForTypeUse)) != 0) {
- return true;
+ return AnnotationTargetAllowed.YES;
} else if ((metaTagBits & TagBits.AnnotationForPackage) != 0) {
if (CharOperation.equals(((ReferenceBinding) recipient).sourceName, TypeConstants.PACKAGE_INFO_NAME))
- return true;
+ return AnnotationTargetAllowed.YES;
}
//{ObjectTeams: allow @Override for roles:
if ( (((ReferenceBinding)recipient).isRole())
&& (annotationType.id == TypeIds.T_JavaLangOverride))
- return true;
+ return AnnotationTargetAllowed.YES;
//SH}
break;
//{ObjectTeams: method mappings
// TODO(SH): should annotations for method mappings be controlled separately?
case Binding.BINDING :
if ((metaTagBits & TagBits.AnnotationForMethod) != 0)
- return true;
+ return AnnotationTargetAllowed.YES;
break;
//SH}
case Binding.METHOD :
MethodBinding methodBinding = (MethodBinding) recipient;
if (methodBinding.isConstructor()) {
if ((metaTagBits & (TagBits.AnnotationForConstructor | TagBits.AnnotationForTypeUse)) != 0)
- return true;
+ return AnnotationTargetAllowed.YES;
} else if ((metaTagBits & TagBits.AnnotationForMethod) != 0) {
- return true;
+ return AnnotationTargetAllowed.YES;
} else if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) {
SourceTypeBinding sourceType = (SourceTypeBinding) methodBinding.declaringClass;
MethodDeclaration methodDecl = (MethodDeclaration) sourceType.scope.referenceContext.declarationOf(methodBinding);
if (isTypeUseCompatible(methodDecl.returnType, scope)) {
- return true;
+ return AnnotationTargetAllowed.YES;
+ } else {
+ return AnnotationTargetAllowed.TYPE_ANNOTATION_ON_QUALIFIED_NAME;
}
}
break;
case Binding.FIELD :
if ((metaTagBits & TagBits.AnnotationForField) != 0) {
- return true;
+ return AnnotationTargetAllowed.YES;
} else if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) {
FieldBinding sourceField = (FieldBinding) recipient;
SourceTypeBinding sourceType = (SourceTypeBinding) sourceField.declaringClass;
FieldDeclaration fieldDeclaration = sourceType.scope.referenceContext.declarationOf(sourceField);
if (isTypeUseCompatible(fieldDeclaration.type, scope)) {
- return true;
+ return AnnotationTargetAllowed.YES;
+ } else {
+ return AnnotationTargetAllowed.TYPE_ANNOTATION_ON_QUALIFIED_NAME;
}
}
break;
@@ -1063,27 +1071,31 @@ public abstract class Annotation extends Expression {
LocalVariableBinding localVariableBinding = (LocalVariableBinding) recipient;
if ((localVariableBinding.tagBits & TagBits.IsArgument) != 0) {
if ((metaTagBits & TagBits.AnnotationForParameter) != 0) {
- return true;
+ return AnnotationTargetAllowed.YES;
} else if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) {
if (isTypeUseCompatible(localVariableBinding.declaration.type, scope)) {
- return true;
+ return AnnotationTargetAllowed.YES;
+ } else {
+ return AnnotationTargetAllowed.TYPE_ANNOTATION_ON_QUALIFIED_NAME;
}
}
} else if ((annotationType.tagBits & TagBits.AnnotationForLocalVariable) != 0) {
- return true;
+ return AnnotationTargetAllowed.YES;
} else if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) {
if (isTypeUseCompatible(localVariableBinding.declaration.type, scope)) {
- return true;
+ return AnnotationTargetAllowed.YES;
+ } else {
+ return AnnotationTargetAllowed.TYPE_ANNOTATION_ON_QUALIFIED_NAME;
}
}
break;
case Binding.TYPE_PARAMETER : // jsr308
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=391196
if ((metaTagBits & (TagBits.AnnotationForTypeParameter | TagBits.AnnotationForTypeUse)) != 0) {
- return true;
+ return AnnotationTargetAllowed.YES;
}
}
- return false;
+ return AnnotationTargetAllowed.NO;
}
public static boolean isAnnotationTargetAllowed(BlockScope scope, TypeBinding annotationType, Binding recipient) {
@@ -1091,10 +1103,10 @@ public abstract class Annotation extends Expression {
if ((metaTagBits & TagBits.AnnotationTargetMASK) == 0) {
return true;
}
- return isAnnotationTargetAllowed(recipient, scope, annotationType, recipient.kind(), metaTagBits);
+ return isAnnotationTargetAllowed(recipient, scope, annotationType, recipient.kind(), metaTagBits)==AnnotationTargetAllowed.YES;
}
- static boolean isAnnotationTargetAllowed(Annotation annotation, BlockScope scope, TypeBinding annotationType, int kind) {
+ static AnnotationTargetAllowed isAnnotationTargetAllowed(Annotation annotation, BlockScope scope, TypeBinding annotationType, int kind) {
long metaTagBits = annotationType.getAnnotationTagBits(); // could be forward reference
if ((metaTagBits & TagBits.AnnotationTargetMASK) == 0) {
@@ -1102,7 +1114,7 @@ public abstract class Annotation extends Expression {
if (kind == Binding.TYPE_PARAMETER || kind == Binding.TYPE_USE) {
scope.problemReporter().explitAnnotationTargetRequired(annotation);
}
- return true;
+ return AnnotationTargetAllowed.YES;
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=391201
@@ -1129,8 +1141,13 @@ public abstract class Annotation extends Expression {
// no need to check annotation usage if missing
return;
}
- if (! isAnnotationTargetAllowed(annotation, scope, annotationType, kind)) {
+ AnnotationTargetAllowed annotationTargetAllowed = isAnnotationTargetAllowed(annotation, scope, annotationType, kind);
+ if (annotationTargetAllowed != AnnotationTargetAllowed.YES) {
+ if(annotationTargetAllowed == AnnotationTargetAllowed.TYPE_ANNOTATION_ON_QUALIFIED_NAME) {
+ scope.problemReporter().typeAnnotationAtQualifiedName(annotation);
+ } else {
scope.problemReporter().disallowedTargetForAnnotation(annotation);
+ }
if (recipient instanceof TypeBinding)
((TypeBinding)recipient).tagBits &= ~tagBitsToRevert;
}
@@ -1199,7 +1216,7 @@ public abstract class Annotation extends Expression {
continue nextAnnotation;
} else {
if (annotation.hasNullBit(TypeIds.BitNonNullAnnotation|TypeIds.BitNullableAnnotation)) {
- scope.problemReporter().nullAnnotationUnsupportedLocation(annotation);
+ scope.problemReporter().nullAnnotationAtQualifyingType(annotation);
continue nextAnnotation;
}
}
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 13f06d9e1..bf50c2a28 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
@@ -360,6 +360,9 @@ public static void checkNeedForArgumentCasts(BlockScope scope, int operator, int
}
public boolean checkNPE(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo, int ttlForFieldCheck) {
+ if((this.resolvedType.tagBits & TagBits.AnnotationNonNull) != 0) {
+ return true;
+ }
checkNPEbyUnboxing(scope, flowContext, flowInfo);
return this.expression.checkNPE(scope, flowContext, flowInfo, ttlForFieldCheck);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
index 98e3208cb..04287d411 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
@@ -376,22 +376,28 @@ public void finalizeProblems() {
Constant cst = inits[iToken].constant;
if (cst != Constant.NotAConstant && cst.typeID() == TypeIds.T_JavaLangString) {
IrritantSet tokenIrritants = CompilerOptions.warningTokenToIrritants(cst.stringValue());
- if (tokenIrritants != null
- && !tokenIrritants.areAllSet() // no complaint against @SuppressWarnings("all")
- && options.isAnyEnabled(tokenIrritants) // if irritant is effectively enabled
- && (foundIrritants[iSuppress] == null || !foundIrritants[iSuppress].isAnySet(tokenIrritants))) { // if irritant had no matching problem
- if (unusedWarningTokenIsWarning) {
- int start = value.sourceStart, end = value.sourceEnd;
- nextSuppress: for (int jSuppress = iSuppress - 1; jSuppress >= 0; jSuppress--) {
- long position = this.suppressWarningScopePositions[jSuppress];
- int startSuppress = (int) (position >>> 32);
- int endSuppress = (int) position;
- if (start < startSuppress) continue nextSuppress;
- if (end > endSuppress) continue nextSuppress;
- if (this.suppressWarningIrritants[jSuppress].areAllSet()) break pairLoop; // suppress all?
+ if (tokenIrritants != null) {
+ if (!tokenIrritants.areAllSet() // no complaint against @SuppressWarnings("all")
+ && (foundIrritants[iSuppress] == null || !foundIrritants[iSuppress].isAnySet(tokenIrritants))) { // if irritant had no matching problem
+ if (unusedWarningTokenIsWarning) {
+ int start = value.sourceStart, end = value.sourceEnd;
+ nextSuppress: for (int jSuppress = iSuppress - 1; jSuppress >= 0; jSuppress--) {
+ long position = this.suppressWarningScopePositions[jSuppress];
+ int startSuppress = (int) (position >>> 32);
+ int endSuppress = (int) position;
+ if (start < startSuppress) continue nextSuppress;
+ if (end > endSuppress) continue nextSuppress;
+ if (this.suppressWarningIrritants[jSuppress].areAllSet()) break pairLoop; // suppress all?
+ }
+ }
+ int id = options.getIgnoredIrritant(tokenIrritants);
+ if (id > 0) {
+ String key = CompilerOptions.optionKeyFromIrritant(id);
+ this.scope.problemReporter().problemNotAnalysed(inits[iToken], key);
+ } else {
+ this.scope.problemReporter().unusedWarningToken(inits[iToken]);
}
}
- this.scope.problemReporter().unusedWarningToken(inits[iToken]);
}
}
}
@@ -400,22 +406,28 @@ public void finalizeProblems() {
Constant cst = value.constant;
if (cst != Constant.NotAConstant && cst.typeID() == T_JavaLangString) {
IrritantSet tokenIrritants = CompilerOptions.warningTokenToIrritants(cst.stringValue());
- if (tokenIrritants != null
- && !tokenIrritants.areAllSet() // no complaint against @SuppressWarnings("all")
- && options.isAnyEnabled(tokenIrritants) // if irritant is effectively enabled
- && (foundIrritants[iSuppress] == null || !foundIrritants[iSuppress].isAnySet(tokenIrritants))) { // if irritant had no matching problem
- if (unusedWarningTokenIsWarning) {
- int start = value.sourceStart, end = value.sourceEnd;
- nextSuppress: for (int jSuppress = iSuppress - 1; jSuppress >= 0; jSuppress--) {
- long position = this.suppressWarningScopePositions[jSuppress];
- int startSuppress = (int) (position >>> 32);
- int endSuppress = (int) position;
- if (start < startSuppress) continue nextSuppress;
- if (end > endSuppress) continue nextSuppress;
- if (this.suppressWarningIrritants[jSuppress].areAllSet()) break pairLoop; // suppress all?
+ if (tokenIrritants != null) {
+ if (!tokenIrritants.areAllSet() // no complaint against @SuppressWarnings("all")
+ && (foundIrritants[iSuppress] == null || !foundIrritants[iSuppress].isAnySet(tokenIrritants))) { // if irritant had no matching problem
+ if (unusedWarningTokenIsWarning) {
+ int start = value.sourceStart, end = value.sourceEnd;
+ nextSuppress: for (int jSuppress = iSuppress - 1; jSuppress >= 0; jSuppress--) {
+ long position = this.suppressWarningScopePositions[jSuppress];
+ int startSuppress = (int) (position >>> 32);
+ int endSuppress = (int) position;
+ if (start < startSuppress) continue nextSuppress;
+ if (end > endSuppress) continue nextSuppress;
+ if (this.suppressWarningIrritants[jSuppress].areAllSet()) break pairLoop; // suppress all?
+ }
+ }
+ int id = options.getIgnoredIrritant(tokenIrritants);
+ if (id > 0) {
+ String key = CompilerOptions.optionKeyFromIrritant(id);
+ this.scope.problemReporter().problemNotAnalysed(value, key);
+ } else {
+ this.scope.problemReporter().unusedWarningToken(value);
}
}
- this.scope.problemReporter().unusedWarningToken(value);
}
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
index d6a97919f..0b3762cd8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
@@ -867,8 +867,11 @@ public TypeBinding resolveType(BlockScope scope) {
// MW,JH,SH}
if (receiverCast && this.actualReceiverType != null) {
// due to change of declaring class with receiver type, only identity cast should be notified
- if (TypeBinding.equalsEquals(((CastExpression)this.receiver).expression.resolvedType, this.actualReceiverType)) {
- scope.problemReporter().unnecessaryCast((CastExpression)this.receiver);
+ TypeBinding resolvedType2 = ((CastExpression)this.receiver).expression.resolvedType;
+ if (TypeBinding.equalsEquals(resolvedType2, this.actualReceiverType)) {
+ if (!scope.environment().usesNullTypeAnnotations() || !NullAnnotationMatching.analyse(this.actualReceiverType, resolvedType2, -1).isAnyMismatch()) {
+ scope.problemReporter().unnecessaryCast((CastExpression) this.receiver);
+ }
}
}
// resolve type arguments (for generic constructor call)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java
index b7095550b..ae21034c6 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java
@@ -128,8 +128,15 @@ public class QualifiedTypeReference extends TypeReference {
for (int j = 0; j < i; j++) {
Annotation[] qualifierAnnot = this.annotations[j];
if (qualifierAnnot != null && qualifierAnnot.length > 0) {
- scope.problemReporter().misplacedTypeAnnotations(qualifierAnnot[0], qualifierAnnot[qualifierAnnot.length - 1]);
- this.annotations[j] = null;
+ if (j == 0) {
+ for (int k = 0; k < qualifierAnnot.length; k++) {
+ scope.problemReporter().typeAnnotationAtQualifiedName(qualifierAnnot[k]);
+ }
+ } else {
+ scope.problemReporter().misplacedTypeAnnotations(qualifierAnnot[0],
+ qualifierAnnot[qualifierAnnot.length - 1]);
+ this.annotations[j] = null;
+ }
}
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
index 004ddafbd..3a2af2c64 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
@@ -239,7 +239,7 @@ public class ReferenceExpression extends FunctionalExpression implements IPolyEx
}
// Process the lambda, taking care not to double report diagnostics. Don't expect any from resolve, Any from code generation should surface, but not those from flow analysis.
- implicitLambda.resolve(currentScope);
+ implicitLambda.resolveType(currentScope, true);
IErrorHandlingPolicy oldPolicy = currentScope.problemReporter().switchErrorHandlingPolicy(silentErrorHandlingPolicy);
try {
implicitLambda.analyseCode(currentScope,
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
index f7709c443..5cdf5b42e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
@@ -2797,7 +2797,7 @@ public void generateSyntheticBodyForDeserializeLambda(SyntheticMethodBinding met
invoke(Opcodes.OPC_invokevirtual, 1, 1,
ConstantPool.JavaLangInvokeSerializedLambdaConstantPoolName,
ConstantPool.GetCapturedArg, ConstantPool.GetCapturedArgSignature);
- checkcast(isLambda ? mb.declaringClass : ((ReferenceExpression)funcEx).receiverType);
+ checkcast(mb.declaringClass);
sig.append(mb.declaringClass.signature());
}
for (int p = 0, max = outerLocalVariables == null ? 0 : outerLocalVariables.length; p < max; p++) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
index c4add1b80..c65ac55d3 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
@@ -1622,6 +1622,22 @@ public class CompilerOptions {
return this.warningThreshold.isAnySet(irritants) || this.errorThreshold.isAnySet(irritants)
|| this.infoThreshold.isAnySet(irritants);
}
+ /*
+ * Just return the first irritant id that is set to 'ignored'.
+ */
+ public int getIgnoredIrritant(IrritantSet irritants) {
+ int[] bits = irritants.getBits();
+ for (int i = 0; i < IrritantSet.GROUP_MAX; i++) {
+ int bit = bits[i];
+ if (bit > 0) {
+ bit |= (i << IrritantSet.GROUP_SHIFT);
+ if (!(this.warningThreshold.isSet(bit) || this.errorThreshold.isSet(bit) || this.infoThreshold.isSet(bit))) {
+ return bit;
+ }
+ }
+ }
+ return 0;
+ }
protected void resetDefaults() {
// problem default severities defined on IrritantSet
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java
index 80db44d0e..6635519df 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java
@@ -335,7 +335,9 @@ public class IrritantSet {
int group = (singleGroupIrritants & GROUP_MASK) >> GROUP_SHIFT;
return (this.bits[group] & singleGroupIrritants) != 0;
}
-
+ public int[] getBits() {
+ return this.bits;
+ }
public IrritantSet set(int singleGroupIrritants) {
int group = (singleGroupIrritants & GROUP_MASK) >> GROUP_SHIFT;
this.bits[group] |= (singleGroupIrritants & ~GROUP_MASK); // erase the group bits
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
index 616c23709..68f82cfdf 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
@@ -2237,7 +2237,9 @@ private void scanTypeForNullDefaultAnnotation(IBinaryType binaryType, PackageBin
}
// no annotation found on the type or its enclosing types
// check the package-info for default annotation if not already done before
- if (packageBinding.defaultNullness == Binding.NO_NULL_DEFAULT && !isPackageInfo) {
+ if (packageBinding.defaultNullness == Binding.NO_NULL_DEFAULT && !isPackageInfo
+ && ((this.typeBits & (TypeIds.BitAnyNullAnnotation)) == 0))
+ {
// this will scan the annotations in package-info
ReferenceBinding packageInfo = packageBinding.getType(TypeConstants.PACKAGE_INFO_NAME);
if (packageInfo == null) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
index c6e2a0233..5d9ecc06e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
@@ -18,6 +18,8 @@
package org.eclipse.jdt.internal.compiler.lookup;
import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.compiler.IProblem;
@@ -94,6 +96,8 @@ public class CompilationUnitScope extends Scope {
boolean connectingHierarchy;
private ArrayList<Invocation> inferredInvocations;
+ /** Cache of interned inference variables. Access only via {@link InferenceVariable#get(TypeBinding, int, InvocationSite, Scope, ReferenceBinding)}. */
+ Map<InferenceVariable.InferenceVarKey, InferenceVariable> uniqueInferenceVariables = new HashMap<>();
//{ObjectTeams: when used as a baseimport scope, remember the original scope during this current lookup
public Scope originalScope;
// store parser for on-demand Dependencies.setup() lateron:
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java
index 8fd61f808..8dd65d1a4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java
@@ -304,7 +304,7 @@ public class ImplicitNullAnnotationVerifier {
this.environment.getNonNullAnnotationName());
break returnType;
} else {
- scope.problemReporter().cannotImplementIncompatibleNullness(currentMethod, inheritedMethod, useTypeAnnotations);
+ scope.problemReporter().cannotImplementIncompatibleNullness(scope.referenceContext(), currentMethod, inheritedMethod, useTypeAnnotations);
return;
}
}
@@ -320,7 +320,7 @@ public class ImplicitNullAnnotationVerifier {
scope.problemReporter().illegalReturnRedefinition(srcMethod, inheritedMethod,
this.environment.getNonNullAnnotationName());
else
- scope.problemReporter().cannotImplementIncompatibleNullness(currentMethod, inheritedMethod, useTypeAnnotations);
+ scope.problemReporter().cannotImplementIncompatibleNullness(scope.referenceContext(), currentMethod, inheritedMethod, useTypeAnnotations);
return;
}
}
@@ -412,7 +412,7 @@ public class ImplicitNullAnnotationVerifier {
inheritedMethod.declaringClass,
(inheritedNonNullNess == null) ? null : this.environment.getNullableAnnotationName());
} else {
- scope.problemReporter().cannotImplementIncompatibleNullness(currentMethod, inheritedMethod, false);
+ scope.problemReporter().cannotImplementIncompatibleNullness(scope.referenceContext(), currentMethod, inheritedMethod, false);
}
continue;
} else if (currentNonNullNess == null)
@@ -425,7 +425,7 @@ public class ImplicitNullAnnotationVerifier {
inheritedMethod.declaringClass,
annotationName);
} else {
- scope.problemReporter().cannotImplementIncompatibleNullness(currentMethod, inheritedMethod, false);
+ scope.problemReporter().cannotImplementIncompatibleNullness(scope.referenceContext(), currentMethod, inheritedMethod, false);
}
continue;
} else if (inheritedNonNullNess == Boolean.TRUE) {
@@ -450,7 +450,7 @@ public class ImplicitNullAnnotationVerifier {
if (currentArgument != null)
scope.problemReporter().illegalParameterRedefinition(currentArgument, inheritedMethod.declaringClass, inheritedParameter);
else
- scope.problemReporter().cannotImplementIncompatibleNullness(currentMethod, inheritedMethod, false);
+ scope.problemReporter().cannotImplementIncompatibleNullness(scope.referenceContext(), currentMethod, inheritedMethod, false);
}
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java
index 2bae65c59..ab2691c3c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java
@@ -131,7 +131,6 @@ public class InferenceContext18 {
/** The inference variables for which as solution is sought. */
InferenceVariable[] inferenceVariables;
- int nextVarId;
/** Constraints that have not yet been reduced and incorporated. */
ConstraintFormula[] initialConstraints;
@@ -165,43 +164,12 @@ public class InferenceContext18 {
/** Not per JLS: signal when current is ready to directly merge all bounds from inner. */
private boolean directlyAcceptingInnerBounds = false;
- // InferenceVariable interning:
- private InferenceVariable[] internedVariables;
-
- private InferenceVariable getInferenceVariable(TypeBinding typeParameter, int rank, InvocationSite site) {
- InferenceContext18 outermostContext = this.environment.currentInferenceContext;
- if (outermostContext == null)
- outermostContext = this;
- int i = 0;
- InferenceVariable[] interned = outermostContext.internedVariables;
- if (interned == null) {
- outermostContext.internedVariables = new InferenceVariable[10];
- } else {
- int len = interned.length;
- for (i = 0; i < len; i++) {
- InferenceVariable var = interned[i];
- if (var == null)
- break;
- if (var.typeParameter == typeParameter && var.rank == rank && isSameSite(var.site, site)) //$IDENTITY-COMPARISON$
- return var;
- }
- if (i >= len)
- System.arraycopy(interned, 0, outermostContext.internedVariables = new InferenceVariable[len+10], 0, len);
- }
- boolean differentContext = outermostContext != this;
- int id = differentContext ? Math.max(this.nextVarId, outermostContext.nextVarId) : this.nextVarId;
- this.nextVarId = id + 1;
- if (differentContext)
- outermostContext.nextVarId = this.nextVarId;
- return outermostContext.internedVariables[i] = new InferenceVariable(typeParameter, rank, id, site, this.environment, this.object);
- }
-
- boolean isSameSite(InvocationSite site1, InvocationSite site2) {
+ public static boolean isSameSite(InvocationSite site1, InvocationSite site2) {
if (site1 == site2)
return true;
if (site1 == null || site2 == null)
return false;
- if (site1.sourceStart() == site2.sourceStart() && site1.sourceEnd() == site2.sourceEnd() && site1.toString().equals(site2.toString()))
+ if (site1.sourceStart() == site2.sourceStart() && site1.sourceEnd() == site2.sourceEnd())
return true;
return false;
}
@@ -337,7 +305,7 @@ public class InferenceContext18 {
}
InferenceVariable[] newVariables = new InferenceVariable[len];
for (int i = 0; i < len; i++)
- newVariables[i] = getInferenceVariable(typeVariables[i], i, this.currentInvocation);
+ newVariables[i] = InferenceVariable.get(typeVariables[i], i, this.currentInvocation, this.scope, this.object);
addInferenceVariables(newVariables);
return newVariables;
}
@@ -365,7 +333,7 @@ public class InferenceContext18 {
newVariables[i] = (InferenceVariable) typeVariables[i]; // prevent double substitution of an already-substituted inferenceVariable
else
toAdd[numToAdd++] =
- newVariables[i] = getInferenceVariable(typeVariables[i], i, this.currentInvocation);
+ newVariables[i] = InferenceVariable.get(typeVariables[i], i, this.currentInvocation, this.scope, this.object);
}
if (numToAdd > 0) {
int start = 0;
@@ -1571,18 +1539,6 @@ public class InferenceContext18 {
if (!isSameSite(innerCtx.currentInvocation, this.currentInvocation))
innerCtx.outerContext = this;
this.usesUncheckedConversion = innerCtx.usesUncheckedConversion;
- for (InferenceVariable variable : this.inferenceVariables)
- if (!isInterned(variable))
- variable.updateSourceName(this.nextVarId++);
- }
-
- boolean isInterned(InferenceVariable iv) {
- if (this.internedVariables != null)
- for (int i = 0; i < this.internedVariables.length; i++) {
- if (this.internedVariables[i] == iv) //$IDENTITY-COMPARISON$
- return true;
- }
- return false;
}
public void resumeSuspendedInference(SuspendedInferenceRecord record) {
@@ -1595,8 +1551,6 @@ public class InferenceContext18 {
// move to back, add previous to front:
System.arraycopy(this.inferenceVariables, 0, this.inferenceVariables=new InferenceVariable[l1+l2], l2, l1);
System.arraycopy(record.inferenceVariables, 0, this.inferenceVariables, 0, l2);
- for (int i=l1;i<l1+l2;i++)
- this.inferenceVariables[i].updateSourceName(this.nextVarId++);
}
// replace invocation site & arguments:
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceSubstitution.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceSubstitution.java
index c76e3ba63..c7dd516e9 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceSubstitution.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceSubstitution.java
@@ -38,7 +38,7 @@ public class InferenceSubstitution extends Scope.Substitutor implements Substitu
public TypeBinding substitute(Substitution substitution, TypeBinding originalType) {
for (int i = 0; i < this.variables.length; i++) {
InferenceVariable variable = this.variables[i];
- if (this.site == variable.site && TypeBinding.equalsEquals(getP(i), originalType)) {
+ if (InferenceContext18.isSameSite(this.site, variable.site) && TypeBinding.equalsEquals(getP(i), originalType)) {
if (this.environment.globalOptions.isAnnotationBasedNullAnalysisEnabled && originalType.hasNullTypeAnnotations())
return this.environment.createAnnotatedType(variable.withoutToplevelNullAnnotation(), originalType.getTypeAnnotations());
return variable;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceVariable.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceVariable.java
index 87560640a..9b852a81f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceVariable.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceVariable.java
@@ -10,6 +10,7 @@
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
+import java.util.Map;
import java.util.Set;
import org.eclipse.jdt.core.compiler.CharOperation;
@@ -18,14 +19,74 @@ import org.eclipse.jdt.core.compiler.CharOperation;
* Implementation of 18.1.1 in JLS8
*/
public class InferenceVariable extends TypeVariableBinding {
+
+ /** Structured key for interning. */
+ static class InferenceVarKey {
+ /*@NonNull*/ TypeBinding typeParameter;
+ long position;
+ int rank;
+ InferenceVarKey(TypeBinding typeParameter, InvocationSite site, int rank) {
+ this.typeParameter = typeParameter;
+ this.position = ((long) site.sourceStart() << 32) + site.sourceEnd();
+ this.rank = rank;
+ }
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + (int) (this.position ^ (this.position >>> 32));
+ result = prime * result + this.rank;
+ result = prime * result + this.typeParameter.id;
+ return result;
+ }
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (!(obj instanceof InferenceVarKey))
+ return false;
+ InferenceVarKey other = (InferenceVarKey) obj;
+ if (this.position != other.position)
+ return false;
+ if (this.rank != other.rank)
+ return false;
+ if (TypeBinding.notEquals(this.typeParameter, other.typeParameter))
+ return false;
+ return true;
+ }
+ }
+
+ /**
+ * Create or retrieve the inference variable representing the given typeParameter.
+ * Inference variables are interned to avoid duplication due to lambda copying.
+ */
+ public static InferenceVariable get(TypeBinding typeParameter, int rank, InvocationSite site, Scope scope, ReferenceBinding object) {
+ Map<InferenceVarKey, InferenceVariable> uniqueInferenceVariables = scope.compilationUnitScope().uniqueInferenceVariables;
+ InferenceVariable var = null;
+ InferenceVarKey key = null;
+ if (site != null && typeParameter != null) {
+ key = new InferenceVarKey(typeParameter, site, rank);
+ var = uniqueInferenceVariables.get(key);
+ }
+ if (var == null) {
+ int newVarId = uniqueInferenceVariables.size();
+ var = new InferenceVariable(typeParameter, rank, newVarId, site, scope.environment(), object);
+ if (key != null)
+ uniqueInferenceVariables.put(key, var);
+ }
+ return var;
+ }
+
InvocationSite site;
TypeBinding typeParameter;
long nullHints; // one of TagBits.{AnnotationNonNull,AnnotationNullable} may steer inference into inferring nullness as well; set both bits to request avoidance.
private InferenceVariable prototype;
- int varId; // this is used for constructing a source name like T#0. NB: varId and sourceName are mutable, to be updated when two InferenceContext18 are integrated.
+ int varId; // this is used for constructing a source name like T#0.
- public InferenceVariable(TypeBinding typeParameter, int parameterRank, int iVarId, InvocationSite site, LookupEnvironment environment, ReferenceBinding object) {
+ private InferenceVariable(TypeBinding typeParameter, int parameterRank, int iVarId, InvocationSite site, LookupEnvironment environment, ReferenceBinding object) {
this(typeParameter, parameterRank, site,
CharOperation.concat(typeParameter.shortReadableName(), Integer.toString(iVarId).toCharArray(), '#'),
environment, object);
@@ -49,15 +110,7 @@ public class InferenceVariable extends TypeVariableBinding {
this.superclass = object;
this.prototype = this;
}
- void updateSourceName(int newId) {
- int hashPos = CharOperation.indexOf('#', this.sourceName);
- this.varId = newId;
- this.sourceName = CharOperation.concat(
- CharOperation.subarray(this.sourceName, 0, hashPos),
- Integer.toString(this.varId).toCharArray(),
- '#');
- }
-
+
@Override
public TypeBinding clone(TypeBinding enclosingType) {
InferenceVariable clone = new InferenceVariable(this.typeParameter, this.rank, this.site, this.sourceName, this.environment, this.superclass);
@@ -137,17 +190,18 @@ public class InferenceVariable extends TypeVariableBinding {
public int hashCode() {
int code = this.typeParameter.hashCode() + 17 * this.rank;
- if (this.site != null)
- return 31 * code + this.site.hashCode();
- else
- return code;
+ if (this.site != null) {
+ code = 31 * code + this.site.sourceStart();
+ code = 31 * code + this.site.sourceEnd();
+ }
+ return code;
}
public boolean equals(Object obj) {
if (!(obj instanceof InferenceVariable))
return false;
InferenceVariable other = (InferenceVariable) obj;
return this.rank == other.rank
- && this.site == other.site
+ && InferenceContext18.isSameSite(this.site, other.site)
&& TypeBinding.equalsEquals(this.typeParameter, other.typeParameter);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java
index 6979eaaa6..6cfe6aaca 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java
@@ -70,6 +70,12 @@ public class ParameterizedGenericMethodBinding extends ParameterizedMethodBindin
*/
public static MethodBinding computeCompatibleMethod(MethodBinding originalMethod, TypeBinding[] arguments, Scope scope, InvocationSite invocationSite)
{
+ LookupEnvironment environment = scope.environment();
+ if ((originalMethod.tagBits & TagBits.IsNullnessKnown) == 0) {
+ // ensure nullness of originalMethod is known (but we are not interested in reporting problems against originalMethod)
+ new ImplicitNullAnnotationVerifier(environment, environment.globalOptions.inheritNullAnnotations)
+ .checkImplicitNullAnnotations(originalMethod, null/*srcMethod*/, false, scope);
+ }
ParameterizedGenericMethodBinding methodSubstitute;
TypeVariableBinding[] typeVariables = originalMethod.typeVariables;
TypeBinding[] substitutes = invocationSite.genericTypeArguments();
@@ -90,7 +96,7 @@ public class ParameterizedGenericMethodBinding extends ParameterizedMethodBindin
// incompatible due to wrong arity
return new ProblemMethodBinding(originalMethod, originalMethod.selector, substitutes, ProblemReasons.TypeParameterArityMismatch);
}
- methodSubstitute = scope.environment().createParameterizedGenericMethod(originalMethod, substitutes);
+ methodSubstitute = environment.createParameterizedGenericMethod(originalMethod, substitutes);
break computeSubstitutes;
}
// perform type argument inference (15.12.2.7)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java
index af32c7801..7749b66f3 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java
@@ -251,6 +251,7 @@ public interface TypeIds {
final int BitNullableAnnotation = 64;
/** Bit for a type configured as a @NonNullByDefault annotation. */
final int BitNonNullByDefaultAnnotation = 128;
+ final int BitAnyNullAnnotation = BitNonNullAnnotation | BitNullableAnnotation | BitNonNullByDefaultAnnotation;
/**
* Set of type bits that should be inherited by any sub types.
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeSystem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeSystem.java
index ca9ebeb7e..85421e94f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeSystem.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeSystem.java
@@ -224,19 +224,7 @@ public class TypeSystem {
urb = (UnresolvedReferenceBinding) type;
ReferenceBinding resolvedType = urb.resolvedType;
if (resolvedType != null) {
- if(CharOperation.indexOf('$', type.sourceName()) > 0) {
- type = this.environment.convertToRawType(resolvedType, false);
- } else {
- type = resolvedType;
- }
- } else if (CharOperation.indexOf('$', type.sourceName()) > 0) {
- boolean mayTolerateMissingType = this.environment.mayTolerateMissingType;
- this.environment.mayTolerateMissingType = true;
- try {
- type = BinaryTypeBinding.resolveType(type, this.environment, true); // to ensure unique id assignment (when enclosing type is parameterized, inner type is also)
- } finally {
- this.environment.mayTolerateMissingType = mayTolerateMissingType;
- }
+ type = resolvedType;
}
}
try {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java
index 62d041dfb..48664dcc3 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java
@@ -1119,8 +1119,7 @@ public class TypeVariableBinding extends ReferenceBinding {
TypeBinding [] annotatedTypes = getDerivedTypesForDeferredInitialization();
for (int i = 0, length = annotatedTypes == null ? 0 : annotatedTypes.length; i < length; i++) {
TypeVariableBinding annotatedType = (TypeVariableBinding) annotatedTypes[i];
- if (annotatedType.firstBound == null)
- annotatedType.firstBound = firstBound;
+ annotatedType.firstBound = firstBound;
}
}
if (firstBound != null && firstBound.hasNullTypeAnnotations())
@@ -1136,8 +1135,7 @@ public class TypeVariableBinding extends ReferenceBinding {
TypeBinding [] annotatedTypes = getDerivedTypesForDeferredInitialization();
for (int i = 0, length = annotatedTypes == null ? 0 : annotatedTypes.length; i < length; i++) {
TypeVariableBinding annotatedType = (TypeVariableBinding) annotatedTypes[i];
- if (annotatedType.superclass == null)
- annotatedType.superclass = superclass;
+ annotatedType.superclass = superclass;
}
}
return superclass;
@@ -1151,8 +1149,7 @@ public class TypeVariableBinding extends ReferenceBinding {
TypeBinding [] annotatedTypes = getDerivedTypesForDeferredInitialization();
for (int i = 0, length = annotatedTypes == null ? 0 : annotatedTypes.length; i < length; i++) {
TypeVariableBinding annotatedType = (TypeVariableBinding) annotatedTypes[i];
- if (annotatedType.superInterfaces == null)
- annotatedType.superInterfaces = superInterfaces;
+ annotatedType.superInterfaces = superInterfaces;
}
}
return superInterfaces;
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 b2efb250c..88b5e90ad 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
@@ -1807,6 +1807,8 @@ public int computeSeverity(int problemID){
return ProblemSeverities.Warning;
case IProblem.IllegalUseOfUnderscoreAsAnIdentifier:
return this.underScoreIsLambdaParameter ? ProblemSeverities.Error : ProblemSeverities.Warning;
+ case IProblem.ProblemNotAnalysed:
+ return ProblemSeverities.Info; // Not configurable
}
int irritant = getIrritant(problemID);
if (irritant != 0) {
@@ -6438,6 +6440,19 @@ public void nullAnnotationUnsupportedLocation(Annotation annotation) {
severity,
annotation.sourceStart, annotation.sourceEnd);
}
+public void nullAnnotationAtQualifyingType(Annotation annotation) {
+ String[] arguments = new String[] {
+ String.valueOf(annotation.resolvedType.readableName())
+ };
+ String[] shortArguments = new String[] {
+ String.valueOf(annotation.resolvedType.shortReadableName())
+ };
+ int severity = ProblemSeverities.Error | ProblemSeverities.Fatal;
+ handle(IProblem.NullAnnotationAtQualifyingType,
+ arguments, shortArguments,
+ severity,
+ annotation.sourceStart, annotation.sourceEnd);
+}
public void nullAnnotationUnsupportedLocation(TypeReference type) {
int sourceEnd = type.sourceEnd;
if (type instanceof ParameterizedSingleTypeReference) {
@@ -9710,6 +9725,14 @@ public void unusedWarningToken(Expression token) {
token.sourceStart,
token.sourceEnd);
}
+public void problemNotAnalysed(Expression token, String optionKey) {
+ this.handle(
+ IProblem.ProblemNotAnalysed,
+ optionKey != null ? new String[]{optionKey} : new String[]{},
+ new String[] { token.constant.stringValue() },
+ token.sourceStart,
+ token.sourceEnd);
+}
public void useAssertAsAnIdentifier(int sourceStart, int sourceEnd) {
this.handle(
IProblem.UseAssertAsAnIdentifier,
@@ -14047,11 +14070,11 @@ public void expressionPotentialNullReference(ASTNode location) {
location.sourceEnd);
}
-public void cannotImplementIncompatibleNullness(MethodBinding currentMethod, MethodBinding inheritedMethod, boolean showReturn) {
+public void cannotImplementIncompatibleNullness(ReferenceContext context, MethodBinding currentMethod, MethodBinding inheritedMethod, boolean showReturn) {
int sourceStart = 0, sourceEnd = 0;
- if (this.referenceContext instanceof TypeDeclaration) {
- sourceStart = ((TypeDeclaration) this.referenceContext).sourceStart;
- sourceEnd = ((TypeDeclaration) this.referenceContext).sourceEnd;
+ if (context instanceof TypeDeclaration) {
+ sourceStart = ((TypeDeclaration) context).sourceStart;
+ sourceEnd = ((TypeDeclaration) context).sourceEnd;
}
String[] problemArguments = {
showReturn
@@ -14800,6 +14823,10 @@ public void disallowedTargetForContainerAnnotation(Annotation annotation, TypeBi
annotation.sourceStart,
annotation.sourceEnd);
}
+public void typeAnnotationAtQualifiedName(Annotation annotation) {
+ this.handle(IProblem.TypeAnnotationAtQualifiedName, NoArgument, NoArgument, annotation.sourceStart,
+ annotation.sourceEnd);
+ }
public void genericInferenceError(String message, InvocationSite invocationSite) {
genericInferenceProblem(message, invocationSite, ProblemSeverities.Error);
}
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 3beee8e97..98c08302e 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
@@ -861,9 +861,12 @@
1057 = strictfp is not permitted for abstract interface method {0}
1058 = Default methods are allowed only in interfaces.
1059 = Cannot infer type argument(s) for <{0}> {1}
+1060 = Illegally placed annotation: type annotations must directly precede the simple name of the type they are meant to affect (or the [] for arrays)
+1061 = The nullness annotation ''{0}'' is not applicable at this location, it must be placed directly before the nested type name.
1100 = Problem detected during type inference: {0}
-
+#1101 is already used up but deprecated
+1102 = At least one of the problems in category ''{0}'' is not analysed due to a compiler option being ignored
### ELABORATIONS
## Access restrictions
78592 = The type ''{1}'' is not API (restriction on classpath entry ''{0}'')
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
index 168465fc7..084f53ff9 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
@@ -116,6 +116,19 @@ import java.util.HashSet;
import java.util.Hashtable;
import java.util.Map;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IMarkerDelta;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
@@ -131,19 +144,6 @@ import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.resources.IMarkerDelta;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceChangeEvent;
-import org.eclipse.core.resources.IResourceChangeListener;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.resources.IWorkspaceRunnable;
-import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
@@ -154,10 +154,26 @@ import org.eclipse.jdt.core.search.TypeNameRequestor;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
-import org.eclipse.jdt.internal.core.*;
+import org.eclipse.jdt.internal.core.BatchOperation;
+import org.eclipse.jdt.internal.core.BufferManager;
+import org.eclipse.jdt.internal.core.ClasspathAccessRule;
+import org.eclipse.jdt.internal.core.ClasspathAttribute;
+import org.eclipse.jdt.internal.core.ClasspathEntry;
+import org.eclipse.jdt.internal.core.ClasspathValidation;
+import org.eclipse.jdt.internal.core.CreateTypeHierarchyOperation;
+import org.eclipse.jdt.internal.core.DefaultWorkingCopyOwner;
+import org.eclipse.jdt.internal.core.ExternalFoldersManager;
+import org.eclipse.jdt.internal.core.JavaCorePreferenceInitializer;
+import org.eclipse.jdt.internal.core.JavaModel;
+import org.eclipse.jdt.internal.core.JavaModelManager;
+import org.eclipse.jdt.internal.core.JavaProject;
+import org.eclipse.jdt.internal.core.Region;
+import org.eclipse.jdt.internal.core.SetContainerOperation;
+import org.eclipse.jdt.internal.core.SetVariablesOperation;
import org.eclipse.jdt.internal.core.builder.JavaBuilder;
import org.eclipse.jdt.internal.core.builder.State;
import org.eclipse.jdt.internal.core.nd.indexer.Indexer;
+import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
import org.eclipse.jdt.internal.core.util.MementoTokenizer;
import org.eclipse.jdt.internal.core.util.Messages;
import org.eclipse.jdt.internal.core.util.Util;
@@ -4162,7 +4178,7 @@ public final class JavaCore extends Plugin {
// if factory is null, default factory must be used
if (factory == null) factory = BufferManager.getDefaultBufferManager().getDefaultBufferFactory();
- return getWorkingCopies(BufferFactoryWrapper.create(factory));
+ return getWorkingCopies(org.eclipse.jdt.internal.core.BufferFactoryWrapper.create(factory));
}
/**
@@ -4227,14 +4243,14 @@ public final class JavaCore extends Plugin {
JavaModelManager manager = JavaModelManager.getJavaModelManager();
try {
SubMonitor subMonitor = mainMonitor.split(50).setWorkRemaining(100); // 50% of the time is spent in initializing containers and variables
- subMonitor.step(5); // give feedback to the user that something is happening
+ subMonitor.split(5); // give feedback to the user that something is happening
manager.batchContainerInitializationsProgress.initializeAfterLoadMonitor.set(subMonitor);
if (manager.forceBatchInitializations(true/*initAfterLoad*/)) { // if no other thread has started the batch container initializations
manager.getClasspathContainer(Path.EMPTY, null); // force the batch initialization
} else { // else wait for the batch initialization to finish
while (manager.batchContainerInitializations == JavaModelManager.BATCH_INITIALIZATION_IN_PROGRESS) {
subMonitor.subTask(manager.batchContainerInitializationsProgress.subTaskName);
- subMonitor.step(manager.batchContainerInitializationsProgress.getWorked());
+ subMonitor.split(manager.batchContainerInitializationsProgress.getWorked());
synchronized(manager) {
try {
manager.wait(100);
@@ -4310,38 +4326,8 @@ public final class JavaCore extends Plugin {
// dummy query for waiting until the indexes are ready
mainMonitor.subTask(Messages.javamodel_configuring_searchengine);
- SearchEngine engine = new SearchEngine();
- IJavaSearchScope scope = SearchEngine.createWorkspaceScope();
- try {
- engine.searchAllTypeNames(
- null,
- SearchPattern.R_EXACT_MATCH,
- "!@$#!@".toCharArray(), //$NON-NLS-1$
- SearchPattern.R_PATTERN_MATCH | SearchPattern.R_CASE_SENSITIVE,
- IJavaSearchConstants.CLASS,
- scope,
- new TypeNameRequestor() {
- public void acceptType(
- int modifiers,
- char[] packageName,
- char[] simpleTypeName,
- char[][] enclosingTypeNames,
- String path) {
- // no type to accept
- }
- },
- // will not activate index query caches if indexes are not ready, since it would take to long
- // to wait until indexes are fully rebuild
- IJavaSearchConstants.CANCEL_IF_NOT_READY_TO_SEARCH,
- mainMonitor.split(47) // 47% of the time is spent in the dummy search
- );
- } catch (JavaModelException e) {
- // /search failed: ignore
- } catch (OperationCanceledException e) {
- if (mainMonitor.isCanceled())
- throw e;
- // else indexes were not ready: catch the exception so that jars are still refreshed
- }
+ // 47% of the time is spent in the dummy search
+ updateLegacyIndex(mainMonitor.split(47));
// check if the build state version number has changed since last session
// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=98969)
@@ -4388,6 +4374,41 @@ public final class JavaCore extends Plugin {
}
}
+ private static void updateLegacyIndex(IProgressMonitor monitor) {
+ SearchEngine engine = new SearchEngine();
+ IJavaSearchScope scope = SearchEngine.createWorkspaceScope();
+ try {
+ engine.searchAllTypeNames(
+ null,
+ SearchPattern.R_EXACT_MATCH,
+ "!@$#!@".toCharArray(), //$NON-NLS-1$
+ SearchPattern.R_PATTERN_MATCH | SearchPattern.R_CASE_SENSITIVE,
+ IJavaSearchConstants.CLASS,
+ scope,
+ new TypeNameRequestor() {
+ public void acceptType(
+ int modifiers,
+ char[] packageName,
+ char[] simpleTypeName,
+ char[][] enclosingTypeNames,
+ String path) {
+ // no type to accept
+ }
+ },
+ // will not activate index query caches if indexes are not ready, since it would take to long
+ // to wait until indexes are fully rebuild
+ IJavaSearchConstants.CANCEL_IF_NOT_READY_TO_SEARCH,
+ monitor
+ );
+ } catch (JavaModelException e) {
+ // /search failed: ignore
+ } catch (OperationCanceledException e) {
+ if (monitor.isCanceled())
+ throw e;
+ // else indexes were not ready: catch the exception so that jars are still refreshed
+ }
+ }
+
/**
* Returns whether a given classpath variable is read-only or not.
*
@@ -5485,7 +5506,23 @@ public final class JavaCore extends Plugin {
JavaModelManager.getDeltaState().removePreResourceChangedListener(listener);
}
-
+ /**
+ * Deletes and rebuilds the java index.
+ *
+ * @param monitor a progress monitor, or <code>null</code> if progress
+ * reporting and cancellation are not desired
+ * @throws CoreException
+ * @since 3.13
+ */
+ public static void rebuildIndex(IProgressMonitor monitor) throws CoreException {
+ SubMonitor subMonitor = SubMonitor.convert(monitor, 10);
+ IndexManager manager = JavaModelManager.getIndexManager();
+ subMonitor.split(1);
+ manager.deleteIndexFiles();
+ manager.reset();
+ Indexer.getInstance().rebuildIndex(subMonitor.split(7));
+ updateLegacyIndex(subMonitor.split(2));
+ }
/**
* Runs the given action as an atomic Java model operation.
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/BatchImageBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/BatchImageBuilder.java
index 3097a43c2..26fb1c4c4 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/BatchImageBuilder.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/BatchImageBuilder.java
@@ -112,7 +112,11 @@ protected void cleanOutputFolders(boolean copyBack) throws CoreException {
}
);
}
- member.delete(IResource.FORCE, null);
+ try {
+ member.delete(IResource.FORCE, null);
+ } catch(CoreException e) {
+ Util.log(e, "Error occurred while deleting: " + member.getFullPath()); //$NON-NLS-1$
+ }
}
}
this.notifier.checkCancel();
@@ -139,7 +143,11 @@ protected void cleanOutputFolders(boolean copyBack) throws CoreException {
return false;
if (!resource.isDerived())
resource.setDerived(true, null);
- resource.delete(IResource.FORCE, null);
+ try {
+ resource.delete(IResource.FORCE, null);
+ } catch(CoreException e) {
+ Util.log(e, "Error occurred while deleting: " + resource.getFullPath()); //$NON-NLS-1$
+ }
}
return false;
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/Nd.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/Nd.java
index fb02f1319..71e492f3d 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/Nd.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/Nd.java
@@ -599,4 +599,8 @@ public class Nd {
public NdNodeTypeRegistry<NdNode> getTypeRegistry() {
return this.fNodeTypeRegistry;
}
+
+ public void clear(IProgressMonitor monitor) {
+ getDB().clear(getDefaultVersion());
+ }
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/indexer/Indexer.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/indexer/Indexer.java
index 318a736b3..7ca27245d 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/indexer/Indexer.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/indexer/Indexer.java
@@ -43,6 +43,7 @@ import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.jobs.JobGroup;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaElement;
@@ -115,10 +116,16 @@ public final class Indexer {
*/
private Set<Listener> listeners = Collections.newSetFromMap(new WeakHashMap<Listener, Boolean>());
+ private JobGroup group = new JobGroup(Messages.Indexer_updating_index_job_name, 1, 1);
+
private Job rescanJob = Job.create(Messages.Indexer_updating_index_job_name, monitor -> {
rescan(monitor);
});
+ private Job rebuildIndexJob = Job.create(Messages.Indexer_updating_index_job_name, monitor -> {
+ rebuildIndex(monitor);
+ });
+
public static interface Listener {
void consume(IndexerEvent event);
}
@@ -983,6 +990,10 @@ public final class Indexer {
public Indexer(Nd toPopulate, IWorkspaceRoot workspaceRoot) {
this.nd = toPopulate;
this.root = workspaceRoot;
+ this.rescanJob.setSystem(true);
+ this.rescanJob.setJobGroup(this.group);
+ this.rebuildIndexJob.setSystem(true);
+ this.rebuildIndexJob.setJobGroup(this.group);
}
public void rescanAll() {
@@ -1070,4 +1081,20 @@ public final class Indexer {
}
}
}
+
+ public void rebuildIndex(IProgressMonitor monitor) throws CoreException {
+ SubMonitor subMonitor = SubMonitor.convert(monitor, 100);
+
+ this.nd.acquireWriteLock(subMonitor.split(1));
+ try {
+ this.nd.clear(subMonitor.split(2));
+ } finally {
+ this.nd.releaseWriteLock();
+ }
+ rescan(subMonitor.split(98));
+ }
+
+ public void requestRebuildIndex() {
+ this.rebuildIndexJob.schedule();
+ }
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/JavaIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/JavaIndex.java
index 006aeff10..f0cbe1f53 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/JavaIndex.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/JavaIndex.java
@@ -293,8 +293,4 @@ public class JavaIndex {
registry.register(0x0200, NdWorkspaceLocation.type.getFactory());
return registry;
}
-
- public void rebuildIndex() {
- // TODO: delete and recreate the index
- }
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/model/BinaryTypeFactory.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/model/BinaryTypeFactory.java
index d6d3981a7..e9ce570ad 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/model/BinaryTypeFactory.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/model/BinaryTypeFactory.java
@@ -37,6 +37,7 @@ import org.eclipse.jdt.internal.core.PackageFragment;
import org.eclipse.jdt.internal.core.nd.IReader;
import org.eclipse.jdt.internal.core.nd.Nd;
import org.eclipse.jdt.internal.core.nd.db.IndexException;
+import org.eclipse.jdt.internal.core.nd.indexer.Indexer;
import org.eclipse.jdt.internal.core.nd.java.JavaIndex;
import org.eclipse.jdt.internal.core.nd.java.JavaNames;
import org.eclipse.jdt.internal.core.nd.java.NdResourceFile;
@@ -217,8 +218,8 @@ public class BinaryTypeFactory {
throw new JavaModelException(e);
}
} catch (IndexException e) {
- // Index corrupted. Rebuild it.
- index.rebuildIndex();
+ Package.log("Index corruption detected. Rebuilding index.", e); //$NON-NLS-1$
+ Indexer.getInstance().requestRebuildIndex();
}
}
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/model/Package.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/model/Package.java
new file mode 100644
index 000000000..1aad35428
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/model/Package.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2015, 2016 Google, Inc and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stefan Xenos (Google) - Initial implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.nd.java.model;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.core.JavaCore;
+
+/* package */ class Package {
+ public static String PLUGIN_ID = JavaCore.PLUGIN_ID;
+
+ public static void log(Throwable e) {
+ String msg = e.getMessage();
+ if (msg == null) {
+ log("Error", e); //$NON-NLS-1$
+ } else {
+ log("Error: " + msg, e); //$NON-NLS-1$
+ }
+ }
+
+ public static void log(String message, Throwable e) {
+ log(createStatus(message, e));
+ }
+
+ public static IStatus createStatus(String msg, Throwable e) {
+ return new Status(IStatus.ERROR, PLUGIN_ID, msg, e);
+ }
+
+ public static IStatus createStatus(String msg) {
+ return new Status(IStatus.ERROR, PLUGIN_ID, msg);
+ }
+
+ public static void logInfo(String message) {
+ log(new Status(IStatus.INFO, PLUGIN_ID, message));
+ }
+
+ public static void log(IStatus status) {
+ JavaCore.getPlugin().getLog().log(status);
+ }
+}
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 7ce53faf5..dc7269743 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
@@ -28,6 +28,7 @@ import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
@@ -164,7 +165,7 @@ public void cleanUpIndexes() {
if (count > 0)
removeIndexesState(locations);
}
- deleteIndexFiles(knownPaths);
+ deleteIndexFiles(knownPaths, null);
}
/**
* Compute the pre-built index location for a specified URL
@@ -212,17 +213,25 @@ public synchronized IndexLocation computeIndexLocation(IPath containerPath) {
}
return indexLocation;
}
-public void deleteIndexFiles() {
+/**
+ * Use {@link #deleteIndexFiles(IProgressMonitor)}
+ */
+public final void deleteIndexFiles() {
+ deleteIndexFiles(null);
+}
+public void deleteIndexFiles(IProgressMonitor monitor) {
if (DEBUG)
Util.verbose("Deleting index files"); //$NON-NLS-1$
this.savedIndexNamesFile.delete(); // forget saved indexes & delete each index file
- deleteIndexFiles(null);
+ deleteIndexFiles(null, monitor);
}
-private void deleteIndexFiles(SimpleSet pathsToKeep) {
+private void deleteIndexFiles(SimpleSet pathsToKeep, IProgressMonitor monitor) {
File[] indexesFiles = getSavedIndexesDirectory().listFiles();
if (indexesFiles == null) return;
+ SubMonitor subMonitor = SubMonitor.convert(monitor, indexesFiles.length);
for (int i = 0, l = indexesFiles.length; i < l; i++) {
+ subMonitor.split(1);
String fileName = indexesFiles[i].getAbsolutePath();
if (pathsToKeep != null && pathsToKeep.includes(new FileIndexLocation(indexesFiles[i]))) continue;
String suffix = ".index"; //$NON-NLS-1$
@@ -865,14 +874,16 @@ public void removeSourceFolderFromIndex(JavaProject javaProject, IPath sourceFol
/**
* Flush current state
*/
-public synchronized void reset() {
+public void reset() {
super.reset();
- if (this.indexes != null) {
- this.indexes = new SimpleLookupTable();
- this.indexStates = null;
+ synchronized (this) {
+ if (this.indexes != null) {
+ this.indexes = new SimpleLookupTable();
+ this.indexStates = null;
+ }
+ this.indexLocations = new SimpleLookupTable();
+ this.javaPluginLocation = null;
}
- this.indexLocations = new SimpleLookupTable();
- this.javaPluginLocation = null;
}
/**
* Resets the index for a given path.
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 71bc06163..7c07d0f47 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
@@ -297,22 +297,29 @@ public abstract class JobManager implements Runnable {
/**
* Flush current state
*/
- public synchronized void reset() {
+ public void reset() {
if (VERBOSE)
Util.verbose("Reset"); //$NON-NLS-1$
- if (this.processingThread != null) {
+ Thread thread;
+ synchronized (this) {
+ thread = this.processingThread;
+ }
+
+ if (thread != null) {
discardJobs(null); // discard all jobs
} else {
- /* initiate background processing */
- this.processingThread = new Thread(this, processName());
- this.processingThread.setDaemon(true);
- // less prioritary by default, priority is raised if clients are actively waiting on it
- this.processingThread.setPriority(Thread.NORM_PRIORITY-1);
- // https://bugs.eclipse.org/bugs/show_bug.cgi?id=296343
- // set the context loader to avoid leaking the current context loader
- this.processingThread.setContextClassLoader(this.getClass().getClassLoader());
- this.processingThread.start();
+ synchronized (this) {
+ /* initiate background processing */
+ this.processingThread = new Thread(this, processName());
+ this.processingThread.setDaemon(true);
+ // less prioritary by default, priority is raised if clients are actively waiting on it
+ this.processingThread.setPriority(Thread.NORM_PRIORITY-1);
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=296343
+ // set the context loader to avoid leaking the current context loader
+ this.processingThread.setContextClassLoader(this.getClass().getClassLoader());
+ this.processingThread.start();
+ }
}
}
/**

Back to the top