Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Herrmann2014-11-04 19:35:01 +0000
committerStephan Herrmann2014-11-09 23:21:14 +0000
commit03fc98ba5195315789db96e8c029652af3ad1833 (patch)
tree1a33baa0d0df8e5bfa68c4f85de4d7f0e66dab94
parent66658d3b43d13700f7c1f7016d44677bff9c371d (diff)
downloadorg.eclipse.objectteams-03fc98ba5195315789db96e8c029652af3ad1833.tar.gz
org.eclipse.objectteams-03fc98ba5195315789db96e8c029652af3ad1833.tar.xz
org.eclipse.objectteams-03fc98ba5195315789db96e8c029652af3ad1833.zip
Update jdt.core & tests to I20140918-0330 (4.5M2)
-rw-r--r--org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF3
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/CompletionParserTest18.java427
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/DietRecoveryTest.java12
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/SelectionParserTest18.java46
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/StatementRecoveryTest.java64
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractNullAnnotationTest.java12
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java83
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ClassFileReaderTest_1_5.java4
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java4
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExternalizeStringLiteralsTest.java26
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ForeachStatementTest.java61
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java128
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java89
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_7.java39
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java53
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InterfaceMethodsTest.java141
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java224
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java35
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java593
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java165
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java368
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ScannerTest.java30
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SerializableLambdaTest.java97
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/eval/DebugEvaluationTest.java11
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/AbstractCompilerTest.java6
-rw-r--r--org.eclipse.jdt.core.tests.compiler/test.xml7
-rw-r--r--org.eclipse.jdt.core.tests.compiler/workspace/Bug422832ClassFile/aspose.pdf.jarbin0 -> 513 bytes
-rw-r--r--org.eclipse.jdt.core.tests.model/JCL/jclMin1.8.jarbin13752 -> 13880 bytes
-rw-r--r--org.eclipse.jdt.core.tests.model/JCL/jclMin1.8src.zipbin8414 -> 9805 bytes
-rw-r--r--org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF3
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java45
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST3_2.java6
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST4_2.java6
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST8_2.java28
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java29
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests18.java690
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/HierarchyOnWorkingCopiesTests.java43
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java102
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests18.java155
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/TypeResolveTests.java3
-rw-r--r--org.eclipse.jdt.core.tests.model/test.xml6
-rw-r--r--org.eclipse.jdt.core.tests.model/workspace/Converter/src/testBug443942/org.eclipse.swt.internal.gtk/A.java4
-rw-r--r--org.eclipse.jdt.core/.settings/.api_filters223
-rw-r--r--org.eclipse.jdt.core/META-INF/MANIFEST.MF8
-rw-r--r--org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/BatchCompilerRequestor.java48
-rw-r--r--org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java22
-rw-r--r--org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java15
-rw-r--r--org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionNodeDetector.java8
-rw-r--r--org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java16
-rw-r--r--org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java61
-rw-r--r--org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnReferenceExpressionName.java5
-rw-r--r--org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java14
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java3
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java33
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java6
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java9
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java5
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java5
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java56
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java5
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java3
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java84
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java42
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java14
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/StringLiteral.java32
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java4
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Wildcard.java3
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java4
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java5
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java7
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/InitializationFlowContext.java5
-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/AnnotatableTypeSystem.java71
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java28
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypeBinding.java2
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java26
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java11
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java6
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java46
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java5
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java13
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java37
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/IntersectionCastTypeBinding.java14
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java2
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java3
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java14
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NullTypeBinding.java2
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java58
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java35
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/RawTypeBinding.java24
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java21
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java111
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java22
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java16
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBindingVisitor.java8
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeSystem.java174
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java25
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/VoidTypeBinding.java2
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java27
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java52
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredBlock.java3
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredElement.java5
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredField.java9
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredLocalVariable.java2
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveryScanner.java10
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.java2
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/DiagnoseParser.java31
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemHandler.java9
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java33
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties1
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java50
-rw-r--r--org.eclipse.jdt.core/component.xml4
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CharacterLiteral.java56
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IDocElement.java23
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IExtendedModifier.java6
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/StringLiteral.java53
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java4
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java1
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java21
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java6
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java46
121 files changed, 4675 insertions, 1152 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF
index 4401b9aa9..4bde9b129 100644
--- a/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF
@@ -20,7 +20,8 @@ Require-Bundle: org.junit;bundle-version="3.8.1",
org.eclipse.core.runtime;bundle-version="[3.2.0,4.0.0)",
org.eclipse.test.performance;bundle-version="[3.10.0,4.0.0)",
org.eclipse.core.resources;bundle-version="[3.2.0,4.0.0)",
- org.eclipse.jdt.annotation;bundle-version="[1.1.0,3.0.0)",
+ org.eclipse.jdt.annotation;bundle-version="[1.1.0,2.0.0)";resolution:=optional,
+ org.eclipse.jdt.annotation;bundle-version="[2.0.0,3.0.0)";resolution:=optional,
org.eclipse.objectteams.otdt
Bundle-RequiredExecutionEnvironment: J2SE-1.4
Eclipse-BundleShape: dir
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/CompletionParserTest18.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/CompletionParserTest18.java
index 39ad67b0b..bba49fa8b 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/CompletionParserTest18.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/CompletionParserTest18.java
@@ -99,7 +99,7 @@ public void test0002() {
int cursorLocation = string.lastIndexOf(completeBehind) + completeBehind.length() - 1;
String expectedCompletionNodeToString = "<CompleteOnName:fi>";
- String expectedParentNodeToString = "System.out.print(<CompleteOnName:fi>)";
+ String expectedParentNodeToString = "<NONE>";
String completionIdentifier = "fi";
String expectedReplacedSource = "fi";
String expectedUnitDisplayString =
@@ -813,7 +813,7 @@ public void testBrokenMethodCall() { // verify that completion works when the c
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=424080, [1.8][completion] Workbench hanging on code completion with lambda expression containing anonymous class
public void test424080() {
- String string =
+String string =
"interface FI {\n" +
" public static int val = 5;\n" +
" default int run (String x) { return 1;};\n" +
@@ -826,7 +826,7 @@ public void test424080() {
String completeBehind = "val";
int cursorLocation = string.lastIndexOf(completeBehind) + completeBehind.length() - 1;
- String expectedCompletionNodeToString = "<CompleteOnName:val>";
+ String expectedCompletionNodeToString = "<NONE>";
String expectedParentNodeToString = "<NONE>";
String completionIdentifier = "val";
String expectedReplacedSource = "val";
@@ -840,7 +840,7 @@ public void test424080() {
" public int run(int x);\n" +
"}\n" +
"public class X {\n" +
- " FI fi = <CompleteOnName:val>;\n" +
+ " FI fi;\n" +
" public X() {\n" +
" }\n" +
"}\n";
@@ -1098,6 +1098,8 @@ public void test427463() {
" };\n" +
" Test() {\n" +
" }\n" +
+ " private void test() throws Exception {\n" +
+ " }\n" +
"}\n";
checkMethodParse(
@@ -1469,7 +1471,7 @@ public void test428735e() { // field
int cursorLocation = string.lastIndexOf(completeBehind) + completeBehind.length() - 1;
String expectedCompletionNodeToString = "<CompleteOnName:y.get>";
- String expectedParentNodeToString = "x.getLastName().compareTo(<CompleteOnName:y.get>)";
+ String expectedParentNodeToString = "<NONE>";
String completionIdentifier = "get";
String expectedReplacedSource = "y.get";
String expectedUnitDisplayString =
@@ -1651,4 +1653,419 @@ public void test402081() { // initializer block
expectedReplacedSource,
"diet ast");
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430656, [1.8][content assist] Content assist does not work for method reference argument
+public void test430656() {
+ String string =
+ "import java.util.ArrayList;\n" +
+ "import java.util.Collections;\n" +
+ "import java.util.Comparator;\n" +
+ "import java.util.List;\n" +
+ "public class X {\n" +
+ " public void bar() {\n" +
+ " List<Person> people = new ArrayList<>();\n" +
+ " Collections.sort(people, Comparator.comparing(Person::get)); \n" +
+ " }\n" +
+ "}\n" +
+ "class Person {\n" +
+ " String getLastName() {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n";
+
+ String completeBehind = "get";
+ int cursorLocation = string.indexOf(completeBehind) + completeBehind.length() - 1;
+
+ String expectedCompletionNodeToString = "<CompletionOnReferenceExpressionName:Person::get>";
+ String expectedParentNodeToString = "Comparator.comparing(<CompletionOnReferenceExpressionName:Person::get>)";
+ String completionIdentifier = "get";
+ String expectedReplacedSource = "Person::get";
+ String expectedUnitDisplayString =
+ "import java.util.ArrayList;\n" +
+ "import java.util.Collections;\n" +
+ "import java.util.Comparator;\n" +
+ "import java.util.List;\n" +
+ "public class X {\n" +
+ " public X() {\n" +
+ " }\n" +
+ " public void bar() {\n" +
+ " List<Person> people;\n" +
+ " Comparator.comparing(<CompletionOnReferenceExpressionName:Person::get>);\n" +
+ " }\n" +
+ "}\n" +
+ "class Person {\n" +
+ " Person() {\n" +
+ " }\n" +
+ " String getLastName() {\n" +
+ " }\n" +
+ "}\n";
+
+ checkMethodParse(
+ string.toCharArray(),
+ cursorLocation,
+ expectedCompletionNodeToString,
+ expectedParentNodeToString,
+ expectedUnitDisplayString,
+ completionIdentifier,
+ expectedReplacedSource,
+ "diet ast");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=438952, [1.8][content assist] StackOverflowError at org.eclipse.jdt.internal.compiler.ast.SingleTypeReference.traverse(SingleTypeReference.java:108)
+// FIXME: Recovered parse tree isn't quite correct, but is harmless.
+public void test438952() {
+ String string =
+ "import java.util.function.Supplier;\n" +
+ "class SO {\n" +
+ " {\n" +
+ " int\n" +
+ " Supplier<SO> m6 = SO::new;\n" +
+ " m6 = () -> new SO() {\n" +
+ " void test() {\n" +
+ " /* here */ \n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ "}\n";
+
+ String completeBehind = "/* here */";
+ int cursorLocation = string.indexOf(completeBehind) + completeBehind.length() - 1;
+
+ String expectedCompletionNodeToString = "<CompleteOnName:>";
+ String expectedParentNodeToString = "<NONE>";
+ String completionIdentifier = "";
+ String expectedReplacedSource = "";
+ String expectedUnitDisplayString =
+ "import java.util.function.Supplier;\n" +
+ "class SO {\n" +
+ " {\n" +
+ " int Supplier;\n" +
+ " new SO() {\n" +
+ " {\n" +
+ " }\n" +
+ " void test() {\n" +
+ " <CompleteOnName:>;\n" +
+ " }\n" +
+ " void test() {\n" +
+ " <CompleteOnName:>;\n" +
+ " }\n" +
+ " };\n" +
+ " m6 = () -> new SO() {\n" +
+ " {\n" +
+ " }\n" +
+ " void test() {\n" +
+ " <CompleteOnName:>;\n" +
+ " }\n" +
+ " void test() {\n" +
+ " <CompleteOnName:>;\n" +
+ " }\n" +
+ "};\n" +
+ " }\n" +
+ " SO() {\n" +
+ " }\n" +
+ "}\n";
+
+ checkMethodParse(
+ string.toCharArray(),
+ cursorLocation,
+ expectedCompletionNodeToString,
+ expectedParentNodeToString,
+ expectedUnitDisplayString,
+ completionIdentifier,
+ expectedReplacedSource,
+ "diet ast");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=435219, [1.8][content assist] No proposals for some closure cases
+public void test435219() {
+ String string =
+ "import java.util.Arrays;\n" +
+ "import java.util.List;\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " List<Integer> costBeforeTax = Arrays.asList(100, 200, 300);\n" +
+ " double bill = costBeforeTax.stream().map((cost) -> cost + 0.19 * cost)\n" +
+ " // .y .n .y\n" +
+ " .reduce((sum, cost) -> sum.doubleValue() + cost.dou\n" +
+ " }\n" +
+ "}\n";
+
+ String completeBehind = "dou";
+ int cursorLocation = string.lastIndexOf(completeBehind) + completeBehind.length() - 1;
+
+ String expectedCompletionNodeToString = "<CompleteOnName:cost.dou>";
+ String expectedParentNodeToString = "(sum.doubleValue() + <CompleteOnName:cost.dou>)";
+ String completionIdentifier = "dou";
+ String expectedReplacedSource = "cost.dou";
+ String expectedUnitDisplayString =
+ "import java.util.Arrays;\n" +
+ "import java.util.List;\n" +
+ "public class X {\n" +
+ " public X() {\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " List<Integer> costBeforeTax;\n" +
+ " double bill = costBeforeTax.stream().map((<no type> cost) -> (cost + (0.19 * cost))).reduce((<no type> sum, <no type> cost) -> (sum.doubleValue() + <CompleteOnName:cost.dou>));\n" +
+ " }\n" +
+ "}\n";
+
+ checkMethodParse(
+ string.toCharArray(),
+ cursorLocation,
+ expectedCompletionNodeToString,
+ expectedParentNodeToString,
+ expectedUnitDisplayString,
+ completionIdentifier,
+ expectedReplacedSource,
+ "diet ast");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=435682, [1.8] content assist not working inside lambda expression
+public void test435682() {
+ String string =
+ "import java.util.Arrays;\n" +
+ "import java.util.List;\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " List<String> words = Arrays.asList(\"hi\", \"hello\", \"hola\", \"bye\", \"goodbye\");\n" +
+ " List<String> list1 = words.stream().map(so -> so.).collect(Collectors.toList());\n" +
+ " }\n" +
+ "}\n";
+
+ String completeBehind = "so.";
+ int cursorLocation = string.lastIndexOf(completeBehind) + completeBehind.length() - 1;
+
+ String expectedCompletionNodeToString = "<CompleteOnName:so.>";
+ String expectedParentNodeToString = "<NONE>";
+ String completionIdentifier = "";
+ String expectedReplacedSource = "so.";
+ String expectedUnitDisplayString =
+ "import java.util.Arrays;\n" +
+ "import java.util.List;\n" +
+ "public class X {\n" +
+ " public X() {\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " List<String> words;\n" +
+ " List<String> list1 = words.stream().map((<no type> so) -> <CompleteOnName:so.>).collect(Collectors.toList());\n" +
+ " }\n" +
+ "}\n";
+
+ checkMethodParse(
+ string.toCharArray(),
+ cursorLocation,
+ expectedCompletionNodeToString,
+ expectedParentNodeToString,
+ expectedUnitDisplayString,
+ completionIdentifier,
+ expectedReplacedSource,
+ "diet ast");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430667, [1.8][content assist] no proposals around lambda as a field
+public void test430667() {
+ String string =
+ "interface D_FI {\n" +
+ " void print(String value, int n);\n" +
+ "}\n" +
+ "class D_DemoRefactorings {\n" +
+ " \n" +
+ " D_FI fi1= (String value, int n) -> {\n" +
+ " for (int j = 0; j < n; j++) {\n" +
+ " System.out.println(value); \n" +
+ " }\n" +
+ " };\n" +
+ " D_F\n" +
+ "}\n";
+
+ String completeBehind = "D_F";
+ int cursorLocation = string.lastIndexOf(completeBehind) + completeBehind.length() - 1;
+
+ String expectedCompletionNodeToString = "<CompleteOnType:D_F>";
+ String expectedParentNodeToString = "<NONE>";
+ String completionIdentifier = "D_F";
+ String expectedReplacedSource = "D_F";
+ String expectedUnitDisplayString =
+ "interface D_FI {\n" +
+ " void print(String value, int n);\n" +
+ "}\n" +
+ "class D_DemoRefactorings {\n" +
+ " D_FI fi1;\n" +
+ " <CompleteOnType:D_F>;\n" +
+ " D_DemoRefactorings() {\n" +
+ " }\n" +
+ "}\n";
+
+ checkMethodParse(
+ string.toCharArray(),
+ cursorLocation,
+ expectedCompletionNodeToString,
+ expectedParentNodeToString,
+ expectedUnitDisplayString,
+ completionIdentifier,
+ expectedReplacedSource,
+ "diet ast");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430667, [1.8][content assist] no proposals around lambda as a field
+public void test430667a() {
+ String string =
+ "class D_DemoRefactorings {\n" +
+ " \n" +
+ " D_FI fi1= (String value, int n) -> {\n" +
+ " for (int j = 0; j < n; j++) {\n" +
+ " System.out.println(value); \n" +
+ " }\n" +
+ " };\n" +
+ " /*HERE*/D_F\n" +
+ "}\n" +
+ "interface D_FI {\n" +
+ " void print(String value, int n);\n" +
+ "}\n";
+
+
+ String completeBehind = "/*HERE*/D_F";
+ int cursorLocation = string.lastIndexOf(completeBehind) + completeBehind.length() - 1;
+
+ String expectedCompletionNodeToString = "<CompleteOnType:D_F>";
+ String expectedParentNodeToString = "<NONE>";
+ String completionIdentifier = "D_F";
+ String expectedReplacedSource = "D_F";
+ String expectedUnitDisplayString =
+ "class D_DemoRefactorings {\n" +
+ " D_FI fi1;\n" +
+ " <CompleteOnType:D_F>;\n" +
+ " D_DemoRefactorings() {\n" +
+ " }\n" +
+ "}\n" +
+ "interface D_FI {\n" +
+ " void print(String value, int n);\n" +
+ "}\n";
+
+ checkMethodParse(
+ string.toCharArray(),
+ cursorLocation,
+ expectedCompletionNodeToString,
+ expectedParentNodeToString,
+ expectedUnitDisplayString,
+ completionIdentifier,
+ expectedReplacedSource,
+ "diet ast");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430667, [1.8][content assist] no proposals around lambda as a field
+public void test430667b() {
+ String string =
+ "public class D_DemoRefactorings {\n" +
+ " D_F\n" +
+ " D_FI fi1= (String value, int n) -> {\n" +
+ " for (int j = 0; j < n; j++) {\n" +
+ " System.out.println(value); \n" +
+ " }\n" +
+ " };\n" +
+ "}\n" +
+ "interface D_FI {\n" +
+ " void print(String value, int n);\n" +
+ "}\n";
+
+ String completeBehind = "D_F";
+ int cursorLocation = string.indexOf(completeBehind) + completeBehind.length() - 1;
+
+ String expectedCompletionNodeToString = "<CompleteOnType:D_F>;";
+ String expectedParentNodeToString = "<NONE>";
+ String completionIdentifier = "D_F";
+ String expectedReplacedSource = "D_F";
+ String expectedUnitDisplayString =
+ "public class D_DemoRefactorings {\n" +
+ " <CompleteOnType:D_F>;\n" +
+ " D_FI fi1;\n" +
+ " public D_DemoRefactorings() {\n" +
+ " }\n" +
+ "}\n" +
+ "interface D_FI {\n" +
+ " void print(String value, int n);\n" +
+ "}\n";
+
+ checkMethodParse(
+ string.toCharArray(),
+ cursorLocation,
+ expectedCompletionNodeToString,
+ expectedParentNodeToString,
+ expectedUnitDisplayString,
+ completionIdentifier,
+ expectedReplacedSource,
+ "diet ast");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430667, [1.8][content assist] no proposals around lambda as a field
+public void test430667c() {
+ String string =
+ "public interface Foo {\n" +
+ " int run(int s1, int s2);\n" +
+ "}\n" +
+ "interface B {\n" +
+ " static Foo f = (int x5, int x2) -> anot\n" +
+ " static int another = 3;\n" +
+ " static int two () { return 2; }\n" +
+ "}";
+
+ String completeBehind = "(int x5, int x2) -> anot";
+ int cursorLocation = string.indexOf(completeBehind) + completeBehind.length() - 1;
+
+ String expectedCompletionNodeToString = "<CompleteOnName:anot>";
+ String expectedParentNodeToString = "<NONE>";
+ String completionIdentifier = "anot";
+ String expectedReplacedSource = "anot";
+ String expectedUnitDisplayString =
+ "public interface Foo {\n" +
+ " int run(int s1, int s2);\n" +
+ "}\n" +
+ "interface B {\n" +
+ " static Foo f = (int x5, int x2) -> <CompleteOnName:anot>;\n" +
+ " static int another;\n" +
+ " <clinit>() {\n" +
+ " }\n" +
+ " static int two() {\n" +
+ " }\n" +
+ "}\n";
+
+ checkMethodParse(
+ string.toCharArray(),
+ cursorLocation,
+ expectedCompletionNodeToString,
+ expectedParentNodeToString,
+ expectedUnitDisplayString,
+ completionIdentifier,
+ expectedReplacedSource,
+ "diet ast");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430667, [1.8][content assist] no proposals around lambda as a field
+public void test430667d() {
+ String string =
+ "import java.util.Arrays;\n" +
+ "import java.util.List;\n" +
+ "public class X {\n" +
+ " List<Integer> list = Arrays.asList(1, 2, 3);\n" +
+ " Object o = list.stream().map((x) -> x * x.hashCode()).forEach(System.out::pri);\n" +
+ "}\n";
+
+ String completeBehind = "pri";
+ int cursorLocation = string.indexOf(completeBehind) + completeBehind.length() - 1;
+
+ String expectedCompletionNodeToString = "<CompletionOnReferenceExpressionName:System.out::pri>";
+ String expectedParentNodeToString = "list.stream().map((<no type> x) -> (x * x.hashCode())).forEach(<CompletionOnReferenceExpressionName:System.out::pri>)";
+ String completionIdentifier = "pri";
+ String expectedReplacedSource = "System.out::pri";
+ String expectedUnitDisplayString =
+ "import java.util.Arrays;\n" +
+ "import java.util.List;\n" +
+ "public class X {\n" +
+ " List<Integer> list;\n" +
+ " Object o = list.stream().map((<no type> x) -> (x * x.hashCode())).forEach(<CompletionOnReferenceExpressionName:System.out::pri>);\n" +
+ " public X() {\n" +
+ " }\n" +
+ "}\n";
+
+ checkMethodParse(
+ string.toCharArray(),
+ cursorLocation,
+ expectedCompletionNodeToString,
+ expectedParentNodeToString,
+ expectedUnitDisplayString,
+ completionIdentifier,
+ expectedReplacedSource,
+ "diet ast");
+}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/DietRecoveryTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/DietRecoveryTest.java
index 12f593bee..0d1d42754 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/DietRecoveryTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/DietRecoveryTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 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
@@ -4646,14 +4646,14 @@ public void test75() {
" super();\n" +
" }\n" +
" int hello() {\n" +
- " fo $missing$;\n" +
+ " fo = $missing$;\n" +
" }\n" +
" int world() {\n" +
" }\n" +
" void foo() {\n" +
" }\n" +
" }\n" +
- " ba $missing$;\n" +
+ " ba = $missing$;\n" +
" }\n" +
"}\n";
@@ -4848,7 +4848,7 @@ public void test77() {
" else\n" +
" if ((depth > 1))\n" +
" {\n" +
- " sol $missing$;\n" +
+ " sol = $missing$;\n" +
" }\n" +
" else\n" +
" ;\n" +
@@ -6003,7 +6003,7 @@ public void test99() {
" restricts breakpoint;\n" +
" given thread;\n" +
" any other;\n" +
- " specified $missing$;\n" +
+ " specified = $missing$;\n" +
" }\n" +
" public void removeThreadFilter(IJavaThread thread) {\n" +
" removes the;\n" +
@@ -6014,7 +6014,7 @@ public void test99() {
" request as;\n" +
" does not;\n" +
" the removal;\n" +
- " thread $missing$;\n" +
+ " thread = $missing$;\n" +
:giro */
// SH}
" }\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/SelectionParserTest18.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/SelectionParserTest18.java
index f0bf1d2ab..9166a00cf 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/SelectionParserTest18.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/SelectionParserTest18.java
@@ -130,4 +130,50 @@ public void test424110a() throws JavaModelException {
expectedReplacedSource,
testName);
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430572, [1.8] CCE on hovering over 'super' in lambda expression
+public void test430572() throws JavaModelException {
+ String string =
+ "@FunctionalInterface\n" +
+ "interface FI {\n" +
+ " default int getID() {\n" +
+ " return 11;\n" +
+ " }\n" +
+ " void print();\n" +
+ "}\n" +
+ "class T {\n" +
+ " FI f2 = () -> System.out.println(super.toString());\n" +
+ "}\n";
+
+ String selection = "super";
+
+ String expectedCompletionNodeToString = "<SelectOnSuper:super>";
+
+ String completionIdentifier = "super";
+ String expectedUnitDisplayString =
+ "@FunctionalInterface interface FI {\n" +
+ " default int getID() {\n" +
+ " }\n" +
+ " void print();\n" +
+ "}\n" +
+ "class T {\n" +
+ " FI f2 = () -> System.out.println(<SelectOnSuper:super>.toString());\n" +
+ " T() {\n" +
+ " }\n" +
+ "}\n";
+ String expectedReplacedSource = "super";
+ String testName = "<select>";
+
+ int selectionStart = string.indexOf(selection);
+ int selectionEnd = selectionStart + selection.length() - 1;
+
+ this.checkDietParse(
+ string.toCharArray(),
+ selectionStart,
+ selectionEnd,
+ expectedCompletionNodeToString,
+ expectedUnitDisplayString,
+ completionIdentifier,
+ expectedReplacedSource,
+ testName);
+}
} \ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/StatementRecoveryTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/StatementRecoveryTest.java
index 01a357dd1..fb718a7ee 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/StatementRecoveryTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/StatementRecoveryTest.java
@@ -3877,4 +3877,68 @@ public void test0047() {
expectedFullWithStatementRecoveryUnitToString,
testName);
}
+public void testBug430336() {
+
+ String s =
+ "package test1;\n" +
+ "import java.util.Collection;\n" +
+ "public class E {\n" +
+ " void foo(Collection collection) {\n" +
+ " collection\n" +
+ " }\n" +
+ "}\n";
+
+ String expectedDietUnitToString =
+ "package test1;\n" +
+ "import java.util.Collection;\n" +
+ "public class E {\n" +
+ " public E() {\n" +
+ " }\n" +
+ " void foo(Collection collection) {\n" +
+ " }\n" +
+ "}\n";
+
+ String expectedDietWithStatementRecoveryUnitToString =
+ expectedDietUnitToString;
+
+ String expectedDietPlusBodyUnitToString =
+ "package test1;\n" +
+ "import java.util.Collection;\n" +
+ "public class E {\n" +
+ " public E() {\n" +
+ " super();\n" +
+ " }\n" +
+ " void foo(Collection collection) {\n" +
+ " }\n" +
+ "}\n";
+
+ String expectedDietPlusBodyWithStatementRecoveryUnitToString =
+ "package test1;\n" +
+ "import java.util.Collection;\n" +
+ "public class E {\n" +
+ " public E() {\n" +
+ " super();\n" +
+ " }\n" +
+ " void foo(Collection collection) {\n" +
+ " collection = $missing$;\n" +
+ " }\n" +
+ "}\n";
+
+ String expectedFullUnitToString =
+ expectedDietUnitToString;
+
+ String expectedFullWithStatementRecoveryUnitToString =
+ expectedDietUnitToString;
+
+ String testName = "<test>";
+ checkParse(
+ s.toCharArray(),
+ expectedDietUnitToString,
+ expectedDietWithStatementRecoveryUnitToString,
+ expectedDietPlusBodyUnitToString,
+ expectedDietPlusBodyWithStatementRecoveryUnitToString,
+ expectedFullUnitToString,
+ expectedFullWithStatementRecoveryUnitToString,
+ testName);
+}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractNullAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractNullAnnotationTest.java
index dc2047df4..98bd7aaf1 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractNullAnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractNullAnnotationTest.java
@@ -113,6 +113,18 @@ public abstract class AbstractNullAnnotationTest extends AbstractComparableTest
this.LIBS,
false /*shouldFlush*/);
}
+ void runNegativeTestWithExtraLibs(String[] testFiles, String expectedErrorLog, String [] extraLibs) {
+ String [] libraries = new String [(this.LIBS == null ? 0 : this.LIBS.length) + (extraLibs == null ? 0 : extraLibs.length)];
+ if (this.LIBS != null)
+ System.arraycopy(this.LIBS, 0, libraries, 0, this.LIBS.length);
+ if (extraLibs != null)
+ System.arraycopy(extraLibs, 0, libraries, (this.LIBS == null ? 0 : this.LIBS.length), extraLibs.length);
+ runNegativeTest(
+ testFiles,
+ expectedErrorLog,
+ libraries,
+ false /*shouldFlush*/);
+ }
void runNegativeTestWithLibs(boolean shouldFlushOutputDirectory, String[] testFiles, Map customOptions, String expectedErrorLog) {
runNegativeTest(
shouldFlushOutputDirectory,
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 78dbc50e3..febf06901 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
@@ -11207,4 +11207,87 @@ public void test438437() {
"The annotation @LV is disallowed for this location\n" +
"----------\n");
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=434556, Broken class file generated for incorrect annotation usage
+public void test434556() throws Exception {
+ if (this.complianceLevel < ClassFileConstants.JDK1_5) {
+ return;
+ }
+ this.runNegativeTest(
+ new String[] {
+ "A.java",
+ "import java.lang.annotation.Retention;\n" +
+ "import java.lang.annotation.RetentionPolicy;\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface C {\n" +
+ " int i();\n" +
+ "}\n" +
+ "public class A {\n" +
+ " @C(b={},i=42)\n" +
+ " public void xxx() {}\n" +
+ " public static void main(String []argv) throws Exception {\n" +
+ " System.out.println(A.class.getDeclaredMethod(\"xxx\").getAnnotations()[0]); \n" +
+ " }\n" +
+ "}"
+ },
+ "----------\n" +
+ "1. ERROR in A.java (at line 8)\n" +
+ " @C(b={},i=42)\n" +
+ " ^\n" +
+ "The attribute b is undefined for the annotation type C\n" +
+ "----------\n",
+ null,
+ true,
+ null,
+ true, // generate output
+ false,
+ false);
+
+ String expectedOutput = "@C(i=(int) 42)\n" +
+ " public void xxx();\n" +
+ " 0 new java.lang.Error [20]\n" +
+ " 3 dup\n" +
+ " 4 ldc <String \"Unresolved compilation problem: \\n\\tThe attribute b is undefined for the annotation type C\\n\"> [22]\n" +
+ " 6 invokespecial java.lang.Error(java.lang.String) [24]\n" +
+ " 9 athrow\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 8]\n" +
+ " Local variable table:\n" +
+ " [pc: 0, pc: 10] local: this index: 0 type: A\n" +
+ " \n";
+ try {
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator +"A.class", "A", expectedOutput, ClassFileBytesDisassembler.DETAILED);
+ } catch(org.eclipse.jdt.core.util.ClassFormatException cfe) {
+ fail("Error reading classfile");
+ }
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=433747, [compiler] TYPE Annotation allowed in package-info instead of only PACKAGE
+public void test433747() throws Exception {
+ if (this.complianceLevel < ClassFileConstants.JDK1_5) {
+ return;
+ }
+ this.runNegativeTest(
+ new String[] {
+ "p/package-info.java",
+ "@PackageAnnot(\"p\")\n" +
+ "package p;\n" +
+ "import java.lang.annotation.ElementType;\n" +
+ "import java.lang.annotation.Target;\n" +
+ "@Target(ElementType.TYPE)\n" +
+ "@interface PackageAnnot {\n" +
+ " String value();\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in p\\package-info.java (at line 1)\n" +
+ " @PackageAnnot(\"p\")\n" +
+ " ^^^^^^^^^^^^^\n" +
+ "The annotation @PackageAnnot is disallowed for this location\n" +
+ "----------\n",
+ null,
+ true,
+ null,
+ true, // generate output
+ false,
+ false);
+ }
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ClassFileReaderTest_1_5.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ClassFileReaderTest_1_5.java
index 4f6a1f9b1..2a19011df 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ClassFileReaderTest_1_5.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ClassFileReaderTest_1_5.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 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
@@ -516,7 +516,7 @@ public class ClassFileReaderTest_1_5 extends AbstractRegressionTest {
"}\n" +
"";
String expectedOutput =
- " public abstract char test2() default \'\\0\';";
+ " public abstract char test2() default \'\\u0000\';";
checkClassFile("", "MonAnnotation", source, expectedOutput, ClassFileBytesDisassembler.DETAILED | ClassFileBytesDisassembler.COMPACT);
}
}
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 25a63ea99..bdaa49c30 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
@@ -840,7 +840,7 @@ public void _test011_problem_categories() {
expectedProblemAttributes.put("NonStaticFieldFromStaticInvocation", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
expectedProblemAttributes.put("NonStaticOrAlienTypeReceiver", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
expectedProblemAttributes.put("NonStaticTypeFromStaticInvocation", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
- expectedProblemAttributes.put("NotAnnoationType", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
+ expectedProblemAttributes.put("NotAnnotationType", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
expectedProblemAttributes.put("NotVisibleConstructor", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
expectedProblemAttributes.put("NotVisibleConstructorInDefaultConstructor", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
expectedProblemAttributes.put("NotVisibleConstructorInImplicitConstructorCall", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
@@ -1747,7 +1747,7 @@ public void test012_compiler_problems_tuning() {
expectedProblemAttributes.put("NonStaticFieldFromStaticInvocation", SKIP);
expectedProblemAttributes.put("NonStaticOrAlienTypeReceiver", SKIP);
expectedProblemAttributes.put("NonStaticTypeFromStaticInvocation", SKIP);
- expectedProblemAttributes.put("NotAnnoationType", SKIP);
+ expectedProblemAttributes.put("NotAnnotationType", SKIP);
expectedProblemAttributes.put("NotVisibleConstructor", SKIP);
expectedProblemAttributes.put("NotVisibleConstructorInDefaultConstructor", SKIP);
expectedProblemAttributes.put("NotVisibleConstructorInImplicitConstructorCall", SKIP);
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExternalizeStringLiteralsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExternalizeStringLiteralsTest.java
index d4e4c0aa1..73cd6c1c6 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExternalizeStringLiteralsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExternalizeStringLiteralsTest.java
@@ -12,6 +12,7 @@ package org.eclipse.jdt.core.tests.compiler.regression;
import java.util.Map;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import junit.framework.Test;
@@ -781,6 +782,31 @@ public void test023() {
false,
true);
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=443456, [1.8][compiler][lambda] $NON-NLS$ in lambda statement used as argument does not work
+public void test443456() {
+ if (this.complianceLevel < ClassFileConstants.JDK1_8)
+ return;
+ Map customOptions = getCompilerOptions();
+ customOptions.put(CompilerOptions.OPTION_ReportNonExternalizedStringLiteral, CompilerOptions.ERROR);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.util.concurrent.Callable;\n" +
+ "public class X {\n" +
+ " Callable<String> c;\n" +
+ " void setC(Callable<String> c) {\n" +
+ " this.c = c;\n" +
+ " }\n" +
+ " X() {\n" +
+ " setC(() -> \"ee\"); //$NON-NLS-1$\n" +
+ " }\n" +
+ "}\n",
+ },
+ "",
+ null,
+ true,
+ customOptions);
+}
public static Class testClass() {
return ExternalizeStringLiteralsTest.class;
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ForeachStatementTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ForeachStatementTest.java
index 4cd07e6b3..afafc76aa 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ForeachStatementTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ForeachStatementTest.java
@@ -1813,36 +1813,37 @@ public void test036() throws Exception {
},
"ab");
String expectedOutput =
- " // Method descriptor #37 (Ljava/lang/Runnable;)V\n" +
- " // Signature: <T::Ljava/lang/Runnable;:Ljava/lang/Iterable<Ljava/lang/String;>;>(TT;)V\n" +
- " // Stack: 2, Locals: 4\n" +
- " public void foo(java.lang.Runnable t);\n" +
- " 0 aload_1 [t]\n" +
- " 1 invokeinterface java.lang.Iterable.iterator() : java.util.Iterator [39] [nargs: 1]\n" +
- " 6 astore_3\n" +
- " 7 goto 27\n" +
- " 10 aload_3\n" +
- " 11 invokeinterface java.util.Iterator.next() : java.lang.Object [43] [nargs: 1]\n" +
- " 16 checkcast java.lang.String [18]\n" +
- " 19 astore_2 [s]\n" +
- " 20 getstatic java.lang.System.out : java.io.PrintStream [49]\n" +
- " 23 aload_2 [s]\n" +
- " 24 invokevirtual java.io.PrintStream.print(java.lang.String) : void [55]\n" +
- " 27 aload_3\n" +
- " 28 invokeinterface java.util.Iterator.hasNext() : boolean [61] [nargs: 1]\n" +
- " 33 ifne 10\n" +
- " 36 return\n" +
- " Line numbers:\n" +
- " [pc: 0, line: 7]\n" +
- " [pc: 20, line: 8]\n" +
- " [pc: 27, line: 7]\n" +
- " [pc: 36, line: 9]\n" +
- " Local variable table:\n" +
- " [pc: 0, pc: 37] local: this index: 0 type: X\n" +
- " [pc: 0, pc: 37] local: t index: 1 type: java.lang.Runnable\n" +
- " [pc: 20, pc: 27] local: s index: 2 type: java.lang.String\n" +
- " Local variable type table:\n" +
- " [pc: 0, pc: 37] local: t index: 1 type: T\n";
+ " // Method descriptor #37 (Ljava/lang/Runnable;)V\n" +
+ " // Signature: <T::Ljava/lang/Runnable;:Ljava/lang/Iterable<Ljava/lang/String;>;>(TT;)V\n" +
+ " // Stack: 2, Locals: 4\n" +
+ " public void foo(java.lang.Runnable t);\n" +
+ " 0 aload_1 [t]\n" +
+ " 1 checkcast java.lang.Iterable [5]\n" +
+ " 4 invokeinterface java.lang.Iterable.iterator() : java.util.Iterator [39] [nargs: 1]\n" +
+ " 9 astore_3\n" +
+ " 10 goto 30\n" +
+ " 13 aload_3\n" +
+ " 14 invokeinterface java.util.Iterator.next() : java.lang.Object [43] [nargs: 1]\n" +
+ " 19 checkcast java.lang.String [18]\n" +
+ " 22 astore_2 [s]\n" +
+ " 23 getstatic java.lang.System.out : java.io.PrintStream [49]\n" +
+ " 26 aload_2 [s]\n" +
+ " 27 invokevirtual java.io.PrintStream.print(java.lang.String) : void [55]\n" +
+ " 30 aload_3\n" +
+ " 31 invokeinterface java.util.Iterator.hasNext() : boolean [61] [nargs: 1]\n" +
+ " 36 ifne 13\n" +
+ " 39 return\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 7]\n" +
+ " [pc: 23, line: 8]\n" +
+ " [pc: 30, line: 7]\n" +
+ " [pc: 39, line: 9]\n" +
+ " Local variable table:\n" +
+ " [pc: 0, pc: 40] local: this index: 0 type: X\n" +
+ " [pc: 0, pc: 40] local: t index: 1 type: java.lang.Runnable\n" +
+ " [pc: 23, pc: 30] local: s index: 2 type: java.lang.String\n" +
+ " Local variable type table:\n" +
+ " [pc: 0, pc: 40] local: t index: 1 type: T\n";
File f = new File(OUTPUT_DIR + File.separator + "X.class");
byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java
index 0aa9c6a2a..acb81ca98 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java
@@ -20,6 +20,7 @@
* Bug 424286 - [1.8] Update type inference to spec version 0.9.1
* Bug 426676 - [1.8][compiler] Wrong generic method type inferred from lambda expression
* Bug 423505 - [1.8] Implement "18.5.4 More Specific Method Inference"
+ * Bug 434483 - [1.8][compiler][inference] Type inference not picked up with method reference
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -26724,6 +26725,8 @@ public void test0824() throws Exception {
}
}
public void test0825() throws Exception {
+ if (this.complianceLevel >= ClassFileConstants.JDK1_8)
+ return;
this.runConformTest(
new String[] {
"X.java",
@@ -26753,51 +26756,53 @@ public void test0825() throws Exception {
"");
// ensure proper declaring class for #run() invocation
String expectedOutput =
- " // Method descriptor #17 (Ljava/io/Serializable;)V\n" +
- " // Signature: (TT;)V\n" +
- " // Stack: 2, Locals: 5\n" +
- " void foo(java.io.Serializable t);\n" +
- " 0 aload_1 [t]\n" +
- " 1 astore_2 [r1]\n" +
- " 2 aload_0 [this]\n" +
- " 3 ifnonnull 10\n" +
- " 6 aload_1 [t]\n" +
- " 7 goto 11\n" +
- " 10 aload_1 [t]\n" +
- " 11 astore_3 [r2]\n" +
- " 12 aload_1 [t]\n" +
- " 13 astore 4 [r3]\n" +
- " 15 aload_0 [this]\n" +
- " 16 aload_1 [t]\n" +
- " 17 invokevirtual X.bar(java.lang.Runnable) : void [20]\n" +
- " 20 aload_0 [this]\n" +
- " 21 aload_0 [this]\n" +
- " 22 ifnonnull 29\n" +
- " 25 aload_1 [t]\n" +
- " 26 goto 30\n" +
- " 29 aload_1 [t]\n" +
- " 30 invokevirtual X.bar(java.lang.Runnable) : void [20]\n" +
- " 33 aload_0 [this]\n" +
- " 34 aload_1 [t]\n" +
- " 35 invokevirtual X.bar(java.lang.Runnable) : void [20]\n" +
- " 38 return\n" +
- " Line numbers:\n" +
- " [pc: 0, line: 5]\n" +
- " [pc: 2, line: 6]\n" +
- " [pc: 12, line: 7]\n" +
- " [pc: 15, line: 9]\n" +
- " [pc: 20, line: 10]\n" +
- " [pc: 33, line: 11]\n" +
- " [pc: 38, line: 12]\n" +
- " Local variable table:\n" +
- " [pc: 0, pc: 39] local: this index: 0 type: X\n" +
- " [pc: 0, pc: 39] local: t index: 1 type: java.io.Serializable\n" +
- " [pc: 2, pc: 39] local: r1 index: 2 type: java.lang.Runnable\n" +
- " [pc: 12, pc: 39] local: r2 index: 3 type: java.lang.Runnable\n" +
- " [pc: 15, pc: 39] local: r3 index: 4 type: java.lang.Runnable\n" +
- " Local variable type table:\n" +
- " [pc: 0, pc: 39] local: this index: 0 type: X<T,V>\n" +
- " [pc: 0, pc: 39] local: t index: 1 type: T\n";
+ " // Method descriptor #17 (Ljava/io/Serializable;)V\n" +
+ " // Signature: (TT;)V\n" +
+ " // Stack: 2, Locals: 5\n" +
+ " void foo(java.io.Serializable t);\n" +
+ " 0 aload_1 [t]\n" +
+ " 1 checkcast java.lang.Runnable [20]\n" +
+ " 4 astore_2 [r1]\n" +
+ " 5 aload_0 [this]\n" +
+ " 6 ifnonnull 13\n" +
+ " 9 aload_1 [t]\n" +
+ " 10 goto 14\n" +
+ " 13 aload_1 [t]\n" +
+ " 14 astore_3 [r2]\n" +
+ " 15 aload_1 [t]\n" +
+ " 16 astore 4 [r3]\n" +
+ " 18 aload_0 [this]\n" +
+ " 19 aload_1 [t]\n" +
+ " 20 checkcast java.lang.Runnable [20]\n" +
+ " 23 invokevirtual X.bar(java.lang.Runnable) : void [22]\n" +
+ " 26 aload_0 [this]\n" +
+ " 27 aload_0 [this]\n" +
+ " 28 ifnonnull 35\n" +
+ " 31 aload_1 [t]\n" +
+ " 32 goto 36\n" +
+ " 35 aload_1 [t]\n" +
+ " 36 invokevirtual X.bar(java.lang.Runnable) : void [22]\n" +
+ " 39 aload_0 [this]\n" +
+ " 40 aload_1 [t]\n" +
+ " 41 invokevirtual X.bar(java.lang.Runnable) : void [22]\n" +
+ " 44 return\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 5]\n" +
+ " [pc: 5, line: 6]\n" +
+ " [pc: 15, line: 7]\n" +
+ " [pc: 18, line: 9]\n" +
+ " [pc: 26, line: 10]\n" +
+ " [pc: 39, line: 11]\n" +
+ " [pc: 44, line: 12]\n" +
+ " Local variable table:\n" +
+ " [pc: 0, pc: 45] local: this index: 0 type: X\n" +
+ " [pc: 0, pc: 45] local: t index: 1 type: java.io.Serializable\n" +
+ " [pc: 5, pc: 45] local: r1 index: 2 type: java.lang.Runnable\n" +
+ " [pc: 15, pc: 45] local: r2 index: 3 type: java.lang.Runnable\n" +
+ " [pc: 18, pc: 45] local: r3 index: 4 type: java.lang.Runnable\n" +
+ " Local variable type table:\n" +
+ " [pc: 0, pc: 45] local: this index: 0 type: X<T,V>\n" +
+ " [pc: 0, pc: 45] local: t index: 1 type: T\n";
File f = new File(OUTPUT_DIR + File.separator + "X.class");
byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
@@ -32822,19 +32827,29 @@ public void test0986() {
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=140643
public void test0987() {
String expectedOutput = new CompilerOptions(getCompilerOptions()).sourceLevel < ClassFileConstants.JDK1_6
- ? "----------\n" +
- "1. ERROR in X.java (at line 11)\n" +
+ ? "----------\n" +
+ "1. ERROR in X.java (at line 7)\n" +
+ " abstract class GLinkElementView<M,CM> extends AbstractLinkView<M> {}\n" +
+ " ^^^^^^^^^^^^^^^^\n" +
+ "The return types are incompatible for the inherited methods EditPart.getViewer(), AbstractLinkView<M>.getViewer()\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 11)\n" +
" public ISheetViewer getViewer() { return null; } \n" +
" ^^^^^^^^^^^^\n" +
"The return type is incompatible with EditPart.getViewer()\n" +
"----------\n" +
- "2. ERROR in X.java (at line 11)\n" +
+ "3. ERROR in X.java (at line 11)\n" +
" public ISheetViewer getViewer() { return null; } \n" +
" ^^^^^^^^^^^\n" +
"The method getViewer() of type AbstractLinkView<M> must override a superclass method\n" +
"----------\n"
- : "----------\n" +
- "1. ERROR in X.java (at line 11)\n" +
+ : "----------\n" +
+ "1. ERROR in X.java (at line 7)\n" +
+ " abstract class GLinkElementView<M,CM> extends AbstractLinkView<M> {}\n" +
+ " ^^^^^^^^^^^^^^^^\n" +
+ "The return types are incompatible for the inherited methods EditPart.getViewer(), AbstractLinkView<M>.getViewer()\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 11)\n" +
" public ISheetViewer getViewer() { return null; } \n" +
" ^^^^^^^^^^^^\n" +
"The return type is incompatible with EditPart.getViewer()\n" +
@@ -32923,7 +32938,12 @@ public void test0988() {
"}", // =================
},
"----------\n" +
- "1. ERROR in X.java (at line 11)\n" +
+ "1. ERROR in X.java (at line 7)\n" +
+ " abstract class GLinkElementView<M,CM> extends AbstractLinkView<M> {}\n" +
+ " ^^^^^^^^^^^^^^^^\n" +
+ "The return types are incompatible for the inherited methods ILinkViewElement.getViewer(), EditPart.getViewer(), AbstractLinkView<M>.getViewer()\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 11)\n" +
" public SheetViewer getViewer() { return null; } \n" +
" ^^^^^^^^^^^\n" +
"The return type is incompatible with AbstractEditPart.getViewer()\n" +
@@ -50481,12 +50501,16 @@ public void test1444() {
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"Type safety: Unchecked cast from Iterator to Iterator<String>\n" +
"----------\n" +
+ (this.complianceLevel < ClassFileConstants.JDK1_8 ?
"5. WARNING in X.java (at line 22)\n" +
" asString = X.<String> asArray((Iterator<String>) getIterator(), String.class);\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"Unnecessary cast from Iterator to Iterator<String>\n" +
"----------\n" +
- "6. ERROR in X.java (at line 38)\n" +
+ "6. ERROR in X.java (at line 38)\n"
+ : // secondary error no longer reported at 1.8+
+ "5. ERROR in X.java (at line 38)\n"
+ ) +
" Zork z;\n" +
" ^^^^\n" +
"Zork cannot be resolved to a type\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java
index cb2558b97..be9743499 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java
@@ -32,6 +32,7 @@
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
+import java.io.File;
import java.util.Map;
import junit.framework.Test;
@@ -5396,5 +5397,93 @@ public void testBug438337comment3() {
"}\n"
});
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=422832, Class file triggers StackOverflowError when creating type hierarchy
+public void testBug422832() {
+ String path = getCompilerTestsPluginDirectoryPath() + File.separator + "workspace" + File.separator +
+ "Bug422832ClassFile" + File.separator + "aspose.pdf.jar";
+ String[] libs = getDefaultClassPaths();
+ int len = libs.length;
+ System.arraycopy(libs, 0, libs = new String[len+1], 0, len);
+ libs[len] = path;
+ runNegativeTest(
+ new String[] {
+ "ExampleClass.java",
+ "public class ExampleClass extends aspose.b.a.a {}\n",
+ },
+ "----------\n" +
+ "1. ERROR in ExampleClass.java (at line 1)\n" +
+ " public class ExampleClass extends aspose.b.a.a {}\n" +
+ " ^^^^^^^^^^^^\n" +
+ "The hierarchy of the type ExampleClass is inconsistent\n" +
+ "----------\n",
+ libs, false);
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=416480, Error in bytecode generated by ECJ compiler leads to IncompatibleClassChangeError
+public void test416480() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X<T extends Object & Runnable> {\n" +
+ " private Runnable cast(T obj) {\n" +
+ " return obj;\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " try {\n" +
+ " Runnable runnable = new X().cast(new Object());\n" +
+ " } catch (ClassCastException c) {\n" +
+ " System.out.println(\"CCE\");\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ "CCE");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=444024, Type mismatch error in annotation generics assignment which happens "sometimes"
+public void test444024() {
+ this.runConformTest(
+ new String[] {
+ "ViewpointOrganisationEntity.java",
+ "abstract public class ViewpointOrganisationEntity<T> {\n" +
+ "}\n",
+ "MetaCombo.java",
+ "public @interface MetaCombo {\n" +
+ " Class< ? extends IComboDataSet< ? >> dataSet();\n" +
+ "}\n",
+ "IComboDataSet.java",
+ "public interface IComboDataSet<T> {\n" +
+ "}\n",
+ "ContractantTypeLister.java",
+ "public class ContractantTypeLister implements IComboDataSet<ContractantType> {\n" +
+ "}\n",
+ "ContractantType.java",
+ "@MetaCombo(dataSet = ContractantTypeLister.class)\n" +
+ "public class ContractantType extends ViewpointOrganisationEntity<Long> {\n" +
+ "}\n",
+ "Contractant.java",
+ "public class Contractant extends ViewpointOrganisationEntity<Long> {\n" +
+ " @MetaCombo(dataSet = ContractantTypeLister.class)\n" +
+ " public ContractantType getContractantType() {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n",
+ },
+ "");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=440019, [1.8][compiler] Type mismatch error with autoboxing/scalar types (works with 1.6)
+public void test440019() {
+ if (this.complianceLevel <= ClassFileConstants.JDK1_7)
+ this.runConformTest(
+ new String[] {
+ "A.java",
+ "public class A {\n" +
+ " <T> T get(String name, T defaultValue) { return defaultValue; }\n" +
+ " void x() {\n" +
+ " long a1 = get(\"key\", 0);\n" +
+ " long a3 = get(\"key\", 0L);\n" +
+ " }\n" +
+ "}\n",
+ },
+ "");
+}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_7.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_7.java
index 055d7e275..be9a8bf88 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_7.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_7.java
@@ -2638,6 +2638,45 @@ public void test428220a() {
"The public type HashMap must be defined in its own file\n" +
"----------\n", null, true, customOptions);
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=442929, [1.8][compiler] ClassCastException during runtime where is no cast
+public void test442929() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " shouldNotThrow();\n" +
+ " }\n" +
+ " static void shouldNotThrow() {\n" +
+ " final String[] array = { \"\" };\n" +
+ " final String[] expected = { \"\" };\n" +
+ " // throws\n" +
+ " try {\n" +
+ " assertThat(op(array, \"\")).isEqualTo(expected);\n" +
+ " } catch (ClassCastException c) {\n" +
+ " System.out.println(\"Expected CCE\");\n" +
+ " }\n" +
+ " }\n" +
+ " static <T> T[] op(T[] array, T element) {\n" +
+ " return asArray(element);\n" +
+ " }\n" +
+ " @SafeVarargs\n" +
+ " static <T> T[] asArray(T... elements) {\n" +
+ " return elements;\n" +
+ " }\n" +
+ " static <T> ObjectArrayAssert<T> assertThat(T actual) {\n" +
+ " return new ObjectArrayAssert<>(actual);\n" +
+ " }\n" +
+ " static class ObjectArrayAssert<T> {\n" +
+ " ObjectArrayAssert(T actual) {\n" +
+ " }\n" +
+ " void isEqualTo(T expected) {\n" +
+ " }\n" +
+ " }\n" +
+ "}\n",
+ },
+ "Expected CCE");
+}
public static Class testClass() {
return GenericsRegressionTest_1_7.class;
}
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 3f59b14bf..f7f13c588 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
@@ -21,7 +21,7 @@ import junit.framework.Test;
public class GenericsRegressionTest_1_8 extends AbstractRegressionTest {
static {
-// TESTS_NAMES = new String[] { "testBug428198b" };
+// TESTS_NAMES = new String[] { "testBug434483" };
// TESTS_NUMBERS = new int[] { 40, 41, 43, 45, 63, 64 };
// TESTS_RANGE = new int[] { 11, -1 };
}
@@ -3390,4 +3390,55 @@ public void testBug435767() {
"The method getValue(String) in the type DummyClass is not applicable for the arguments (Object)\n" +
"----------\n");
}
+public void testBug434483() {
+ runConformTest(
+ new String[] {
+ "Foo.java",
+ "import java.util.*;\n" +
+ "public class Foo {\n" +
+ " \n" +
+ " // Similar to Guava's newLinkedList()\n" +
+ " public static <E> LinkedList<E> newLinkedList() {\n" +
+ " return new LinkedList<E>();\n" +
+ " }\n" +
+ " \n" +
+ " private final ThreadLocal<Queue<String>> brokenQueue = ThreadLocal.withInitial(Foo::newLinkedList);\n" +
+ " \n" +
+ " private final ThreadLocal<Queue<String>> workingQueue1 = ThreadLocal.withInitial(Foo::<String>newLinkedList);\n" +
+ " \n" +
+ " private final ThreadLocal<Queue<String>> workingQueue2 = ThreadLocal.withInitial(() -> Foo.<String>newLinkedList());\n" +
+ "\n" +
+ "}\n"
+ });
+}
+public void testBug441734() {
+ runConformTest(
+ new String[] {
+ "Example.java",
+ "import java.util.*;\n" +
+ "import java.util.function.*;\n" +
+ "class Example {\n" +
+ " void foo(Iterable<Number> x) { }\n" +
+ "\n" +
+ " <T> void bar(Consumer<Iterable<T>> f) { }\n" +
+ "\n" +
+ " void test() {\n" +
+ " //call 1: lambda w/argument type - OK\n" +
+ " bar((Iterable<Number> x) -> foo(x));\n" +
+ "\n" +
+ " //call 2: lambda w/explicit type - OK\n" +
+ " this.<Number> bar(x -> foo(x));\n" +
+ "\n" +
+ " //call 3: method ref w/explicit type - OK\n" +
+ " this.<Number> bar(this::foo);\n" +
+ "\n" +
+ " //call 4: lambda w/implicit type - correctly(?) fails*\n" +
+ " //bar(x -> foo(x));\n" +
+ "\n" +
+ " //call 5: method ref w/implicit type - BUG!\n" +
+ " bar(this::foo); // errors!\n" +
+ " }\n" +
+ "}\n"
+ });
+}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InterfaceMethodsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InterfaceMethodsTest.java
index 5cb2f0602..9b02bc2e6 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InterfaceMethodsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InterfaceMethodsTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 GK Software AG, IBM Corporation and others.
+ * Copyright (c) 2013, 2014 GK Software AG, 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
@@ -11,9 +11,13 @@
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
+import java.io.File;
import java.util.Map;
import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.ToolFactory;
+import org.eclipse.jdt.core.tests.util.Util;
+import org.eclipse.jdt.core.util.ClassFileBytesDisassembler;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import junit.framework.Test;
@@ -2509,4 +2513,139 @@ public class InterfaceMethodsTest extends AbstractComparableTest {
},
"");
}
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=438471, Java 1.8 functional interface rejected if it extends an interface which overrides another interface's method
+ public void test438471() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "Bar.java",
+ "@FunctionalInterface\n" +
+ "public interface Bar extends Overridden {\n" +
+ " void foo();\n" +
+ " @Override\n" +
+ " default void close() {\n" +
+ " System.out.println(\"bar\");\n" +
+ " }\n" +
+ "}\n" +
+ "\n" +
+ "interface Overridden extends AutoCloseable {\n" +
+ " // Works without this overridden method\n" +
+ " @Override\n" +
+ " void close();\n" +
+ "}"
+ },
+ "");
+ }
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=436350, [1.8][compiler] Missing bridge method in interface results in AbstractMethodError
+ public void test436350() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " public static void main(String [] args) {\n" +
+ " }\n" +
+ "}\n" +
+ "interface GenericInterface<T> {\n" +
+ " T reduce(Integer i);\n" +
+ "}\n" +
+ "interface DoubleInterface extends GenericInterface<Double> {\n" +
+ " default Double reduce(Integer i) {\n" +
+ " return 0.0;\n" +
+ " }\n" +
+ " double reduce(String s);\n" +
+ "}\n", // =================
+ },
+ "");
+ // ensure bridge methods are generated in interfaces.
+ String expectedOutput =
+ " public bridge synthetic java.lang.Object reduce(java.lang.Integer arg0);\n" +
+ " 0 aload_0 [this]\n" +
+ " 1 aload_1 [arg0]\n" +
+ " 2 invokeinterface DoubleInterface.reduce(java.lang.Integer) : java.lang.Double [24] [nargs: 2]\n" +
+ " 7 areturn\n";
+
+ File f = new File(OUTPUT_DIR + File.separator + "DoubleInterface.class");
+ byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
+ ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
+ String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED);
+ int index = result.indexOf(expectedOutput);
+ if (index == -1 || expectedOutput.length() == 0) {
+ System.out.println(Util.displayString(result, 3));
+ }
+ if (index == -1) {
+ assertEquals("Wrong contents", expectedOutput, result);
+ }
+ }
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=436350, [1.8][compiler] Missing bridge method in interface results in AbstractMethodError
+ public void test436350a() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.util.Iterator;\n" +
+ "import java.util.PrimitiveIterator;\n" +
+ "import java.util.PrimitiveIterator.OfDouble;\n" +
+ "/**\n" +
+ " * @author Tobias Grasl\n" +
+ " */\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " final double[] doubles = new double[]{1,2,3};\n" +
+ " OfDouble doubleIterator = new DoubleArrayIterator(doubles);\n" +
+ " Double value = new Reducer<Double>().reduce(doubleIterator, new DoubleInterface() {\n" +
+ " @Override\n" +
+ " public double reduce(OfDouble iterator_) {\n" +
+ " double sum = 0;\n" +
+ " while(iterator_.hasNext()) {\n" +
+ " sum += iterator_.nextDouble();\n" +
+ " }\n" +
+ " return sum;\n" +
+ " }\n" +
+ " });\n" +
+ " System.out.println(\"Anonymous class value: \"+value);\n" +
+ " doubleIterator = new DoubleArrayIterator(doubles);\n" +
+ " value = new Reducer<Double>().reduce(doubleIterator, (DoubleInterface) iterator_ -> {\n" +
+ " double sum = 0;\n" +
+ " while(iterator_.hasNext()) {\n" +
+ " sum += iterator_.nextDouble();\n" +
+ " }\n" +
+ " return sum;\n" +
+ " });\n" +
+ " System.out.println(\"Lambda expression value: \"+value);\n" +
+ " }\n" +
+ " private static class DoubleArrayIterator implements PrimitiveIterator.OfDouble {\n" +
+ " int index = 0;\n" +
+ " private double[] _doubles;\n" +
+ " public DoubleArrayIterator(double[] doubles_) {\n" +
+ " _doubles = doubles_;\n" +
+ " }\n" +
+ " @Override\n" +
+ " public boolean hasNext() {\n" +
+ " return index < _doubles.length;\n" +
+ " }\n" +
+ " @Override\n" +
+ " public double nextDouble() {\n" +
+ " return _doubles[index++];\n" +
+ " }\n" +
+ " };\n" +
+ " interface GenericInterface<T> {\n" +
+ " T reduce(Iterator<T> iterator_);\n" +
+ " }\n" +
+ " interface DoubleInterface extends GenericInterface<Double> {\n" +
+ " default Double reduce(Iterator<Double> iterator_) {\n" +
+ " if(iterator_ instanceof PrimitiveIterator.OfDouble) {\n" +
+ " return reduce((PrimitiveIterator.OfDouble)iterator_);\n" +
+ " }\n" +
+ " return Double.NaN;\n" +
+ " };\n" +
+ " double reduce(PrimitiveIterator.OfDouble iterator_);\n" +
+ " }\n" +
+ " static class Reducer<T> {\n" +
+ " T reduce(Iterator<T> iterator_, GenericInterface<T> reduction_) {\n" +
+ " return reduction_.reduce(iterator_);\n" +
+ " }\n" +
+ " }\n" +
+ "}\n", // =================
+ },
+ "Anonymous class value: 6.0\n" +
+ "Lambda expression value: 6.0");
+ }
}
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 84d948ec2..054052cd0 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
@@ -4387,32 +4387,6 @@ public void test432531() {
"}"
});
}
-// https://bugs.eclipse.org/bugs/show_bug.cgi?id=432531 [1.8] VerifyError with anonymous subclass inside of lambda expression in the superclass constructor call
-public void test432531a() {
- this.runConformTest(
- new String[] {
- "Y.java",
- "import java.util.function.Supplier;\n" +
- "class E {\n" +
- " E(Supplier<Object> factory) { }\n" +
- "}\n" +
- "public class Y extends E {\n" +
- " Y() {\n" +
- " super( () -> {\n" +
- " class Z extends E {\n" +
- " Z() {\n" +
- " super(() -> new Object());\n" +
- " }\n" +
- " }\n" +
- " return new Z();\n" +
- " });\n" +
- " }\n" +
- " public static void main(String[] args) {\n" +
- " new Y();\n" +
- " }\n" +
- "}"
- });
-}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=434297 [1.8] NPE in LamdaExpression.analyseCode with lamda expression nested in a conditional expression
public void test434297() {
this.runConformTest(
@@ -4506,7 +4480,8 @@ public void test436542() throws Exception {
assertNull("Found generic signature for lambda method", signature);
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=439515 [1.8] ECJ reports error at method reference to overloaded instance method
-public void _test439515() {
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=440643, Eclipse compiler doesn't like method references with overloaded varargs method
+public void test439515() {
this.runConformTest(
new String[] {
"X.java",
@@ -4531,6 +4506,33 @@ public void _test439515() {
},
"-1");
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=439515 [1.8] ECJ reports error at method reference to overloaded instance method
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=440643, Eclipse compiler doesn't like method references with overloaded varargs method
+public void test439515a() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface Fun<T, R> {\n" +
+ " R apply(T arg);\n" +
+ "}\n" +
+ "public class X {\n" +
+ " static int size() {\n" +
+ " return -1;\n" +
+ " }\n" +
+ " static int size(Object arg) {\n" +
+ " return 0;\n" +
+ " }\n" +
+ " static int size(X arg) {\n" +
+ " return 1;\n" +
+ " }\n" +
+ " public static void main(String args[]) {\n" +
+ " Fun<X, Integer> f1 = X::size;\n" +
+ " System.out.println(f1.apply(new X()));\n" +
+ " }\n" +
+ "}\n"
+ },
+ "1");
+}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=438534 Java8 java.lang.Method.getGeneric* methods fail with java.lang.reflect.GenericSignatureFormatError: Signature Parse error: Expected Field Type Signature
public void test438534() {
this.runConformTest(
@@ -4604,6 +4606,174 @@ public void test440152a() {
"}\n"
});
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=432110, [1.8][compiler] nested lambda type incorrectly inferred vs javac
+public void test432110() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.util.function.Function;\n" +
+ "public interface X {\n" +
+ " default void test() {\n" +
+ " testee().flatMap(_warning_ -> {\n" +
+ " return result().map(s -> 0);\n" +
+ " });\n" +
+ " }\n" +
+ " Either<Integer, Integer> testee();\n" +
+ " Either<Integer, String> result();\n" +
+ " static interface Either<L, R> {\n" +
+ " <U> Either<L, U> flatMap(Function<? super R, Either<L, U>> mapper);\n" +
+ " <U> Either<L, U> map(Function<? super R, U> mapper);\n" +
+ " }\n" +
+ " public static void main(String [] args) {\n" +
+ " System.out.println(\"OK\");\n" +
+ " }\n" +
+ "}\n",
+ },
+ "OK");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=441929, [1.8][compiler] @SuppressWarnings("unchecked") not accepted on local variable
+public void test441929() {
+ this.runNegativeTest(
+ new String[] {
+ "Y.java",
+ "public class Y {\n" +
+ " @FunctionalInterface\n" +
+ " interface X {\n" +
+ " public void x();\n" +
+ " }\n" +
+ " public void z(X x) {\n" +
+ " }\n" +
+ " public <T> void test() {\n" +
+ " z(() -> {\n" +
+ " try {\n" +
+ " @SuppressWarnings(\"unchecked\") // (1)\n" +
+ " Class<? extends T> klass = (Class<? extends T>) Class.forName(\"java.lang.Object\"); // (2)\n" +
+ " System.out.println(klass.getName());\n" +
+ " } catch (Exception e) {\n" +
+ " e.printStackTrace();\n" +
+ " }\n" +
+ " });\n" +
+ " }\n" +
+ "}\n",
+ },
+ "");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=437781, [1.8][compiler] Eclipse accepts code rejected by javac because of ambiguous method reference
+public void test437781() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.util.function.Consumer;\n" +
+ "import java.util.function.Function;\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " new X().visit( System.out::println );\n" +
+ " }\n" +
+ " public boolean visit(Function<Integer, Boolean> func) {\n" +
+ " System.out.println(\"Function\");\n" +
+ " return true;\n" +
+ " }\n" +
+ " public void visit(Consumer<Integer> func) {\n" +
+ " System.out.println(\"Consumer\");\n" +
+ " } \n" +
+ "}\n"
+ },
+ "Consumer");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=441907, [1.8][compiler] Eclipse 4.4.x compiler generics bugs with streams and lambdas
+public void _test441907() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.util.*;\n" +
+ "public class X {\n" +
+ " public static class FooBar<V> {\n" +
+ " }\n" +
+ " public interface FooBarred {\n" +
+ " public <V> boolean hasFooBar(final FooBar<V> fooBar);\n" +
+ " }\n" +
+ " public interface Widget extends FooBarred {\n" +
+ " }\n" +
+ " public static void test() {\n" +
+ " Set<FooBar<?>> foobars = new HashSet<>();\n" +
+ " Set<Widget> widgets = new HashSet<>();\n" +
+ " boolean anyWidgetHasFooBar = widgets.stream().anyMatch(\n" +
+ " widget -> foobars.stream().anyMatch(widget::hasFooBar)\n" +
+ " );\n" +
+ " }\n" +
+ "}\n"
+ },
+ "");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=443889, [1.8][compiler] Lambdas get compiled to duplicate methods
+public void test443889() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.util.function.BiConsumer;\n" +
+ "import java.util.function.Consumer;\n" +
+ "public class X {\n" +
+ " public interface CurryBiConsumer<T, U> extends BiConsumer<T, U> {\n" +
+ " default public CurryConsumer<U> curryFirst(T t) {\n" +
+ " return (u) -> accept(t, u);\n" +
+ " }\n" +
+ " default public CurryConsumer<T> currySecond(U u) {\n" +
+ " return (t) -> accept(t, u);\n" +
+ " }\n" +
+ " }\n" +
+ " public interface CurryConsumer<T> extends Consumer<T> {\n" +
+ " default public Runnable curry(T t) {\n" +
+ " return () -> accept(t);\n" +
+ " }\n" +
+ " }\n" +
+ " static void execute(Runnable r) {\n" +
+ " System.out.println(\"BEFORE\");\n" +
+ " r.run();\n" +
+ " System.out.println(\"AFTER\");\n" +
+ " }\n" +
+ " static void display(String str, int count) {\n" +
+ " System.out.println(\"DISP: \" + str + \" \" + count);\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " CurryBiConsumer<String, Integer> bc = X::display;\n" +
+ " execute(bc.curryFirst(\"Salomon\").curry(42));\n" +
+ " }\n" +
+ "}\n"
+ },
+ "BEFORE\n" +
+ "DISP: Salomon 42\n" +
+ "AFTER");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=441907, [1.8][compiler] Eclipse 4.4.x compiler generics bugs with streams and lambdas
+public void test441907() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.util.*;\n" +
+ "import java.util.function.Predicate;\n" +
+ "import java.util.stream.Stream;\n" +
+ "public class X {\n" +
+ " public static class FooBar<V> {\n" +
+ " }\n" +
+ " public interface FooBarred {\n" +
+ " public <V> boolean hasFooBar(final FooBar<V> fooBar);\n" +
+ " }\n" +
+ " public interface Widget extends FooBarred {\n" +
+ " }\n" +
+ " public static void test() {\n" +
+ " Set<FooBar<?>> foobars = new HashSet<>();\n" +
+ " Set<Widget> widgets = new HashSet<>();\n" +
+ " Stream<X.FooBar<?>> s = null;\n" +
+ " FooBarred fb = null;\n" +
+ " fb.hasFooBar((FooBar<?>) null);\n" +
+ " boolean anyWidgetHasFooBar = widgets.stream().anyMatch(\n" +
+ " widget -> foobars.stream().anyMatch(widget::hasFooBar)\n" +
+ " );\n" +
+ " }\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/MethodVerifyTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java
index 2a3d88335..4453690a8 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java
@@ -14079,4 +14079,39 @@ public void testBug426546() {
},
"CCC");
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=438812, Missing bridge methods in indirect child classes with ECJ 3.10.0
+public void testBug438812() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "A.java",
+ "import java.util.Collection;\n" +
+ "import java.util.List;\n" +
+ "\n" +
+ "public interface A {\n" +
+ " Iterable getIterable();\n" +
+ "}\n" +
+ "\n" +
+ "class B implements A {\n" +
+ " public Collection getIterable() { return null; }\n" +
+ "}\n" +
+ "\n" +
+ "class C extends B {\n" +
+ " public List getIterable() { return null; }\n" +
+ "}",
+ },
+ "");
+ String expectedOutput = " public bridge synthetic java.lang.Iterable getIterable();";
+
+ File f = new File(OUTPUT_DIR + File.separator + "C.class");
+ byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
+ ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
+ String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED);
+ int index = result.indexOf(expectedOutput);
+ if (index == -1 || expectedOutput.length() == 0) {
+ System.out.println(Util.displayString(result, 3));
+ }
+ if (index == -1) {
+ assertEquals("Wrong contents", expectedOutput, result);
+ }
+}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java
index c7ba530a3..c344e06e3 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java
@@ -5062,7 +5062,7 @@ this.runNegativeTest(
" public static void main(String[] args) {\n" +
" new X().foo(()->{ return \"\";});\n" +
" new X().foo(()-> 10);\n" +
- " new X().foo((s)->{});\n" + // error not reported here, since analyzeCode does not get to run.
+ " new X().foo((s)->{});\n" +
" new X().foo((s)->{ return;});\n" +
" new X().foo((s)->{ return \"\";});\n" +
" new X().foo((s)-> \"hello\");\n" +
@@ -5092,10 +5092,25 @@ this.runNegativeTest(
" ^^\n" +
"Void methods cannot return a value\n" +
"----------\n" +
- "5. ERROR in X.java (at line 18)\n" +
+ "5. ERROR in X.java (at line 17)\n" +
+ " new X().foo((s)->{});\n" +
+ " ^^^\n" +
+ "The method foo(I) in the type X is not applicable for the arguments ((<no type> s) -> {})\n" +
+ "----------\n" +
+ "6. ERROR in X.java (at line 17)\n" +
+ " new X().foo((s)->{});\n" +
+ " ^^^^^\n" +
+ "Lambda expression\'s signature does not match the signature of the functional interface method foo()\n" +
+ "----------\n" +
+ "7. ERROR in X.java (at line 18)\n" +
+ " new X().foo((s)->{ return;});\n" +
+ " ^^^\n" +
+ "The method foo(I) in the type X is not applicable for the arguments ((<no type> s) -> {})\n" +
+ "----------\n" +
+ "8. ERROR in X.java (at line 18)\n" +
" new X().foo((s)->{ return;});\n" +
- " ^^^^^^^\n" +
- "This method must return a result of type String\n" +
+ " ^^^^^\n" +
+ "Lambda expression\'s signature does not match the signature of the functional interface method foo()\n" +
"----------\n");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=401610, [1.8][compiler] Allow lambda/reference expressions in non-overloaded method invocation contexts
@@ -5766,58 +5781,48 @@ public void test401939b() {
"----------\n" +
"1. ERROR in X.java (at line 14)\n" +
" goo((x) -> { while (FALSE) throw new Exception(); });\n" +
- " ^^^^^^\n" +
- "This method must return a result of type String\n" +
+ " ^^^\n" +
+ "The method goo(I) in the type X is not applicable for the arguments ((<no type> x) -> {})\n" +
"----------\n" +
- "2. ERROR in X.java (at line 14)\n" +
- " goo((x) -> { while (FALSE) throw new Exception(); });\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Unreachable code\n" +
+ "2. ERROR in X.java (at line 15)\n" +
+ " goo((x) -> { while (TRUE) throw new Exception(); });\n" +
+ " ^^^\n" +
+ "The method goo(I) in the type X is not applicable for the arguments ((<no type> x) -> {})\n" +
"----------\n" +
- "3. ERROR in X.java (at line 17)\n" +
- " goo((x) -> { while (POI) throw new Exception(); });\n" +
- " ^^^^^^\n" +
- "This method must return a result of type String\n" +
+ "3. ERROR in X.java (at line 16)\n" +
+ " goo((x) -> { while (NIJAM) throw new Exception(); });\n" +
+ " ^^^\n" +
+ "The method goo(I) in the type X is not applicable for the arguments ((<no type> x) -> {})\n" +
"----------\n" +
"4. ERROR in X.java (at line 17)\n" +
" goo((x) -> { while (POI) throw new Exception(); });\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Unreachable code\n" +
+ " ^^^\n" +
+ "The method goo(I) in the type X is not applicable for the arguments ((<no type> x) -> {})\n" +
"----------\n" +
- "5. WARNING in X.java (at line 18)\n" +
+ "5. ERROR in X.java (at line 18)\n" +
" goo((x) -> { if (TRUE) throw new Exception(); else throw new Exception(); });\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Statement unnecessarily nested within else clause. The corresponding then clause does not complete normally\n" +
+ " ^^^\n" +
+ "The method goo(I) in the type X is not applicable for the arguments ((<no type> x) -> {})\n" +
"----------\n" +
"6. ERROR in X.java (at line 19)\n" +
" goo((x) -> { if (TRUE) throw new Exception(); });\n" +
- " ^^^^^^\n" +
- "This method must return a result of type String\n" +
- "----------\n" +
- "7. WARNING in X.java (at line 20)\n" +
- " goo((x) -> { if (true) throw new Exception(); else throw new Exception(); });\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Statement unnecessarily nested within else clause. The corresponding then clause does not complete normally\n" +
+ " ^^^\n" +
+ "The method goo(I) in the type X is not applicable for the arguments ((<no type> x) -> {})\n" +
"----------\n" +
- "8. WARNING in X.java (at line 20)\n" +
+ "7. ERROR in X.java (at line 20)\n" +
" goo((x) -> { if (true) throw new Exception(); else throw new Exception(); });\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Dead code\n" +
- "----------\n" +
- "9. WARNING in X.java (at line 21)\n" +
- " goo((x) -> { if (false) throw new Exception(); else throw new Exception(); });\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Dead code\n" +
+ " ^^^\n" +
+ "The method goo(I) in the type X is not applicable for the arguments ((<no type> x) -> {})\n" +
"----------\n" +
- "10. WARNING in X.java (at line 21)\n" +
+ "8. ERROR in X.java (at line 21)\n" +
" goo((x) -> { if (false) throw new Exception(); else throw new Exception(); });\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Statement unnecessarily nested within else clause. The corresponding then clause does not complete normally\n" +
+ " ^^^\n" +
+ "The method goo(I) in the type X is not applicable for the arguments ((<no type> x) -> {})\n" +
"----------\n" +
- "11. ERROR in X.java (at line 22)\n" +
+ "9. ERROR in X.java (at line 22)\n" +
" goo((x) -> { while (BLANK) throw new Exception(); });\n" +
- " ^^^^^^\n" +
- "This method must return a result of type String\n" +
+ " ^^^\n" +
+ "The method goo(I) in the type X is not applicable for the arguments ((<no type> x) -> {})\n" +
"----------\n");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=401939, [1.8][compiler] Incorrect shape analysis leads to method resolution failure .
@@ -5841,6 +5846,11 @@ public void test401939c() {
" goo((x) -> { if (x) return null; });\n" +
" ^\n" +
"Type mismatch: cannot convert from String to boolean\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 9)\n" +
+ " goo((x) -> {});\n" +
+ " ^^^\n" +
+ "The method goo(I) in the type X is not applicable for the arguments ((<no type> x) -> {})\n" +
"----------\n");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=401939, [1.8][compiler] Incorrect shape analysis leads to method resolution failure .
@@ -5861,8 +5871,8 @@ public void test401939ca() {
"----------\n" +
"1. ERROR in X.java (at line 8)\n" +
" goo((x) -> {});\n" +
- " ^^^^^^\n" +
- "This method must return a result of type String\n" +
+ " ^^^\n" +
+ "The method goo(I) in the type X is not applicable for the arguments ((<no type> x) -> {})\n" +
"----------\n");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=401939, [1.8][compiler] Incorrect shape analysis leads to method resolution failure .
@@ -5883,8 +5893,8 @@ public void test401939d() {
"----------\n" +
"1. ERROR in X.java (at line 8)\n" +
" goo((x) -> { if (x) return null; });\n" +
- " ^^^^^^\n" +
- "This method must return a result of type String\n" +
+ " ^^^\n" +
+ "The method goo(I) in the type X is not applicable for the arguments ((<no type> x) -> {})\n" +
"----------\n");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=401939, [1.8][compiler] Incorrect shape analysis leads to method resolution failure .
@@ -5905,6 +5915,11 @@ public void test401939e() {
"----------\n" +
"1. ERROR in X.java (at line 8)\n" +
" goo((x) -> { return null; });\n" +
+ " ^^^\n" +
+ "The method goo(I) in the type X is not applicable for the arguments ((<no type> x) -> {})\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 8)\n" +
+ " goo((x) -> { return null; });\n" +
" ^^^^^^^^^^^^\n" +
"Void methods cannot return a value\n" +
"----------\n");
@@ -5980,11 +5995,6 @@ public void test402219a() {
"----------\n" +
"1. ERROR in X.java (at line 11)\n" +
" new X().goo((p1, p2) -> {});\n" +
- " ^^^\n" +
- "The method goo(I) is ambiguous for the type X\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 11)\n" +
- " new X().goo((p1, p2) -> {});\n" +
" ^^\n" +
"Empty block should be documented\n" +
"----------\n",
@@ -6961,7 +6971,6 @@ public void test412284c() {
" }\n" +
"}\n"
},
-
"----------\n" +
"1. ERROR in X.java (at line 4)\n" +
" X(){\n" +
@@ -6971,9 +6980,19 @@ public void test412284c() {
"2. ERROR in X.java (at line 7)\n" +
" t += 3;\n" +
" ^\n" +
+ "The blank final field t may not have been initialized\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 7)\n" +
+ " t += 3;\n" +
+ " ^\n" +
"The final field X.t cannot be assigned\n" +
"----------\n" +
- "3. ERROR in X.java (at line 9)\n" +
+ "4. ERROR in X.java (at line 9)\n" +
+ " t += 4;\n" +
+ " ^\n" +
+ "The blank final field t may not have been initialized\n" +
+ "----------\n" +
+ "5. ERROR in X.java (at line 9)\n" +
" t += 4;\n" +
" ^\n" +
"The final field X.t cannot be assigned\n" +
@@ -7506,17 +7525,7 @@ public void test422489b() { // interfaces and methods order changed, triggers NP
" }\n" +
"}\n"
},
- "----------\n" +
- "1. ERROR in X.java (at line 13)\n" +
- " goo((x, y) -> { return x[0] += 1; });\n" +
- " ^^^\n" +
- "The method goo(J) is ambiguous for the type X\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 13)\n" +
- " goo((x, y) -> { return x[0] += 1; });\n" +
- " ^^^^\n" +
- "The type of the expression must be an array type but it resolved to int\n" +
- "----------\n"
+ ""
);
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=422489, [1.8][compiler] NPE in CompoundAssignment.analyseCode when creating AST for java.util.stream.Collectors
@@ -9093,7 +9102,465 @@ public void test439707() {
"The type T2.InvisibleInterface from the descriptor computed for the target context is not visible here. \n" +
"----------\n");
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=442983, [1.8] NPE in Scope.findDefaultAbstractMethod
+public void test442983() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.util.function.Function;\n" +
+ "class CL<T> {\n" +
+ " <F> String method1(CL<T> ie) {\n" +
+ " return \"b\";\n" +
+ " }\n" +
+ " public void bar() { \n" +
+ " Function<CL<Integer>, String> v5 = CL::method1;\n" +
+ " v5 = t -> t.method1(); \n" +
+ " } \n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 7)\n" +
+ " Function<CL<Integer>, String> v5 = CL::method1;\n" +
+ " ^^^^^^^^^^^\n" +
+ "The type CL does not define method1(CL<Integer>) that is applicable here\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 8)\n" +
+ " v5 = t -> t.method1(); \n" +
+ " ^^^^^^^\n" +
+ "The method method1(CL<Integer>) in the type CL<Integer> is not applicable for the arguments ()\n" +
+ "----------\n");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=438945, [1.8] NullPointerException InferenceContext18.checkExpression in java 8 with generics, primitives, and overloading
+public void test438945() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.util.function.ToIntFunction;\n" +
+ "import java.util.function.ToLongFunction;\n" +
+ "public class X {\n" +
+ " public static void error() {\n" +
+ " test(X::works);\n" +
+ " test(X::broken);\n" +
+ " }\n" +
+ " private static <T> void test(ToLongFunction<T> func) {}\n" +
+ " private static <T> void test(ToIntFunction<T> func) {}\n" +
+ " private static int broken(Object o) { return 0; }\n" +
+ " private static long works(Object o) { return 0; } \n" +
+ "}\n"
+ },
+ "");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=440643, Eclipse compiler doesn't like method references with overloaded varargs method
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=439515, [1.8] ECJ reports error at method reference to overloaded instance method
+public void test440643() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR);
+
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "@FunctionalInterface\n" +
+ "interface Accumalator<E> {\n" +
+ " void acum(Container<E> container, E data);\n" +
+ "}\n" +
+ "interface Container<E> {\n" +
+ " public void add(E data);\n" +
+ " @SuppressWarnings(\"unchecked\")\n" +
+ " public void add(E...data);\n" +
+ "}\n" +
+ "class Binding<E> {\n" +
+ " private final Accumalator<E> function;\n" +
+ " \n" +
+ " public Binding() {\n" +
+ " function = Container::add;\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 11)\n" +
+ " private final Accumalator<E> function;\n" +
+ " ^^^^^^^^\n" +
+ "The value of the field Binding<E>.function is not used\n" +
+ "----------\n",
+ null,
+ false,
+ options);
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=440643, Eclipse compiler doesn't like method references with overloaded varargs method
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=439515, [1.8] ECJ reports error at method reference to overloaded instance method
+public void test440643a() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "interface Fun<T, R> {\n" +
+ " R apply(T arg);\n" +
+ "}\n" +
+ "public class X {\n" +
+ " static int size() {\n" +
+ " return -1;\n" +
+ " }\n" +
+ " static int size(Object arg) {\n" +
+ " return 0;\n" +
+ " }\n" +
+ " int size(X arg) {\n" +
+ " return 1;\n" +
+ " }\n" +
+ " public static void main(String args[]) {\n" +
+ " Fun<X, Integer> f1 = X::size;\n" +
+ " System.out.println(f1.apply(new X()));\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 15)\n" +
+ " Fun<X, Integer> f1 = X::size;\n" +
+ " ^^^^^^^\n" +
+ "Cannot make a static reference to the non-static method size(X) from the type X\n" +
+ "----------\n");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=440643, Eclipse compiler doesn't like method references with overloaded varargs method
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=439515, [1.8] ECJ reports error at method reference to overloaded instance method
+public void test440643b() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "interface Fun<T, R> {\n" +
+ " R apply(T arg);\n" +
+ "}\n" +
+ "public class X {\n" +
+ " int size() {\n" +
+ " return -1;\n" +
+ " }\n" +
+ " static int size(Object arg) {\n" +
+ " return 0;\n" +
+ " }\n" +
+ " public static void main(String args[]) {\n" +
+ " Fun<X, Integer> f1 = X::size;\n" +
+ " System.out.println(f1.apply(new X()));\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 12)\n" +
+ " Fun<X, Integer> f1 = X::size;\n" +
+ " ^^^^^^^\n" +
+ "Ambiguous method reference: both size() and size(Object) from the type X are eligible\n" +
+ "----------\n");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=435397, [1.8][compiler] Ambiguous method while using Lambdas
+public void test435397() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.util.function.Function;\n" +
+ "interface B {}\n" +
+ "interface Config {}\n" +
+ "interface M {\n" +
+ " void configure(B binder);\n" +
+ "}\n" +
+ "class M2 implements M {\n" +
+ " public M2(final Config conf) {\n" +
+ " }\n" +
+ " public M2() {\n" +
+ " }\n" +
+ "@Override\n" +
+ " public void configure(final B binder) {\n" +
+ " }\n" +
+ "}\n" +
+ "// BootModule\n" +
+ "class BaseModule implements M {\n" +
+ " // eager module creation\n" +
+ " public BaseModule module(final M m) {\n" +
+ " return this;\n" +
+ " }\n" +
+ " // lazy module creation\n" +
+ " public BaseModule module(final Function<Config, M> cons) {\n" +
+ " return this;\n" +
+ " }\n" +
+ " @Override\n" +
+ " public void configure(final B binder) {\n" +
+ " }\n" +
+ "}\n" +
+ "// Client with error\n" +
+ "class M1 extends BaseModule {\n" +
+ " public static void main(final String[] args) {\n" +
+ " new M1().module((c) -> new M2());\n" +
+ " // The method module(M) is ambiguous for the type M1\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 33)\n" +
+ " new M1().module((c) -> new M2());\n" +
+ " ^^^^^^\n" +
+ "The method module(M) is ambiguous for the type M1\n" +
+ "----------\n");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=433458, [1.8][compiler] Eclipse accepts lambda expression with potentially uninitialized arguments
+public void test433458() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.util.Comparator;\n" +
+ "public class X {\n" +
+ " final Comparator mComparator1;\n" +
+ //" Comparator mComparator2 = mComparator1;\n" +
+ " Comparator mComparator2 = (pObj1, pObj2) -> mComparator1.compare(pObj1, pObj2);\n" +
+ " X() {mComparator1 = Comparator.naturalOrder();}\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. WARNING in X.java (at line 3)\n" +
+ " final Comparator mComparator1;\n" +
+ " ^^^^^^^^^^\n" +
+ "Comparator is a raw type. References to generic type Comparator<T> should be parameterized\n" +
+ "----------\n" +
+ "2. WARNING in X.java (at line 4)\n" +
+ " Comparator mComparator2 = (pObj1, pObj2) -> mComparator1.compare(pObj1, pObj2);\n" +
+ " ^^^^^^^^^^\n" +
+ "Comparator is a raw type. References to generic type Comparator<T> should be parameterized\n" +
+ "----------\n" +
+ "3. WARNING in X.java (at line 4)\n" +
+ " Comparator mComparator2 = (pObj1, pObj2) -> mComparator1.compare(pObj1, pObj2);\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Type safety: The method compare(Object, Object) belongs to the raw type Comparator. References to generic type Comparator<T> should be parameterized\n" +
+ "----------\n" +
+ "4. ERROR in X.java (at line 4)\n" +
+ " Comparator mComparator2 = (pObj1, pObj2) -> mComparator1.compare(pObj1, pObj2);\n" +
+ " ^^^^^^^^^^^^\n" +
+ "The blank final field mComparator1 may not have been initialized\n" +
+ "----------\n");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=433458, [1.8][compiler] Eclipse accepts lambda expression with potentially uninitialized arguments
+public void test433458a() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " void foo();\n" +
+ "}\n" +
+ "class X {\n" +
+ " final int x;\n" +
+ " X() {\n" +
+ " I i = () -> {\n" +
+ " x = 20;\n" +
+ " };\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 6)\n" +
+ " X() {\n" +
+ " ^^^\n" +
+ "The blank final field x may not have been initialized\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 8)\n" +
+ " x = 20;\n" +
+ " ^\n" +
+ "The final field X.x cannot be assigned\n" +
+ "----------\n");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=433588, [1.8][compiler] ECJ compiles an ambiguous call in the presence of an unrelated unused method.
+public void test433588() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.IOException;\n" +
+ "import java.nio.file.Files;\n" +
+ "import java.nio.file.Paths;\n" +
+ "import java.util.function.Consumer;\n" +
+ "import java.util.stream.Stream;\n" +
+ "public class X {\n" +
+ " private interface StreamyBase<T, E extends Exception> {\n" +
+ " @SuppressWarnings(\"unused\")\n" +
+ " default void forEachOrdered(Consumer<? super T> action) throws E {}\n" +
+ " }\n" +
+ " abstract private static class AbstractStream<T, E extends Exception, STREAM, SELF extends AbstractStream<T, E, STREAM, SELF, CONSUMER>, CONSUMER> implements StreamyBase<T, E> {\n" +
+ " @SuppressWarnings(\"unused\")\n" +
+ " public void forEachOrdered(CONSUMER action) throws E {}\n" +
+ " // remove this method with a warning about it being unused:\n" +
+ " public final @SafeVarargs void forEachOrdered(Consumer<? super T> action, Consumer<? super T>... actions) throws E {}\n" +
+ " }\n" +
+ " private static class UnStream<T> extends AbstractStream<T, RuntimeException, Stream<T>, UnStream<T>, Consumer<? super T>> {}\n" +
+ " private static class IOStream<T> extends AbstractStream<T, IOException, Stream<T>, IOStream<T>, IOConsumer<? super T>> {}\n" +
+ " @FunctionalInterface\n" +
+ " private interface ExConsumer<T, E extends Exception> {\n" +
+ " void accept(T t1) throws E;\n" +
+ " }\n" +
+ " @FunctionalInterface\n" +
+ " private interface IOConsumer<T> extends ExConsumer<T, IOException> {}\n" +
+ " public static void tests1(IOStream<String> lines1, UnStream<String> lines2) throws IOException {\n" +
+ " IOConsumer<? super String> action = s -> Files.isHidden(Paths.get(s));\n" +
+ " Consumer<? super String> action2 = s -> System.out.println(s);\n" +
+ " // After removal these two become ambiguous:\n" +
+ " lines1.forEachOrdered(s -> Files.isHidden(Paths.get(s)));\n" +
+ " lines1.forEachOrdered(s -> System.out.println(s));\n" +
+ " lines1.forEachOrdered(action);\n" +
+ " lines1.forEachOrdered(action2);\n" +
+ " lines2.forEachOrdered(action2);\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. WARNING in X.java (at line 15)\n" +
+ " public final @SafeVarargs void forEachOrdered(Consumer<? super T> action, Consumer<? super T>... actions) throws E {}\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "The method forEachOrdered(Consumer<? super T>, Consumer<? super T>...) from the type X.AbstractStream<T,E,STREAM,SELF,CONSUMER> is never used locally\n" +
+ "----------\n" +
+ "2. WARNING in X.java (at line 17)\n" +
+ " private static class UnStream<T> extends AbstractStream<T, RuntimeException, Stream<T>, UnStream<T>, Consumer<? super T>> {}\n" +
+ " ^^^^^^^^\n" +
+ "Access to enclosing constructor X.AbstractStream<T,E,STREAM,SELF,CONSUMER>() is emulated by a synthetic accessor method\n" +
+ "----------\n" +
+ "3. WARNING in X.java (at line 18)\n" +
+ " private static class IOStream<T> extends AbstractStream<T, IOException, Stream<T>, IOStream<T>, IOConsumer<? super T>> {}\n" +
+ " ^^^^^^^^\n" +
+ "Access to enclosing constructor X.AbstractStream<T,E,STREAM,SELF,CONSUMER>() is emulated by a synthetic accessor method\n" +
+ "----------\n" +
+ "4. ERROR in X.java (at line 29)\n" +
+ " lines1.forEachOrdered(s -> Files.isHidden(Paths.get(s)));\n" +
+ " ^^^^^^^^^^^^^^\n" +
+ "The method forEachOrdered(X.IOConsumer<? super String>) is ambiguous for the type X.IOStream<String>\n" +
+ "----------\n" +
+ "5. ERROR in X.java (at line 30)\n" +
+ " lines1.forEachOrdered(s -> System.out.println(s));\n" +
+ " ^^^^^^^^^^^^^^\n" +
+ "The method forEachOrdered(X.IOConsumer<? super String>) is ambiguous for the type X.IOStream<String>\n" +
+ "----------\n");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=433588, [1.8][compiler] ECJ compiles an ambiguous call in the presence of an unrelated unused method.
+public void test433588a() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.IOException;\n" +
+ "import java.nio.file.Files;\n" +
+ "import java.nio.file.Paths;\n" +
+ "import java.util.function.Consumer;\n" +
+ "import java.util.stream.Stream;\n" +
+ "public class X {\n" +
+ " private interface StreamyBase<T, E extends Exception> {\n" +
+ " @SuppressWarnings(\"unused\")\n" +
+ " default void forEachOrdered(Consumer<? super T> action) throws E {}\n" +
+ " }\n" +
+ " abstract private static class AbstractStream<T, E extends Exception, STREAM, SELF extends AbstractStream<T, E, STREAM, SELF, CONSUMER>, CONSUMER> implements StreamyBase<T, E> {\n" +
+ " @SuppressWarnings(\"unused\")\n" +
+ " public void forEachOrdered(CONSUMER action) throws E {}\n" +
+ " // remove this method with a warning about it being unused:\n" +
+ " // public final @SafeVarargs void forEachOrdered(Consumer<? super T> action, Consumer<? super T>... actions) throws E {}\n" +
+ " }\n" +
+ " private static class UnStream<T> extends AbstractStream<T, RuntimeException, Stream<T>, UnStream<T>, Consumer<? super T>> {}\n" +
+ " private static class IOStream<T> extends AbstractStream<T, IOException, Stream<T>, IOStream<T>, IOConsumer<? super T>> {}\n" +
+ " @FunctionalInterface\n" +
+ " private interface ExConsumer<T, E extends Exception> {\n" +
+ " void accept(T t1) throws E;\n" +
+ " }\n" +
+ " @FunctionalInterface\n" +
+ " private interface IOConsumer<T> extends ExConsumer<T, IOException> {}\n" +
+ " public static void tests1(IOStream<String> lines1, UnStream<String> lines2) throws IOException {\n" +
+ " IOConsumer<? super String> action = s -> Files.isHidden(Paths.get(s));\n" +
+ " Consumer<? super String> action2 = s -> System.out.println(s);\n" +
+ " // After removal these two become ambiguous:\n" +
+ " lines1.forEachOrdered(s -> Files.isHidden(Paths.get(s)));\n" +
+ " lines1.forEachOrdered(s -> System.out.println(s));\n" +
+ " lines1.forEachOrdered(action);\n" +
+ " lines1.forEachOrdered(action2);\n" +
+ " lines2.forEachOrdered(action2);\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. WARNING in X.java (at line 17)\n" +
+ " private static class UnStream<T> extends AbstractStream<T, RuntimeException, Stream<T>, UnStream<T>, Consumer<? super T>> {}\n" +
+ " ^^^^^^^^\n" +
+ "Access to enclosing constructor X.AbstractStream<T,E,STREAM,SELF,CONSUMER>() is emulated by a synthetic accessor method\n" +
+ "----------\n" +
+ "2. WARNING in X.java (at line 18)\n" +
+ " private static class IOStream<T> extends AbstractStream<T, IOException, Stream<T>, IOStream<T>, IOConsumer<? super T>> {}\n" +
+ " ^^^^^^^^\n" +
+ "Access to enclosing constructor X.AbstractStream<T,E,STREAM,SELF,CONSUMER>() is emulated by a synthetic accessor method\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 29)\n" +
+ " lines1.forEachOrdered(s -> Files.isHidden(Paths.get(s)));\n" +
+ " ^^^^^^^^^^^^^^\n" +
+ "The method forEachOrdered(X.IOConsumer<? super String>) is ambiguous for the type X.IOStream<String>\n" +
+ "----------\n" +
+ "4. ERROR in X.java (at line 30)\n" +
+ " lines1.forEachOrdered(s -> System.out.println(s));\n" +
+ " ^^^^^^^^^^^^^^\n" +
+ "The method forEachOrdered(X.IOConsumer<? super String>) is ambiguous for the type X.IOStream<String>\n" +
+ "----------\n");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=433735, [1.8] Discrepancy with javac when dealing with local classes in lambda expressions
+public void test433735() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.util.function.Supplier;\n" +
+ "class E {\n" +
+ " E(Supplier<Object> factory) { }\n" +
+ "}\n" +
+ "public class X extends E {\n" +
+ " X() {\n" +
+ " super( () -> {\n" +
+ " class Z extends E {\n" +
+ " Z() {\n" +
+ " super(new Supplier<Object>() {\n" +
+ " @Override\n" +
+ " public Object get() {\n" +
+ " return new Object();\n" +
+ " }\n" +
+ " });\n" +
+ " }\n" +
+ " } \n" +
+ " return new Z();\n" +
+ " });\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " new X();\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 7)\n" +
+ " super( () -> {\n" +
+ " ^^^^^\n" +
+ "No enclosing instance of type X is available due to some intermediate constructor invocation\n" +
+ "----------\n");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=432531 [1.8] VerifyError with anonymous subclass inside of lambda expression in the superclass constructor call
+public void test432531a() {
+ this.runNegativeTest(
+ new String[] {
+ "Y.java",
+ "import java.util.function.Supplier;\n" +
+ "class E {\n" +
+ " E(Supplier<Object> factory) { }\n" +
+ "}\n" +
+ "public class Y extends E {\n" +
+ " Y() {\n" +
+ " super( () -> {\n" +
+ " class Z extends E {\n" +
+ " Z() {\n" +
+ " super(() -> new Object());\n" +
+ " }\n" +
+ " }\n" +
+ " return new Z();\n" +
+ " });\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " new Y();\n" +
+ " }\n" +
+ "}"
+ },
+ "----------\n" +
+ "1. ERROR in Y.java (at line 7)\n" +
+ " super( () -> {\n" +
+ " ^^^^^\n" +
+ "No enclosing instance of type Y is available due to some intermediate constructor invocation\n" +
+ "----------\n");
+}
public static Class testClass() {
return NegativeLambdaExpressionsTest.class;
}
-} \ No newline at end of file
+}
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 1ad303e52..aadbe0103 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
@@ -3001,6 +3001,47 @@ public void test_default_nullness_017() {
"----------\n");
}
+// package case
+public void test_nullness_default_018() {
+ Map customOptions = getCompilerOptions();
+ customOptions.put(JavaCore.COMPILER_PB_MISSING_NONNULL_BY_DEFAULT_ANNOTATION, JavaCore.WARNING);
+ customOptions.put(JavaCore.COMPILER_PB_UNUSED_WARNING_TOKEN, JavaCore.ERROR);
+ runConformTestWithLibs(
+ new String[] {
+ "pack/NullWarn.java",
+ "package pack;\n" +
+ "@SuppressWarnings(\"null\")\n" +
+ "public class NullWarn {\n" +
+ "\n" +
+ " // Some code\n" +
+ "\n" +
+ "}\n"
+ },
+ customOptions,
+ "");
+
+}
+
+// type case (inside default package)
+public void test_nullness_default_018b() {
+ Map customOptions = getCompilerOptions();
+ customOptions.put(JavaCore.COMPILER_PB_MISSING_NONNULL_BY_DEFAULT_ANNOTATION, JavaCore.WARNING);
+ customOptions.put(JavaCore.COMPILER_PB_UNUSED_WARNING_TOKEN, JavaCore.ERROR);
+ runConformTestWithLibs(
+ new String[] {
+ "NullWarn.java",
+ "@SuppressWarnings(\"null\")\n" +
+ "public class NullWarn {\n" +
+ "\n" +
+ " // Some code\n" +
+ "\n" +
+ "}\n"
+ },
+ customOptions,
+ "");
+
+}
+
// redundant default annotations - class vs. inner class
public void test_redundant_annotation_01() {
Map customOptions = getCompilerOptions();
@@ -7437,4 +7478,128 @@ public void testBug434374c() {
getCompilerOptions(),
"");
}
+
+// @NNBD should not affect implicit constructor
+public void testBug443347() {
+ runConformTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "abstract class Super {\n" +
+ " Super(String s) { }\n" +
+ " abstract void bar();\n" +
+ " void foo() { bar(); }\n" +
+ "}\n" +
+ "\n" +
+ "@NonNullByDefault\n" +
+ "public class X {\n" +
+ " void test1(@Nullable String s) {\n" +
+ " new Super(s) {\n" +
+ " @Override\n" +
+ " void bar() {}\n" +
+ " }.foo();\n" +
+ " }\n" +
+ "}\n"
+ },
+ getCompilerOptions(),
+ "");
+}
+
+// explicit annotation on super ctor should be inherited
+public void testBug443347b() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "abstract class Super {\n" +
+ " Super(@NonNull String s) { }\n" +
+ " abstract void bar();\n" +
+ " void foo() { bar(); }\n" +
+ "}\n" +
+ "\n" +
+ "@NonNullByDefault\n" +
+ "public class X {\n" +
+ " void test1(@Nullable String s) {\n" +
+ " new Super(s) {\n" +
+ " @Override\n" +
+ " void bar() {}\n" +
+ " }.foo();\n" +
+ " }\n" +
+ "}\n"
+ },
+ getCompilerOptions(),
+ "----------\n" +
+ "1. ERROR in X.java (at line 11)\n" +
+ " new Super(s) {\n" +
+ " ^\n" +
+ (this.complianceLevel < ClassFileConstants.JDK1_8
+ ? "Null type mismatch: required \'@NonNull String\' but the provided value is specified as @Nullable\n"
+ : "Null type mismatch (type annotations): required \'@NonNull String\' but this expression has type \'@Nullable String\'\n") +
+ "----------\n");
+}
+
+// @NNBD on super ctor should be inherited
+public void testBug443347c() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "@NonNullByDefault\n" +
+ "abstract class Super {\n" +
+ " Super(String s) { }\n" +
+ " abstract void bar();\n" +
+ " void foo() { bar(); }\n" +
+ "}\n" +
+ "\n" +
+ "@NonNullByDefault\n" +
+ "public class X {\n" +
+ " void test1(@Nullable String s) {\n" +
+ " new Super(s) {\n" +
+ " @Override\n" +
+ " void bar() {}\n" +
+ " }.foo();\n" +
+ " }\n" +
+ "}\n"
+ },
+ getCompilerOptions(),
+ "----------\n" +
+ "1. ERROR in X.java (at line 12)\n" +
+ " new Super(s) {\n" +
+ " ^\n" +
+ (this.complianceLevel < ClassFileConstants.JDK1_8
+ ? "Null type mismatch: required \'@NonNull String\' but the provided value is specified as @Nullable\n"
+ : "Null type mismatch (type annotations): required \'@NonNull String\' but this expression has type \'@Nullable String\'\n") +
+ "----------\n");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=444024, Type mismatch error in annotation generics assignment which happens "sometimes"
+public void _test444024() {
+ this.runConformTest(
+ new String[] {
+ "ViewpointOrganisationEntity.java",
+ "abstract public class ViewpointOrganisationEntity<T> {\n" +
+ "}\n",
+ "MetaCombo.java",
+ "public @interface MetaCombo {\n" +
+ " Class< ? extends IComboDataSet< ? >> dataSet();\n" +
+ "}\n",
+ "IComboDataSet.java",
+ "public interface IComboDataSet<T> {\n" +
+ "}\n",
+ "ContractantTypeLister.java",
+ "public class ContractantTypeLister implements IComboDataSet<ContractantType> {\n" +
+ "}\n",
+ "ContractantType.java",
+ "@MetaCombo(dataSet = ContractantTypeLister.class)\n" +
+ "public class ContractantType extends ViewpointOrganisationEntity<Long> {\n" +
+ "}\n",
+ "Contractant.java",
+ "public class Contractant extends ViewpointOrganisationEntity<Long> {\n" +
+ " @MetaCombo(dataSet = ContractantTypeLister.class)\n" +
+ " public ContractantType getContractantType() {\n" +
+ " return null;\n" +
+ " }\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 1b9a3db33..f7f39ebc6 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
@@ -16,6 +16,7 @@ import java.util.Map;
import junit.framework.Test;
import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.tests.util.Util;
public class NullTypeAnnotationTest extends AbstractNullAnnotationTest {
@@ -26,7 +27,7 @@ public class NullTypeAnnotationTest extends AbstractNullAnnotationTest {
// 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[] { "testNullTypeInference3b" };
+// TESTS_NAMES = new String[] { "testBug441693other" };
// TESTS_NUMBERS = new int[] { 561 };
// TESTS_RANGE = new int[] { 1, 2049 };
}
@@ -3969,7 +3970,7 @@ public class NullTypeAnnotationTest extends AbstractNullAnnotationTest {
"1. ERROR in X.java (at line 17)\n" +
" getAdd(lx);\n" +
" ^^\n" +
- "Contradictory null annotations: method was inferred as \'void getAdd(List<@NonNull @Nullable capture#of @Nullable ? extends X>)\', but only one of \'@NonNull\' and \'@Nullable\' can be effective at any location\n" +
+ "Null type mismatch (type annotations): required \'List<@NonNull capture#of ? extends X>\' but this expression has type \'List<@Nullable capture#of ? extends X>\'\n" +
"----------\n");
}
public void testLocalArrays() {
@@ -5896,6 +5897,133 @@ public void testTypeVariable18raw() {
"Null type mismatch (type annotations): required \'@NonNull Collection\' but this expression has type \'@Nullable Collection\'\n" +
"----------\n");
}
+// top-level annotation is overridden at use-site, details remain - parameterized type
+public void testTypeVariable19() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import java.util.ArrayList;\n" +
+ "import java.util.List;\n" +
+ "\n" +
+ "import org.eclipse.jdt.annotation.NonNull;\n" +
+ "import org.eclipse.jdt.annotation.Nullable;\n" +
+ "interface I<T,U extends List<T>> {\n" +
+ " U get0();\n" +
+ " @Nullable U get1();\n" +
+ " @NonNull U get2();\n" +
+ "}\n" +
+ "class X {\n" +
+ " static String test (I<@Nullable String, @NonNull ArrayList<@Nullable String>> i1,\n" +
+ " I<@NonNull String, @Nullable ArrayList<@NonNull String>> i2, int s) {\n" +
+ " switch(s) {\n" +
+ " case 0 : return i1.get0().get(0).toUpperCase(); // problem at detail\n" +
+ " case 1 : return i1.get1().get(0).toUpperCase(); // 2 problems\n" +
+ " case 2 : return i1.get2().get(0).toUpperCase(); // problem at detail\n" +
+ " case 3 : return i2.get0().get(0).toUpperCase(); // problem at top\n" +
+ " case 4 : return i2.get1().get(0).toUpperCase(); // problem at top\n" +
+ " case 5 : return i2.get2().get(0).toUpperCase(); // OK\n" +
+ " default : return \"\";" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ getCompilerOptions(),
+ "----------\n" +
+ "1. ERROR in X.java (at line 15)\n" +
+ " case 0 : return i1.get0().get(0).toUpperCase(); // problem at detail\n" +
+ " ^^^^^^^^^^^^^^^^\n" +
+ "Potential null pointer access: The method get(int) may return null\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 16)\n" +
+ " case 1 : return i1.get1().get(0).toUpperCase(); // 2 problems\n" +
+ " ^^^^^^^^^\n" +
+ "Potential null pointer access: The method get1() may return null\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 16)\n" +
+ " case 1 : return i1.get1().get(0).toUpperCase(); // 2 problems\n" +
+ " ^^^^^^^^^^^^^^^^\n" +
+ "Potential null pointer access: The method get(int) may return null\n" +
+ "----------\n" +
+ "4. ERROR in X.java (at line 17)\n" +
+ " case 2 : return i1.get2().get(0).toUpperCase(); // problem at detail\n" +
+ " ^^^^^^^^^^^^^^^^\n" +
+ "Potential null pointer access: The method get(int) may return null\n" +
+ "----------\n" +
+ "5. ERROR in X.java (at line 18)\n" +
+ " case 3 : return i2.get0().get(0).toUpperCase(); // problem at top\n" +
+ " ^^^^^^^^^\n" +
+ "Potential null pointer access: The method get0() may return null\n" +
+ "----------\n" +
+ "6. ERROR in X.java (at line 19)\n" +
+ " case 4 : return i2.get1().get(0).toUpperCase(); // problem at top\n" +
+ " ^^^^^^^^^\n" +
+ "Potential null pointer access: The method get1() may return null\n" +
+ "----------\n");
+}
+// top-level annotation is overridden at use-site, array with anotations on dimensions
+public void testTypeVariable19a() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.NonNull;\n" +
+ "import org.eclipse.jdt.annotation.Nullable;\n" +
+ "interface I1<T> {\n" +
+ " T @Nullable[] get0();\n" +
+ " @Nullable T @NonNull[] get1();\n" +
+ " @Nullable T @Nullable[] get2();\n" +
+ "}\n" +
+ "interface I2<T> {\n" +
+ " T @NonNull[] get0();\n" +
+ " @NonNull T @NonNull[] get1();\n" +
+ " @NonNull T @Nullable[] get2();\n" +
+ "}\n" +
+ "class X {\n" +
+ " static String test (I1<@NonNull String> i1, I2<@Nullable String> i2, int s) {\n" +
+ " switch (s) {\n" +
+ " case 0: return i1.get0()[0].toUpperCase(); // problem on array\n" +
+ " case 1: return i1.get1()[0].toUpperCase(); // problem on element\n" +
+ " case 2: return i1.get2()[0].toUpperCase(); // 2 problems\n" +
+ " case 3: return i2.get0()[0].toUpperCase(); // problem on element\n" +
+ " case 4: return i2.get1()[0].toUpperCase(); // OK\n" +
+ " case 5: return i2.get2()[0].toUpperCase(); // problem on array\n" +
+ " default: return \"\";\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ getCompilerOptions(),
+ "----------\n" +
+ "1. ERROR in X.java (at line 16)\n" +
+ " case 0: return i1.get0()[0].toUpperCase(); // problem on array\n" +
+ " ^^^^^^^^^\n" +
+ "Potential null pointer access: The method get0() may return null\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 17)\n" +
+ " case 1: return i1.get1()[0].toUpperCase(); // problem on element\n" +
+ " ^^^^^^^^^^^^\n" +
+ "Potential null pointer access: array element may be null\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 18)\n" +
+ " case 2: return i1.get2()[0].toUpperCase(); // 2 problems\n" +
+ " ^^^^^^^^^\n" +
+ "Potential null pointer access: The method get2() may return null\n" +
+ "----------\n" +
+ "4. ERROR in X.java (at line 18)\n" +
+ " case 2: return i1.get2()[0].toUpperCase(); // 2 problems\n" +
+ " ^^^^^^^^^^^^\n" +
+ "Potential null pointer access: array element may be null\n" +
+ "----------\n" +
+ "5. ERROR in X.java (at line 19)\n" +
+ " case 3: return i2.get0()[0].toUpperCase(); // problem on element\n" +
+ " ^^^^^^^^^^^^\n" +
+ "Potential null pointer access: array element may be null\n" +
+ "----------\n" +
+ "6. ERROR in X.java (at line 21)\n" +
+ " case 5: return i2.get2()[0].toUpperCase(); // problem on array\n" +
+ " ^^^^^^^^^\n" +
+ "Potential null pointer access: The method get2() may return null\n" +
+ "----------\n");
+}
public void testBug434600() {
runConformTestWithLibs(
new String[] {
@@ -6394,4 +6522,240 @@ public void testBug435841() {
getCompilerOptions(),
"");
}
+public void testBug441693() {
+ runConformTestWithLibs(
+ new String[] {
+ "Foo.java",
+ "import org.eclipse.jdt.annotation.NonNull;\n" +
+ "import org.eclipse.jdt.annotation.NonNullByDefault;\n" +
+ "import org.eclipse.jdt.annotation.Nullable;\n" +
+ "\n" +
+ "@NonNullByDefault({})\n" +
+ "public abstract class Foo {\n" +
+ " \n" +
+ " abstract <T> @NonNull T requireNonNull(@Nullable T obj);\n" +
+ " \n" +
+ " @NonNull Iterable<@NonNull String> iterable;\n" +
+ " \n" +
+ " Foo(@Nullable Iterable<@NonNull String> iterable) {\n" +
+ " this.iterable = requireNonNull(iterable); // (*)\n" +
+ " }\n" +
+ "}\n"
+ },
+ getCompilerOptions(),
+ "");
+}
+public void testBug441693other() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "Foo.java",
+ "import org.eclipse.jdt.annotation.NonNull;\n" +
+ "import org.eclipse.jdt.annotation.NonNullByDefault;\n" +
+ "import org.eclipse.jdt.annotation.Nullable;\n" +
+ "import java.util.*;\n" +
+ "\n" +
+ "@NonNullByDefault({})\n" +
+ "public abstract class Foo {\n" +
+ " \n" +
+ " abstract <T> @NonNull T requireNonNull(@Nullable T obj);\n" +
+ " \n" +
+ " @NonNull String @NonNull[] array;\n" +
+ " \n" +
+ " Foo(@NonNull String @Nullable[] arr) {\n" +
+ " this.array = requireNonNull(arr); // (*)\n" +
+ " }\n" +
+ " @NonNull Foo testWild1(@Nullable List<? extends @NonNull Foo> foos) {\n" +
+ " return requireNonNull(foos).get(0);\n" +
+ " }\n" +
+ " @NonNull Foo testWild2(@Nullable List<@Nullable ? extends List<@NonNull Foo>> foos) {\n" +
+ " return requireNonNull(foos.get(0)).get(0);\n" +
+ " }\n" +
+ "}\n"
+ },
+ getCompilerOptions(),
+ "----------\n" +
+ "1. ERROR in Foo.java (at line 20)\n" +
+ " return requireNonNull(foos.get(0)).get(0);\n" +
+ " ^^^^\n" +
+ "Potential null pointer access: this expression has a \'@Nullable\' type\n" +
+ "----------\n");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=439158, [1.8][compiler][null] Adding null annotation to return type causes IllegalStateException and sometimes InvocationTargetException
+public void testBug439158() {
+ runConformTestWithLibs(
+ new String[] {
+ "Test.java",
+ "import java.util.Collection;\n" +
+ "import java.util.List;\n" +
+ "import java.util.Set;\n" +
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "\n" +
+ "public class Test {\n" +
+ " class X {\n" +
+ " \n" +
+ " }\n" +
+ " \n" +
+ " public static <C extends Collection<?>, A extends C, B extends C>\n" +
+ " @Nullable A transform(B arg) {\n" +
+ " return null;\n" +
+ " }\n" +
+ " \n" +
+ " public static void main(String[] args) {\n" +
+ " List<X> list = null;\n" +
+ " Set<X> result = transform(list);\n" +
+ " }\n" +
+ "}\n"
+ },
+ getCompilerOptions(),
+ "");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=434579, [1.8][compiler][null] Annotation-based null analysis causes incorrect type errors
+public void testBug434579() {
+ Map options = getCompilerOptions();
+ runConformTestWithLibs(
+ new String[] {
+ "AbstractNode.java",
+ "import org.eclipse.jdt.annotation.NonNullByDefault;\n" +
+ "@NonNullByDefault\n" +
+ "interface ExtendedNode {\n" +
+ " ExtendedNode getParent();\n" +
+ " void setParent(ExtendedNode newParent);\n" +
+ "}\n" +
+ "@NonNullByDefault\n" +
+ "public class AbstractNode implements ExtendedNode {\n" +
+ " private ExtendedNode parent;\n" +
+ " protected AbstractNode() {\n" +
+ " parent = this;\n" +
+ " }\n" +
+ " @Override\n" +
+ " public ExtendedNode getParent() {\n" +
+ " return parent;\n" +
+ " }\n" +
+ " @Override\n" +
+ " public void setParent(final ExtendedNode newParent) {\n" +
+ " parent = newParent;\n" +
+ " }\n" +
+ "}\n"
+ },
+ options,
+ "");
+ runConformTestWithLibs(
+ new String[] {
+ "UnequalBinaryNode.java",
+ "public class UnequalBinaryNode<L extends ExtendedNode, R extends ExtendedNode>\n" +
+ " extends AbstractNode {\n" +
+ " private L left;\n" +
+ " private R right;\n" +
+ " public UnequalBinaryNode(final L initialLeft, final R initialRight) {\n" +
+ " left = initialLeft;\n" +
+ " right = initialRight;\n" +
+ " left.setParent(this);\n" +
+ " right.setParent(this); // error on this line without fix\n" +
+ " }\n" +
+ "}\n"
+ },
+ options,
+ "");
+}
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=434582,
+//[1.8][compiler][null] @Nullable annotation in type parameter causes NullPointerException in JDT core
+public void testBug434582() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.Nullable;\n" +
+ "import org.eclipse.jdt.annotation.NonNullByDefault;\n" +
+ "@NonNullByDefault\n" +
+ "class ProgramNode {}\n" +
+ "@NonNullByDefault\n" +
+ "interface ConcreteNodeVisitor<R, P> {\n" +
+ " R visit(ProgramNode node, P extraParameter);\n" +
+ "}\n" +
+ "public class X implements\n" +
+ " ConcreteNodeVisitor<Boolean, @Nullable Object> {\n" +
+ " public Boolean visit(ProgramNode node, Object extraParameter) {\n" +
+ " return Boolean.FALSE;\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. WARNING in X.java (at line 11)\n" +
+ " public Boolean visit(ProgramNode node, Object extraParameter) {\n" +
+ " ^^^^^^^^^^^\n" +
+ "Missing non-null annotation: inherited method from ConcreteNodeVisitor<Boolean,Object> specifies this parameter as @NonNull\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 11)\n" +
+ " public Boolean visit(ProgramNode node, Object extraParameter) {\n" +
+ " ^^^^^^\n" +
+ "Missing nullable annotation: inherited method from ConcreteNodeVisitor<Boolean,Object> specifies this parameter as @Nullable\n" +
+ "----------\n");
+}
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=434582,
+//[1.8][compiler][null] @Nullable annotation in type parameter causes NullPointerException in JDT core
+public void testBug434582a() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.Nullable;\n" +
+ "import org.eclipse.jdt.annotation.NonNullByDefault;\n" +
+ "@NonNullByDefault\n" +
+ "class ProgramNode {}\n" +
+ "@NonNullByDefault\n" +
+ "interface ConcreteNodeVisitor<R, P> {\n" +
+ " void visit(ProgramNode node, P extraParameter);\n" +
+ "}\n" +
+ "public class X implements\n" +
+ " ConcreteNodeVisitor<Boolean, @Nullable Object> {\n" +
+ " public void visit(ProgramNode node, Object extraParameter) {}\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. WARNING in X.java (at line 11)\n" +
+ " public void visit(ProgramNode node, Object extraParameter) {}\n" +
+ " ^^^^^^^^^^^\n" +
+ "Missing non-null annotation: inherited method from ConcreteNodeVisitor<Boolean,Object> specifies this parameter as @NonNull\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 11)\n" +
+ " public void visit(ProgramNode node, Object extraParameter) {}\n" +
+ " ^^^^^^\n" +
+ "Missing nullable annotation: inherited method from ConcreteNodeVisitor<Boolean,Object> specifies this parameter as @Nullable\n" +
+ "----------\n");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=443467, [1.8][null]InternalError: Unexpected binding type
+public void test443467() throws Exception {
+ String jreDirectory = Util.getJREDirectory();
+ String jfxJar = Util.toNativePath(jreDirectory + "/lib/ext/jfxrt.jar");
+ this.runNegativeTestWithExtraLibs(
+ new String[] {
+ "BuildIdeMain.java",
+ "import java.nio.file.Path;\n" +
+ "import java.time.Instant;\n" +
+ "import java.util.HashMap;\n" +
+ "import java.util.stream.Stream;\n" +
+ "import javafx.util.Pair;\n" +
+ "\n" +
+ "public class BuildIdeMain {\n" +
+ "static void writeUpdates(Stream<Path> filter2, HashMap<Path, Pair<byte[], Instant>> ideFiles, HashMap<Path, Path> updateToFile) {\n" +
+ " filter2.map(p -> new Pair<>(updateToFile.get(p), p->ideFiles.get(p)));\n" +
+ "}\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in BuildIdeMain.java (at line 9)\n" +
+ " filter2.map(p -> new Pair<>(updateToFile.get(p), p->ideFiles.get(p)));\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "The constructor Pair<Path,Object>(Path, (<no type> p) -> {}) is undefined\n" +
+ "----------\n" +
+ "2. ERROR in BuildIdeMain.java (at line 9)\n" +
+ " filter2.map(p -> new Pair<>(updateToFile.get(p), p->ideFiles.get(p)));\n" +
+ " ^^^^^^^^^^^^^^^^^^\n" +
+ "The target type of this expression must be a functional interface\n" +
+ "----------\n" +
+ "3. ERROR in BuildIdeMain.java (at line 9)\n" +
+ " filter2.map(p -> new Pair<>(updateToFile.get(p), p->ideFiles.get(p)));\n" +
+ " ^^^^^^^^^^^^^^^^^^\n" +
+ "The target type of this expression must be a functional interface\n" +
+ "----------\n",
+ new String[]{jfxJar});
+}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ScannerTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ScannerTest.java
index 46bc6a704..4a4073732 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ScannerTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ScannerTest.java
@@ -1368,4 +1368,34 @@ public class ScannerTest extends AbstractRegressionTest {
}
assertEquals("Expecting ::", ITerminalSymbols.TokenNameCOLON_COLON, token);
}
+
+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=443854
+ public void test064() {
+ String source =
+ "public enum X {\n" +
+ " Hello\\u205fworld;\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(Hello\\u205fworld);\n" +
+ " System.out.println(Character.isJavaIdentifierPart('\\u205f')); // false\n" +
+ " }\n" +
+ "}";
+ if (this.complianceLevel > ClassFileConstants.JDK1_5) {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ source
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 2)\n" +
+ " Hello\\u205fworld;\n" +
+ " ^^^^^^\n" +
+ "Syntax error on token \"Invalid Character\", , expected\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 4)\n" +
+ " System.out.println(Hello\\u205fworld);\n" +
+ " ^^^^^^\n" +
+ "Syntax error on token \"Invalid Character\", invalid AssignmentOperator\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 94f1d61c9..d58ce0a44 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
@@ -9,6 +9,11 @@
* Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
* Bug 405104 - [1.8][compiler][codegen] Implement support for serializeable lambdas
* Bug 439889 - [1.8][compiler] [lambda] Deserializing lambda fails with IllegalArgumentException: "Invalid lambda deserialization"
+ * Bug 442416 - $deserializeLambda$ missing cases for nested lambdas
+ * Bug 442418 - $deserializeLambda$ off-by-one error when deserializing the captured arguments of a lambda that also capture this
+ * Olivier Tardieu tardieu@us.ibm.com - Contributions for
+ * Bug 442416 - $deserializeLambda$ missing cases for nested lambdas
+ * Bug 442418 - $deserializeLambda$ off-by-one error when deserializing the captured arguments of a lambda that also capture this
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -1314,6 +1319,98 @@ public class SerializableLambdaTest extends AbstractRegressionTest {
null,true,
new String[]{"-Ddummy"}); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution.
}
+
+ public void testNestedLambdas_442416() throws Exception {
+ this.runConformTest(
+ new String[]{
+ "Foo.java",
+ "import java.io.*;\n"+
+ "public class Foo {\n"+
+ " static byte[] toSer(Object o) {\n"+
+ " try {\n"+
+ " final ByteArrayOutputStream buffer = new ByteArrayOutputStream();\n"+
+ " try (ObjectOutputStream out = new ObjectOutputStream(buffer) ) {\n"+
+ " out.writeObject(o);\n"+
+ " }\n"+
+ " return buffer.toByteArray();\n"+
+ " } catch (Exception e) {e.printStackTrace();return null;}\n"+
+ " }\n"+
+ " static Object fromSer(byte[] bs) {\n"+
+ " try {\n"+
+ " try (ObjectInputStream in = new ObjectInputStream( new ByteArrayInputStream(bs))) {\n"+
+ " final Object s = in.readObject();\n"+
+ " return s;\n"+
+ " }\n"+
+ " } catch (Exception e) {e.printStackTrace();return null;}\n"+
+ " }\n"+
+ " public static void main(String[] args) throws Exception {\n"+
+ " Runnable nested1,nested2;\n"+
+ " Runnable lambda0 = (java.io.Serializable & Runnable) () -> {\n"+
+ " Runnable lambda1 = (java.io.Serializable & Runnable) () -> {\n"+
+ " Runnable lambda2 = (java.io.Serializable & Runnable) () -> {\n"+
+ " System.out.println(\"Hello,world!\");\n"+
+ " };\n"+
+ " byte[] bs = toSer(lambda2);\n"+
+ " Runnable r = (Runnable)fromSer(bs);\n"+
+ " r.run();\n"+
+ " };\n"+
+ " byte[] bs = toSer(lambda1);\n"+
+ " Runnable r = (Runnable)fromSer(bs);\n"+
+ " r.run();\n"+
+ " };\n"+
+ " byte[] bs = toSer(lambda0);\n"+
+ " Runnable r = (Runnable)fromSer(bs);\n"+
+ " r.run();\n"+
+ " }\n"+
+ "}\n",
+ },
+ "Hello,world!",
+ null,true,
+ new String[]{"-Ddummy"}); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution.
+ }
+
+ public void testBindingThis_442418() throws Exception {
+ this.runConformTest(
+ new String[]{
+ "Foo.java",
+ "import java.io.*;\n"+
+ "public class Foo implements Serializable {\n"+
+ " static byte[] toSer(Object o) {\n"+
+ " try {\n"+
+ " final ByteArrayOutputStream buffer = new ByteArrayOutputStream();\n"+
+ " try (ObjectOutputStream out = new ObjectOutputStream(buffer) ) {\n"+
+ " out.writeObject(o);\n"+
+ " }\n"+
+ " return buffer.toByteArray();\n"+
+ " } catch (Exception e) {e.printStackTrace();return null;}\n"+
+ " }\n"+
+ " static Object fromSer(byte[] bs) {\n"+
+ " try {\n"+
+ " try (ObjectInputStream in = new ObjectInputStream( new ByteArrayInputStream(bs))) {\n"+
+ " final Object s = in.readObject();\n"+
+ " return s;\n"+
+ " }\n"+
+ " } catch (Exception e) {e.printStackTrace();return null;}\n"+
+ " }\n"+
+ " void m(int i) {\n"+
+ " System.out.println(i);\n"+
+ " }\n"+
+ " void n(int i) {\n"+
+ " Runnable lambda = (java.io.Serializable & Runnable) () -> { this.m(i); };\n"+
+ " byte[] bs = toSer(lambda);\n"+
+ " Runnable r = (Runnable)fromSer(bs);\n"+
+ " r.run();\n"+
+ " }\n"+
+ " public static void main(String[] args) throws Exception {\n"+
+ " new Foo().n(42);\n"+
+ " }\n"+
+ "}\n",
+ },
+ "42",
+ null,true,
+ new String[]{"-Ddummy"}); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution.
+ }
+
// ---
private void checkExpected(String expected, String actual) {
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/eval/DebugEvaluationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/eval/DebugEvaluationTest.java
index f675eb41d..4252cdceb 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/eval/DebugEvaluationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/eval/DebugEvaluationTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 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
@@ -561,11 +561,11 @@ public void test011() throws Exception {
/**
* Set local variable 'date'.
*/
-public void test012() throws Exception {
+public void _test012() throws Exception {
String userCode =
"java.util.GregorianCalendar cal = new java.util.GregorianCalendar();\n" +
"java.util.Date date = cal.getGregorianChange();\n" +
- "date.toString();";
+ "System.out.println(\"Old date =\t\" + date.toString());";
JDIStackFrame stackFrame = new JDIStackFrame(
this.jdiVM,
this,
@@ -575,7 +575,10 @@ public void test012() throws Exception {
char[] snippet = "date = new java.util.Date();".toCharArray();
evaluate(stackFrame, requestor, snippet);
requestor = new DebugRequestor();
- snippet = "return date.after(cal.getGregorianChange());".toCharArray();
+ userCode = "System.out.println(\"new date =\t\" + date.toString());\n" +
+ "System.out.println(\"cal.getGregorianChange() =\t\" + cal.getGregorianChange());\n" +
+ "return date.after(cal.getGregorianChange());";
+ snippet = userCode.toCharArray();
evaluate(stackFrame, requestor, snippet);
assertTrue("Should get one result but got " + requestor.resultIndex+1, requestor.resultIndex == 0);
EvaluationResult result = requestor.results[0];
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/AbstractCompilerTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/AbstractCompilerTest.java
index a2dc69f6a..ae4112032 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/AbstractCompilerTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/AbstractCompilerTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 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
@@ -250,7 +250,9 @@ public class AbstractCompilerTest extends TestCase {
long highestLevel = highestComplianceLevels();
if (highestLevel < uniqueCompliance) {
String complianceString;
- if (highestLevel == ClassFileConstants.JDK1_7)
+ if (highestLevel == ClassFileConstants.JDK1_8)
+ complianceString = "1.8";
+ else if (highestLevel == ClassFileConstants.JDK1_7)
complianceString = "1.7";
else if (highestLevel == ClassFileConstants.JDK1_6)
complianceString = "1.6";
diff --git a/org.eclipse.jdt.core.tests.compiler/test.xml b/org.eclipse.jdt.core.tests.compiler/test.xml
index c4e07bb77..89441a14d 100644
--- a/org.eclipse.jdt.core.tests.compiler/test.xml
+++ b/org.eclipse.jdt.core.tests.compiler/test.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright (c) 2002, 2011 IBM Corporation and others.
+ Copyright (c) 2002, 2014 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
@@ -89,9 +89,4 @@
-->
</target>
-
- <!-- This target runs the performance test suites. -->
- <target name="performance">
- </target>
-
</project>
diff --git a/org.eclipse.jdt.core.tests.compiler/workspace/Bug422832ClassFile/aspose.pdf.jar b/org.eclipse.jdt.core.tests.compiler/workspace/Bug422832ClassFile/aspose.pdf.jar
new file mode 100644
index 000000000..5c32d6450
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.compiler/workspace/Bug422832ClassFile/aspose.pdf.jar
Binary files differ
diff --git a/org.eclipse.jdt.core.tests.model/JCL/jclMin1.8.jar b/org.eclipse.jdt.core.tests.model/JCL/jclMin1.8.jar
index 2b78416f3..0e017da1d 100644
--- a/org.eclipse.jdt.core.tests.model/JCL/jclMin1.8.jar
+++ b/org.eclipse.jdt.core.tests.model/JCL/jclMin1.8.jar
Binary files differ
diff --git a/org.eclipse.jdt.core.tests.model/JCL/jclMin1.8src.zip b/org.eclipse.jdt.core.tests.model/JCL/jclMin1.8src.zip
index 0757f3a23..c85ea263d 100644
--- a/org.eclipse.jdt.core.tests.model/JCL/jclMin1.8src.zip
+++ b/org.eclipse.jdt.core.tests.model/JCL/jclMin1.8src.zip
Binary files differ
diff --git a/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF
index 4b75946c5..d9f193421 100644
--- a/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF
@@ -23,7 +23,8 @@ Require-Bundle: org.eclipse.core.resources;bundle-version="[3.2.0,4.0.0)",
org.eclipse.text;bundle-version="[3.2.0,4.0.0)",
com.ibm.icu;bundle-version="3.4.4",
org.eclipse.core.filesystem;bundle-version="[1.2.0,2.0.0)",
- org.eclipse.jdt.annotation;bundle-version="[1.0.0,3.0.0)"
+ org.eclipse.jdt.annotation;bundle-version="[1.1.0,2.0.0)";resolution:=optional,
+ org.eclipse.jdt.annotation;bundle-version="[2.0.0,3.0.0)";resolution:=optional
Bundle-RequiredExecutionEnvironment: J2SE-1.4
Eclipse-BundleShape: dir
Bundle-Activator: org.eclipse.jdt.core.tests.Activator
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java
index 2530e9aef..e9e5f0298 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java
@@ -4858,5 +4858,50 @@ public void testBug432175() throws JavaModelException {
this.ast.newSimpleType(this.ast.newName(res));
}
}
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=435348, [1.8][compiler] NPE in JDT Core during AST creation
+// NPE without fix
+public void testBug435348() throws JavaModelException {
+ this.workingCopy = getWorkingCopy("/Converter18/src/testBug435348/X.java",
+ true/* resolve */);
+ String contents = "package testBug435348;\n" +
+ "class Y {}\n" +
+ "class Z{}\n" +
+ "class X {\n" +
+ " void bar2(@ Z z) {}\n" +
+ " // ^ Illegal @ \n" +
+ " static {\n" +
+ " bar(new Y() {});\n" +
+ " }\n" +
+ "}\n";
+ buildAST(contents, this.workingCopy, false);
+}
+public void testBug432614() throws JavaModelException {
+ this.workingCopy = getWorkingCopy("/Converter18/src/testBug432614/X.java", true);
+ String contents = "package testBug432614;\n" +
+ "import java.lang.annotation.ElementType;\n" +
+ "import java.lang.annotation.Target;\n" +
+ "public class X {\n" +
+ " FI fi1= (@T2 int i) -> {};\n" +
+ "}\n" +
+ "interface FI {\n" +
+ " void foo(@T1 int iii);\n" +
+ "}\n" +
+ "@Target(ElementType.TYPE_USE) @interface T1 {}\n" +
+ "@Target(ElementType.TYPE_USE) @interface T2 {}";
+ CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy);
+ TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, 0);
+ FieldDeclaration fieldDeclaration = (FieldDeclaration) typedeclaration.bodyDeclarations().get(0);
+ VariableDeclarationFragment fragment = (VariableDeclarationFragment)fieldDeclaration.fragments().get(0);
+ Expression expression = fragment.getInitializer();
+ assertTrue(expression instanceof LambdaExpression);
+ LambdaExpression lambdaExpression = (LambdaExpression)expression;
+ assertEquals("(@T2 int i) -> {\n}\n", lambdaExpression.toString());
+ assertTrue(lambdaExpression.parameters().size() == 1);
+ IMethodBinding binding = lambdaExpression.resolveMethodBinding();
+ ITypeBinding[] params = binding.getParameterTypes();
+ assertEquals("Incorrect no of parameters", 1, params.length);
+ ITypeBinding thatParam = params[0];
+ assertEquals("Incorrect param", "@T2 int", thatParam.toString());
+}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST3_2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST3_2.java
index 908679449..8fa744141 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST3_2.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST3_2.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 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
@@ -7576,7 +7576,7 @@ public class ASTConverterTestAST3_2 extends ConverterTestSetup {
/**
* http://dev.eclipse.org/bugs/show_bug.cgi?id=129330
*/
- public void _test0642() throws JavaModelException {
+ public void test0642() throws JavaModelException {
ICompilationUnit workingCopy = null;
try {
String contents =
@@ -7594,7 +7594,7 @@ public class ASTConverterTestAST3_2 extends ConverterTestSetup {
true);
assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
CompilationUnit unit = (CompilationUnit) node;
- assertProblemsSize(unit, 1, "Syntax error, insert \"AssignmentOperator Expression\" to complete Expression");
+ assertProblemsSize(unit, 1, "Syntax error, insert \"VariableDeclarators\" to complete LocalVariableDeclaration");
node = getASTNode(unit, 0, 0, 0);
assertEquals("Not an expression statement", ASTNode.EXPRESSION_STATEMENT, node.getNodeType());
assertTrue("Not recovered", isRecovered(node));
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST4_2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST4_2.java
index 6b17366f5..94138a038 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST4_2.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST4_2.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2013 IBM Corporation and others.
+ * Copyright (c) 2011, 2014 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
@@ -7574,7 +7574,7 @@ public class ASTConverterTestAST4_2 extends ConverterTestSetup {
/**
* http://dev.eclipse.org/bugs/show_bug.cgi?id=129330
*/
- public void _test0642() throws JavaModelException {
+ public void test0642() throws JavaModelException {
ICompilationUnit workingCopy = null;
try {
String contents =
@@ -7592,7 +7592,7 @@ public class ASTConverterTestAST4_2 extends ConverterTestSetup {
true);
assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
CompilationUnit unit = (CompilationUnit) node;
- assertProblemsSize(unit, 1, "Syntax error, insert \"AssignmentOperator Expression\" to complete Expression");
+ assertProblemsSize(unit, 1, "Syntax error, insert \"VariableDeclarators\" to complete LocalVariableDeclaration");
node = getASTNode(unit, 0, 0, 0);
assertEquals("Not an expression statement", ASTNode.EXPRESSION_STATEMENT, node.getNodeType());
assertTrue("Not recovered", isRecovered(node));
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST8_2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST8_2.java
index db01e20a0..1edd12112 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST8_2.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST8_2.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2013 IBM Corporation and others.
+ * Copyright (c) 2011, 2014 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
@@ -10777,4 +10777,30 @@ public class ASTConverterTestAST8_2 extends ConverterTestSetup {
}
}
}
+ /**
+ * @deprecated
+ * @throws JavaModelException
+ */
+ public void testBug443942() throws JavaModelException {
+ ICompilationUnit sourceUnit = getCompilationUnit("Converter", "src", "org.eclipse.swt.internal.gtk", "A.java"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ try {
+ ReconcilerTests.ProblemRequestor pbRequestor = new ReconcilerTests.ProblemRequestor() {
+ public boolean isActive() {
+ return false;
+ }
+ };
+ sourceUnit.becomeWorkingCopy(pbRequestor, null);
+ sourceUnit.getBuffer().setContents(
+ "package org.eclipse.swt.internal.gtk;\n" +
+ "public class X {\n" +
+ " public static final native long /*int*/ realpath(byte[] path, byte[] realPath);\n" +
+ "}"
+ );
+ // TODO improve test for AST.JLS8
+ CompilationUnit unit = sourceUnit.reconcile(AST.JLS8, false, null, null);
+ assertEquals("Unexpected well known type", null, unit.getAST().resolveWellKnownType("void"));
+ } finally {
+ sourceUnit.discardWorkingCopy();
+ }
+ }
} \ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java
index 72870cccd..70e86b3b2 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 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
@@ -1746,6 +1746,11 @@ public class ASTTest extends org.eclipse.jdt.core.tests.junit.extension.TestCase
x.setEscapedValue("\"'\"");
assertEquals("", "\"'\"", x.getEscapedValue());
assertEquals("", "'", x.getLiteralValue());
+
+ // test for bug 442614
+ x.setLiteralValue("\0041");
+ assertEquals("", "\"\\u00041\"", x.getEscapedValue());
+ assertEquals("", "\u00041", x.getLiteralValue());
}
public void testStringLiteralUnicode() {
@@ -1884,23 +1889,27 @@ public class ASTTest extends org.eclipse.jdt.core.tests.junit.extension.TestCase
x.setCharValue('\r');
assertTrue(x.getEscapedValue().equals("\'\\r\'")); //$NON-NLS-1$
x.setCharValue('\"');
- assertTrue(x.getEscapedValue().equals("\'\\\"\'")); //$NON-NLS-1$
+ assertTrue(x.getEscapedValue().equals("\'\"\'")); //$NON-NLS-1$
x.setCharValue('\0');
- assertTrue(x.getEscapedValue().equals("\'\\0\'")); //$NON-NLS-1$
+ assertTrue(x.getEscapedValue().equals("\'\\u0000\'")); //$NON-NLS-1$
x.setCharValue('\1');
- assertTrue(x.getEscapedValue().equals("\'\\1\'")); //$NON-NLS-1$
+ assertTrue(x.getEscapedValue().equals("\'\\u0001\'")); //$NON-NLS-1$
x.setCharValue('\2');
- assertTrue(x.getEscapedValue().equals("\'\\2\'")); //$NON-NLS-1$
+ assertTrue(x.getEscapedValue().equals("\'\\u0002\'")); //$NON-NLS-1$
x.setCharValue('\3');
- assertTrue(x.getEscapedValue().equals("\'\\3\'")); //$NON-NLS-1$
+ assertTrue(x.getEscapedValue().equals("\'\\u0003\'")); //$NON-NLS-1$
x.setCharValue('\4');
- assertTrue(x.getEscapedValue().equals("\'\\4\'")); //$NON-NLS-1$
+ assertTrue(x.getEscapedValue().equals("\'\\u0004\'")); //$NON-NLS-1$
x.setCharValue('\5');
- assertTrue(x.getEscapedValue().equals("\'\\5\'")); //$NON-NLS-1$
+ assertTrue(x.getEscapedValue().equals("\'\\u0005\'")); //$NON-NLS-1$
x.setCharValue('\6');
- assertTrue(x.getEscapedValue().equals("\'\\6\'")); //$NON-NLS-1$
+ assertTrue(x.getEscapedValue().equals("\'\\u0006\'")); //$NON-NLS-1$
x.setCharValue('\7');
- assertTrue(x.getEscapedValue().equals("\'\\7\'")); //$NON-NLS-1$
+ assertTrue(x.getEscapedValue().equals("\'\\u0007\'")); //$NON-NLS-1$
+ x.setCharValue('\33');
+ assertTrue(x.getEscapedValue().equals("\'\\u001b\'")); //$NON-NLS-1$
+ x.setCharValue('\41');
+ assertTrue(x.getEscapedValue().equals("\'!\'")); //$NON-NLS-1$
}
public void testNumberLiteral() {
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests18.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests18.java
index ae2ac36bf..0fe9ec614 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests18.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests18.java
@@ -12,6 +12,7 @@
package org.eclipse.jdt.core.tests.model;
import java.util.Map;
+
import junit.framework.Test;
import org.eclipse.jdt.core.ICompilationUnit;
@@ -19,6 +20,7 @@ import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.eval.IEvaluationContext;
+import org.eclipse.jdt.internal.codeassist.RelevanceConstants;
public class CompletionTests18 extends AbstractJavaModelCompletionTests {
@@ -1545,4 +1547,692 @@ public void test430441() throws JavaModelException {
CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
context.codeComplete(str, cursorLocation, requestor);
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430656, [1.8][content assist] Content assist does not work for method reference argument
+public void test430656() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/test/X.java",
+ "import java.util.ArrayList;\n" +
+ "import java.util.Collections;\n" +
+ "import java.util.Comparator;\n" +
+ "import java.util.List;\n" +
+ "public class X {\n" +
+ " public void bar() {\n" +
+ " List<Person> people = new ArrayList<>();\n" +
+ " Collections.sort(people, Comparator.comparing(Person::get)); \n" +
+ " }\n" +
+ "}\n" +
+ "class Person {\n" +
+ " String getLastName() {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "get";
+ int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults(
+ "getClass[METHOD_IMPORT]{getClass, Ljava.lang.Object;, ()Ljava.lang.Class<*>;, getClass, null, 35}\n" +
+ "getLastName[METHOD_IMPORT]{getLastName, Ltest.Person;, ()Ljava.lang.String;, getLastName, null, 35}",
+ requestor.getResults());
+}
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=433178
+public void test433178() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/X.java",
+ "interface I {\n" +
+ " String foo(String x);\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public String longMethodName(String x) {\n" +
+ " return null;\n" +
+ " }\n" +
+ " void foo() {\n" +
+ " X x = new X();\n" +
+ " I i = x::ne\n" +
+ " System.out.println();\n" +
+ " }\n" +
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "ne";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults("new[KEYWORD]{new, null, null, null, null, new, null, [183, 185], " +
+ (RelevanceConstants.R_DEFAULT + RelevanceConstants.R_RESOLVED + RelevanceConstants.R_INTERESTING + RelevanceConstants.R_NON_RESTRICTED
+ + RelevanceConstants.R_CASE + RelevanceConstants.R_CONSTRUCTOR) + "}", requestor.getResults());
+}
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=433178
+public void test433178a() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/X.java",
+ "interface I {\n" +
+ " String foo(String x);\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public String longMethodName(String x) {\n" +
+ " return null;\n" +
+ " }\n" +
+ " void foo() {\n" +
+ " X x = new X();\n" +
+ " I i = I::ne\n" +
+ " System.out.println();\n" +
+ " }\n" +
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "ne";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults("", requestor.getResults());
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=435219, [1.8][content assist] No proposals for some closure cases
+public void test435219() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/X.java",
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " new Thread(()->System.o);\n" +
+ " }\n" +
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "System.o";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults("out[FIELD_REF]{out, Ljava.lang.System;, Ljava.io.PrintStream;, null, null, out, null, [83, 84], 26}", requestor.getResults());
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=435219, [1.8][content assist] No proposals for some closure cases
+public void test435219a() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/X.java",
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " new Thread(()->System.out.p);\n" +
+ " }\n" +
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "System.out.p";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults("print[METHOD_REF]{print(), Ljava.io.PrintStream;, (C)V, null, null, print, (arg0), [87, 88], 35}\n" +
+ "print[METHOD_REF]{print(), Ljava.io.PrintStream;, (D)V, null, null, print, (arg0), [87, 88], 35}\n" +
+ "print[METHOD_REF]{print(), Ljava.io.PrintStream;, (F)V, null, null, print, (arg0), [87, 88], 35}\n" +
+ "print[METHOD_REF]{print(), Ljava.io.PrintStream;, (I)V, null, null, print, (arg0), [87, 88], 35}\n" +
+ "print[METHOD_REF]{print(), Ljava.io.PrintStream;, (J)V, null, null, print, (arg0), [87, 88], 35}\n" +
+ "print[METHOD_REF]{print(), Ljava.io.PrintStream;, (Ljava.lang.Object;)V, null, null, print, (arg0), [87, 88], 35}\n" +
+ "print[METHOD_REF]{print(), Ljava.io.PrintStream;, (Ljava.lang.String;)V, null, null, print, (arg0), [87, 88], 35}\n" +
+ "print[METHOD_REF]{print(), Ljava.io.PrintStream;, (Z)V, null, null, print, (arg0), [87, 88], 35}\n" +
+ "print[METHOD_REF]{print(), Ljava.io.PrintStream;, ([C)V, null, null, print, (arg0), [87, 88], 35}\n" +
+ "printf[METHOD_REF]{printf(), Ljava.io.PrintStream;, (Ljava.lang.String;[Ljava.lang.Object;)Ljava.io.PrintStream;, null, null, printf, (arg0, arg1), [87, 88], 35}\n" +
+ "printf[METHOD_REF]{printf(), Ljava.io.PrintStream;, (Ljava.util.Locale;Ljava.lang.String;[Ljava.lang.Object;)Ljava.io.PrintStream;, null, null, printf, (arg0, arg1, arg2), [87, 88], 35}\n" +
+ "println[METHOD_REF]{println(), Ljava.io.PrintStream;, ()V, null, null, println, null, [87, 88], 35}\n" +
+ "println[METHOD_REF]{println(), Ljava.io.PrintStream;, (C)V, null, null, println, (arg0), [87, 88], 35}\n" +
+ "println[METHOD_REF]{println(), Ljava.io.PrintStream;, (D)V, null, null, println, (arg0), [87, 88], 35}\n" +
+ "println[METHOD_REF]{println(), Ljava.io.PrintStream;, (F)V, null, null, println, (arg0), [87, 88], 35}\n" +
+ "println[METHOD_REF]{println(), Ljava.io.PrintStream;, (I)V, null, null, println, (arg0), [87, 88], 35}\n" +
+ "println[METHOD_REF]{println(), Ljava.io.PrintStream;, (J)V, null, null, println, (arg0), [87, 88], 35}\n" +
+ "println[METHOD_REF]{println(), Ljava.io.PrintStream;, (Ljava.lang.Object;)V, null, null, println, (arg0), [87, 88], 35}\n" +
+ "println[METHOD_REF]{println(), Ljava.io.PrintStream;, (Ljava.lang.String;)V, null, null, println, (arg0), [87, 88], 35}\n" +
+ "println[METHOD_REF]{println(), Ljava.io.PrintStream;, (Z)V, null, null, println, (arg0), [87, 88], 35}\n" +
+ "println[METHOD_REF]{println(), Ljava.io.PrintStream;, ([C)V, null, null, println, (arg0), [87, 88], 35}", requestor.getResults());
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=435219, [1.8][content assist] No proposals for some closure cases
+public void test435219b() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/X.java",
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " new Thread(()->System.out.println(\"foo\")).st);\n" +
+ " }\n" +
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "st";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults("start[METHOD_REF]{start(), Ljava.lang.Thread;, ()V, null, null, start, null, [103, 105], 35}\n" +
+ "stop[METHOD_REF]{stop(), Ljava.lang.Thread;, ()V, null, null, stop, null, [103, 105], 35}\n" +
+ "stop[METHOD_REF]{stop(), Ljava.lang.Thread;, (Ljava.lang.Throwable;)V, null, null, stop, (arg0), [103, 105], 35}", requestor.getResults());
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=435219, [1.8][content assist] No proposals for some closure cases
+public void test435219c() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/X.java",
+ "import java.util.Arrays;\n" +
+ "import java.util.List;\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " List<Integer> list = Arrays.asList(1, 2, 3);\n" +
+ " list.stream().map((x) -> x * x.h);\n" +
+ " }\n" +
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "x.h";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults("hashCode[METHOD_REF]{hashCode(), Ljava.lang.Integer;, (I)I, null, null, hashCode, (arg0), [187, 188], 54}\n" +
+ "highestOneBit[METHOD_REF]{highestOneBit(), Ljava.lang.Integer;, (I)I, null, null, highestOneBit, (arg0), [187, 188], 54}\n" +
+ "hashCode[METHOD_REF]{hashCode(), Ljava.lang.Integer;, ()I, null, null, hashCode, null, [187, 188], 65}", requestor.getResults());
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=435219, [1.8][content assist] No proposals for some closure cases
+public void test435219d() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/X.java",
+ "import java.util.Arrays;\n" +
+ "import java.util.List;\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " List<Integer> list = Arrays.asList(1, 2, 3);\n" +
+ " list.stream().map((x) -> x * x.hashCode()).forEach(System.out::pri);\n" +
+ " }\n" +
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "pri";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults("print[METHOD_IMPORT]{print, Ljava.io.PrintStream;, (C)V, null, null, print, null, [219, 222], 30}\n" +
+ "print[METHOD_IMPORT]{print, Ljava.io.PrintStream;, (D)V, null, null, print, null, [219, 222], 30}\n" +
+ "print[METHOD_IMPORT]{print, Ljava.io.PrintStream;, (F)V, null, null, print, null, [219, 222], 30}\n" +
+ "print[METHOD_IMPORT]{print, Ljava.io.PrintStream;, (I)V, null, null, print, null, [219, 222], 30}\n" +
+ "print[METHOD_IMPORT]{print, Ljava.io.PrintStream;, (J)V, null, null, print, null, [219, 222], 30}\n" +
+ "print[METHOD_IMPORT]{print, Ljava.io.PrintStream;, (Ljava.lang.Object;)V, null, null, print, null, [219, 222], 30}\n" +
+ "print[METHOD_IMPORT]{print, Ljava.io.PrintStream;, (Ljava.lang.String;)V, null, null, print, null, [219, 222], 30}\n" +
+ "print[METHOD_IMPORT]{print, Ljava.io.PrintStream;, (Z)V, null, null, print, null, [219, 222], 30}\n" +
+ "print[METHOD_IMPORT]{print, Ljava.io.PrintStream;, ([C)V, null, null, print, null, [219, 222], 30}\n" +
+ "println[METHOD_IMPORT]{println, Ljava.io.PrintStream;, ()V, null, null, println, null, [219, 222], 30}\n" +
+ "println[METHOD_IMPORT]{println, Ljava.io.PrintStream;, (C)V, null, null, println, null, [219, 222], 30}\n" +
+ "println[METHOD_IMPORT]{println, Ljava.io.PrintStream;, (D)V, null, null, println, null, [219, 222], 30}\n" +
+ "println[METHOD_IMPORT]{println, Ljava.io.PrintStream;, (F)V, null, null, println, null, [219, 222], 30}\n" +
+ "println[METHOD_IMPORT]{println, Ljava.io.PrintStream;, (I)V, null, null, println, null, [219, 222], 30}\n" +
+ "println[METHOD_IMPORT]{println, Ljava.io.PrintStream;, (J)V, null, null, println, null, [219, 222], 30}\n" +
+ "println[METHOD_IMPORT]{println, Ljava.io.PrintStream;, (Ljava.lang.Object;)V, null, null, println, null, [219, 222], 30}\n" +
+ "println[METHOD_IMPORT]{println, Ljava.io.PrintStream;, (Ljava.lang.String;)V, null, null, println, null, [219, 222], 30}\n" +
+ "println[METHOD_IMPORT]{println, Ljava.io.PrintStream;, (Z)V, null, null, println, null, [219, 222], 30}\n" +
+ "println[METHOD_IMPORT]{println, Ljava.io.PrintStream;, ([C)V, null, null, println, null, [219, 222], 30}\n" +
+ "printf[METHOD_IMPORT]{printf, Ljava.io.PrintStream;, (Ljava.lang.String;[Ljava.lang.Object;)Ljava.io.PrintStream;, null, null, printf, null, [219, 222], 35}\n" +
+ "printf[METHOD_IMPORT]{printf, Ljava.io.PrintStream;, (Ljava.util.Locale;Ljava.lang.String;[Ljava.lang.Object;)Ljava.io.PrintStream;, null, null, printf, null, [219, 222], 35}", requestor.getResults());
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=435219, [1.8][content assist] No proposals for some closure cases
+public void test435219e() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/X.java",
+ "import java.util.Arrays;\n" +
+ "import java.util.List;\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " List<Integer> costBeforeTax = Arrays.asList(100, 200, 300);\n" +
+ " double bill = costBeforeTax.stream().map((cost) -> cost + 0.19 * cost)\n" +
+ " // .y .n .y\n" +
+ " .reduce((sum, cost) -> sum.dou\n" +
+ " }\n" +
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "dou";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults("doubleToLongBits[METHOD_REF]{doubleToLongBits(), Ljava.lang.Double;, (D)J, null, null, doubleToLongBits, (arg0), [355, 358], 24}\n" +
+ "doubleToRawLongBits[METHOD_REF]{doubleToRawLongBits(), Ljava.lang.Double;, (D)J, null, null, doubleToRawLongBits, (arg0), [355, 358], 24}\n" +
+ "doubleValue[METHOD_REF]{doubleValue(), Ljava.lang.Double;, ()D, null, null, doubleValue, null, [355, 358], 35}", requestor.getResults());
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=435219, [1.8][content assist] No proposals for some closure cases
+public void test435219f() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/X.java",
+ "import java.util.Arrays;\n" +
+ "import java.util.List;\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " List<Integer> costBeforeTax = Arrays.asList(100, 200, 300);\n" +
+ " double bill = costBeforeTax.stream().map((cost) -> cost + 0.19 * cost)\n" +
+ " // .y .n .y\n" +
+ " .reduce((sum, cost) -> sum.doubleValue() + cost.doubleValue()).g\n" +
+ " }\n" +
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "g";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults("getClass[METHOD_REF]{getClass(), Ljava.lang.Object;, ()Ljava.lang.Class<*>;, null, null, getClass, null, [391, 392], 35}\n" +
+ "get[METHOD_REF]{get(), Ljava.util.Optional<Ljava.lang.Double;>;, ()Ljava.lang.Double;, null, null, get, null, [391, 392], 55}", requestor.getResults());
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=435219, [1.8][content assist] No proposals for some closure cases
+public void test435219g() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/X.java",
+ "import java.util.Arrays;\n" +
+ "import java.util.List;\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " List<Integer> costBeforeTax = Arrays.asList(100, 200, 300);\n" +
+ " double bill = costBeforeTax.stream().map((cost) -> cost + 0.19 * cost)\n" +
+ " // .y .n .y\n" +
+ " .reduce((sum, cost) -> sum.doubleValue() + cost.dou\n" +
+ " }\n" +
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "dou";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults("doubleToLongBits[METHOD_REF]{doubleToLongBits(), Ljava.lang.Double;, (D)J, null, null, doubleToLongBits, (arg0), [376, 379], 54}\n" +
+ "doubleToRawLongBits[METHOD_REF]{doubleToRawLongBits(), Ljava.lang.Double;, (D)J, null, null, doubleToRawLongBits, (arg0), [376, 379], 54}\n" +
+ "doubleValue[METHOD_REF]{doubleValue(), Ljava.lang.Double;, ()D, null, null, doubleValue, null, [376, 379], 65}", requestor.getResults());
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=435682, [1.8] content assist not working inside lambda expression
+public void test435682() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/X.java",
+ "import java.util.Arrays;\n" +
+ "import java.util.List;\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " List<String> words = Arrays.asList(\"hi\", \"hello\", \"hola\", \"bye\", \"goodbye\");\n" +
+ " List<String> list1 = words.stream().map(so -> so.tr).collect(Collectors.toList());\n" +
+ " }\n" +
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "so.tr";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults("trim[METHOD_REF]{trim(), Ljava.lang.String;, ()Ljava.lang.String;, null, null, trim, null, [237, 239], 35}", requestor.getResults());
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=435682, [1.8] content assist not working inside lambda expression
+public void test435682a() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/X.java",
+ "import java.util.Arrays;\n" +
+ "import java.util.List;\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " List<String> words = Arrays.asList(\"hi\", \"hello\", \"hola\", \"bye\", \"goodbye\");\n" +
+ " List<String> list1 = words.stream().map((String so) -> so.tr).collect(Collectors.toList());\n" +
+ " }\n" +
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "so.tr";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults("trim[METHOD_REF]{trim(), Ljava.lang.String;, ()Ljava.lang.String;, null, null, trim, null, [246, 248], 35}", requestor.getResults());
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430667, [1.8][content assist] no proposals around lambda as a field
+public void test430667() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/X.java",
+ "interface D_FI {\n" +
+ " void print(String value, int n);\n" +
+ "}\n" +
+ "class D_DemoRefactorings {\n" +
+ " \n" +
+ " D_FI fi1= (String value, int n) -> {\n" +
+ " for (int j = 0; j < n; j++) {\n" +
+ " System.out.println(value); \n" +
+ " }\n" +
+ " };\n" +
+ " D_F\n" +
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "D_F";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults("D_F[POTENTIAL_METHOD_DECLARATION]{D_F, LD_DemoRefactorings;, ()V, null, null, D_F, null, [195, 198], 14}\n" +
+ "D_FI[TYPE_REF]{D_FI, , LD_FI;, null, null, null, null, [195, 198], 27}", requestor.getResults());
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430667, [1.8][content assist] no proposals around lambda as a field
+public void test430667a() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/X.java",
+ "class D_DemoRefactorings {\n" +
+ " \n" +
+ " D_FI fi1= (String value, int n) -> {\n" +
+ " for (int j = 0; j < n; j++) {\n" +
+ " System.out.println(value); \n" +
+ " }\n" +
+ " };\n" +
+ " /*HERE*/D_F\n" +
+ "}\n" +
+ "interface D_FI {\n" +
+ " void print(String value, int n);\n" +
+ "}\n"
+ );
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "/*HERE*/D_F";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults("D_F[POTENTIAL_METHOD_DECLARATION]{D_F, LD_DemoRefactorings;, ()V, null, null, D_F, null, [150, 153], 14}\n" +
+ "D_FI[TYPE_REF]{D_FI, , LD_FI;, null, null, null, null, [150, 153], 27}", requestor.getResults());
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430667, [1.8][content assist] no proposals around lambda as a field
+public void test430667b() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/X.java",
+ "class D_DemoRefactorings {\n" +
+ " /*HERE*/D_F\n" +
+ " D_FI fi1= (String value, int n) -> {\n" +
+ " for (int j = 0; j < n; j++) {\n" +
+ " System.out.println(value); \n" +
+ " }\n" +
+ " };\n" +
+ "}\n" +
+ "interface D_FI {\n" +
+ " void print(String value, int n);\n" +
+ "}\n"
+ );
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "/*HERE*/D_F";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults("D_F[POTENTIAL_METHOD_DECLARATION]{D_F, LD_DemoRefactorings;, ()V, null, null, D_F, null, [36, 39], 14}\n" +
+ "D_FI[TYPE_REF]{D_FI, , LD_FI;, null, null, null, null, [36, 39], 27}", requestor.getResults());
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=443932, [1.8][code complete] method reference proposals not applied when caret inside method name
+public void test443932() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/X.java",
+ "import java.util.function.IntFunction;\n" +
+ "public class X {\n" +
+ " IntFunction<String> ts= Integer::toString;\n" +
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "to";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults("toBinaryString[METHOD_IMPORT]{toBinaryString, Ljava.lang.Integer;, (I)Ljava.lang.String;, null, null, toBinaryString, null, [90, 98], 24}\n" +
+ "toHexString[METHOD_IMPORT]{toHexString, Ljava.lang.Integer;, (I)Ljava.lang.String;, null, null, toHexString, null, [90, 98], 24}\n" +
+ "toOctalString[METHOD_IMPORT]{toOctalString, Ljava.lang.Integer;, (I)Ljava.lang.String;, null, null, toOctalString, null, [90, 98], 24}\n" +
+ "toString[METHOD_IMPORT]{toString, Ljava.lang.Integer;, (I)Ljava.lang.String;, null, null, toString, null, [90, 98], 24}\n" +
+ "toString[METHOD_IMPORT]{toString, Ljava.lang.Integer;, (II)Ljava.lang.String;, null, null, toString, null, [90, 98], 24}\n" +
+ "toUnsignedLong[METHOD_IMPORT]{toUnsignedLong, Ljava.lang.Integer;, (I)J, null, null, toUnsignedLong, null, [90, 98], 24}\n" +
+ "toUnsignedString[METHOD_IMPORT]{toUnsignedString, Ljava.lang.Integer;, (I)Ljava.lang.String;, null, null, toUnsignedString, null, [90, 98], 24}\n" +
+ "toUnsignedString[METHOD_IMPORT]{toUnsignedString, Ljava.lang.Integer;, (II)Ljava.lang.String;, null, null, toUnsignedString, null, [90, 98], 24}\n" +
+ "toString[METHOD_IMPORT]{toString, Ljava.lang.Integer;, ()Ljava.lang.String;, null, null, toString, null, [90, 98], 35}", requestor.getResults());
+ assertTrue(str.substring(90, 98).equals("toString"));
+
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=444300, [1.8] content assist not working inside lambda expression in case of fields
+public void test444300() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/X.java",
+ "import java.util.Arrays;\n" +
+ "import java.util.List;\n" +
+ "import java.util.stream.Collectors;\n" +
+ "public class Test {\n" +
+ " List<String> words = Arrays.asList(\"hi\", \"hello\", \"hola\", \"bye\", \"goodbye\");\n" +
+ " List<String> list1 = words.stream().map(so -> so.ch).collect(Collectors.toList());\n" +
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "so.ch";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults("charAt[METHOD_REF]{charAt(), Ljava.lang.String;, (I)C, null, null, charAt, (arg0), [232, 234], 35}\n" +
+ "chars[METHOD_REF]{chars(), Ljava.lang.CharSequence;, ()Ljava.util.stream.IntStream;, null, null, chars, null, [232, 234], 35}", requestor.getResults());
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=435219, [1.8][content assist] No proposals for some closure cases
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=444300, [1.8] content assist not working inside lambda expression in case of fields
+public void test435219h() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/X.java",
+ "import java.util.Arrays;\n" +
+ "import java.util.List;\n" +
+ "public class X {\n" +
+ " List<Integer> list = Arrays.asList(1, 2, 3);\n" +
+ " List<String> list1 = list.stream().map((x) -> x * x.h).collect(Collectors.toList());\n" +
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "x.h";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults("hashCode[METHOD_REF]{hashCode(), Ljava.lang.Integer;, (I)I, null, null, hashCode, (arg0), [164, 165], 54}\n" +
+ "highestOneBit[METHOD_REF]{highestOneBit(), Ljava.lang.Integer;, (I)I, null, null, highestOneBit, (arg0), [164, 165], 54}\n" +
+ "hashCode[METHOD_REF]{hashCode(), Ljava.lang.Integer;, ()I, null, null, hashCode, null, [164, 165], 65}", requestor.getResults());
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=435219, [1.8][content assist] No proposals for some closure cases
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=444300, [1.8] content assist not working inside lambda expression in case of fields
+public void test435219i() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/X.java",
+ "import java.util.Arrays;\n" +
+ "import java.util.List;\n" +
+ "public class X {\n" +
+ " List<Integer> list = Arrays.asList(1, 2, 3);\n" +
+ " Object o = list.stream().map((x) -> x * x.hashCode()).forEach(System.out::pri);\n" +
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "pri";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults("print[METHOD_IMPORT]{print, Ljava.io.PrintStream;, (C)V, null, null, print, null, [188, 191], 30}\n" +
+ "print[METHOD_IMPORT]{print, Ljava.io.PrintStream;, (D)V, null, null, print, null, [188, 191], 30}\n" +
+ "print[METHOD_IMPORT]{print, Ljava.io.PrintStream;, (F)V, null, null, print, null, [188, 191], 30}\n" +
+ "print[METHOD_IMPORT]{print, Ljava.io.PrintStream;, (I)V, null, null, print, null, [188, 191], 30}\n" +
+ "print[METHOD_IMPORT]{print, Ljava.io.PrintStream;, (J)V, null, null, print, null, [188, 191], 30}\n" +
+ "print[METHOD_IMPORT]{print, Ljava.io.PrintStream;, (Ljava.lang.Object;)V, null, null, print, null, [188, 191], 30}\n" +
+ "print[METHOD_IMPORT]{print, Ljava.io.PrintStream;, (Ljava.lang.String;)V, null, null, print, null, [188, 191], 30}\n" +
+ "print[METHOD_IMPORT]{print, Ljava.io.PrintStream;, (Z)V, null, null, print, null, [188, 191], 30}\n" +
+ "print[METHOD_IMPORT]{print, Ljava.io.PrintStream;, ([C)V, null, null, print, null, [188, 191], 30}\n" +
+ "println[METHOD_IMPORT]{println, Ljava.io.PrintStream;, ()V, null, null, println, null, [188, 191], 30}\n" +
+ "println[METHOD_IMPORT]{println, Ljava.io.PrintStream;, (C)V, null, null, println, null, [188, 191], 30}\n" +
+ "println[METHOD_IMPORT]{println, Ljava.io.PrintStream;, (D)V, null, null, println, null, [188, 191], 30}\n" +
+ "println[METHOD_IMPORT]{println, Ljava.io.PrintStream;, (F)V, null, null, println, null, [188, 191], 30}\n" +
+ "println[METHOD_IMPORT]{println, Ljava.io.PrintStream;, (I)V, null, null, println, null, [188, 191], 30}\n" +
+ "println[METHOD_IMPORT]{println, Ljava.io.PrintStream;, (J)V, null, null, println, null, [188, 191], 30}\n" +
+ "println[METHOD_IMPORT]{println, Ljava.io.PrintStream;, (Ljava.lang.Object;)V, null, null, println, null, [188, 191], 30}\n" +
+ "println[METHOD_IMPORT]{println, Ljava.io.PrintStream;, (Ljava.lang.String;)V, null, null, println, null, [188, 191], 30}\n" +
+ "println[METHOD_IMPORT]{println, Ljava.io.PrintStream;, (Z)V, null, null, println, null, [188, 191], 30}\n" +
+ "println[METHOD_IMPORT]{println, Ljava.io.PrintStream;, ([C)V, null, null, println, null, [188, 191], 30}\n" +
+ "printf[METHOD_IMPORT]{printf, Ljava.io.PrintStream;, (Ljava.lang.String;[Ljava.lang.Object;)Ljava.io.PrintStream;, null, null, printf, null, [188, 191], 35}\n" +
+ "printf[METHOD_IMPORT]{printf, Ljava.io.PrintStream;, (Ljava.util.Locale;Ljava.lang.String;[Ljava.lang.Object;)Ljava.io.PrintStream;, null, null, printf, null, [188, 191], 35}", requestor.getResults());
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=435219, [1.8][content assist] No proposals for some closure cases
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=444300, [1.8] content assist not working inside lambda expression in case of fields
+public void test435219j() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/X.java",
+ "import java.util.Arrays;\n" +
+ "import java.util.List;\n" +
+ "public class X {\n" +
+ " List<Integer> costBeforeTax = Arrays.asList(100, 200, 300);\n" +
+ " double bill = costBeforeTax.stream().map((cost) -> cost + 0.19 * cost)\n" +
+ " .reduce((sum, cost) -> sum.dou\n" +
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "dou";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults("doubleToLongBits[METHOD_REF]{doubleToLongBits(), Ljava.lang.Double;, (D)J, null, null, doubleToLongBits, (arg0), [235, 238], 24}\n" +
+ "doubleToRawLongBits[METHOD_REF]{doubleToRawLongBits(), Ljava.lang.Double;, (D)J, null, null, doubleToRawLongBits, (arg0), [235, 238], 24}\n" +
+ "doubleValue[METHOD_REF]{doubleValue(), Ljava.lang.Double;, ()D, null, null, doubleValue, null, [235, 238], 35}", requestor.getResults());
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=435219, [1.8][content assist] No proposals for some closure cases
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=444300, [1.8] content assist not working inside lambda expression in case of fields
+public void test435219k() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/X.java",
+ "import java.util.Arrays;\n" +
+ "import java.util.List;\n" +
+ "public class X {\n" +
+ " List<Integer> costBeforeTax = Arrays.asList(100, 200, 300);\n" +
+ " double bill = costBeforeTax.stream().map((cost) -> cost + 0.19 * cost)\n" +
+ " .reduce((sum, cost) -> sum.doubleValue() + cost.doubleValue()).g\n" +
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "g";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults("getClass[METHOD_REF]{getClass(), Ljava.lang.Object;, ()Ljava.lang.Class<*>;, null, null, getClass, null, [271, 272], 35}\n" +
+ "get[METHOD_REF]{get(), Ljava.util.Optional<Ljava.lang.Double;>;, ()Ljava.lang.Double;, null, null, get, null, [271, 272], 55}", requestor.getResults());
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=435219, [1.8][content assist] No proposals for some closure cases
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=444300, [1.8] content assist not working inside lambda expression in case of fields
+public void test435219l() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/X.java",
+ "import java.util.Arrays;\n" +
+ "import java.util.List;\n" +
+ "public class X {\n" +
+ " List<Integer> costBeforeTax = Arrays.asList(100, 200, 300);\n" +
+ " double bill = costBeforeTax.stream().map((cost) -> cost + 0.19 * cost)\n" +
+ " .reduce((sum, cost) -> sum.doubleValue() + cost.dou\n" +
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "dou";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults("doubleToLongBits[METHOD_REF]{doubleToLongBits(), Ljava.lang.Double;, (D)J, null, null, doubleToLongBits, (arg0), [256, 259], 54}\n" +
+ "doubleToRawLongBits[METHOD_REF]{doubleToRawLongBits(), Ljava.lang.Double;, (D)J, null, null, doubleToRawLongBits, (arg0), [256, 259], 54}\n" +
+ "doubleValue[METHOD_REF]{doubleValue(), Ljava.lang.Double;, ()D, null, null, doubleValue, null, [256, 259], 65}", requestor.getResults());
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=435281, [1.8][code assist] No import or completion proposal for anonymous class inside lambda
+public void test435281() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[3];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/FI1.java",
+ "package p4a;\n" +
+ "@FunctionalInterface\n" +
+ "public interface FI1<R> {\n" +
+ " public R foo1();\n" +
+ "}\n");
+ this.workingCopies[1] = getWorkingCopy(
+ "/Completion/src/FI2.java",
+ "package p4a;\n" +
+ "@FunctionalInterface\n" +
+ "public interface FI2 {\n" +
+ " public void foo2();\n" +
+ "}\n");
+
+ this.workingCopies[2] = getWorkingCopy(
+ "/Completion/src/Test.java",
+ "package p4b;\n" +
+ "import p4a.FI1;\n" +
+ "public class Test {\n" +
+ " {\n" +
+ " new FI2() {};\n" +
+ " FI1 fi1 = () -> new FI2() {\n" +
+ " @Override\n" +
+ " public void foo2() {}\n" +
+ " };\n" +
+ " }\n" +
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[2].getSource();
+ String completeBehind = "FI2";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[2].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults("FI2[TYPE_REF]{p4a.FI2, p4a, Lp4a.FI2;, null, null, null, null, [104, 107], 28}", requestor.getResults());
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=431811, content assist should propose keyword 'super' after type name
+public void test431811() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/FI1.java",
+ "interface Intf {\n" +
+ " void foo();\n" +
+ "}\n" +
+ "public class X implements Intf {\n" +
+ " class Inner {\n" +
+ " {\n" +
+ " X.super.hashCode();\n" +
+ " }\n" +
+ " }\n" +
+ " @Override\n" +
+ " public void foo() {\n" +
+ " Intf.su;\n" +
+ " }\n" +
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "su";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults("super[KEYWORD]{super, null, null, null, null, super, null, [192, 194], 26}", requestor.getResults());
+}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/HierarchyOnWorkingCopiesTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/HierarchyOnWorkingCopiesTests.java
index e2303bc4f..d1331d4ce 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/HierarchyOnWorkingCopiesTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/HierarchyOnWorkingCopiesTests.java
@@ -482,5 +482,48 @@ public void test429537() throws CoreException, IOException {
}
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=442534, Eclipse's Run button does not work.
+public void test442534() throws CoreException, IOException {
+
+ IJavaProject project = null;
+ try {
+ project = this.createJavaProject(
+ "Bug442534",
+ new String[] {"src"},
+ new String[] {this.getExternalJCLPathString(), "lib"},
+ "bin");
+ project.setOption(JavaCore.COMPILER_COMPLIANCE, "1.8");
+ project.setOption(JavaCore.COMPILER_SOURCE, "1.8");
+
+ this.createFolder("Bug442534/src/q");
+ this.createFile("Bug442534/src/X.java",
+ "import q.*;\n" +
+ "public final class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " foo(e -> { if (new Object() instanceof Y);});\n" +
+ " };\n" +
+ " static void foo(I i) {\n" +
+ " return;\n" +
+ " }\n" +
+ "}\n" +
+ "interface I {\n" +
+ " void foo(int x);\n" +
+ "}\n");
+
+ this.createFile("Bug442534/src/q/Y.java",
+ "package q;\n" +
+ "public class Y {\n" +
+ "}\n");
+
+ this.createFile("Bug442534/src/q/package-info.java",
+ "package q;\n"
+ );
+
+ project.findType("X").newSupertypeHierarchy(null);
+ } finally {
+ if (project != null)
+ this.deleteProject(project);
+ }
+}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java
index ba2e6fe21..c04672ce6 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java
@@ -5727,4 +5727,106 @@ public void testBug410207d() throws Exception {
deleteProjects(new String[] { "Lib", "P" });
}
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=440592, Cannot easily launch application in case of certain usage of lambda expressions
+public void testBug440592() throws Exception {
+ try {
+ createJavaProject("P", new String[] {"src"}, new String[] {"JCL18_FULL"}, "bin", "1.8", true);
+ createFile(
+ "/P/src/BugTest.java",
+ "public class BugTest {\n" +
+ " public void baz(InterfaceForBugTest arg) {\n" +
+ " }\n" +
+ " public void bar() {\n" +
+ " baz(InterfaceForBugTest.instance); \n" +
+ " }\n" +
+ " public Runnable returningLambda() { \n" +
+ " return () -> {\n" +
+ " };\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " }\n" +
+ "}\n"
+ );
+ createFile(
+ "/P/src/InterfaceForBugTest.java",
+ "public interface InterfaceForBugTest {\n" +
+ " public static InterfaceForBugTest creator1(Runnable simpleInstance){\n" +
+ " return null;\n" +
+ " }\n" +
+ " public static void methodWithAnonymousImplementation() {\n" +
+ " new InterfaceForBugTest() {\n" +
+ " @Override\n" +
+ " public void fun1() {\n" +
+ " }\n" +
+ " @Override\n" +
+ " public void fun2() {\n" +
+ " }\n" +
+ " @Override\n" +
+ " public void fun3() {\n" +
+ " }\n" +
+ " @Override\n" +
+ " public void fun4() {\n" +
+ " }\n" +
+ " @Override\n" +
+ " public void fun5() {\n" +
+ " }\n" +
+ " };\n" +
+ " } \n" +
+ " public static void methodWithAnonymousImplementation2() {\n" +
+ " new InterfaceForBugTest() {\n" +
+ " @Override\n" +
+ " public void fun1() {\n" +
+ " }\n" +
+ " @Override\n" +
+ " public void fun2() {\n" +
+ " }\n" +
+ " @Override\n" +
+ " public void fun3() {\n" +
+ " }\n" +
+ " @Override\n" +
+ " public void fun4() {\n" +
+ " }\n" +
+ " @Override\n" +
+ " public void fun5() {\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ " public static InterfaceForBugTest instance = creator1(() -> {\n" +
+ " });\n" +
+ " void fun1();\n" +
+ " void fun2();\n" +
+ " void fun3();\n" +
+ " void fun4();\n" +
+ " void fun5();\n" +
+ "}\n"
+
+ );
+ getProject("P").build(IncrementalProjectBuilder.FULL_BUILD, null);
+ setUpWorkingCopy(
+ "/P/src/BugTest.java",
+ "public class BugTest {\n" +
+ " public void baz(InterfaceForBugTest arg) {\n" +
+ " }\n" +
+ " public void bar() {\n" +
+ " baz(InterfaceForBugTest.instance); \n" +
+ " }\n" +
+ " public Runnable returningLambda() { \n" +
+ " return () -> {\n" +
+ " };\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " }\n" +
+ "}\n"
+ );
+ this.problemRequestor.reset();
+ this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force problem detection*/, null, null);
+ assertProblems(
+ "Unexpected problems",
+ "----------\n" +
+ "----------\n"
+ );
+ } finally {
+ deleteProjects(new String[] { "P" });
+ }
+}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests18.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests18.java
index 78b9ac2e0..74d00733f 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests18.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests18.java
@@ -2658,4 +2658,159 @@ public void test439234() throws JavaModelException {
elements
);
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=440731, [1.8] Hover, F3 doesn't work for method reference in method invocation
+public void test440731() throws JavaModelException {
+ this.wc = getWorkingCopy(
+ "/Resolve/src/X.java",
+ "class Y {\n" +
+ " public void fooY() {return;}\n" +
+ " public void bar(I2 i) {return;}\n" +
+ " public void bar(I i) {return;} \n" +
+ "}\n" +
+ "class fooY() {}\n" +
+ "interface I { void fooI(Y y); }\n" +
+ "interface I2 { void fooI2(int n);}\n" +
+ "public class X {\n" +
+ " void foo() {\n" +
+ " I i = Y::fooY; // works\n" +
+ " }\n" +
+ "}");
+
+ String str = this.wc.getSource();
+ String selection = "fooY";
+ int start = str.lastIndexOf(selection);
+ int length = selection.length();
+ IJavaElement[] elements;
+
+ elements = this.wc.codeSelect(start, length);
+ assertElementsEqual(
+ "Unexpected elements",
+ "fooY() [in Y [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]",
+ elements
+ );
+
+ this.wc = getWorkingCopy(
+ "/Resolve/src/X.java",
+ "class Y {\n" +
+ " public void fooY() {return;}\n" +
+ " public void bar(I2 i) {return;}\n" +
+ " public void bar(I i) {return;} \n" +
+ "}\n" +
+ // [1]: Why class fooY {} ?
+ "class fooY{}\n" +
+ "interface I { void fooI(Y y); }\n" +
+ "interface I2 { void fooI2(int n);}\n" +
+ "public class X {\n" +
+ " void foo() {\n" +
+ " Y y = new Y();\n" +
+ " y.bar(Y::fooY);\n" +
+ " }\n" +
+ "}");
+ str = this.wc.getSource();
+ selection = "::";
+ //y.bar(Y::fooY)
+ // ^^
+ start = str.lastIndexOf(selection);
+ length = selection.length();
+
+ elements = this.wc.codeSelect(start, length);
+ assertElementsEqual(
+ "Unexpected elements",
+ "fooI(Y) [in I [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]",
+ elements);
+
+ // [1] The reason for having the class fooY {} as part of the test case:
+ // Without the fix we resolve to the type fooY (class) and not the method fooY()
+ // declared in class Y. Please see Comment 4.
+
+ selection = "fooY";
+ //y.bar(Y::fooY)
+ // ^^^^
+
+ start = str.lastIndexOf(selection);
+ length = selection.length();
+
+ // Unable to find element without fix.
+ elements = this.wc.codeSelect(start, length);
+ assertElementsEqual(
+ "Unexpected elements",
+ "fooY() [in Y [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]",
+ elements);
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430572, [1.8] CCE on hovering over 'super' in lambda expression
+public void test430572() throws JavaModelException {
+ this.wc = getWorkingCopy(
+ "/Resolve/src/X.java",
+ "@FunctionalInterface\n" +
+ "interface FI {\n" +
+ " default int getID() {\n" +
+ " return 11;\n" +
+ " }\n" +
+ " void print();\n" +
+ "}\n" +
+ "class T {\n" +
+ " FI f2 = () -> System.out.println(super.toString());\n" +
+ "}\n");
+
+ String str = this.wc.getSource();
+ String selection = "super";
+ int start = str.lastIndexOf(selection);
+ int length = selection.length();
+ IJavaElement[] elements;
+
+ elements = this.wc.codeSelect(start, length);
+ assertElementsEqual(
+ "Unexpected elements",
+ "Object [in Object.class [in java.lang [in "+ getExternalPath() + "jclFull1.8.jar]]]",
+ elements
+ );
+
+ this.wc = getWorkingCopy(
+ "/Resolve/src/X.java",
+ "class Y {\n" +
+ " public void fooY() {return;}\n" +
+ " public void bar(I2 i) {return;}\n" +
+ " public void bar(I i) {return;} \n" +
+ "}\n" +
+ // [1]: Why class fooY {} ?
+ "class fooY{}\n" +
+ "interface I { void fooI(Y y); }\n" +
+ "interface I2 { void fooI2(int n);}\n" +
+ "public class X {\n" +
+ " void foo() {\n" +
+ " Y y = new Y();\n" +
+ " y.bar(Y::fooY);\n" +
+ " }\n" +
+ "}");
+ str = this.wc.getSource();
+ selection = "::";
+ //y.bar(Y::fooY)
+ // ^^
+ start = str.lastIndexOf(selection);
+ length = selection.length();
+
+ elements = this.wc.codeSelect(start, length);
+ assertElementsEqual(
+ "Unexpected elements",
+ "fooI(Y) [in I [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]",
+ elements);
+
+ // [1] The reason for having the class fooY {} as part of the test case:
+ // Without the fix we resolve to the type fooY (class) and not the method fooY()
+ // declared in class Y. Please see Comment 4.
+
+ selection = "fooY";
+ //y.bar(Y::fooY)
+ // ^^^^
+
+ start = str.lastIndexOf(selection);
+ length = selection.length();
+
+ // Unable to find element without fix.
+ elements = this.wc.codeSelect(start, length);
+ assertElementsEqual(
+ "Unexpected elements",
+ "fooY() [in Y [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]",
+ elements);
+}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/TypeResolveTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/TypeResolveTests.java
index fb0d6551d..be72ebbff 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/TypeResolveTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/TypeResolveTests.java
@@ -1002,6 +1002,9 @@ public void test405026b() throws CoreException, IOException {
itype = nameLookup.findType("test13outer", packageFragments[0], true, NameLookup.ACCEPT_ALL, false, false);
assertNull(itype);
+ itype = nameLookup.findType("test1", packageFragments[0], true, NameLookup.ACCEPT_ALL, false, false);
+ assertEquals("test13", itype.getElementName());
+
answer = nameLookup.findType("test13out", "p", true, NameLookup.ACCEPT_ALL, /* considerSecondaryTypes */ true, true, false, null);
assertEquals("test13outer", answer.type.getElementName());
} finally {
diff --git a/org.eclipse.jdt.core.tests.model/test.xml b/org.eclipse.jdt.core.tests.model/test.xml
index 5176681e6..22c5f2309 100644
--- a/org.eclipse.jdt.core.tests.model/test.xml
+++ b/org.eclipse.jdt.core.tests.model/test.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright (c) 2002, 2011 IBM Corporation and others.
+ Copyright (c) 2002, 2014 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
@@ -89,8 +89,4 @@
-->
</target>
- <!-- This target runs the performance test suites. -->
- <target name="performance">
- </target>
-
</project>
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Converter/src/testBug443942/org.eclipse.swt.internal.gtk/A.java b/org.eclipse.jdt.core.tests.model/workspace/Converter/src/testBug443942/org.eclipse.swt.internal.gtk/A.java
new file mode 100644
index 000000000..3e2b54ca7
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Converter/src/testBug443942/org.eclipse.swt.internal.gtk/A.java
@@ -0,0 +1,4 @@
+package org.eclipse.swt.internal.gtk;
+public class A {
+public static final native long /*int*/ realpath(byte[] path, byte[] realPath);
+}
diff --git a/org.eclipse.jdt.core/.settings/.api_filters b/org.eclipse.jdt.core/.settings/.api_filters
index 7a1750262..3228363e1 100644
--- a/org.eclipse.jdt.core/.settings/.api_filters
+++ b/org.eclipse.jdt.core/.settings/.api_filters
@@ -1,226 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<component id="org.eclipse.jdt.core" version="2">
- <resource path="compiler/org/eclipse/objectteams/otdt/core/compiler/CompilerVersion.java" type="org.eclipse.objectteams.otdt.core.compiler.CompilerVersion">
- <filter comment="Intermediary API was not necessary after all" id="338792546">
+ <resource path="dom/org/eclipse/jdt/core/dom/IExtendedModifier.java" type="org.eclipse.jdt.core.dom.IExtendedModifier">
+ <filter comment="IExtendedModifier was never meant to be extendable (bug 416586)" id="403853384">
<message_arguments>
- <message_argument value="org.eclipse.objectteams.otdt.core.compiler.CompilerVersion"/>
- <message_argument value="setDynamicWeaving(boolean)"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="dom/org/eclipse/jdt/core/dom/ASTNode.java" type="org.eclipse.jdt.core.dom.ASTNode">
- <filter comment="OT AST constants must be updated when new constants are added in JDT" id="388194388">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.dom.ASTNode"/>
- <message_argument value="BASE_CALL_MESSAGE_SEND"/>
- <message_argument value="92"/>
- </message_arguments>
- </filter>
- <filter comment="OT AST constants must be updated when new constants are added in JDT" id="388194388">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.dom.ASTNode"/>
- <message_argument value="BASE_CONSTRUCTOR_INVOCATION"/>
- <message_argument value="90"/>
- </message_arguments>
- </filter>
- <filter comment="OT AST constants must be updated when new constants are added in JDT" id="388194388">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.dom.ASTNode"/>
- <message_argument value="CALLIN_MAPPING_DECLARATION"/>
- <message_argument value="86"/>
- </message_arguments>
- </filter>
- <filter comment="OT AST constants must be updated when new constants are added in JDT" id="388194388">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.dom.ASTNode"/>
- <message_argument value="CALLOUT_MAPPING_DECLARATION"/>
- <message_argument value="87"/>
- </message_arguments>
- </filter>
- <filter comment="OT AST constants must be updated when new constants are added in JDT" id="388194388">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.dom.ASTNode"/>
- <message_argument value="FIELD_ACCESS_SPEC"/>
- <message_argument value="93"/>
- </message_arguments>
- </filter>
- <filter comment="OT AST constants must be updated when new constants are added in JDT" id="388194388">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.dom.ASTNode"/>
- <message_argument value="GUARD_PREDICATE_DECLARATION"/>
- <message_argument value="99"/>
- </message_arguments>
- </filter>
- <filter comment="OT AST constants must be updated when new constants are added in JDT" id="388194388">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.dom.ASTNode"/>
- <message_argument value="LIFTING_TYPE"/>
- <message_argument value="88"/>
- </message_arguments>
- </filter>
- <filter comment="OT AST constants must be updated when new constants are added in JDT" id="388194388">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.dom.ASTNode"/>
- <message_argument value="METHOD_BINDING_OPERATOR"/>
- <message_argument value="100"/>
- </message_arguments>
- </filter>
- <filter comment="OT AST constants must be updated when new constants are added in JDT" id="388194388">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.dom.ASTNode"/>
- <message_argument value="METHOD_SPEC"/>
- <message_argument value="85"/>
- </message_arguments>
- </filter>
- <filter comment="OT AST constants must be updated when new constants are added in JDT" id="388194388">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.dom.ASTNode"/>
- <message_argument value="PARAMETER_MAPPING"/>
- <message_argument value="91"/>
- </message_arguments>
- </filter>
- <filter comment="OT AST constants must be updated when new constants are added in JDT" id="388194388">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.dom.ASTNode"/>
- <message_argument value="PRECEDENCE_DECLARATION"/>
- <message_argument value="98"/>
- </message_arguments>
- </filter>
- <filter comment="OT AST constants must be updated when new constants are added in JDT" id="388194388">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.dom.ASTNode"/>
- <message_argument value="ROLE_TYPE_DECLARATION"/>
- <message_argument value="94"/>
- </message_arguments>
- </filter>
- <filter comment="OT AST constants must be updated when new constants are added in JDT" id="388194388">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.dom.ASTNode"/>
- <message_argument value="TSUPER_CONSTRUCTOR_INVOCATION"/>
- <message_argument value="96"/>
- </message_arguments>
- </filter>
- <filter comment="OT AST constants must be updated when new constants are added in JDT" id="388194388">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.dom.ASTNode"/>
- <message_argument value="TSUPER_MESSAGE_SEND"/>
- <message_argument value="95"/>
- </message_arguments>
- </filter>
- <filter comment="OT AST constants must be updated when new constants are added in JDT" id="388194388">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.dom.ASTNode"/>
- <message_argument value="TYPE_ANCHOR"/>
- <message_argument value="97"/>
- </message_arguments>
- </filter>
- <filter comment="OT AST constants must be updated when new constants are added in JDT" id="388194388">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.dom.ASTNode"/>
- <message_argument value="WITHIN_STATEMENT"/>
- <message_argument value="89"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="dom/org/eclipse/jdt/core/dom/Modifier.java" type="org.eclipse.jdt.core.dom.Modifier">
- <filter comment="Necessary constant update to avoid conflicts with new mod for DefaultMethods introduced in JDT/Core" id="388194388">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.dom.Modifier"/>
- <message_argument value="OT_AFTER_CALLIN"/>
- <message_argument value="65536"/>
- </message_arguments>
- </filter>
- <filter comment="Necessary constant update to avoid conflicts with new mod for DefaultMethods introduced in JDT/Core" id="388194388">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.dom.Modifier"/>
- <message_argument value="OT_GET_CALLOUT"/>
- <message_argument value="131072"/>
- </message_arguments>
- </filter>
- <filter comment="Necessary constant update to avoid conflicts with new mod for DefaultMethods introduced in JDT/Core" id="388194388">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.dom.Modifier"/>
- <message_argument value="OT_SET_CALLOUT"/>
- <message_argument value="262144"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="dom/org/eclipse/jdt/core/dom/rewrite/ASTNodeCreator.java" type="org.eclipse.jdt.core.dom.rewrite.ASTNodeCreator">
- <filter comment="signature had to be reduced for JLS8" id="338792546">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.dom.rewrite.ASTNodeCreator"/>
- <message_argument value="createArgument(AST, int, Type, String, int, Expression)"/>
- </message_arguments>
- </filter>
- <filter comment="Method had to be adjusted after JLS8-related changes in JDT/Core" id="338792546">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.dom.rewrite.ASTNodeCreator"/>
- <message_argument value="createMethodSpec(AST, String, String, List&lt;String&gt;, List&lt;String&gt;, List&lt;Integer&gt;, boolean)"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="model/org/eclipse/jdt/core/CompletionProposal.java" type="org.eclipse.jdt.core.CompletionProposal">
- <filter comment="need to adjust OT constants to be correctly folded into int bitset" id="388194388">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.CompletionProposal"/>
- <message_argument value="OT_CALLIN_DECLARATION"/>
- <message_argument value="32"/>
- </message_arguments>
- </filter>
- <filter comment="need to adjust OT constants to be correctly folded into int bitset" id="388194388">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.CompletionProposal"/>
- <message_argument value="OT_CALLOUT_DECLARATION"/>
- <message_argument value="28"/>
- </message_arguments>
- </filter>
- <filter comment="need to adjust OT constants to be correctly folded into int bitset" id="388194388">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.CompletionProposal"/>
- <message_argument value="OT_CALLOUT_GET"/>
- <message_argument value="30"/>
- </message_arguments>
- </filter>
- <filter comment="need to adjust OT constants to be correctly folded into int bitset" id="388194388">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.CompletionProposal"/>
- <message_argument value="OT_CALLOUT_OVERRIDE_DECLARATION"/>
- <message_argument value="29"/>
- </message_arguments>
- </filter>
- <filter comment="need to adjust OT constants to be correctly folded into int bitset" id="388194388">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.CompletionProposal"/>
- <message_argument value="OT_CALLOUT_SET"/>
- <message_argument value="31"/>
- </message_arguments>
- </filter>
- <filter comment="need to adjust OT constants to be correctly folded into int bitset" id="388194388">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.CompletionProposal"/>
- <message_argument value="OT_FIELD_SPEC"/>
- <message_argument value="33"/>
- </message_arguments>
- </filter>
- <filter comment="need to adjust OT constants to be correctly folded into int bitset" id="388194388">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.CompletionProposal"/>
- <message_argument value="OT_METHOD_SPEC"/>
- <message_argument value="34"/>
- </message_arguments>
- </filter>
- <filter comment="need to adjust OT constants to be correctly folded into int bitset" id="388194388">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.CompletionProposal"/>
- <message_argument value="OVERRIDE_ROLE_DECLARATION"/>
- <message_argument value="28"/>
- </message_arguments>
- </filter>
- <filter comment="need to adjust OT constants to be correctly folded into int bitset" id="388194388">
- <message_arguments>
- <message_argument value="org.eclipse.jdt.core.CompletionProposal"/>
- <message_argument value="OVERRIDE_ROLE_DECLARATION"/>
- <message_argument value="35"/>
+ <message_argument value="org.eclipse.jdt.core.dom.IExtendedModifier"/>
</message_arguments>
</filter>
</resource>
diff --git a/org.eclipse.jdt.core/META-INF/MANIFEST.MF b/org.eclipse.jdt.core/META-INF/MANIFEST.MF
index 565079a50..cb9459e43 100644
--- a/org.eclipse.jdt.core/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core/META-INF/MANIFEST.MF
@@ -12,10 +12,10 @@ Export-Package: org.eclipse.jdt.core,
org.eclipse.jdt.core.dom.rewrite,
org.eclipse.jdt.core.eval,
org.eclipse.jdt.core.formatter,
+ org.eclipse.jdt.core.index,
org.eclipse.jdt.core.jdom,
org.eclipse.jdt.core.search,
org.eclipse.jdt.core.util,
- org.eclipse.jdt.core.index,
org.eclipse.jdt.internal.codeassist;x-internal:=true,
org.eclipse.jdt.internal.codeassist.complete;x-internal:=true,
org.eclipse.jdt.internal.codeassist.impl;x-internal:=true,
@@ -32,7 +32,11 @@ Export-Package: org.eclipse.jdt.core,
org.eclipse.jdt.internal.compiler.parser;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
org.eclipse.jdt.internal.compiler.parser.diagnose;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
org.eclipse.jdt.internal.compiler.problem;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
- org.eclipse.jdt.internal.compiler.util;x-friends:="org.eclipse.jdt.apt.pluggable.core,org.eclipse.jdt.compiler.tool,org.eclipse.pde.api.tools",
+ org.eclipse.jdt.internal.compiler.util;
+ x-friends:="org.eclipse.jdt.apt.pluggable.core,
+ org.eclipse.jdt.compiler.tool,
+ org.eclipse.pde.api.tools,
+ org.eclipse.jdt.apt.core",
org.eclipse.jdt.internal.core;x-friends:="org.eclipse.jdt.apt.pluggable.core,org.eclipse.pde.api.tools",
org.eclipse.jdt.internal.core.builder;x-friends:="org.eclipse.jdt.apt.pluggable.core,org.eclipse.pde.api.tools",
org.eclipse.jdt.internal.core.dom;x-internal:=true,
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/BatchCompilerRequestor.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/BatchCompilerRequestor.java
new file mode 100644
index 000000000..bfaf56eb6
--- /dev/null
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/BatchCompilerRequestor.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2014 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Gauthier JACQUES - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.batch;
+
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
+
+public class BatchCompilerRequestor implements ICompilerRequestor {
+
+ private Main compiler;
+ private int lineDelta = 0;
+
+ public BatchCompilerRequestor(Main compiler) {
+ this.compiler = compiler;
+ }
+
+ @Override
+ public void acceptResult(CompilationResult compilationResult) {
+ if (compilationResult.lineSeparatorPositions != null) {
+ int unitLineCount = compilationResult.lineSeparatorPositions.length;
+ this.lineDelta += unitLineCount;
+ if (this.compiler.showProgress && this.lineDelta > 2000) {
+ // in -log mode, dump a dot every 2000 lines compiled
+ this.compiler.logger.logProgress();
+ this.lineDelta = 0;
+ }
+ }
+ this.compiler.logger.startLoggingSource(compilationResult);
+ if (compilationResult.hasProblems() || compilationResult.hasTasks()) {
+ this.compiler.logger.logProblems(compilationResult.getAllProblems(), compilationResult.compilationUnit.getContents(), this.compiler);
+ reportProblems(compilationResult);
+ }
+ this.compiler.outputClassFiles(compilationResult);
+ this.compiler.logger.endLoggingSource();
+ }
+
+ protected void reportProblems(CompilationResult result) {
+ // Nothing to do
+ }
+}
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
index 56c7ae63b..ebbc51207 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
@@ -1722,7 +1722,6 @@ private boolean checkVMVersion(long minimalSupportedVersion) {
* Low-level API performing the actual compilation
*/
public boolean compile(String[] argv) {
-
// decode command line arguments
try {
configure(argv);
@@ -3067,26 +3066,7 @@ public String extractDestinationPathFromSourceFile(CompilationResult result) {
* Answer the component to which will be handed back compilation results from the compiler
*/
public ICompilerRequestor getBatchRequestor() {
- return new ICompilerRequestor() {
- int lineDelta = 0;
- public void acceptResult(CompilationResult compilationResult) {
- if (compilationResult.lineSeparatorPositions != null) {
- int unitLineCount = compilationResult.lineSeparatorPositions.length;
- this.lineDelta += unitLineCount;
- if (Main.this.showProgress && this.lineDelta > 2000) {
- // in -log mode, dump a dot every 2000 lines compiled
- Main.this.logger.logProgress();
- this.lineDelta = 0;
- }
- }
- Main.this.logger.startLoggingSource(compilationResult);
- if (compilationResult.hasProblems() || compilationResult.hasTasks()) {
- Main.this.logger.logProblems(compilationResult.getAllProblems(), compilationResult.compilationUnit.getContents(), Main.this);
- }
- outputClassFiles(compilationResult);
- Main.this.logger.endLoggingSource();
- }
- };
+ return new BatchCompilerRequestor(this);
}
/*
* Build the set of compilation source units
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
index 5b44c7262..6cb0b9301 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
@@ -2919,6 +2919,11 @@ public final class CompletionEngine
TypeBinding receiverType = (TypeBinding) qualifiedBinding;
if (receiverType != null && receiverType instanceof ReferenceBinding) {
+ if (!(receiverType.isInterface() || this.requestor.isIgnored(CompletionProposal.KEYWORD))) {
+ this.assistNodeIsConstructor = true;
+ setSourceAndTokenRange(referenceExpression.nameSourceStart, referenceExpression.sourceEnd);
+ findKeywords(this.completionToken, new char[][] { Keywords.NEW }, false, false);
+ }
findMethods(
this.completionToken,
referenceExpression.resolvedTypeArguments,
@@ -8563,6 +8568,9 @@ public final class CompletionEngine
relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN);
relevance += computeRelevanceForQualification(false);
}
+ if (CharOperation.equals(choices[i], Keywords.NEW)) {
+ relevance += computeRelevanceForConstructor();
+ }
this.noProposal = false;
if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
InternalCompletionProposal proposal = createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
@@ -9282,10 +9290,7 @@ public final class CompletionEngine
}
}
// SH}
- if (completionOnReferenceExpressionName)
- proposal.setReplaceRange(this.endPosition - this.offset - methodLength, this.endPosition - this.offset);
- else
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
proposal.setRelevance(relevance);
if(parameterNames != null) proposal.setParameterNames(parameterNames);
@@ -9839,7 +9844,7 @@ public final class CompletionEngine
((scope instanceof MethodScope && !((MethodScope)scope).isStatic)
|| ((methodScope = scope.enclosingMethodScope()) != null && !methodScope.isStatic))) {
if (token.length > 0) {
- findKeywords(token, new char[][]{Keywords.THIS}, true, false);
+ findKeywords(token, new char[][]{Keywords.THIS, Keywords.SUPER}, true, false);
} else {
int relevance = computeBaseRelevance();
relevance += computeRelevanceForResolution();
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionNodeDetector.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionNodeDetector.java
index 617ace923..f3fb7ebaa 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionNodeDetector.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionNodeDetector.java
@@ -134,6 +134,10 @@ public class CompletionNodeDetector extends ASTVisitor {
public void endVisit(QualifiedTypeReference qualifiedTypeReference, ClassScope scope) {
endVisit(qualifiedTypeReference);
}
+ @Override
+ public void endVisit(ReferenceExpression referenceExpression, BlockScope blockScope) {
+ endVisit(referenceExpression);
+ }
public void endVisit(SingleNameReference singleNameReference, BlockScope scope) {
endVisit(singleNameReference);
}
@@ -254,6 +258,10 @@ public class CompletionNodeDetector extends ASTVisitor {
public boolean visit(QualifiedTypeReference qualifiedTypeReference, ClassScope scope) {
return this.visit(qualifiedTypeReference);
}
+ @Override
+ public boolean visit(ReferenceExpression referenceExpression, BlockScope blockScope) {
+ return this.visit(referenceExpression);
+ }
public boolean visit(SingleNameReference singleNameReference, BlockScope scope) {
return this.visit(singleNameReference);
}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
index e00ac5a3d..98b0ec3e7 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
@@ -2910,7 +2910,13 @@ protected void consumeExitVariableWithInitialization() {
} else if (this.assistNode != null && this.assistNode == variable.initialization) {
this.assistNodeParent = variable;
}
- triggerRecoveryUponLambdaClosure(variable, false);
+ if (triggerRecoveryUponLambdaClosure(variable, false)) {
+ if (this.currentElement != null) {
+ this.restartRecovery = true;
+ }
+ if (!isInsideMethod())
+ popElement(K_FIELD_INITIALIZER_DELIMITER);
+ }
}
protected void consumeExitVariableWithoutInitialization() {
// ExitVariableWithoutInitialization ::= $empty
@@ -3914,6 +3920,7 @@ protected void consumeToken(int token) {
if (token == TokenNameIdentifier
&& this.identifierStack[this.identifierPtr] == assistIdentifier()
&& this.currentElement == null
+ && (!isIndirectlyInsideLambdaExpression() || isIndirectlyInsideLambdaBlock())
&& isIndirectlyInsideFieldInitialization()) {
this.scanner.eofPosition = this.cursorLocation < Integer.MAX_VALUE ? this.cursorLocation+1 : this.cursorLocation;
}
@@ -5630,14 +5637,15 @@ protected void updateRecoveryState() {
/* expose parser state to recovery state */
this.currentElement.updateFromParserState();
- /* may be able to retrieve completionNode as an orphan, and then attach it */
- completionIdentifierCheck();
- // attachOrphanCompletionNode pops various stacks to construct astNodeParent and enclosingNode. This does not gel well with extended recovery.
+ // completionIdentifierCheck && attachOrphanCompletionNode pops various stacks to construct astNodeParent and enclosingNode. This does not gel well with extended recovery.
CommitRollbackParser parser = null;
if (lastIndexOfElement(K_LAMBDA_EXPRESSION_DELIMITER) >= 0) {
parser = createSnapShotParser();
parser.copyState(this);
}
+
+ /* may be able to retrieve completionNode as an orphan, and then attach it */
+ completionIdentifierCheck();
attachOrphanCompletionNode();
if (parser != null)
this.copyState(parser);
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java
index 5201b8951..e8fec6854 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java
@@ -51,6 +51,7 @@ import org.eclipse.jdt.internal.compiler.parser.RecoveredBlock;
import org.eclipse.jdt.internal.compiler.parser.RecoveredElement;
import org.eclipse.jdt.internal.compiler.parser.RecoveredField;
import org.eclipse.jdt.internal.compiler.parser.RecoveredInitializer;
+import org.eclipse.jdt.internal.compiler.parser.RecoveredLocalVariable;
import org.eclipse.jdt.internal.compiler.parser.RecoveredMethod;
import org.eclipse.jdt.internal.compiler.parser.RecoveredStatement;
import org.eclipse.jdt.internal.compiler.parser.RecoveredType;
@@ -476,29 +477,47 @@ protected boolean triggerRecoveryUponLambdaClosure(Statement statement, boolean
}
}
- if (lambdaClosed && this.currentElement != null) {
- this.restartRecovery = true;
+ if (lambdaClosed && this.currentElement != null && !(this.currentElement instanceof RecoveredField)) {
if (!(statement instanceof AbstractVariableDeclaration)) { // added already as part of standard recovery since these contribute a name to the scope prevailing at the cursor.
/* See if CompletionParser.attachOrphanCompletionNode has already added bits and pieces of AST to the recovery tree. If so, we want to
replace those fragments with the fuller statement that provides target type for the lambda that got closed just now. There is prior
art/precedent in the Java 7 world to this: Search for recoveredBlock.statements[--recoveredBlock.statementCount] = null;
See also that this concern does not arise in the case of field/local initialization since the initializer is replaced with full tree by consumeExitVariableWithInitialization.
*/
- ASTNode assistNodeParent = this.assistNodeParent();
- ASTNode enclosingNode = this.enclosingNode();
- if (assistNodeParent != null || enclosingNode != null) {
- RecoveredBlock recoveredBlock = (RecoveredBlock) (this.currentElement instanceof RecoveredBlock ? this.currentElement :
- (this.currentElement.parent instanceof RecoveredBlock) ? this.currentElement.parent : null);
- if (recoveredBlock != null) {
- RecoveredStatement recoveredStatement = recoveredBlock.statementCount > 0 ? recoveredBlock.statements[recoveredBlock.statementCount - 1] : null;
- ASTNode parseTree = recoveredStatement != null ? recoveredStatement.updatedStatement(0, new HashSet()) : null;
- if (parseTree != null && (parseTree == assistNodeParent || parseTree == enclosingNode)) {
+ RecoveredBlock recoveredBlock = (RecoveredBlock) (this.currentElement instanceof RecoveredBlock ? this.currentElement :
+ (this.currentElement.parent instanceof RecoveredBlock) ? this.currentElement.parent : null);
+ if (recoveredBlock != null) {
+ RecoveredStatement recoveredStatement = recoveredBlock.statementCount > 0 ? recoveredBlock.statements[recoveredBlock.statementCount - 1] : null;
+ ASTNode parseTree = recoveredStatement != null ? recoveredStatement.updatedStatement(0, new HashSet()) : null;
+ if (parseTree != null) {
+ if ((parseTree.sourceStart == 0 || parseTree.sourceEnd == 0) || (parseTree.sourceStart >= statementStart && parseTree.sourceEnd <= statementEnd)) {
recoveredBlock.statements[--recoveredBlock.statementCount] = null;
this.currentElement = recoveredBlock;
+ } else if (recoveredStatement instanceof RecoveredLocalVariable && statement instanceof Expression) {
+ RecoveredLocalVariable local = (RecoveredLocalVariable) recoveredStatement;
+ if (local.localDeclaration != null && local.localDeclaration.initialization != null) {
+ if ((local.localDeclaration.initialization.sourceStart == 0 || local.localDeclaration.initialization.sourceEnd == 0) ||
+ (local.localDeclaration.initialization.sourceStart >= statementStart && local.localDeclaration.initialization.sourceEnd <= statementEnd) ){
+ local.localDeclaration.initialization = (Expression) statement;
+ local.localDeclaration.declarationSourceEnd = statement.sourceEnd;
+ local.localDeclaration.declarationEnd = statement.sourceEnd;
+ statement = null;
+ }
+ }
+ }
+ }
+ }
+
+ if (statement != null) {
+ while (this.currentElement != null) {
+ ASTNode tree = this.currentElement.parseTree();
+ if (tree.sourceStart < statement.sourceStart) {
+ this.currentElement.add(statement, 0);
+ break;
}
+ this.currentElement = this.currentElement.parent;
}
}
- this.currentElement.add(statement, 0);
}
}
this.snapShot = null;
@@ -518,17 +537,22 @@ public boolean isAssistParser() {
}
protected void consumeBlockStatement() {
super.consumeBlockStatement();
- triggerRecoveryUponLambdaClosure((Statement) this.astStack[this.astPtr], true);
+ if (triggerRecoveryUponLambdaClosure((Statement) this.astStack[this.astPtr], true) && this.currentElement != null)
+ this.restartRecovery = true;
}
protected void consumeBlockStatements() {
super.consumeBlockStatements();
- triggerRecoveryUponLambdaClosure((Statement) this.astStack[this.astPtr], true);
+ if (triggerRecoveryUponLambdaClosure((Statement) this.astStack[this.astPtr], true) && this.currentElement != null) {
+ this.restartRecovery = true;
+ }
}
protected void consumeFieldDeclaration() {
super.consumeFieldDeclaration();
if (triggerRecoveryUponLambdaClosure((Statement) this.astStack[this.astPtr], true)) {
if (this.currentElement instanceof RecoveredType)
popUntilElement(K_TYPE_DELIMITER);
+ if (this.currentElement != null)
+ this.restartRecovery = true;
}
}
protected void consumeForceNoDiet() {
@@ -1513,6 +1537,15 @@ protected boolean isIndirectlyInsideLambdaExpression(){
}
return false;
}
+protected boolean isIndirectlyInsideLambdaBlock(){
+ int i = this.elementPtr;
+ while (i > -1) {
+ if (this.elementKindStack[i] == K_LAMBDA_EXPRESSION_DELIMITER && this.elementInfoStack[i] == BLOCK_BODY)
+ return true;
+ i--;
+ }
+ return false;
+}
protected boolean isIndirectlyInsideType(){
int i = this.elementPtr;
while(i > -1) {
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnReferenceExpressionName.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnReferenceExpressionName.java
index 90665a220..6f791013b 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnReferenceExpressionName.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnReferenceExpressionName.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 IBM Corporation and others.
+ * Copyright (c) 2013, 2014 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
@@ -15,6 +15,7 @@ import org.eclipse.jdt.internal.compiler.ast.ReferenceExpression;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.PolyTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
public class SelectionOnReferenceExpressionName extends ReferenceExpression {
@@ -41,7 +42,7 @@ public class SelectionOnReferenceExpressionName extends ReferenceExpression {
public TypeBinding resolveType(BlockScope scope) {
TypeBinding type = super.resolveType(scope);
- if (type instanceof PolyTypeBinding)
+ if (type == null || type instanceof ProblemReferenceBinding || type instanceof PolyTypeBinding)
return type;
MethodBinding method = getMethodBinding();
if (method != null && method.isValidBinding() && !method.isSynthetic())
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java
index 888b70d1f..f7183707e 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java
@@ -800,7 +800,7 @@ protected void consumeLocalVariableDeclarationStatement() {
super.consumeLocalVariableDeclarationStatement();
// force to restart in recovery mode if the declaration contains the selection
- if (!this.diet) {
+ if (!this.diet && this.astStack[this.astPtr] instanceof LocalDeclaration) {
LocalDeclaration localDeclaration = (LocalDeclaration) this.astStack[this.astPtr];
if ((this.selectionStart >= localDeclaration.sourceStart)
&& (this.selectionEnd <= localDeclaration.sourceEnd)) {
@@ -908,6 +908,18 @@ protected void consumeMethodInvocationName() {
}
} else {
super.consumeMethodInvocationName();
+ if (requireExtendedRecovery()) {
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=430572, compensate for the hacks elsewhere where super/this gets treated as identifier. See getUnspecifiedReference
+ if (this.astPtr >= 0 && this.astStack[this.astPtr] == this.assistNode && this.assistNode instanceof ThisReference) {
+ MessageSend messageSend = (MessageSend) this.expressionStack[this.expressionPtr];
+ if (messageSend.receiver instanceof SingleNameReference) {
+ SingleNameReference snr = (SingleNameReference) messageSend.receiver;
+ if (snr.token == CharOperation.NO_CHAR) { // dummy reference created by getUnspecifiedReference ???
+ messageSend.receiver = (Expression) this.astStack[this.astPtr--];
+ }
+ }
+ }
+ }
return;
}
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 a0c391ac5..a3e5ed6c8 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
@@ -1839,7 +1839,8 @@ void setSourceStart(int sourceStart);
/** @since 3.10 */
int GenericInferenceError = 1100; // FIXME: This is just a stop-gap measure, be more specific via https://bugs.eclipse.org/404675
- /** @since 3.10 */
+ /** @deprecated - problem is no longer generated (implementation issue has been resolved)
+ * @since 3.10 */
int LambdaShapeComputationError = 1101;
//{ObjectTeams:
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
index f1a0c185d..7b847fade 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
@@ -22,8 +22,12 @@
* Bug 415399 - [1.8][compiler] Type annotations on constructor results dropped by the code generator
* Bug 415470 - [1.8][compiler] Type annotations on class declaration go vanishing
* Bug 405104 - [1.8][compiler][codegen] Implement support for serializeable lambdas
+ * Bug 434556 - Broken class file generated for incorrect annotation usage
+ * Bug 442416 - $deserializeLambda$ missing cases for nested lambdas
* Stephan Herrmann - Contribution for
* Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables
+ * Olivier Tardieu tardieu@us.ibm.com - Contributions for
+ * Bug 442416 - $deserializeLambda$ missing cases for nested lambdas
*******************************************************************************/
package org.eclipse.jdt.internal.compiler;
@@ -956,6 +960,7 @@ public class ClassFile implements TypeConstants, TypeIds {
// add synthetic methods infos
int emittedSyntheticsCount = 0;
+ SyntheticMethodBinding deserializeLambdaMethod = null;
boolean continueScanningSynthetics = true;
while (continueScanningSynthetics) {
continueScanningSynthetics = false;
@@ -1020,14 +1025,16 @@ public class ClassFile implements TypeConstants, TypeIds {
addSyntheticFactoryMethod(syntheticMethod);
break;
case SyntheticMethodBinding.DeserializeLambda:
- // TODO [andy] do we need to do this after the loop to ensure it is done last?
- addSyntheticDeserializeLambda(syntheticMethod,this.referenceBinding.syntheticMethods());
+ deserializeLambdaMethod = syntheticMethod; // delay processing
break;
}
}
emittedSyntheticsCount = currentSyntheticsCount;
}
}
+ if (deserializeLambdaMethod != null) {
+ addSyntheticDeserializeLambda(deserializeLambdaMethod,this.referenceBinding.syntheticMethods());
+ }
}
public void addSyntheticArrayConstructor(SyntheticMethodBinding methodBinding) {
@@ -2356,7 +2363,7 @@ public class ClassFile implements TypeConstants, TypeIds {
LocalVariableBinding localVariable = annotationContext.variableBinding;
int actualSize = 0;
int initializationCount = localVariable.initializationCount;
- actualSize += 6 * initializationCount;
+ actualSize += 2 /* for number of entries */ + (6 * initializationCount);
// reserve enough space
if (this.contentsOffset + actualSize >= this.contents.length) {
resizeContents(actualSize);
@@ -2422,9 +2429,11 @@ public class ClassFile implements TypeConstants, TypeIds {
MemberValuePair[] memberValuePairs = normalAnnotation.memberValuePairs;
int memberValuePairOffset = this.contentsOffset;
if (memberValuePairs != null) {
+ int memberValuePairsCount = 0;
+ int memberValuePairsLengthPosition = this.contentsOffset;
+ this.contentsOffset += 2; // leave space to fill in the pair count later
+ int resetPosition = this.contentsOffset;
final int memberValuePairsLength = memberValuePairs.length;
- this.contents[this.contentsOffset++] = (byte) (memberValuePairsLength >> 8);
- this.contents[this.contentsOffset++] = (byte) memberValuePairsLength;
loop: for (int i = 0; i < memberValuePairsLength; i++) {
MemberValuePair memberValuePair = memberValuePairs[i];
if (this.contentsOffset + 2 >= this.contents.length) {
@@ -2435,7 +2444,7 @@ public class ClassFile implements TypeConstants, TypeIds {
this.contents[this.contentsOffset++] = (byte) elementNameIndex;
MethodBinding methodBinding = memberValuePair.binding;
if (methodBinding == null) {
- this.contentsOffset = startingContentsOffset;
+ this.contentsOffset = resetPosition;
} else {
try {
generateElementValue(memberValuePair.value, methodBinding.returnType, memberValuePairOffset);
@@ -2445,13 +2454,17 @@ public class ClassFile implements TypeConstants, TypeIds {
this.contents[this.contentsOffset++] = 0;
break loop;
}
+ memberValuePairsCount++;
+ resetPosition = this.contentsOffset;
} catch(ClassCastException e) {
- this.contentsOffset = startingContentsOffset;
+ this.contentsOffset = resetPosition;
} catch(ShouldNotImplement e) {
- this.contentsOffset = startingContentsOffset;
+ this.contentsOffset = resetPosition;
}
}
}
+ this.contents[memberValuePairsLengthPosition++] = (byte) (memberValuePairsCount >> 8);
+ this.contents[memberValuePairsLengthPosition++] = (byte) memberValuePairsCount;
} else {
this.contents[this.contentsOffset++] = 0;
this.contents[this.contentsOffset++] = 0;
@@ -5299,11 +5312,11 @@ public class ClassFile implements TypeConstants, TypeIds {
this.innerClassesBindings = new HashSet(INNER_CLASSES_SIZE);
}
ReferenceBinding innerClass = (ReferenceBinding) binding;
- this.innerClassesBindings.add(innerClass.erasure().unannotated(false)); // should not emit yet another inner class for Outer.@Inner Inner.
+ this.innerClassesBindings.add(innerClass.erasure().unannotated()); // should not emit yet another inner class for Outer.@Inner Inner.
ReferenceBinding enclosingType = innerClass.enclosingType();
while (enclosingType != null
&& enclosingType.isNestedType()) {
- this.innerClassesBindings.add(enclosingType.erasure().unannotated(false));
+ this.innerClassesBindings.add(enclosingType.erasure().unannotated());
enclosingType = enclosingType.enclosingType();
}
}
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 4a414f6b3..1449ff1b1 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
@@ -32,6 +32,8 @@
* Bug 427163 - [1.8][null] bogus error "Contradictory null specification" on varags
* Bug 432348 - [1.8] Internal compiler error (NPE) after upgrade to 1.8
* Bug 440143 - [1.8][null] one more case of contradictory null annotations regarding type variables
+ * Bug 441693 - [1.8][null] Bogus warning for type argument annotated with @NonNull
+ * Bug 434483 - [1.8][compiler][inference] Type inference not picked up with method reference
* Jesper S Moller - Contributions for
* bug 382721 - [1.8][compiler] Effectively final variables needs special treatment
* bug 412153 - [1.8][compiler] Check validity of annotations which may be repeatable
@@ -744,7 +746,7 @@ public abstract class ASTNode implements TypeConstants, TypeIds {
final TypeBinding[] parameters = candidateMethod.parameters;
Expression[] innerArguments = invocation.arguments();
Expression [] arguments = innerArguments;
- if (infCtx == null && variableArity && parameters.length == arguments.length) { // re-check
+ if (infCtx == null && variableArity && arguments != null && parameters.length == arguments.length) { // re-check
TypeBinding lastParam = parameters[parameters.length-1];
Expression lastArg = arguments[arguments.length-1];
if (lastArg.isCompatibleWith(lastParam, null)) {
@@ -1179,7 +1181,7 @@ public abstract class ASTNode implements TypeConstants, TypeIds {
if (se8nullBits != 0 && prevNullBits != se8nullBits && ((prevNullBits | se8nullBits) == TagBits.AnnotationNullMASK)) {
if (existingType instanceof TypeVariableBinding) {
// let type-use annotations override annotations on the type parameter declaration
- existingType = existingType.unannotated(true);
+ existingType = existingType.withoutToplevelNullAnnotation();
} else {
scope.problemReporter().contradictoryNullAnnotations(se8NullAnnotation);
}
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 9e4982478..f60e77dda 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
@@ -791,7 +791,7 @@ public abstract class Annotation extends Expression {
}
}
if (isSuppressingWarnings && suppressWarningIrritants != null) {
- scope.referenceCompilationUnit().recordSuppressWarnings(suppressWarningIrritants, this, startSuppresss, endSuppress);
+ scope.referenceCompilationUnit().recordSuppressWarnings(suppressWarningIrritants, this, startSuppresss, endSuppress, scope.referenceContext());
}
}
@@ -885,7 +885,7 @@ public abstract class Annotation extends Expression {
tagBits &= ~Binding.NullnessDefaultMASK;
// record annotation positions in the compilation result
- scope.referenceCompilationUnit().recordSuppressWarnings(IrritantSet.NLS, null, this.sourceStart, this.declarationSourceEnd);
+ scope.referenceCompilationUnit().recordSuppressWarnings(IrritantSet.NLS, null, this.sourceStart, this.declarationSourceEnd, scope.referenceContext());
if (this.recipient != null) {
int kind = this.recipient.kind();
if (tagBits != 0 || defaultNullness != 0) {
@@ -976,6 +976,11 @@ public abstract class Annotation extends Expression {
}
break;
}
+ }
+ if (kind == Binding.TYPE) {
+ SourceTypeBinding sourceType = (SourceTypeBinding) this.recipient;
+ if (CharOperation.equals(sourceType.sourceName, TypeConstants.PACKAGE_INFO_NAME))
+ kind = Binding.PACKAGE;
}
checkAnnotationTarget(this, scope, annotationType, kind);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java
index 74feee392..1833a96eb 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java
@@ -53,6 +53,11 @@ public class Argument extends LocalDeclaration {
}
this.bits |= (IsLocalDeclarationReachable | IsArgument);
}
+
+ @Override
+ public boolean isRecoveredFromLoneIdentifier() {
+ return false;
+ }
public Argument(char[] name, long posNom, TypeReference tr, int modifiers, boolean typeElided) {
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 d35bf20f1..5240ed2cf 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
@@ -617,7 +617,10 @@ public boolean isWarningSuppressedAt(int problemID, int start, int end, Irritant
}
// SH}
-public void recordSuppressWarnings(IrritantSet irritants, Annotation annotation, int scopeStart, int scopeEnd) {
+public void recordSuppressWarnings(IrritantSet irritants, Annotation annotation, int scopeStart, int scopeEnd, ReferenceContext context) {
+ if (context instanceof LambdaExpression && context != ((LambdaExpression) context).original())
+ return; // Do not record from copies. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=441929
+
if (this.suppressWarningIrritants == null) {
this.suppressWarningIrritants = new IrritantSet[3];
this.suppressWarningAnnotations = new Annotation[3];
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
index b90060ddc..a23c17fc0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
@@ -32,6 +32,7 @@
* Bug 429430 - [1.8] Lambdas and method reference infer wrong exception type with generics (RuntimeException instead of IOException)
* Bug 432110 - [1.8][compiler] nested lambda type incorrectly inferred vs javac
* Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables
+ * Bug 441693 - [1.8][null] Bogus warning for type argument annotated with @NonNull
* Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
* Bug 405104 - [1.8][compiler][codegen] Implement support for serializeable lambdas
*******************************************************************************/
@@ -448,8 +449,14 @@ public class LambdaExpression extends FunctionalExpression implements ReferenceC
new ExceptionHandlingFlowContext(null, this, Binding.NO_EXCEPTIONS, null, this.scope, FlowInfo.DEAD_END),
UnconditionalFlowInfo.fakeInitializedFlowInfo(this.scope.outerMostMethodScope().analysisIndex, this.scope.referenceType().maxFieldCount)) == FlowInfo.DEAD_END;
} catch (RuntimeException e) {
- this.scope.problemReporter().lambdaShapeComputationError(this);
- return this.valueCompatible;
+ /* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=432110 for an example of where the flow analysis can result in run time error.
+ We can recover and do the right thing by falling back on the results of the structural analysis done already and be right 99.99%
+ of the time. Strictly speaking void/value compatibility is not a structural property. { throw NPE(); } is value compatible despite
+ structurally there not being a return statement. Likewise { if (x) return value; } is not value compatible despite there being a
+ return statement. We will miss the former case, but that is mostly pedantic. We would misclassify the latter case *here*, but it
+ would be caught elsewhere, so it should all wash out in the end.
+ */
+ return this.original.valueCompatible;
}
}
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, final FlowInfo flowInfo) {
@@ -463,7 +470,7 @@ public class LambdaExpression extends FunctionalExpression implements ReferenceC
flowContext,
this,
this.binding.thrownExceptions,
- null,
+ flowContext.getInitializationContext(),
this.scope,
FlowInfo.DEAD_END);
@@ -510,7 +517,7 @@ public class LambdaExpression extends FunctionalExpression implements ReferenceC
int length = this.binding.parameters.length;
for (int i=0; i<length; i++) {
if (!this.scope.validateNullAnnotation(this.binding.returnType.tagBits, this.arguments[i].type, this.arguments[i].annotations))
- this.binding.returnType = this.binding.returnType.unannotated(true);
+ this.binding.returnType = this.binding.returnType.withoutToplevelNullAnnotation();
}
}
}
@@ -686,7 +693,8 @@ public class LambdaExpression extends FunctionalExpression implements ReferenceC
}
}
if (this.body instanceof Expression) {
- this.voidCompatible = ((Expression) this.body).statementExpression();
+ // When completion is still in progress, it is not possible to ask if the expression constitutes a statement expression. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=435219
+ this.voidCompatible = /* ((Expression) this.body).statementExpression(); */ true;
this.valueCompatible = true;
} else {
// We need to be a bit tolerant/fuzzy here: the code is being written "just now", if we are too pedantic, selection/completion will break;
@@ -712,14 +720,7 @@ public class LambdaExpression extends FunctionalExpression implements ReferenceC
if (copy == null) {
if (this.assistNode) {
analyzeShape(); // not on terra firma here !
-// FIXME: we don't yet have the same, should we compute it here & now?
-// if (sam.returnType.id == TypeIds.T_void) {
-// if (!this.voidCompatible)
-// return false;
-// } else {
-// if (!this.valueCompatible)
-// return false;
-// }
+ break shapeAnalysis;
}
return !isPertinentToApplicability(left, null);
}
@@ -734,10 +735,9 @@ public class LambdaExpression extends FunctionalExpression implements ReferenceC
this.shapeAnalysisComplete = true;
}
} else {
- this.voidCompatible = ((Expression) this.body).statementExpression();
- // TODO: in getResolvedCopyForInferenceTargeting() we need to check if the expression
- // *could* also produce a value and set valueCompatible accordingly.
- // Is that needed also here?
+ final Expression expressionBody = (Expression) this.body;
+ this.voidCompatible = this.assistNode ? true : expressionBody.statementExpression();
+ this.valueCompatible = expressionBody.resolvedType != TypeBinding.VOID;
this.shapeAnalysisComplete = true;
}
// Do not proceed with data/control flow analysis if resolve encountered errors.
@@ -776,9 +776,6 @@ public class LambdaExpression extends FunctionalExpression implements ReferenceC
if (sam.parameters.length != this.arguments.length)
return false;
- if (!isPertinentToApplicability(left, null)) // This check should happen after return type check below, but for buggy javac compatibility we have left it in.
- return true;
-
if (sam.returnType.id == TypeIds.T_void) {
if (!this.voidCompatible)
return false;
@@ -786,6 +783,10 @@ public class LambdaExpression extends FunctionalExpression implements ReferenceC
if (!this.valueCompatible)
return false;
}
+
+ if (!isPertinentToApplicability(left, null))
+ return true;
+
Expression [] returnExpressions = this.resultExpressions;
for (int i = 0, length = returnExpressions.length; i < length; i++) {
if (returnExpressions[i] instanceof FunctionalExpression) { // don't want to use the resolvedType - polluted from some other overload resolution candidate
@@ -841,8 +842,6 @@ public class LambdaExpression extends FunctionalExpression implements ReferenceC
if (this.body instanceof Block) {
if (copy.returnsVoid) {
copy.shapeAnalysisComplete = true;
- } else {
- copy.valueCompatible = this.returnsValue;
}
} else {
copy.voidCompatible = ((Expression) this.body).statementExpression();
@@ -1203,9 +1202,16 @@ public class LambdaExpression extends FunctionalExpression implements ReferenceC
public MethodBinding getMethodBinding() {
if (this.actualMethodBinding == null) {
if (this.binding != null) {
- this.actualMethodBinding = new MethodBinding(this.binding.modifiers, this.binding.selector, this.binding.returnType,
- this.binding instanceof SyntheticMethodBinding ? this.descriptor.parameters : this.binding.parameters, // retain any faults in parameter list.
- this.binding.thrownExceptions, this.binding.declaringClass);
+ // Get rid of the synthetic arguments added via addSyntheticArgument()
+ TypeBinding[] newParams = null;
+ if (this.binding instanceof SyntheticMethodBinding && this.outerLocalVariables.length > 0) {
+ newParams = new TypeBinding[this.binding.parameters.length - this.outerLocalVariables.length];
+ System.arraycopy(this.binding.parameters, this.outerLocalVariables.length, newParams, 0, newParams.length);
+ } else {
+ newParams = this.binding.parameters;
+ }
+ this.actualMethodBinding = new MethodBinding(this.binding.modifiers, this.binding.selector,
+ this.binding.returnType, newParams, this.binding.thrownExceptions, this.binding.declaringClass);
this.actualMethodBinding.tagBits = this.binding.tagBits;
} else {
this.actualMethodBinding = new ProblemMethodBinding(CharOperation.NO_CHAR, null, ProblemReasons.NoSuchSingleAbstractMethod);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
index f9d635ebf..6da91608c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
@@ -46,6 +46,7 @@ import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.codegen.*;
import org.eclipse.jdt.internal.compiler.flow.*;
import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.parser.RecoveryScanner;
import org.eclipse.objectteams.otdt.internal.core.compiler.control.Config;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.DependentTypeBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.IAlienScopeTypeReference;
@@ -406,4 +407,8 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl
visitor.endVisit(this, scope);
}
+ public boolean isRecoveredFromLoneIdentifier() { // recovered from lonely identifier or identifier cluster ?
+ return this.name == RecoveryScanner.FAKE_IDENTIFIER &&
+ (this.type instanceof SingleTypeReference || (this.type instanceof QualifiedTypeReference && !(this.type instanceof ArrayQualifiedTypeReference))) && this.initialization == null && !this.type.isBaseTypeReference();
+ }
}
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 a76b569c8..d363c0dcf 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
@@ -49,6 +49,7 @@
* Bug 426996 - [1.8][inference] try to avoid method Expression.unresolve()?
* Bug 428352 - [1.8][compiler] Resolution errors don't always surface
* Bug 429430 - [1.8] Lambdas and method reference infer wrong exception type with generics (RuntimeException instead of IOException)
+ * Bug 441734 - [1.8][inference] Generic method with nested parameterized type argument fails on method reference
* Jesper S Moller - Contributions for
* Bug 378674 - "The method can be declared as static" is wrong
* Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
@@ -1339,7 +1340,7 @@ protected void findMethodBinding(BlockScope scope, TypeBinding[] argumentTypes)
return;
finalArgumentTypes[i] = finalArgumentType;
}
- if (scope.parameterCompatibilityLevel(this.binding, finalArgumentTypes, false) == Scope.NOT_COMPATIBLE)
+ if (scope.parameterCompatibilityLevel(this.binding, finalArgumentTypes, false, false) == Scope.NOT_COMPATIBLE)
this.binding = new ProblemMethodBinding(this.binding.original(), this.binding.selector, finalArgumentTypes, ProblemReasons.NotFound);
}
}
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 9ce03b569..310c53d91 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
@@ -29,6 +29,9 @@
* Bug 435570 - [1.8][null] @NonNullByDefault illegally tries to affect "throws E"
* Bug 435689 - [1.8][inference] Type inference not occurring with lambda expression and method reference
* Bug 438383 - [1.8][null] Bogus warning: Null type safety at method return type
+ * Bug 434483 - [1.8][compiler][inference] Type inference not picked up with method reference
+ * Bug 441734 - [1.8][inference] Generic method with nested parameterized type argument fails on method reference
+ * Bug 438945 - [1.8] NullPointerException InferenceContext18.checkExpression in java 8 with generics, primitives, and overloading
* Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contribution for
* Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
*******************************************************************************/
@@ -87,7 +90,9 @@ public class ReferenceExpression extends FunctionalExpression implements Invocat
private int depth;
private MethodBinding exactMethodBinding; // != null ==> exact method reference.
private boolean receiverPrecedesParameters = false;
- protected boolean trialResolution = false;
+ private TypeBinding[] freeParameters; // descriptor parameters as used for method lookup - may or may not include the receiver
+ public boolean trialResolution = false;
+ public int inferenceKind; // TODO: define life-cycle: when to re-initialize? How long to keep value?
public ReferenceExpression() {
super();
@@ -402,7 +407,13 @@ public class ReferenceExpression extends FunctionalExpression implements Invocat
lhsType = lhsType.closestMatch(); // improve resolving experience
if (!lhsType.isValidBinding())
return this.resolvedType = null; // nope, no useful type found
- final TypeBinding[] descriptorParameters = this.descriptor != null ? this.descriptor.parameters : Binding.NO_PARAMETERS;
+
+ // Convert parameters into argument expressions for look up.
+ TypeBinding[] descriptorParameters = this.descriptor != null && this.descriptor.parameters != null && this.descriptor.parameters.length > 0 ?
+ new TypeBinding[this.descriptor.parameters.length] : Binding.NO_PARAMETERS;
+ for (int i = 0, length = descriptorParameters.length; i < length; i++)
+ descriptorParameters[i] = this.descriptor.parameters[i].capture(scope, this.sourceEnd);
+
if (lhsType.isBaseType()) {
scope.problemReporter().errorNoMethodFor(this.lhs, lhsType, this.selector, descriptorParameters);
return this.resolvedType = null;
@@ -417,11 +428,11 @@ public class ReferenceExpression extends FunctionalExpression implements Invocat
scope.problemReporter().nullAnnotationUnsupportedLocation((TypeReference) this.lhs);
}
- /* 15.28: "It is a compile-time error if a method reference of the form super :: NonWildTypeArgumentsopt Identifier or of the form
- TypeName . super :: NonWildTypeArgumentsopt Identifier occurs in a static context.": This is nop since the primary when it resolves
+ /* 15.13: "If a method reference expression has the form super :: [TypeArguments] Identifier or TypeName . super :: [TypeArguments] Identifier,
+ it is a compile-time error if the expression occurs in a static context. ": This is nop since the primary when it resolves
itself will complain automatically.
- 15.28: "The immediately enclosing instance of an inner class instance (15.9.2) must be provided for a constructor reference by a lexically
+ 15.13: "The immediately enclosing instance of an inner class instance (15.9.2) must be provided for a constructor reference by a lexically
enclosing instance of this (8.1.3)", we will actually implement this check in code generation. Emulation path computation will fail if there
is no suitable enclosing instance. While this could be pulled up to here, leaving it to code generation is more consistent with Java 5,6,7
modus operandi.
@@ -465,24 +476,18 @@ public class ReferenceExpression extends FunctionalExpression implements Invocat
if (this.descriptor == null || !this.descriptor.isValidBinding())
return this.resolvedType = null;
- // 15.28.1
+ // 15.13.1
final boolean isMethodReference = isMethodReference();
this.depth = 0;
+ this.freeParameters = descriptorParameters;
MethodBinding someMethod = isMethodReference ? scope.getMethod(this.receiverType, this.selector, descriptorParameters, this) :
scope.getConstructor((ReferenceBinding) this.receiverType, descriptorParameters, this);
int someMethodDepth = this.depth, anotherMethodDepth = 0;
if (someMethod != null && someMethod.isValidBinding()) {
- final boolean isStatic = someMethod.isStatic();
- if (isStatic && (this.haveReceiver || this.receiverType.isParameterizedTypeWithActualArguments())) {
+ if (someMethod.isStatic() && (this.haveReceiver || this.receiverType.isParameterizedTypeWithActualArguments())) {
scope.problemReporter().methodMustBeAccessedStatically(this, someMethod);
return this.resolvedType = null;
}
- if (!this.haveReceiver) {
- if (!isStatic && !someMethod.isConstructor()) {
- scope.problemReporter().methodMustBeAccessedWithInstance(this, someMethod);
- return this.resolvedType = null;
- }
- }
}
if (this.lhs.isSuper() && this.lhs.resolvedType.isInterface()) {
@@ -506,34 +511,41 @@ public class ReferenceExpression extends FunctionalExpression implements Invocat
System.arraycopy(descriptorParameters, 1, parameters, 0, parametersLength - 1);
}
this.depth = 0;
+ this.freeParameters = parameters;
anotherMethod = scope.getMethod(typeToSearch, this.selector, parameters, this);
anotherMethodDepth = this.depth;
this.depth = 0;
}
- if (anotherMethod != null && anotherMethod.isValidBinding() && anotherMethod.isStatic()) {
- scope.problemReporter().methodMustBeAccessedStatically(this, anotherMethod);
- return this.resolvedType = null;
- }
}
- if (someMethod != null && someMethod.isValidBinding() && anotherMethod != null && anotherMethod.isValidBinding()) {
+ if (someMethod != null && someMethod.isValidBinding() && someMethod.isStatic() && anotherMethod != null && anotherMethod.isValidBinding() && !anotherMethod.isStatic()) {
scope.problemReporter().methodReferenceSwingsBothWays(this, anotherMethod, someMethod);
return this.resolvedType = null;
}
- if (someMethod != null && someMethod.isValidBinding()) {
+ if (someMethod != null && someMethod.isValidBinding() && (anotherMethod == null || !anotherMethod.isValidBinding() || anotherMethod.isStatic())) {
this.binding = someMethod;
this.bits &= ~ASTNode.DepthMASK;
if (someMethodDepth > 0) {
this.bits |= (someMethodDepth & 0xFF) << ASTNode.DepthSHIFT;
}
- } else if (anotherMethod != null && anotherMethod.isValidBinding()) {
+ if (!this.haveReceiver) {
+ if (!someMethod.isStatic() && !someMethod.isConstructor()) {
+ scope.problemReporter().methodMustBeAccessedWithInstance(this, someMethod);
+ return this.resolvedType = null;
+ }
+ }
+ } else if (anotherMethod != null && anotherMethod.isValidBinding() && (someMethod == null || !someMethod.isValidBinding() || !someMethod.isStatic())) {
this.binding = anotherMethod;
this.receiverPrecedesParameters = true; // 0 is receiver, real parameters start at 1
this.bits &= ~ASTNode.DepthMASK;
if (anotherMethodDepth > 0) {
this.bits |= (anotherMethodDepth & 0xFF) << ASTNode.DepthSHIFT;
}
+ if (anotherMethod.isStatic()) {
+ scope.problemReporter().methodMustBeAccessedStatically(this, anotherMethod);
+ return this.resolvedType = null;
+ }
} else {
this.binding = null;
this.bits &= ~ASTNode.DepthMASK;
@@ -583,6 +595,7 @@ public class ReferenceExpression extends FunctionalExpression implements Invocat
scope.problemReporter().unhandledException(methodExceptions[i], this);
}
if (scope.compilerOptions().isAnnotationBasedNullAnalysisEnabled) {
+ // TODO: simplify by using this.freeParameters?
int len;
int expectedlen = this.binding.parameters.length;
int providedLen = this.descriptor.parameters.length;
@@ -617,6 +630,7 @@ public class ReferenceExpression extends FunctionalExpression implements Invocat
}
}
}
+ this.freeParameters = null; // not used after method lookup
if (checkInvocationArguments(scope, null, this.receiverType, this.binding, null, descriptorParameters, false, this))
this.bits |= ASTNode.Unchecked;
@@ -686,6 +700,18 @@ public class ReferenceExpression extends FunctionalExpression implements Invocat
}
}
+ public MethodBinding prepareForInferenceResult(Scope scope) {
+ try {
+ setExpressionContext(INVOCATION_CONTEXT);
+ this.binding = null;
+ this.trialResolution = true;
+ resolveType(this.enclosingScope);
+ return this.binding;
+ } finally {
+ this.trialResolution = false;
+ }
+ }
+
public boolean isConstructorReference() {
return CharOperation.equals(this.selector, ConstantPool.Init);
}
@@ -694,6 +720,10 @@ public class ReferenceExpression extends FunctionalExpression implements Invocat
return this.exactMethodBinding != null;
}
+ public MethodBinding getExactMethod() {
+ return this.exactMethodBinding;
+ }
+
public boolean isMethodReference() {
return !CharOperation.equals(this.selector, ConstantPool.Init);
}
@@ -710,7 +740,11 @@ public class ReferenceExpression extends FunctionalExpression implements Invocat
}
public InferenceContext18 freshInferenceContext(Scope scope) {
- return null; // subject to inference only as an argument to an outer invocation
+ if (this.expressionContext != ExpressionContext.VANILLA_CONTEXT) {
+ Expression[] arguments = createPseudoExpressions(this.freeParameters);
+ return new InferenceContext18(scope, arguments, this);
+ }
+ return null; // shouldn't happen, actually
}
public boolean isSuperAccess() {
@@ -770,9 +804,7 @@ public class ReferenceExpression extends FunctionalExpression implements Invocat
}
public Expression[] createPseudoExpressions(TypeBinding[] p) {
- if (this.descriptor == null)
- return null;
- // from 15.28.1:
+ // from 15.13.1:
// ... the reference is treated as if it were an invocation with argument expressions of types P1..Pn
// ... the reference is treated as if it were an invocation with argument expressions of types P2..Pn
// (the different sets of types are passed from our resolveType to scope.getMethod(..), see someMethod, anotherMethod)
@@ -790,7 +822,7 @@ public class ReferenceExpression extends FunctionalExpression implements Invocat
&& this.resolvedType != null && this.resolvedType.isValidBinding()) {
return this.resolvedType.isCompatibleWith(left, scope);
}
- // 15.28.2
+ // 15.13.2
left = left.uncapture(this.enclosingScope);
final MethodBinding sam = left.getSingleAbstractMethod(this.enclosingScope, true);
if (sam == null || !sam.isValidBinding())
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
index bce8fbfaa..77a7b1a35 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
@@ -296,27 +296,33 @@ public boolean checkNPE(BlockScope scope, FlowContext flowContext, FlowInfo flow
public void computeConversion(Scope scope, TypeBinding runtimeTimeType, TypeBinding compileTimeType) {
if (runtimeTimeType == null || compileTimeType == null)
return;
- if ((this.bits & Binding.FIELD) != 0 && this.binding != null && this.binding.isValidBinding()) {
- // set the generic cast after the fact, once the type expectation is fully known (no need for strict cast)
- FieldBinding field = (FieldBinding) this.binding;
- FieldBinding originalBinding = field.original();
- TypeBinding originalType = originalBinding.type;
- // extra cast needed if field type is type variable
- if (originalType.leafComponentType().isTypeVariable()) {
- TypeBinding targetType = (!compileTimeType.isBaseType() && runtimeTimeType.isBaseType())
- ? compileTimeType // unboxing: checkcast before conversion
- : runtimeTimeType;
- this.genericCast = originalType.genericCast(scope.boxing(targetType));
- if (this.genericCast instanceof ReferenceBinding) {
+ if (this.binding != null && this.binding.isValidBinding()) {
+ TypeBinding originalType = null;
+ if ((this.bits & Binding.FIELD) != 0) {
+ // set the generic cast after the fact, once the type expectation is fully known (no need for strict cast)
+ FieldBinding field = (FieldBinding) this.binding;
+ FieldBinding originalBinding = field.original();
+ originalType = originalBinding.type;
+ } else if ((this.bits & Binding.LOCAL) != 0) {
+ LocalVariableBinding local = (LocalVariableBinding) this.binding;
+ originalType = local.type;
+ }
+ // extra cast needed if field/local type is type variable
+ if (originalType != null && originalType.leafComponentType().isTypeVariable()) {
+ TypeBinding targetType = (!compileTimeType.isBaseType() && runtimeTimeType.isBaseType())
+ ? compileTimeType // unboxing: checkcast before conversion
+ : runtimeTimeType;
+ this.genericCast = originalType.genericCast(scope.boxing(targetType));
+ if (this.genericCast instanceof ReferenceBinding) {
ReferenceBinding referenceCast = (ReferenceBinding) this.genericCast;
if (!referenceCast.canBeSeenBy(scope)) {
- scope.problemReporter().invalidType(this,
- new ProblemReferenceBinding(
- CharOperation.splitOn('.', referenceCast.shortReadableName()),
- referenceCast,
- ProblemReasons.NotVisible));
+ scope.problemReporter().invalidType(this,
+ new ProblemReferenceBinding(
+ CharOperation.splitOn('.', referenceCast.shortReadableName()),
+ referenceCast,
+ ProblemReasons.NotVisible));
}
- }
+ }
}
}
super.computeConversion(scope, runtimeTimeType, compileTimeType);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java
index 7ee4c816e..b6ef490d1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java
@@ -77,6 +77,20 @@ public class SingleTypeReference extends TypeReference {
return new char[][] { this.token };
}
+ @Override
+ public boolean isBaseTypeReference() {
+ return this.token == BYTE ||
+ this.token == SHORT ||
+ this.token == INT ||
+ this.token == LONG ||
+ this.token == FLOAT ||
+ this.token == DOUBLE ||
+ this.token == CHAR ||
+ this.token == BOOLEAN ||
+ this.token == NULL ||
+ this.token == VOID;
+ }
+
public StringBuffer printExpression(int indent, StringBuffer output){
if (this.annotations != null && this.annotations[0] != null) {
printAnnotations(this.annotations[0], output);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/StringLiteral.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/StringLiteral.java
index 211cf17ea..ebf451a02 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/StringLiteral.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/StringLiteral.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 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
@@ -15,6 +15,7 @@ import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
import org.eclipse.jdt.internal.compiler.impl.StringConstant;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.util.Util;
public class StringLiteral extends Literal {
@@ -77,34 +78,7 @@ public class StringLiteral extends Literal {
// handle some special char.....
output.append('\"');
for (int i = 0; i < this.source.length; i++) {
- switch (this.source[i]) {
- case '\b' :
- output.append("\\b"); //$NON-NLS-1$
- break;
- case '\t' :
- output.append("\\t"); //$NON-NLS-1$
- break;
- case '\n' :
- output.append("\\n"); //$NON-NLS-1$
- break;
- case '\f' :
- output.append("\\f"); //$NON-NLS-1$
- break;
- case '\r' :
- output.append("\\r"); //$NON-NLS-1$
- break;
- case '\"' :
- output.append("\\\""); //$NON-NLS-1$
- break;
- case '\'' :
- output.append("\\'"); //$NON-NLS-1$
- break;
- case '\\' : //take care not to display the escape as a potential real char
- output.append("\\\\"); //$NON-NLS-1$
- break;
- default :
- output.append(this.source[i]);
- }
+ Util.appendEscapedChar(output, this.source[i], true);
}
output.append('\"');
return output;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
index 3b974833a..afbef5a68 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
@@ -885,4 +885,8 @@ public static boolean containsNullAnnotation(Annotation[] annotations) {
public TypeReference[] getTypeReferences() {
return new TypeReference [] { this };
}
+
+public boolean isBaseTypeReference() {
+ return false;
+}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Wildcard.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Wildcard.java
index adb00abf1..cc3b41b5e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Wildcard.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Wildcard.java
@@ -14,6 +14,7 @@
* Bug 417295 - [1.8[[null] Massage type annotated null analysis to gel well with deep encoded type bindings.
* Bug 429958 - [1.8][null] evaluate new DefaultLocation attribute of @NonNullByDefault
* Bug 440462 - [null][compiler]NPE in EJC for erroneous null annotations
+ * Bug 441693 - [1.8][null] Bogus warning for type argument annotated with @NonNull
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -77,7 +78,7 @@ public class Wildcard extends SingleTypeReference {
if (((boundType.tagBits | this.resolvedType.tagBits) & TagBits.AnnotationNullMASK) == TagBits.AnnotationNullMASK) { // are both set?
Annotation annotation = this.bound.findAnnotation(boundType.tagBits & TagBits.AnnotationNullMASK);
if (annotation == null) { // false alarm, implicit annotation is no conflict, but should be removed:
- TypeBinding newBound = boundType.unannotated(true);
+ TypeBinding newBound = boundType.withoutToplevelNullAnnotation();
((WildcardBinding)this.resolvedType).bound = newBound;
this.bound.resolvedType = newBound;
} else {
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 c99094a14..ad3cfce01 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
@@ -21,6 +21,8 @@
* Bug 409236 - [1.8][compiler] Type annotations on intersection cast types dropped by code generator
* Bug 409250 - [1.8][compiler] Various loose ends in 308 code generation
* Bug 405104 - [1.8][compiler][codegen] Implement support for serializeable lambdas
+ * Olivier Tardieu (tardieu@us.ibm.com) - Contributions for
+ * Bug 442418 - $deserializeLambda$ off-by-one error when deserializing the captured arguments of a lambda that also capture this
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.codegen;
@@ -2775,7 +2777,7 @@ public void generateSyntheticBodyForDeserializeLambda(SyntheticMethodBinding met
SyntheticArgumentBinding[] outerLocalVariables = lambdaEx.outerLocalVariables;
for (int p=0,max=outerLocalVariables.length;p<max;p++) {
aload_0();
- loadInt(p);
+ loadInt(index);
invoke(Opcodes.OPC_invokevirtual, 1, 1, ConstantPool.JavaLangInvokeSerializedLambdaConstantPoolName,
ConstantPool.GetCapturedArg, ConstantPool.GetCapturedArgSignature);
TypeBinding varType = outerLocalVariables[p].type;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java
index 9c3295660..f11f05879 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java
@@ -200,7 +200,10 @@ private ASTNode getExceptionType(int index) {
return node;
}
-
+@Override
+public FlowContext getInitializationContext() {
+ return this.initializationParent;
+}
public String individualToString() {
StringBuffer buffer = new StringBuffer("Exception flow context"); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java
index 04a47c0a7..af0b19ce7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java
@@ -607,6 +607,13 @@ public FlowContext getTargetContextForDefaultContinue() {
}
/**
+ * Answer flow context that corresponds to initialization. Suitably override in subtypes.
+ */
+public FlowContext getInitializationContext() {
+ return null;
+}
+
+/**
* Answer the parent flow context but be careful not to cross the boundary of a nested type,
* or null if no such parent exists.
*/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/InitializationFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/InitializationFlowContext.java
index 547086bc8..410ded586 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/InitializationFlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/InitializationFlowContext.java
@@ -51,6 +51,11 @@ public class InitializationFlowContext extends ExceptionHandlingFlowContext {
}
}
+ @Override
+ public FlowContext getInitializationContext() {
+ return this;
+ }
+
public String individualToString() {
StringBuffer buffer = new StringBuffer("Initialization flow context"); //$NON-NLS-1$
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 8656db5b7..66fd8fc6a 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
@@ -15,6 +15,7 @@
* bug 265744 - Enum switch should warn about missing default
* bug 374605 - Unreasonable warning for enum-based switch statements
* bug 381443 - [compiler][null] Allow parameter widening from @NonNull to unannotated
+ * Bug 441208 - [1.8][null]SuppressWarnings("null") does not suppress / marked Unnecessary
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.impl;
@@ -207,7 +208,8 @@ public class IrritantSet {
.set(CompilerOptions.NullAnnotationInferenceConflict)
.set(CompilerOptions.NullUncheckedConversion)
.set(CompilerOptions.RedundantNullAnnotation)
- .set(CompilerOptions.NonnullParameterAnnotationDropped);
+ .set(CompilerOptions.NonnullParameterAnnotationDropped)
+ .set(CompilerOptions.MissingNonNullByDefaultAnnotation);
RESTRICTION.set(CompilerOptions.DiscouragedReference);
STATIC_ACCESS.set(CompilerOptions.NonStaticAccessToStatic);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotatableTypeSystem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotatableTypeSystem.java
index 9db8baf4e..2c910a23a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotatableTypeSystem.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotatableTypeSystem.java
@@ -30,7 +30,6 @@ import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.RoleTypeBindin
public class AnnotatableTypeSystem extends TypeSystem {
- private LookupEnvironment environment;
private boolean isAnnotationBasedNullAnalysisEnabled;
public AnnotatableTypeSystem(LookupEnvironment environment) {
@@ -63,6 +62,9 @@ public class AnnotatableTypeSystem extends TypeSystem {
/* This method replaces the version that used to sit in LE. The parameter `annotations' is a flattened sequence of annotations,
where each dimension's annotations end with a sentinel null. Leaf type can be an already annotated type.
+
+ See ArrayBinding.swapUnresolved for further special case handling if incoming leafType is a URB that would resolve to a raw
+ type later.
*/
public ArrayBinding getArrayType(TypeBinding leafType, int dimensions, AnnotationBinding [] annotations) {
@@ -113,50 +115,24 @@ public class AnnotatableTypeSystem extends TypeSystem {
if (genericType.hasTypeAnnotations()) // @NonNull (List<String>) and not (@NonNull List)<String>
throw new IllegalStateException();
- ParameterizedTypeBinding nakedType = null;
- TypeBinding[] derivedTypes = getDerivedTypes(genericType);
- for (int i = 0, length = derivedTypes.length; i < length; i++) {
- TypeBinding derivedType = derivedTypes[i];
- if (derivedType == null)
- break;
-//{ObjectTeams: parameterized and/or anchored?
-/* orig:
- if (!derivedType.isParameterizedType() || derivedType.actualType() != genericType) //$IDENTITY-COMPARISON$
- continue;
- :giro */
- if (!(derivedType instanceof ParameterizedTypeBinding)) // roles might answer 'false' to isParameterized(), still they are valid candidates, here
- continue;
- if (derivedType.actualType() != genericType) //$IDENTITY-COMPARISON$
- continue;
- if (derivedType.isRawType() && typeArguments != null)
- continue;
- // also match team anchor if given:
- if (!isRoleTypeMatch(teamAnchor, valueParamPosition, derivedType))
- continue;
-//SH}
- if (derivedType.enclosingType() != enclosingType || !Util.effectivelyEqual(derivedType.typeArguments(), typeArguments)) //$IDENTITY-COMPARISON$
- continue;
- if (Util.effectivelyEqual(annotations, derivedType.getTypeAnnotations()))
- return (ParameterizedTypeBinding) derivedType;
- if (!derivedType.hasTypeAnnotations())
- nakedType = (ParameterizedTypeBinding) derivedType;
- }
- if (nakedType == null)
-//{ObjectTeams: all parameters:
-/* orig:
- nakedType = super.getParameterizedType(genericType, typeArguments, enclosingType);
- :orig */
- nakedType = super.getParameterizedType(genericType, typeArguments, teamAnchor, valueParamPosition, enclosingType);
+ ParameterizedTypeBinding parameterizedType = this.parameterizedTypes.get(genericType, typeArguments, enclosingType, annotations);
+ if (parameterizedType != null)
+ return parameterizedType;
+
+//{ObjectTeams: pass more args:
+/*
+ ParameterizedTypeBinding nakedType = super.getParameterizedType(genericType, typeArguments, enclosingType);
+ */
+ ParameterizedTypeBinding nakedType = super.getParameterizedType(genericType, typeArguments, teamAnchor, valueParamPosition, enclosingType);
// SH}
-
+
if (!haveTypeAnnotations(genericType, enclosingType, typeArguments, annotations))
return nakedType;
//{ObjectTeams: dependent type?
/* orig:
- TypeBinding parameterizedType = new ParameterizedTypeBinding(genericType, typeArguments, enclosingType, this.environment);
+ parameterizedType = new ParameterizedTypeBinding(genericType, typeArguments, enclosingType, this.environment);
:giro */
- ParameterizedTypeBinding parameterizedType;
if (teamAnchor == null) {
parameterizedType = new ParameterizedTypeBinding(genericType,typeArguments, enclosingType, this.environment);
} else {
@@ -169,6 +145,7 @@ public class AnnotatableTypeSystem extends TypeSystem {
// SH}
parameterizedType.id = nakedType.id;
parameterizedType.setTypeAnnotations(annotations, this.isAnnotationBasedNullAnalysisEnabled);
+ this.parameterizedTypes.put(genericType, typeArguments, enclosingType, parameterizedType);
return (ParameterizedTypeBinding) cacheDerivedType(genericType, nakedType, parameterizedType);
}
@@ -336,6 +313,14 @@ public class AnnotatableTypeSystem extends TypeSystem {
Likewise so the bindings for @Readonly List<@NonNull String> != @Readonly List<@Nullable String> != @Readonly List<@Interned String>
*/
private TypeBinding getAnnotatedType(TypeBinding type, TypeBinding enclosingType, AnnotationBinding[] annotations) {
+ if (type.kind() == Binding.PARAMETERIZED_TYPE) {
+//{ObjectTeams: more args:
+/*
+ return getParameterizedType(type.actualType(), type.typeArguments(), (ReferenceBinding) enclosingType, annotations);
+ */
+ return getParameterizedType(type.actualType(), type.typeArguments(), null, -1, (ReferenceBinding) enclosingType, annotations);
+// SH}
+ }
TypeBinding nakedType = null;
TypeBinding[] derivedTypes = getDerivedTypes(type);
for (int i = 0, length = derivedTypes.length; i < length; i++) {
@@ -350,14 +335,11 @@ public class AnnotatableTypeSystem extends TypeSystem {
if (!derivedType.isArrayType() || derivedType.dimensions() != type.dimensions() || derivedType.leafComponentType() != type.leafComponentType()) //$IDENTITY-COMPARISON$
continue;
break;
- case Binding.PARAMETERIZED_TYPE:
- if (!derivedType.isParameterizedType() || derivedType.actualType() != type.actualType()) //$IDENTITY-COMPARISON$
- continue;
- break;
case Binding.RAW_TYPE:
if (!derivedType.isRawType() || derivedType.actualType() != type.actualType()) //$IDENTITY-COMPARISON$
continue;
break;
+ case Binding.INTERSECTION_TYPE:
case Binding.WILDCARD_TYPE:
if (!derivedType.isWildcard() || derivedType.actualType() != type.actualType() || derivedType.rank() != type.rank() || derivedType.boundKind() != type.boundKind()) //$IDENTITY-COMPARISON$
continue;
@@ -367,7 +349,6 @@ public class AnnotatableTypeSystem extends TypeSystem {
default:
switch(derivedType.kind()) {
case Binding.ARRAY_TYPE:
- case Binding.PARAMETERIZED_TYPE:
case Binding.RAW_TYPE:
case Binding.WILDCARD_TYPE:
case Binding.INTERSECTION_CAST_TYPE:
@@ -377,9 +358,6 @@ public class AnnotatableTypeSystem extends TypeSystem {
break;
}
if (Util.effectivelyEqual(derivedType.getTypeAnnotations(), annotations)) {
- // point-fix for https://bugs.eclipse.org/432977
- if (!type.isUnresolvedType() && derivedType.isUnresolvedType())
- return ((UnresolvedReferenceBinding)derivedType).resolve(this.environment, false);
return derivedType;
}
if (!derivedType.hasTypeAnnotations())
@@ -399,7 +377,6 @@ public class AnnotatableTypeSystem extends TypeSystem {
case Binding.ARRAY_TYPE:
keyType = type.leafComponentType();
break;
- case Binding.PARAMETERIZED_TYPE:
case Binding.RAW_TYPE:
case Binding.WILDCARD_TYPE:
keyType = type.actualType();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
index 5d652aa0c..ac12a5e08 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
@@ -23,6 +23,7 @@
* Bug 428019 - [1.8][compiler] Type inference failure with nested generic invocation.
* Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables
* Bug 440759 - [1.8][null] @NonNullByDefault should never affect wildcards and uses of a type variable
+ * Bug 441693 - [1.8][null] Bogus warning for type argument annotated with @NonNull
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -457,7 +458,14 @@ public void swapUnresolved(UnresolvedReferenceBinding unresolvedType, ReferenceB
/* Leaf component type is the key in the type system. If it undergoes change, the array has to be rehashed.
We achieve by creating a fresh array with the new component type and equating this array's id with that.
This means this array can still be found under the old key, but that is harmless (since the component type
- is always consulted (see TypeSystem.getArrayType())
+ is always consulted (see TypeSystem.getArrayType()).
+
+ This also means that this array type is not a fully interned singleton: There is `this' object and there is
+ the array that is being created down below that gets cached by the type system and doled out for all further
+ array creations against the same (raw) component type, dimensions and annotations. This again is harmless,
+ since TypeBinding.id is consulted for (in)equality checks.
+
+ See https://bugs.eclipse.org/bugs/show_bug.cgi?id=430425 for details and a test case.
*/
if (this.leafComponentType != resolvedType) //$IDENTITY-COMPARISON$
this.id = env.createArrayType(this.leafComponentType, this.dimensions, this.typeAnnotations).id;
@@ -478,17 +486,15 @@ public TypeBinding maybeWrapRoleType(ASTNode typedNode, TypeArgumentUpdater upda
public String toString() {
return this.leafComponentType != null ? debugName() : "NULL TYPE ARRAY"; //$NON-NLS-1$
}
-public TypeBinding unannotated(boolean removeOnlyNullAnnotations) {
- if (!hasTypeAnnotations())
+public TypeBinding unannotated() {
+ return this.hasTypeAnnotations() ? this.environment.getUnannotatedType(this) : this;
+}
+@Override
+public TypeBinding withoutToplevelNullAnnotation() {
+ if (!hasNullTypeAnnotations())
return this;
- if (removeOnlyNullAnnotations) {
- if (!hasNullTypeAnnotations())
- return this;
- AnnotationBinding[] newAnnotations = this.environment.filterNullTypeAnnotations(this.typeAnnotations);
- if (newAnnotations.length > 0)
- return this.environment.createArrayType(this.leafComponentType.unannotated(false), this.dimensions, newAnnotations);
- }
- return this.environment.getUnannotatedType(this);
+ AnnotationBinding[] newAnnotations = this.environment.filterNullTypeAnnotations(this.typeAnnotations);
+ return this.environment.createArrayType(this.leafComponentType, this.dimensions, newAnnotations);
}
@Override
public TypeBinding uncapture(Scope scope) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypeBinding.java
index aad394b07..8a5753680 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypeBinding.java
@@ -173,7 +173,7 @@ public class BaseTypeBinding extends TypeBinding {
super.setTypeAnnotations(annotations, false); // never set nullTagBits on base types
}
- public TypeBinding unannotated(boolean removeOnlyNullAnnotations) {
+ public TypeBinding unannotated() {
if (!this.hasTypeAnnotations())
return this;
switch (this.id) {
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 87c7cf542..e2dfd7932 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
@@ -31,6 +31,7 @@
* Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables
* Bug 439516 - [1.8][null] NonNullByDefault wrongly applied to implicit type bound of binary type
* Bug 434602 - Possible error with inferred null annotations leading to contradictory null annotations
+ * Bug 441693 - [1.8][null] Bogus warning for type argument annotated with @NonNull
* Jesper Steen Moller - Contributions for
* Bug 412150 [1.8] [compiler] Enable reflected parameter names during annotation processing
* Bug 412153 - [1.8][compiler] Check validity of annotations which may be repeatable
@@ -2247,6 +2248,13 @@ public ReferenceBinding[] superInterfaces() {
this.environment.mayTolerateMissingType = true; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=360164
try {
this.superInterfaces[i].superclass();
+ if (this.superInterfaces[i].isParameterizedType()) {
+ ReferenceBinding superType = this.superInterfaces[i].actualType();
+ if (TypeBinding.equalsEquals(superType, this)) {
+ this.tagBits |= TagBits.HierarchyHasProblems;
+ continue;
+ }
+ }
this.superInterfaces[i].superInterfaces();
} finally {
this.environment.mayTolerateMissingType = wasToleratingMissingTypeProcessingAnnotations;
@@ -2373,17 +2381,17 @@ public String toString() {
return buffer.toString();
}
-public TypeBinding unannotated(boolean removeOnlyNullAnnotations) {
- if (removeOnlyNullAnnotations) {
- if (!hasNullTypeAnnotations())
- return this;
- AnnotationBinding[] newAnnotations = this.environment.filterNullTypeAnnotations(this.typeAnnotations);
- if (newAnnotations.length > 0)
- return this.environment.createAnnotatedType(this.prototype, newAnnotations);
- }
+public TypeBinding unannotated() {
+ return this.prototype;
+}
+public TypeBinding withoutToplevelNullAnnotation() {
+ if (!hasNullTypeAnnotations())
+ return this;
+ AnnotationBinding[] newAnnotations = this.environment.filterNullTypeAnnotations(this.typeAnnotations);
+ if (newAnnotations.length > 0)
+ return this.environment.createAnnotatedType(this.prototype, newAnnotations);
return this.prototype;
}
-
MethodBinding[] unResolvedMethods() { // for the MethodVerifier so it doesn't resolve types
if (!isPrototype())
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
index 59506820f..af46df150 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
@@ -149,8 +149,11 @@ public final void addLocalType(TypeDeclaration localType) {
MethodScope methodScope = methodScope();
while (methodScope != null && methodScope.referenceContext instanceof LambdaExpression) {
LambdaExpression lambda = (LambdaExpression) methodScope.referenceContext;
- if (!lambda.scope.isStatic && !lambda.scope.isConstructorCall) {
+ if (!lambda.scope.isStatic) {
lambda.shouldCaptureInstance = true;
+ if (lambda.scope.isConstructorCall) {
+ lambda.scope.problemReporter().noSuchEnclosingInstance(enclosingSourceType(), lambda, true);
+ }
}
methodScope = methodScope.enclosingMethodScope();
}
@@ -1104,12 +1107,10 @@ public final boolean needBlankFinalFieldInitializationCheck(FieldBinding binding
boolean isStatic = binding.isStatic();
ReferenceBinding fieldDeclaringClass = binding.declaringClass;
// loop in enclosing context, until reaching the field declaring context
- MethodScope methodScope = methodScope();
+ MethodScope methodScope = namedMethodScope();
while (methodScope != null) {
if (methodScope.isStatic != isStatic)
return false;
- if (methodScope.isLambdaScope())
- return false;
if (!methodScope.isInsideInitializer() // inside initializer
&& !((AbstractMethodDeclaration) methodScope.referenceContext).isInitializationMethod()) { // inside constructor or clinit
return false; // found some non-initializer context
@@ -1121,7 +1122,7 @@ public final boolean needBlankFinalFieldInitializationCheck(FieldBinding binding
if (!enclosingType.erasure().isAnonymousType()) {
return false; // only check inside anonymous type
}
- methodScope = methodScope.enclosingMethodScope();
+ methodScope = methodScope.enclosingMethodScope().namedMethodScope();
}
return false;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java
index d121d3edc..c438ac56d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java
@@ -238,7 +238,7 @@ class BoundSet {
if (nullHints == TagBits.AnnotationNullMASK) {
// on contradiction remove null type annotations
for (int i = 0; i < boundTypes.length; i++)
- boundTypes[i] = boundTypes[i].unannotated(true);
+ boundTypes[i] = boundTypes[i].withoutToplevelNullAnnotation();
} else {
AnnotationBinding[] annot = environment.nullAnnotationsFromTagBits(nullHints);
if (annot != null) {
@@ -268,7 +268,7 @@ class BoundSet {
nullHints |= it.next().nullHints;
}
if (nullHints == TagBits.AnnotationNullMASK) // on contradiction remove null type annotations
- return type.unannotated(true);
+ return type.withoutToplevelNullAnnotation();
AnnotationBinding[] annot = environment.nullAnnotationsFromTagBits(nullHints);
if (annot != null)
// only get here if exactly one of @NonNull or @Nullable was hinted; now apply this hint:
@@ -288,7 +288,7 @@ class BoundSet {
// adjust 'type' to fit the newBits
AnnotationBinding[] annot = environment.nullAnnotationsFromTagBits(newBits);
if (annot != null)
- type = environment.createAnnotatedType(type.unannotated(true), annot);
+ type = environment.createAnnotatedType(type.withoutToplevelNullAnnotation(), annot);
}
}
this.instantiation = type;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java
index c3c30a220..43331f717 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java
@@ -11,6 +11,7 @@
* Stephan Herrmann - Contribution for
* Bug 400874 - [1.8][compiler] Inference infrastructure should evolve to meet JLS8 18.x (Part G of JSR335 spec)
* Bug 429384 - [1.8][null] implement conformance rules for null-annotated lower / upper type bounds
+ * Bug 441797 - [1.8] synchronize type annotations on capture and its wildcard
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -42,7 +43,15 @@ public class CaptureBinding extends TypeVariableBinding {
this.captureID = captureID;
this.tagBits |= TagBits.HasCapturedWildcard;
if (wildcard.hasTypeAnnotations()) {
- setTypeAnnotations(wildcard.getTypeAnnotations(), wildcard.environment.globalOptions.isAnnotationBasedNullAnalysisEnabled);
+ // register an unannoted version before adding the annotated wildcard:
+ CaptureBinding unannotated = (CaptureBinding) clone(null);
+ unannotated.wildcard = (WildcardBinding) this.wildcard.unannotated();
+ this.environment.getUnannotatedType(unannotated);
+ this.id = unannotated.id; // transfer fresh id
+ // now register this annotated type:
+ this.environment.typeSystem.cacheDerivedType(this, unannotated, this);
+ // propagate from wildcard to capture - use super version, because our own method propagates type annotations in the opposite direction:
+ super.setTypeAnnotations(wildcard.getTypeAnnotations(), wildcard.environment.globalOptions.isAnnotationBasedNullAnalysisEnabled);
if (wildcard.hasNullTypeAnnotations())
this.tagBits |= TagBits.HasNullTypeAnnotation;
}
@@ -303,7 +312,7 @@ public class CaptureBinding extends TypeVariableBinding {
try {
if (this.wildcard != null) {
nameBuffer.append("of "); //$NON-NLS-1$
- nameBuffer.append(this.wildcard.nullAnnotatedReadableName(options, shortNames));
+ nameBuffer.append(this.wildcard.withoutToplevelNullAnnotation().nullAnnotatedReadableName(options, shortNames));
} else if (this.lowerBound != null) {
nameBuffer.append(" super "); //$NON-NLS-1$
nameBuffer.append(this.lowerBound.nullAnnotatedReadableName(options, shortNames));
@@ -325,6 +334,39 @@ public class CaptureBinding extends TypeVariableBinding {
}
@Override
+ public TypeBinding withoutToplevelNullAnnotation() {
+ if (!hasNullTypeAnnotations())
+ return this;
+ if (this.wildcard != null && this.wildcard.hasNullTypeAnnotations()) {
+ WildcardBinding newWildcard = (WildcardBinding) this.wildcard.withoutToplevelNullAnnotation();
+ if (newWildcard != this.wildcard) { //$IDENTITY-COMPARISON$
+
+ CaptureBinding newCapture = (CaptureBinding) this.environment.getUnannotatedType(this).clone(null);
+ if (newWildcard.hasTypeAnnotations())
+ newCapture.tagBits |= TagBits.HasTypeAnnotations;
+ newCapture.wildcard = newWildcard;
+
+ // manually transfer the following two, because we are not in a context where we can call initializeBounds():
+ newCapture.superclass = this.superclass;
+ newCapture.superInterfaces = this.superInterfaces;
+
+ AnnotationBinding[] newAnnotations = this.environment.filterNullTypeAnnotations(this.typeAnnotations);
+ return this.environment.createAnnotatedType(newCapture, newAnnotations);
+ }
+ }
+ return super.withoutToplevelNullAnnotation();
+ }
+
+ @Override
+ public void setTypeAnnotations(AnnotationBinding[] annotations, boolean evalNullAnnotations) {
+ super.setTypeAnnotations(annotations, evalNullAnnotations);
+ if (annotations != Binding.NO_ANNOTATIONS && this.wildcard != null) {
+ // keep annotations in sync, propagate from capture to its wildcard:
+ this.wildcard = (WildcardBinding) this.wildcard.environment.createAnnotatedType(this.wildcard, annotations);
+ }
+ }
+
+ @Override
public TypeBinding uncapture(Scope scope) {
return this.wildcard;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
index f093aa1dd..44590fab1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
@@ -2304,6 +2304,11 @@ public class ClassScope extends Scope {
// force its superclass & superinterfaces to be found... 2 possibilities exist - the source type is included in the hierarchy of:
// - a binary type... this case MUST be caught & reported here
// - another source type... this case is reported against the other source type
+ if (superType.problemId() != ProblemReasons.NotFound && (superType.tagBits & TagBits.HierarchyHasProblems) != 0) {
+ sourceType.tagBits |= TagBits.HierarchyHasProblems;
+ problemReporter().hierarchyHasProblems(sourceType);
+ return true;
+ }
boolean hasCycle = false;
ReferenceBinding parentType = superType.superclass();
if (parentType != null) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java
index f8f3f81e5..620f46692 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java
@@ -254,7 +254,7 @@ class ConstraintExpressionFormula extends ConstraintFormula {
MethodBinding functionType = t.getSingleAbstractMethod(inferenceContext.scope, true);
if (functionType == null)
return FALSE;
- // potentially-applicable method for the method reference when targeting T (15.28.1),
+ // potentially-applicable method for the method reference when targeting T (15.13.1),
MethodBinding potentiallyApplicable = reference.findCompileTimeMethodTargeting(t, inferenceContext.scope);
if (potentiallyApplicable == null)
return FALSE;
@@ -285,7 +285,7 @@ class ConstraintExpressionFormula extends ConstraintFormula {
for (int i = 0; i < n; i++)
if (!functionType.parameters[i].isProperType(true))
return FALSE;
- // Otherwise, a search for a compile-time declaration is performed, as defined in 15.28.1....
+ // Otherwise, a search for a compile-time declaration is performed, as defined in 15.13.1....
// Note: we currently don't distinguish search for a potentially-applicable method from searching the compiler-time declaration,
// hence reusing the method binding from above
MethodBinding compileTimeDecl = potentiallyApplicable;
@@ -295,18 +295,19 @@ class ConstraintExpressionFormula extends ConstraintFormula {
if (r.id == TypeIds.T_void)
return TRUE;
// ignore parameterization of resolve result and do a fresh start:
- MethodBinding original = compileTimeDecl.original();
+ MethodBinding original = compileTimeDecl.shallowOriginal();
+ TypeBinding compileTypeReturn = original.isConstructor() ? original.declaringClass : original.returnType;
if (reference.typeArguments == null
- && ((original.typeVariables() != Binding.NO_TYPE_VARIABLES && r.mentionsAny(original.typeVariables(), -1))
+ && ((original.typeVariables() != Binding.NO_TYPE_VARIABLES && compileTypeReturn.mentionsAny(original.typeVariables(), -1))
|| (original.isConstructor() && original.declaringClass.typeVariables() != Binding.NO_TYPE_VARIABLES)))
// not checking r.mentionsAny for constructors, because A::new resolves to the raw type
// whereas in fact the type of all expressions of this shape depends on their type variable (if any)
{
- SuspendedInferenceRecord prevInvocation = inferenceContext.enterPolyInvocation(reference, null/*no invocation arguments available*/);
+ SuspendedInferenceRecord prevInvocation = inferenceContext.enterPolyInvocation(reference, reference.createPseudoExpressions(functionType.parameters));
// Invocation Applicability Inference: 18.5.1 & Invocation Type Inference: 18.5.2
try {
- inferInvocationApplicability(inferenceContext, original, functionType.parameters, original.isConstructor()/*mimic a diamond?*/, inferenceContext.inferenceKind);
+ inferInvocationApplicability(inferenceContext, original, functionType.parameters, original.isConstructor()/*mimic a diamond?*/, reference.inferenceKind);
if (!inferPolyInvocationType(inferenceContext, reference, r, original))
return FALSE;
if (!original.isConstructor()
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 5d01de1a2..7d5531ff0 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
@@ -798,19 +798,19 @@ public class InferenceContext18 {
}
return reduceAndIncorporate(ConstraintTypeFormula.create(r1, r2, ReductionResult.SUBTYPE));
} else if (expri instanceof ReferenceExpression && ((ReferenceExpression)expri).isExactMethodReference()) {
+ ReferenceExpression reference = (ReferenceExpression) expri;
for (int i = 0; i < u.length; i++) {
- ReferenceExpression reference = (ReferenceExpression) expri;
if (!reduceAndIncorporate(ConstraintTypeFormula.create(u[i], v[i], ReductionResult.SAME)))
return false;
- if (r2.id == TypeIds.T_void)
- return true;
- MethodBinding method = reference.findCompileTimeMethodTargeting(null, this.scope); // TODO directly access exactMethodBinding!
- TypeBinding returnType = method.isConstructor() ? method.declaringClass : method.returnType;
- if (r1.isPrimitiveType() && !r2.isPrimitiveType() && returnType.isPrimitiveType())
- return true;
- if (r2.isPrimitiveType() && !r1.isPrimitiveType() && !returnType.isPrimitiveType())
- return true;
}
+ if (r2.id == TypeIds.T_void)
+ return true;
+ MethodBinding method = reference.getExactMethod();
+ TypeBinding returnType = method.isConstructor() ? method.declaringClass : method.returnType;
+ if (r1.isPrimitiveType() && !r2.isPrimitiveType() && returnType.isPrimitiveType())
+ return true;
+ if (r2.isPrimitiveType() && !r1.isPrimitiveType() && !returnType.isPrimitiveType())
+ return true;
return reduceAndIncorporate(ConstraintTypeFormula.create(r1, r2, ReductionResult.SUBTYPE));
} else if (expri instanceof ConditionalExpression) {
ConditionalExpression cond = (ConditionalExpression) expri;
@@ -1445,6 +1445,8 @@ public class InferenceContext18 {
public void rebindInnerPolies(BoundSet bounds, TypeBinding[] parameterTypes) {
// This updates all remaining poly expressions that are direct arguments of the current invocation:
// (handles FunctionalExpression & ConditionalExpression)
+ if (this.currentInvocation instanceof ReferenceExpression)
+ return; // no inner expressions
boolean isVarargs = this.inferenceKind == CHECK_VARARG;
acceptPendingPolyArguments(bounds, parameterTypes, isVarargs);
// This loops over all poly expressions for which a sub-inference was triggered:
@@ -1452,7 +1454,17 @@ public class InferenceContext18 {
int len = this.innerPolies.size();
for (int i = 0; i < len; i++) {
Expression inner = (Expression) this.innerPolies.get(i);
- if (inner instanceof Invocation) {
+ if (inner instanceof ReferenceExpression) {
+ ReferenceExpression referenceExpression = (ReferenceExpression) inner;
+ MethodBinding compileTimeDecl = referenceExpression.prepareForInferenceResult(this.scope);
+ if (compileTimeDecl != null) {
+ TypeVariableBinding[] variables = compileTimeDecl.typeVariables;
+ if (variables != Binding.NO_TYPE_VARIABLES) {
+ TypeBinding[] arguments = getSolutions(variables, (InvocationSite) inner, bounds);
+ referenceExpression.binding = this.environment.createParameterizedGenericMethod(compileTimeDecl, arguments);
+ }
+ }
+ } else if (inner instanceof Invocation) {
Invocation innerMessage = (Invocation) inner;
TypeBinding innerTargetType = inner.expectedType(); // may be set from acceptPendingPolyArguments
if (innerTargetType != null && !innerTargetType.isProperType(true))
@@ -1527,7 +1539,10 @@ public class InferenceContext18 {
expression.setExpectedType(targetType);
}
} else {
- expression.checkAgainstFinalTargetType(targetType, this.scope);
+ if (this.innerPolies.contains(expression)) // may get here for ReferenceExpressions ...
+ expression.setExpectedType(targetType); // ... prepare for final inference via rebindInnerPolies
+ else
+ expression.checkAgainstFinalTargetType(targetType, this.scope);
}
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/IntersectionCastTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/IntersectionCastTypeBinding.java
index ecb2ec574..05d5cb565 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/IntersectionCastTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/IntersectionCastTypeBinding.java
@@ -38,6 +38,20 @@ public class IntersectionCastTypeBinding extends ReferenceBinding {
}
}
+ private IntersectionCastTypeBinding(IntersectionCastTypeBinding prototype) {
+ this.intersectingTypes = prototype.intersectingTypes;
+ this.length = prototype.length;
+ if (!this.intersectingTypes[0].isClass()) {
+ this.javaLangObject = prototype.javaLangObject;
+ this.modifiers |= ClassFileConstants.AccInterface;
+ }
+ }
+
+ @Override
+ public TypeBinding clone(TypeBinding enclosingType) {
+ return new IntersectionCastTypeBinding(this);
+ }
+
public MethodBinding getSingleAbstractMethod(Scope scope, boolean replaceWildcards) {
int index = replaceWildcards ? 0 : 1;
if (this.singleAbstractMethod != null) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java
index d07ce007a..1e0414e6b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java
@@ -109,6 +109,8 @@ public void addInnerEmulationDependent(BlockScope dependentScope, boolean wasEnc
public ReferenceBinding anonymousOriginalSuperType() {
if (!isPrototype())
return ((LocalTypeBinding) this.prototype).anonymousOriginalSuperType();
+ if (this.superclass == null && this.scope != null)
+ return this.scope.getJavaLangObject();
if (this.superInterfaces != Binding.NO_SUPERINTERFACES) {
return this.superInterfaces[0];
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java
index 2ba813598..1349ca4d1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java
@@ -24,6 +24,7 @@
* Bug 429958 - [1.8][null] evaluate new DefaultLocation attribute of @NonNullByDefault
* Bug 438012 - [1.8][null] Bogus Warning: The nullness annotation is redundant with a default that applies to this location
* Bug 440759 - [1.8][null] @NonNullByDefault should never affect wildcards and uses of a type variable
+ * Bug 443347 - [1.8][null] @NonNullByDefault should not affect constructor arguments of an anonymous instantiation
* Jesper Steen Moller - Contributions for
* Bug 412150 [1.8] [compiler] Enable reflected parameter names during annotation processing
*******************************************************************************/
@@ -1859,6 +1860,8 @@ public TypeVariableBinding[] typeVariables() {
}
//pre: null annotation analysis is enabled
public boolean hasNonNullDefaultFor(int location, boolean useTypeAnnotations) {
+ if ((this.modifiers & ExtraCompilerModifiers.AccIsDefaultConstructor) != 0)
+ return false;
if (useTypeAnnotations) {
if (this.defaultNullness != 0)
return (this.defaultNullness & location) != 0;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
index 56960dd1d..c36f3d2aa 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
@@ -1040,11 +1040,15 @@ boolean isInterfaceMethodImplemented(MethodBinding inheritedMethod, MethodBindin
return false; // must hold onto ParameterizedMethod to see if a bridge method is necessary
inheritedMethod = computeSubstituteMethod(inheritedMethod, existingMethod);
- return inheritedMethod != null
- && (TypeBinding.equalsEquals(inheritedMethod.returnType, existingMethod.returnType) // need to keep around to produce bridge methods? ...
- || (TypeBinding.notEquals(this.type, existingMethod.declaringClass) // ... not if inheriting the bridge situation from a superclass
- && !existingMethod.declaringClass.isInterface()))
- && doesMethodOverride(existingMethod, inheritedMethod);
+ if (inheritedMethod == null
+ || TypeBinding.notEquals(inheritedMethod.returnType, existingMethod.returnType)) // need to keep around to produce bridge methods? ...
+ return false;
+
+ if (!doesMethodOverride(existingMethod, inheritedMethod))
+ return false;
+
+ return TypeBinding.notEquals(this.type, existingMethod.declaringClass) // ... not if inheriting the bridge situation from a superclass
+ && !existingMethod.declaringClass.isInterface();
}
public boolean isMethodSubsignature(MethodBinding method, MethodBinding inheritedMethod) {
if (!org.eclipse.jdt.core.compiler.CharOperation.equals(method.selector, inheritedMethod.selector))
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NullTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NullTypeBinding.java
index 49eb52c1f..99c24d8e9 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NullTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NullTypeBinding.java
@@ -27,7 +27,7 @@ public class NullTypeBinding extends BaseTypeBinding {
return; // reject misguided attempt.
}
- public TypeBinding unannotated(boolean removeOnlyNullAnnotations) {
+ public TypeBinding unannotated() {
return this;
}
} \ No newline at end of file
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 74f6d8102..10c8d6ad2 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
@@ -21,6 +21,7 @@
* Bug 416182 - [1.8][compiler][null] Contradictory null annotations not rejected
* Bug 429958 - [1.8][null] evaluate new DefaultLocation attribute of @NonNullByDefault
* Bug 434602 - Possible error with inferred null annotations leading to contradictory null annotations
+ * Bug 434483 - [1.8][compiler][inference] Type inference not picked up with method reference
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -28,6 +29,7 @@ import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.Invocation;
import org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.eclipse.jdt.internal.compiler.ast.NullAnnotationMatching;
+import org.eclipse.jdt.internal.compiler.ast.ReferenceExpression;
import org.eclipse.jdt.internal.compiler.ast.Wildcard;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
@@ -116,9 +118,11 @@ public class ParameterizedGenericMethodBinding extends ParameterizedMethodBindin
CompilerOptions compilerOptions = scope.compilerOptions();
if (compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8) {
if ((inferenceLevel & Scope.APPLICABILITY) != 0)
- infCtx18 = invocationSite.freshInferenceContext(scope);
+ infCtx18 = invocationSite.freshInferenceContext(scope);
else if (invocationSite instanceof Invocation && originalMethod instanceof ParameterizedGenericMethodBinding)
infCtx18 = ((Invocation) invocationSite).getInferenceContext((ParameterizedGenericMethodBinding) originalMethod);
+ if (infCtx18 == null)
+ return originalMethod;
}
if (infCtx18 != null) {
try {
@@ -127,46 +131,48 @@ public class ParameterizedGenericMethodBinding extends ParameterizedMethodBindin
if ((inferenceLevel & Scope.APPLICABILITY) != 0) {
// ---- 18.5.1 (Applicability): ----
- boolean isDiamond = originalMethod.isConstructor()
- && invocationSite instanceof Expression
- && ((Expression)invocationSite).isPolyExpression(originalMethod);
+ boolean isDiamond = originalMethod.isConstructor()
+ && invocationSite instanceof Expression
+ && ((Expression)invocationSite).isPolyExpression(originalMethod);
if (arguments.length == parameters.length) {
infCtx18.inferenceKind = InferenceContext18.CHECK_LOOSE; // TODO: validate if 2 phase checking (strict/loose + vararg) is sufficient.
infCtx18.inferInvocationApplicability(originalMethod, arguments, isDiamond);
provisionalResult = infCtx18.solve();
}
- if (provisionalResult == null && originalMethod.isVarargs()) {
+ if (provisionalResult == null && originalMethod.isVarargs()) {
// check for variable-arity applicability
- infCtx18 = invocationSite.freshInferenceContext(scope); // start over
+ infCtx18 = invocationSite.freshInferenceContext(scope); // start over
infCtx18.inferenceKind = InferenceContext18.CHECK_VARARG;
infCtx18.inferInvocationApplicability(originalMethod, arguments, isDiamond);
- provisionalResult = infCtx18.solve();
- }
- if (provisionalResult != null && infCtx18.isResolved(provisionalResult)) {
+ provisionalResult = infCtx18.solve();
+ }
+ if (provisionalResult != null && infCtx18.isResolved(provisionalResult)) {
infCtx18.storedSolution = provisionalResult;
infCtx18.stepCompleted = InferenceContext18.APPLICABILITY_INFERRED;
+ if (invocationSite instanceof ReferenceExpression)
+ ((ReferenceExpression) invocationSite).inferenceKind = infCtx18.inferenceKind;
}
} else {
provisionalResult = infCtx18.storedSolution;
}
result = infCtx18.currentBounds.copy(); // the result after reduction, without effects of resolve()
- TypeBinding expectedType = invocationSite.invocationTargetType();
- boolean hasReturnProblem = false;
- boolean invocationTypeInferred = false;
+ TypeBinding expectedType = invocationSite.invocationTargetType();
+ boolean hasReturnProblem = false;
+ boolean invocationTypeInferred = false;
if ((inferenceLevel & Scope.INVOCATION_TYPE) != 0 // requested?
&& (expectedType != null || !invocationSite.getExpressionContext().definesTargetType())) { // possible?
// ---- 18.5.2 (Invocation type): ----
result = infCtx18.inferInvocationType(result, expectedType, invocationSite, originalMethod);
- invocationTypeInferred = true;
- hasReturnProblem |= result == null;
- if (hasReturnProblem)
- result = provisionalResult; // let's prefer a type error regarding the return type over reporting no match at all
- } else {
- // we're not yet ready for invocation type inference
- result = provisionalResult;
- }
+ invocationTypeInferred = true;
+ hasReturnProblem |= result == null;
+ if (hasReturnProblem)
+ result = provisionalResult; // let's prefer a type error regarding the return type over reporting no match at all
+ } else {
+ // we're not yet ready for invocation type inference
+ result = provisionalResult;
+ }
if (result != null) {
// assemble the solution etc:
@@ -187,7 +193,7 @@ public class ParameterizedGenericMethodBinding extends ParameterizedMethodBindin
if (hasReturnProblem) { // illegally working from the provisional result?
MethodBinding problemMethod = infCtx18.getReturnProblemMethodIfNeeded(expectedType, methodSubstitute);
if (problemMethod instanceof ProblemMethodBinding)
- return problemMethod;
+ return problemMethod;
}
if (invocationTypeInferred) {
if (compilerOptions.isAnnotationBasedNullAnalysisEnabled)
@@ -195,15 +201,17 @@ public class ParameterizedGenericMethodBinding extends ParameterizedMethodBindin
infCtx18.rebindInnerPolies(result, methodSubstitute.parameters);
//{ObjectTeams: 2nd arg added:
/* orig:
- return methodSubstitute.boundCheck18(scope, arguments);
+ MethodBinding problemMethod = methodSubstitute.boundCheck18(scope, arguments);
:giro */
- return methodSubstitute.boundCheck18(scope, invocationSite, arguments);
+ MethodBinding problemMethod = methodSubstitute.boundCheck18(scope, invocationSite, arguments);
// SH}
+ if (problemMethod != null)
+ return problemMethod;
} else {
if (invocationSite instanceof Invocation)
((Invocation) invocationSite).registerInferenceContext(methodSubstitute, infCtx18); // keep context so we can finish later
- return methodSubstitute;
}
+ return methodSubstitute;
}
}
return null;
@@ -853,4 +861,4 @@ public class ParameterizedGenericMethodBinding extends ParameterizedMethodBindin
return this; // -> prefer traditional comparison using the substituted method
return this.originalMethod;
}
-} \ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
index 45b85d059..b12541b14 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
@@ -36,6 +36,7 @@
* Bug 416182 - [1.8][compiler][null] Contradictory null annotations not rejected
* Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables
* Bug 438179 - [1.8][null] 'Contradictory null annotations' error on type variable with explicit null-annotation.
+ * Bug 441693 - [1.8][null] Bogus warning for type argument annotated with @NonNull
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -66,7 +67,7 @@ public class ParameterizedTypeBinding extends ReferenceBinding implements Substi
//{ObjectTeams: make visible to objectteams package
/* orig:
- private ReferenceBinding type; // must ensure the type is resolved
+ protected ReferenceBinding type; // must ensure the type is resolved
:giro */
public ReferenceBinding type; // must ensure the type is resolved
// SH}
@@ -78,7 +79,7 @@ public class ParameterizedTypeBinding extends ReferenceBinding implements Substi
public FieldBinding[] fields;
public ReferenceBinding[] memberTypes;
public MethodBinding[] methods;
- private ReferenceBinding enclosingType;
+ protected ReferenceBinding enclosingType;
public ParameterizedTypeBinding(ReferenceBinding type, TypeBinding[] arguments, ReferenceBinding enclosingType, LookupEnvironment environment){
this.environment = environment;
@@ -968,27 +969,17 @@ public class ParameterizedTypeBinding extends ReferenceBinding implements Substi
return isRawType();
}
- public TypeBinding unannotated(boolean removeOnlyNullAnnotations) {
- if (!hasTypeAnnotations())
- return this;
- if (removeOnlyNullAnnotations && !hasNullTypeAnnotations())
+ public TypeBinding unannotated() {
+ return this.hasTypeAnnotations() ? this.environment.getUnannotatedType(this) : this;
+ }
+
+ @Override
+ public TypeBinding withoutToplevelNullAnnotation() {
+ if (!hasNullTypeAnnotations())
return this;
- if (removeOnlyNullAnnotations) {
- ReferenceBinding unannotatedGenericType = (ReferenceBinding) this.environment.getUnannotatedType(this.type);
- AnnotationBinding[] newAnnotations = this.environment.filterNullTypeAnnotations(this.typeAnnotations);
- TypeBinding[] newArguments = null;
- if (this.arguments != null) {
- newArguments = new TypeBinding[this.arguments.length];
- for (int i = 0; i < this.arguments.length; i++) {
- newArguments[i] = this.arguments[i].unannotated(removeOnlyNullAnnotations);
- }
- }
- ReferenceBinding newEnclosing = null;
- if (this.enclosingType != null)
- newEnclosing = (ReferenceBinding)this.enclosingType.unannotated(removeOnlyNullAnnotations);
- return this.environment.createParameterizedType(unannotatedGenericType, newArguments, newEnclosing, newAnnotations);
- }
- return this.environment.getUnannotatedType(this);
+ ReferenceBinding unannotatedGenericType = (ReferenceBinding) this.environment.getUnannotatedType(this.type);
+ AnnotationBinding[] newAnnotations = this.environment.filterNullTypeAnnotations(this.typeAnnotations);
+ return this.environment.createParameterizedType(unannotatedGenericType, this.arguments, this.enclosingType, newAnnotations);
}
public int kind() {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/RawTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/RawTypeBinding.java
index 78eff9faf..556580a4a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/RawTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/RawTypeBinding.java
@@ -14,6 +14,7 @@
* Bug 423504 - [1.8] Implement "18.5.3 Functional Interface Parameterization Inference"
* Bug 425783 - An internal error occurred during: "Requesting Java AST from selection". java.lang.StackOverflowError
* Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables
+ * Bug 441693 - [1.8][null] Bogus warning for type argument annotated with @NonNull
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -80,20 +81,13 @@ public class RawTypeBinding extends ParameterizedTypeBinding {
return new RawTypeBinding(this.actualType(), (ReferenceBinding) outerType, this.environment);
}
- public TypeBinding unannotated(boolean removeOnlyNullAnnotations) {
- if (!hasTypeAnnotations())
- return this;
- if (removeOnlyNullAnnotations && !hasNullTypeAnnotations())
+ @Override
+ public TypeBinding withoutToplevelNullAnnotation() {
+ if (!hasNullTypeAnnotations())
return this;
- if (removeOnlyNullAnnotations) {
- ReferenceBinding unannotatedGenericType = (ReferenceBinding) this.environment.getUnannotatedType(this.genericType());
- AnnotationBinding[] newAnnotations = this.environment.filterNullTypeAnnotations(this.typeAnnotations);
- ReferenceBinding newEnclosing = null;
- if (this.enclosingType() != null)
- newEnclosing = (ReferenceBinding)this.enclosingType().unannotated(removeOnlyNullAnnotations);
- return this.environment.createRawType(unannotatedGenericType, newEnclosing, newAnnotations);
- }
- return this.environment.getUnannotatedType(this);
+ ReferenceBinding unannotatedGenericType = (ReferenceBinding) this.environment.getUnannotatedType(this.genericType());
+ AnnotationBinding[] newAnnotations = this.environment.filterNullTypeAnnotations(this.typeAnnotations);
+ return this.environment.createRawType(unannotatedGenericType, this.enclosingType(), newAnnotations);
}
/**
@@ -197,8 +191,8 @@ public class RawTypeBinding extends ParameterizedTypeBinding {
}
public boolean isProperType(boolean admitCapture18) {
- TypeBinding type = actualType();
- return type != null && type.isProperType(admitCapture18);
+ TypeBinding actualType = actualType();
+ return actualType != null && actualType.isProperType(admitCapture18);
}
protected void initializeArguments() {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java
index cbfe59e20..94b3d1154 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java
@@ -2367,19 +2367,18 @@ private MethodBinding [] getInterfaceAbstractContracts(Scope scope) throws Inval
continue;
if (!method.isValidBinding())
throw new InvalidInputException("Not a functional interface"); //$NON-NLS-1$
- if (method.isDefaultMethod()) {
- for (int j = 0; j < contractsCount; j++) {
- if (contracts[j] == null)
- continue;
- if (MethodVerifier.doesMethodOverride(method, contracts[j], scope.environment())) {
- contractsCount--;
- // abstract method from super type rendered default by present interface ==> contracts[j] = null;
- if (j < contractsCount)
- System.arraycopy(contracts, j+1, contracts, j, contractsCount - j);
- }
+ for (int j = 0; j < contractsCount; j++) {
+ if (contracts[j] == null)
+ continue;
+ if (MethodVerifier.doesMethodOverride(method, contracts[j], scope.environment())) {
+ contractsCount--;
+ // abstract method from super type overridden by present interface ==> contracts[j] = null;
+ if (j < contractsCount)
+ System.arraycopy(contracts, j+1, contracts, j, contractsCount - j);
}
- continue; // skip default method itself
}
+ if (method.isDefaultMethod())
+ continue; // skip default method itself
if (contractsCount == contractsLength) {
System.arraycopy(contracts, 0, contracts = new MethodBinding[contractsLength += 16], 0, contractsCount);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
index d305327f8..c922d6160 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
@@ -45,6 +45,8 @@
* Bug 429424 - [1.8][inference] Problem inferring type of method's parameter
* Bug 429958 - [1.8][null] evaluate new DefaultLocation attribute of @NonNullByDefault
* Bug 434570 - Generic type mismatch for parametrized class annotation attribute with inner class
+ * Bug 434483 - [1.8][compiler][inference] Type inference not picked up with method reference
+ * Bug 441734 - [1.8][inference] Generic method with nested parameterized type argument fails on method reference
* Jesper S Moller - Contributions for
* Bug 378674 - "The method can be declared as static" is wrong
* Bug 405066 - [1.8][compiler][codegen] Implement code generation infrastructure for JSR335
@@ -892,7 +894,8 @@ public abstract class Scope {
}
}
// fall back to old method:
- return parameterCompatibilityLevel(method, arguments, tiebreakingVarargsMethods);
+ boolean tolerateInferenceVariables = ((site instanceof ReferenceExpression) && ((ReferenceExpression) site).trialResolution);
+ return parameterCompatibilityLevel(method, arguments, tiebreakingVarargsMethods, tolerateInferenceVariables);
}
//{ObjectTeams: new arg:
@@ -1385,7 +1388,7 @@ public abstract class Scope {
InvocationSite invocationSite,
ReferenceBinding classHierarchyStart,
ObjectVector found,
- MethodBinding concreteMatch) {
+ MethodBinding [] concreteMatches) {
int startFoundSize = found.size;
final boolean sourceLevel18 = this.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_8;
@@ -1395,10 +1398,14 @@ public abstract class Scope {
findMethodInSuperInterfaces(currentType, selector, found, visitedTypes, invocationSite);
currentType = currentType.superclass();
}
- MethodBinding[] candidates = null;
- int candidatesCount = 0;
- MethodBinding problemMethod = null;
+
+ int candidatesCount = concreteMatches == null ? 0 : concreteMatches.length;
int foundSize = found.size;
+ MethodBinding[] candidates = new MethodBinding[foundSize - startFoundSize + candidatesCount];
+ if (concreteMatches != null)
+ System.arraycopy(concreteMatches, 0, candidates, 0, candidatesCount);
+
+ MethodBinding problemMethod = null;
if (foundSize > startFoundSize) {
// argument type compatibility check
final MethodVerifier methodVerifier = environment().methodVerifier();
@@ -1408,9 +1415,11 @@ public abstract class Scope {
MethodBinding compatibleMethod = computeCompatibleMethod(methodBinding, argumentTypes, invocationSite, APPLICABILITY);
if (compatibleMethod != null) {
if (compatibleMethod.isValidBinding()) {
- if (concreteMatch != null) {
- if (methodVerifier.areMethodsCompatible(concreteMatch, compatibleMethod))
- continue; // can skip this method since concreteMatch overrides it
+ if (concreteMatches != null) {
+ for (int j = 0, length = concreteMatches.length; j < length; j++) {
+ if (methodVerifier.areMethodsCompatible(concreteMatches[j], compatibleMethod))
+ continue; // can skip this method since concreteMatch overrides it
+ }
}
if (sourceLevel18 || !(compatibleMethod.isVarargs() && compatibleMethod instanceof ParameterizedGenericMethodBinding)) {
for (int j = 0; j < startFoundSize; j++) {
@@ -1419,11 +1428,6 @@ public abstract class Scope {
continue next; // can skip this method since classMethod overrides it
}
}
- if (candidatesCount == 0) {
- candidates = new MethodBinding[foundSize - startFoundSize + 1];
- if (concreteMatch != null)
- candidates[candidatesCount++] = concreteMatch;
- }
candidates[candidatesCount++] = compatibleMethod;
} else if (problemMethod == null) {
problemMethod = compatibleMethod;
@@ -1432,17 +1436,19 @@ public abstract class Scope {
}
}
+ MethodBinding concreteMatch = null;
if (candidatesCount < 2) {
- if (concreteMatch == null) {
+ if (concreteMatches == null) {
if (candidatesCount == 0)
return problemMethod; // can be null
- concreteMatch = candidates[0];
}
+ concreteMatch = candidates[0];
// 1.8: Give inference a chance to perform outstanding tasks (18.5.2):
concreteMatch = inferInvocationType(invocationSite, concreteMatch, argumentTypes);
- compilationUnitScope().recordTypeReferences(concreteMatch.thrownExceptions);
+ if (concreteMatch != null)
+ compilationUnitScope().recordTypeReferences(concreteMatch.thrownExceptions);
//{ObjectTeams: visibility of role ifc methods:
- if (concreteMatch.isValidBinding() && concreteMatch.declaringClass.isSynthInterface())
+ if (concreteMatch != null && concreteMatch.isValidBinding() && concreteMatch.declaringClass.isSynthInterface())
if (!concreteMatch.canBeSeenBy(receiverType, invocationSite, this))
concreteMatch = new ProblemMethodBinding(concreteMatch, selector, argumentTypes, ProblemReasons.NotVisible);
// SH}
@@ -1976,10 +1982,10 @@ public abstract class Scope {
if (foundSize == 1 && compatibleMethod.canBeSeenBy(receiverType, invocationSite, this)) {
// return the single visible match now
if (searchForDefaultAbstractMethod)
- return findDefaultAbstractMethod(receiverType, selector, argumentTypes, invocationSite, classHierarchyStart, found, compatibleMethod);
+ return findDefaultAbstractMethod(receiverType, selector, argumentTypes, invocationSite, classHierarchyStart, found, new MethodBinding [] {compatibleMethod});
// ==== 1.8: Finalize type inference of generic methods: ====
MethodBinding improved = inferInvocationType(invocationSite, compatibleMethod, argumentTypes);
- if (improved.isValidBinding()) {
+ if (improved != null && improved.isValidBinding()) {
compatibleMethod = improved;
} else {
problemMethod = improved;
@@ -2096,6 +2102,7 @@ public abstract class Scope {
}
// SH}
}
+
switch (visiblesCount) {
case 0 :
MethodBinding interfaceMethod =
@@ -2106,10 +2113,11 @@ public abstract class Scope {
candidate.isStatic() && candidate.declaringClass.isInterface() ? ProblemReasons.NonStaticOrAlienTypeReceiver : ProblemReasons.NotVisible);
case 1 :
if (searchForDefaultAbstractMethod)
- return findDefaultAbstractMethod(receiverType, selector, argumentTypes, invocationSite, classHierarchyStart, found, candidates[0]);
+ return findDefaultAbstractMethod(receiverType, selector, argumentTypes, invocationSite, classHierarchyStart, found, new MethodBinding [] { candidates[0] });
// 1.8: Give inference a chance to perform outstanding tasks (18.5.2):
candidate = inferInvocationType(invocationSite, candidates[0], argumentTypes);
- unitScope.recordTypeReferences(candidate.thrownExceptions);
+ if (candidate != null)
+ unitScope.recordTypeReferences(candidate.thrownExceptions);
return candidate;
default :
break;
@@ -2152,18 +2160,10 @@ public abstract class Scope {
if (staticCount > 1)
return mostSpecificMethodBinding(staticCandidates, staticCount, argumentTypes, invocationSite, receiverType);
}
-
- MethodBinding mostSpecificMethod = mostSpecificMethodBinding(candidates, visiblesCount, argumentTypes, invocationSite, receiverType);
- if (searchForDefaultAbstractMethod) { // search interfaces for a better match
- if (mostSpecificMethod.isValidBinding())
- // see if there is a better match in the interfaces - see AutoBoxingTest 99, LookupTest#81
- return findDefaultAbstractMethod(receiverType, selector, argumentTypes, invocationSite, classHierarchyStart, found, mostSpecificMethod);
- // see if there is a match in the interfaces - see LookupTest#84
- MethodBinding interfaceMethod = findDefaultAbstractMethod(receiverType, selector, argumentTypes, invocationSite, classHierarchyStart, found, null);
- if (interfaceMethod != null && interfaceMethod.isValidBinding() /* else return the same error as before */)
- return interfaceMethod;
- }
- return mostSpecificMethod;
+ if (visiblesCount != candidates.length)
+ System.arraycopy(candidates, 0, candidates = new MethodBinding[visiblesCount], 0, visiblesCount);
+ return searchForDefaultAbstractMethod ? findDefaultAbstractMethod(receiverType, selector, argumentTypes, invocationSite, classHierarchyStart, found, candidates)
+ : mostSpecificMethodBinding(candidates, visiblesCount, argumentTypes, invocationSite, receiverType);
}
// Internal use only
@@ -2585,7 +2585,7 @@ public abstract class Scope {
private static final long serialVersionUID = -7996779527641476028L;
}
- // For exact method references. 15.28.1
+ // For exact method references. 15.13.1
private MethodBinding getExactMethod(TypeBinding receiverType, TypeBinding type, char[] selector, InvocationSite invocationSite, MethodBinding candidate) {
if (type == null)
@@ -2621,7 +2621,7 @@ public abstract class Scope {
return candidate;
}
- // For exact method references. 15.28.1
+ // For exact method references. 15.13.1
public MethodBinding getExactMethod(TypeBinding receiverType, char[] selector, InvocationSite invocationSite) {
if (receiverType == null || !receiverType.isValidBinding() || receiverType.isBaseType())
return null;
@@ -2658,7 +2658,7 @@ public abstract class Scope {
return exactMethod;
}
- // For exact constructor references. 15.28.1
+ // For exact constructor references. 15.13.1
public MethodBinding getExactConstructor(TypeBinding receiverType, InvocationSite invocationSite) {
if (receiverType == null || !receiverType.isValidBinding() || !receiverType.canBeInstantiated() || receiverType.isBaseType())
return null;
@@ -4038,8 +4038,8 @@ public abstract class Scope {
for (int i = (oneParamsLength > twoParamsLength ? twoParamsLength : oneParamsLength) - 2; i >= 0; i--)
if (TypeBinding.notEquals(oneParams[i], twoParams[i]) && !oneParams[i].isCompatibleWith(twoParams[i]))
return false;
- if (parameterCompatibilityLevel(one, twoParams, true) == NOT_COMPATIBLE
- && parameterCompatibilityLevel(two, oneParams, true) == VARARGS_COMPATIBLE)
+ if (parameterCompatibilityLevel(one, twoParams, true, false) == NOT_COMPATIBLE
+ && parameterCompatibilityLevel(two, oneParams, true, false) == VARARGS_COMPATIBLE)
return true;
}
return false;
@@ -4854,7 +4854,8 @@ public abstract class Scope {
return new ProblemMethodBinding(visible[0].selector, argumentTypes, ProblemReasons.NotFound);
} else if (compatibleCount == 1) {
MethodBinding candidate = inferInvocationType(invocationSite, visible[0], argumentTypes);
- compilationUnitScope().recordTypeReferences(candidate.thrownExceptions);
+ if (candidate != null)
+ compilationUnitScope().recordTypeReferences(candidate.thrownExceptions);
return candidate;
}
if (compatibleCount != visibleSize) {
@@ -4925,7 +4926,8 @@ public abstract class Scope {
return new ProblemMethodBinding(visible[0], visible[0].selector, visible[0].parameters, ProblemReasons.Ambiguous);
} else if (count == 1) {
MethodBinding candidate = inferInvocationType(invocationSite, moreSpecific[0], argumentTypes);
- compilationUnitScope().recordTypeReferences(candidate.thrownExceptions);
+ if (candidate != null)
+ compilationUnitScope().recordTypeReferences(candidate.thrownExceptions);
return candidate;
} else {
visibleSize = count;
@@ -5006,7 +5008,8 @@ public abstract class Scope {
if (moreSpecific[i] != null) {
// 1.8: Give inference a chance to perform outstanding tasks (18.5.2):
MethodBinding candidate = inferInvocationType(invocationSite, visible[i], argumentTypes);
- compilationUnitScope().recordTypeReferences(candidate.thrownExceptions);
+ if (candidate != null)
+ compilationUnitScope().recordTypeReferences(candidate.thrownExceptions);
return candidate;
}
}
@@ -5191,9 +5194,9 @@ public abstract class Scope {
}
public int parameterCompatibilityLevel(MethodBinding method, TypeBinding[] arguments) {
- return parameterCompatibilityLevel(method, arguments, false);
+ return parameterCompatibilityLevel(method, arguments, false, false);
}
- public int parameterCompatibilityLevel(MethodBinding method, TypeBinding[] arguments, boolean tiebreakingVarargsMethods) {
+ public int parameterCompatibilityLevel(MethodBinding method, TypeBinding[] arguments, boolean tiebreakingVarargsMethods, boolean tolerateInferenceVariables) {
TypeBinding[] parameters = method.parameters;
int paramLength = parameters.length;
int argLength = arguments.length;
@@ -5232,14 +5235,14 @@ public abstract class Scope {
TypeBinding param = parameters[lastIndex]; // is an ArrayBinding by definition
TypeBinding arg = arguments[lastIndex];
if (TypeBinding.notEquals(param, arg)) {
- level = parameterCompatibilityLevel(arg, param, env, tiebreakingVarargsMethods);
+ level = parameterCompatibilityLevel(arg, param, env, tiebreakingVarargsMethods, tolerateInferenceVariables);
if (level == NOT_COMPATIBLE) {
// expect X[], is it called with X
param = ((ArrayBinding) param).elementsType();
if (tiebreakingVarargsMethods) {
arg = ((ArrayBinding) arg).elementsType();
}
- if (parameterCompatibilityLevel(arg, param, env, tiebreakingVarargsMethods) == NOT_COMPATIBLE)
+ if (parameterCompatibilityLevel(arg, param, env, tiebreakingVarargsMethods, tolerateInferenceVariables) == NOT_COMPATIBLE)
return NOT_COMPATIBLE;
level = VARARGS_COMPATIBLE; // varargs support needed
}
@@ -5249,7 +5252,7 @@ public abstract class Scope {
TypeBinding param = ((ArrayBinding) parameters[lastIndex]).elementsType();
for (int i = lastIndex; i < argLength; i++) {
TypeBinding arg = (tiebreakingVarargsMethods && (i == (argLength - 1))) ? ((ArrayBinding)arguments[i]).elementsType() : arguments[i];
- if (TypeBinding.notEquals(param, arg) && parameterCompatibilityLevel(arg, param, env, tiebreakingVarargsMethods) == NOT_COMPATIBLE)
+ if (TypeBinding.notEquals(param, arg) && parameterCompatibilityLevel(arg, param, env, tiebreakingVarargsMethods, tolerateInferenceVariables) == NOT_COMPATIBLE)
return NOT_COMPATIBLE;
}
} else if (lastIndex != argLength) { // can call foo(int i, X ... x) with foo(1) but NOT foo();
@@ -5265,7 +5268,7 @@ public abstract class Scope {
TypeBinding param = parameters[i];
TypeBinding arg = (tiebreakingVarargsMethods && (i == (argLength - 1))) ? ((ArrayBinding)arguments[i]).elementsType() : arguments[i];
if (TypeBinding.notEquals(arg,param)) {
- int newLevel = parameterCompatibilityLevel(arg, param, env, tiebreakingVarargsMethods);
+ int newLevel = parameterCompatibilityLevel(arg, param, env, tiebreakingVarargsMethods, tolerateInferenceVariables);
if (newLevel == NOT_COMPATIBLE)
return NOT_COMPATIBLE;
if (newLevel > level)
@@ -5297,7 +5300,7 @@ public abstract class Scope {
return NOT_COMPATIBLE;
}
- private int parameterCompatibilityLevel(TypeBinding arg, TypeBinding param, LookupEnvironment env, boolean tieBreakingVarargsMethods) {
+ private int parameterCompatibilityLevel(TypeBinding arg, TypeBinding param, LookupEnvironment env, boolean tieBreakingVarargsMethods, boolean tolerateInferenceVariables) {
// only called if env.options.sourceLevel >= ClassFileConstants.JDK1_5
if (arg == null || param == null)
return NOT_COMPATIBLE;
@@ -5317,6 +5320,11 @@ public abstract class Scope {
if (TypeBinding.equalsEquals(convertedType, param) || convertedType.isCompatibleWith(param, this))
return AUTOBOX_COMPATIBLE;
}
+ if (tolerateInferenceVariables && (!arg.isProperType(false) || !param.isProperType(false))) {
+ // during type inference involving a ReferenceExpression ignore incompatibility due to an inference variable,
+ // knowing that we will produce constraints that will ensure compatible instantiation (if one exists).
+ return COMPATIBLE;
+ }
return NOT_COMPATIBLE;
}
@@ -5705,7 +5713,7 @@ public abstract class Scope {
}
/**
- * Given a selected applibable method, check if it has an unfinished InferenceContext18 associated.
+ * Given a selected applicable method, check if it has an unfinished InferenceContext18 associated.
* If so perform the outstanding Invocation Type Inference and return the improved method,
* otherwise return the applicable method unchanged.
*/
@@ -5721,6 +5729,11 @@ public abstract class Scope {
} else {
ASTNode.resolvePolyExpressionArguments(invocation, applicable, argumentTypes, this);
}
+ } else if (invocationSite instanceof ReferenceExpression) {
+ if (applicable instanceof ParameterizedGenericMethodBinding)
+ applicable = applicable.shallowOriginal();
+ if (applicable.typeVariables() != Binding.NO_TYPE_VARIABLES)
+ return ParameterizedGenericMethodBinding.computeCompatibleMethod(applicable, argumentTypes, this, invocationSite, FULL_INFERENCE);
}
return applicable;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
index 93bc35be3..5a0822627 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
@@ -35,6 +35,7 @@
* Bug 432348 - [1.8] Internal compiler error (NPE) after upgrade to 1.8
* Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables
* Bug 435570 - [1.8][null] @NonNullByDefault illegally tries to affect "throws E"
+ * Bug 441693 - [1.8][null] Bogus warning for type argument annotated with @NonNull
* Jesper S Moller <jesper@selskabet.org> - Contributions for
* Bug 412153 - [1.8][compiler] Check validity of annotations which may be repeatable
* Till Brychcy - Contributions for
@@ -984,7 +985,7 @@ public SyntheticMethodBinding addSyntheticFactoryMethod(MethodBinding privateCon
*/
public SyntheticMethodBinding addSyntheticBridgeMethod(MethodBinding inheritedMethodToBridge, MethodBinding targetMethod) {
if (!isPrototype()) throw new IllegalStateException();
- if (isInterface()) return null; // only classes & enums get bridge methods
+ if (isInterface() && this.scope.compilerOptions().sourceLevel <= ClassFileConstants.JDK1_7) return null; // only classes & enums get bridge methods, interfaces too at 1.8+
// targetMethod may be inherited
//{ObjectTeams: retrieve callin method's real return type:
TypeBinding inheritedReturn= MethodModel.getReturnType(inheritedMethodToBridge);
@@ -3533,14 +3534,17 @@ void verifyMethods(MethodVerifier verifier) {
// SH}
}
-public TypeBinding unannotated(boolean removeOnlyNullAnnotations) {
- if (removeOnlyNullAnnotations) {
- if (!hasNullTypeAnnotations())
- return this;
- AnnotationBinding[] newAnnotations = this.environment.filterNullTypeAnnotations(this.typeAnnotations);
- if (newAnnotations.length > 0)
- return this.environment.createAnnotatedType(this.prototype, newAnnotations);
- }
+public TypeBinding unannotated() {
+ return this.prototype;
+}
+
+@Override
+public TypeBinding withoutToplevelNullAnnotation() {
+ if (!hasNullTypeAnnotations())
+ return this;
+ AnnotationBinding[] newAnnotations = this.environment.filterNullTypeAnnotations(this.typeAnnotations);
+ if (newAnnotations.length > 0)
+ return this.environment.createAnnotatedType(this.prototype, newAnnotations);
return this.prototype;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
index 29da06df1..dcb3a7a3b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
@@ -28,6 +28,7 @@
* Bug 435962 - [RC2] StackOverFlowError when building
* Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables
* Bug 440759 - [1.8][null] @NonNullByDefault should never affect wildcards and uses of a type variable
+ * Bug 441693 - [1.8][null] Bogus warning for type argument annotated with @NonNull
* Jesper S Moller <jesper@selskabet.org> - Contributions for
* bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression
*******************************************************************************/
@@ -1470,17 +1471,24 @@ public TypeBinding original() {
case Binding.PARAMETERIZED_TYPE :
case Binding.RAW_TYPE :
case Binding.ARRAY_TYPE :
- return erasure().unannotated(false);
+ return erasure().unannotated();
default :
- return this.unannotated(false);
+ return this.unannotated();
}
}
/**
* Return this type minus its type annotations
- * @param removeOnlyNullAnnotations if true only null type annotations are removed, otherwise all type annotations.
*/
-public TypeBinding unannotated(boolean removeOnlyNullAnnotations) {
+public TypeBinding unannotated() {
+ return this;
+}
+
+/**
+ * Return this type minus its toplevel null annotations. Any annotations on type arguments or
+ * bounds are retained.
+ */
+public TypeBinding withoutToplevelNullAnnotation() {
return this;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBindingVisitor.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBindingVisitor.java
index 3ca4f0507..bc940796c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBindingVisitor.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBindingVisitor.java
@@ -49,6 +49,10 @@ public class TypeBindingVisitor {
public boolean visit(RawTypeBinding rawTypeBinding) {
return true; // continue traversal.
}
+
+ public boolean visit(PolyTypeBinding polyTypeBinding) {
+ return true; // continue traversal.
+ }
public static void visit(TypeBindingVisitor visitor, ReferenceBinding[] types) {
for (int i = 0, length = types == null ? 0 : types.length; i < length; i++) {
@@ -130,6 +134,10 @@ public class TypeBindingVisitor {
visit(visitor, intersectionCastTypeBinding.intersectingTypes);
break;
+ case Binding.POLY_TYPE:
+ visitor.visit((PolyTypeBinding) type);
+ break;
+
default:
throw new InternalError("Unexpected binding type"); //$NON-NLS-1$
}
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 749f421f5..7b5469c94 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
@@ -12,6 +12,8 @@
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
+import java.util.HashMap;
+
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
import org.eclipse.jdt.internal.compiler.util.Util;
@@ -60,22 +62,114 @@ import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.RoleTypeBindin
*/
public class TypeSystem {
+ public final class HashedParameterizedTypes {
+
+ private final class InternalParameterizedTypeBinding extends ParameterizedTypeBinding {
+
+ public InternalParameterizedTypeBinding(ReferenceBinding genericType, TypeBinding[] typeArguments, ReferenceBinding enclosingType, LookupEnvironment environment) {
+ super(genericType, typeArguments, enclosingType, environment);
+ }
+
+ public boolean equals(Object other) {
+ ParameterizedTypeBinding that = (ParameterizedTypeBinding) other; // homogeneous container.
+ return this.type == that.type && this.enclosingType == that.enclosingType && Util.effectivelyEqual(this.arguments, that.arguments); //$IDENTITY-COMPARISON$
+ }
+
+ public int hashCode() {
+ int hashCode = this.type.hashCode() + 13 * (this.enclosingType != null ? this.enclosingType.hashCode() : 0);
+ for (int i = 0, length = this.arguments == null ? 0 : this.arguments.length; i < length; i++) {
+ hashCode += (i + 1) * this.arguments[i].id * this.arguments[i].hashCode();
+ }
+ return hashCode;
+ }
+ }
+
+ HashMap<ParameterizedTypeBinding, ParameterizedTypeBinding []> hashedParameterizedTypes = new HashMap<ParameterizedTypeBinding, ParameterizedTypeBinding[]>(256);
+
+ ParameterizedTypeBinding get(ReferenceBinding genericType, TypeBinding[] typeArguments, ReferenceBinding enclosingType, AnnotationBinding[] annotations) {
+
+ ReferenceBinding unannotatedGenericType = (ReferenceBinding) getUnannotatedType(genericType);
+ int typeArgumentsLength = typeArguments == null ? 0: typeArguments.length;
+ TypeBinding [] unannotatedTypeArguments = typeArguments == null ? null : new TypeBinding[typeArgumentsLength];
+ for (int i = 0; i < typeArgumentsLength; i++) {
+ unannotatedTypeArguments[i] = getUnannotatedType(typeArguments[i]);
+ }
+ ReferenceBinding unannotatedEnclosingType = enclosingType == null ? null : (ReferenceBinding) getUnannotatedType(enclosingType);
+
+ ParameterizedTypeBinding typeParameterization = new InternalParameterizedTypeBinding(unannotatedGenericType, unannotatedTypeArguments, unannotatedEnclosingType, TypeSystem.this.environment);
+ ReferenceBinding genericTypeToMatch = unannotatedGenericType, enclosingTypeToMatch = unannotatedEnclosingType;
+ TypeBinding [] typeArgumentsToMatch = unannotatedTypeArguments;
+ if (TypeSystem.this instanceof AnnotatableTypeSystem) {
+ genericTypeToMatch = genericType;
+ enclosingTypeToMatch = enclosingType;
+ typeArgumentsToMatch = typeArguments;
+ }
+ ParameterizedTypeBinding [] parameterizedTypeBindings = this.hashedParameterizedTypes.get(typeParameterization);
+ for (int i = 0, length = parameterizedTypeBindings == null ? 0 : parameterizedTypeBindings.length; i < length; i++) {
+ ParameterizedTypeBinding parameterizedType = parameterizedTypeBindings[i];
+ if (parameterizedType.actualType() != genericTypeToMatch) { //$IDENTITY-COMPARISON$
+ continue;
+ }
+ if (parameterizedType.enclosingType() != enclosingTypeToMatch //$IDENTITY-COMPARISON$
+ || !Util.effectivelyEqual(parameterizedType.typeArguments(), typeArgumentsToMatch))
+ continue;
+ if (Util.effectivelyEqual(annotations, parameterizedType.getTypeAnnotations()))
+ return parameterizedType;
+ }
+
+ return null;
+ }
+
+ void put (ReferenceBinding genericType, TypeBinding[] typeArguments, ReferenceBinding enclosingType, ParameterizedTypeBinding parameterizedType) {
+ ReferenceBinding unannotatedGenericType = (ReferenceBinding) getUnannotatedType(genericType);
+ int typeArgumentsLength = typeArguments == null ? 0: typeArguments.length;
+ TypeBinding [] unannotatedTypeArguments = typeArguments == null ? null : new TypeBinding[typeArgumentsLength];
+ for (int i = 0; i < typeArgumentsLength; i++) {
+ unannotatedTypeArguments[i] = getUnannotatedType(typeArguments[i]);
+ }
+ ReferenceBinding unannotatedEnclosingType = enclosingType == null ? null : (ReferenceBinding) getUnannotatedType(enclosingType);
+
+ ParameterizedTypeBinding typeParameterization = new InternalParameterizedTypeBinding(unannotatedGenericType, unannotatedTypeArguments, unannotatedEnclosingType, TypeSystem.this.environment);
+
+ ParameterizedTypeBinding [] parameterizedTypeBindings = this.hashedParameterizedTypes.get(typeParameterization);
+ int slot;
+ if (parameterizedTypeBindings == null) {
+ slot = 0;
+ parameterizedTypeBindings = new ParameterizedTypeBinding[1];
+ } else {
+ slot = parameterizedTypeBindings.length;
+ System.arraycopy(parameterizedTypeBindings, 0, parameterizedTypeBindings = new ParameterizedTypeBinding[slot + 1], 0, slot);
+ }
+ parameterizedTypeBindings[slot] = parameterizedType;
+ this.hashedParameterizedTypes.put(typeParameterization, parameterizedTypeBindings);
+ }
+ }
+
private int typeid = TypeIds.T_LastWellKnownTypeId;
private TypeBinding [][] types;
+ protected HashedParameterizedTypes parameterizedTypes; // auxiliary fast lookup table for parameterized types.
private SimpleLookupTable annotationTypes; // cannot store in types, since AnnotationBinding is not a TypeBinding and we don't want types to operate at Binding level.
- private LookupEnvironment environment;
+ LookupEnvironment environment;
public TypeSystem(LookupEnvironment environment) {
this.environment = environment;
this.annotationTypes = new SimpleLookupTable(16);
this.typeid = TypeIds.T_LastWellKnownTypeId;
this.types = new TypeBinding[TypeIds.T_LastWellKnownTypeId * 2][];
+ this.parameterizedTypes = new HashedParameterizedTypes();
}
// Given a type, answer its unannotated aka naked prototype. This is also a convenient way to "register" a type with TypeSystem and have it id stamped.
public final TypeBinding getUnannotatedType(TypeBinding type) {
- if (type.isUnresolvedType() && CharOperation.indexOf('$', type.sourceName()) > 0)
- type = BinaryTypeBinding.resolveType(type, this.environment, true); // to ensure unique id assignment (when enclosing type is parameterized, inner type is also)
+ if (type.isUnresolvedType() && 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;
+ }
+ }
if (type.id == TypeIds.NoId) {
if (type.hasTypeAnnotations())
throw new IllegalStateException();
@@ -102,6 +196,8 @@ public class TypeSystem {
/* Note: parameters will not have type type annotations if lookup environment directly uses TypeSystem as its typeSystem. When ATS is used however
they may be annotated and we need to materialize the unannotated versions and work on them.
+
+ See ArrayBinding.swapUnresolved for further special case handling if incoming leafType is a URB that would resolve to a raw type later.
*/
public ArrayBinding getArrayType(TypeBinding leafType, int dimensions) {
TypeBinding unannotatedLeafType = getUnannotatedType(leafType);
@@ -157,43 +253,16 @@ public class TypeSystem {
}
ReferenceBinding unannotatedEnclosingType = enclosingType == null ? null : (ReferenceBinding) getUnannotatedType(enclosingType);
- TypeBinding[] derivedTypes = this.types[unannotatedGenericType.id];
- int i, length = derivedTypes.length;
- for (i = 0 ; i < length; i++) {
- TypeBinding derivedType = derivedTypes[i];
- if (derivedType == null)
- break;
-//{ObjectTeams: parameterized and/or anchored?
-/* orig:
- if (!derivedType.isParameterizedType() || derivedType.actualType() != unannotatedGenericType || derivedType.hasTypeAnnotations()) //$IDENTITY-COMPARISON$
- continue;
- :giro */
- if (!(derivedType instanceof ParameterizedTypeBinding)) // roles might answer 'false' to isParameterized(), still they are valid candidates, here
- continue;
- if (derivedType.actualType() != unannotatedGenericType) //$IDENTITY-COMPARISON$
- continue;
- if (derivedType.isRawType() && unannotatedTypeArguments != null)
- continue;
- // also match team anchor if given:
- if (!isRoleTypeMatch(teamAnchor, valueParamPosition, derivedType))
- continue;
-//SH}
+ ParameterizedTypeBinding parameterizedType = this.parameterizedTypes.get(unannotatedGenericType, unannotatedTypeArguments, unannotatedEnclosingType, Binding.NO_ANNOTATIONS);
+ if (parameterizedType != null)
+ return parameterizedType;
- if (derivedType.enclosingType() == unannotatedEnclosingType && Util.effectivelyEqual(derivedType.typeArguments(), unannotatedTypeArguments)) //$IDENTITY-COMPARISON$
- return (ParameterizedTypeBinding) derivedType;
- }
-
- if (i == length) {
- System.arraycopy(derivedTypes, 0, derivedTypes = new TypeBinding[length * 2], 0, length);
- this.types[unannotatedGenericType.id] = derivedTypes;
- }
//{ObjectTeams: dependent type?
/* orig:
- TypeBinding parameterizedType = derivedTypes[i] = new ParameterizedTypeBinding(unannotatedGenericType, unannotatedTypeArguments, unannotatedEnclosingType, this.environment);
+ parameterizedType = new ParameterizedTypeBinding(unannotatedGenericType, unannotatedTypeArguments, unannotatedEnclosingType, this.environment);
:giro */
- ParameterizedTypeBinding parameterizedType;
if (teamAnchor == null) {
- parameterizedType = new ParameterizedTypeBinding(unannotatedGenericType,unannotatedTypeArguments, unannotatedEnclosingType, this.environment);
+ parameterizedType = new ParameterizedTypeBinding(unannotatedGenericType, unannotatedTypeArguments, unannotatedEnclosingType, this.environment);
} else {
if (genericType.isRole()) {
parameterizedType = new RoleTypeBinding(unannotatedGenericType, unannotatedTypeArguments, teamAnchor, unannotatedEnclosingType, this.environment);
@@ -201,10 +270,9 @@ public class TypeSystem {
parameterizedType = new DependentTypeBinding(unannotatedGenericType, unannotatedTypeArguments, teamAnchor, valueParamPosition, unannotatedEnclosingType, this.environment);
}
}
- derivedTypes[i] = parameterizedType;
// SH}
-
-
+ cacheDerivedType(unannotatedGenericType, parameterizedType);
+ this.parameterizedTypes.put(genericType, typeArguments, enclosingType, parameterizedType);
int typesLength = this.types.length;
if (this.typeid == typesLength)
System.arraycopy(this.types, 0, this.types = new TypeBinding[typesLength * 2][], 0, typesLength);
@@ -319,10 +387,20 @@ public class TypeSystem {
throw new IllegalStateException();
TypeBinding[] derivedTypes = this.types[keyType.id];
- int i = 0, length = derivedTypes.length;
- while (i < length && derivedTypes[i] != null) {
- i++;
- }
+ // binary search for the *earliest* slot with a null reference. By design and construction, a null value will never be followed by a valid derived type.
+ int first, last,length = derivedTypes.length;
+ first = 0; last = length;
+ int i = (first + last) / 2;
+ do {
+ if (derivedTypes[i] == null) {
+ if (i == first || i > 0 && derivedTypes[i - 1] != null)
+ break;
+ last = i - 1;
+ } else {
+ first = i + 1;
+ }
+ i = (first + last) / 2;
+ } while (i < length && first <= last);
if (i == length) {
System.arraycopy(derivedTypes, 0, derivedTypes = new TypeBinding[length * 2], 0, length);
this.types[keyType.id] = derivedTypes;
@@ -383,9 +461,15 @@ public class TypeSystem {
public void updateCaches(UnresolvedReferenceBinding unresolvedType, ReferenceBinding resolvedType) {
final int unresolvedTypeId = unresolvedType.id;
if (unresolvedTypeId != TypeIds.NoId) {
- if (this.types[unresolvedTypeId] != null && this.types[unresolvedTypeId][0] == unresolvedType) { //$IDENTITY-COMPARISON$
- resolvedType.id = unresolvedTypeId;
- this.types[unresolvedTypeId][0] = resolvedType;
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=432977
+ TypeBinding[] derivedTypes = this.types[unresolvedTypeId];
+ for (int i = 0, length = derivedTypes == null ? 0 : derivedTypes.length; i < length; i++) {
+ if (derivedTypes[i] == null)
+ break;
+ if (derivedTypes[i] == unresolvedType) { //$IDENTITY-COMPARISON$
+ resolvedType.id = unresolvedTypeId;
+ derivedTypes[i] = resolvedType;
+ }
}
}
if (this.annotationTypes.get(unresolvedType) != null) { // update the key
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 6ae69c83d..61fff8180 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
@@ -29,6 +29,7 @@
* Bug 438179 - [1.8][null] 'Contradictory null annotations' error on type variable with explicit null-annotation.
* Bug 440143 - [1.8][null] one more case of contradictory null annotations regarding type variables
* Bug 440759 - [1.8][null] @NonNullByDefault should never affect wildcards and uses of a type variable
+ * Bug 441693 - [1.8][null] Bogus warning for type argument annotated with @NonNull
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -923,18 +924,18 @@ public class TypeVariableBinding extends ReferenceBinding {
return readableName;
}
- public TypeBinding unannotated(boolean removeOnlyNullAnnotations) {
- if (!hasTypeAnnotations())
- return this;
- if (removeOnlyNullAnnotations && !hasNullTypeAnnotations())
+ public TypeBinding unannotated() {
+ return this.hasTypeAnnotations() ? this.environment.getUnannotatedType(this) : this;
+ }
+
+ @Override
+ public TypeBinding withoutToplevelNullAnnotation() {
+ if (!hasNullTypeAnnotations())
return this;
TypeBinding unannotated = this.environment.getUnannotatedType(this);
- if (removeOnlyNullAnnotations) {
- AnnotationBinding[] newAnnotations = this.environment.filterNullTypeAnnotations(this.typeAnnotations);
- if (newAnnotations.length > 0)
- return this.environment.createAnnotatedType(unannotated, newAnnotations);
- // FIXME: selectively keep type annotations on bounds
- }
+ AnnotationBinding[] newAnnotations = this.environment.filterNullTypeAnnotations(this.typeAnnotations);
+ if (newAnnotations.length > 0)
+ return this.environment.createAnnotatedType(unannotated, newAnnotations);
return unannotated;
}
/**
@@ -988,7 +989,7 @@ public class TypeVariableBinding extends ReferenceBinding {
this.tagBits &= ~TagBits.AnnotationNullMASK;
} else {
// implicit annotation: let the new one override
- return boundType.unannotated(true);
+ return boundType.withoutToplevelNullAnnotation();
}
return boundType;
}
@@ -1055,7 +1056,7 @@ public class TypeVariableBinding extends ReferenceBinding {
// may need to merge annotations from the original variable and from substitution:
if (hasRelevantTypeUseNullAnnotations()) {
// explicit type use null annotation overrides any annots on type parameter and concrete type arguments
- substitute = substitute.unannotated(true);
+ substitute = substitute.withoutToplevelNullAnnotation();
}
if (this.typeAnnotations != Binding.NO_ANNOTATIONS)
return this.environment.createAnnotatedType(substitute, this.typeAnnotations);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/VoidTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/VoidTypeBinding.java
index 3ad8be42c..69b3043ea 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/VoidTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/VoidTypeBinding.java
@@ -27,7 +27,7 @@ public class VoidTypeBinding extends BaseTypeBinding {
return; // reject misguided attempt.
}
- public TypeBinding unannotated(boolean removeOnlyNullAnnotations) {
+ public TypeBinding unannotated() {
return this;
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java
index 7d2cce697..d59dd7892 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java
@@ -21,6 +21,7 @@
* Bug 435962 - [RC2] StackOverFlowError when building
* Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables
* Bug 440759 - [1.8][null] @NonNullByDefault should never affect wildcards and uses of a type variable
+ * Bug 441693 - [1.8][null] Bogus warning for type argument annotated with @NonNull
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -935,24 +936,16 @@ public class WildcardBinding extends ReferenceBinding {
return this.typeVariable;
}
- public TypeBinding unannotated(boolean removeOnlyNullAnnotations) {
- if (!hasTypeAnnotations())
- return this;
- if (removeOnlyNullAnnotations && !hasNullTypeAnnotations())
+ public TypeBinding unannotated() {
+ return this.hasTypeAnnotations() ? this.environment.getUnannotatedType(this) : this;
+ }
+
+ @Override
+ public TypeBinding withoutToplevelNullAnnotation() {
+ if (!hasNullTypeAnnotations())
return this;
- ReferenceBinding unannotatedGenericType = (ReferenceBinding) this.genericType.unannotated(removeOnlyNullAnnotations);
- if (removeOnlyNullAnnotations) {
- // cf. structure of uncapture():
- TypeBinding unannotatedBound = this.bound != null ? this.bound.unannotated(removeOnlyNullAnnotations) : null;
- int length = 0;
- TypeBinding [] unannotatedOtherBounds = this.otherBounds == null ? null : new TypeBinding[length = this.otherBounds.length];
- for (int i = 0; i < length; i++) {
- unannotatedOtherBounds[i] = this.otherBounds[i] == null ? null : this.otherBounds[i].unannotated(removeOnlyNullAnnotations);
- }
- AnnotationBinding[] newAnnotations = this.environment.filterNullTypeAnnotations(getTypeAnnotations());
- return this.environment.createWildcard(unannotatedGenericType, this.rank, unannotatedBound, unannotatedOtherBounds, this.boundKind, newAnnotations);
- }
- return unannotatedGenericType;
+ AnnotationBinding[] newAnnotations = this.environment.filterNullTypeAnnotations(getTypeAnnotations());
+ return this.environment.createWildcard(this.genericType, this.rank, this.bound, this.otherBounds, this.boundKind, newAnnotations);
}
@Override
public TypeBinding uncapture(Scope scope) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
index bebcdc31c..754b03287 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
@@ -974,6 +974,7 @@ private boolean haltOnSyntaxError = false;
private boolean tolerateDefaultClassMethods = false;
private boolean processingLambdaParameterList = false;
private boolean expectTypeAnnotation = false;
+private boolean reparsingLambdaExpression = false;
//{ObjectTeams: context info while parsing separate role files:
@@ -5791,13 +5792,58 @@ private void consumeBeginLiftingType() {
// SH}
protected void consumeLocalVariableDeclarationStatement() {
+
+ int variableDeclaratorsCounter = this.astLengthStack[this.astLengthPtr];
+ if (variableDeclaratorsCounter == 1) {
+ LocalDeclaration localDeclaration = (LocalDeclaration) this.astStack[this.astPtr];
+ if (localDeclaration.isRecoveredFromLoneIdentifier()) {
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=430336, [1.8][compiler] Bad syntax error recovery: Lonely identifier should be variable name, not type
+ // Mutate foo $missing; into foo = $missing$;
+ Expression left;
+ if (localDeclaration.type instanceof QualifiedTypeReference) {
+ QualifiedTypeReference qtr = (QualifiedTypeReference) localDeclaration.type;
+ left = new QualifiedNameReference(qtr.tokens, qtr.sourcePositions, 0, 0);
+ } else {
+ left = new SingleNameReference(localDeclaration.type.getLastToken(), 0L);
+ }
+ left.sourceStart = localDeclaration.type.sourceStart;
+ left.sourceEnd = localDeclaration.type.sourceEnd;
+
+ Expression right = new SingleNameReference(localDeclaration.name, 0L);
+ right.sourceStart = localDeclaration.sourceStart;
+ right.sourceEnd = localDeclaration.sourceEnd;
+
+ Assignment assignment = new Assignment(left, right, 0);
+ int end = this.endStatementPosition;
+ assignment.sourceEnd = (end == localDeclaration.sourceEnd) ? ++end : end;
+ assignment.statementEnd = end;
+ this.astStack[this.astPtr] = assignment;
+
+ // also massage recovery scanner data.
+ if (this.recoveryScanner != null) {
+ RecoveryScannerData data = this.recoveryScanner.getData();
+ int position = data.insertedTokensPtr;
+ while (position > 0) {
+ if (data.insertedTokensPosition[position] != data.insertedTokensPosition[position - 1])
+ break;
+ position--;
+ }
+ this.recoveryScanner.insertTokenAhead(TerminalTokens.TokenNameEQUAL, position);
+ }
+
+ if (this.currentElement != null) {
+ this.lastCheckPoint = assignment.sourceEnd + 1;
+ this.currentElement = this.currentElement.add(assignment, 0);
+ }
+ return;
+ }
+ }
// LocalVariableDeclarationStatement ::= LocalVariableDeclaration ';'
// see blockReal in case of change: duplicated code
// increment the amount of declared variables for this block
this.realBlockStack[this.realBlockPtr]++;
// update source end to include the semi-colon
- int variableDeclaratorsCounter = this.astLengthStack[this.astLengthPtr];
for (int i = variableDeclaratorsCounter - 1; i >= 0; i--) {
LocalDeclaration localDeclaration = (LocalDeclaration) this.astStack[this.astPtr - i];
localDeclaration.declarationSourceEnd = this.endStatementPosition;
@@ -10085,6 +10131,7 @@ protected void consumeLambdaHeader() {
this.processingLambdaParameterList = false;
if (this.currentElement != null) {
this.lastCheckPoint = arrowPosition + 1; // we don't want the typed formal parameters to be processed by recovery.
+ this.currentElement.lambdaNestLevel++;
}
}
protected void consumeLambdaExpression() {
@@ -10117,6 +10164,7 @@ protected void consumeLambdaExpression() {
pushOnExpressionStack(lexp);
if (this.currentElement != null) {
this.lastCheckPoint = body.sourceEnd + 1;
+ this.currentElement.lambdaNestLevel --;
}
this.referenceContext.compilationResult().hasFunctionalTypes = true;
markEnclosingMemberWithLocalOrFunctionalType(LocalTypeKind.LAMBDA);
@@ -11209,6 +11257,7 @@ protected void consumeToken(int type) {
case TokenNameStringLiteral :
StringLiteral stringLiteral;
if (this.recordStringLiterals &&
+ !this.reparsingLambdaExpression &&
this.checkExternalizeStrings &&
this.lastPosistion < this.scanner.currentPosition &&
!this.statementRecoveryActivated) {
@@ -14450,6 +14499,7 @@ public ASTNode[] parseClassBodyDeclarations(char[] source, int offset, int lengt
public Expression parseLambdaExpression(char[] source, int offset, int length, CompilationUnitDeclaration unit, boolean recordLineSeparators) {
this.haltOnSyntaxError = true; // unexposed/unshared object, no threading concerns.
+ this.reparsingLambdaExpression = true;
return parseExpression(source, offset, length, unit, recordLineSeparators);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredBlock.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredBlock.java
index 6adf3eec4..cd7a56f3a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredBlock.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredBlock.java
@@ -96,6 +96,9 @@ public RecoveredElement add(LocalDeclaration localDeclaration, int bracketBalanc
*/
public RecoveredElement add(LocalDeclaration localDeclaration, int bracketBalanceValue, boolean delegatedByParent) {
+ if (localDeclaration.isRecoveredFromLoneIdentifier()) {
+ return this; // skip, the local will be mutated into an assignment and added later, see Parser.consumeLocalVariableDeclarationStatement
+ }
/* local variables inside method can only be final and non void */
/*
char[][] localTypeName;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredElement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredElement.java
index 81466874a..81c50c8e8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredElement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredElement.java
@@ -32,6 +32,11 @@ public class RecoveredElement {
public int bracketBalance;
public boolean foundOpeningBrace;
protected Parser recoveringParser;
+
+ // There is no RecoveredLambdaElement, we just keep track of entry and exit of lambdas via a counter. This allows to prevent certain incorrect mutations of current element.
+ // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=430667.
+ public int lambdaNestLevel;
+
public RecoveredElement(RecoveredElement parent, int bracketBalance){
this(parent, bracketBalance, null);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredField.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredField.java
index 96f9ab856..aa520ae79 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredField.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredField.java
@@ -24,6 +24,7 @@ import org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Statement;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
@@ -50,6 +51,14 @@ public RecoveredField(FieldDeclaration fieldDeclaration, RecoveredElement parent
this.alreadyCompletedFieldInitialization = fieldDeclaration.initialization != null;
}
/*
+ * Record a local declaration
+ */
+public RecoveredElement add(LocalDeclaration localDeclaration, int bracketBalanceValue) {
+ if (this.lambdaNestLevel > 0) // current element is really the lambda which is recovered in full elsewhere.
+ return this;
+ return super.add(localDeclaration, bracketBalanceValue);
+}
+/*
* Record a field declaration
*/
public RecoveredElement add(FieldDeclaration addedfieldDeclaration, int bracketBalanceValue) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredLocalVariable.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredLocalVariable.java
index 643b98622..fc1b9c75a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredLocalVariable.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredLocalVariable.java
@@ -33,7 +33,7 @@ public class RecoveredLocalVariable extends RecoveredStatement {
public int modifiersStart;
public LocalDeclaration localDeclaration;
- boolean alreadyCompletedLocalInitialization;
+ public boolean alreadyCompletedLocalInitialization;
public RecoveredLocalVariable(LocalDeclaration localDeclaration, RecoveredElement parent, int bracketBalance){
super(localDeclaration, parent, bracketBalance);
this.localDeclaration = localDeclaration;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveryScanner.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveryScanner.java
index cbdb51b3f..340588faf 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveryScanner.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveryScanner.java
@@ -93,6 +93,16 @@ public class RecoveryScanner extends Scanner {
this.data.insertedTokensPosition[this.data.insertedTokensPtr] = position;
this.data.insertedTokenUsed[this.data.insertedTokensPtr] = false;
}
+
+ public void insertTokenAhead(int token, int index) {
+ if(!this.record) return;
+
+ int length = this.data.insertedTokens[index].length;
+ int [] tokens = new int [length + 1];
+ System.arraycopy(this.data.insertedTokens[index], 0, tokens, 1, length);
+ tokens[0] = token;
+ this.data.insertedTokens[index] = tokens;
+ }
public void replaceTokens(int token, int start, int end) {
replaceTokens(new int []{token}, start, end);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.java
index d28a3445e..117cafe32 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.java
@@ -28,7 +28,7 @@ public class ScannerHelper {
ASTNode.Bit13, ASTNode.Bit14, ASTNode.Bit15, ASTNode.Bit16, ASTNode.Bit17, ASTNode.Bit18,
ASTNode.Bit19, ASTNode.Bit20, ASTNode.Bit21, ASTNode.Bit22, ASTNode.Bit23, ASTNode.Bit24,
ASTNode.Bit25, ASTNode.Bit26, ASTNode.Bit27, ASTNode.Bit28, ASTNode.Bit29, ASTNode.Bit30,
- ASTNode.Bit31, ASTNode.Bit32, ASTNode.Bit33L, ASTNode.Bit34L, ASTNode.Bit35L, ASTNode.Bit36L,
+ ASTNode.Bit31, ASTNode.Bit32L, ASTNode.Bit33L, ASTNode.Bit34L, ASTNode.Bit35L, ASTNode.Bit36L,
ASTNode.Bit37L, ASTNode.Bit38L, ASTNode.Bit39L, ASTNode.Bit40L, ASTNode.Bit41L, ASTNode.Bit42L,
ASTNode.Bit43L, ASTNode.Bit44L, ASTNode.Bit45L, ASTNode.Bit46L, ASTNode.Bit47L, ASTNode.Bit48L,
ASTNode.Bit49L, ASTNode.Bit50L, ASTNode.Bit51L, ASTNode.Bit52L, ASTNode.Bit53L, ASTNode.Bit54L,
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/DiagnoseParser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/DiagnoseParser.java
index 3af00d0ff..807a290f8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/DiagnoseParser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/DiagnoseParser.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 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
@@ -472,34 +472,7 @@ public class DiagnoseParser implements ParserBasicInformation, TerminalTokens, C
for (int i = start; i < end; i++) {
char c = tokenSource[i];
- switch (c) {
- case '\r' :
- tokenSourceBuffer.append("\\r"); //$NON-NLS-1$
- break;
- case '\n' :
- tokenSourceBuffer.append("\\n"); //$NON-NLS-1$
- break;
- case '\b' :
- tokenSourceBuffer.append("\\b"); //$NON-NLS-1$
- break;
- case '\t' :
- tokenSourceBuffer.append("\t"); //$NON-NLS-1$
- break;
- case '\f' :
- tokenSourceBuffer.append("\\f"); //$NON-NLS-1$
- break;
- case '\"' :
- tokenSourceBuffer.append("\\\""); //$NON-NLS-1$
- break;
- case '\'' :
- tokenSourceBuffer.append("\\'"); //$NON-NLS-1$
- break;
- case '\\' :
- tokenSourceBuffer.append("\\\\"); //$NON-NLS-1$
- break;
- default :
- tokenSourceBuffer.append(c);
- }
+ Util.appendEscapedChar(tokenSourceBuffer, c, true);
}
for (int i = end; i < tokenSource.length; i++) {
tokenSourceBuffer.append(tokenSource[i]);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemHandler.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemHandler.java
index 3b9dcde09..28e22a0bc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemHandler.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemHandler.java
@@ -150,6 +150,15 @@ private void protectedHandle(
boolean mandatory = (severity & (ProblemSeverities.Error | ProblemSeverities.Optional)) == ProblemSeverities.Error;
if (severity < ProblemSeverities.InternalError && this.policy.ignoreAllErrors()) {
// Error is not to be exposed, but clients may need still notification as to whether there are silently-ignored-errors.
+ // if no reference context, we need to abort from the current compilation process
+ if (referenceContext == null) {
+ if ((severity & ProblemSeverities.Error) != 0) { // non reportable error is fatal
+ CategorizedProblem problem = this.createProblem(null, problemId, problemArguments, elaborationId, messageArguments, severity, 0, 0, 0, 0);
+ throw new AbortCompilation(null, problem);
+ } else {
+ return; // ignore non reportable warning
+ }
+ }
if (mandatory)
referenceContext.tagAsHavingIgnoredMandatoryErrors(problemId);
return;
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 fbda4b7b0..fc2c92b1f 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
@@ -1781,8 +1781,6 @@ public int computeSeverity(int problemID){
return ProblemSeverities.Warning;
case IProblem.IllegalUseOfUnderscoreAsAnIdentifier:
return this.underScoreIsLambdaParameter ? ProblemSeverities.Error : ProblemSeverities.Warning;
- case IProblem.LambdaShapeComputationError:
- return ProblemSeverities.InternalError;
}
int irritant = getIrritant(problemID);
if (irritant != 0) {
@@ -5257,6 +5255,10 @@ public void illegalTypeAnnotationsInStaticMemberAccess(Annotation first, Annotat
last.sourceEnd);
}
public void isClassPathCorrect(char[][] wellKnownTypeName, CompilationUnitDeclaration compUnitDecl, Object location) {
+ // ProblemReporter is not designed to be reentrant. Just in case, we discovered a build path problem while we are already
+ // in the midst of reporting some other problem, save and restore reference context thereby mimicking a stack.
+ // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=442755.
+ ReferenceContext savedContext = this.referenceContext;
this.referenceContext = compUnitDecl;
String[] arguments = new String[] {CharOperation.toString(wellKnownTypeName)};
int start = 0, end = 0;
@@ -5271,12 +5273,16 @@ public void isClassPathCorrect(char[][] wellKnownTypeName, CompilationUnitDeclar
end = node.sourceEnd();
}
}
- this.handle(
- IProblem.IsClassPathCorrect,
- arguments,
- arguments,
- start,
- end);
+ try {
+ this.handle(
+ IProblem.IsClassPathCorrect,
+ arguments,
+ arguments,
+ start,
+ end);
+ } finally {
+ this.referenceContext = savedContext;
+ }
}
private boolean isIdentifier(int token) {
return token == TerminalTokens.TokenNameIdentifier;
@@ -7218,7 +7224,7 @@ public void noSuchEnclosingInstance(TypeBinding targetType, ASTNode location, bo
new String[] { new String(targetType.readableName())},
new String[] { new String(targetType.shortReadableName())},
location.sourceStart,
- location.sourceEnd);
+ location instanceof LambdaExpression ? ((LambdaExpression)location).diagnosticsSourceEnd() : location.sourceEnd);
}
public void notCompatibleTypesError(EqualExpression expression, TypeBinding leftType, TypeBinding rightType) {
String leftName = new String(leftType.readableName());
@@ -14572,13 +14578,4 @@ public void uninternedIdentityComparison(EqualExpression expr, TypeBinding lhs,
expr.sourceStart,
expr.sourceEnd);
}
-
-public void lambdaShapeComputationError(LambdaExpression expression) {
- this.handle(
- IProblem.LambdaShapeComputationError,
- NoArgument,
- NoArgument,
- expression.sourceStart,
- expression.diagnosticsSourceEnd());
-}
}
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 07f258500..77a3f6400 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
@@ -848,7 +848,6 @@
1058 = Default methods are allowed only in interfaces.
1100 = Problem detected during type inference: {0}
-1101 = (Recovered) Internal inconsistency detected during lambda shape analysis
### ELABORATIONS
## Access restrictions
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java
index 3ffd96c28..428b453d2 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 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
@@ -1629,4 +1629,52 @@ public class Util implements SuffixConstants {
}
return true;
}
+
+ public static void appendEscapedChar(StringBuffer buffer, char c, boolean stringLiteral) {
+ switch (c) {
+ case '\b' :
+ buffer.append("\\b"); //$NON-NLS-1$
+ break;
+ case '\t' :
+ buffer.append("\\t"); //$NON-NLS-1$
+ break;
+ case '\n' :
+ buffer.append("\\n"); //$NON-NLS-1$
+ break;
+ case '\f' :
+ buffer.append("\\f"); //$NON-NLS-1$
+ break;
+ case '\r' :
+ buffer.append("\\r"); //$NON-NLS-1$
+ break;
+ case '\"':
+ if (stringLiteral) {
+ buffer.append("\\\""); //$NON-NLS-1$
+ } else {
+ buffer.append(c);
+ }
+ break;
+ case '\'':
+ if (stringLiteral) {
+ buffer.append(c);
+ } else {
+ buffer.append("\\\'"); //$NON-NLS-1$
+ }
+ break;
+ case '\\':
+ buffer.append("\\\\"); //$NON-NLS-1$
+ break;
+ default:
+ if (c >= 0x20) {
+ buffer.append(c);
+ } else if (c >= 0x10) {
+ buffer.append("\\u00").append(Integer.toHexString(c)); //$NON-NLS-1$
+ } else if (c >= 0) {
+ buffer.append("\\u000").append(Integer.toHexString(c)); //$NON-NLS-1$
+ } else {
+ buffer.append(c);
+ }
+ }
+ }
+
}
diff --git a/org.eclipse.jdt.core/component.xml b/org.eclipse.jdt.core/component.xml
index 6199452c0..6ac71e0d1 100644
--- a/org.eclipse.jdt.core/component.xml
+++ b/org.eclipse.jdt.core/component.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright (c) 2005, 2009 IBM Corporation and others.
+ Copyright (c) 2005, 2014 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
@@ -152,7 +152,7 @@
<type name="ForStatement" instantiate="false"/>
<type name="IAnnotationBinding" instantiate="false" implement="false"/>
<type name="IBinding" instantiate="false" implement="false"/>
- <type name="IDocElement" reference="false"/>
+ <type name="IDocElement" instantiate="false"/>
<type name="IExtendedModifier" instantiate="false"/>
<type name="IfStatement" instantiate="false"/>
<type name="IMemberValuePairBinding" instantiate="false" implement="false"/>
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CharacterLiteral.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CharacterLiteral.java
index 59c2c7304..b4b1da6d9 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CharacterLiteral.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CharacterLiteral.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 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
@@ -18,6 +18,7 @@ import org.eclipse.jdt.core.compiler.InvalidInputException;
import org.eclipse.jdt.internal.compiler.parser.Scanner;
import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+import org.eclipse.jdt.internal.compiler.util.Util;
/**
* Character literal nodes.
@@ -316,58 +317,7 @@ public class CharacterLiteral extends Expression {
StringBuffer b = new StringBuffer(3);
b.append('\''); // opening delimiter
- switch(value) {
- case '\b' :
- b.append("\\b"); //$NON-NLS-1$
- break;
- case '\t' :
- b.append("\\t"); //$NON-NLS-1$
- break;
- case '\n' :
- b.append("\\n"); //$NON-NLS-1$
- break;
- case '\f' :
- b.append("\\f"); //$NON-NLS-1$
- break;
- case '\r' :
- b.append("\\r"); //$NON-NLS-1$
- break;
- case '\"':
- b.append("\\\""); //$NON-NLS-1$
- break;
- case '\'':
- b.append("\\\'"); //$NON-NLS-1$
- break;
- case '\\':
- b.append("\\\\"); //$NON-NLS-1$
- break;
- case '\0' :
- b.append("\\0"); //$NON-NLS-1$
- break;
- case '\1' :
- b.append("\\1"); //$NON-NLS-1$
- break;
- case '\2' :
- b.append("\\2"); //$NON-NLS-1$
- break;
- case '\3' :
- b.append("\\3"); //$NON-NLS-1$
- break;
- case '\4' :
- b.append("\\4"); //$NON-NLS-1$
- break;
- case '\5' :
- b.append("\\5"); //$NON-NLS-1$
- break;
- case '\6' :
- b.append("\\6"); //$NON-NLS-1$
- break;
- case '\7' :
- b.append("\\7"); //$NON-NLS-1$
- break;
- default:
- b.append(value);
- }
+ Util.appendEscapedChar(b, value, false);
b.append('\''); // closing delimiter
setEscapedValue(b.toString());
}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IDocElement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IDocElement.java
index d492a90a2..a8f237615 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IDocElement.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IDocElement.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2006 IBM Corporation and others.
+ * Copyright (c) 2004, 2014 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
@@ -12,11 +12,22 @@
package org.eclipse.jdt.core.dom;
/**
- * Internal marker-type interface used to tag node types that can legitimately
- * be included in {@link TagElement#fragments() TagElement.fragments()}.
- *
- * @since 3.0
+ * Common marker interface for AST nodes that represent fragments in doc elements.
+ * These are node types that can legitimately be included in {@link TagElement#fragments()}.
+ * <pre>
+ * IDocElement:
+ * {@link MemberRef}
+ * {@link MethodRef}
+ * {@link Name}
+ * {@link TagElement}
+ * {@link TextElement}
+ * </pre>
+ *
+ * @since 3.11, internal interface since 3.0
+ * @see TagElement#fragments()
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
*/
-interface IDocElement {
+public interface IDocElement {
// marker-type interfaces have no members
}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IExtendedModifier.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IExtendedModifier.java
index 7872c3f28..c686c3ecd 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IExtendedModifier.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IExtendedModifier.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * Copyright (c) 2004, 2014 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
@@ -14,11 +14,13 @@ package org.eclipse.jdt.core.dom;
* Common interface for AST nodes that represent modifiers or
* annotations.
* <pre>
- * ExtendedModifier:
+ * IExtendedModifier:
* Modifier
* Annotation
* </pre>
* @since 3.1
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
*/
public interface IExtendedModifier {
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/StringLiteral.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/StringLiteral.java
index 6400b8191..e5f6f4691 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/StringLiteral.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/StringLiteral.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 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
@@ -17,6 +17,7 @@ import java.util.List;
import org.eclipse.jdt.core.compiler.InvalidInputException;
import org.eclipse.jdt.internal.compiler.parser.Scanner;
import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+import org.eclipse.jdt.internal.compiler.util.Util;
/**
* String literal nodes.
@@ -273,55 +274,7 @@ public class StringLiteral extends Expression {
b.append("\""); // opening delimiter //$NON-NLS-1$
for (int i = 0; i < len; i++) {
char c = value.charAt(i);
- switch(c) {
- case '\b' :
- b.append("\\b"); //$NON-NLS-1$
- break;
- case '\t' :
- b.append("\\t"); //$NON-NLS-1$
- break;
- case '\n' :
- b.append("\\n"); //$NON-NLS-1$
- break;
- case '\f' :
- b.append("\\f"); //$NON-NLS-1$
- break;
- case '\r' :
- b.append("\\r"); //$NON-NLS-1$
- break;
- case '\"':
- b.append("\\\""); //$NON-NLS-1$
- break;
- case '\\':
- b.append("\\\\"); //$NON-NLS-1$
- break;
- case '\0' :
- b.append("\\0"); //$NON-NLS-1$
- break;
- case '\1' :
- b.append("\\1"); //$NON-NLS-1$
- break;
- case '\2' :
- b.append("\\2"); //$NON-NLS-1$
- break;
- case '\3' :
- b.append("\\3"); //$NON-NLS-1$
- break;
- case '\4' :
- b.append("\\4"); //$NON-NLS-1$
- break;
- case '\5' :
- b.append("\\5"); //$NON-NLS-1$
- break;
- case '\6' :
- b.append("\\6"); //$NON-NLS-1$
- break;
- case '\7' :
- b.append("\\7"); //$NON-NLS-1$
- break;
- default:
- b.append(c);
- }
+ Util.appendEscapedChar(b, c, true);
}
b.append("\""); // closing delimiter //$NON-NLS-1$
setEscapedValue(b.toString());
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
index 6235afe0e..24179feb6 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
@@ -535,7 +535,7 @@ class TypeBinding implements ITypeBinding {
public ITypeBinding getTypeDeclaration() {
if (this.binding instanceof ParameterizedTypeBinding)
return this.resolver.getTypeBinding(((ParameterizedTypeBinding)this.binding).genericType());
- return this.resolver.getTypeBinding(this.binding.unannotated(false));
+ return this.resolver.getTypeBinding(this.binding.unannotated());
}
/* (non-Javadoc)
@@ -1300,7 +1300,7 @@ class TypeBinding implements ITypeBinding {
return false;
}
org.eclipse.jdt.internal.compiler.lookup.TypeBinding otherBinding = ((TypeBinding) other).binding;
- if (org.eclipse.jdt.internal.compiler.lookup.TypeBinding.equalsEquals(otherBinding.unannotated(false), this.binding.unannotated(false))) {
+ if (org.eclipse.jdt.internal.compiler.lookup.TypeBinding.equalsEquals(otherBinding.unannotated(), this.binding.unannotated())) {
return true;
}
// check return type
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java
index b1c0c4e3c..cd25bdbeb 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java
@@ -466,6 +466,7 @@ protected void consumeMethodHeaderName(boolean isAnnotationMethod) {
this.sourceEnds.put(this.astStack[this.astPtr], selectorSourceEnd);
rememberCategories();
}
+ flushCommentsDefinedPriorTo(this.scanner.currentPosition);
}
protected void consumeMethodHeaderNameWithTypeParameters(boolean isAnnotationMethod) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java
index 09f336541..78a66b4b4 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java
@@ -42,11 +42,6 @@ public class JarPackageFragmentRoot extends PackageFragmentRoot {
private final static ArrayList EMPTY_LIST = new ArrayList();
/**
- * Compiler compliance level that was used to produce the jar.
- */
- protected final String complianceLevel;
-
- /**
* The path to the jar file
* (a workspace relative path if the jar is internal,
* or an OS path if the jar is external)
@@ -61,9 +56,6 @@ public class JarPackageFragmentRoot extends PackageFragmentRoot {
protected JarPackageFragmentRoot(IPath externalJarPath, JavaProject project) {
super(null, project);
this.jarPath = externalJarPath;
- Object file = JavaModel.getTarget(getPath(), true);
- long level = Util.getJdkLevel(file);
- this.complianceLevel = CompilerOptions.versionFromJdkLevel(level);
}
/**
* Constructs a package fragment root which is the root of the Java package directory hierarchy
@@ -72,9 +64,6 @@ public class JarPackageFragmentRoot extends PackageFragmentRoot {
protected JarPackageFragmentRoot(IResource resource, JavaProject project) {
super(resource, project);
this.jarPath = resource.getFullPath();
- Object file = JavaModel.getTarget(getPath(), true);
- long level = Util.getJdkLevel(file);
- this.complianceLevel = CompilerOptions.versionFromJdkLevel(level);
}
/**
@@ -87,6 +76,9 @@ public class JarPackageFragmentRoot extends PackageFragmentRoot {
IJavaElement[] children;
ZipFile jar = null;
try {
+ Object file = JavaModel.getTarget(getPath(), true);
+ long level = Util.getJdkLevel(file);
+ String compliance = CompilerOptions.versionFromJdkLevel(level);
jar = getJar();
// always create the default package
@@ -94,7 +86,7 @@ public class JarPackageFragmentRoot extends PackageFragmentRoot {
for (Enumeration e= jar.entries(); e.hasMoreElements();) {
ZipEntry member= (ZipEntry) e.nextElement();
- initRawPackageInfo(rawPackageInfo, member.getName(), member.isDirectory());
+ initRawPackageInfo(rawPackageInfo, member.getName(), member.isDirectory(), compliance);
}
// loop through all of referenced packages, creating package fragments if necessary
@@ -221,7 +213,7 @@ public class JarPackageFragmentRoot extends PackageFragmentRoot {
public int hashCode() {
return this.jarPath.hashCode();
}
- private void initRawPackageInfo(HashtableOfArrayToObject rawPackageInfo, String entryName, boolean isDirectory) {
+ private void initRawPackageInfo(HashtableOfArrayToObject rawPackageInfo, String entryName, boolean isDirectory, String compliance) {
int lastSeparator = isDirectory ? entryName.length()-1 : entryName.lastIndexOf('/');
String[] pkgName = Util.splitOn('/', entryName, 0, lastSeparator);
String[] existing = null;
@@ -235,8 +227,7 @@ public class JarPackageFragmentRoot extends PackageFragmentRoot {
JavaModelManager manager = JavaModelManager.getJavaModelManager();
for (int i = existingLength; i < length; i++) {
// sourceLevel must be null because we know nothing about it based on a jar file
- // complianceLevel can be retrieved from a jar file
- if (Util.isValidFolderNameForPackage(pkgName[i], null, this.complianceLevel)) {
+ if (Util.isValidFolderNameForPackage(pkgName[i], null, compliance)) {
System.arraycopy(existing, 0, existing = new String[i+1], 0, i);
existing[i] = manager.intern(pkgName[i]);
rawPackageInfo.put(existing, new ArrayList[] { EMPTY_LIST, EMPTY_LIST });
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java
index 5af28dea1..88550cb1b 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java
@@ -1174,6 +1174,12 @@ public class NameLookup implements SuffixConstants {
*/
ICompilationUnit cu = (ICompilationUnit) type.getParent();
String cuName = cu.getElementName().substring(0, cu.getElementName().lastIndexOf('.'));
+ /*
+ * Secondary types along with primary types have their parent as the compilation unit.
+ * The names of the primary type would match with their compilation unit.
+ */
+ if (!cuName.equals(type.getElementName()))
+ return false;
if (partialMatch) {
return cuName.regionMatches(0, name, 0, name.length());
} else {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java
index 5db5a3852..8a150b44c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java
@@ -183,55 +183,13 @@ public class Disassembler extends ClassFileBytesDisassembler {
StringBuffer buffer = new StringBuffer();
for (int i = 0, max = chars.length; i < max; i++) {
char c = chars[i];
- escapeChar(buffer, c);
+ org.eclipse.jdt.internal.compiler.util.Util.appendEscapedChar(buffer, c, true);
}
return buffer.toString();
}
private static void escapeChar(StringBuffer buffer, char c) {
- switch(c) {
- case '\b' :
- buffer.append("\\b"); //$NON-NLS-1$
- break;
- case '\t' :
- buffer.append("\\t"); //$NON-NLS-1$
- break;
- case '\n' :
- buffer.append("\\n"); //$NON-NLS-1$
- break;
- case '\f' :
- buffer.append("\\f"); //$NON-NLS-1$
- break;
- case '\r' :
- buffer.append("\\r"); //$NON-NLS-1$
- break;
- case '\0' :
- buffer.append("\\0"); //$NON-NLS-1$
- break;
- case '\1' :
- buffer.append("\\1"); //$NON-NLS-1$
- break;
- case '\2' :
- buffer.append("\\2"); //$NON-NLS-1$
- break;
- case '\3' :
- buffer.append("\\3"); //$NON-NLS-1$
- break;
- case '\4' :
- buffer.append("\\4"); //$NON-NLS-1$
- break;
- case '\5' :
- buffer.append("\\5"); //$NON-NLS-1$
- break;
- case '\6' :
- buffer.append("\\6"); //$NON-NLS-1$
- break;
- case '\7' :
- buffer.append("\\7"); //$NON-NLS-1$
- break;
- default:
- buffer.append(c);
- }
+ org.eclipse.jdt.internal.compiler.util.Util.appendEscapedChar(buffer, c, false);
}
static String decodeStringValue(String s) {

Back to the top