Update jdt.core and tests to v20120221-0704
includes revert of null analysis for fields entailing also
a revert of commit 7ab5e31c24d0eb1a3e3c1c6f079a57204550e8f1
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/SelectionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/SelectionTest.java
index 816aac9..a11f6ac 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/SelectionTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/SelectionTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 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
@@ -2448,4 +2448,66 @@
expectedReplacedSource,
testName);
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=291040
+public void test56() {
+
+ String str =
+ "class X {\n" +
+ " void foo() {\n" +
+ " new X(null) {\n" +
+ " void goo() {\n" +
+ " new X(zoo()) {\n" +
+ " void voo() {\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ "\n" +
+ " Object zoo() {\n" +
+ " return null;\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ "\n" +
+ " X(Object k) {\n" +
+ " }\n" +
+ "}\n";
+
+ String selection = "zoo";
+
+ String expectedCompletionNodeToString = "<SelectOnMessageSend:zoo()>";
+
+ String completionIdentifier = "zoo";
+ String expectedUnitDisplayString =
+ "class X {\n" +
+ " void foo() {\n" +
+ " new X(null) {\n" +
+ " void goo() {\n" +
+ " new X(<SelectOnMessageSend:zoo()>) {\n" +
+ " void voo() {\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ " Object zoo() {\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ " X(Object k) {\n" +
+ " }\n" +
+ "}\n";
+ String expectedReplacedSource = "zoo()";
+ String testName = "<select>";
+
+ int selectionStart = str.indexOf(selection);
+ int selectionEnd = str.indexOf(selection) + selection.length() - 1;
+
+ this.checkMethodParse(
+ str.toCharArray(),
+ selectionStart,
+ selectionEnd,
+ expectedCompletionNodeToString,
+ expectedUnitDisplayString,
+ completionIdentifier,
+ expectedReplacedSource,
+ testName);
+}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
index d63b9d0..925533c 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
@@ -17,6 +17,7 @@
* bug 359721 - [options] add command line option for new warning token "resource"
* bug 186342 - [compiler][null] Using annotations for null checking
* bug 365208 - [compiler][batch] command line options for annotation based null analysis
+ * bug 370639 - [compiler][resource] restore the default for resource leak warnings
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -1772,10 +1773,9 @@
" nullable|nonnull|nonnullbydefault annotation types\n" +
" optionally specified using fully qualified names\n" +
" nullDereference + missing null check\n" +
- " nullFields + null analysis for fields\n" +
- " over-ann missing @Override annotation (superclass)\n" +
- " paramAssign assignment to a parameter\n" +
- " pkgDefaultMethod + attempt to override package-default method\n" +
+ " over-ann missing @Override annotation (superclass)\n" +
+ " paramAssign assignment to a parameter\n" +
+ " pkgDefaultMethod + attempt to override package-default method\n" +
" raw + usage of raw type\n" +
" resource + (pot.) unsafe usage of resource of type Closeable\n" +
//OT:
@@ -1912,7 +1912,6 @@
" <option key=\"org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally\" value=\"warning\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.forbiddenReference\" value=\"warning\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock\" value=\"warning\"/>\n" +
- " <option key=\"org.eclipse.jdt.core.compiler.problem.includeFieldsInNullAnalysis\" value=\"disabled\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts\" value=\"disabled\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod\" value=\"warning\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch\" value=\"ignore\"/>\n" +
@@ -1967,7 +1966,7 @@
" <option key=\"org.eclipse.jdt.core.compiler.problem.typeParameterHiding\" value=\"warning\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems\" value=\"enabled\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation\" value=\"warning\"/>\n" +
- " <option key=\"org.eclipse.jdt.core.compiler.problem.unclosedCloseable\" value=\"ignore\"/>\n" +
+ " <option key=\"org.eclipse.jdt.core.compiler.problem.unclosedCloseable\" value=\"warning\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock\" value=\"ignore\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.unhandledWarningToken\" value=\"warning\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.unnecessaryElse\" value=\"ignore\"/>\n" +
@@ -12457,36 +12456,6 @@
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=325342
-// -warn option - regression tests to check option nulLFields
-// Null warnings should be flagged on fields
-public void test311_warn_options() {
- this.runConformTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " Object o;\n" +
- " void foo() {\n" +
- " if (o == null && o.toString() == \"\"){}\n" +
- " else {}\n" +
- " o.toString();\n" + // toString() call above defuses null info, so no warning here
- " }\n" +
- "}\n",
- },
- "\"" + OUTPUT_DIR + File.separator + "X.java\""
- + " -sourcepath \"" + OUTPUT_DIR + "\""
- + " -warn:null,nullFields -proc:none -d \"" + OUTPUT_DIR + "\"",
- "",
- "----------\n" +
- "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 4)\n" +
- " if (o == null && o.toString() == \"\"){}\n" +
- " ^\n" +
- "Potential null pointer access: The field o may be null at this location\n" +
- "----------\n" +
- "1 problem (1 warning)",
- true);
-}
-
-// https://bugs.eclipse.org/bugs/show_bug.cgi?id=325342
// -warn option - regression tests to check option nullAnnot (with args)
// Null warnings because of annotations - custom annotation types used - challenging various kinds of diagnostics
public void test312_warn_options() {
@@ -12690,7 +12659,8 @@
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=325342
// -warn option - regression tests to check option nullAnnot
// Null warnings because of annotations, global nonNullByDefault
-public void test315_warn_options() {
+// DISABLED due to dysfunctional global default after Bug 366063 - Compiler should not add synthetic @NonNull annotations
+public void _test315_warn_options() {
this.runConformTest(
new String[] {
"p/X.java",
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 3d036f9..6a306e4 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
@@ -702,7 +702,6 @@
expectedProblemAttributes.put("MissingEnclosingInstanceForConstructorCall", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
expectedProblemAttributes.put("MissingEnumConstantCase", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("MissingOverrideAnnotation", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
- expectedProblemAttributes.put("MissingNullAnnotationType", new ProblemAttributes(CategorizedProblem.CAT_BUILDPATH));
expectedProblemAttributes.put("MissingOverrideAnnotationForInterfaceMethodImplementation", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
expectedProblemAttributes.put("MissingReturnType", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
expectedProblemAttributes.put("MissingSemiColon", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
@@ -730,7 +729,6 @@
expectedProblemAttributes.put("NonGenericConstructor", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
expectedProblemAttributes.put("NonGenericMethod", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
expectedProblemAttributes.put("NonGenericType", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
- expectedProblemAttributes.put("NonNullFieldComparisonYieldsFalse", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("NonNullLocalVariableComparisonYieldsFalse", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("NonStaticAccessToStaticField", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
expectedProblemAttributes.put("NonStaticAccessToStaticMethod", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
@@ -743,9 +741,6 @@
expectedProblemAttributes.put("NotVisibleField", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
expectedProblemAttributes.put("NotVisibleMethod", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
expectedProblemAttributes.put("NotVisibleType", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
- expectedProblemAttributes.put("NullFieldComparisonYieldsFalse", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
- expectedProblemAttributes.put("NullFieldInstanceofYieldsFalse", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
- expectedProblemAttributes.put("NullFieldReference", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("NullLocalVariableComparisonYieldsFalse", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("NullLocalVariableInstanceofYieldsFalse", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("NullLocalVariableReference", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
@@ -789,7 +784,6 @@
expectedProblemAttributes.put("PotentialHeapPollutionFromVararg", new ProblemAttributes(CategorizedProblem.CAT_UNCHECKED_RAW));
expectedProblemAttributes.put("PotentiallyUnclosedCloseable", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("PotentiallyUnclosedCloseableAtExit", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
- expectedProblemAttributes.put("PotentialNullFieldReference", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("PotentialNullLocalVariableReference", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("PotentialNullMessageSendReference", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("PublicClassMustMatchFileName", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
@@ -799,13 +793,10 @@
expectedProblemAttributes.put("RedefinedArgument", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
expectedProblemAttributes.put("RedefinedLocal", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
expectedProblemAttributes.put("RedundantSpecificationOfTypeArguments", new ProblemAttributes(CategorizedProblem.CAT_UNNECESSARY_CODE));
- expectedProblemAttributes.put("RedundantFieldNullAssignment", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("RedundantLocalVariableNullAssignment", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("RedundantNullAnnotation", new ProblemAttributes(CategorizedProblem.CAT_UNNECESSARY_CODE));
- expectedProblemAttributes.put("RedundantNullCheckOnNonNullField", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("RedundantNullCheckOnNonNullLocalVariable", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("RedundantNullCheckOnNonNullMessageSend", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
- expectedProblemAttributes.put("RedundantNullCheckOnNullField", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("RedundantNullCheckOnNullLocalVariable", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("RedundantNullDefaultAnnotation", new ProblemAttributes(CategorizedProblem.CAT_UNNECESSARY_CODE));
expectedProblemAttributes.put("RedundantNullDefaultAnnotationPackage", new ProblemAttributes(CategorizedProblem.CAT_UNNECESSARY_CODE));
@@ -1486,7 +1477,6 @@
expectedProblemAttributes.put("MissingEnclosingInstance", SKIP);
expectedProblemAttributes.put("MissingEnclosingInstanceForConstructorCall", SKIP);
expectedProblemAttributes.put("MissingEnumConstantCase", new ProblemAttributes(JavaCore.COMPILER_PB_INCOMPLETE_ENUM_SWITCH));
- expectedProblemAttributes.put("MissingNullAnnotationType", SKIP);
expectedProblemAttributes.put("MissingOverrideAnnotation", new ProblemAttributes(JavaCore.COMPILER_PB_MISSING_OVERRIDE_ANNOTATION));
expectedProblemAttributes.put("MissingOverrideAnnotationForInterfaceMethodImplementation", new ProblemAttributes(JavaCore.COMPILER_PB_MISSING_OVERRIDE_ANNOTATION));
expectedProblemAttributes.put("MissingReturnType", SKIP);
@@ -1515,7 +1505,6 @@
expectedProblemAttributes.put("NonGenericConstructor", SKIP);
expectedProblemAttributes.put("NonGenericMethod", SKIP);
expectedProblemAttributes.put("NonGenericType", SKIP);
- expectedProblemAttributes.put("NonNullFieldComparisonYieldsFalse", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
expectedProblemAttributes.put("NonNullLocalVariableComparisonYieldsFalse", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
expectedProblemAttributes.put("NonStaticAccessToStaticField", new ProblemAttributes(JavaCore.COMPILER_PB_STATIC_ACCESS_RECEIVER));
expectedProblemAttributes.put("NonStaticAccessToStaticMethod", new ProblemAttributes(JavaCore.COMPILER_PB_STATIC_ACCESS_RECEIVER));
@@ -1528,9 +1517,6 @@
expectedProblemAttributes.put("NotVisibleField", SKIP);
expectedProblemAttributes.put("NotVisibleMethod", SKIP);
expectedProblemAttributes.put("NotVisibleType", SKIP);
- expectedProblemAttributes.put("NullFieldComparisonYieldsFalse", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
- expectedProblemAttributes.put("NullFieldInstanceofYieldsFalse", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
- expectedProblemAttributes.put("NullFieldReference", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_REFERENCE));
expectedProblemAttributes.put("NullLocalVariableComparisonYieldsFalse", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
expectedProblemAttributes.put("NullLocalVariableInstanceofYieldsFalse", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
expectedProblemAttributes.put("NullLocalVariableReference", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_REFERENCE));
@@ -1574,7 +1560,6 @@
expectedProblemAttributes.put("PotentialHeapPollutionFromVararg", new ProblemAttributes(JavaCore.COMPILER_PB_UNCHECKED_TYPE_OPERATION));
expectedProblemAttributes.put("PotentiallyUnclosedCloseable", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE));
expectedProblemAttributes.put("PotentiallyUnclosedCloseableAtExit", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE));
- expectedProblemAttributes.put("PotentialNullFieldReference", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE));
expectedProblemAttributes.put("PotentialNullLocalVariableReference", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE));
expectedProblemAttributes.put("PotentialNullMessageSendReference", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE));
expectedProblemAttributes.put("PublicClassMustMatchFileName", SKIP);
@@ -1584,13 +1569,10 @@
expectedProblemAttributes.put("RedefinedArgument", SKIP);
expectedProblemAttributes.put("RedefinedLocal", SKIP);
expectedProblemAttributes.put("RedundantSpecificationOfTypeArguments", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_TYPE_ARGUMENTS));
- expectedProblemAttributes.put("RedundantFieldNullAssignment", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
expectedProblemAttributes.put("RedundantLocalVariableNullAssignment", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
expectedProblemAttributes.put("RedundantNullAnnotation", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_ANNOTATION));
- expectedProblemAttributes.put("RedundantNullCheckOnNonNullField", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
expectedProblemAttributes.put("RedundantNullCheckOnNonNullLocalVariable", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
expectedProblemAttributes.put("RedundantNullCheckOnNonNullMessageSend", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
- expectedProblemAttributes.put("RedundantNullCheckOnNullField", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
expectedProblemAttributes.put("RedundantNullCheckOnNullLocalVariable", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
expectedProblemAttributes.put("RedundantNullDefaultAnnotation", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_ANNOTATION));
expectedProblemAttributes.put("RedundantNullDefaultAnnotationPackage", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_ANNOTATION));
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java
index 669345c..4e75828 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2012 IBM Corporation and others.
+ * Copyright (c) 2005, 2011 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
@@ -31,7 +31,7 @@
public class FlowAnalysisTest extends AbstractRegressionTest {
static {
-// TESTS_NAMES = new String[] { "testInnerClassesWithFields1" };
+// TESTS_NAMES = new String[] { "testLocalClassInInitializer1" };
// TESTS_NUMBERS = new int[] { 69 };
}
public FlowAnalysisTest(String name) {
@@ -2496,119 +2496,6 @@
"continue cannot be used outside of a loop\n" +
"----------\n");
}
-// final field in anonymous nested class
-// witness a regression during working on Bug 247564 - [compiler][null] Detecting null field reference
-public void testFinalFieldInNested1() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " void print4() {\n" +
- " for (int i=0; i<4; i++)\n" +
- " new Runnable() {\n" +
- " final String s1local;\n" +
- " public void run() {\n" +
- " s1local.toString();\n" +
- " }\n" +
- " }.run();\n" +
- " }\n" +
- "}\n"
- },
- "----------\n" +
- "1. ERROR in X.java (at line 4)\n" +
- " new Runnable() {\n" +
- " ^^^^^^^^^^\n" +
- "The blank final field s1local may not have been initialized\n" +
- "----------\n");
-}
-// witness a regression during working on Bug 247564 - [compiler][null] Detecting null field reference
-// local variable in inner class triggered IAE in StackMapFrame.addStackItem
-public void testInnerClassesWithFields1() {
- if (this.complianceLevel >= ClassFileConstants.JDK1_6) { // we're specifically interested in StackMap generation
- this.runConformTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " int f1, f2, f3;\n" +
- " class I1 {\n" +
- " int f4;\n" +
- " String m(boolean b) {\n" +
- " String l1 = \"Hello\";\n" +
- " if (b) {\n" +
- " l1 += \" world!\";\n" +
- " } else {\n" +
- " l1 += \" test.\";\n" +
- " }\n" +
- " return l1;\n" +
- " }\n" +
- " }\n" +
- " class I2 {\n" +
- " int f5, f6, f7;\n" +
- " }\n" +
- "}\n"
- },
- "");
- }
-}
-// witness a regression during working on Bug 247564 - [compiler][null] Detecting null field reference
-// local variable in local class triggered IAE in StackMapFrame.addStackItem
-public void testInnerClassesWithFields1a() {
- if (this.complianceLevel >= ClassFileConstants.JDK1_6) { // we're specifically interested in StackMap generation
- this.runConformTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " int f1, f2, f3;\n" +
- " void foo() {\n" +
- " class I1 {\n" +
- " int f4;\n" +
- " String m(boolean b) {\n" +
- " String l1 = \"Hello\";\n" +
- " if (b) {\n" +
- " l1 += \" world!\";\n" +
- " } else {\n" +
- " l1 += \" test.\";\n" +
- " }\n" +
- " return l1;\n" +
- " }\n" +
- " }\n" +
- " }\n" +
- " class I2 {\n" +
- " int f5, f6, f7;\n" +
- " }\n" +
- "}\n"
- },
- "");
- }
-}
-// witness a regression during working on Bug 247564 - [compiler][null] Detecting null field reference
-// final fields in parameterized nested were reported as uninitialized
-public void testInnerClassesWithFields2() {
- if (this.complianceLevel >= ClassFileConstants.JDK1_5) {
- this.runConformTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " static final String f1 = \"f1\";\n" +
- " static final String f2 = \"f2\";\n" +
- " String f3;\n" +
- " X() {\n" +
- " f3 = \"f3\";\n" +
- " }\n" +
- " protected abstract class I<T> {\n" +
- " final String f5, f6;\n" +
- " T f7;\n" +
- " I(T a) {\n" +
- " f5 = \"f5\";\n" +
- " f6 = \"f6\";\n" +
- " f7 = a;\n" +
- " }\n" +
- " }\n" +
- "}\n"
- },
- "");
- }
-}
public static Class testClass() {
return FlowAnalysisTest.class;
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InitializationTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InitializationTests.java
index 0309b5f..23d9410 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InitializationTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InitializationTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010, 2012 IBM Corporation and others.
+ * Copyright (c) 2010, 2011 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
@@ -464,44 +464,6 @@
"The local variable b2 may not have been initialized\n" +
"----------\n");
}
-// https://bugs.eclipse.org/bugs/show_bug.cgi?id=247564
-// Change in the way field id's are calculated should not affect initializations
-public void testBug247564j() {
- this.runNegativeTest(
- new String[] {
- "Z.java",
- "public class Z {\n" +
- " final int field1 = 0;\n" +
- " {\n" +
- " class ZInner {\n" +
- " final int fieldz1;\n" +
- " final int fieldz2 = 0;\n" +
- " }\n" +
- " }\n" +
- "}\n"},
- "----------\n" +
- "1. WARNING in Z.java (at line 4)\n" +
- " class ZInner {\n" +
- " ^^^^^^\n" +
- "The type ZInner is never used locally\n" +
- "----------\n" +
- "2. ERROR in Z.java (at line 4)\n" +
- " class ZInner {\n" +
- " ^^^^^^\n" +
- "The blank final field fieldz1 may not have been initialized\n" +
- "----------\n" +
- "3. WARNING in Z.java (at line 5)\n" +
- " final int fieldz1;\n" +
- " ^^^^^^^\n" +
- "The value of the field ZInner.fieldz1 is not used\n" +
- "----------\n" +
- "4. WARNING in Z.java (at line 6)\n" +
- " final int fieldz2 = 0;\n" +
- " ^^^^^^^\n" +
- "The value of the field ZInner.fieldz2 is not used\n" +
- "----------\n"
- );
-}
public static Class testClass() {
return InitializationTests.class;
}
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 1b1d69c..ebd5df0 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
@@ -53,7 +53,7 @@
// 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[] { "test_redundant_annotation_" };
+// TESTS_NAMES = new String[] { "test_message_send_in_control_structure_02" };
// TESTS_NUMBERS = new int[] { 561 };
// TESTS_RANGE = new int[] { 1, 2049 };
}
@@ -762,6 +762,43 @@
true /* shouldFlush*/);
}
+// assigning potential null to a nonnull local variable - separate decl and assignment
+public void test_nonnull_local_002() {
+ runNegativeTest(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " void foo(boolean b, Object p) {\n" +
+ " @NonNull Object o1;\n" +
+ " o1 = b ? null : new Object();\n" +
+ " @NonNull String o2;\n" +
+ " o2 = \"\";\n" +
+ " o2 = null;\n" +
+ " @NonNull Object o3;\n" +
+ " o3 = p;\n" +
+ " }\n" +
+ "}\n"},
+ "----------\n" +
+ "1. ERROR in X.java (at line 5)\n" +
+ " o1 = b ? null : new Object();\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Type mismatch: required \'@NonNull Object\' but the provided value can be null\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 8)\n" +
+ " o2 = null;\n" +
+ " ^^^^\n" +
+ "Type mismatch: required \'@NonNull String\' but the provided value is null\n" +
+ "----------\n" +
+ "3. WARNING in X.java (at line 10)\n" +
+ " o3 = p;\n" +
+ " ^\n" +
+ "Potential type mismatch: required \'@NonNull Object\' but nullness of the provided value is unknown\n" +
+ "----------\n",
+ this.LIBS,
+ true /* shouldFlush*/);
+}
+
// a method tries to tighten the type specification, super declares parameter o as @Nullable
// other parameters: s is redefined from not constrained to @Nullable which is OK
// third is redefined from not constrained to @NonNull which is bad, too
@@ -1877,15 +1914,14 @@
"----------\n",
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
}
-// using nullness defaulting to nonnull, missing annotation types
+// using nullness defaulting to nonnull, missing annotation types, no longer a problem
public void test_annotation_import_007() {
Map customOptions = getCompilerOptions();
customOptions.put(JavaCore.COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO, JavaCore.ERROR);
customOptions.put(JavaCore.COMPILER_NULLABLE_ANNOTATION_NAME, "org.foo.MayBeNull");
customOptions.put(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "org.foo.MustNotBeNull");
customOptions.put(JavaCore.COMPILER_NONNULL_IS_DEFAULT, JavaCore.ENABLED);
- runNegativeTest(
- true/*shouldFlushOutputDirectory*/,
+ runConformTestWithLibs(
new String[] {
"Lib.java",
"public class Lib {\n" +
@@ -1898,15 +1934,8 @@
" }\n" +
"}\n"
},
- this.LIBS,
customOptions,
- "----------\n" +
- "1. ERROR in Lib.java (at line 1)\n" +
- " public class Lib {\n" +
- " ^\n" +
- "Buildpath problem: the type org.foo.MustNotBeNull, which is configured as a null annotation type, cannot be resolved\n" +
- "----------\n",
- JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
+ "");
}
// a null annotation is illegally used on a class:
@@ -2085,11 +2114,13 @@
public void test_default_nullness_002() {
Map customOptions = getCompilerOptions();
// customOptions.put(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, JavaCore.ERROR);
- customOptions.put(JavaCore.COMPILER_NONNULL_IS_DEFAULT, JavaCore.ENABLED);
+// This option currently does nothing:
+// customOptions.put(JavaCore.COMPILER_NONNULL_IS_DEFAULT, JavaCore.ENABLED);
runNegativeTestWithLibs(
new String[] {
"X.java",
"import org.eclipse.jdt.annotation.*;\n" +
+ "@NonNullByDefault\n" +
"public class X {\n" +
" Object getObject(@Nullable Object o) {\n" +
" return new Object();\n" +
@@ -2097,6 +2128,7 @@
"}\n",
"Y.java",
"import org.eclipse.jdt.annotation.*;\n" +
+ "@NonNullByDefault\n" +
"public class Y extends X {\n" +
" @Override\n" +
" @Nullable Object getObject(Object o) {\n" + // complain illegal return redef and inherited annot is not repeated
@@ -2107,13 +2139,13 @@
customOptions,
// main error:
"----------\n" +
- "1. ERROR in Y.java (at line 4)\n" +
+ "1. ERROR in Y.java (at line 5)\n" +
" @Nullable Object getObject(Object o) {\n" +
" ^^^^^^^^^^^^^^^^\n" +
"The return type is incompatible with the @NonNull return from X.getObject(Object)\n" +
"----------\n" +
// additional error:
- "2. ERROR in Y.java (at line 4)\n" +
+ "2. ERROR in Y.java (at line 5)\n" +
" @Nullable Object getObject(Object o) {\n" +
" ^^^^^^\n" +
"Illegal redefinition of parameter o, inherited method from X declares this parameter as @Nullable\n" +
@@ -2162,7 +2194,7 @@
"Type mismatch: required \'@NonNull Object\' but the provided value can be null\n" +
"----------\n");
}
-// package level default is consumed from package-info.class
+// package level default is consumed from package-info.class, similarly for type level default
public void test_default_nullness_003a() {
Map customOptions = getCompilerOptions();
// customOptions.put(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, JavaCore.ERROR);
@@ -2219,7 +2251,7 @@
"Type mismatch: required \'@NonNull Object\' but the provided value can be null\n" +
"----------\n");
}
-//same as test_default_nullness_003b, but default-induced annotations are combined with explicit ones (not null related)
+// same as test_default_nullness_003a, but default-induced annotations are combined with explicit ones (not null related)
public void test_default_nullness_003b() {
Map customOptions = getCompilerOptions();
runConformTestWithLibs(
@@ -2373,7 +2405,8 @@
"----------\n");
}
// global default nonnull, but return may be null
-public void test_default_nullness_007() {
+// DISABLED due to dysfunctional global default after Bug 366063 - Compiler should not add synthetic @NonNull annotations
+public void _test_default_nullness_007() {
Map customOptions = getCompilerOptions();
// customOptions.put(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, JavaCore.ERROR);
customOptions.put(JavaCore.COMPILER_NONNULL_IS_DEFAULT, JavaCore.ENABLED);
@@ -2828,7 +2861,8 @@
}
// redundant default annotations - package / class / method vs global default
-public void test_redundant_annotation_03() {
+// DISABLED due to dysfunctional global default after Bug 366063 - Compiler should not add synthetic @NonNull annotations
+public void _test_redundant_annotation_03() {
Map customOptions = getCompilerOptions();
customOptions.put(JavaCore.COMPILER_NONNULL_IS_DEFAULT, JavaCore.ENABLED);
runConformTestWithLibs(
@@ -2956,11 +2990,13 @@
public void test_nonnull_var_in_constrol_structure_1() {
Map customOptions = getCompilerOptions();
// customOptions.put(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, JavaCore.ERROR);
- customOptions.put(JavaCore.COMPILER_NONNULL_IS_DEFAULT, JavaCore.ENABLED);
+// This option currently does nothing:
+// customOptions.put(JavaCore.COMPILER_NONNULL_IS_DEFAULT, JavaCore.ENABLED);
runNegativeTestWithLibs(
new String[] {
"X.java",
"import org.eclipse.jdt.annotation.*;\n" +
+ "@NonNullByDefault\n" +
"public class X {\n" +
" void print4(@NonNull String s) {\n" +
" for (int i=0; i<4; i++)\n" +
@@ -2983,22 +3019,22 @@
},
customOptions,
"----------\n" +
- "1. WARNING in X.java (at line 3)\n" +
+ "1. WARNING in X.java (at line 4)\n" +
" void print4(@NonNull String s) {\n" +
" ^^^^^^^^^^^^^^^^^\n" +
"The nullness annotation is redundant with a default that applies to this location\n" +
"----------\n" +
- "2. ERROR in X.java (at line 9)\n" +
+ "2. ERROR in X.java (at line 10)\n" +
" print(s);\n" +
" ^\n" +
"Type mismatch: required \'@NonNull String\' but the provided value can be null\n" +
"----------\n" +
- "3. ERROR in X.java (at line 14)\n" +
+ "3. ERROR in X.java (at line 15)\n" +
" print(s);\n" +
" ^\n" +
"Type mismatch: required \'@NonNull String\' but the provided value can be null\n" +
"----------\n" +
- "4. WARNING in X.java (at line 16)\n" +
+ "4. WARNING in X.java (at line 17)\n" +
" void print(@NonNull String s) {\n" +
" ^^^^^^^^^^^^^^^^^\n" +
"The nullness annotation is redundant with a default that applies to this location\n" +
@@ -3008,11 +3044,13 @@
public void test_nonnull_var_in_constrol_structure_2() {
Map customOptions = getCompilerOptions();
// customOptions.put(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, JavaCore.ERROR);
- customOptions.put(JavaCore.COMPILER_NONNULL_IS_DEFAULT, JavaCore.ENABLED);
+// This option currently does nothing:
+// customOptions.put(JavaCore.COMPILER_NONNULL_IS_DEFAULT, JavaCore.ENABLED);
runNegativeTestWithLibs(
new String[] {
"X.java",
- "import org.eclipse.jdt.annotation.*;\n" +
+ "import org.eclipse.jdt.annotation.*;" +
+ "@NonNullByDefault\n" +
"public class X {\n" +
" void print4(String s) {\n" +
" try { /*empty*/ } finally {\n" +
@@ -3183,6 +3221,54 @@
"Null comparison always yields false: The variable enclosingSourceType cannot be null at this location\n" +
"----------\n");
}
+// Bug 370930 - NonNull annotation not considered for enhanced for loops
+public void test_message_send_in_control_structure_02() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "Bug370930.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "import java.util.*;\n" +
+ "public class Bug370930 {\n" +
+ " void loop(Collection<String> list) {\n" +
+ " for(@NonNull String s: list) { // warning here: insufficient info on elements\n" +
+ " expectNonNull(s); // no warning here\n" +
+ " }\n" +
+ " }\n" +
+ " \n" +
+ " void expectNonNull(@NonNull String s) {}\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. WARNING in Bug370930.java (at line 5)\n" +
+ " for(@NonNull String s: list) { // warning here: insufficient info on elements\n" +
+ " ^^^^\n" +
+ "Potential type mismatch: required \'@NonNull String\' but nullness of the provided value is unknown\n" +
+ "----------\n");
+}
+//Bug 370930 - NonNull annotation not considered for enhanced for loops
+public void test_message_send_in_control_structure_03() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "Bug370930.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "import java.util.*;\n" +
+ "public class Bug370930 {\n" +
+ " void loop(Collection<String> list) {\n" +
+ " for(@Nullable String s: list) {\n" +
+ " expectNonNull(s); // warning here\n" +
+ " }\n" +
+ " }\n" +
+ " \n" +
+ " void expectNonNull(@NonNull String s) {}\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in Bug370930.java (at line 6)\n" +
+ " expectNonNull(s); // warning here\n" +
+ " ^\n" +
+ "Type mismatch: required \'@NonNull String\' but the provided value can be null\n" +
+ "----------\n");
+}
public void test_assignment_expression_1() {
Map customOptions = getCompilerOptions();
// customOptions.put(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, JavaCore.ERROR);
@@ -3217,11 +3303,13 @@
public void test_nesting_1() {
Map customOptions = getCompilerOptions();
// customOptions.put(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, JavaCore.ERROR);
- customOptions.put(JavaCore.COMPILER_NONNULL_IS_DEFAULT, JavaCore.ENABLED);
+// This option currently does nothing:
+// customOptions.put(JavaCore.COMPILER_NONNULL_IS_DEFAULT, JavaCore.ENABLED);
runNegativeTestWithLibs(
new String[] {
"X.java",
"import org.eclipse.jdt.annotation.*;\n" +
+ "@NonNullByDefault\n" +
"public class X {\n" +
" void print4(final String s1) {\n" +
" for (int i=0; i<3; i++)\n" +
@@ -3256,12 +3344,12 @@
},
customOptions,
"----------\n" +
- "1. ERROR in X.java (at line 15)\n" +
+ "1. ERROR in X.java (at line 16)\n" +
" print(s2);\n" +
" ^^\n" +
"Type mismatch: required \'@NonNull String\' but the provided value can be null\n" +
"----------\n" +
- "2. ERROR in X.java (at line 24)\n" +
+ "2. ERROR in X.java (at line 25)\n" +
" @NonNull String s3R = s3;\n" +
" ^^\n" +
"Type mismatch: required \'@NonNull String\' but the provided value can be null\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTests.java
index 2bb4c61..95af131 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2011 IBM Corporation and others.
+ * Copyright (c) 2005, 2010 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
@@ -37,7 +37,6 @@
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
/**
* A tests series especially meant to validate the internals of our null
@@ -1084,21 +1083,18 @@
return copy;
}
-public void markAsDefinitelyNonNull(VariableBinding local) {
- int position = local.getAnalysisId(this.maxFieldCount);
- grow(position);
+public void markAsDefinitelyNonNull(LocalVariableBinding local) {
+ grow(local.id + this.maxFieldCount);
super.markAsDefinitelyNonNull(local);
}
-public void markAsDefinitelyNull(VariableBinding local) {
- int position = local.getAnalysisId(this.maxFieldCount);
- grow(position);
+public void markAsDefinitelyNull(LocalVariableBinding local) {
+ grow(local.id + this.maxFieldCount);
super.markAsDefinitelyNull(local);
}
-public void markAsDefinitelyUnknown(VariableBinding local) {
- int position = local.getAnalysisId(this.maxFieldCount);
- grow(position);
+public void markAsDefinitelyUnknown(LocalVariableBinding local) {
+ grow(local.id + this.maxFieldCount);
super.markAsDefinitelyUnknown(local);
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java
index 6e8dfa6..31f6af6 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java
@@ -49,7 +49,7 @@
// Only the highest compliance level is run; add the VM argument
// -Dcompliance=1.4 (for example) to lower it if needed
static {
-// TESTS_NAMES = new String[] { "testBug247564n_3" };
+// TESTS_NAMES = new String[] { "testBug360328" };
// TESTS_NUMBERS = new int[] { 561 };
// TESTS_RANGE = new int[] { 1, 2049 };
}
@@ -72,7 +72,6 @@
defaultOptions.put(CompilerOptions.OPTION_ReportRedundantNullCheck, CompilerOptions.ERROR);
defaultOptions.put(CompilerOptions.OPTION_ReportRawTypeReference, CompilerOptions.IGNORE);
defaultOptions.put(CompilerOptions.OPTION_IncludeNullInfoFromAsserts, CompilerOptions.ENABLED);
- defaultOptions.put(CompilerOptions.OPTION_IncludeFieldsInNullAnalysis, CompilerOptions.ENABLED);
}
return defaultOptions;
}
@@ -110,12 +109,13 @@
" o.toString();\n" +
" }\n" +
"}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 5)\n" +
- " o.toString();\n" +
- " ^\n" +
- "Potential null pointer access: The field o may be null at this location\n" +
- "----------\n"
+ ""
+// "----------\n" +
+// "1. ERROR in X.java (at line 5)\n" +
+// " o.toString();\n" +
+// " ^\n" +
+// "The field o is likely null; it was either set to null or checked for null when last used\n" +
+// "----------\n"
);
}
@@ -346,12 +346,13 @@
" this.o.toString();\n" +
" }\n" +
"}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 5)\n" +
- " this.o.toString();\n" +
- " ^\n" +
- "Potential null pointer access: The field o may be null at this location\n" +
- "----------\n"
+ ""
+// "----------\n" +
+// "1. ERROR in X.java (at line 5)\n" +
+// " this.o.toString();\n" +
+// " ^^^^^^\n" +
+// "The field o is likely null; it was either set to null or checked for null when last used\n" +
+// "----------\n"
);
}
@@ -367,12 +368,13 @@
" o.toString();\n" +
" }\n" +
"}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 5)\n" +
- " o.toString();\n" +
- " ^\n" +
- "Potential null pointer access: The field o may be null at this location\n" +
- "----------\n"
+ ""
+// "----------\n" +
+// "1. ERROR in X.java (at line 5)\n" +
+// " o.toString();\n" +
+// " ^\n" +
+// "The field o is likely null; it was either set to null or checked for null when last used\n" +
+// "----------\n"
);
}
@@ -422,12 +424,13 @@
" }\n" +
" }\n" +
"}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 6)\n" +
- " X.this.o.toString();\n" +
- " ^\n" +
- "Potential null pointer access: The field o may be null at this location\n" +
- "----------\n"
+ ""
+// "----------\n" +
+// "1. ERROR in X.java (at line 6)\n" +
+// " X.this.o.toString();\n" +
+// " ^^^^^^^^\n" +
+// "The field o is likely null; it was either set to null or checked for null when last used\n" +
+// "----------\n"
);
}
@@ -446,12 +449,13 @@
" }\n" +
" void bar() {/* */}\n" +
"}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 5)\n" +
- " o.toString();\n" +
- " ^\n" +
- "Potential null pointer access: The field o may be null at this location\n" +
- "----------\n"
+ ""
+// "----------\n" +
+// "1. ERROR in X.java (at line 5)\n" +
+// " o.toString();\n" +
+// " ^\n" +
+// "The field o is likely null; it was either set to null or checked for null when last used\n" +
+// "----------\n"
);
}
@@ -3095,7 +3099,7 @@
// null analysis -- while
public void test0413_while_unknown_field() {
- this.runNegativeTest(
+ this.runConformTest(
new String[] {
"X.java",
"public class X {\n" +
@@ -3107,12 +3111,7 @@
" o.toString();\n" +
" }\n" +
"}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 7)\n" +
- " o.toString();\n" +
- " ^\n" +
- "Potential null pointer access: The field o may be null at this location\n" +
- "----------\n");
+ "");
}
// null analysis -- while
@@ -15456,2709 +15455,4 @@
"",/* expected error */
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
}
-
-// null analysis -- simple case for field
-public void testBug247564a() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " Object o;\n" +
- " void foo() {\n" +
- " if (o == null && o.toString() == \"\"){}\n" +
- " else {}\n" +
- " o.toString();\n" + // toString() call above defuses null info, so no warning here
- " }\n" +
- "}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 4)\n" +
- " if (o == null && o.toString() == \"\"){}\n" +
- " ^\n" +
- "Potential null pointer access: The field o may be null at this location\n" +
- "----------\n"
- );
-}
-
-// null analysis -- simple case for field
-// no redundant null check warnings should be obtained since value of field
-// may be changed in another thread.
-public void testBug247564a_1() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " Object o;\n" +
- " void foo() {\n" +
- " o = null;" +
- " if (o == null){}\n" +
- " if (o != null){}\n" +
- " o.toString();\n" + // warn here
- " }\n" +
- "}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 6)\n" +
- " o.toString();\n" +
- " ^\n" +
- "Potential null pointer access: The field o may be null at this location\n" +
- "----------\n"
- );
-}
-
-// null analysis -- simple case for field
-public void testBug247564a_2() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " Object o;\n" +
- " void foo() {\n" +
- " if (o == null){\n" + // o is null inside the if block
- " o.toString();\n" +
- " }\n" +
- " }\n" +
- "}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 5)\n" +
- " o.toString();\n" +
- " ^\n" +
- "Potential null pointer access: The field o may be null at this location\n" +
- "----------\n"
- );
-}
-
-// null analysis -- simple case for field
-// null info from one method should not be present in the other (for instance fields)
-public void testBug247564a_3() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " Object o;\n" +
- " void foo() {\n" +
- " o = null;\n" +
- " }\n" +
- " void foo1() {\n" +
- " o.toString();\n" +
- " }\n" +
- "}\n"},
- ""
- );
-}
-
-//null analysis -- simple case for field
-public void testBug247564a_4() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " Object o;\n" +
- " int foo() {\n" +
- " if (o != null && o.toString() == \"\") {\n" +
- " } else {\n" +
- " }\n" +
- " return o.hashCode();\n" + // the above check has shed doubts so give a warning here
- " }\n" +
- "}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 7)\n" +
- " return o.hashCode();\n" +
- " ^\n" +
- "Potential null pointer access: The field o may be null at this location\n" +
- "----------\n"
- );
-}
-
-// null analysis -- field accessed inside control structure
-// from https://bugs.eclipse.org/bugs/show_bug.cgi?id=247564#c121
-public void testBug247564a_5() {
- this.runConformTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " private Object field;\n" +
- " void goo(Object var) throws Exception{\n" +
- " if (field != null) field.hashCode();\n" +
- " int i = 20;\n" +
- " while (i<10) {\n" +
- " if (field == null) { \n" +
- " field = new Object();\n" +
- " }\n" +
- " field.toString(); // Wrong outcome was: Pot. NPE\n" +
- " i--;\n" +
- " }\n" +
- " }\n" +
- "}\n"},
- ""
- );
-}
-
-// null analysis -- simple case for static final field
-// once dereferenced, treat as non null. Consistent with local variables.
-public void testBug247564b() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " static final Object o = null;\n" +
- " static final Object o1 = new Object();\n" +
- " void foo() {\n" +
- " if (o.toString() == \"\") {}\n" +
- " if (o == null) {}\n" +
- " if (o != null) {}\n" +
- " if (o1 == null) {}\n" +
- " if (o1 != null) {}\n" +
- " }\n" +
- "}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 5)\n" +
- " if (o.toString() == \"\") {}\n" +
- " ^\n" +
- "Null pointer access: The field o can only be null at this location\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 6)\n" +
- " if (o == null) {}\n" +
- " ^\n" +
- "Null comparison always yields false: The field o cannot be null at this location\n" +
- "----------\n" +
- "3. WARNING in X.java (at line 6)\n" +
- " if (o == null) {}\n" +
- " ^^\n" +
- "Dead code\n" +
- "----------\n" +
- "4. ERROR in X.java (at line 7)\n" +
- " if (o != null) {}\n" +
- " ^\n" +
- "Redundant null check: The field o cannot be null at this location\n" +
- "----------\n" +
- "5. ERROR in X.java (at line 8)\n" +
- " if (o1 == null) {}\n" +
- " ^^\n" +
- "Null comparison always yields false: The field o1 cannot be null at this location\n" +
- "----------\n" +
- "6. WARNING in X.java (at line 8)\n" +
- " if (o1 == null) {}\n" +
- " ^^\n" +
- "Dead code\n" +
- "----------\n" +
- "7. ERROR in X.java (at line 9)\n" +
- " if (o1 != null) {}\n" +
- " ^^\n" +
- "Redundant null check: The field o1 cannot be null at this location\n" +
- "----------\n"
- );
-}
-
-// null analysis -- simple case for static final field
-public void testBug247564b_1() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " static final Object o;\n" +
- " static final Object o1;\n" +
- " static {\n" +
- " o = null;\n" +
- " o1 = new Object();\n" +
- " }\n" +
- " void foo() {\n" +
- " if (o.toString() == \"\") {}\n" +
- " if (o == null) {}\n" +
- " if (o != null) {}\n" +
- " if (o1 == null) {}\n" +
- " if (o1 != null) {}\n" +
- " }\n" +
- "}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 9)\n" +
- " if (o.toString() == \"\") {}\n" +
- " ^\n" +
- "Null pointer access: The field o can only be null at this location\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 10)\n" +
- " if (o == null) {}\n" +
- " ^\n" +
- "Null comparison always yields false: The field o cannot be null at this location\n" +
- "----------\n" +
- "3. WARNING in X.java (at line 10)\n" +
- " if (o == null) {}\n" +
- " ^^\n" +
- "Dead code\n" +
- "----------\n" +
- "4. ERROR in X.java (at line 11)\n" +
- " if (o != null) {}\n" +
- " ^\n" +
- "Redundant null check: The field o cannot be null at this location\n" +
- "----------\n" +
- "5. ERROR in X.java (at line 12)\n" +
- " if (o1 == null) {}\n" +
- " ^^\n" +
- "Null comparison always yields false: The field o1 cannot be null at this location\n" +
- "----------\n" +
- "6. WARNING in X.java (at line 12)\n" +
- " if (o1 == null) {}\n" +
- " ^^\n" +
- "Dead code\n" +
- "----------\n" +
- "7. ERROR in X.java (at line 13)\n" +
- " if (o1 != null) {}\n" +
- " ^^\n" +
- "Redundant null check: The field o1 cannot be null at this location\n" +
- "----------\n"
- );
-}
-
-// null analysis -- simple case for static final field
-public void testBug247564b_1_2() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- "Object field0, \n" +
- "field1, field2, field3, field4, \n" +
- "field5, field6, field7, field8, \n" +
- "field9, field10, field11, field12, \n" +
- "field13, field14, field15, field16, \n" +
- "field17, field18, field19, field20, \n" +
- "field21, field22, field23, field24, \n" +
- "field25, field26, field27, field28, \n" +
- "field29, field30, field31, field32, \n" +
- "field33, field34, field35, field36, \n" +
- "field37, field38, field39, field40, \n" +
- "field41, field42, field43, field44, \n" +
- "field45, field46, field47, field48, \n" +
- "field49, field50, field51, field52, \n" +
- "field53, field54, field55, field56, \n" +
- "field57, field58, field59, field60, \n" +
- "field61, field62, field63, field64, \n" +
- "field65, field66, field67, field68, \n" +
- "field69, field70, field71, field72, \n" +
- "field73, field74, field75, field76, \n" +
- "field77, field78, field79, field80, \n" +
- "field81, field82, field83, field84, \n" +
- "field85, field86, field87, field88, \n" +
- "field89, field90, field91, field92, \n" +
- "field93, field94, field95, field96, \n" +
- "field97, field98, field99;\n" +
- " static final Object o;\n" +
- " static final Object o1;\n" +
- " static {\n" +
- " o = null;\n" +
- " o1 = new Object();\n" +
- " }\n" +
- " void foo() {\n" +
- " if (o.toString() == \"\") {}\n" +
- " if (o == null) {}\n" +
- " if (o != null) {}\n" +
- " if (o1 == null) {}\n" +
- " if (o1 != null) {}\n" +
- " }\n" +
- "}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 35)\n" +
- " if (o.toString() == \"\") {}\n" +
- " ^\n" +
- "Null pointer access: The field o can only be null at this location\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 36)\n" +
- " if (o == null) {}\n" +
- " ^\n" +
- "Null comparison always yields false: The field o cannot be null at this location\n" +
- "----------\n" +
- "3. WARNING in X.java (at line 36)\n" +
- " if (o == null) {}\n" +
- " ^^\n" +
- "Dead code\n" +
- "----------\n" +
- "4. ERROR in X.java (at line 37)\n" +
- " if (o != null) {}\n" +
- " ^\n" +
- "Redundant null check: The field o cannot be null at this location\n" +
- "----------\n" +
- "5. ERROR in X.java (at line 38)\n" +
- " if (o1 == null) {}\n" +
- " ^^\n" +
- "Null comparison always yields false: The field o1 cannot be null at this location\n" +
- "----------\n" +
- "6. WARNING in X.java (at line 38)\n" +
- " if (o1 == null) {}\n" +
- " ^^\n" +
- "Dead code\n" +
- "----------\n" +
- "7. ERROR in X.java (at line 39)\n" +
- " if (o1 != null) {}\n" +
- " ^^\n" +
- "Redundant null check: The field o1 cannot be null at this location\n" +
- "----------\n"
- );
-}
-
-// null analysis -- case for static final field initialized inside static block with different values
-// checked before use
-public void testBug247564b_2() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " static final Object o;\n" +
- " static final Object o1 = new Object();\n" +
- " static {\n" +
- " if (o1.hashCode() == 2){\n" +
- " o = new Object();\n" +
- " } else {\n" +
- " o = null;\n" +
- " }\n" +
- " }\n" +
- " void foo1() {\n" +
- " if (o == null) \n" +
- " return;\n" +
- " o.toString();\n" + // cant be null for sure, dont complain
- " }\n" +
- "}\n"},
- ""
- );
-}
-
-// null analysis -- case for static final field initialized inside static block with different values
-// checked before use
-public void testBug247564b_2_2() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- "Object field0, \n" +
- "field1, field2, field3, field4, \n" +
- "field5, field6, field7, field8, \n" +
- "field9, field10, field11, field12, \n" +
- "field13, field14, field15, field16, \n" +
- "field17, field18, field19, field20, \n" +
- "field21, field22, field23, field24, \n" +
- "field25, field26, field27, field28, \n" +
- "field29, field30, field31, field32, \n" +
- "field33, field34, field35, field36, \n" +
- "field37, field38, field39, field40, \n" +
- "field41, field42, field43, field44, \n" +
- "field45, field46, field47, field48, \n" +
- "field49, field50, field51, field52, \n" +
- "field53, field54, field55, field56, \n" +
- "field57, field58, field59, field60, \n" +
- "field61, field62, field63, field64, \n" +
- "field65, field66, field67, field68, \n" +
- "field69, field70, field71, field72, \n" +
- "field73, field74, field75, field76, \n" +
- "field77, field78, field79, field80, \n" +
- "field81, field82, field83, field84, \n" +
- "field85, field86, field87, field88, \n" +
- "field89, field90, field91, field92, \n" +
- "field93, field94, field95, field96, \n" +
- "field97, field98, field99;\n" +
- " static final Object o;\n" +
- " static final Object o1 = new Object();\n" +
- " static {\n" +
- " if (o1.hashCode() == 2){\n" +
- " o = new Object();\n" +
- " } else {\n" +
- " o = null;\n" +
- " }\n" +
- " }\n" +
- " void foo1() {\n" +
- " if (o == null) \n" +
- " return;\n" +
- " o.toString();\n" + // cant be null for sure, dont complain
- " }\n" +
- "}\n"},
- ""
- );
-}
-
-// null analysis -- case for static final field initialized inside static block with different values
-// Check pot. NPE case for constant fields
-// Once dereferenced, treat as non null. Just like locals.
-public void testBug247564b_3() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " static final Object o;\n" +
- " static final Object o1 = new Object();\n" +
- " static {\n" +
- " if (o1.hashCode() == 2){\n" +
- " o = new Object();\n" +
- " } else {\n" +
- " o = null;\n" +
- " }\n" +
- " }\n" +
- " void foo() {\n" +
- " if (o.toString() == \"\") {}\n" +
- " if (o == null) {}\n" +
- " if (o != null) {}\n" +
- " }\n" +
- "}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 12)\n" +
- " if (o.toString() == \"\") {}\n" +
- " ^\n" +
- "Potential null pointer access: The field o may be null at this location\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 13)\n" +
- " if (o == null) {}\n" +
- " ^\n" +
- "Null comparison always yields false: The field o cannot be null at this location\n" +
- "----------\n" +
- "3. WARNING in X.java (at line 13)\n" +
- " if (o == null) {}\n" +
- " ^^\n" +
- "Dead code\n" +
- "----------\n" +
- "4. ERROR in X.java (at line 14)\n" +
- " if (o != null) {}\n" +
- " ^\n" +
- "Redundant null check: The field o cannot be null at this location\n" +
- "----------\n"
- );
-}
-
-// null analysis -- case for static final field initialized inside static block with different values
-// Check pot. NPE case for constant fields
-// Once dereferenced, treat as non null. Just like locals.
-public void testBug247564b_3_2() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- "Object field0, \n" +
- "field1, field2, field3, field4, \n" +
- "field5, field6, field7, field8, \n" +
- "field9, field10, field11, field12, \n" +
- "field13, field14, field15, field16, \n" +
- "field17, field18, field19, field20, \n" +
- "field21, field22, field23, field24, \n" +
- "field25, field26, field27, field28, \n" +
- "field29, field30, field31, field32, \n" +
- "field33, field34, field35, field36, \n" +
- "field37, field38, field39, field40, \n" +
- "field41, field42, field43, field44, \n" +
- "field45, field46, field47, field48, \n" +
- "field49, field50, field51, field52, \n" +
- "field53, field54, field55, field56, \n" +
- "field57, field58, field59, field60, \n" +
- "field61, field62, field63, field64, \n" +
- "field65, field66, field67, field68, \n" +
- "field69, field70, field71, field72, \n" +
- "field73, field74, field75, field76, \n" +
- "field77, field78, field79, field80, \n" +
- "field81, field82, field83, field84, \n" +
- "field85, field86, field87, field88, \n" +
- "field89, field90, field91, field92, \n" +
- "field93, field94, field95, field96, \n" +
- "field97, field98, field99;\n" +
- " static final Object o;\n" +
- " static final Object o1 = new Object();\n" +
- " static {\n" +
- " if (o1.hashCode() == 2){\n" +
- " o = new Object();\n" +
- " } else {\n" +
- " o = null;\n" +
- " }\n" +
- " }\n" +
- " void foo() {\n" +
- " if (o.toString() == \"\") {}\n" +
- " if (o == null) {}\n" +
- " if (o != null) {}\n" +
- " }\n" +
- "}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 38)\n" +
- " if (o.toString() == \"\") {}\n" +
- " ^\n" +
- "Potential null pointer access: The field o may be null at this location\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 39)\n" +
- " if (o == null) {}\n" +
- " ^\n" +
- "Null comparison always yields false: The field o cannot be null at this location\n" +
- "----------\n" +
- "3. WARNING in X.java (at line 39)\n" +
- " if (o == null) {}\n" +
- " ^^\n" +
- "Dead code\n" +
- "----------\n" +
- "4. ERROR in X.java (at line 40)\n" +
- " if (o != null) {}\n" +
- " ^\n" +
- "Redundant null check: The field o cannot be null at this location\n" +
- "----------\n"
- );
-}
-
-// null analysis -- case for static final field initialized inside static block with different values
-// checked before use
-public void testBug247564b_4() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " static final Object o;\n" +
- " static final Object o1 = new Object();\n" +
- " static {\n" +
- " if (o1.hashCode() == 2){\n" +
- " o = new Object();\n" +
- " } else {\n" +
- " o = null;\n" +
- " }\n" +
- " }\n" +
- " void foo1() {\n" +
- " if (o == null) {\n" +
- " o.toString(); // danger\n" +
- " return;\n" +
- " }\n" +
- " o.toString(); // safe\n" +
- " }\n" +
- " void foo2() {\n" +
- " if (o != null) {\n" +
- " o.toString(); // safe (2)\n" +
- " }\n" +
- " o.toString(); // uncertain\n" +
- " }\n" +
- "}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 13)\n" +
- " o.toString(); // danger\n" +
- " ^\n" +
- "Null pointer access: The field o can only be null at this location\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 22)\n" +
- " o.toString(); // uncertain\n" +
- " ^\n" +
- "Potential null pointer access: The field o may be null at this location\n" +
- "----------\n"
- );
-}
-
-// null analysis -- case for static final field initialized inside static block with different values
-// checked before use
-public void testBug247564b_4_2() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- "Object field0, \n" +
- "field1, field2, field3, field4, \n" +
- "field5, field6, field7, field8, \n" +
- "field9, field10, field11, field12, \n" +
- "field13, field14, field15, field16, \n" +
- "field17, field18, field19, field20, \n" +
- "field21, field22, field23, field24, \n" +
- "field25, field26, field27, field28, \n" +
- "field29, field30, field31, field32, \n" +
- "field33, field34, field35, field36, \n" +
- "field37, field38, field39, field40, \n" +
- "field41, field42, field43, field44, \n" +
- "field45, field46, field47, field48, \n" +
- "field49, field50, field51, field52, \n" +
- "field53, field54, field55, field56, \n" +
- "field57, field58, field59, field60, \n" +
- "field61, field62, field63, field64, \n" +
- "field65, field66, field67, field68, \n" +
- "field69, field70, field71, field72, \n" +
- "field73, field74, field75, field76, \n" +
- "field77, field78, field79, field80, \n" +
- "field81, field82, field83, field84, \n" +
- "field85, field86, field87, field88, \n" +
- "field89, field90, field91, field92, \n" +
- "field93, field94, field95, field96, \n" +
- "field97, field98, field99;\n" +
- " static final Object o;\n" +
- " static final Object o1 = new Object();\n" +
- " static {\n" +
- " if (o1.hashCode() == 2){\n" +
- " o = new Object();\n" +
- " } else {\n" +
- " o = null;\n" +
- " }\n" +
- " }\n" +
- " void foo1() {\n" +
- " if (o == null) {\n" +
- " o.toString(); // danger\n" +
- " return;\n" +
- " }\n" +
- " o.toString(); // safe\n" +
- " }\n" +
- " void foo2() {\n" +
- " if (o != null) {\n" +
- " o.toString(); // safe (2)\n" +
- " }\n" +
- " o.toString(); // uncertain\n" +
- " }\n" +
- "}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 39)\n" +
- " o.toString(); // danger\n" +
- " ^\n" +
- "Null pointer access: The field o can only be null at this location\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 48)\n" +
- " o.toString(); // uncertain\n" +
- " ^\n" +
- "Potential null pointer access: The field o may be null at this location\n" +
- "----------\n"
- );
-}
-
-// null analysis -- case for static final field initialized inside static block with different values
-// check if the resetting works properly i.e. null status for constant fields should not be
-// reset on method calls.
-public void testBug247564b_5() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " static final Object o;\n" +
- " static final Object o1 = new Object();\n" +
- " static final Object o2 = new Object();\n" +
- " static {\n" +
- " if (o1.hashCode() == 2){\n" +
- " o = new Object();\n" +
- " } else {\n" +
- " o = null;\n" +
- " }\n" +
- " }\n" +
- " void foo1() {\n" +
- " final Object local = null;\n" +
- " if (local == null) {\n" +
- " local.toString();\n" +
- " }\n" +
- " local.toString();\n" +
- " if (o == null) {\n" + // don't know o's nullness, so silent
- " o.toString();\n" + // report NPE
- " }\n" +
- " local.toString();\n" + // try to diffuse status for o / o2
- " o.toString();\n" + // already reported NPE above. So silent. Same behaviour as 'local'
- " if (o2 == null) {\n" + // report always false null check
- " o2.toString();\n" + // dead code
- " }\n" +
- " o2.toString();" +
- " }\n" +
- "}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 14)\n" +
- " if (local == null) {\n" +
- " ^^^^^\n" +
- "Redundant null check: The variable local can only be null at this location\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 15)\n" +
- " local.toString();\n" +
- " ^^^^^\n" +
- "Null pointer access: The variable local can only be null at this location\n" +
- "----------\n" +
- "3. ERROR in X.java (at line 19)\n" +
- " o.toString();\n" +
- " ^\n" +
- "Null pointer access: The field o can only be null at this location\n" +
- "----------\n" +
- "4. ERROR in X.java (at line 23)\n" +
- " if (o2 == null) {\n" +
- " ^^\n" +
- "Null comparison always yields false: The field o2 cannot be null at this location\n" +
- "----------\n" +
- "5. WARNING in X.java (at line 23)\n" +
- " if (o2 == null) {\n" +
- " o2.toString();\n" +
- " }\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Dead code\n" +
- "----------\n"
- );
-}
-
-// null analysis -- case for static final field initialized inside static block with different values
-// check if the resetting works properly i.e. null status for constant fields should not be
-// reset on method calls. This test is for constructors
-public void testBug247564b_6() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " static final Object o;\n" +
- " static final Object o1 = new Object();\n" +
- " static final Object o2 = new Object();\n" +
- " static {\n" +
- " if (o1.hashCode() == 2){\n" +
- " o = new Object();\n" +
- " } else {\n" +
- " o = null;\n" +
- " }\n" +
- " }\n" +
- " public X() {\n" +
- " final Object local = null;\n" +
- " if (local == null) {\n" +
- " local.toString();\n" +
- " }\n" +
- " local.toString();\n" +
- " if (o == null) {\n" + // don't know o's nullness, so silent
- " o.toString();\n" + // report NPE
- " }\n" +
- " local.toString();\n" + // try to diffuse status for o / o2
- " o.toString();\n" + // already reported NPE above. So silent. Same behaviour as 'local'
- " if (o2 == null) {\n" + // report always false null check
- " o2.toString();\n" + // dead code
- " }\n" +
- " o2.toString();" +
- " }\n" +
- "}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 14)\n" +
- " if (local == null) {\n" +
- " ^^^^^\n" +
- "Redundant null check: The variable local can only be null at this location\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 15)\n" +
- " local.toString();\n" +
- " ^^^^^\n" +
- "Null pointer access: The variable local can only be null at this location\n" +
- "----------\n" +
- "3. ERROR in X.java (at line 19)\n" +
- " o.toString();\n" +
- " ^\n" +
- "Null pointer access: The field o can only be null at this location\n" +
- "----------\n" +
- "4. ERROR in X.java (at line 23)\n" +
- " if (o2 == null) {\n" +
- " ^^\n" +
- "Null comparison always yields false: The field o2 cannot be null at this location\n" +
- "----------\n" +
- "5. WARNING in X.java (at line 23)\n" +
- " if (o2 == null) {\n" +
- " o2.toString();\n" +
- " }\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Dead code\n" +
- "----------\n"
- );
-}
-
-// null analysis -- case for static final field initialized inside static block with different values
-// check if the resetting works properly i.e. null status for constant fields should not be
-// reset on method calls. This test is for constructors
-public void testBug247564b_6_2() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- "Object field0, \n" +
- "field1, field2, field3, field4, \n" +
- "field5, field6, field7, field8, \n" +
- "field9, field10, field11, field12, \n" +
- "field13, field14, field15, field16, \n" +
- "field17, field18, field19, field20, \n" +
- "field21, field22, field23, field24, \n" +
- "field25, field26, field27, field28, \n" +
- "field29, field30, field31, field32, \n" +
- "field33, field34, field35, field36, \n" +
- "field37, field38, field39, field40, \n" +
- "field41, field42, field43, field44, \n" +
- "field45, field46, field47, field48, \n" +
- "field49, field50, field51, field52, \n" +
- "field53, field54, field55, field56, \n" +
- "field57, field58, field59, field60, \n" +
- "field61, field62, field63, field64, \n" +
- "field65, field66, field67, field68, \n" +
- "field69, field70, field71, field72, \n" +
- "field73, field74, field75, field76, \n" +
- "field77, field78, field79, field80, \n" +
- "field81, field82, field83, field84, \n" +
- "field85, field86, field87, field88, \n" +
- "field89, field90, field91, field92, \n" +
- "field93, field94, field95, field96, \n" +
- "field97, field98, field99;\n" +
- " static final Object o;\n" +
- " static final Object o1 = new Object();\n" +
- " static final Object o2 = new Object();\n" +
- " static {\n" +
- " if (o1.hashCode() == 2){\n" +
- " o = new Object();\n" +
- " } else {\n" +
- " o = null;\n" +
- " }\n" +
- " }\n" +
- " public X() {\n" +
- " final Object local = null;\n" +
- " if (local == null) {\n" +
- " local.toString();\n" +
- " }\n" +
- " local.toString();\n" +
- " if (o == null) {\n" + // don't know o's nullness, so silent
- " o.toString();\n" + // report NPE
- " }\n" +
- " local.toString();\n" + // try to diffuse status for o / o2
- " o.toString();\n" + // already reported NPE above. So silent. Same behaviour as 'local'
- " if (o2 == null) {\n" + // report always false null check
- " o2.toString();\n" + // dead code
- " }\n" +
- " o2.toString();" +
- " }\n" +
- "}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 40)\n" +
- " if (local == null) {\n" +
- " ^^^^^\n" +
- "Redundant null check: The variable local can only be null at this location\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 41)\n" +
- " local.toString();\n" +
- " ^^^^^\n" +
- "Null pointer access: The variable local can only be null at this location\n" +
- "----------\n" +
- "3. ERROR in X.java (at line 45)\n" +
- " o.toString();\n" +
- " ^\n" +
- "Null pointer access: The field o can only be null at this location\n" +
- "----------\n" +
- "4. ERROR in X.java (at line 49)\n" +
- " if (o2 == null) {\n" +
- " ^^\n" +
- "Null comparison always yields false: The field o2 cannot be null at this location\n" +
- "----------\n" +
- "5. WARNING in X.java (at line 49)\n" +
- " if (o2 == null) {\n" +
- " o2.toString();\n" +
- " }\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Dead code\n" +
- "----------\n"
- );
-}
-
-// null analysis -- case for static final field initialized inside static block with different values
-// check if the resetting works properly i.e. null status for constant fields should not be
-// reset on method calls. Also, null info of constant field from static block is available in methods
-public void testBug247564b_7() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " static final Object o;\n" +
- " static final Object o1 = null;\n" +
- " static final Object o2 = new Object();\n" +
- " static {\n" +
- " if (o1.hashCode() == 2){\n" + // report NPE. But dereferenced here, so later it should be treated as non null
- " o = new Object();\n" +
- " } else {\n" +
- " o = null;\n" +
- " }\n" +
- " }\n" +
- " void foo1() {\n" +
- " final Object local = null;\n" +
- " if (local == null) {\n" +
- " local.toString();\n" +
- " }\n" +
- " local.toString();\n" +
- " if (o1 == null) {\n" + // can't be null, was dereferenced in static initializer
- " o1.toString();\n" + // dead
- " }\n" +
- " local.toString();\n" + // try to diffuse status for o1 / o2
- " o1.toString();\n" + // safe
- " if (o2 == null) {\n" + // report always false null check
- " o2.toString();\n" + // dead code
- " }\n" +
- " o2.toString();" +
- " }\n" +
- "}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 6)\n" +
- " if (o1.hashCode() == 2){\n" +
- " ^^\n" +
- "Null pointer access: The field o1 can only be null at this location\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 14)\n" +
- " if (local == null) {\n" +
- " ^^^^^\n" +
- "Redundant null check: The variable local can only be null at this location\n" +
- "----------\n" +
- "3. ERROR in X.java (at line 15)\n" +
- " local.toString();\n" +
- " ^^^^^\n" +
- "Null pointer access: The variable local can only be null at this location\n" +
- "----------\n" +
- "4. ERROR in X.java (at line 18)\n" +
- " if (o1 == null) {\n" +
- " ^^\n" +
- "Null comparison always yields false: The field o1 cannot be null at this location\n" +
- "----------\n" +
- "5. WARNING in X.java (at line 18)\n" +
- " if (o1 == null) {\n" +
- " o1.toString();\n" +
- " }\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Dead code\n" +
- "----------\n" +
- "6. ERROR in X.java (at line 23)\n" +
- " if (o2 == null) {\n" +
- " ^^\n" +
- "Null comparison always yields false: The field o2 cannot be null at this location\n" +
- "----------\n" +
- "7. WARNING in X.java (at line 23)\n" +
- " if (o2 == null) {\n" +
- " o2.toString();\n" +
- " }\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Dead code\n" +
- "----------\n"
- );
-}
-
-// null analysis -- case for static final field initialized inside static block with different values
-// check if the resetting works properly i.e. null status for constant fields should not be
-// reset on method calls. This test is for more than 64 fields to check for extra bits.
-public void testBug247564b_8() {
- Map compilerOptions = getCompilerOptions();
- compilerOptions.put(CompilerOptions.OPTION_ReportNonStaticAccessToStatic, CompilerOptions.IGNORE);
- this.runNegativeTest(
- false,
- new String[] {
- "X.java",
- "public class X {\n" +
- "Object field0, \n" +
- "field1, field2, field3, field4, \n" +
- "field5, field6, field7, field8, \n" +
- "field9, field10, field11, field12, \n" +
- "field13, field14, field15, field16, \n" +
- "field17, field18, field19, field20, \n" +
- "field21, field22, field23, field24, \n" +
- "field25, field26, field27, field28, \n" +
- "field29, field30, field31, field32, \n" +
- "field33, field34, field35, field36, \n" +
- "field37, field38, field39, field40, \n" +
- "field41, field42, field43, field44, \n" +
- "field45, field46, field47, field48, \n" +
- "field49, field50, field51, field52, \n" +
- "field53, field54, field55, field56, \n" +
- "field57, field58, field59, field60, \n" +
- "field61, field62, field63, field64, \n" +
- "field65, field66, field67, field68, \n" +
- "field69, field70, field71, field72, \n" +
- "field73, field74, field75, field76, \n" +
- "field77, field78, field79, field80, \n" +
- "field81, field82, field83, field84, \n" +
- "field85, field86, field87, field88, \n" +
- "field89, field90, field91, field92, \n" +
- "field93, field94, field95, field96, \n" +
- "field97, field98, field99;\n" +
- "static final Object o1 = null;\n" +
- "static final Object o2 = new Object();\n" +
- " void foo1() {\n" +
- " final Object local = null;\n" +
- " if (local == null) {\n" +
- " local.toString();\n" +
- " }\n" +
- " local.toString();\n" +
- " if (o1 == null) {\n" + // report redundant null check
- " o1.toString();\n" + // report NPE
- " }\n" +
- " local.toString();\n" + // try to diffuse status for o1 / o2
- " o1.toString();\n" + // already reported NPE above. So silent. Same behaviour as 'local'
- " if (o2 == null) {\n" + // report always false null check
- " o2.toString();\n" + // dead code
- " }\n" +
- " o2.toString();" +
- " }\n" +
- "}\n"},
- null,
- compilerOptions,
- "----------\n" +
- "1. ERROR in X.java (at line 32)\n" +
- " if (local == null) {\n" +
- " ^^^^^\n" +
- "Redundant null check: The variable local can only be null at this location\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 33)\n" +
- " local.toString();\n" +
- " ^^^^^\n" +
- "Null pointer access: The variable local can only be null at this location\n" +
- "----------\n" +
- "3. ERROR in X.java (at line 36)\n" +
- " if (o1 == null) {\n" +
- " ^^\n" +
- "Redundant null check: The field o1 can only be null at this location\n" +
- "----------\n" +
- "4. ERROR in X.java (at line 37)\n" +
- " o1.toString();\n" +
- " ^^\n" +
- "Null pointer access: The field o1 can only be null at this location\n" +
- "----------\n" +
- "5. ERROR in X.java (at line 41)\n" +
- " if (o2 == null) {\n" +
- " ^^\n" +
- "Null comparison always yields false: The field o2 cannot be null at this location\n" +
- "----------\n" +
- "6. WARNING in X.java (at line 41)\n" +
- " if (o2 == null) {\n" +
- " o2.toString();\n" +
- " }\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Dead code\n" +
- "----------\n",
- JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
-}
-
-// null analysis -- case for static final field initialized inside static block where some locals are also present
-// check if the resetting works properly
-public void testBug247564b_9() {
- Map compilerOptions = getCompilerOptions();
- compilerOptions.put(CompilerOptions.OPTION_ReportNonStaticAccessToStatic, CompilerOptions.IGNORE);
- this.runNegativeTest(
- false,
- new String[] {
- "X.java",
- "public class X {\n" +
- " static final Object o1;\n" +
- " static final Object o2 = new Object();\n" +
- " static {\n" +
- " int i = 10;\n" +
- " o1 = null;\n" +
- " }\n" +
- " void foo1() {\n" +
- " final Object local = null;\n" +
- " if (local == null) {\n" +
- " local.toString();\n" +
- " }\n" +
- " local.toString();\n" +
- " if (o1 == null) {\n" + // report redundant null check
- " o1.toString();\n" + // report NPE
- " }\n" +
- " local.toString();\n" + // try to diffuse status for o1 / o2
- " o1.toString();\n" + // already reported NPE above. So silent. Same behaviour as 'local'
- " if (o2 == null) {\n" + // report always false null check
- " o2.toString();\n" + // dead code
- " }\n" +
- " o2.toString();" +
- " }\n" +
- "}\n"},
- null,
- compilerOptions,
- "----------\n" +
- "1. ERROR in X.java (at line 10)\n" +
- " if (local == null) {\n" +
- " ^^^^^\n" +
- "Redundant null check: The variable local can only be null at this location\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 11)\n" +
- " local.toString();\n" +
- " ^^^^^\n" +
- "Null pointer access: The variable local can only be null at this location\n" +
- "----------\n" +
- "3. ERROR in X.java (at line 14)\n" +
- " if (o1 == null) {\n" +
- " ^^\n" +
- "Redundant null check: The field o1 can only be null at this location\n" +
- "----------\n" +
- "4. ERROR in X.java (at line 15)\n" +
- " o1.toString();\n" +
- " ^^\n" +
- "Null pointer access: The field o1 can only be null at this location\n" +
- "----------\n" +
- "5. ERROR in X.java (at line 19)\n" +
- " if (o2 == null) {\n" +
- " ^^\n" +
- "Null comparison always yields false: The field o2 cannot be null at this location\n" +
- "----------\n" +
- "6. WARNING in X.java (at line 19)\n" +
- " if (o2 == null) {\n" +
- " o2.toString();\n" +
- " }\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Dead code\n" +
- "----------\n",
- JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
-}
-
-// null analysis -- case for static final field initialized inside static block with different values
-// check if the resetting works properly i.e. null status for constant fields should not be
-// reset on method calls.
-// Boundary condition: field <boundary> constant local
-public void testBug247564b_10() {
- Map compilerOptions = getCompilerOptions();
- compilerOptions.put(CompilerOptions.OPTION_ReportNonStaticAccessToStatic, CompilerOptions.IGNORE);
- this.runNegativeTest(
- false,
- new String[] {
- "X.java",
- "public class X {\n" +
- "Object field0, \n" +
- "field1, field2, field3, field4, \n" +
- "field5, field6, field7, field8, \n" +
- "field9, field10, field11, field12, \n" +
- "field13, field14, field15, field16, \n" +
- "field17, field18, field19, field20, \n" +
- "field21, field22, field23, field24, \n" +
- "field25, field26, field27, field28, \n" +
- "field29, field30, field31, field32, \n" +
- "field33, field34, field35, field36, \n" +
- "field37, field38, field39, field40, \n" +
- "field41, field42, field43, field44, \n" +
- "field45, field46, field47, field48, \n" +
- "field49, field50, field51, field52, \n" +
- "field53, field54, field55, field56, \n" +
- "field57, field58, field59, field60, \n" +
- "field61, field62, field63;\n" +
- "static final Object static64 = null;\n" +
- " void foo1(Object local65) {\n" +
- " if (field63 == null) {\n" +
- " field63.toString(); // report NPE\n" +
- " }\n" +
- " if (static64 == null) { // redundant\n" +
- " static64.toString(); // report NPE\n" +
- " }\n" +
- " if (local65 == null) {\n" +
- " local65.toString(); // report NPE\n" +
- " }\n" +
- " if (field63 == null) {\n" +
- " this.toString();\n" +
- " field63.toString();\n" + // wiped by method call
- " }\n" +
- " if (static64 == null) { // always false\n" + // because we're past static64.toString()
- " this.toString(); // dead\n" +
- " static64.toString();\n" +
- " }\n" +
- " if (local65 == null) { // alwayws false\n" + // because we're past local65.toString()
- " this.toString(); // dead\n" +
- " local65.toString();\n" +
- " }\n" +
- " }\n" +
- "}\n"},
- null,
- compilerOptions,
- "----------\n" +
- "1. ERROR in X.java (at line 22)\n" +
- " field63.toString(); // report NPE\n" +
- " ^^^^^^^\n" +
- "Potential null pointer access: The field field63 may be null at this location\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 24)\n" +
- " if (static64 == null) { // redundant\n" +
- " ^^^^^^^^\n" +
- "Redundant null check: The field static64 can only be null at this location\n" +
- "----------\n" +
- "3. ERROR in X.java (at line 25)\n" +
- " static64.toString(); // report NPE\n" +
- " ^^^^^^^^\n" +
- "Null pointer access: The field static64 can only be null at this location\n" +
- "----------\n" +
- "4. ERROR in X.java (at line 28)\n" +
- " local65.toString(); // report NPE\n" +
- " ^^^^^^^\n" +
- "Null pointer access: The variable local65 can only be null at this location\n" +
- "----------\n" +
- "5. ERROR in X.java (at line 34)\n" +
- " if (static64 == null) { // always false\n" +
- " ^^^^^^^^\n" +
- "Null comparison always yields false: The field static64 cannot be null at this location\n" +
- "----------\n" +
- "6. WARNING in X.java (at line 34)\n" +
- " if (static64 == null) { // always false\n" +
- " this.toString(); // dead\n" +
- " static64.toString();\n" +
- " }\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Dead code\n" +
- "----------\n" +
- "7. ERROR in X.java (at line 38)\n" +
- " if (local65 == null) { // alwayws false\n" +
- " ^^^^^^^\n" +
- "Null comparison always yields false: The variable local65 cannot be null at this location\n" +
- "----------\n" +
- "8. WARNING in X.java (at line 38)\n" +
- " if (local65 == null) { // alwayws false\n" +
- " this.toString(); // dead\n" +
- " local65.toString();\n" +
- " }\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Dead code\n" +
- "----------\n",
- JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
-}
-
-// null analysis -- case for static final field initialized inside static block with different values
-// check if the resetting works properly i.e. null status for constant fields should not be
-// reset on method calls.
-// Boundary condition: constant field <boundary> local
-public void testBug247564b_11() {
- Map compilerOptions = getCompilerOptions();
- compilerOptions.put(CompilerOptions.OPTION_ReportNonStaticAccessToStatic, CompilerOptions.IGNORE);
- this.runNegativeTest(
- false,
- new String[] {
- "X.java",
- "public class X {\n" +
- "Object field0, \n" +
- "field1, field2, field3, field4, \n" +
- "field5, field6, field7, field8, \n" +
- "field9, field10, field11, field12, \n" +
- "field13, field14, field15, field16, \n" +
- "field17, field18, field19, field20, \n" +
- "field21, field22, field23, field24, \n" +
- "field25, field26, field27, field28, \n" +
- "field29, field30, field31, field32, \n" +
- "field33, field34, field35, field36, \n" +
- "field37, field38, field39, field40, \n" +
- "field41, field42, field43, field44, \n" +
- "field45, field46, field47, field48, \n" +
- "field49, field50, field51, field52, \n" +
- "field53, field54, field55, field56, \n" +
- "field57, field58, field59, field60, \n" +
- "field61;\n" +
- "static final Object static62 = null;\n" +
- "Object field63;" +
- " void foo1(Object local64) {\n" +
- " if (static62 == null) { // redundant\n" +
- " static62.toString(); // report NPE\n" +
- " }\n" +
- " if (field63 == null) {\n" +
- " field63.toString(); // report NPE\n" +
- " }\n" +
- " if (local64 == null) {\n" +
- " local64.toString(); // report NPE\n" +
- " }\n" +
- " if (static62 == null) { // always false\n" + // because we're past static64.toString()
- " this.toString(); // dead\n" +
- " static62.toString();\n" +
- " }\n" +
- " if (field63 == null) {\n" +
- " this.toString(); //\n" +
- " field63.toString();\n" + // wiped by method call
- " }\n" +
- " if (local64 == null) { // alwayws false\n" + // because we're past local64.toString()
- " this.toString(); // dead\n" +
- " local64.toString();\n" +
- " }\n" +
- " }\n" +
- "}\n"},
- null,
- compilerOptions,
- "----------\n" +
- "1. ERROR in X.java (at line 21)\n" +
- " if (static62 == null) { // redundant\n" +
- " ^^^^^^^^\n" +
- "Redundant null check: The field static62 can only be null at this location\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 22)\n" +
- " static62.toString(); // report NPE\n" +
- " ^^^^^^^^\n" +
- "Null pointer access: The field static62 can only be null at this location\n" +
- "----------\n" +
- "3. ERROR in X.java (at line 25)\n" +
- " field63.toString(); // report NPE\n" +
- " ^^^^^^^\n" +
- "Potential null pointer access: The field field63 may be null at this location\n" +
- "----------\n" +
- "4. ERROR in X.java (at line 28)\n" +
- " local64.toString(); // report NPE\n" +
- " ^^^^^^^\n" +
- "Null pointer access: The variable local64 can only be null at this location\n" +
- "----------\n" +
- "5. ERROR in X.java (at line 30)\n" +
- " if (static62 == null) { // always false\n" +
- " ^^^^^^^^\n" +
- "Null comparison always yields false: The field static62 cannot be null at this location\n" +
- "----------\n" +
- "6. WARNING in X.java (at line 30)\n" +
- " if (static62 == null) { // always false\n" +
- " this.toString(); // dead\n" +
- " static62.toString();\n" +
- " }\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Dead code\n" +
- "----------\n" +
- "7. ERROR in X.java (at line 38)\n" +
- " if (local64 == null) { // alwayws false\n" +
- " ^^^^^^^\n" +
- "Null comparison always yields false: The variable local64 cannot be null at this location\n" +
- "----------\n" +
- "8. WARNING in X.java (at line 38)\n" +
- " if (local64 == null) { // alwayws false\n" +
- " this.toString(); // dead\n" +
- " local64.toString();\n" +
- " }\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Dead code\n" +
- "----------\n",
- JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
-}
-
-// null analysis -- fields in synchronized methods
-// check that null analysis for fields in synchronized methods
-// behave as it does in ordinary methods.
-public void testBug247564c() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " Object o;\n" +
- " Object o1;\n" +
- " static final Object o2 = null;\n" +
- " static final Object o3 = new Object();\n" +
- " synchronized void foo() {\n" +
- " o = null;\n" +
- " if (o == null) {\n" +
- " o.toString();\n" +
- " }\n" +
- " o1 = new Object();\n" +
- " if (o1 == null) {\n" +
- " o1.toString();\n" +
- " }\n" +
- " if (o2 != null) {\n" +
- " }\n" +
- " else {\n" +
- " o2.toString();\n" +
- " }\n" +
- " if (o3 == null) {\n" +
- " }\n" +
- " else {\n" +
- " o3.toString();\n" +
- " }\n" +
- " }\n" +
- " void foo1() {\n" +
- " o.toString();\n" +
- " }\n" +
- "}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 9)\n" +
- " o.toString();\n" +
- " ^\n" +
- "Potential null pointer access: The field o may be null at this location\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 13)\n" +
- " o1.toString();\n" +
- " ^^\n" +
- "Potential null pointer access: The field o1 may be null at this location\n" +
- "----------\n" +
- "3. ERROR in X.java (at line 15)\n" +
- " if (o2 != null) {\n" +
- " ^^\n" +
- "Null comparison always yields false: The field o2 can only be null at this location\n" +
- "----------\n" +
- "4. WARNING in X.java (at line 15)\n" +
- " if (o2 != null) {\n" +
- " }\n" +
- " ^^^^^\n" +
- "Dead code\n" +
- "----------\n" +
- "5. ERROR in X.java (at line 18)\n" +
- " o2.toString();\n" +
- " ^^\n" +
- "Null pointer access: The field o2 can only be null at this location\n" +
- "----------\n" +
- "6. ERROR in X.java (at line 20)\n" +
- " if (o3 == null) {\n" +
- " ^^\n" +
- "Null comparison always yields false: The field o3 cannot be null at this location\n" +
- "----------\n" +
- "7. WARNING in X.java (at line 20)\n" +
- " if (o3 == null) {\n" +
- " }\n" +
- " ^^^^^\n" +
- "Dead code\n" +
- "----------\n"
- );
-}
-
-// null analysis -- fields in synchronized methods
-// check that null analysis for fields in synchronized methods
-// behave as it does in ordinary methods. Higher no. of fields
-public void testBug247564c_2() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " Object o;\n" +
- " Object o1;\n" +
- "Object field0, \n" +
- "field1, field2, field3, field4, \n" +
- "field5, field6, field7, field8, \n" +
- "field9, field10, field11, field12, \n" +
- "field13, field14, field15, field16, \n" +
- "field17, field18, field19, field20, \n" +
- "field21, field22, field23, field24, \n" +
- "field25, field26, field27, field28, \n" +
- "field29, field30, field31, field32, \n" +
- "field33, field34, field35, field36, \n" +
- "field37, field38, field39, field40, \n" +
- "field41, field42, field43, field44, \n" +
- "field45, field46, field47, field48, \n" +
- "field49, field50, field51, field52, \n" +
- "field53, field54, field55, field56, \n" +
- "field57, field58, field59, field60, \n" +
- "field61, field62, field63, field64, \n" +
- "field65, field66, field67, field68, \n" +
- "field69, field70, field71, field72, \n" +
- "field73, field74, field75, field76, \n" +
- "field77, field78, field79, field80, \n" +
- "field81, field82, field83, field84, \n" +
- "field85, field86, field87, field88, \n" +
- "field89, field90, field91, field92, \n" +
- "field93, field94, field95, field96, \n" +
- "field97, field98, field99;\n" +
- " static final Object o2 = null;\n" +
- " static final Object o3 = new Object();\n" +
- " synchronized void foo() {\n" +
- " o = null;\n" +
- " if (o == null) {\n" +
- " o.toString();\n" +
- " }\n" +
- " o1 = new Object();\n" +
- " if (o1 == null) {\n" +
- " o1.toString();\n" +
- " }\n" +
- " if (o2 != null) {\n" +
- " }\n" +
- " else {\n" +
- " o2.toString();\n" +
- " }\n" +
- " if (o3 == null) {\n" +
- " }\n" +
- " else {\n" +
- " o3.toString();\n" +
- " }\n" +
- " }\n" +
- " void foo1() {\n" +
- " o.toString();\n" +
- " }\n" +
- "}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 35)\n" +
- " o.toString();\n" +
- " ^\n" +
- "Potential null pointer access: The field o may be null at this location\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 39)\n" +
- " o1.toString();\n" +
- " ^^\n" +
- "Potential null pointer access: The field o1 may be null at this location\n" +
- "----------\n" +
- "3. ERROR in X.java (at line 41)\n" +
- " if (o2 != null) {\n" +
- " ^^\n" +
- "Null comparison always yields false: The field o2 can only be null at this location\n" +
- "----------\n" +
- "4. WARNING in X.java (at line 41)\n" +
- " if (o2 != null) {\n" +
- " }\n" +
- " ^^^^^\n" +
- "Dead code\n" +
- "----------\n" +
- "5. ERROR in X.java (at line 44)\n" +
- " o2.toString();\n" +
- " ^^\n" +
- "Null pointer access: The field o2 can only be null at this location\n" +
- "----------\n" +
- "6. ERROR in X.java (at line 46)\n" +
- " if (o3 == null) {\n" +
- " ^^\n" +
- "Null comparison always yields false: The field o3 cannot be null at this location\n" +
- "----------\n" +
- "7. WARNING in X.java (at line 46)\n" +
- " if (o3 == null) {\n" +
- " }\n" +
- " ^^^^^\n" +
- "Dead code\n" +
- "----------\n"
- );
-}
-
-// null analysis -- test redundant instanceof warning for static final field
-public void testBug247564d() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " static final Object o = null;\n" +
- " static final Object o1 = new Object();\n" +
- " void foo() {\n" +
- " if (o instanceof String) {}\n" +
- " if (o1 instanceof String) {}\n" +
- " }\n" +
- "}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 5)\n" +
- " if (o instanceof String) {}\n" +
- " ^\n" +
- "instanceof always yields false: The field o can only be null at this location\n" +
- "----------\n"
- );
-}
-
-// null analysis -- test redundant instanceof warning for static final field. More fields
-public void testBug247564d_1() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- "Object field0, \n" +
- "field1, field2, field3, field4, \n" +
- "field5, field6, field7, field8, \n" +
- "field9, field10, field11, field12, \n" +
- "field13, field14, field15, field16, \n" +
- "field17, field18, field19, field20, \n" +
- "field21, field22, field23, field24, \n" +
- "field25, field26, field27, field28, \n" +
- "field29, field30, field31, field32, \n" +
- "field33, field34, field35, field36, \n" +
- "field37, field38, field39, field40, \n" +
- "field41, field42, field43, field44, \n" +
- "field45, field46, field47, field48, \n" +
- "field49, field50, field51, field52, \n" +
- "field53, field54, field55, field56, \n" +
- "field57, field58, field59, field60, \n" +
- "field61, field62, field63, field64, \n" +
- "field65, field66, field67, field68, \n" +
- "field69, field70, field71, field72, \n" +
- "field73, field74, field75, field76, \n" +
- "field77, field78, field79, field80, \n" +
- "field81, field82, field83, field84, \n" +
- "field85, field86, field87, field88, \n" +
- "field89, field90, field91, field92, \n" +
- "field93, field94, field95, field96, \n" +
- "field97, field98, field99;\n" +
- " static final Object o = null;\n" +
- " static final Object o1 = new Object();\n" +
- " void foo() {\n" +
- " if (o instanceof String) {}\n" +
- " if (o1 instanceof String) {}\n" +
- " }\n" +
- "}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 31)\n" +
- " if (o instanceof String) {}\n" +
- " ^\n" +
- "instanceof always yields false: The field o can only be null at this location\n" +
- "----------\n"
- );
-}
-
-// null analysis -- test potential null ptr access warning because of static field access through object returned by method call
-public void testBug247564f() {
- Map compilerOptions = getCompilerOptions();
- compilerOptions.put(CompilerOptions.OPTION_ReportNonStaticAccessToStatic, CompilerOptions.IGNORE);
- this.runNegativeTest(
- false,
- new String[] {
- "X.java",
- "public class X {\n" +
- " static Object o;\n" +
- " static Object o1;\n" +
- " Object o2;\n" +
- " X getX() { return new X();\n}\n" +
- " void foo() {\n" +
- " if (getX().o == null && this.o.hashCode() == 0) return;\n" +
- " if (getX().o2 == null && this.o2.hashCode() == 0) return;\n" +
- " }\n" +
- "}"},
- null,
- compilerOptions,
- "----------\n" +
- "1. ERROR in X.java (at line 8)\n" +
- " if (getX().o == null && this.o.hashCode() == 0) return;\n" +
- " ^\n" +
- "Potential null pointer access: The field o may be null at this location\n" +
- "----------\n",
- JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
-}
-
-// null analysis -- test potential null ptr access warning because of static field access through object returned by method call
-public void testBug247564f_1() {
- Map compilerOptions = getCompilerOptions();
- compilerOptions.put(CompilerOptions.OPTION_ReportNonStaticAccessToStatic, CompilerOptions.IGNORE);
- this.runNegativeTest(
- false,
- new String[] {
- "X.java",
- "public class X {\n" +
- " static Object o;\n" +
- " X getX() { return new X();\n}\n" +
- " Y getY() { return new Y();\n}\n" +
- " void foo() {\n" +
- " if (getY().o == null && this.o.hashCode() == 0) return;\n" +
- " if (getX().o == null && this.o.hashCode() == 0) return;\n" +
- " }\n" +
- "}\n" +
- "class Y{\n" +
- " static Object o;\n" +
- "}\n"},
- null,
- compilerOptions,
- "----------\n" +
- "1. ERROR in X.java (at line 9)\n" +
- " if (getX().o == null && this.o.hashCode() == 0) return;\n" +
- " ^\n" +
- "Potential null pointer access: The field o may be null at this location\n" +
- "----------\n",
- JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
-}
-
-// null analysis -- test field analysis in case of more than 64 fields
-public void testBug247564g() {
- Map compilerOptions = getCompilerOptions();
- compilerOptions.put(CompilerOptions.OPTION_ReportNonStaticAccessToStatic, CompilerOptions.IGNORE);
- this.runNegativeTest(
- false,
- new String[] {
- "X.java",
- "public class X {\n" +
- "Object field0, \n" +
- "field1, field2, field3, field4, \n" +
- "field5, field6, field7, field8, \n" +
- "field9, field10, field11, field12, \n" +
- "field13, field14, field15, field16, \n" +
- "field17, field18, field19, field20, \n" +
- "field21, field22, field23, field24, \n" +
- "field25, field26, field27, field28, \n" +
- "field29, field30, field31, field32, \n" +
- "field33, field34, field35, field36, \n" +
- "field37, field38, field39, field40, \n" +
- "field41, field42, field43, field44, \n" +
- "field45, field46, field47, field48, \n" +
- "field49, field50, field51, field52, \n" +
- "field53, field54, field55, field56, \n" +
- "field57, field58, field59, field60, \n" +
- "field61, field62, field63, field64, \n" +
- "field65, field66, field67, field68, \n" +
- "field69, field70, field71, field72, \n" +
- "field73, field74, field75, field76, \n" +
- "field77, field78, field79, field80, \n" +
- "field81, field82, field83, field84, \n" +
- "field85, field86, field87, field88, \n" +
- "field89, field90, field91, field92, \n" +
- "field93, field94, field95, field96, \n" +
- "field97, field98, field99;\n" +
- "static final Object field100 = null;\n" +
- " void foo() {\n" +
- " int i = 0;" +
- " while (i<10){\n" +
- " i++;\n" +
- " if (this.field99 == null && this.field99.hashCode() == 0){}\n" +
- " this.field98 = null;\n" +
- " }\n" +
- " if (this.field98.hashCode() == 0) {}\n" +
- " this.field97 = null;\n" +
- " if (this.field97.hashCode() == 0) {}\n" +
- " if (this.field100.hashCode() == 0) {}\n" +
- " }\n" +
- "}"},
- null,
- compilerOptions,
- "----------\n" +
- "1. ERROR in X.java (at line 32)\n" +
- " if (this.field99 == null && this.field99.hashCode() == 0){}\n" +
- " ^^^^^^^\n" +
- "Potential null pointer access: The field field99 may be null at this location\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 35)\n" +
- " if (this.field98.hashCode() == 0) {}\n" +
- " ^^^^^^^\n" +
- "Potential null pointer access: The field field98 may be null at this location\n" +
- "----------\n" +
- "3. ERROR in X.java (at line 37)\n" +
- " if (this.field97.hashCode() == 0) {}\n" +
- " ^^^^^^^\n" +
- "Potential null pointer access: The field field97 may be null at this location\n" +
- "----------\n" +
- "4. ERROR in X.java (at line 38)\n" +
- " if (this.field100.hashCode() == 0) {}\n" +
- " ^^^^^^^^\n" +
- "Null pointer access: The field field100 can only be null at this location\n" +
- "----------\n",
- JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
-}
-
-// null analysis -- simple case for field for inner class
-// to make sure field id's of inner and outer classes are not same for flow analysis
-public void testBug247564h() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " Object o;\n" +
- " class X1 {\n" +
- " Object x;" +
- " Object x1;" +
- " Object x2;" +
- " void goo() {\n" +
- " if (o == null && x.toString() == \"\"){}\n" +
- " if (o2 == null && o2.toString() == \"\"){}\n" +
- " if (o2 == null && x2.toString() == \"\"){}\n" +
- " }\n" +
-
- " }\n" +
- " Object o1;\n" +
- " static Object o2;\n" +
- "}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 6)\n" +
- " if (o2 == null && o2.toString() == \"\"){}\n" +
- " ^^\n" +
- "Potential null pointer access: The field o2 may be null at this location\n" +
- "----------\n"
- );
-}
-
-// null analysis -- simple case for field for inner class
-// to make sure that id's of local variables in inner classes don't conflict with those of fields.
-public void testBug247564h_1() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " Object field0;\n" +
- " Object field1;\n" +
- " class X1 {\n" +
- " Object field2;" +
- " Object field3;" +
- " void goo(Object var) {\n" +
- " if (var == null && field2.toString() == \"\"){}\n" +
- " if (var == null && field3.toString() == \"\"){}\n" +
- " if (field2 == null && field2.toString() == \"\"){}\n" +
- " }\n" +
- " }\n" +
- "}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 8)\n" +
- " if (field2 == null && field2.toString() == \"\"){}\n" +
- " ^^^^^^\n" +
- "Potential null pointer access: The field field2 may be null at this location\n" +
- "----------\n"
- );
-}
-
-// null analysis -- simple case for field for inner class
-// to make sure that id's of local variables in inner classes don't conflict with those of fields.
-public void testBug247564h_2() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " Object field0;\n" +
- " Object field1;\n" +
- " class X1 {\n" +
- " Object field2;\n" +
- " Object field3;\n" +
- " class X2 {\n" +
- " Object field4;\n" +
- " Object field5;\n" +
- " void goo(Object var) {\n" +
- " if (var == null && field4.toString() == \"\"){}\n" +
- " if (var == null && field5.toString() == \"\"){}\n" +
- " if (field3 == null && field3.toString() == \"\"){}\n" +
- " if (field3 == null && field1.toString() == \"\"){}\n" +
- " }\n" +
- " }\n" +
- " Object field22;\n" +
- " }\n" +
- "}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 13)\n" +
- " if (field3 == null && field3.toString() == \"\"){}\n" +
- " ^^^^^^\n" +
- "Potential null pointer access: The field field3 may be null at this location\n" +
- "----------\n"
- );
-}
-
-// null analysis -- simple case for static fields
-// to make sure that static field only of the current type is assigned potentially null when compared against null
-// Static fields belonging to any other class should be ignored
-// Qualified access to static fields should also work
-public void testBug247564i_1() {
- Map compilerOptions = getCompilerOptions();
- compilerOptions.put(CompilerOptions.OPTION_ReportNonStaticAccessToStatic, CompilerOptions.IGNORE);
- this.runNegativeTest(
- true,
- new String[] {
- "X.java",
- "public class X {\n" +
- " static Object field0;\n" +
- " static Object field1;\n" +
- " Y getY(){ return new Y();}\n" +
- " X getX() { return new X();}\n" +
- " void goo(Object var) {\n" +
- " if (Y.yField1 == null && field0.toString() == \"\"){}\n" + // no warn
- " if (Y.yField1 == null && this.field0.toString() == \"\"){}\n" + // no warn
- " if (Y.xiny.field0 == null && Y.xiny.field0.toString() == \"\"){}\n" + // warn, qualified access
- " if (Y.yField1 == null && Y.yField1.toString() == \"\"){}\n" + // no warn
- " if (Y.xiny.field1 == null && Y.yField1.toString() == \"\"){}\n" + // no warn
- " if (X.field0 == null && X.field0.toString() == \"\"){}\n" + // warn
- " if (this.field0 == null && X.field0.toString() == \"\"){}\n" + // warn
- " if (X.field0 == null && this.field0.toString() == \"\"){}\n" + // warn
- " if (X.field0 == null && getX().field0.toString() == \"\"){}\n" + // no warn (diffused by getX() call)
- " }\n" +
- "}\n" +
- "class Y{\n" +
- " Y getY(){ return new Y();}\n" +
- " X getX(){ return new X();}\n" +
- " static Object yField1;" +
- " static X xiny;\n" +
- "}"},
- null,
- compilerOptions,
- "----------\n" +
- "1. ERROR in X.java (at line 9)\n" +
- " if (Y.xiny.field0 == null && Y.xiny.field0.toString() == \"\"){}\n" +
- " ^^^^^^\n" +
- "Potential null pointer access: The field field0 may be null at this location\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 12)\n" +
- " if (X.field0 == null && X.field0.toString() == \"\"){}\n" +
- " ^^^^^^\n" +
- "Potential null pointer access: The field field0 may be null at this location\n" +
- "----------\n" +
- "3. ERROR in X.java (at line 13)\n" +
- " if (this.field0 == null && X.field0.toString() == \"\"){}\n" +
- " ^^^^^^\n" +
- "Potential null pointer access: The field field0 may be null at this location\n" +
- "----------\n" +
- "4. ERROR in X.java (at line 14)\n" +
- " if (X.field0 == null && this.field0.toString() == \"\"){}\n" +
- " ^^^^^^\n" +
- "Potential null pointer access: The field field0 may be null at this location\n" +
- "----------\n",
- JavacTestOptions.Excuse.EclipseWarningConfiguredAsError
- );
-}
-
-// null analysis -- static fields accessed via MessageSend
-// to make sure that static field only of the current type is assigned potentially null when compared against null
-// Static fields belonging to any other class should be ignored
-// Qualified access to static fields should also work
-public void testBug247564i_2() {
- Map compilerOptions = getCompilerOptions();
- compilerOptions.put(CompilerOptions.OPTION_ReportNonStaticAccessToStatic, CompilerOptions.IGNORE);
- this.runNegativeTest(
- true,
- new String[] {
- "X.java",
- "public class X {\n" +
- " static Object field0;\n" +
- " static Object field1;\n" +
- " Y getY(){ return new Y();}\n" +
- " X getX() { return new X();}\n" +
- " void goo(Object var) {\n" +
- " if (new Y().getY().yField1 == null && field0.toString() == \"\"){}\n" + // no warn
- " if (getY().yField1 == null && field0.toString() == \"\"){}\n" + // no warn
- " if (getY().yField1 == null && this.field0.toString() == \"\"){}\n" + // no warn
- " if (new Y().getX().field0 == null && field0.toString() == \"\"){}\n" + // warn
- " if (getX().field0 == null && field0.toString() == \"\"){}\n" + // warn
- " if (getX().field0 == null && this.field0.toString() == \"\"){}\n" + // warn
- " if (getX().field0 == null && getX().field0.toString() == \"\"){}\n" + // no warn, getX() wipes out null info
- " if (getX().field0 == null && X.field0.toString() == \"\"){}\n" + // warn, qualified access
- // fields from other types, don't warn
- " if (new Y().getY().yField1 == null && Y.yField1.toString() == \"\"){}\n" + // no warn
- " if (getY().yField1 == null && Y.yField1.toString() == \"\"){}\n" + // no warn
- " if (getX().field0 == null && Y.yField1.toString() == \"\"){}\n" + // no warn
- " }\n" +
- "}\n" +
- "class Y{\n" +
- " Y getY(){ return new Y();}\n" +
- " X getX(){ return new X();}\n" +
- " static Object yField1;\n" +
- "}"},
- null,
- compilerOptions,
- "----------\n" +
- "1. ERROR in X.java (at line 10)\n" +
- " if (new Y().getX().field0 == null && field0.toString() == \"\"){}\n" +
- " ^^^^^^\n" +
- "Potential null pointer access: The field field0 may be null at this location\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 11)\n" +
- " if (getX().field0 == null && field0.toString() == \"\"){}\n" +
- " ^^^^^^\n" +
- "Potential null pointer access: The field field0 may be null at this location\n" +
- "----------\n" +
- "3. ERROR in X.java (at line 12)\n" +
- " if (getX().field0 == null && this.field0.toString() == \"\"){}\n" +
- " ^^^^^^\n" +
- "Potential null pointer access: The field field0 may be null at this location\n" +
- "----------\n" +
- "4. ERROR in X.java (at line 14)\n" +
- " if (getX().field0 == null && X.field0.toString() == \"\"){}\n" +
- " ^^^^^^\n" +
- "Potential null pointer access: The field field0 may be null at this location\n" +
- "----------\n",
- JavacTestOptions.Excuse.EclipseWarningConfiguredAsError
- );
-}
-
-// null analysis -- static fields accessed from Member type
-// Qualified access to static fields should also work
-public void testBug247564i_3() {
- Map compilerOptions = getCompilerOptions();
- compilerOptions.put(CompilerOptions.OPTION_ReportNonStaticAccessToStatic, CompilerOptions.IGNORE);
- this.runNegativeTest(
- true,
- new String[] {
- "X.java",
- "public class X {\n" +
- " static Object field0;\n" +
- " static Object field1;\n" +
- " static Y getY(){ return new Y();}\n" +
- " static X getX() { return new X();}\n" +
- " static class XInner{\n" +
- " static Object xinnerfield;\n" +
- " XInner getXInner() { return new XInner();\n}" +
- " void goo(Object var) {\n" +
- " if (new Y().getY().yField1 == null && field0.toString() == \"\"){}\n" + // no warn
- " if (getY().yField1 == null && field0.toString() == \"\"){}\n" + // no warn
- " if (new Y().getX().field0 == null && field0.toString() == \"\"){}\n" + // warn
- " if (getX().field0 == null && field0.toString() == \"\"){}\n" + // warn
- " if (getX().field0 == null && getX().field0.toString() == \"\"){}\n" + // no warn, getX() wipes out null info
- " if (getX().field0 == null && X.field0.toString() == \"\"){}\n" + // warn, qualified access
- " if (getXInner().xinnerfield == null && xinnerfield.toString() == \"\"){}\n" + // warn
- " if (getXInner().xinnerfield == null && this.xinnerfield.toString() == \"\"){}\n" + // warn
- " if (getX().field0 == null && this.xinnerfield.toString() == \"\"){}\n" + // no warn
- " if (getXInner().xinnerfield == null && field0.toString() == \"\"){}\n" + // no warn
- // fields from other types, don't warn
- " if (new Y().getY().yField1 == null && Y.yField1.toString() == \"\"){}\n" + // no warn
- " if (getY().yField1 == null && Y.yField1.toString() == \"\"){}\n" + // no warn
- " if (getX().field0 == null && Y.yField1.toString() == \"\"){}\n" + // no warn
- // qualified accesses
- " if (Y.yField1 == null && field0.toString() == \"\"){}\n" + // no warn
- " if (Y.xiny.field0 == null && Y.xiny.field0.toString() == \"\"){}\n" + // warn, qualified access
- " if (Y.yField1 == null && Y.yField1.toString() == \"\"){}\n" + // no warn
- " if (Y.xiny.field1 == null && Y.yField1.toString() == \"\"){}\n" + // no warn
- " if (X.field0 == null && X.field0.toString() == \"\"){}\n" + // warn
- " if (X.field0 == null && getX().field0.toString() == \"\"){}\n" + // no warn
- " }\n" +
- " }\n" +
- "}\n" +
- "class Y{\n" +
- " Y getY(){ return new Y();}\n" +
- " X getX(){ return new X();}\n" +
- " static Object yField1;\n" +
- " static X xiny;\n" +
- "}"},
- null,
- compilerOptions,
- "----------\n" +
- "1. ERROR in X.java (at line 12)\n" +
- " if (new Y().getX().field0 == null && field0.toString() == \"\"){}\n" +
- " ^^^^^^\n" +
- "Potential null pointer access: The field field0 may be null at this location\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 13)\n" +
- " if (getX().field0 == null && field0.toString() == \"\"){}\n" +
- " ^^^^^^\n" +
- "Potential null pointer access: The field field0 may be null at this location\n" +
- "----------\n" +
- "3. ERROR in X.java (at line 15)\n" +
- " if (getX().field0 == null && X.field0.toString() == \"\"){}\n" +
- " ^^^^^^\n" +
- "Potential null pointer access: The field field0 may be null at this location\n" +
- "----------\n" +
- "4. ERROR in X.java (at line 16)\n" +
- " if (getXInner().xinnerfield == null && xinnerfield.toString() == \"\"){}\n" +
- " ^^^^^^^^^^^\n" +
- "Potential null pointer access: The field xinnerfield may be null at this location\n" +
- "----------\n" +
- "5. ERROR in X.java (at line 17)\n" +
- " if (getXInner().xinnerfield == null && this.xinnerfield.toString() == \"\"){}\n" +
- " ^^^^^^^^^^^\n" +
- "Potential null pointer access: The field xinnerfield may be null at this location\n" +
- "----------\n" +
- "6. ERROR in X.java (at line 24)\n" +
- " if (Y.xiny.field0 == null && Y.xiny.field0.toString() == \"\"){}\n" +
- " ^^^^^^\n" +
- "Potential null pointer access: The field field0 may be null at this location\n" +
- "----------\n" +
- "7. ERROR in X.java (at line 27)\n" +
- " if (X.field0 == null && X.field0.toString() == \"\"){}\n" +
- " ^^^^^^\n" +
- "Potential null pointer access: The field field0 may be null at this location\n" +
- "----------\n",
- JavacTestOptions.Excuse.EclipseWarningConfiguredAsError
- );
-}
-
-// null analysis -- static fields accessed from a local type
-// Qualified access to static fields should also work
-public void testBug247564i_4() {
- Map compilerOptions = getCompilerOptions();
- compilerOptions.put(CompilerOptions.OPTION_ReportNonStaticAccessToStatic, CompilerOptions.IGNORE);
- this.runNegativeTest(
- true,
- new String[] {
- "X.java",
- "public class X {\n" +
- " static Object field0;\n" +
- " static Object field1;\n" +
- " Y getY(){ return new Y();}\n" +
- " X getX() { return new X();}\n" +
- " void goo(Object var) {\n" +
- " class Local{\n" +
- " void localfoo(){\n " +
- " if (new Y().getY().yField1 == null && field0.toString() == \"\"){}\n" + // no warn
- " if (getY().yField1 == null && field0.toString() == \"\"){}\n" + // no warn
- " if (new Y().getX().field0 == null && field0.toString() == \"\"){}\n" + // warn
- " if (getX().field0 == null && field0.toString() == \"\"){}\n" + // warn
- " if (getX().field0 == null && getX().field0.toString() == \"\"){}\n" + // no warn, getX() wipes out null info
- " if (getX().field0 == null && X.field0.toString() == \"\"){}\n" + // warn, qualified access
- // fields from other types, don't warn
- " if (new Y().getY().yField1 == null && Y.yField1.toString() == \"\"){}\n" + // no warn
- " if (getY().yField1 == null && Y.yField1.toString() == \"\"){}\n" + // no warn
- " if (getX().field0 == null && Y.yField1.toString() == \"\"){}\n" + // no warn
- // qualified accesses
- " if (Y.yField1 == null && field0.toString() == \"\"){}\n" + // no warn
- " if (Y.xiny.field0 == null && Y.xiny.field0.toString() == \"\"){}\n" + // warn, qualified access
- " if (Y.yField1 == null && Y.yField1.toString() == \"\"){}\n" + // no warn
- " if (Y.xiny.field1 == null && Y.yField1.toString() == \"\"){}\n" + // no warn
- " if (X.field0 == null && X.field0.toString() == \"\"){}\n" + // warn
- " if (X.field0 == null && getX().field0.toString() == \"\"){}\n" + // no warn
- " }\n" +
- " }\n" +
- " }\n" +
- "}\n" +
- "class Y{\n" +
- " Y getY(){ return new Y();}\n" +
- " X getX(){ return new X();}\n" +
- " static Object yField1;\n" +
- " static X xiny;\n" +
- "}"},
- null,
- compilerOptions,
- "----------\n" +
- "1. WARNING in X.java (at line 7)\n" +
- " class Local{\n" +
- " ^^^^^\n" +
- "The type Local is never used locally\n" +
- "----------\n" +
- "2. WARNING in X.java (at line 8)\n" +
- " void localfoo(){\n" +
- " ^^^^^^^^^^\n" +
- "The method localfoo() from the type Local is never used locally\n" +
- "----------\n" +
- "3. ERROR in X.java (at line 11)\n" +
- " if (new Y().getX().field0 == null && field0.toString() == \"\"){}\n" +
- " ^^^^^^\n" +
- "Potential null pointer access: The field field0 may be null at this location\n" +
- "----------\n" +
- "4. ERROR in X.java (at line 12)\n" +
- " if (getX().field0 == null && field0.toString() == \"\"){}\n" +
- " ^^^^^^\n" +
- "Potential null pointer access: The field field0 may be null at this location\n" +
- "----------\n" +
- "5. ERROR in X.java (at line 14)\n" +
- " if (getX().field0 == null && X.field0.toString() == \"\"){}\n" +
- " ^^^^^^\n" +
- "Potential null pointer access: The field field0 may be null at this location\n" +
- "----------\n" +
- "6. ERROR in X.java (at line 19)\n" +
- " if (Y.xiny.field0 == null && Y.xiny.field0.toString() == \"\"){}\n" +
- " ^^^^^^\n" +
- "Potential null pointer access: The field field0 may be null at this location\n" +
- "----------\n" +
- "7. ERROR in X.java (at line 22)\n" +
- " if (X.field0 == null && X.field0.toString() == \"\"){}\n" +
- " ^^^^^^\n" +
- "Potential null pointer access: The field field0 may be null at this location\n" +
- "----------\n",
- JavacTestOptions.Excuse.EclipseWarningConfiguredAsError
- );
-}
-
-// null analysis -- static fields from an anonymous type
-// Qualified access to static fields should also work
-public void testBug247564i_5() {
- Map compilerOptions = getCompilerOptions();
- compilerOptions.put(CompilerOptions.OPTION_ReportNonStaticAccessToStatic, CompilerOptions.IGNORE);
- this.runNegativeTest(
- true,
- new String[] {
- "X.java",
- "interface Anon{}\n" +
- "public class X {\n" +
- " static Object field0;\n" +
- " static Object field1;\n" +
- " Y getY(){ return new Y();}\n" +
- " X getX() { return new X();}\n" +
- " void goo(Object var) {\n" +
- " new Anon(){\n" +
- " void localfoo(){\n " +
- " if (new Y().getY().yField1 == null && field0.toString() == \"\"){}\n" + // no warn
- " if (getY().yField1 == null && field0.toString() == \"\"){}\n" + // no warn
- " if (new Y().getX().field0 == null && field0.toString() == \"\"){}\n" + // warn
- " if (getX().field0 == null && field0.toString() == \"\"){}\n" + // warn
- " if (getX().field0 == null && getX().field0.toString() == \"\"){}\n" + // no warn, getX() wipes out null info
- " if (getX().field0 == null && X.field0.toString() == \"\"){}\n" + // warn, qualified access
- // fields from other types, don't warn
- " if (new Y().getY().yField1 == null && Y.yField1.toString() == \"\"){}\n" + // no warn
- " if (getY().yField1 == null && Y.yField1.toString() == \"\"){}\n" + // no warn
- " if (getX().field0 == null && Y.yField1.toString() == \"\"){}\n" + // no warn
- // qualified accesses
- " if (Y.yField1 == null && field0.toString() == \"\"){}\n" + // no warn
- " if (Y.xiny.field0 == null && Y.xiny.field0.toString() == \"\"){}\n" + // warn, qualified access
- " if (Y.yField1 == null && Y.yField1.toString() == \"\"){}\n" + // no warn
- " if (Y.xiny.field1 == null && Y.yField1.toString() == \"\"){}\n" + // no warn
- " if (X.field0 == null && X.field0.toString() == \"\"){}\n" + // warn
- " if (X.field0 == null && getX().field0.toString() == \"\"){}\n" + // no warn
- " }\n" +
- " };\n" +
- " }\n" +
- "}\n" +
- "class Y{\n" +
- " Y getY(){ return new Y();}\n" +
- " X getX(){ return new X();}\n" +
- " static Object yField1;\n" +
- " static X xiny;\n" +
- "}"},
- null,
- compilerOptions,
- "----------\n" +
- "1. WARNING in X.java (at line 9)\n" +
- " void localfoo(){\n" +
- " ^^^^^^^^^^\n" +
- "The method localfoo() from the type new Anon(){} is never used locally\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 12)\n" +
- " if (new Y().getX().field0 == null && field0.toString() == \"\"){}\n" +
- " ^^^^^^\n" +
- "Potential null pointer access: The field field0 may be null at this location\n" +
- "----------\n" +
- "3. ERROR in X.java (at line 13)\n" +
- " if (getX().field0 == null && field0.toString() == \"\"){}\n" +
- " ^^^^^^\n" +
- "Potential null pointer access: The field field0 may be null at this location\n" +
- "----------\n" +
- "4. ERROR in X.java (at line 15)\n" +
- " if (getX().field0 == null && X.field0.toString() == \"\"){}\n" +
- " ^^^^^^\n" +
- "Potential null pointer access: The field field0 may be null at this location\n" +
- "----------\n" +
- "5. ERROR in X.java (at line 20)\n" +
- " if (Y.xiny.field0 == null && Y.xiny.field0.toString() == \"\"){}\n" +
- " ^^^^^^\n" +
- "Potential null pointer access: The field field0 may be null at this location\n" +
- "----------\n" +
- "6. ERROR in X.java (at line 23)\n" +
- " if (X.field0 == null && X.field0.toString() == \"\"){}\n" +
- " ^^^^^^\n" +
- "Potential null pointer access: The field field0 may be null at this location\n" +
- "----------\n",
- JavacTestOptions.Excuse.EclipseWarningConfiguredAsError
- );
-}
-// null analysis -- static fields
-// to check static field access from fieldReference and QualifiedReference when the type is parameterized
-public void testBug247564i_6() {
- if (this.complianceLevel < ClassFileConstants.JDK1_5) return;
- Map compilerOptions = getCompilerOptions();
- compilerOptions.put(CompilerOptions.OPTION_ReportNonStaticAccessToStatic, CompilerOptions.IGNORE);
- this.runNegativeTest(
- true,
- new String[] {
- "X.java",
- "public class X<T> {\n" +
- " static Object field0;\n" +
- " static Object field1;\n" +
- " Y getY(){ return new Y();}\n" +
- " X getX() { return new X();}\n" +
- " void goo(Object var) {\n" +
- " if (new Y().getY().yField1 == null && X.field0.toString() == \"\"){}\n" + // no warn
- " if (getY().yField1 == null && X.field0.toString() == \"\"){}\n" + // no warn
- " if (getY().yField1 == null && this.field0.toString() == \"\"){}\n" + // no warn
- " if (new Y().getX().field0 == null && X.field0.toString() == \"\"){}\n" + // warn
- " if (getX().field0 == null && X.field0.toString() == \"\"){}\n" + // warn
- " if (getX().field0 == null && this.field0.toString() == \"\"){}\n" + // warn
- " if (getX().field0 == null && getX().field0.toString() == \"\"){}\n" + // no warn, getX() wipes out null info
- // fields from other types, don't warn
- " if (new Y().getY().yField1 == null && Y.yField1.toString() == \"\"){}\n" + // no warn
- " if (getY().yField1 == null && Y.yField1.toString() == \"\"){}\n" + // no warn
- " if (getX().field0 == null && Y.yField1.toString() == \"\"){}\n" + // no warn
- " }\n" +
- "}\n" +
- "class Y<K>{\n" +
- " Y getY(){ return new Y();}\n" +
- " X getX(){ return new X();}\n" +
- " static Object yField1;\n" +
- "}"},
- null,
- compilerOptions,
- "----------\n" +
- "1. ERROR in X.java (at line 10)\n" +
- " if (new Y().getX().field0 == null && X.field0.toString() == \"\"){}\n" +
- " ^^^^^^\n" +
- "Potential null pointer access: The field field0 may be null at this location\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 11)\n" +
- " if (getX().field0 == null && X.field0.toString() == \"\"){}\n" +
- " ^^^^^^\n" +
- "Potential null pointer access: The field field0 may be null at this location\n" +
- "----------\n" +
- "3. ERROR in X.java (at line 12)\n" +
- " if (getX().field0 == null && this.field0.toString() == \"\"){}\n" +
- " ^^^^^^\n" +
- "Potential null pointer access: The field field0 may be null at this location\n" +
- "----------\n",
- JavacTestOptions.Excuse.EclipseWarningConfiguredAsError
- );
-}
-//null analysis -- simple case for field of parent type
-public void testBug247564j() {
- this.runConformTest(
- new String[] {
- "X.java",
- "public class X extends Y {\n" +
- " private Object fieldx;\n" +
- " void goo(Object var) {\n" +
- " if (fieldx == null && fieldy.toString() == \"\"){}\n" + // don't flag fieldy, nothing known
- " }\n" +
- "}\n" +
- "class Y{\n" +
- " protected Object fieldy = null;\n" +
- "}\n" +
- ""},
- ""
- );
-}
-
-// null analysis -- simple case for field in try-finally
-public void testBug247564k() {
- this.runConformTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " private Object f;\n" +
- " void goo(Object var) {\n" +
- " try {\n" +
- " int i = 10;\n" +
- " while (i<20){\n" +
- " if (i == 15) {\n" +
- " f = null;\n" +
- " break;\n" +
- " }\n" +
- " i++;\n" +
- " }\n" +
- " return;\n" +
- " } finally {\n" +
- " if (f != null && f.hashCode() == 0){}\n" +
- " }\n" +
- " }\n" +
- "}\n"},
- ""
- );
-}
-
-// null analysis -- simple case for field in try-finally
-// presence or absence of throw should not affect the behaviour
-public void testBug247564k_1() {
- this.runConformTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " private Object f;\n" +
- " void goo(Object var) throws Exception{\n" +
- " try {\n" +
- " int i = 10;\n" +
- " } catch(Exception e) {\n" +
- " f = null;\n" +
- " throw e;\n" +
- " } finally {\n" +
- " if (f != null && f.hashCode() == 0){}\n" +
- " }\n" +
- " }\n" +
- "}\n"},
- ""
- );
-}
-
-// null analysis -- simple case for field in try-finally
-// presence or absence of method call in finally should not affect the behaviour
-public void testBug247564k_2() {
- this.runConformTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " private Object f;\n" +
- " void gooCalls(){}\n" +
- " void goo(Object var) throws Exception{\n" +
- " try {\n" +
- " if (f != null) {}\n" +
- " } finally {\n" +
- " if (f != null ) {\n" +
- " gooCalls();\n" +
- " f.toString();\n" +
- " }\n" + // silent
- " }\n" +
- " }\n" +
- "}\n"},
- ""
- );
-}
-
-// null analysis -- simple case for constant field in try-catch-finally
-// presence or absence of method call in finally should not affect the behaviour
-public void testBug247564k_3() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " private static final Object f = null;\n" +
- " void gooCalls() throws NumberFormatException{}\n" +
- " void goo(Object var) throws Exception{\n" +
- " try {\n" +
- " gooCalls();\n" +
- " } catch(NumberFormatException e) {\n" +
- " if (f.hashCode() == 0){}\n" +
- " } finally {\n" +
- " gooCalls();\n" +
- " if (f.hashCode() == 0){}\n" +
- " }\n" +
- " }\n" +
- "}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 8)\n" +
- " if (f.hashCode() == 0){}\n" +
- " ^\n" +
- "Null pointer access: The field f can only be null at this location\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 11)\n" +
- " if (f.hashCode() == 0){}\n" +
- " ^\n" +
- "Null pointer access: The field f can only be null at this location\n" +
- "----------\n"
- );
-}
-
-// null analysis -- potentially redundant checks against the same field
-public void testBug247564l_1() {
- this.runConformTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " private Object f;\n" +
- " int foo() throws Exception{\n" +
- " if (f == null && f != null)\n" +
- " return 13;\n" +
- " return -13;\n" +
- " }\n" +
- " int goo() throws Exception{\n" +
- " if (f == null && f == null)\n" +
- " return 14;\n" +
- " return -14;\n" +
- " }\n" +
- " boolean hoo() throws Exception{\n" +
- " if (f == null)\n" +
- " return f != null;\n" +
- " return f == null;\n" +
- " }\n" +
- "}\n"},
- ""
- );
-}
-
-// null analysis -- fields assigned a def. non null value in a loop
-// comment 121
-public void testBug247564l_2() {
- this.runConformTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " private Object field;\n" +
- " void foo() throws Exception{\n" +
- " if (field != null) field.hashCode();\n" +
- " int i = 10;\n" +
- " while (i<20) {\n" +
- " if (field == null) field = new Object();\n" +
- " field.toString();\n" + // should not warn
- " i++;\n" +
- " }\n" +
- " }\n" +
- "}\n"},
- ""
- );
-}
-
-// null analysis -- checked and unchecked exceptions
-public void testBug247564m() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "class MyException extends Exception{}\n" +
- "public class X {\n" +
- " private Object f;\n" +
- " void gooCalls() throws MyException{}\n" +
- " void goo(){\n" +
- " try {\n" +
- " if (f == null) return;\n" +
- " gooCalls();\n" +
- " } catch(MyException e) {\n" + // checked Exception
- " f.toString();\n" + // silent - at gooCalls() in 'try', f is not going to be null
- " } catch(NumberFormatException e) {\n" + // unchecked Exception
- " f.toString();\n" + // could have come from anywhere, f can be null as doubted in 'try'
- " }\n" +
- " }\n" +
- "}\n"},
- "----------\n" +
- "1. WARNING in X.java (at line 1)\n" +
- " class MyException extends Exception{}\n" +
- " ^^^^^^^^^^^\n" +
- "The serializable class MyException does not declare a static final serialVersionUID field of type long\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 12)\n" +
- " f.toString();\n" +
- " ^\n" +
- "Potential null pointer access: The field f may be null at this location\n" +
- "----------\n"
- );
-}
-
-// null analysis -- check resetting of large no. of fields
-// https://bugs.eclipse.org/bugs/show_bug.cgi?id=247564#c161
-public void testBug247564n() {
- this.runConformTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- "Object field0, \n" +
- "field1, field2, field3, field4, \n" +
- "field5, field6, field7, field8, \n" +
- "field9, field10, field11, field12, \n" +
- "field13, field14, field15, field16, \n" +
- "field17, field18, field19, field20, \n" +
- "field21, field22, field23, field24, \n" +
- "field25, field26, field27, field28, \n" +
- "field29, field30, field31, field32, \n" +
- "field33, field34, field35, field36, \n" +
- "field37, field38, field39, field40, \n" +
- "field41, field42, field43, field44, \n" +
- "field45, field46, field47, field48, \n" +
- "field49, field50, field51, field52, \n" +
- "field53, field54, field55, field56, \n" +
- "field57, field58, field59, field60, \n" +
- "field61, field62, field63, field64; \n" +
- " static final Object o2 = new Object();\n" +
- " public X() {\n" +
- " field23 = null;\n" +
- " o2.toString();\n" +
- " if (field23.hashCode() == 0){}\n" + // don't warn
- " }\n" +
- "}\n"},
- ""
- );
-}
-// null analysis -- check resetting of large no. of fields
-// see also https://bugs.eclipse.org/bugs/show_bug.cgi?id=369381
-public void testBug247564n_2() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- "Object field0, \n" + // more than 64 fields
- "field1, field2, field3, field4, \n" +
- "field5, field6, field7, field8, \n" +
- "field9, field10, field11, field12, \n" +
- "field13, field14, field15, field16, \n" +
- "field17, field18, field19, field20, \n" +
- "field21, field22, field23, field24, \n" +
- "field25, field26, field27, field28, \n" +
- "field29, field30, field31, field32, \n" +
- "field33, field34, field35, field36, \n" +
- "field37, field38, field39, field40, \n" +
- "field41, field42, field43, field44, \n" +
- "field45, field46, field47, field48, \n" +
- "field49, field50, field51, field52, \n" +
- "field53, field54, field55, field56, \n" +
- "field57, field58, field59, field60, \n" +
- "field61, field62, field63, field64; \n" +
- " static final Object o2 = new Object();\n" +
- " public X() {\n" +
- " Object l0, l1, l2, l3, l4, l5, l6, l7, l8, l9,\n" + // more than 64 locals
- " l10, l11, l12, l13, l14, l15, l16, l17, l18, l19,\n" +
- " l20, l21, l22, l23, l24, l25, l26, l27, l28, l29,\n" +
- " l30, l31, l32, l33, l34, l35, l36, l37, l38, l39,\n" +
- " l40, l41, l42, l43, l44, l45, l46, l47, l48, l49,\n" +
- " l50, l51, l52, l53, l54, l55, l56, l57, l58, l59,\n" +
- " l60, l61, l62, l63, l64, l65, l66, l67, l68, l69;\n" +
- " l69 = null;\n" + // l69 has bits in extra[x][1]
- " o2.toString();\n" + // resetNullInfoForFields() must not reset any bits in extra[x][1]
- " l69.toString();\n" + // warn!
- " }\n" +
- "}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 30)\n" +
- " l69.toString();\n" +
- " ^^^\n" +
- "Null pointer access: The variable l69 can only be null at this location\n" +
- "----------\n"
- );
-}
-
-// null analysis - should not throw NPE
-// see also https://bugs.eclipse.org/bugs/show_bug.cgi?id=369381
-public void testBug369381() {
- this.runConformTest(
- new String[] {
- "X.java",
- "public class X extends XParent{\n" +
- " public void foo(X x, int i) {\n" +
- " if (this.field0.length == i){}\n" + // declaring class of 'length' is null. Dont throw NPE
- " }\n" +
- "}\n" +
- "class XParent {\n" +
- " protected Object[] field0 = {new Object()}; \n" +
- "}\n"
- },
- ""
- );
-}
-
-// null analysis -- with large no. of fields, no AIOOBE should be thrown
-// no. of static final fields less than no. of final-only fields
-public void _testBug369381a() {
- this.runConformTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- "static final Object field0 = null;\n " +
- "static final Object field1 = null;\n " +
- "static final Object field2 = null;\n " +
- "static final Object field3 = null;\n " +
- "static final Object field4 = null;\n " +
- "static final Object field5 = null;\n " +
- "static final Object field6 = null;\n " +
- "static final Object field7 = null;\n " +
- "static final Object field8 = null;\n " +
- "static final Object field9 = null;\n " +
- "static final Object field10 = null;\n" +
- "static final Object field11 = null;\n" +
- "static final Object field12 = null;\n" +
- "static final Object field13 = null;\n" +
- "static final Object field14 = null;\n" +
- "static final Object field15 = null;\n" +
- "static final Object field16 = null;\n" +
- "static final Object field17 = null;\n" +
- "static final Object field18 = null;\n" +
- "static final Object field19 = null;\n" +
- "static final Object field20 = null;\n" +
- "static final Object field21 = null;\n" +
- "static final Object field22 = null;\n" +
- "static final Object field23 = null;\n" +
- "static final Object field24 = null;\n" +
- "static final Object field25 = null;\n" +
- "static final Object field26 = null;\n" +
- "static final Object field27 = null;\n" +
- "static final Object field28 = null;\n" +
- "static final Object field29 = null;\n" +
- "static final Object field30 = null;\n" +
- "static final Object field31 = null;\n" +
- "static final Object field32 = null;\n" +
- "static final Object field33 = null;\n" +
- "static final Object field34 = null;\n" +
- "static final Object field35 = null;\n" +
- "static final Object field36 = null;\n" +
- "static final Object field37 = null;\n" +
- "static final Object field38 = null;\n" +
- "static final Object field39 = null;\n" +
- "static final Object field40 = null;\n" +
- "static final Object field41 = null;\n" +
- "static final Object field42 = null;\n" +
- "static final Object field43 = null;\n" +
- "static final Object field44 = null;\n" +
- "static final Object field45 = null;\n" +
- "static final Object field46 = null;\n" +
- "static final Object field47 = null;\n" +
- "static final Object field48 = null;\n" +
- "static final Object field49 = null;\n" +
- "static final Object field50 = null;\n" +
- "static final Object field51 = null;\n" +
- "static final Object field52 = null;\n" +
- "static final Object field53 = null;\n" +
- "static final Object field54 = null;\n" +
- "static final Object field55 = null;\n" +
- "static final Object field56 = null;\n" +
- "static final Object field57 = null;\n" +
- "static final Object field58 = null;\n" +
- "static final Object field59 = null;\n" +
- "static final Object field60 = null;\n" +
- "static final Object field61 = null;\n" +
- "static final Object field62 = null;\n" +
- "static final Object field63 = null;\n" +
- "static final Object field64 = null;\n" +
- "static final Object field65 = null;\n" +
- "static final Object field66 = null;\n" +
- "static final Object field67 = null;\n" +
- "static final Object field68 = null;\n" +
- "static final Object field69 = null;\n" +
- "final Object field00 = null; \n" +
- "final Object field01 = null; \n" +
- "final Object field02 = null; \n" +
- "final Object field03 = null; \n" +
- "final Object field04 = null; \n" +
- "final Object field05 = null; \n" +
- "final Object field06 = null; \n" +
- "final Object field07 = null; \n" +
- "final Object field08 = null; \n" +
- "final Object field09 = null; \n" +
- "final Object field010 = null;\n" +
- "final Object field011 = null;\n" +
- "final Object field012 = null;\n" +
- "final Object field013 = null;\n" +
- "final Object field014 = null;\n" +
- "final Object field015 = null;\n" +
- "final Object field016 = null;\n" +
- "final Object field017 = null;\n" +
- "final Object field018 = null;\n" +
- "final Object field019 = null;\n" +
- "final Object field020 = null;\n" +
- "final Object field021 = null;\n" +
- "final Object field022 = null;\n" +
- "final Object field023 = null;\n" +
- "final Object field024 = null;\n" +
- "final Object field025 = null;\n" +
- "final Object field026 = null;\n" +
- "final Object field027 = null;\n" +
- "final Object field028 = null;\n" +
- "final Object field029 = null;\n" +
- "final Object field030 = null;\n" +
- "final Object field031 = null;\n" +
- "final Object field032 = null;\n" +
- "final Object field033 = null;\n" +
- "final Object field034 = null;\n" +
- "final Object field035 = null;\n" +
- "final Object field036 = null;\n" +
- "final Object field037 = null;\n" +
- "final Object field038 = null;\n" +
- "final Object field039 = null;\n" +
- "final Object field040 = null;\n" +
- "final Object field041 = null;\n" +
- "final Object field042 = null;\n" +
- "final Object field043 = null;\n" +
- "final Object field044 = null;\n" +
- "final Object field045 = null;\n" +
- "final Object field046 = null;\n" +
- "final Object field047 = null;\n" +
- "final Object field048 = null;\n" +
- "final Object field049 = null;\n" +
- "final Object field050 = null;\n" +
- "final Object field051 = null;\n" +
- "final Object field052 = null;\n" +
- "final Object field053 = null;\n" +
- "final Object field054 = null;\n" +
- "final Object field055 = null;\n" +
- "final Object field056 = null;\n" +
- "final Object field057 = null;\n" +
- "final Object field058 = null;\n" +
- "final Object field059 = null;\n" +
- "final Object field060 = null;\n" +
- "final Object field061 = null;\n" +
- "final Object field062 = null;\n" +
- "final Object field063 = null;\n" +
- "final Object field064 = null;\n" +
- "final Object field065 = null;\n" +
- "final Object field066 = null;\n" +
- "final Object field067 = null;\n" +
- "final Object field068 = null;\n" +
- "final Object field069 = null;\n" +
- " public X() {\n" +
- " }\n" +
- "}\n"},
- ""
- );
-}
-}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java
index c587eaf..beeb07b 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java
@@ -26,7 +26,7 @@
public class ResourceLeakTests extends AbstractRegressionTest {
static {
-// TESTS_NAMES = new String[] { "testBug368709"};
+// TESTS_NAMES = new String[] { "test066"};
// TESTS_NUMBERS = new int[] { 50 };
// TESTS_RANGE = new int[] { 11, -1 };
}
@@ -1489,7 +1489,7 @@
" final FileReader reader23 = new FileReader(\"file\");\n" +
" provider = new ResourceProvider() {\n" +
" public FileReader provide() {\n" +
- " return reader23;\n" +
+ " return reader23;\n" + // responsibility now lies at the caller of this method
" }\n" +
" };\n" +
" }\n" +
@@ -1500,11 +1500,6 @@
" final FileReader reader31 = new FileReader(\"file\");\n" +
" ^^^^^^^^\n" +
"Potential resource leak: 'reader31' may not be closed\n" +
- "----------\n" +
- "2. WARNING in X.java (at line 17)\n" +
- " final FileReader reader23 = new FileReader(\"file\");\n" +
- " ^^^^^^^^\n" +
- "Potential resource leak: 'reader23' may not be closed\n" +
"----------\n",
null,
true,
@@ -3143,12 +3138,7 @@
"}\n"
},
"----------\n" +
- "1. ERROR in X.java (at line 15)\n" +
- " return wc.open(getObjectId(), type).openStream();\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Resource leak: \'in\' is not closed at this location\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 18)\n" +
+ "1. ERROR in X.java (at line 18)\n" +
" return new ObjectStream.Filter(type, size, in);\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"Potential resource leak: \'in\' may not be closed at this location\n" +
@@ -3189,4 +3179,535 @@
true,
options);
}
+
+// Bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+// example from comment 3
+public void test064() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ this.runNegativeTest(new String[] {
+ "Test064.java",
+ "import java.io.*;\n" +
+ "public class Test064 {\n" +
+ " void foo(File outfile) {\n" +
+ " OutputStream out= System.out;\n" +
+ " if (outfile != null) {\n" +
+ " try {\n" +
+ " out = new FileOutputStream(outfile);\n" +
+ " } catch (java.io.IOException e) {\n" +
+ " throw new RuntimeException(e);\n" +
+ " }\n" +
+ " }\n" +
+ " setOutput(out);\n" +
+ " }\n" +
+ " private void setOutput(OutputStream out) { }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in Test064.java (at line 7)\n" +
+ " out = new FileOutputStream(outfile);\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Potential resource leak: \'out\' may not be closed\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+// example from comment 10
+// disabled, because basic null-analysis machinery doesn't support this pattern
+// see also Bug 370424 - [compiler][null] throw-catch analysis for null flow could be more precise
+public void _test065() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.IGNORE);
+ this.runConformTest(new String[] {
+ "Test065.java",
+ "import java.io.*;\n" +
+ "class MyException extends Exception{}\n" +
+ "public class Test065 {\n" +
+ " void foo(String fileName) throws IOException, MyException {\n" +
+ " FileReader fileRead = new FileReader(fileName);\n" +
+ " BufferedReader bufRead = new BufferedReader(fileRead);\n" +
+ " LineNumberReader lineReader = new LineNumberReader(bufRead);\n" +
+ " try {\n" +
+ " while (lineReader.readLine() != null) {\n" +
+ " bufRead.close();\n" +
+ " callSome(); // only this can throw MyException\n" +
+ " }\n" +
+ " } catch (MyException e) {\n" +
+ " throw e; // Pot. leak reported here\n" +
+ " }\n" +
+ " bufRead.close(); \n" +
+ " }\n" +
+ " private void callSome() throws MyException\n" +
+ " {\n" +
+ " \n" +
+ " }\n" +
+ "}\n"
+ },
+ "",
+ null,
+ true,
+ null,
+ options,
+ null);
+}
+
+// Bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+// example from comment 11
+public void test066() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.IGNORE);
+ this.runNegativeTest(new String[] {
+ "Test066.java",
+ "import java.io.*;\n" +
+ "class MyException extends Exception{}\n" +
+ "public class Test066 {\n" +
+ " void countFileLines(String fileName) throws IOException {\n" +
+ " FileReader fileRead = new FileReader(fileName);\n" +
+ " BufferedReader bufRead = new BufferedReader(fileRead);\n" +
+ " LineNumberReader lineReader = new LineNumberReader(bufRead);\n" +
+ " while (lineReader.readLine() != null) {\n" +
+ " if (lineReader.markSupported())\n" +
+ " throw new IOException();\n" +
+ " bufRead.close();\n" +
+ " }\n" +
+ " bufRead.close();\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in Test066.java (at line 10)\n" +
+ " throw new IOException();\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Potential resource leak: \'lineReader\' may not be closed at this location\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+// example from comment 11 - variant with closing top-level resource
+public void test066b() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.IGNORE);
+ this.runNegativeTest(new String[] {
+ "Test066.java",
+ "import java.io.*;\n" +
+ "class MyException extends Exception{}\n" +
+ "public class Test066 {\n" +
+ " void countFileLines(String fileName) throws IOException {\n" +
+ " FileReader fileRead = new FileReader(fileName);\n" +
+ " BufferedReader bufRead = new BufferedReader(fileRead);\n" +
+ " LineNumberReader lineReader = new LineNumberReader(bufRead);\n" +
+ " while (lineReader.readLine() != null) {\n" +
+ " if (lineReader.markSupported())\n" +
+ " throw new IOException();\n" +
+ " lineReader.close();\n" +
+ " }\n" +
+ " lineReader.close();\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in Test066.java (at line 10)\n" +
+ " throw new IOException();\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Potential resource leak: \'lineReader\' may not be closed at this location\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+
+// Bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+// example from comment 12
+// disabled because null info after try-catch is too weak,
+// see also Bug 370424 - [compiler][null] throw-catch analysis for null flow could be more precise
+public void _test067() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.IGNORE);
+ this.runConformTest(new String[] {
+ "Test067.java",
+ "import java.io.*;\n" +
+ "public class Test067 {\n" +
+ " public void comment12() throws IOException {\n" +
+ " LineNumberReader o = null;\n" +
+ " try {\n" +
+ " o = new LineNumberReader(null); \n" +
+ " } catch (NumberFormatException e) { \n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ "",
+ null,
+ true,
+ null,
+ options,
+ null);
+}
+
+// Bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+// example from comment 12
+// disabled because null info after try-catch is too weak,
+// see also Bug 370424 - [compiler][null] throw-catch analysis for null flow could be more precise
+public void _test067b() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.IGNORE);
+ this.runConformTest(new String[] {
+ "Test067.java",
+ "import java.io.*;\n" +
+ "public class Test067 {\n" +
+ " public void comment12b() throws IOException {\n" +
+ " LineNumberReader o = new LineNumberReader(null);\n" +
+ " try {\n" +
+ " o.close();\n" +
+ " } catch (NumberFormatException e) {\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ "",
+ null,
+ true,
+ null,
+ options,
+ null);
+}
+
+// Bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+// example from comment 13
+public void test068() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.IGNORE);
+ this.runConformTest(new String[] {
+ "Test068.java",
+ "import java.io.*;\n" +
+ "public class Test068 {\n" +
+ " class ProcessingStep extends OutputStream {\n" +
+ " public void write(int b) throws IOException {}\n" +
+ " public OutputStream getDestination() { return null; }\n" +
+ " }\n" +
+ " class ArtifactOutputStream extends OutputStream {\n" +
+ " public void write(int b) throws IOException {}\n" +
+ " }" +
+ " ArtifactOutputStream comment13(OutputStream stream) {\n" +
+ " OutputStream current = stream;\n" +
+ " while (current instanceof ProcessingStep)\n" +
+ " current = ((ProcessingStep) current).getDestination();\n" + // we previously saw a bogus warning here.
+ " if (current instanceof ArtifactOutputStream)\n" +
+ " return (ArtifactOutputStream) current;\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n"
+ },
+ "",
+ null,
+ true,
+ null,
+ options,
+ null);
+}
+
+// Bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+// example from comment 16
+public void test069() {
+ if (this.complianceLevel < ClassFileConstants.JDK1_5) return; // generics used
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.IGNORE);
+ this.runConformTest(new String[] {
+ "Test069.java",
+ "import java.io.*;\n" +
+ "import java.util.Collection;\n" +
+ "public class Test069 {\n" +
+ " class Profile {}\n" +
+ " class CoreException extends Exception {}\n" +
+ " void writeProfilesToStream(Collection<Profile> p, OutputStream s, String enc) {}\n" +
+ " CoreException createException(IOException ioex, String message) { return new CoreException(); }\n" +
+ " public void comment16(Collection<Profile> profiles, File file, String encoding) throws CoreException {\n" +
+ " final OutputStream stream;\n" +
+ " try {\n" +
+ " stream= new FileOutputStream(file);\n" +
+ " try {\n" +
+ " writeProfilesToStream(profiles, stream, encoding);\n" +
+ " } finally {\n" +
+ " try { stream.close(); } catch (IOException e) { /* ignore */ }\n" +
+ " }\n" +
+ " } catch (IOException e) {\n" +
+ " throw createException(e, \"message\"); // should not shout here\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ "",
+ null,
+ true,
+ null,
+ options,
+ null);
+}
+
+// Bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+// referenced in array initializer
+public void test070() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.IGNORE);
+ this.runNegativeTest(new String[] {
+ "Test070.java",
+ "import java.io.*;\n" +
+ "public class Test070 {\n" +
+ " void storeInArray(String fileName) throws IOException {\n" +
+ " FileReader fileRead = new FileReader(fileName);\n" +
+ " closeThemAll(new FileReader[] { fileRead });\n" +
+ " }\n" +
+ " void closeThemAll(FileReader[] readers) { }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in Test070.java (at line 4)\n" +
+ " FileReader fileRead = new FileReader(fileName);\n" +
+ " ^^^^^^^^\n" +
+ "Potential resource leak: \'fileRead\' may not be closed\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+
+// Bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+// referenced in array initializer
+public void test071() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.IGNORE);
+ this.runNegativeTest(new String[] {
+ "Test071.java",
+ "import java.io.*;\n" +
+ "public class Test071 {\n" +
+ " class ReaderHolder {\n" +
+ " FileReader reader;\n" +
+ " }\n" +
+ " private FileReader getReader() {\n" +
+ " return null;\n" +
+ " }\n" +
+ " void invokeCompiler(ReaderHolder readerHolder, boolean flag) throws FileNotFoundException {\n" +
+ " FileReader reader = readerHolder.reader;\n" +
+ " if (reader == null)\n" +
+ " reader = getReader();\n" +
+ " try {\n" +
+ " return;\n" +
+ " } finally {\n" +
+ " try {\n" +
+ " if (flag)\n" +
+ " reader.close();\n" +
+ " } catch (IOException e) {\n" +
+ " // nop\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in Test071.java (at line 14)\n" +
+ " return;\n" +
+ " ^^^^^^^\n" +
+ "Potential resource leak: \'reader\' may not be closed at this location\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+
+// Bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+// referenced in array initializer
+// disabled because it would require correlation analysis between the tracking variable and its original
+// need to pass to downstream: either (nonnull & open) or (null)
+public void _test071b() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.IGNORE);
+ this.runNegativeTest(new String[] {
+ "Test071b.java",
+ "import java.io.*;\n" +
+ "public class Test071b {\n" +
+ " private FileReader getReader() {\n" +
+ " return null;\n" +
+ " }\n" +
+ " void invokeCompiler(boolean flag) throws FileNotFoundException {\n" +
+ " FileReader reader = null;\n" +
+ " if (flag)\n" +
+ " reader = new FileReader(\"file\");\n" +
+ " if (reader == null)\n" +
+ " reader = getReader();\n" +
+ " try {\n" +
+ " return;\n" +
+ " } finally {\n" +
+ " try {\n" +
+ " if (flag)\n" +
+ " reader.close();\n" +
+ " } catch (IOException e) {\n" +
+ " // nop\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in Test071b.java (at line 13)\n" +
+ " return;\n" +
+ " ^^^^^^^\n" +
+ "Potential resource leak: \'reader\' may not be closed at this location\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+
+// Bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+// throw inside loop inside try - while closed in finally
+public void test072() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.IGNORE);
+ this.runConformTest(new String[] {
+ "Test072.java",
+ "import java.io.*;\n" +
+ "public class Test072 {\n" +
+ " void readState(File file) {\n" +
+ " DataInputStream in = null;\n" +
+ " try {\n" +
+ " in= new DataInputStream(new BufferedInputStream(new FileInputStream(file)));\n" +
+ " int sizeOfFlags = in.readInt();\n" +
+ " for (int i = 0; i < sizeOfFlags; ++i) {\n" +
+ " String childPath = in.readUTF();\n" +
+ " if (childPath.length() == 0)\n" +
+ " throw new IOException();\n" +
+ " }\n" +
+ " }\n" +
+ " catch (IOException ioe) { /* nop */ }\n" +
+ " finally {\n" +
+ " if (in != null) {\n" +
+ " try {in.close();} catch (IOException ioe) {}\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ "",
+ null,
+ true,
+ null,
+ options,
+ null);
+}
+
+// Bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+// unspecific parameter is casted into a resource, yet need to mark as OWNED_BY_OUTSIDE
+public void test073() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.IGNORE);
+ this.runConformTest(new String[] {
+ "Test073.java",
+ "import java.io.*;\n" +
+ "public class Test073 {\n" +
+ " String getEncoding(Object reader) {\n" +
+ " if (reader instanceof FileReader) {\n" +
+ " final FileReader fr = (FileReader) reader;\n" +
+ " return fr.getEncoding();\n" +
+ " }\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n"
+ },
+ "",
+ null,
+ true,
+ null,
+ options,
+ null);
+}
+
+// Bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+// status after nested try-finally
+public void test074() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.IGNORE);
+ this.runNegativeTest(new String[] {
+ "Test074.java",
+ "import java.io.*;\n" +
+ "public class Test074 {\n" +
+ " void foo() throws FileNotFoundException {\n" +
+ " FileOutputStream out = null;\n" +
+ " try {\n" +
+ " out = new FileOutputStream(\"outfile\");\n" +
+ " } finally {\n" +
+ " try {\n" +
+ " out.flush();\n" +
+ " out.close();\n" +
+ " } catch (IOException e) {\n" +
+ " e.printStackTrace();\n" +
+ " }\n" +
+ " out = null;\n" + // unclosed if exception occurred on flush()
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in Test074.java (at line 14)\n" +
+ " out = null;\n" +
+ " ^^^^^^^^^^\n" +
+ "Potential resource leak: \'out\' may not be closed at this location\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 370639 - [compiler][resource] restore the default for resource leak warnings
+// check that the default is warning
+public void test075() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.File;\n" +
+ "import java.io.FileReader;\n" +
+ "import java.io.IOException;\n" +
+ "public class X {\n" +
+ " void foo() throws IOException {\n" +
+ " File file = new File(\"somefile\");\n" +
+ " FileReader fileReader = new FileReader(file);\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. WARNING in X.java (at line 7)\n" +
+ " FileReader fileReader = new FileReader(file);\n" +
+ " ^^^^^^^^^^\n" +
+ "Resource leak: 'fileReader' is never closed\n" +
+ "----------\n");
+}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/TestVerifier.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/TestVerifier.java
index 6f4e1fd..cdba7ba 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/TestVerifier.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/TestVerifier.java
@@ -23,7 +23,7 @@
boolean reuseVM = true;
//{ObjectTeams: support reuse even in presence of vmargs, if unchanged:
- protected String[] vmArguments = null;
+ protected String[] fVMArguments = null;
// SH}
String[] classpathCache;
LocalVirtualMachine vm;
@@ -119,7 +119,7 @@
}
String fileName = dir + File.separator + simpleName + ".java";
Util.writeToFile(getVerifyTestsCode(), fileName);
- BatchCompiler.compile("\"" + fileName + "\" -d \"" + verifierDir + "\" -classpath \"" + Util.getJavaClassLibsAsString() + "\" -warn:-resource", new PrintWriter(System.out), new PrintWriter(System.err), null/*progress*/);
+ BatchCompiler.compile("\"" + fileName + "\" -d \"" + verifierDir + "\" -warn:-resource -classpath \"" + Util.getJavaClassLibsAsString() + "\"", new PrintWriter(System.out), new PrintWriter(System.err), null/*progress*/);
}
public void execute(String className, String[] classpaths) {
this.outputBuffer = new StringBuffer();
@@ -148,236 +148,257 @@
*/
private String getVerifyTestsCode() {
return
- "/*******************************************************************************" +
- " * Copyright (c) 2000, 2005 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:" +
- " * IBM Corporation - initial API and implementation" +
- " *******************************************************************************/" +
- "package org.eclipse.jdt.core.tests.util;\n" +
- "\n" +
- "import java.lang.reflect.*;\n" +
- "import java.io.*;\n" +
- "import java.net.*;\n" +
- "import java.util.*;\n" +
- "\n" +
- "/******************************************************\n" +
- " * \n" +
- " * IMPORTANT NOTE: If modifying this class, copy the source to TestVerifier#getVerifyTestsCode()\n" +
- " * (see this method for details)\n" +
- " * \n" +
- " ******************************************************/\n" +
- "\n" +
- "public class VerifyTests {\n" +
- " int portNumber;\n" +
- " Socket socket;\n" +
- "\n" +
- "/**\n" +
- " * NOTE: Code copied from junit.util.TestCaseClassLoader.\n" +
- " *\n" +
- " * A custom class loader which enables the reloading\n" +
- " * of classes for each test run. The class loader\n" +
- " * can be configured with a list of package paths that\n" +
- " * should be excluded from loading. The loading\n" +
- " * of these packages is delegated to the system class\n" +
- " * loader. They will be shared across test runs.\n" +
- " * <p>\n" +
- " * The list of excluded package paths is specified in\n" +
- " * a properties file \"excluded.properties\" that is located in \n" +
- " * the same place as the TestCaseClassLoader class.\n" +
- " * <p>\n" +
- " * <b>Known limitation:</b> the VerifyClassLoader cannot load classes\n" +
- " * from jar files.\n" +
- " */\n" +
- "\n" +
- "\n" +
- "public class VerifyClassLoader extends ClassLoader {\n" +
- " /** scanned class path */\n" +
- " private String[] fPathItems;\n" +
- " \n" +
- " /** excluded paths */\n" +
- " private String[] fExcluded= {};\n" +
- "\n" +
- " /**\n" +
- " * Constructs a VerifyClassLoader. It scans the class path\n" +
- " * and the excluded package paths\n" +
- " */\n" +
- " public VerifyClassLoader() {\n" +
- " super();\n" +
- " String classPath= System.getProperty(\"java.class.path\");\n" +
- " String separator= System.getProperty(\"path.separator\");\n" +
- " \n" +
- " // first pass: count elements\n" +
- " StringTokenizer st= new StringTokenizer(classPath, separator);\n" +
- " int i= 0;\n" +
- " while (st.hasMoreTokens()) {\n" +
- " st.nextToken();\n" +
- " i++;\n" +
- " }\n" +
- " // second pass: split\n" +
- " fPathItems= new String[i];\n" +
- " st= new StringTokenizer(classPath, separator);\n" +
- " i= 0;\n" +
- " while (st.hasMoreTokens()) {\n" +
- " fPathItems[i++]= st.nextToken();\n" +
- " }\n" +
- "\n" +
- " }\n" +
- " public java.net.URL getResource(String name) {\n" +
- " return ClassLoader.getSystemResource(name);\n" +
- " }\n" +
- " public InputStream getResourceAsStream(String name) {\n" +
- " return ClassLoader.getSystemResourceAsStream(name);\n" +
- " }\n" +
- " protected boolean isExcluded(String name) {\n" +
- " // exclude the \"java\" packages.\n" +
- " // They always need to be excluded so that they are loaded by the system class loader\n" +
- " if (name.startsWith(\"java\"))\n" +
+ "/*******************************************************************************\n" +
+ " * Copyright (c) 2000, 2011 IBM Corporation and others.\n" +
+ " * All rights reserved. This program and the accompanying materials\n" +
+ " * are made available under the terms of the Eclipse Public License v1.0\n" +
+ " * which accompanies this distribution, and is available at\n" +
+ " * http://www.eclipse.org/legal/epl-v10.html\n" +
+ " *\n" +
+ " * Contributors:\n" +
+ " * IBM Corporation - initial API and implementation\n" +
+ " *******************************************************************************/\n" +
+ "package org.eclipse.jdt.core.tests.util;\n" +
+ "\n" +
+ "import java.io.DataInputStream;\n" +
+ "import java.io.DataOutputStream;\n" +
+ "import java.io.File;\n" +
+ "import java.io.FileInputStream;\n" +
+ "import java.io.FileNotFoundException;\n" +
+ "import java.io.IOException;\n" +
+ "import java.io.InputStream;\n" +
+ "import java.lang.reflect.InvocationTargetException;\n" +
+ "import java.lang.reflect.Method;\n" +
+ "import java.net.ServerSocket;\n" +
+ "import java.net.Socket;\n" +
+ "import java.util.StringTokenizer;\n" +
+ "\n" +
+ "/******************************************************\n" +
+ " *\n" +
+ " * IMPORTANT NOTE: If modifying this class, copy the source to TestVerifier#getVerifyTestsCode()\n" +
+ " * (see this method for details)\n" +
+ " *\n" +
+ " ******************************************************/\n" +
+ "\n" +
+ "public class VerifyTests {\n" +
+ " int portNumber;\n" +
+ " Socket socket;\n" +
+ "\n" +
+ "/**\n" +
+ " * NOTE: Code copied from junit.util.TestCaseClassLoader.\n" +
+ " *\n" +
+ " * A custom class loader which enables the reloading\n" +
+ " * of classes for each test run. The class loader\n" +
+ " * can be configured with a list of package paths that\n" +
+ " * should be excluded from loading. The loading\n" +
+ " * of these packages is delegated to the system class\n" +
+ " * loader. They will be shared across test runs.\n" +
+ " * <p>\n" +
+ " * The list of excluded package paths is specified in\n" +
+ " * a properties file \"excluded.properties\" that is located in\n" +
+ " * the same place as the TestCaseClassLoader class.\n" +
+ " * <p>\n" +
+ " * <b>Known limitation:</b> the VerifyClassLoader cannot load classes\n" +
+ " * from jar files.\n" +
+ " */\n" +
+ "\n" +
+ "\n" +
+ "public class VerifyClassLoader extends ClassLoader {\n" +
+ " /** scanned class path */\n" +
+ " private String[] pathItems;\n" +
+ "\n" +
+ " /** excluded paths */\n" +
+ " private String[] excluded= {};\n" +
+ "\n" +
+ " /**\n" +
+ " * Constructs a VerifyClassLoader. It scans the class path\n" +
+ " * and the excluded package paths\n" +
+ " */\n" +
+ " public VerifyClassLoader() {\n" +
+ " super();\n" +
+ " String classPath= System.getProperty(\"java.class.path\");\n" +
+ " String separator= System.getProperty(\"path.separator\");\n" +
+ "\n" +
+ " // first pass: count elements\n" +
+ " StringTokenizer st= new StringTokenizer(classPath, separator);\n" +
+ " int i= 0;\n" +
+ " while (st.hasMoreTokens()) {\n" +
+ " st.nextToken();\n" +
+ " i++;\n" +
+ " }\n" +
+ " // second pass: split\n" +
+ " this.pathItems= new String[i];\n" +
+ " st= new StringTokenizer(classPath, separator);\n" +
+ " i= 0;\n" +
+ " while (st.hasMoreTokens()) {\n" +
+ " this.pathItems[i++]= st.nextToken();\n" +
+ " }\n" +
+ "\n" +
+ " }\n" +
+ " public java.net.URL getResource(String name) {\n" +
+ " return ClassLoader.getSystemResource(name);\n" +
+ " }\n" +
+ " public InputStream getResourceAsStream(String name) {\n" +
+ " return ClassLoader.getSystemResourceAsStream(name);\n" +
+ " }\n" +
+ " protected boolean isExcluded(String name) {\n" +
+ " // exclude the \"java\" packages.\n" +
+ " // They always need to be excluded so that they are loaded by the system class loader\n" +
+ " if (name.startsWith(\"java\"))\n" +
+ " return true;\n" +
+ "\n" +
+//{ObjectTeams: don't process core OT-classes either (unpacked .class not available on classpath):
+ " if (name.startsWith(\"org.objectteams\"))\n" +
" return true;\n" +
" \n" +
-//{ObjectTeams: don't process core OT-classes either (unpacked .class not available on classpath):
-" if (name.startsWith(\"org.objectteams\"))\n" +
-" return true;\n" +
-" \n" +
-" if (name.startsWith(\"org.eclipse.objectteams.otre\"))\n" +
-" return true;\n" +
-" \n" +
-" if (name.startsWith(\"org.apache.bcel\"))\n" +
-" return true;\n" +
-" \n" +
-" if (name.startsWith(\"sun\"))\n" + // have a test that needs sun/reflect/SerializationConstructorAccessorImpl
-" return true;\n" +
-" \n" +
+ " if (name.startsWith(\"org.eclipse.objectteams.otre\"))\n" +
+ " return true;\n" +
+ " \n" +
+ " if (name.startsWith(\"org.apache.bcel\"))\n" +
+ " return true;\n" +
+ " \n" +
+ " if (name.startsWith(\"sun\"))\n" + // have a test that needs sun/reflect/SerializationConstructorAccessorImpl
+ " return true;\n" +
+ " \n" +
// SH}
- " // exclude the user defined package paths\n" +
- " for (int i= 0; i < fExcluded.length; i++) {\n" +
- " if (name.startsWith(fExcluded[i])) {\n" +
- " return true;\n" +
- " }\n" +
- " }\n" +
- " return false; \n" +
- " }\n" +
- " public synchronized Class loadClass(String name, boolean resolve)\n" +
- " throws ClassNotFoundException {\n" +
- " \n" +
- " Class c= findLoadedClass(name);\n" +
- " if (c != null)\n" +
- " return c;\n" +
- " //\n" +
- " // Delegate the loading of excluded classes to the\n" +
- " // standard class loader.\n" +
- " //\n" +
- " if (isExcluded(name)) {\n" +
- " try {\n" +
- " c= findSystemClass(name);\n" +
- " return c;\n" +
- " } catch (ClassNotFoundException e) {\n" +
- " // keep searching\n" +
- " }\n" +
- " }\n" +
- " File file= locate(name);\n" +
- " if (file == null)\n" +
- " throw new ClassNotFoundException();\n" +
- " byte data[]= loadClassData(file);\n" +
- " c= defineClass(name, data, 0, data.length);\n" +
- " if (resolve) \n" +
- " resolveClass(c);\n" +
- " return c;\n" +
- " }\n" +
- " private byte[] loadClassData(File f) throws ClassNotFoundException {\n" +
- " try {\n" +
- " //System.out.println(\"loading: \"+f.getPath());\n" +
- " FileInputStream stream= new FileInputStream(f);\n" +
- " \n" +
- " try {\n" +
- " byte[] b= new byte[stream.available()];\n" +
- " stream.read(b);\n" +
- " stream.close();\n" +
- " return b;\n" +
- " }\n" +
- " catch (IOException e) {\n" +
- " throw new ClassNotFoundException();\n" +
- " }\n" +
- " }\n" +
- " catch (FileNotFoundException e) {\n" +
- " throw new ClassNotFoundException();\n" +
- " }\n" +
- " }\n" +
- " /**\n" +
- " * Locate the given file.\n" +
- " * @return Returns null if file couldn\'t be found.\n" +
- " */\n" +
- " private File locate(String fileName) { \n" +
- " if (fileName != null) {\n" +
- " fileName= fileName.replace(\'.\', \'/\')+\".class\";\n" +
- " File path= null;\n" +
- " for (int i= 0; i < fPathItems.length; i++) {\n" +
- " path= new File(fPathItems[i], fileName);\n" +
- " if (path.exists())\n" +
- " return path;\n" +
- " }\n" +
- " }\n" +
- " return null;\n" +
- " }\n" +
- "}\n" +
- " \n" +
- "public void loadAndRun(String className) throws Throwable {\n" +
- " //System.out.println(\"Loading \" + className + \"...\");\n" +
- " Class testClass = new VerifyClassLoader().loadClass(className);\n" +
- " //System.out.println(\"Loaded \" + className);\n" +
- " try {\n" +
- " Method main = testClass.getMethod(\"main\", new Class[] {String[].class});\n" +
- " //System.out.println(\"Running \" + className);\n" +
- " main.invoke(null, new Object[] {new String[] {}});\n" +
- " //System.out.println(\"Finished running \" + className);\n" +
- " } catch (NoSuchMethodException e) {\n" +
- " return;\n" +
- " } catch (InvocationTargetException e) {\n" +
- " throw e.getTargetException();\n" +
- " }\n" +
- "}\n" +
- "public static void main(String[] args) throws IOException {\n" +
- " VerifyTests verify = new VerifyTests();\n" +
- " verify.portNumber = Integer.parseInt(args[0]);\n" +
- " verify.run();\n" +
- "}\n" +
- "public void run() throws IOException {\n" +
- " ServerSocket server = new ServerSocket(this.portNumber);\n" +
- " this.socket = server.accept();\n" +
- " this.socket.setTcpNoDelay(true);\n" +
- " server.close();\n" +
- "\n" +
- " final DataInputStream in = new DataInputStream(this.socket.getInputStream());\n" +
- " final DataOutputStream out = new DataOutputStream(this.socket.getOutputStream());\n" +
- " while (true) {\n" +
- " final String className = in.readUTF();\n" +
- " Thread thread = new Thread() {\n" +
- " public void run() {\n" +
- " try {\n" +
- " loadAndRun(className);\n" +
- " out.writeBoolean(true);\n" +
- " System.err.println(VerifyTests.class.getName());\n" +
- " System.out.println(VerifyTests.class.getName());\n" +
- " } catch (Throwable e) {\n" +
- " e.printStackTrace();\n" +
- " try {\n" +
- " System.err.println(VerifyTests.class.getName());\n" +
- " System.out.println(VerifyTests.class.getName());\n" +
- " out.writeBoolean(false);\n" +
- " } catch (IOException e1) {\n" +
- " // ignore\n" +
- " }\n" +
- " }\n" +
- " }\n" +
- " };\n" +
- " thread.start();\n" +
- " }\n" +
- "}\n" +
- "}\n";
+ " // exclude the user defined package paths\n" +
+ " for (int i= 0; i < this.excluded.length; i++) {\n" +
+ " if (name.startsWith(this.excluded[i])) {\n" +
+ " return true;\n" +
+ " }\n" +
+ " }\n" +
+ " return false;\n" +
+ " }\n" +
+ " public synchronized Class loadClass(String name, boolean resolve)\n" +
+ " throws ClassNotFoundException {\n" +
+ "\n" +
+ " Class c= findLoadedClass(name);\n" +
+ " if (c != null)\n" +
+ " return c;\n" +
+ " //\n" +
+ " // Delegate the loading of excluded classes to the\n" +
+ " // standard class loader.\n" +
+ " //\n" +
+ " if (isExcluded(name)) {\n" +
+ " try {\n" +
+ " c= findSystemClass(name);\n" +
+ " return c;\n" +
+ " } catch (ClassNotFoundException e) {\n" +
+ " // keep searching\n" +
+ " }\n" +
+ " }\n" +
+ " File file= locate(name);\n" +
+ " if (file == null)\n" +
+ " throw new ClassNotFoundException();\n" +
+ " byte data[]= loadClassData(file);\n" +
+ " c= defineClass(name, data, 0, data.length);\n" +
+ " if (resolve)\n" +
+ " resolveClass(c);\n" +
+ " return c;\n" +
+ " }\n" +
+ " private byte[] loadClassData(File f) throws ClassNotFoundException {\n" +
+ " FileInputStream stream = null;\n" +
+ " try {\n" +
+ " //System.out.println(\"loading: \"+f.getPath());\n" +
+ " stream = new FileInputStream(f);\n" +
+ "\n" +
+ " try {\n" +
+ " byte[] b= new byte[stream.available()];\n" +
+ " stream.read(b);\n" +
+ " return b;\n" +
+ " }\n" +
+ " catch (IOException e) {\n" +
+ " throw new ClassNotFoundException();\n" +
+ " }\n" +
+ " }\n" +
+ " catch (FileNotFoundException e) {\n" +
+ " throw new ClassNotFoundException();\n" +
+ " } finally {\n" +
+ " if (stream != null) {\n" +
+ " try {\n" +
+ " stream.close();\n" +
+ " } catch (IOException e) {\n" +
+ " /* ignore */\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " /**\n" +
+ " * Locate the given file.\n" +
+ " * @return Returns null if file couldn't be found.\n" +
+ " */\n" +
+ " private File locate(String fileName) {\n" +
+ " if (fileName != null) {\n" +
+ " fileName= fileName.replace('.', '/')+\".class\";\n" +
+ " File path= null;\n" +
+ " for (int i= 0; i < this.pathItems.length; i++) {\n" +
+ " path= new File(this.pathItems[i], fileName);\n" +
+ " if (path.exists())\n" +
+ " return path;\n" +
+ " }\n" +
+ " }\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n" +
+ "\n" +
+ "public void loadAndRun(String className) throws Throwable {\n" +
+ " //System.out.println(\"Loading \" + className + \"...\");\n" +
+ " Class testClass = new VerifyClassLoader().loadClass(className);\n" +
+ " //System.out.println(\"Loaded \" + className);\n" +
+ " try {\n" +
+ " Method main = testClass.getMethod(\"main\", new Class[] {String[].class});\n" +
+ " //System.out.println(\"Running \" + className);\n" +
+ " main.invoke(null, new Object[] {new String[] {}});\n" +
+ " //System.out.println(\"Finished running \" + className);\n" +
+ " } catch (NoSuchMethodException e) {\n" +
+ " return;\n" +
+ " } catch (InvocationTargetException e) {\n" +
+ " throw e.getTargetException();\n" +
+ " }\n" +
+ "}\n" +
+ "public static void main(String[] args) throws IOException {\n" +
+ " VerifyTests verify = new VerifyTests();\n" +
+ " verify.portNumber = Integer.parseInt(args[0]);\n" +
+ " verify.run();\n" +
+ "}\n" +
+ "public void run() throws IOException {\n" +
+ " ServerSocket server = new ServerSocket(this.portNumber);\n" +
+ " this.socket = server.accept();\n" +
+ " this.socket.setTcpNoDelay(true);\n" +
+ " server.close();\n" +
+ "\n" +
+ " DataInputStream in = new DataInputStream(this.socket.getInputStream());\n" +
+ " final DataOutputStream out = new DataOutputStream(this.socket.getOutputStream());\n" +
+ " while (true) {\n" +
+ " final String className = in.readUTF();\n" +
+ " Thread thread = new Thread() {\n" +
+ " public void run() {\n" +
+ " try {\n" +
+ " loadAndRun(className);\n" +
+ " out.writeBoolean(true);\n" +
+ " System.err.println(VerifyTests.class.getName());\n" +
+ " System.out.println(VerifyTests.class.getName());\n" +
+ " } catch (Throwable e) {\n" +
+ " e.printStackTrace();\n" +
+ " try {\n" +
+ " System.err.println(VerifyTests.class.getName());\n" +
+ " System.out.println(VerifyTests.class.getName());\n" +
+ " out.writeBoolean(false);\n" +
+ " } catch (IOException e1) {\n" +
+ " e1.printStackTrace();\n" +
+ " }\n" +
+ " }\n" +
+ " try {\n" +
+ " out.flush();\n" +
+ " } catch (IOException e) {\n" +
+ " e.printStackTrace();\n" +
+ " }\n" +
+ " }\n" +
+ " };\n" +
+ " thread.start();\n" +
+ " }\n" +
+ "}\n" +
+ "}";
}
private void launchAndRun(String className, String[] classpaths, String[] programArguments, String[] vmArguments) {
// we won't reuse the vm, shut the existing one if running
@@ -669,12 +690,12 @@
}
//{ObjectTeams: helper
public boolean vmArgsEqual(String[] newArgs) {
- if (this.vmArguments == null || newArgs == null)
- return this.vmArguments == null && newArgs == null;
- if (this.vmArguments.length != newArgs.length)
+ if (this.fVMArguments == null || newArgs == null)
+ return this.fVMArguments == null && newArgs == null;
+ if (this.fVMArguments.length != newArgs.length)
return false;
for (int i=0; i<newArgs.length; i++)
- if (!this.vmArguments[i].equals(newArgs[i]))
+ if (!this.fVMArguments[i].equals(newArgs[i]))
return false;
return true;
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/VerifyTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/VerifyTests.java
index 5a65937..45404f9 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/VerifyTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/VerifyTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 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
@@ -10,10 +10,18 @@
*******************************************************************************/
package org.eclipse.jdt.core.tests.util;
-import java.lang.reflect.*;
-import java.io.*;
-import java.net.*;
-import java.util.*;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.StringTokenizer;
/******************************************************
*
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTestsRequestor2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTestsRequestor2.java
index 38e7374..09935f5 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTestsRequestor2.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTestsRequestor2.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2011 IBM Corporation and others.
+ * Copyright (c) 2004, 2012 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
@@ -603,7 +603,6 @@
public boolean canUseDiamond(int proposalNo) {
if (proposalNo < this.proposals.length && this.proposals[proposalNo] != null) {
- System.out.println(this.proposals[proposalNo]);
return this.proposals[proposalNo].canUseDiamond(this.context);
}
return false;
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java
index b6003f8..99548b5 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java
@@ -94,7 +94,7 @@
// Debug
static {
// org.eclipse.jdt.internal.core.search.BasicSearchEngine.VERBOSE = true;
-// TESTS_NAMES = new String[] {"testBug306223"};
+// TESTS_NAMES = new String[] {"testBug324189d"};
}
public JavaSearchBugsTests(String name) {
@@ -13408,7 +13408,7 @@
},
new HashMap(),
libPath);
- IJavaProject javaProject = createJavaProject("P", new String[0], new String[] {libPath}, "");
+ IJavaProject javaProject = createJavaProject("P", new String[0], new String[] {libPath, "JCL_LIB"}, "");
waitUntilIndexesReady();
int mask = IJavaSearchScope.APPLICATION_LIBRARIES | IJavaSearchScope.SOURCES ;
IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[] { javaProject }, mask);
@@ -13751,4 +13751,5 @@
}
}
+// Add new tests in JavaSearchBugsTests2
}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java
new file mode 100644
index 0000000..0caa888
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java
@@ -0,0 +1,456 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.tests.model;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.Test;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.search.IJavaSearchConstants;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.search.SearchEngine;
+import org.eclipse.jdt.core.search.SearchMatch;
+import org.eclipse.jdt.core.search.SearchPattern;
+
+// The size of JavaSearchBugsTests.java is very big, Hence continuing here.
+public class JavaSearchBugsTests2 extends AbstractJavaSearchTests {
+
+ public JavaSearchBugsTests2(String name) {
+ super(name);
+ this.endChar = "";
+ }
+
+ static {
+ //TESTS_NAMES = new String[] {"testBug123836"};
+ }
+
+ public static Test suite() {
+ return buildModelTestSuite(JavaSearchBugsTests2.class);
+ }
+
+ class TestCollector extends JavaSearchResultCollector {
+ public List matches = new ArrayList();
+
+ public void acceptSearchMatch(SearchMatch searchMatch) throws CoreException {
+ super.acceptSearchMatch(searchMatch);
+ this.matches.add(searchMatch);
+ }
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ this.resultCollector = new TestCollector();
+ this.resultCollector.showAccuracy(true);
+ }
+
+ /**
+ * Test that missing types in the class shouldn't impact the search of a type in an inner class
+ */
+ public void testBug362633() throws CoreException, IOException {
+ try {
+ IJavaProject p = createJavaProject("P", new String[] {}, new String[] { "/P/lib325418.jar", "JCL15_LIB" }, "", "1.5");
+ org.eclipse.jdt.core.tests.util.Util.createJar(new String[] {
+ "p325418M/Missing.java",
+ "package p325418M;\n" +
+ "public class Missing{}\n" },
+ p.getProject().getLocation().append("lib325418M.jar").toOSString(), "1.5");
+
+ org.eclipse.jdt.core.tests.util.Util.createJar(
+ new String[] {
+ "p325418/Test.java",
+ "package p325418;\n" +
+ "public class Test{\n" +
+ " public void foo(p325418M.Missing a) {}\n" +
+ " public <T> T foo(int a) {\n" +
+ " return new Inner<T>() {T run() { return null; }}.run();\n" +
+ " }\n" + "}\n",
+ "p325418/Inner.java",
+ "package p325418;\n" +
+ "abstract class Inner <T> {\n" +
+ " abstract T run();\n" + "}\n" },
+ null,
+ p.getProject().getLocation().append("lib325418.jar").toOSString(),
+ new String[] { p.getProject().getLocation().append("lib325418M.jar").toOSString() },
+ "1.5");
+ refresh(p);
+ int mask = IJavaSearchScope.APPLICATION_LIBRARIES | IJavaSearchScope.SOURCES;
+ IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[] { p }, mask);
+ search("Inner.run()", IJavaSearchConstants.METHOD, IJavaSearchConstants.DECLARATIONS, scope, this.resultCollector);
+ assertSearchResults(
+ "Unexpected search results!",
+ "lib325418.jar T p325418.Inner.run() [No source] EXACT_MATCH\n" +
+ "lib325418.jar T p325418.<anonymous>.run() [No source] EXACT_MATCH",
+ this.resultCollector);
+ } finally {
+ deleteProject("P");
+ }
+ }
+
+ /**
+ * @bug 123836: [1.5][search] for references to overriding method with bound type variable is not polymorphic
+ * @test Search for references to an overridden method with bound variables should yield.
+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=123836"
+ */
+ public void testBug123836a() throws CoreException {
+ IJavaProject project = null;
+ try
+ {
+ project = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB"}, "","1.5");
+ createFile("/P/Sub.java",
+ "abstract class Sup<C> {\n" +
+ " protected void m(C classifier) {}\n"+
+ " public void use(C owner) { m (owner); }\n" +
+ "}\n" +
+ "public class Sub extends Sup<String>{\n" +
+ " @Override\n"+
+ " protected void m(String classifier) {}\n"+
+ "}\n");
+ IType type = getCompilationUnit("/P/Sub.java").getType("Sub");
+ IMethod method = type.getMethod("m", new String[]{"QString;"});
+ search(method, REFERENCES, EXACT_RULE, SearchEngine.createWorkspaceScope(), this.resultCollector);
+ assertSearchResults("Sub.java void Sup.use(C) [m (owner)] EXACT_MATCH");
+ } finally {
+ deleteProject(project);
+ }
+ }
+ // Search for a non-overriden method with same name as which could have been overriden should
+ // not have results
+ public void testBug123836b() throws CoreException {
+ IJavaProject project = null;
+ try
+ {
+ project = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB"}, "","1.5");
+ createFile("/P/Sub.java",
+ "abstract class Sup<C> {\n" +
+ " protected void m(C classifier) {}\n"+
+ " public void use(C owner) { m (owner); }\n" +
+ "}\n" +
+ "public class Sub extends Sup<String>{\n" +
+ " @Override\n"+
+ " protected void m(String classifier) {}\n"+
+ " protected void m(Sub classifier) {}\n"+
+ "}\n" );
+ // search
+ IType type = getCompilationUnit("/P/Sub.java").getType("Sub");
+ IMethod method = type.getMethod("m", new String[]{"QSub;"});
+ search(method, REFERENCES, EXACT_RULE, SearchEngine.createWorkspaceScope(), this.resultCollector);
+ assertSearchResults("");
+
+ } finally {
+ deleteProject(project);
+ }
+ }
+ // another variant of the testcase
+ public void testBug123836c() throws CoreException {
+ IJavaProject project = null;
+ try
+ {
+ // create the common project and create an interface
+ project = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB"}, "","1.5");
+ createFile("/P/Test.java",
+ "class Test {\n"+
+ " void calc(Property prop, Property<? extends Serializable> p2) {\n"+
+ " prop.compute(null);\n"+
+ " p2.compute(null);\n"+
+ " }\n"+
+ "}\n"+
+ "abstract class Property<E> {\n"+
+ " public abstract void compute(E e);\n"+
+ "}\n"+
+ "class StringProperty extends Property<String> {\n"+
+ " @Override public void compute(String e) {\n"+
+ " System.out.println(e);\n"+
+ " }");
+ IType type = getCompilationUnit("/P/Test.java").getType("StringProperty");
+ IMethod method = type.getMethod("compute", new String[]{"QString;"});
+ search(method, REFERENCES, EXACT_RULE, SearchEngine.createWorkspaceScope(), this.resultCollector);
+ assertSearchResults("Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH\n" +
+ "Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH");
+ } finally {
+ deleteProject(project);
+ }
+ }
+ // Test inner class
+ public void testBug123836d() throws CoreException {
+ IJavaProject project = null;
+ try
+ {
+ // create the common project and create an interface
+ project = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB"}, "","1.5");
+ createFile("/P/Test.java",
+ "class Test {\n"+
+ " void calc(Property prop, Property<? extends Serializable> p2) {\n"+
+ " prop.compute(null);\n"+
+ " p2.compute(null);\n"+
+ " }\n"+
+ " class StringProperty extends Property<String> {\n"+
+ " @Override public void compute(String e) {\n"+
+ " System.out.println(e);\n"+
+ " }\n"+
+ "}\n"+
+ "abstract class Property<E> {\n"+
+ " public abstract void compute(E e);\n"+
+ "}");
+
+ IType type = getCompilationUnit("/P/Test.java").getType("Test").getType("StringProperty");
+ IMethod method = type.getMethod("compute", new String[]{"QString;"});
+ search(method, REFERENCES, EXACT_RULE, SearchEngine.createWorkspaceScope(), this.resultCollector);
+ assertSearchResults("Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH\n" +
+ "Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH");
+ } finally {
+ deleteProject(project);
+ }
+ }
+ // Test local class
+ public void testBug123836e() throws CoreException {
+ IJavaProject project = null;
+ try
+ {
+ // create the common project and create an interface
+ project = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB"}, "","1.5");
+ createFile("/P/Test.java",
+ "class Test {\n"+
+ " void calc(Property prop, Property<? extends Serializable> p2) {\n"+
+ " prop.compute(null);\n"+
+ " p2.compute(null);\n"+
+ " class StringProperty extends Property<String> {\n"+
+ " @Override public void compute(String e) {\n"+
+ " System.out.println(e);\n"+
+ " }\n"+
+ " }\n"+
+ " }\n"+
+ "}\n"+
+ "abstract class Property<E> {\n"+
+ " public abstract void compute(E e);\n"+
+ "}");
+ IMethod method = selectMethod(getCompilationUnit("/P/Test.java"), "compute", 3);
+ search(method, REFERENCES, EXACT_RULE, SearchEngine.createWorkspaceScope(), this.resultCollector);
+ assertSearchResults("Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH\n" +
+ "Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH");
+ } finally {
+ deleteProject(project);
+ }
+ }
+ // test inner class
+ public void testBug123836f() throws CoreException {
+ IJavaProject project = null;
+ try
+ {
+ // create the common project and create an interface
+ project = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB"}, "","1.5");
+ createFile("/P/Test.java",
+ "class Test {\n"+
+ " void calc(Property prop, Property<? extends Serializable> p2) {\n"+
+ " prop.compute(null);\n"+
+ " p2.compute(null);\n"+
+ " new Property<String>() {\n"+
+ " @Override public void compute(String e) {\n"+
+ " System.out.println(e);\n"+
+ " }\n"+
+ " };\n"+
+ " }\n"+
+ "}\n"+
+ "abstract class Property<E> {\n"+
+ " public abstract void compute(E e);\n"+
+ "}");
+ IMethod method = selectMethod(getCompilationUnit("/P/Test.java"), "compute", 3);
+ search(method, REFERENCES, EXACT_RULE, SearchEngine.createWorkspaceScope(), this.resultCollector);
+ assertSearchResults("Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH\n" +
+ "Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH");
+ } finally {
+ deleteProject(project);
+ }
+ }
+ // test in initializer block
+ public void testBug123836g() throws CoreException {
+ IJavaProject project = null;
+ try
+ {
+ // create the common project and create an interface
+ project = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB"}, "","1.5");
+ createFile("/P/Test.java",
+ "class Test {\n"+
+ " {\n" +
+ " new Property<String>() {\n" +
+ " @Override public void compute(String e) {}\n" +
+ " };\n"+
+ " }\n"+
+ " void calc(Property prop, Property<? extends Serializable> p2) {\n"+
+ " prop.compute(null);\n"+
+ " p2.compute(null);\n"+
+ " }\n"+
+ "}\n"+
+ "abstract class Property<E> {\n"+
+ " public abstract void compute(E e);\n"+
+ "}");
+ IMethod method = selectMethod(getCompilationUnit("/P/Test.java"), "compute", 1);
+ search(method, REFERENCES, EXACT_RULE, SearchEngine.createWorkspaceScope(), this.resultCollector);
+ assertSearchResults("Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH\n" +
+ "Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH");
+ } finally {
+ deleteProject(project);
+ }
+ }
+ // test in static initializer
+ public void testBug123836h() throws CoreException {
+ IJavaProject project = null;
+ try
+ {
+ // create the common project and create an interface
+ project = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB"}, "","1.5");
+ createFile("/P/Test.java",
+ "class Test {\n"+
+ " static {\n" +
+ " new Property<String>() {\n" +
+ " @Override public void compute(String e) {}\n" +
+ " };\n"+
+ " }\n"+
+ " void calc(Property prop, Property<? extends Serializable> p2) {\n"+
+ " prop.compute(null);\n"+
+ " p2.compute(null);\n"+
+ " }\n"+
+ "}\n"+
+ "abstract class Property<E> {\n"+
+ " public abstract void compute(E e);\n"+
+ "}");
+ IMethod method = selectMethod(getCompilationUnit("/P/Test.java"), "compute", 1);
+ search(method, REFERENCES, EXACT_RULE, SearchEngine.createWorkspaceScope(), this.resultCollector);
+ assertSearchResults("Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH\n" +
+ "Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH");
+ } finally {
+ deleteProject(project);
+ }
+ }
+ // test in static initializer
+ public void testBug123836i() throws CoreException {
+ IJavaProject project = null;
+ try
+ {
+ // create the common project and create an interface
+ project = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB"}, "","1.5");
+ createFile("/P/Test.java",
+ "class Test {\n"+
+ " Property <?>p = new Property<String>() {\n" +
+ " @Override public void compute(String e) {}\n" +
+ " };\n"+
+ " void calc(Property prop, Property<? extends Serializable> p2) {\n"+
+ " prop.compute(null);\n"+
+ " p2.compute(null);\n"+
+ " }\n"+
+ "}\n"+
+ "abstract class Property<E> {\n"+
+ " public abstract void compute(E e);\n"+
+ "}");
+ IMethod method = selectMethod(getCompilationUnit("/P/Test.java"), "compute", 1);
+ search(method, REFERENCES, EXACT_RULE, SearchEngine.createWorkspaceScope(), this.resultCollector);
+ assertSearchResults("Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH\n" +
+ "Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH");
+ } finally {
+ deleteProject(project);
+ }
+ }
+ public void testBug123836j() throws CoreException {
+ IJavaProject project = null;
+ try
+ {
+ // create the common project and create an interface
+ project = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB"}, "","1.5");
+ createFile("/P/Test.java",
+ "class Test {\n"+
+ " void calc(Property prop, Property<? extends Serializable> p2) {\n"+
+ " prop.compute(null);\n"+
+ " p2.compute(null);\n"+
+ " }\n"+
+ "}\n"+
+ "abstract class Property<E> {\n"+
+ " public abstract void compute(E e);\n"+
+ "}\n"+
+ "class StringProperty extends Property<String> {\n"+
+ " @Override public void compute(String e) {\n"+
+ " new Property<String>() {\n"+
+ " @Override public void compute(String e) {\n"+
+ " new Property<String>() {\n"+
+ " @Override public void compute(String e) {}\n"+
+ " };\n"+
+ " }\n"+
+ " };\n"+
+ " }\n"+
+ "}");
+ IMethod method = selectMethod(getCompilationUnit("/P/Test.java"), "compute", 6);
+ search(method, REFERENCES, EXACT_RULE, SearchEngine.createWorkspaceScope(), this.resultCollector);
+ assertSearchResults("Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH\n" +
+ "Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH");
+ } finally {
+ deleteProject(project);
+ }
+ }
+ // test search of name
+ public void _testBug123836g1() throws CoreException {
+ IJavaProject project = null;
+ try
+ {
+ // create the common project and create an interface
+ project = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB"}, "","1.5");
+ createFile("/P/Sub.java",
+ "abstract class Sup<C> {\n" +
+ " protected void m(C classifier) {}\n"+
+ " public void use(C owner) { m (owner); }\n" +
+ "}\n" +
+ "public class Sub extends Sup<String>{\n" +
+ " @Override\n"+
+ " protected void m(String classifier) {}\n"+
+ " protected void m(Sub classifier) {}\n"+
+ "}\n" );
+ waitUntilIndexesReady();
+ // search
+ SearchPattern pattern = SearchPattern.createPattern("Sub.m(String)", METHOD, REFERENCES, EXACT_RULE);
+ search(pattern, SearchEngine.createWorkspaceScope(), this.resultCollector);
+ assertSearchResults("Sub.java void Sup.use(C) [m (owner)] EXACT_MATCH");
+
+ } finally {
+ deleteProject(project);
+ }
+ }
+ // test search of name (negative)
+ public void _testBug123836h1() throws CoreException {
+ IJavaProject project = null;
+ try
+ {
+ // create the common project and create an interface
+ project = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB"}, "","1.5");
+ createFile("/P/Sub.java",
+ "abstract class Sup<C> {\n" +
+ " protected void m(C classifier) {}\n"+
+ " public void use(C owner) { m (owner); }\n" +
+ "}\n" +
+ "public class Sub extends Sup<String>{\n" +
+ " @Override\n"+
+ " protected void m(String classifier) {}\n"+
+ " protected void m(Sub classifier) {}\n"+
+ "}\n" );
+ // search
+ SearchPattern pattern = SearchPattern.createPattern("Sub.m(Sub)", METHOD, REFERENCES, EXACT_RULE);
+ search(pattern, SearchEngine.createWorkspaceScope(), this.resultCollector);
+ assertSearchResults("");
+
+ } finally {
+ deleteProject(project);
+ }
+ }
+}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchTests.java
index 923d153..316b1c7 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 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
@@ -2168,8 +2168,8 @@
search("MissingFieldType.*", FIELD, DECLARATIONS, getJavaSearchScope());
assertSearchResults(
"AbortCompilation.jar AbortCompilation.MissingFieldType.field [No source] EXACT_MATCH\n" +
- "AbortCompilation.jar AbortCompilation.MissingFieldType.otherField [No source] EXACT_MATCH\n" +
- "AbortCompilation.jar AbortCompilation.MissingFieldType.missing [No source] POTENTIAL_MATCH"
+ "AbortCompilation.jar AbortCompilation.MissingFieldType.missing [No source] EXACT_MATCH\n" +
+ "AbortCompilation.jar AbortCompilation.MissingFieldType.otherField [No source] EXACT_MATCH"
);
} finally {
// reset classpath
@@ -2229,8 +2229,8 @@
search("MissingArgumentType.foo*", METHOD, DECLARATIONS, getJavaSearchScope());
assertSearchResults(
"AbortCompilation.jar void AbortCompilation.MissingArgumentType.foo() [No source] EXACT_MATCH\n" +
- "AbortCompilation.jar void AbortCompilation.MissingArgumentType.foo2() [No source] EXACT_MATCH\n" +
- "AbortCompilation.jar void AbortCompilation.MissingArgumentType.foo(java.util.EventListener) [No source] POTENTIAL_MATCH"
+ "AbortCompilation.jar void AbortCompilation.MissingArgumentType.foo(java.util.EventListener) [No source] EXACT_MATCH\n" +
+ "AbortCompilation.jar void AbortCompilation.MissingArgumentType.foo2() [No source] EXACT_MATCH"
);
} finally {
// reset classpath
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NullAnnotationModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NullAnnotationModelTests.java
index d38f045..82e5422 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NullAnnotationModelTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NullAnnotationModelTests.java
@@ -67,8 +67,8 @@
return FileLocator.toFileURL(libEntry).getPath();
}
-
- public void testConvertedSourceType1() throws CoreException, InterruptedException {
+ // DISABLED due to dysfunctional global default after Bug 366063 - Compiler should not add synthetic @NonNull annotations
+ public void _testConvertedSourceType1() throws CoreException, InterruptedException {
try {
// Resources creation
IJavaProject p = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB", this.ANNOTATION_LIB}, "bin", "1.5");
@@ -119,7 +119,8 @@
}
}
- public void testBinaryType1() throws CoreException, InterruptedException, IOException {
+ // DISABLED due to dysfunctional global default after Bug 366063 - Compiler should not add synthetic @NonNull annotations
+ public void _testBinaryType1() throws CoreException, InterruptedException, IOException {
try {
// Resources creation
IJavaProject p = createJavaProject("P", new String[] {""},
@@ -161,7 +162,8 @@
}
}
- public void testMissingAnnotation1() throws CoreException {
+ // DISABLED: no longer a problem since bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
+ public void _testMissingAnnotation1() throws CoreException {
try {
// Resources creation
IJavaProject p = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB", this.ANNOTATION_LIB}, "bin", "1.5");
@@ -197,7 +199,8 @@
}
}
- public void testMissingAnnotation2() throws CoreException {
+ // DISABLED: no longer a problem since bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
+ public void _testMissingAnnotation2() throws CoreException {
Hashtable javaOptions = JavaCore.getOptions();
try {
// Resources creation
@@ -241,7 +244,8 @@
// Bug 363858 - [dom] early throwing of AbortCompilation causes NPE in CompilationUnitResolver
// currently not actually challenging the NPE, because we no longer report
// "Cannot use the unqualified name \'invalid\' as an annotation name for null specification"
- public void testMissingAnnotation3() throws CoreException {
+ // DISABLED: no longer a problem since bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
+ public void _testMissingAnnotation3() throws CoreException {
try {
// Resources creation
IJavaProject p = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB", this.ANNOTATION_LIB}, "bin", "1.5");
@@ -357,7 +361,8 @@
// - triggered from resolveTypesFor(MethodBinding)
// - default is defined in package-info.java:
// must detect missing non-null annotation and report against the project
- public void testMissingAnnotation5() throws CoreException, InterruptedException {
+ // DISABLED: no longer a problem since bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
+ public void _testMissingAnnotation5() throws CoreException, InterruptedException {
try {
// Resources creation
IJavaProject p = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB", this.ANNOTATION_LIB}, "bin", "1.5");
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests.java
index 429a4cb..73f1d9d 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 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
@@ -2686,4 +2686,43 @@
);
assertTrue("Not a parameter", ((ILocalVariable)elements[0]).isParameter());
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=244544
+public void testConstantInLocal() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[2];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Resolve/src/Test2.java",
+ "class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " class Local {\n" +
+ " private static final long CONSTANT = 1L; // code select fails\n" +
+ " }\n" +
+ " new X() {\n" +
+ " private static final long FINAL = 1L; // code select fails\n" +
+ " };\n" +
+ " }\n" +
+ "}\n");
+
+ String str = this.workingCopies[0].getSource();
+ String selectAt = "FINAL";
+ String selection = "FINAL";
+ int start = str.indexOf(selectAt);
+ int length = selection.length();
+ IJavaElement[] elements = this.workingCopies[0].codeSelect(start, length, this.wcOwner);
+
+ assertElementsEqual(
+ "Unexpected elements",
+ "FINAL [in <anonymous #1> [in main(String[]) [in X [in [Working copy] Test2.java [in <default> [in src [in Resolve]]]]]]]",
+ elements);
+
+ selectAt = "CONSTANT";
+ selection = "CONSTANT";
+ start = str.indexOf(selectAt);
+ length = selection.length();
+ elements = this.workingCopies[0].codeSelect(start, length, this.wcOwner);
+
+ assertElementsEqual(
+ "Unexpected elements",
+ "CONSTANT [in Local [in main(String[]) [in X [in [Working copy] Test2.java [in <default> [in src [in Resolve]]]]]]]",
+ elements);
+}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchGenericTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchGenericTests.java
index d33e9c5..0a06040 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchGenericTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchGenericTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 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
@@ -45,6 +45,7 @@
AbstractJavaSearchTests.JAVA_SEARCH_SUITES = new ArrayList(Arrays.asList(getJavaSearchTestClasses()));
List allClasses = new ArrayList(AbstractJavaSearchTests.JAVA_SEARCH_SUITES);
allClasses.add(JavaSearchBugsTests.class);
+ allClasses.add(JavaSearchBugsTests2.class);
// Reset forgotten subsets of tests
TestCase.TESTS_PREFIX = null;
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchTests.java
index 2d7d864..36977b7 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 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
@@ -58,6 +58,7 @@
// Get all classes
List allClasses = new ArrayList(TEST_CLASSES);
allClasses.add(JavaSearchBugsTests.class);
+ allClasses.add(JavaSearchBugsTests2.class);
allClasses.add(JavaSearchMultipleProjectsTests.class);
allClasses.add(SearchTests.class);
allClasses.add(JavaSearchScopeTests.class);
diff --git a/org.eclipse.jdt.core.tests.model/workspace/JavaSearchBugs/lib/b317264.jar b/org.eclipse.jdt.core.tests.model/workspace/JavaSearchBugs/lib/b317264.jar
new file mode 100644
index 0000000..d0ad276
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/JavaSearchBugs/lib/b317264.jar
Binary files differ
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 b1098e2..be20e27 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
@@ -3549,11 +3549,6 @@
setSeverity(CompilerOptions.OPTION_ReportRedundantNullCheck, ProblemSeverities.Ignore, isEnabling);
}
return;
- } else if (token.equals("nullFields")) { //$NON-NLS-1$
- this.options.put(
- CompilerOptions.OPTION_IncludeFieldsInNullAnalysis,
- isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
- return;
} else if (token.startsWith("nullAnnot")) { //$NON-NLS-1$
String annotationNames = Util.EMPTY_STRING;
int start = token.indexOf('(');
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
index 394bb17..3ded165 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
@@ -1,5 +1,5 @@
###############################################################################
-# Copyright (c) 2000, 2011 IBM Corporation and others.
+# Copyright (c) 2000, 2012 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
@@ -20,7 +20,7 @@
#Format: compiler.name = word1 word2 word3
compiler.name = Eclipse Compiler for Java(TM)
#Format: compiler.version = 0.XXX[, other words (don't forget the comma if adding other words)]
-compiler.version = 0.C33, 3.8.0 M5
+compiler.version = 0.C35, 3.8.0 M6
compiler.copyright = Copyright IBM Corp 2000, 2011. All rights reserved.
###{ObjectTeams:
@@ -345,7 +345,6 @@
\ nullable|nonnull|nonnullbydefault annotation types\n\
\ optionally specified using fully qualified names\n\
\ nullDereference + missing null check\n\
-\ nullFields + null analysis for fields\n\
\ over-ann missing @Override annotation (superclass)\n\
\ paramAssign assignment to a parameter\n\
\ pkgDefaultMethod + attempt to override package-default method\n\
diff --git a/org.eclipse.jdt.core/buildnotes_jdt-core.html b/org.eclipse.jdt.core/buildnotes_jdt-core.html
index 41570a4..4e0c612 100644
--- a/org.eclipse.jdt.core/buildnotes_jdt-core.html
+++ b/org.eclipse.jdt.core/buildnotes_jdt-core.html
@@ -42,11 +42,56 @@
</td>
</tr>
</table>
+<a name="v_C35"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - February 21, 2012 - 3.8.0 M6
+<br>Project org.eclipse.jdt.core v_C35
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_C35">cvs</a>).
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365499">365499</a>
+Add a system property to control for JavaModelManager's jar type cache size
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=368152">368152</a>
+ConcurrentModificationException on startup in ExternalFoldersManager.createPendingFolders
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=244544">244544</a>
+codeSelect fails on constant declaration in anonymous and local classes
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=291040">291040</a>
+codeSelect(..) does not work for a deeply nested method invocation in nested and anonymous class
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=370930">370930</a>
+NonNull annotation not considered for enhanced for loops
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=366063">366063</a>
+Compiler should not add synthetic @NonNull annotations
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365531">365531</a>
+[compiler][null] investigate alternative strategy for internally encoding nullness defaults
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=370639">370639</a>
+[compiler][resource] restore the default for resource leak warnings
+
+<a name="v_C34"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - February 14, 2012
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=123836">123836</a>
+[1.5][search] for references to overriding method with bound type variable is not polymorphic
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=368546">368546</a>
+[compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=364254">364254</a>
+Reduce console output during JDT/Core junits execution.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=362633">362633</a>
+NPE while trying to rename a class
+
<a name="v_C33"></a>
<hr><h1>
Eclipse Platform Build Notes<br>
Java development tools core</h1>
-Eclipse SDK 3.8.0 - %date% - 3.8.0 M5
+Eclipse SDK 3.8.0 - January 25, 2012 - 3.8.0 M5
<br>
<h2>What's new in this drop</h2>
@@ -65,8 +110,6 @@
<h3>Problem Reports Fixed</h3>
<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=366829">366829</a>
Batch compiler option and SuppressWarnings token for Overriding a Synchronized Method with a Non-synchronized Method
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=369381">369381</a>
-[null][compiler] 'Adding potential null mark in unexpected state' assertion while compiling
<a name="v_C31"></a>
<hr><h1>
@@ -110,45 +153,6 @@
String SOURCE_ATTACHMENT_ENCODING = "source_encoding";
</pre>
</li>
-<li> New JavaCore option to control null analysis for fields
-<pre>
- /**
- * Compiler option ID: Raise null related errors or warnings on fields.
- *
- * When enabled, the compiler will flag all null related errors or warnings that have been enabled by the user
- * on fields, in addition to local variables.
- * When disabled, the compiler will not flag null related errors or warnings on fields.
- *
- * Option id:<code>"org.eclipse.jdt.core.compiler.problem.includeFieldsInNullAnalysis"</code>
- * Possible values:<code>{ "enabled", "disabled" }</code>
- * Default:<code>"disabled"</code>
- *
- * @since 3.8
- * @category CompilerOptionID
- */
- public static final String COMPILER_PB_INCLUDE_FIELDS_IN_NULL_ANALYSIS = PLUGIN_ID + ".compiler.problem.includeFieldsInNullAnalysis";
-</pre>
-</li>
-<li> New IProblems for messages relating to null analysis for fields
-<pre>
- /** @since 3.8*/
- int NullFieldReference = Internal + FieldRelated + 670;
- /** @since 3.8*/
- int PotentialNullFieldReference = Internal + FieldRelated + 671;
- /** @since 3.8*/
- int RedundantNullCheckOnNullField = Internal + FieldRelated + 672;
- /** @since 3.8*/
- int NullFieldComparisonYieldsFalse = Internal + FieldRelated + 673;
- /** @since 3.8*/
- int RedundantNullCheckOnNonNullField = Internal + FieldRelated + 674;
- /** @since 3.8*/
- int NonNullFieldComparisonYieldsFalse = Internal + FieldRelated + 675;
- /** @since 3.8*/
- int RedundantFieldNullAssignment = Internal + FieldRelated + 676;
- /** @since 3.8*/
- int NullFieldInstanceofYieldsFalse = Internal + FieldRelated + 677;
-</pre>
-</li>
<li> New IProblems for messages relating to contradictory or redundant null annotations
<pre>
/** @since 3.8 */
@@ -171,8 +175,6 @@
FUP of bug 361938: Other error code pattern
<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365662">365662</a>
[compiler][null] warn on contradictory and redundant null annotations
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=247564">247564</a>
-[compiler][null] Detecting null field reference
<a name="v_C29"></a>
<hr><h1>
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 14b0ec0..30e7f9c 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
@@ -128,7 +128,6 @@
* RequiredNonNullButProvidedNull
* RequiredNonNullButProvidedPotentialNull
* RequiredNonNullButProvidedUnknown
- * MissingNullAnnotationType
* NullAnnotationNameMustBeQualified
* IllegalReturnNullityRedefinition
* IllegalRedefinitionToNonNullParameter
@@ -1291,26 +1290,6 @@
/** @since 3.4 */
int UnusedTypeArgumentsForConstructorInvocation = MethodRelated + 660;
- /**
- * Null analysis for fields
- */
- /** @since 3.8*/
- int NullFieldReference = Internal + FieldRelated + 670;
- /** @since 3.8*/
- int PotentialNullFieldReference = Internal + FieldRelated + 671;
- /** @since 3.8*/
- int RedundantNullCheckOnNullField = Internal + FieldRelated + 672;
- /** @since 3.8*/
- int NullFieldComparisonYieldsFalse = Internal + FieldRelated + 673;
- /** @since 3.8*/
- int RedundantNullCheckOnNonNullField = Internal + FieldRelated + 674;
- /** @since 3.8*/
- int NonNullFieldComparisonYieldsFalse = Internal + FieldRelated + 675;
- /** @since 3.8*/
- int RedundantFieldNullAssignment = Internal + FieldRelated + 676;
- /** @since 3.8*/
- int NullFieldInstanceofYieldsFalse = Internal + FieldRelated + 677;
-
/**
* Corrupted binaries
*/
@@ -1468,8 +1447,7 @@
int RequiredNonNullButProvidedPotentialNull = TypeRelated + 911;
/** @since 3.8 */
int RequiredNonNullButProvidedUnknown = TypeRelated + 912;
- /** @since 3.8 */
- int MissingNullAnnotationType = ImportRelated + 913;
+ // removed during 3.8 M6: ImportRelated + 913
/** @since 3.8 */
int IllegalReturnNullityRedefinition = MethodRelated + 914;
/** @since 3.8 */
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 704c404..bbdca16 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 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
@@ -4064,7 +4064,6 @@
// retrieve the enclosing one guaranteed to be the one matching the propagated flow info
// 1FF9ZBU: LFCOM:ALL - Local variable attributes busted (Sanity check)
- // see also https://bugs.eclipse.org/bugs/show_bug.cgi?id=247564#c65
this.codeStream.maxFieldCount = aType.scope.outerMostClassScope().referenceType().maxFieldCount;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
index 500d003..0617799 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
@@ -13,11 +13,11 @@
* bug 186342 - [compiler][null] Using annotations for null checking
* bug 367203 - [compiler][null] detect assigning null to nonnull argument
* bug 365519 - editorial cleanup after bug 186342 and bug 365387
+ * bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
import java.util.List;
-import java.util.Arrays;
import org.eclipse.jdt.core.compiler.*;
import org.eclipse.jdt.internal.compiler.*;
@@ -216,41 +216,6 @@
}
/**
- * Materialize a non-null annotation that has been added from the current default,
- * in order to ensure that this annotation will be generated into the .class file, too.
- */
- public void addNonNullAnnotation(ReferenceBinding annotationBinding) {
- this.annotations = addAnnotation(this, this.annotations, annotationBinding);
- }
-
- /**
- * Materialize a non-null parameter annotation that has been added from the current default,
- * in order to ensure that this annotation will be generated into the .class file, too.
- */
- public void addParameterNonNullAnnotation(Argument argument, ReferenceBinding annotationBinding) {
- if (argument.type != null) // null happens for constructors of anonymous classes
- argument.annotations = addAnnotation(argument.type, argument.annotations, annotationBinding);
- }
-
- private Annotation[] addAnnotation(ASTNode location, Annotation[] oldAnnotations, ReferenceBinding annotationBinding) {
- long pos = ((long)location.sourceStart<<32) + location.sourceEnd;
- long[] poss = new long[annotationBinding.compoundName.length];
- Arrays.fill(poss, pos);
- MarkerAnnotation annotation = new MarkerAnnotation(new QualifiedTypeReference(annotationBinding.compoundName, poss), location.sourceStart);
- annotation.declarationSourceEnd = location.sourceEnd;
- annotation.resolvedType = annotationBinding;
- annotation.bits = IsSynthetic;
- if (oldAnnotations == null) {
- oldAnnotations = new Annotation[] {annotation};
- } else {
- int len = oldAnnotations.length;
- System.arraycopy(oldAnnotations, 0, oldAnnotations=new Annotation[len+1], 1, len);
- oldAnnotations[0] = annotation;
- }
- return oldAnnotations;
- }
-
- /**
* When a method is accessed via SourceTypeBinding.resolveTypesFor(MethodBinding)
* we create the argument binding and resolve annotations in order to compute null annotation tagbits.
*/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java
index 6608e84..f84c472 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java
@@ -15,6 +15,8 @@
* bug 349326 - [1.7] new warning for missing try-with-resources
* bug 186342 - [compiler][null] Using annotations for null checking
* bug 358903 - Filter practically unimportant resource leak warnings
+ * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+ * bug 370639 - [compiler][resource] restore the default for resource leak warnings
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -85,7 +87,9 @@
// process arguments
if (this.arguments != null) {
- boolean hasResourceWrapperType = this.resolvedType instanceof ReferenceBinding
+ boolean analyseResources = currentScope.compilerOptions().analyseResourceLeaks;
+ boolean hasResourceWrapperType = analyseResources
+ && this.resolvedType instanceof ReferenceBinding
&& ((ReferenceBinding)this.resolvedType).hasTypeBit(TypeIds.BitWrapperCloseable);
for (int i = 0, count = this.arguments.length; i < count; i++) {
flowInfo =
@@ -93,7 +97,7 @@
.analyseCode(currentScope, flowContext, flowInfo)
.unconditionalInits();
// if argument is an AutoCloseable insert info that it *may* be closed (by the target method, i.e.)
- if (!hasResourceWrapperType) { // allocation of wrapped closeables is analyzed specially
+ if (analyseResources && !hasResourceWrapperType) { // allocation of wrapped closeables is analyzed specially
flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo, false);
}
if ((this.arguments[i].implicitConversion & TypeIds.UNBOXING) != 0) {
@@ -103,9 +107,6 @@
analyseArguments(currentScope, flowContext, flowInfo, this.binding, this.arguments);
}
- if (FakedTrackingVariable.isAnyCloseable(this.resolvedType))
- FakedTrackingVariable.analyseCloseableAllocation(currentScope, flowInfo, this);
-
// record some dependency information for exception types
ReferenceBinding[] thrownExceptions;
if (((thrownExceptions = this.binding.thrownExceptions).length) != 0) {
@@ -120,6 +121,11 @@
flowInfo.unconditionalCopy(),
currentScope);
}
+
+ // after having analysed exceptions above start tracking newly allocated resource:
+ if (FakedTrackingVariable.isAnyCloseable(this.resolvedType) && currentScope.compilerOptions().analyseResourceLeaks)
+ FakedTrackingVariable.analyseCloseableAllocation(currentScope, flowInfo, this);
+
if (this.binding.declaringClass.isMemberType() && !this.binding.declaringClass.isStatic()) {
// allocating a non-static member type without an enclosing instance of parent type
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=335845
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java
index afe4153..41027f8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 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
@@ -7,6 +7,9 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contributions for
+ * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+ * bug 370639 - [compiler][resource] restore the default for resource leak warnings
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -32,8 +35,13 @@
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
if (this.expressions != null) {
+ boolean analyseResources = currentScope.compilerOptions().analyseResourceLeaks;
for (int i = 0, max = this.expressions.length; i < max; i++) {
flowInfo = this.expressions[i].analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
+
+ if (analyseResources && FakedTrackingVariable.isAnyCloseable(this.expressions[i].resolvedType)) {
+ flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.expressions[i], flowInfo, false);
+ }
}
}
return flowInfo;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java
index 9a87b49..af54844 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java
@@ -17,6 +17,7 @@
* bug 349326 - [1.7] new warning for missing try-with-resources
* bug 186342 - [compiler][null] Using annotations for null checking
* bug 358903 - Filter practically unimportant resource leak warnings
+ * bug 370639 - [compiler][resource] restore the default for resource leak warnings
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -74,46 +75,44 @@
// record setting a variable: various scenarii are possible, setting an array reference,
// a field reference, a blank final field reference, a field of an enclosing instance or
// just a local variable.
- VariableBinding var = this.lhs.variableBinding(currentScope);
+ LocalVariableBinding local = this.lhs.localVariableBinding();
if ((this.expression.implicitConversion & TypeIds.UNBOXING) != 0) {
this.expression.checkNPE(currentScope, flowContext, flowInfo);
}
FlowInfo preInitInfo = null;
- LocalVariableBinding localToAnalyseAsResource = null;
- if (var instanceof LocalVariableBinding
- && flowInfo.reachMode() == FlowInfo.REACHABLE
+ boolean shouldAnalyseResource = local != null
+ && flowInfo.reachMode() == FlowInfo.REACHABLE
+ && currentScope.compilerOptions().analyseResourceLeaks
&& (FakedTrackingVariable.isAnyCloseable(this.expression.resolvedType)
- || this.expression.resolvedType == TypeBinding.NULL)) {
- localToAnalyseAsResource = (LocalVariableBinding) var;
-
+ || this.expression.resolvedType == TypeBinding.NULL);
+ if (shouldAnalyseResource) {
preInitInfo = flowInfo.unconditionalCopy();
// analysis of resource leaks needs additional context while analyzing the RHS:
- FakedTrackingVariable.preConnectTrackerAcrossAssignment(this, localToAnalyseAsResource, this.expression);
+ FakedTrackingVariable.preConnectTrackerAcrossAssignment(this, local, this.expression);
}
flowInfo = ((Reference) this.lhs)
.analyseAssignment(currentScope, flowContext, flowInfo, this, false)
.unconditionalInits();
- if (localToAnalyseAsResource != null) {
- FakedTrackingVariable.handleResourceAssignment(currentScope, preInitInfo, flowInfo, this, this.expression, localToAnalyseAsResource);
- } else {
+ if (shouldAnalyseResource)
+ FakedTrackingVariable.handleResourceAssignment(currentScope, preInitInfo, flowInfo, this, this.expression, local);
+ else
FakedTrackingVariable.cleanUpAfterAssignment(currentScope, this.lhs.bits, this.expression);
- }
int nullStatus = this.expression.nullStatus(flowInfo);
- if (var != null && (var.type.tagBits & TagBits.IsBaseType) == 0) {
+ if (local != null && (local.type.tagBits & TagBits.IsBaseType) == 0) {
if (nullStatus == FlowInfo.NULL) {
- flowContext.recordUsingNullReference(currentScope, var, this.lhs,
+ flowContext.recordUsingNullReference(currentScope, local, this.lhs,
FlowContext.CAN_ONLY_NULL | FlowContext.IN_ASSIGNMENT, flowInfo);
}
}
- nullStatus = checkAssignmentAgainstNullAnnotation(currentScope, flowContext, var, nullStatus, this.expression);
- if (var != null && (var.type.tagBits & TagBits.IsBaseType) == 0) {
- flowInfo.markNullStatus(var, nullStatus);
+ nullStatus = checkAssignmentAgainstNullAnnotation(currentScope, flowContext, local, nullStatus, this.expression);
+ if (local != null && (local.type.tagBits & TagBits.IsBaseType) == 0) {
+ flowInfo.markNullStatus(local, nullStatus);
if (flowContext.initsOnFinally != null)
- flowContext.initsOnFinally.markNullStatus(var, nullStatus);
+ flowContext.initsOnFinally.markNullStatus(local, nullStatus);
}
return flowInfo;
}
@@ -291,7 +290,4 @@
public LocalVariableBinding localVariableBinding() {
return this.lhs.localVariableBinding();
}
-public VariableBinding variableBinding(Scope scope) {
- return this.lhs.variableBinding(scope);
-}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java
index eec56b7..0f273c7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java
@@ -8,9 +8,11 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
- * Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
* Fraunhofer FIRST - extended API and implementation
* Technical University Berlin - extended API and implementation
+ * Stephan Herrmann - Contributions for
+ * bug 349326 - [1.7] new warning for missing try-with-resources
+ * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -50,9 +52,8 @@
flowInfo = stat.analyseCode(this.scope, flowContext, flowInfo);
}
}
-
if (this.explicitDeclarations > 0) // if block has its own scope analyze tracking vars now:
- this.scope.checkUnclosedCloseables(flowInfo, null, null);
+ this.scope.checkUnclosedCloseables(flowInfo, flowContext, null, null);
return flowInfo;
}
/**
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
index a870ad4..08c2de8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 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
@@ -36,7 +36,6 @@
import org.eclipse.jdt.internal.compiler.lookup.TagBits;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
-import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
@@ -546,13 +545,6 @@
return this.expression.localVariableBinding();
}
-/**
- * @see org.eclipse.jdt.internal.compiler.ast.Expression#variableBinding(Scope)
- */
-public VariableBinding variableBinding(Scope scope) {
- return this.expression.variableBinding(scope);
-}
-
public int nullStatus(FlowInfo flowInfo) {
return this.expression.nullStatus(flowInfo);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
index 7563740..9e79a91 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
@@ -14,6 +14,7 @@
* bug 349326 - [1.7] new warning for missing try-with-resources
* bug 186342 - [compiler][null] Using annotations for null checking
* bug 361407 - Resource leak warning when resource is assigned to a field outside of constructor
+ * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -308,7 +309,7 @@
constructorContext.complainIfUnusedExceptionHandlers(this);
// check unused parameters
this.scope.checkUnusedParameters(this.binding);
- this.scope.checkUnclosedCloseables(flowInfo, null/*don't report against a specific location*/, null);
+ this.scope.checkUnclosedCloseables(flowInfo, null, null/*don't report against a specific location*/, null);
} catch (AbortMethod e) {
this.ignoreFurtherInvestigation = true;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java
index 5c08d86..134ccdb 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 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
@@ -39,43 +39,43 @@
// TODO: handle all kinds of expressions (cf. also https://bugs.eclipse.org/364326)
}
- VariableBinding var = this.left.variableBinding(scope);
- if (var != null && (var.type.tagBits & TagBits.IsBaseType) == 0) {
- checkVariableComparison(scope, flowContext, flowInfo, initsWhenTrue, initsWhenFalse, var, rightStatus, this.left);
+ LocalVariableBinding local = this.left.localVariableBinding();
+ if (local != null && (local.type.tagBits & TagBits.IsBaseType) == 0) {
+ checkVariableComparison(scope, flowContext, flowInfo, initsWhenTrue, initsWhenFalse, local, rightStatus, this.left);
}
- var = this.right.variableBinding(scope);
- if (var != null && (var.type.tagBits & TagBits.IsBaseType) == 0) {
- checkVariableComparison(scope, flowContext, flowInfo, initsWhenTrue, initsWhenFalse, var, leftStatus, this.right);
+ local = this.right.localVariableBinding();
+ if (local != null && (local.type.tagBits & TagBits.IsBaseType) == 0) {
+ checkVariableComparison(scope, flowContext, flowInfo, initsWhenTrue, initsWhenFalse, local, leftStatus, this.right);
}
}
- private void checkVariableComparison(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo, FlowInfo initsWhenTrue, FlowInfo initsWhenFalse, VariableBinding var, int nullStatus, Expression reference) {
+ private void checkVariableComparison(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo, FlowInfo initsWhenTrue, FlowInfo initsWhenFalse, LocalVariableBinding local, int nullStatus, Expression reference) {
switch (nullStatus) {
case FlowInfo.NULL :
if (((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) {
- flowContext.recordUsingNullReference(scope, var, reference,
+ flowContext.recordUsingNullReference(scope, local, reference,
FlowContext.CAN_ONLY_NULL_NON_NULL | FlowContext.IN_COMPARISON_NULL, flowInfo);
- initsWhenTrue.markAsComparedEqualToNull(var); // from thereon it is set
- initsWhenFalse.markAsComparedEqualToNonNull(var); // from thereon it is set
+ initsWhenTrue.markAsComparedEqualToNull(local); // from thereon it is set
+ initsWhenFalse.markAsComparedEqualToNonNull(local); // from thereon it is set
} else {
- flowContext.recordUsingNullReference(scope, var, reference,
+ flowContext.recordUsingNullReference(scope, local, reference,
FlowContext.CAN_ONLY_NULL_NON_NULL | FlowContext.IN_COMPARISON_NON_NULL, flowInfo);
- initsWhenTrue.markAsComparedEqualToNonNull(var); // from thereon it is set
- initsWhenFalse.markAsComparedEqualToNull(var); // from thereon it is set
+ initsWhenTrue.markAsComparedEqualToNonNull(local); // from thereon it is set
+ initsWhenFalse.markAsComparedEqualToNull(local); // from thereon it is set
}
if ((flowContext.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) != 0) {
- flowInfo.markedAsNullOrNonNullInAssertExpression(var);
+ flowInfo.markedAsNullOrNonNullInAssertExpression(local);
}
break;
case FlowInfo.NON_NULL :
if (((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) {
- flowContext.recordUsingNullReference(scope, var, reference,
+ flowContext.recordUsingNullReference(scope, local, reference,
FlowContext.CAN_ONLY_NULL | FlowContext.IN_COMPARISON_NON_NULL, flowInfo);
- initsWhenTrue.markAsComparedEqualToNonNull(var); // from thereon it is set
+ initsWhenTrue.markAsComparedEqualToNonNull(local); // from thereon it is set
if ((flowContext.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) != 0) {
- initsWhenTrue.markedAsNullOrNonNullInAssertExpression(var);
+ initsWhenTrue.markedAsNullOrNonNullInAssertExpression(local);
}
} else {
- flowContext.recordUsingNullReference(scope, var, reference,
+ flowContext.recordUsingNullReference(scope, local, reference,
FlowContext.CAN_ONLY_NULL | FlowContext.IN_COMPARISON_NULL, flowInfo);
}
break;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
index 47941f1..13ac321 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
@@ -14,6 +14,7 @@
* bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
* bug 186342 - [compiler][null] Using annotations for null checking
* bug 361407 - Resource leak warning when resource is assigned to a field outside of constructor
+ * bug 370639 - [compiler][resource] restore the default for resource leak warnings
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -136,13 +137,16 @@
}
// process arguments
if (this.arguments != null) {
+ boolean analyseResources = currentScope.compilerOptions().analyseResourceLeaks;
for (int i = 0, max = this.arguments.length; i < max; i++) {
flowInfo =
this.arguments[i]
.analyseCode(currentScope, flowContext, flowInfo)
.unconditionalInits();
- // if argument is an AutoCloseable insert info that it *may* be closed (by the target constructor, i.e.)
- flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo, false);
+ if (analyseResources) {
+ // if argument is an AutoCloseable insert info that it *may* be closed (by the target constructor, i.e.)
+ flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo, false);
+ }
if ((this.arguments[i].implicitConversion & TypeIds.UNBOXING) != 0) {
this.arguments[i].checkNPE(currentScope, flowContext, flowInfo);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
index 31ce927..59588d2 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 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
@@ -43,7 +43,6 @@
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
-import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
import org.eclipse.jdt.internal.compiler.lookup.WildcardBinding;
import org.eclipse.jdt.internal.compiler.problem.ShouldNotImplement;
import org.eclipse.jdt.internal.compiler.util.Messages;
@@ -711,22 +710,22 @@
* @param flowInfo the upstream flow info; caveat: may get modified
*/
public void checkNPE(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo) {
- VariableBinding var = variableBinding(scope);
- if (var != null &&
- (var.type.tagBits & TagBits.IsBaseType) == 0) {
+ LocalVariableBinding local = localVariableBinding();
+ if (local != null &&
+ (local.type.tagBits & TagBits.IsBaseType) == 0) {
if ((this.bits & ASTNode.IsNonNull) == 0) {
- flowContext.recordUsingNullReference(scope, var, this,
+ flowContext.recordUsingNullReference(scope, local, this,
FlowContext.MAY_NULL, flowInfo);
}
- flowInfo.markAsComparedEqualToNonNull(var );
+ flowInfo.markAsComparedEqualToNonNull(local);
// from thereon it is set
if ((flowContext.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) != 0) {
- flowInfo.markedAsNullOrNonNullInAssertExpression(var);
+ flowInfo.markedAsNullOrNonNullInAssertExpression(local);
}
if (flowContext.initsOnFinally != null) {
- flowContext.initsOnFinally.markAsComparedEqualToNonNull(var);
+ flowContext.initsOnFinally.markAsComparedEqualToNonNull(local);
if ((flowContext.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) != 0) {
- flowContext.initsOnFinally.markedAsNullOrNonNullInAssertExpression(var);
+ flowContext.initsOnFinally.markedAsNullOrNonNullInAssertExpression(local);
}
}
}
@@ -1058,9 +1057,9 @@
this.constant != null && this.constant != Constant.NotAConstant)
return FlowInfo.NON_NULL; // constant expression cannot be null
- VariableBinding var = variableBinding(null);
- if (var != null)
- return flowInfo.nullStatus(var);
+ LocalVariableBinding local = localVariableBinding();
+ if (local != null)
+ return flowInfo.nullStatus(local);
return FlowInfo.NON_NULL;
}
@@ -1298,15 +1297,4 @@
public void traverse(ASTVisitor visitor, ClassScope scope) {
// nothing to do
}
-
-/**
- * Returns the field or local variable referenced by this node. Can be a direct reference (SingleNameReference)
- * or thru a cast expression etc...
- * This is used for the purpose of obtaining a local variable or field binding for the purpose of null analysis.
- * @param scope This is the current scope in which binding is requested and is needed to ascertain if a static field
- * belongs to the current type for null analysis. A <code>null</code> value may be passed to this parameter
-*/
-public VariableBinding variableBinding(Scope scope) {
- return null;
-}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
index 6343221..4ac6c2f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
@@ -109,6 +109,7 @@
scope.getJavaLangObject(), // dummy, just needs to be a reference type
0,
false);
+ this.binding.closeTracker = this;
this.binding.declaringScope = scope;
this.binding.setConstant(Constant.NotAConstant);
this.binding.useFlag = LocalVariableBinding.USED;
@@ -336,18 +337,35 @@
disconnectedTracker = previousTracker; // report error below, unless we have a self-wrap assignment
}
+ rhsAnalyis:
if (rhs.resolvedType != TypeBinding.NULL) {
// new value is AutoCloseable, start tracking, possibly re-using existing tracker var:
FakedTrackingVariable rhsTrackVar = getCloseTrackingVariable(rhs);
if (rhsTrackVar != null) { // 1. if RHS has a tracking variable...
if (local.closeTracker == null) {
- // null shouldn't occur but let's play safe
+ // null shouldn't occur but let's play safe:
if (rhsTrackVar.originalBinding != null)
- local.closeTracker = rhsTrackVar; // a.: let fresh LHS share it
+ local.closeTracker = rhsTrackVar; // a.: let fresh LHS share it
+ if (rhsTrackVar.currentAssignment == location) {
+ // pre-set tracker from lhs - passed from outside?
+ // now it's a fresh resource
+ rhsTrackVar.globalClosingState &= ~(SHARED_WITH_OUTSIDE|OWNED_BY_OUTSIDE);
+ }
} else {
- if (rhsTrackVar == disconnectedTracker && rhs instanceof AllocationExpression)
- return; // b.: self wrapper: res = new Wrap(res); -> done!
- local.closeTracker = rhsTrackVar; // c.: conflicting LHS and RHS, proceed with recordErrorLocation below
+ if (rhs instanceof AllocationExpression) {
+ if (rhsTrackVar == disconnectedTracker)
+ return; // b.: self wrapper: res = new Wrap(res); -> done!
+ if (local.closeTracker == rhsTrackVar
+ && ((rhsTrackVar.globalClosingState & OWNED_BY_OUTSIDE) != 0)) {
+ // c.: assigning a fresh resource (pre-connected alloc)
+ // to a local previously holding an alien resource -> start over
+ local.closeTracker = new FakedTrackingVariable(local, location);
+ flowInfo.markAsDefinitelyNull(local.closeTracker.binding);
+ // still check disconnectedTracker below
+ break rhsAnalyis;
+ }
+ }
+ local.closeTracker = rhsTrackVar; // d.: conflicting LHS and RHS, proceed with recordErrorLocation below
}
// keep close-status of RHS unchanged across this assignment
} else if (previousTracker != null) { // 2. re-use tracking variable from the LHS?
@@ -420,8 +438,11 @@
FakedTrackingVariable tracker = new FakedTrackingVariable(local, location);
tracker.globalClosingState |= SHARED_WITH_OUTSIDE;
flowInfo.markPotentiallyNullBit(tracker.binding); // shed some doubt
- return tracker;
- } else if ((expression.bits & RestrictiveFlagMASK) == Binding.FIELD)
+ return tracker;
+ } else if (
+ (expression.bits & RestrictiveFlagMASK) == Binding.FIELD
+ ||((expression instanceof QualifiedNameReference)
+ && ((QualifiedNameReference) expression).isFieldAccess()))
{
// responsibility for this resource probably lies at a higher level
FakedTrackingVariable tracker = new FakedTrackingVariable(local, location);
@@ -440,7 +461,12 @@
if (local.closeTracker != null)
// (c): inner has already been analyzed: -> re-use track var
return local.closeTracker;
- return new FakedTrackingVariable(local, location);
+ FakedTrackingVariable newTracker = new FakedTrackingVariable(local, location);
+ LocalVariableBinding rhsLocal = expression.localVariableBinding();
+ if (rhsLocal != null && rhsLocal.isParameter()) {
+ newTracker.globalClosingState |= OWNED_BY_OUTSIDE;
+ }
+ return newTracker;
}
public static void cleanUpAfterAssignment(BlockScope currentScope, int lhsBits, Expression expression) {
@@ -552,8 +578,8 @@
flowInfo.markAsDefinitelyNonNull(current.binding);
current.globalClosingState |= CLOSE_SEEN;
//TODO(stephan): this might be useful, but I could not find a test case for it:
-// if (flowContext.initsOnFinally != null)
-// flowContext.initsOnFinally.markAsDefinitelyNonNull(this.binding);
+ if (flowContext.initsOnFinally != null)
+ flowContext.initsOnFinally.markAsDefinitelyNonNull(this.binding);
current = current.innerTracker;
} while (current != null);
}
@@ -631,6 +657,35 @@
return trackingVar;
}
+ /**
+ * Answer true if we know for sure that no resource is bound to this variable
+ * at the point of 'flowInfo'.
+ */
+ public boolean hasDefinitelyNoResource(FlowInfo flowInfo) {
+ if (this.originalBinding == null) return false; // shouldn't happen but keep quiet.
+ if (flowInfo.isDefinitelyNull(this.originalBinding)) {
+ return true;
+ }
+ if (!(flowInfo.isDefinitelyAssigned(this.originalBinding)
+ || flowInfo.isPotentiallyAssigned(this.originalBinding))) {
+ return true;
+ }
+ return false;
+ }
+
+ public boolean isClosedInFinallyOfEnclosing(BlockScope scope) {
+ BlockScope currentScope = scope;
+ while (true) {
+ if (currentScope.finallyInfo != null
+ && currentScope.finallyInfo.isDefinitelyNonNull(this.binding)) {
+ return true; // closed in enclosing finally
+ }
+ if (!(currentScope.parent instanceof BlockScope)) {
+ return false;
+ }
+ currentScope = (BlockScope) currentScope.parent;
+ }
+ }
/**
* If current is the same as 'returnedResource' or a wrapper thereof,
* mark as reported and return true, otherwise false.
@@ -648,6 +703,9 @@
}
public void recordErrorLocation(ASTNode location, int nullStatus) {
+ if ((this.globalClosingState & OWNED_BY_OUTSIDE) != 0) {
+ return;
+ }
if (this.recordedLocations == null)
this.recordedLocations = new HashMap();
this.recordedLocations.put(location, new Integer(nullStatus));
@@ -684,12 +742,15 @@
}
public int reportError(ProblemReporter problemReporter, ASTNode location, int nullStatus) {
+ if ((this.globalClosingState & OWNED_BY_OUTSIDE) != 0) {
+ return 0; // TODO: should we still propagate some flags??
+ }
// which degree of problem?
boolean isPotentialProblem = false;
if (nullStatus == FlowInfo.NULL) {
if ((this.globalClosingState & CLOSED_IN_NESTED_METHOD) != 0)
isPotentialProblem = true;
- } else if (nullStatus == FlowInfo.POTENTIALLY_NULL) {
+ } else if ((nullStatus & (FlowInfo.POTENTIALLY_NULL|FlowInfo.POTENTIALLY_NON_NULL)) != 0) {
isPotentialProblem = true;
}
// report:
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java
index 0dde07b..a629d99 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 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
@@ -111,13 +111,6 @@
.analyseCode(initializationScope, flowContext, flowInfo)
.unconditionalInits();
flowInfo.markAsDefinitelyAssigned(this.binding);
- if (this.binding.isFinal() && this.binding.isStatic()) {
- int nullStatus = this.initialization.nullStatus(flowInfo);
- // static final field being initialized. Record its null status for future reference
- // since the flowInfo from an initialization wont be available in a method
- flowInfo.markNullStatus(this.binding, nullStatus);
-// this.binding.setNullStatusForStaticFinalField(nullStatus);
- }
}
return flowInfo;
}
@@ -167,6 +160,12 @@
return (this.modifiers & ClassFileConstants.AccStatic) != 0;
}
+public boolean isFinal() {
+ if (this.binding != null)
+ return this.binding.isFinal();
+ return (this.modifiers & ClassFileConstants.AccFinal) != 0;
+}
+
public StringBuffer printStatement(int indent, StringBuffer output) {
if (this.javadoc != null) {
this.javadoc.print(indent, output);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
index a1d5c99..64331cd 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 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
@@ -21,12 +21,10 @@
import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
import org.eclipse.jdt.internal.compiler.flow.FlowContext;
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
-import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
-import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
@@ -43,7 +41,6 @@
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
-import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.CalloutMappingDeclaration;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.FieldAccessSpec;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.RoleTypeBinding;
@@ -835,22 +832,4 @@
}
visitor.endVisit(this, scope);
}
-
-public VariableBinding variableBinding(Scope scope) {
- if (scope != null) {
- CompilerOptions options = scope.compilerOptions();
- if(!options.includeFieldsInNullAnalysis) return null;
- if (this.receiver.isThis()) return this.binding;
- if (this.binding != null && this.binding.declaringClass != null && this.binding.isStatic()) {
- // does the static field belong to the current type or one of the enclosing ones?
- ClassScope enclosingClass = scope.enclosingClassScope();
- while (enclosingClass != null) {
- TypeDeclaration type = enclosingClass.referenceContext;
- if (type != null && (this.binding.declaringClass.original() == type.binding)) return this.binding;
- enclosingClass = enclosingClass.enclosingClassScope();
- }
- }
- }
- return null;
-}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java
index e2f1711..85f3b59 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 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
@@ -7,8 +7,10 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
- * Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
* Technical University Berlin - extended API and implementation
+ * Stephan Herrmann - Contribution for
+ * bug 349326 - [1.7] new warning for missing try-with-resources
+ * bug 370930 - NonNull annotation not considered for enhanced for loops
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -29,6 +31,7 @@
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
import org.eclipse.objectteams.otdt.internal.core.compiler.control.Config;
@@ -96,9 +99,10 @@
this.collection.checkNPE(currentScope, flowContext, flowInfo);
flowInfo = this.elementVariable.analyseCode(this.scope, flowContext, flowInfo);
FlowInfo condInfo = this.collection.analyseCode(this.scope, flowContext, flowInfo.copy());
+ LocalVariableBinding elementVarBinding = this.elementVariable.binding;
// element variable will be assigned when iterating
- condInfo.markAsDefinitelyAssigned(this.elementVariable.binding);
+ condInfo.markAsDefinitelyAssigned(elementVarBinding);
this.postCollectionInitStateIndex = currentScope.methodScope().recordInitializationStates(condInfo);
@@ -108,7 +112,17 @@
this.continueLabel, this.scope);
UnconditionalFlowInfo actionInfo =
condInfo.nullInfoLessUnconditionalCopy();
- actionInfo.markAsDefinitelyUnknown(this.elementVariable.binding);
+ actionInfo.markAsDefinitelyUnknown(elementVarBinding);
+ if (currentScope.compilerOptions().isAnnotationBasedNullAnalysisEnabled) {
+ // this currently produces an unavoidable warning against all @NonNull element vars:
+ int nullStatus = this.elementVariable.checkAssignmentAgainstNullAnnotation(currentScope, flowContext,
+ elementVarBinding, FlowInfo.UNKNOWN, this.collection);
+ // TODO (stephan): once we have JSR 308 fetch nullStatus from the collection element type
+ // and feed the result into the above check (instead of FlowInfo.UNKNOWN)
+ if ((elementVarBinding.type.tagBits & TagBits.IsBaseType) == 0) {
+ actionInfo.markNullStatus(elementVarBinding, nullStatus);
+ }
+ }
FlowInfo exitBranch;
if (!(this.action == null || (this.action.isEmptyBlock()
&& currentScope.compilerOptions().complianceLevel <= ClassFileConstants.JDK1_3))) {
@@ -142,7 +156,7 @@
switch(this.kind) {
case ARRAY :
if (!hasEmptyAction
- || this.elementVariable.binding.resolvedPosition != -1) {
+ || elementVarBinding.resolvedPosition != -1) {
this.collectionVariable.useFlag = LocalVariableBinding.USED;
if (this.continueLabel != null) {
this.indexVariable.useFlag = LocalVariableBinding.USED;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java
index f65a1f3..5b16a03 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 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
@@ -63,16 +63,16 @@
if (this.roleCheckExpr != null)
return this.roleCheckExpr.analyseCode(currentScope, flowContext, flowInfo);
// SH}
- VariableBinding variable = this.expression.variableBinding(currentScope);
- if (variable != null && (variable.type.tagBits & TagBits.IsBaseType) == 0) {
+ LocalVariableBinding local = this.expression.localVariableBinding();
+ if (local != null && (local.type.tagBits & TagBits.IsBaseType) == 0) {
flowInfo = this.expression.analyseCode(currentScope, flowContext, flowInfo).
unconditionalInits();
FlowInfo initsWhenTrue = flowInfo.copy();
- initsWhenTrue.markAsComparedEqualToNonNull(variable );
+ initsWhenTrue.markAsComparedEqualToNonNull(local);
if ((flowContext.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) != 0) {
- initsWhenTrue.markedAsNullOrNonNullInAssertExpression(variable);
+ initsWhenTrue.markedAsNullOrNonNullInAssertExpression(local);
}
- flowContext.recordUsingNullReference(currentScope, variable,
+ flowContext.recordUsingNullReference(currentScope, local,
this.expression, FlowContext.CAN_ONLY_NULL | FlowContext.IN_INSTANCEOF, flowInfo);
// no impact upon enclosing try context
return FlowInfo.conditional(initsWhenTrue, flowInfo.copy());
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 2645370..6414c6b 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
@@ -17,6 +17,7 @@
* bug 349326 - [1.7] new warning for missing try-with-resources
* bug 186342 - [compiler][null] Using annotations for null checking
* bug 358903 - Filter practically unimportant resource leak warnings
+ * bug 370639 - [compiler][resource] restore the default for resource leak warnings
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -121,8 +122,9 @@
FlowInfo preInitInfo = null;
boolean shouldAnalyseResource = this.binding != null
- && flowInfo.reachMode() == FlowInfo.REACHABLE
- && FakedTrackingVariable.isAnyCloseable(this.initialization.resolvedType);
+ && flowInfo.reachMode() == FlowInfo.REACHABLE
+ && FakedTrackingVariable.isAnyCloseable(this.initialization.resolvedType)
+ && currentScope.compilerOptions().analyseResourceLeaks;
if (shouldAnalyseResource) {
preInitInfo = flowInfo.unconditionalCopy();
// analysis of resource leaks needs additional context while analyzing the RHS:
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 bb46f0d..88470f8 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
@@ -16,6 +16,7 @@
* bug 349326 - [1.7] new warning for missing try-with-resources
* bug 186342 - [compiler][null] Using annotations for null checking
* bug 358903 - Filter practically unimportant resource leak warnings
+ * bug 370639 - [compiler][resource] restore the default for resource leak warnings
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -153,7 +154,8 @@
boolean nonStatic = !this.binding.isStatic();
flowInfo = this.receiver.analyseCode(currentScope, flowContext, flowInfo, nonStatic).unconditionalInits();
// recording the closing of AutoCloseable resources:
- if (CharOperation.equals(TypeConstants.CLOSE, this.selector))
+ boolean analyseResources = currentScope.compilerOptions().analyseResourceLeaks;
+ if (analyseResources && CharOperation.equals(TypeConstants.CLOSE, this.selector))
{
FakedTrackingVariable trackingVariable = FakedTrackingVariable.getCloseTrackingVariable(this.receiver);
if (trackingVariable != null) { // null happens if receiver is not a local variable or not an AutoCloseable
@@ -185,8 +187,10 @@
this.arguments[i].checkNPE(currentScope, flowContext, flowInfo);
}
flowInfo = this.arguments[i].analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
- // if argument is an AutoCloseable insert info that it *may* be closed (by the target method, i.e.)
- flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo, false);
+ if (analyseResources) {
+ // if argument is an AutoCloseable insert info that it *may* be closed (by the target method, i.e.)
+ flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo, false);
+ }
}
analyseArguments(currentScope, flowContext, flowInfo, this.binding, this.arguments);
}
@@ -203,11 +207,6 @@
// NullReferenceTest#test0510
}
manageSyntheticAccessIfNecessary(currentScope, flowInfo);
- // a method call can result in changed values for fields,
- // so wipe out null info for fields collected till now.
- CompilerOptions options = currentScope.compilerOptions();
- if(options.includeFieldsInNullAnalysis)
- flowInfo.resetNullInfoForFields();
//{ObjectTeams: base calls via super:
flowInfo = checkBaseCallsIfSuper(currentScope, flowInfo);
// SH}
@@ -249,6 +248,11 @@
return flowInfo;
}
// SH}
+public void checkNPE(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo) {
+ super.checkNPE(scope, flowContext, flowInfo);
+ if ((nullStatus(flowInfo) & FlowInfo.POTENTIALLY_NULL) != 0)
+ scope.problemReporter().messageSendPotentialNullReference(this.binding, this);
+}
/**
* @see org.eclipse.jdt.internal.compiler.ast.Expression#computeConversion(org.eclipse.jdt.internal.compiler.lookup.Scope, org.eclipse.jdt.internal.compiler.lookup.TypeBinding, org.eclipse.jdt.internal.compiler.lookup.TypeBinding)
*/
@@ -396,11 +400,6 @@
}
codeStream.recordPositionsFrom(pc, (int)(this.nameSourcePosition >>> 32)); // highlight selector
}
-public void checkNPE(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo) {
- super.checkNPE(scope, flowContext, flowInfo);
- if ((nullStatus(flowInfo) & FlowInfo.POTENTIALLY_NULL) != 0)
- scope.problemReporter().messageSendPotentialNullReference(this.binding, this);
-}
/**
* @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#genericTypeArguments()
*/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
index 3d0cfde..882980c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 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,6 +14,7 @@
* bug 349326 - [1.7] new warning for missing try-with-resources
* bug 186342 - [compiler][null] Using annotations for null checking
* bug 365519 - editorial cleanup after bug 186342 and bug 365387
+ * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -192,7 +193,7 @@
}
}
- this.scope.checkUnclosedCloseables(flowInfo, null/*don't report against a specific location*/, null);
+ this.scope.checkUnclosedCloseables(flowInfo, null, null/*don't report against a specific location*/, null);
} catch (AbortMethod e) {
this.ignoreFurtherInvestigation = true;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
index 74cbe54..7fa5367 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 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
@@ -13,6 +13,8 @@
* bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
* bug 349326 - [1.7] new warning for missing try-with-resources
* bug 186342 - [compiler][null] Using annotations for null checking
+ * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+ * bug 370639 - [compiler][resource] restore the default for resource leak warnings
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -148,9 +150,12 @@
// process arguments
if (this.arguments != null) {
+ boolean analyseResources = currentScope.compilerOptions().analyseResourceLeaks;
for (int i = 0, count = this.arguments.length; i < count; i++) {
- // if argument is an AutoCloseable insert info that it *may* be closed (by the target method, i.e.)
- flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo, false);
+ if (analyseResources) {
+ // if argument is an AutoCloseable insert info that it *may* be closed (by the target method, i.e.)
+ flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo, false);
+ }
flowInfo = this.arguments[i].analyseCode(currentScope, flowContext, flowInfo);
if ((this.arguments[i].implicitConversion & TypeIds.UNBOXING) != 0) {
this.arguments[i].checkNPE(currentScope, flowContext, flowInfo);
@@ -178,6 +183,12 @@
flowInfo.unconditionalCopy(),
currentScope);
}
+
+ // after having analysed exceptions above start tracking newly allocated resource:
+ if (FakedTrackingVariable.isAnyCloseable(this.resolvedType) && currentScope.compilerOptions().analyseResourceLeaks) {
+ FakedTrackingVariable.analyseCloseableAllocation(currentScope, flowInfo, this);
+ }
+
manageEnclosingInstanceAccessIfNecessary(currentScope, flowInfo);
manageSyntheticAccessIfNecessary(currentScope, flowInfo);
return flowInfo;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java
index e855731..06751b8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java
@@ -14,6 +14,7 @@
* bug 185682 - Increment/decrement operators mark local variables as read
* bug 186342 - [compiler][null] Using annotations for null checking
* bug 365519 - editorial cleanup after bug 186342 and bug 365387
+ * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -909,7 +910,12 @@
setSyntheticAccessor(baseclassField, idx, new SyntheticMethodBinding(fakedAccessorBinding, SyntheticMethodBinding.InferredCalloutToField));
}
// SH}
-
+public boolean isFieldAccess() {
+ if (this.otherBindings != null) {
+ return true;
+ }
+ return (this.bits & ASTNode.RestrictiveFlagMASK) == Binding.FIELD;
+}
public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
//If inlinable field, forget the access emulation, the code gen will directly target it
if (((this.bits & ASTNode.DepthMASK) == 0) || (this.constant != Constant.NotAConstant)) {
@@ -1298,32 +1304,4 @@
public String unboundReferenceErrorName() {
return new String(this.tokens[0]);
}
-
-public VariableBinding variableBinding(Scope scope) {
- // if this is a *static* field and its actualResolvedType is the type in which we currently are asking for the binding,
- // we can safely return the field binding
- if (scope != null) {
- CompilerOptions options = scope.compilerOptions();
- if(!options.includeFieldsInNullAnalysis) return null;
- if (this.binding != null && (this.bits & RestrictiveFlagMASK) == Binding.FIELD) {
- FieldBinding fieldBinding;
- if (this.otherBindings == null) {
- fieldBinding = (FieldBinding) this.binding;
- } else {
- fieldBinding = this.otherBindings[this.otherBindings.length - 1];
- }
- if (fieldBinding.isStatic()) {
- // does the static field belong to the current type or one of the enclosing ones?
- ClassScope enclosingClass = scope.enclosingClassScope();
- while (enclosingClass != null) {
- TypeDeclaration type = enclosingClass.referenceContext;
- if (type != null && fieldBinding.declaringClass.original() == type.binding)
- return fieldBinding;
- enclosingClass = enclosingClass.enclosingClassScope();
- }
- }
- }
- }
- return super.variableBinding(scope);
-}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
index b149e34..ecf9f97 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
@@ -16,6 +16,8 @@
* bug 365835 - [compiler][null] inconsistent error reporting.
* bug 365519 - editorial cleanup after bug 186342 and bug 365387
* bug 358903 - Filter practically unimportant resource leak warnings
+ * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+ * bug 370639 - [compiler][resource] restore the default for resource leak warnings
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -56,12 +58,14 @@
}
if (flowInfo.reachMode() == FlowInfo.REACHABLE)
checkAgainstNullAnnotation(currentScope, flowContext, this.expression.nullStatus(flowInfo));
- FakedTrackingVariable trackingVariable = FakedTrackingVariable.getCloseTrackingVariable(this.expression);
- if (trackingVariable != null) {
- if (methodScope != trackingVariable.methodScope)
- trackingVariable.markClosedInNestedMethod();
- // by returning the method passes the responsibility to the caller:
- flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.expression, flowInfo, true);
+ if (currentScope.compilerOptions().analyseResourceLeaks) {
+ FakedTrackingVariable trackingVariable = FakedTrackingVariable.getCloseTrackingVariable(this.expression);
+ if (trackingVariable != null) {
+ if (methodScope != trackingVariable.methodScope)
+ trackingVariable.markClosedInNestedMethod();
+ // by returning the method passes the responsibility to the caller:
+ flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.expression, flowInfo, true);
+ }
}
}
this.initStateIndex =
@@ -135,7 +139,7 @@
}
}
}
- currentScope.checkUnclosedCloseables(flowInfo, this, currentScope);
+ currentScope.checkUnclosedCloseables(flowInfo, flowContext, this, currentScope);
return FlowInfo.DEAD_END;
}
void checkAgainstNullAnnotation(BlockScope scope, FlowContext flowContext, int nullStatus) {
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 46b0d62..0c23109 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 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
@@ -839,20 +839,6 @@
return null;
}
-public VariableBinding variableBinding(Scope scope) {
- switch (this.bits & ASTNode.RestrictiveFlagMASK) {
- case Binding.FIELD :
- // reading a field
- if (scope != null) {
- CompilerOptions options = scope.compilerOptions();
- if(!options.includeFieldsInNullAnalysis) return null;
- }
- //$FALL-THROUGH$
- case Binding.LOCAL : // reading a local variable
- return (VariableBinding) this.binding;
- }
- return null;
-}
public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
//If inlinable field, forget the access emulation, the code gen will directly target it
if (((this.bits & ASTNode.DepthMASK) == 0) || (this.constant != Constant.NotAConstant)) {
@@ -921,10 +907,11 @@
}
switch (this.bits & ASTNode.RestrictiveFlagMASK) {
case Binding.FIELD : // reading a field
+ return FlowInfo.UNKNOWN;
case Binding.LOCAL : // reading a local variable
- VariableBinding variable = (VariableBinding) this.binding;
- if (variable != null)
- return flowInfo.nullStatus(variable);
+ LocalVariableBinding local = (LocalVariableBinding) this.binding;
+ if (local != null)
+ return flowInfo.nullStatus(local);
}
return FlowInfo.NON_NULL; // never get there
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
index deec8bc..73eeaea 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 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,8 @@
* bug 349326 - [1.7] new warning for missing try-with-resources
* bug 186342 - [compiler][null] Using annotations for null checking
* bug 365983 - [compiler][null] AIOOB with null annotation analysis and varargs
+ * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+ * bug 370930 - NonNull annotation not considered for enhanced for loops
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -71,6 +73,7 @@
public static final int COMPLAINED_FAKE_REACHABLE = 1;
public static final int COMPLAINED_UNREACHABLE = 2;
+
/** Analysing arguments of MessageSend, ExplicitConstructorCall, AllocationExpression. */
protected void analyseArguments(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, MethodBinding methodBinding, Expression[] arguments)
{
@@ -109,13 +112,17 @@
/** Check null-ness of 'local' against a possible null annotation */
protected int checkAssignmentAgainstNullAnnotation(BlockScope currentScope, FlowContext flowContext,
- VariableBinding var, int nullStatus, Expression expression)
+ LocalVariableBinding local, int nullStatus, Expression expression)
{
- if (var != null
- && (var.tagBits & TagBits.AnnotationNonNull) != 0
- && nullStatus != FlowInfo.NON_NULL) {
- flowContext.recordNullityMismatch(currentScope, expression, nullStatus, var.type);
- nullStatus=FlowInfo.NON_NULL;
+ if (local != null) {
+ if ((local.tagBits & TagBits.AnnotationNonNull) != 0
+ && nullStatus != FlowInfo.NON_NULL) {
+ flowContext.recordNullityMismatch(currentScope, expression, nullStatus, local.type);
+ return FlowInfo.NON_NULL;
+ } else if ((local.tagBits & TagBits.AnnotationNullable) != 0
+ && nullStatus == FlowInfo.UNKNOWN) { // provided a legacy type?
+ return FlowInfo.POTENTIALLY_NULL; // -> use more specific info from the annotation
+ }
}
return nullStatus;
}
@@ -153,7 +160,7 @@
/* OT: */ if (shouldReport)
scope.problemReporter().unreachableCode(this);
if (endOfBlock)
- scope.checkUnclosedCloseables(flowInfo, null, null);
+ scope.checkUnclosedCloseables(flowInfo, null, null, null);
}
return COMPLAINED_UNREACHABLE;
} else {
@@ -162,7 +169,7 @@
// SH}
scope.problemReporter().fakeReachable(this);
if (endOfBlock)
- scope.checkUnclosedCloseables(flowInfo, null, null);
+ scope.checkUnclosedCloseables(flowInfo, null, null, null);
}
return COMPLAINED_FAKE_REACHABLE;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java
index 2529629..d8fdce8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 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
@@ -8,9 +8,11 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
- * Stephan Herrmann - Contribution for bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points
* Fraunhofer FIRST - extended API and implementation
* Technical University Berlin - extended API and implementation
+ * Stephan Herrmann - Contributions for
+ * bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points
+ * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -47,7 +49,7 @@
this.exception.checkNPE(currentScope, flowContext, flowInfo);
// need to check that exception thrown is actually caught somewhere
flowContext.checkExceptionHandlers(this.exceptionType, this, flowInfo, currentScope);
- currentScope.checkUnclosedCloseables(flowInfo, this, currentScope);
+ currentScope.checkUnclosedCloseables(flowInfo, flowContext, this, currentScope);
return FlowInfo.DEAD_END;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
index 237f522..9063edd 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
@@ -110,7 +110,7 @@
public MethodScope initializerScope;
public MethodScope staticInitializerScope;
public boolean ignoreFurtherInvestigation = false;
- public int maxFieldCount; // maximum cumulative number of fields of this type and its inners (see updateMaxFieldCount())
+ public int maxFieldCount;
public int declarationSourceStart;
public int declarationSourceEnd;
public int bodyStart;
@@ -545,6 +545,7 @@
localType.setConstantPoolName(currentScope.compilationUnitScope().computeConstantPoolName(localType));
}
manageEnclosingInstanceAccessIfNecessary(currentScope, flowInfo);
+ updateMaxFieldCount(); // propagate down the max field count
internalAnalyseCode(flowContext, flowInfo);
} catch (AbortType e) {
this.ignoreFurtherInvestigation = true;
@@ -560,7 +561,9 @@
if (this.ignoreFurtherInvestigation)
return;
try {
- internalAnalyseCode(null, FlowInfo.initial(this.scope.outerMostClassScope().referenceType().maxFieldCount));
+ // propagate down the max field count
+ updateMaxFieldCount();
+ internalAnalyseCode(null, FlowInfo.initial(this.maxFieldCount));
} catch (AbortType e) {
this.ignoreFurtherInvestigation = true;
}
@@ -580,6 +583,7 @@
localType.setConstantPoolName(currentScope.compilationUnitScope().computeConstantPoolName(localType));
}
manageEnclosingInstanceAccessIfNecessary(currentScope, flowInfo);
+ updateMaxFieldCount(); // propagate down the max field count
internalAnalyseCode(flowContext, flowInfo);
} catch (AbortType e) {
this.ignoreFurtherInvestigation = true;
@@ -1202,11 +1206,6 @@
staticInitializerContext.handledExceptions = Binding.ANY_EXCEPTION; // tolerate them all, and record them
/*}*/
staticFieldInfo = field.analyseCode(this.staticInitializerScope, staticInitializerContext, staticFieldInfo);
- if (field.binding != null && this.scope.compilerOptions().includeFieldsInNullAnalysis
- && ((field.binding.modifiers & ClassFileConstants.AccFinal) != 0)) {
- // we won't reset null Info for constant fields
- staticFieldInfo.updateConstantFieldsMask(field.binding);
- }
// in case the initializer is not reachable, use a reinitialized flowInfo and enter a fake reachable
// branch, since the previous initializer already got the blame.
if (staticFieldInfo == FlowInfo.DEAD_END) {
@@ -1254,18 +1253,7 @@
// SH}
if (this.methods != null) {
UnconditionalFlowInfo outerInfo = flowInfo.unconditionalFieldLessCopy();
- UnconditionalFlowInfo staticFieldUnconditionalInfo = staticFieldInfo.unconditionalInits();
- FlowInfo constructorInfo;
- if (this.scope.compilerOptions().includeFieldsInNullAnalysis) {
- flowInfo.addNullInfoFrom(staticFieldUnconditionalInfo.discardNonFieldInitializations());
- flowInfo.addConstantFieldsMask(staticFieldUnconditionalInfo); // prevent resetting null info for constant fields inside methods
- flowInfo.resetNullInfoForFields(); // only preserve null info for constant fields
- constructorInfo = nonStaticFieldInfo.unconditionalInits().discardNonFieldInitializations().addInitializationsFrom(flowInfo);
- constructorInfo.addConstantFieldsMask(staticFieldUnconditionalInfo); // prevent resetting null info for constant fields inside c'tor too
- } else {
- constructorInfo = nonStaticFieldInfo.unconditionalInits().discardNonFieldInitializations().addInitializationsFrom(outerInfo);
- }
-
+ FlowInfo constructorInfo = nonStaticFieldInfo.unconditionalInits().discardNonFieldInitializations().addInitializationsFrom(outerInfo);
for (int i = 0, count = this.methods.length; i < count; i++) {
AbstractMethodDeclaration method = this.methods[i];
if (method.ignoreFurtherInvestigation)
@@ -1280,7 +1268,7 @@
((Clinit)method).analyseCode(
this.scope,
staticInitializerContext,
- staticFieldUnconditionalInfo.addInitializationsFrom(outerInfo));
+ staticFieldInfo.unconditionalInits().discardNonFieldInitializations().addInitializationsFrom(outerInfo));
} else { // constructor
((ConstructorDeclaration)method).analyseCode(this.scope, initializerContext, constructorInfo.copy(), flowInfo.reachMode());
}
@@ -1756,6 +1744,8 @@
}
}
// SH}
+ // this.maxFieldCount might already be set
+ int localMaxFieldCount = 0;
int lastVisibleFieldID = -1;
boolean hasEnumConstants = false;
FieldDeclaration[] enumConstantsWithoutBody = null;
@@ -1765,43 +1755,6 @@
this.typeParameters[i].resolve(this.scope);
}
}
- // field count from enclosing and supertypes should be included in maxFieldCount,
- // to make field-ids unique among all fields in scope.
- // 1.: enclosing:
- TypeBinding original = sourceType.original();
- int fieldAnalysisOffset = 0;
- if (original instanceof NestedTypeBinding) {
- // note: local types have no enclosingType in the AST but only in the binding:
- fieldAnalysisOffset = ((NestedTypeBinding)original).enclosingType.cumulativeFieldCount;
- }
- // 2.: supers:
- ReferenceBinding superClassBinding = sourceType.superclass;
- while (superClassBinding != null) {
- FieldBinding[] unResolvedFields = superClassBinding.unResolvedFields();
- if (unResolvedFields != null) {
- for (int i=unResolvedFields.length-1; i>=0; i--) {
- // if the field is an initializer we do not want to update the count
- switch (unResolvedFields[i].kind()) {
- case AbstractVariableDeclaration.FIELD:
- case AbstractVariableDeclaration.ENUM_CONSTANT:
- fieldAnalysisOffset++;
- }
- }
- }
- fieldAnalysisOffset += findFieldCountFromSuperInterfaces(superClassBinding.superInterfaces());
- superClassBinding = superClassBinding.superclass();
- }
- ReferenceBinding[] superInterfacesBinding = sourceType.superInterfaces;
- fieldAnalysisOffset += findFieldCountFromSuperInterfaces(superInterfacesBinding);
-//{ObjectTeams: also count type value parameters into maxFieldCount
- if (this.typeParameters != null)
- fieldAnalysisOffset += TypeValueParameter.count(this);
-// SH}
-
- sourceType.cumulativeFieldCount += fieldAnalysisOffset;
- sourceType.fieldAnalysisOffset = fieldAnalysisOffset;
- this.maxFieldCount = sourceType.cumulativeFieldCount;
-
if (this.memberTypes != null) {
//{ObjectTeams: don't cache count, array may grow during this loop!
/* orig:
@@ -1815,7 +1768,7 @@
//{ObjectTeams: should we work at all?
Config config = Config.getConfig();
boolean fieldsAndMethods = config.verifyMethods;
- if (fieldsAndMethods)
+ if (fieldsAndMethods) {
// SH}
if (this.fields != null) {
for (int i = 0, count = this.fields.length; i < count; i++) {
@@ -1843,6 +1796,7 @@
&& TypeBinding.LONG == fieldBinding.type) {
needSerialVersion = false;
}
+ localMaxFieldCount++;
lastVisibleFieldID = field.binding.id;
break;
@@ -1853,6 +1807,14 @@
field.resolve(field.isStatic() ? this.staticInitializerScope : this.initializerScope);
}
}
+//{ObjectTeams: also count type value parameters into maxFieldCount
+ if (this.typeParameters != null)
+ TypeValueParameter.updateMaxFieldCount(this);
+ }
+// SH}
+ if (this.maxFieldCount < localMaxFieldCount) {
+ this.maxFieldCount = localMaxFieldCount;
+ }
if (needSerialVersion) {
//check that the current type doesn't extend javax.rmi.CORBA.Stub
TypeBinding javaxRmiCorbaStub = this.scope.getType(TypeConstants.JAVAX_RMI_CORBA_STUB, 4);
@@ -1961,19 +1923,6 @@
}
}
-private int findFieldCountFromSuperInterfaces(ReferenceBinding[] superinterfaces) {
- int numOfFields = 0;
- if (superinterfaces == null)
- return numOfFields ;
- for (int i = 0; i < superinterfaces.length; i++) {
- FieldBinding[] unResolvedFields = superinterfaces[i].unResolvedFields();
- // no need to check field kinds as initializer cannot occur inside interfaces
- numOfFields += unResolvedFields != null ? unResolvedFields.length : 0;
- numOfFields += findFieldCountFromSuperInterfaces(superinterfaces[i].superInterfaces());
- }
- return numOfFields;
-}
-
/**
* Resolve a local type declaration
*/
@@ -2214,9 +2163,9 @@
if (this.fields != null) {
int length = this.fields.length;
for (int i = 0; i < length; i++) {
- FieldDeclaration field;
- if ((field = this.fields[i]).isStatic()) {
- // local type cannot have static fields
+ FieldDeclaration field = this.fields[i];
+ if (field.isStatic() && !field.isFinal()) {
+ // local type cannot have static fields that are not final, https://bugs.eclipse.org/bugs/show_bug.cgi?id=244544
} else {
field.traverse(visitor, this.initializerScope);
}
@@ -2301,21 +2250,21 @@
/**
* MaxFieldCount's computation is necessary so as to reserve space for
* the flow info field portions. It corresponds to the maximum amount of
- * accumulated fields this class or one of its innertypes have.
+ * fields this class or one of its innertypes have.
*
- * During buildFields() accumulative field counts are gather per class,
- * which include fields of outer and super types.
- * During resolve, the maximum of these counts is collected inside out.
+ * During name resolution, types are traversed, and the max field count is recorded
+ * on the outermost type. It is then propagated down during the flow analysis.
+ *
+ * This method is doing either up/down propagation.
*/
-//{ObjectTeams: make accessible for ClassScope.addGeneratedField():
-public
-// SH}
void updateMaxFieldCount() {
if (this.binding == null)
return; // error scenario
TypeDeclaration outerMostType = this.scope.outerMostClassScope().referenceType();
if (this.maxFieldCount > outerMostType.maxFieldCount) {
outerMostType.maxFieldCount = this.maxFieldCount; // up
+ } else {
+ this.maxFieldCount = outerMostType.maxFieldCount; // down
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java
index 4689bf8..5cb4166 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 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
@@ -13,7 +13,6 @@
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
-import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
/**
* Record conditional initialization status during definite assignment analysis
@@ -74,120 +73,121 @@
return this.initsWhenTrue;
}
-public boolean isDefinitelyAssigned(VariableBinding var) {
+public boolean isDefinitelyAssigned(FieldBinding field) {
- return this.initsWhenTrue.isDefinitelyAssigned(var)
- && this.initsWhenFalse.isDefinitelyAssigned(var);
+ return this.initsWhenTrue.isDefinitelyAssigned(field)
+ && this.initsWhenFalse.isDefinitelyAssigned(field);
}
-public boolean isDefinitelyNonNull(VariableBinding var) {
- return this.initsWhenTrue.isDefinitelyNonNull(var)
- && this.initsWhenFalse.isDefinitelyNonNull(var);
+public boolean isDefinitelyAssigned(LocalVariableBinding local) {
+
+ return this.initsWhenTrue.isDefinitelyAssigned(local)
+ && this.initsWhenFalse.isDefinitelyAssigned(local);
}
-public boolean isDefinitelyNull(VariableBinding var) {
- return this.initsWhenTrue.isDefinitelyNull(var)
- && this.initsWhenFalse.isDefinitelyNull(var);
+public boolean isDefinitelyNonNull(LocalVariableBinding local) {
+ return this.initsWhenTrue.isDefinitelyNonNull(local)
+ && this.initsWhenFalse.isDefinitelyNonNull(local);
}
-public boolean isDefinitelyUnknown(VariableBinding var) {
- return this.initsWhenTrue.isDefinitelyUnknown(var)
- && this.initsWhenFalse.isDefinitelyUnknown(var);
+public boolean isDefinitelyNull(LocalVariableBinding local) {
+ return this.initsWhenTrue.isDefinitelyNull(local)
+ && this.initsWhenFalse.isDefinitelyNull(local);
}
-public boolean isPotentiallyAssigned(VariableBinding var) {
- return this.initsWhenTrue.isPotentiallyAssigned(var)
- || this.initsWhenFalse.isPotentiallyAssigned(var);
+public boolean isDefinitelyUnknown(LocalVariableBinding local) {
+ return this.initsWhenTrue.isDefinitelyUnknown(local)
+ && this.initsWhenFalse.isDefinitelyUnknown(local);
}
-public boolean isPotentiallyNonNull(VariableBinding var) {
- return this.initsWhenTrue.isPotentiallyNonNull(var)
- || this.initsWhenFalse.isPotentiallyNonNull(var);
+public boolean isPotentiallyAssigned(FieldBinding field) {
+ return this.initsWhenTrue.isPotentiallyAssigned(field)
+ || this.initsWhenFalse.isPotentiallyAssigned(field);
}
-public boolean isPotentiallyNull(VariableBinding var) {
- return this.initsWhenTrue.isPotentiallyNull(var)
- || this.initsWhenFalse.isPotentiallyNull(var);
+public boolean isPotentiallyAssigned(LocalVariableBinding local) {
+ return this.initsWhenTrue.isPotentiallyAssigned(local)
+ || this.initsWhenFalse.isPotentiallyAssigned(local);
}
-public boolean isPotentiallyUnknown(VariableBinding var) {
- return this.initsWhenTrue.isPotentiallyUnknown(var)
- || this.initsWhenFalse.isPotentiallyUnknown(var);
+public boolean isPotentiallyNonNull(LocalVariableBinding local) {
+ return this.initsWhenTrue.isPotentiallyNonNull(local)
+ || this.initsWhenFalse.isPotentiallyNonNull(local);
}
-public boolean isProtectedNonNull(VariableBinding var) {
- return this.initsWhenTrue.isProtectedNonNull(var)
- && this.initsWhenFalse.isProtectedNonNull(var);
+public boolean isPotentiallyNull(LocalVariableBinding local) {
+ return this.initsWhenTrue.isPotentiallyNull(local)
+ || this.initsWhenFalse.isPotentiallyNull(local);
}
-public boolean isProtectedNull(VariableBinding var) {
- return this.initsWhenTrue.isProtectedNull(var)
- && this.initsWhenFalse.isProtectedNull(var);
+public boolean isPotentiallyUnknown(LocalVariableBinding local) {
+ return this.initsWhenTrue.isPotentiallyUnknown(local)
+ || this.initsWhenFalse.isPotentiallyUnknown(local);
}
-public void markAsComparedEqualToNonNull(VariableBinding var) {
- this.initsWhenTrue.markAsComparedEqualToNonNull(var);
- this.initsWhenFalse.markAsComparedEqualToNonNull(var);
+public boolean isProtectedNonNull(LocalVariableBinding local) {
+ return this.initsWhenTrue.isProtectedNonNull(local)
+ && this.initsWhenFalse.isProtectedNonNull(local);
}
-public void markAsComparedEqualToNull(VariableBinding var) {
- this.initsWhenTrue.markAsComparedEqualToNull(var);
- this.initsWhenFalse.markAsComparedEqualToNull(var);
+public boolean isProtectedNull(LocalVariableBinding local) {
+ return this.initsWhenTrue.isProtectedNull(local)
+ && this.initsWhenFalse.isProtectedNull(local);
}
-public void markAsDefinitelyAssigned(VariableBinding var) {
- this.initsWhenTrue.markAsDefinitelyAssigned(var);
- this.initsWhenFalse.markAsDefinitelyAssigned(var);
+public void markAsComparedEqualToNonNull(LocalVariableBinding local) {
+ this.initsWhenTrue.markAsComparedEqualToNonNull(local);
+ this.initsWhenFalse.markAsComparedEqualToNonNull(local);
}
-public void markAsDefinitelyNonNull(VariableBinding var) {
- this.initsWhenTrue.markAsDefinitelyNonNull(var);
- this.initsWhenFalse.markAsDefinitelyNonNull(var);
+public void markAsComparedEqualToNull(LocalVariableBinding local) {
+ this.initsWhenTrue.markAsComparedEqualToNull(local);
+ this.initsWhenFalse.markAsComparedEqualToNull(local);
}
-public void markAsDefinitelyNull(VariableBinding var) {
- this.initsWhenTrue.markAsDefinitelyNull(var);
- this.initsWhenFalse.markAsDefinitelyNull(var);
+public void markAsDefinitelyAssigned(FieldBinding field) {
+ this.initsWhenTrue.markAsDefinitelyAssigned(field);
+ this.initsWhenFalse.markAsDefinitelyAssigned(field);
}
-public void resetNullInfo(VariableBinding var) {
- this.initsWhenTrue.resetNullInfo(var);
- this.initsWhenFalse.resetNullInfo(var);
+public void markAsDefinitelyAssigned(LocalVariableBinding local) {
+ this.initsWhenTrue.markAsDefinitelyAssigned(local);
+ this.initsWhenFalse.markAsDefinitelyAssigned(local);
}
-public void resetNullInfoForFields() {
- this.initsWhenTrue.resetNullInfoForFields();
- this.initsWhenFalse.resetNullInfoForFields();
+public void markAsDefinitelyNonNull(LocalVariableBinding local) {
+ this.initsWhenTrue.markAsDefinitelyNonNull(local);
+ this.initsWhenFalse.markAsDefinitelyNonNull(local);
}
-public void updateConstantFieldsMask(FieldBinding field) {
- this.initsWhenTrue.updateConstantFieldsMask(field);
- this.initsWhenFalse.updateConstantFieldsMask(field);
+public void markAsDefinitelyNull(LocalVariableBinding local) {
+ this.initsWhenTrue.markAsDefinitelyNull(local);
+ this.initsWhenFalse.markAsDefinitelyNull(local);
}
-public void addConstantFieldsMask(UnconditionalFlowInfo other) {
- this.initsWhenTrue.addConstantFieldsMask(other);
- this.initsWhenFalse.addConstantFieldsMask(other);
+public void resetNullInfo(LocalVariableBinding local) {
+ this.initsWhenTrue.resetNullInfo(local);
+ this.initsWhenFalse.resetNullInfo(local);
}
-public void markPotentiallyNullBit(VariableBinding var) {
- this.initsWhenTrue.markPotentiallyNullBit(var);
- this.initsWhenFalse.markPotentiallyNullBit(var);
+public void markPotentiallyNullBit(LocalVariableBinding local) {
+ this.initsWhenTrue.markPotentiallyNullBit(local);
+ this.initsWhenFalse.markPotentiallyNullBit(local);
}
-public void markPotentiallyNonNullBit(VariableBinding var) {
- this.initsWhenTrue.markPotentiallyNonNullBit(var);
- this.initsWhenFalse.markPotentiallyNonNullBit(var);
+public void markPotentiallyNonNullBit(LocalVariableBinding local) {
+ this.initsWhenTrue.markPotentiallyNonNullBit(local);
+ this.initsWhenFalse.markPotentiallyNonNullBit(local);
}
-public void markAsDefinitelyUnknown(VariableBinding var) {
- this.initsWhenTrue.markAsDefinitelyUnknown(var);
- this.initsWhenFalse.markAsDefinitelyUnknown(var);
+public void markAsDefinitelyUnknown(LocalVariableBinding local) {
+ this.initsWhenTrue.markAsDefinitelyUnknown(local);
+ this.initsWhenFalse.markAsDefinitelyUnknown(local);
}
-public void markPotentiallyUnknownBit(VariableBinding var) {
- this.initsWhenTrue.markPotentiallyUnknownBit(var);
- this.initsWhenFalse.markPotentiallyUnknownBit(var);
+public void markPotentiallyUnknownBit(LocalVariableBinding local) {
+ this.initsWhenTrue.markPotentiallyUnknownBit(local);
+ this.initsWhenFalse.markPotentiallyUnknownBit(local);
}
public FlowInfo setReachMode(int reachMode) {
@@ -243,18 +243,18 @@
mergedWith(this.initsWhenFalse.unconditionalInits());
}
-public void markedAsNullOrNonNullInAssertExpression(VariableBinding var) {
- this.initsWhenTrue.markedAsNullOrNonNullInAssertExpression(var);
- this.initsWhenFalse.markedAsNullOrNonNullInAssertExpression(var);
+public void markedAsNullOrNonNullInAssertExpression(LocalVariableBinding local) {
+ this.initsWhenTrue.markedAsNullOrNonNullInAssertExpression(local);
+ this.initsWhenFalse.markedAsNullOrNonNullInAssertExpression(local);
}
-public boolean isMarkedAsNullOrNonNullInAssertExpression(VariableBinding var) {
- return (this.initsWhenTrue.isMarkedAsNullOrNonNullInAssertExpression(var)
- || this.initsWhenFalse.isMarkedAsNullOrNonNullInAssertExpression(var));
+public boolean isMarkedAsNullOrNonNullInAssertExpression(LocalVariableBinding local) {
+ return (this.initsWhenTrue.isMarkedAsNullOrNonNullInAssertExpression(local)
+ || this.initsWhenFalse.isMarkedAsNullOrNonNullInAssertExpression(local));
}
-public void resetAssignmentInfo(LocalVariableBinding var) {
- this.initsWhenTrue.resetAssignmentInfo(var);
- this.initsWhenFalse.resetAssignmentInfo(var);
+public void resetAssignmentInfo(LocalVariableBinding local) {
+ this.initsWhenTrue.resetAssignmentInfo(local);
+ this.initsWhenFalse.resetAssignmentInfo(local);
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java
index ea64a1a..76784ee 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java
@@ -10,6 +10,7 @@
* Stephan Herrmann - Contributions for
* bug 186342 - [compiler][null] Using annotations for null checking
* bug 365519 - editorial cleanup after bug 186342 and bug 365387
+ * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.flow;
@@ -34,8 +35,10 @@
VariableBinding[] finalVariables;
int assignCount;
- VariableBinding[] nullVariables;
- Expression[] nullReferences;
+ // the following three arrays are in sync regarding their indices:
+ LocalVariableBinding[] nullLocals;
+ ASTNode[] nullReferences; // Expressions for null checking, Statements for resource analysis
+ // cast to Expression is safe if corresponding nullCheckType != EXIT_RESOURCE
int[] nullCheckTypes;
int nullCount;
// see also the related field FlowContext#expectedTypes
@@ -59,13 +62,13 @@
boolean complained = false; // remember if have complained on this final assignment
if (variable instanceof FieldBinding) {
// final field
- if (flowInfo.isPotentiallyAssigned(variable)) {
+ if (flowInfo.isPotentiallyAssigned((FieldBinding)variable)) {
complained = true;
scope.problemReporter().duplicateInitializationOfBlankFinalField((FieldBinding)variable, this.finalAssignments[i]);
}
} else {
// final local variable
- if (flowInfo.isPotentiallyAssigned(variable)) {
+ if (flowInfo.isPotentiallyAssigned((LocalVariableBinding)variable)) {
complained = true;
scope.problemReporter().duplicateInitializationOfFinalLocal(
(LocalVariableBinding) variable,
@@ -89,29 +92,30 @@
if ((this.tagBits & FlowContext.DEFER_NULL_DIAGNOSTIC) != 0) { // within an enclosing loop, be conservative
for (int i = 0; i < this.nullCount; i++) {
if (this.nullCheckTypes[i] == ASSIGN_TO_NONNULL)
- this.parent.recordNullityMismatch(scope, this.nullReferences[i],
- flowInfo.nullStatus(this.nullVariables[i]), this.expectedTypes[i]);
+ this.parent.recordNullityMismatch(scope, (Expression)this.nullReferences[i],
+ flowInfo.nullStatus(this.nullLocals[i]), this.expectedTypes[i]);
else
- this.parent.recordUsingNullReference(scope, this.nullVariables[i],
+ this.parent.recordUsingNullReference(scope, this.nullLocals[i],
this.nullReferences[i], this.nullCheckTypes[i], flowInfo);
+
}
}
else { // no enclosing loop, be as precise as possible right now
for (int i = 0; i < this.nullCount; i++) {
- Expression expression = this.nullReferences[i];
+ ASTNode location = this.nullReferences[i];
// final local variable
- VariableBinding var = this.nullVariables[i];
+ LocalVariableBinding local = this.nullLocals[i];
switch (this.nullCheckTypes[i]) {
case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL:
case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL:
- if (flowInfo.isDefinitelyNonNull(var)) {
+ if (flowInfo.isDefinitelyNonNull(local)) {
if (this.nullCheckTypes[i] == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) {
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableRedundantCheckOnNonNull(var, expression);
+ scope.problemReporter().localVariableRedundantCheckOnNonNull(local, location);
}
} else {
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableNonNullComparedToNull(var, expression);
+ scope.problemReporter().localVariableNonNullComparedToNull(local, location);
}
}
continue;
@@ -121,46 +125,47 @@
case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL:
case CAN_ONLY_NULL | IN_ASSIGNMENT:
case CAN_ONLY_NULL | IN_INSTANCEOF:
- if (flowInfo.isDefinitelyNull(var)) {
+ Expression expression = (Expression) location;
+ if (flowInfo.isDefinitelyNull(local)) {
switch(this.nullCheckTypes[i] & CONTEXT_MASK) {
case FlowContext.IN_COMPARISON_NULL:
if (((this.nullCheckTypes[i] & CHECK_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
- scope.problemReporter().variableNullReference(var, expression);
+ scope.problemReporter().localVariableNullReference(local, expression);
continue;
}
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableRedundantCheckOnNull(var, expression);
+ scope.problemReporter().localVariableRedundantCheckOnNull(local, expression);
}
continue;
case FlowContext.IN_COMPARISON_NON_NULL:
if (((this.nullCheckTypes[i] & CHECK_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
- scope.problemReporter().variableNullReference(var, expression);
+ scope.problemReporter().localVariableNullReference(local, expression);
continue;
}
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableNullComparedToNonNull(var, expression);
+ scope.problemReporter().localVariableNullComparedToNonNull(local, expression);
}
continue;
case FlowContext.IN_ASSIGNMENT:
- scope.problemReporter().variableRedundantNullAssignment(var, expression);
+ scope.problemReporter().localVariableRedundantNullAssignment(local, expression);
continue;
case FlowContext.IN_INSTANCEOF:
- scope.problemReporter().variableNullInstanceof(var, expression);
+ scope.problemReporter().localVariableNullInstanceof(local, expression);
continue;
}
- } else if (flowInfo.isPotentiallyNull(var)) {
+ } else if (flowInfo.isPotentiallyNull(local)) {
switch(this.nullCheckTypes[i] & CONTEXT_MASK) {
case FlowContext.IN_COMPARISON_NULL:
this.nullReferences[i] = null;
if (((this.nullCheckTypes[i] & CHECK_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
- scope.problemReporter().variablePotentialNullReference(var, expression);
+ scope.problemReporter().localVariablePotentialNullReference(local, expression);
continue;
}
break;
case FlowContext.IN_COMPARISON_NON_NULL:
this.nullReferences[i] = null;
if (((this.nullCheckTypes[i] & CHECK_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
- scope.problemReporter().variablePotentialNullReference(var, expression);
+ scope.problemReporter().localVariablePotentialNullReference(local, expression);
continue;
}
break;
@@ -168,19 +173,19 @@
}
break;
case MAY_NULL:
- if (flowInfo.isDefinitelyNull(var)) {
- scope.problemReporter().variableNullReference(var, expression);
+ if (flowInfo.isDefinitelyNull(local)) {
+ scope.problemReporter().localVariableNullReference(local, location);
continue;
}
- if (flowInfo.isPotentiallyNull(var)) {
- scope.problemReporter().variablePotentialNullReference(var, expression);
+ if (flowInfo.isPotentiallyNull(local)) {
+ scope.problemReporter().localVariablePotentialNullReference(local, location);
}
break;
case ASSIGN_TO_NONNULL:
- int nullStatus = flowInfo.nullStatus(var);
+ int nullStatus = flowInfo.nullStatus(local);
if (nullStatus != FlowInfo.NON_NULL) {
char[][] annotationName = scope.environment().getNonNullAnnotationName();
- scope.problemReporter().nullityMismatch(expression, this.expectedTypes[i], nullStatus, annotationName);
+ scope.problemReporter().nullityMismatch((Expression) location, this.expectedTypes[i], nullStatus, annotationName);
}
break;
default:
@@ -228,9 +233,9 @@
return true;
}
- public void recordUsingNullReference(Scope scope, VariableBinding var,
- Expression reference, int checkType, FlowInfo flowInfo) {
- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0 && !flowInfo.isDefinitelyUnknown(var)) {
+ public void recordUsingNullReference(Scope scope, LocalVariableBinding local,
+ ASTNode location, int checkType, FlowInfo flowInfo) {
+ if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0 && !flowInfo.isDefinitelyUnknown(local)) {
if ((this.tagBits & FlowContext.DEFER_NULL_DIAGNOSTIC) != 0) { // within an enclosing loop, be conservative
switch (checkType) {
case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL:
@@ -239,68 +244,69 @@
case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL:
case CAN_ONLY_NULL | IN_ASSIGNMENT:
case CAN_ONLY_NULL | IN_INSTANCEOF:
- if (flowInfo.cannotBeNull(var)) {
+ Expression reference = (Expression) location;
+ if (flowInfo.cannotBeNull(local)) {
if (checkType == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) {
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableRedundantCheckOnNonNull(var, reference);
+ scope.problemReporter().localVariableRedundantCheckOnNonNull(local, reference);
}
- if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(var)) {
+ if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
} else if (checkType == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL)) {
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableNonNullComparedToNull(var, reference);
+ scope.problemReporter().localVariableNonNullComparedToNull(local, reference);
}
- if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(var)) {
+ if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
}
return;
}
- if (flowInfo.canOnlyBeNull(var)) {
+ if (flowInfo.canOnlyBeNull(local)) {
switch(checkType & CONTEXT_MASK) {
case FlowContext.IN_COMPARISON_NULL:
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
- scope.problemReporter().variableNullReference(var, reference);
+ scope.problemReporter().localVariableNullReference(local, reference);
return;
}
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableRedundantCheckOnNull(var, reference);
+ scope.problemReporter().localVariableRedundantCheckOnNull(local, reference);
}
- if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(var)) {
+ if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
return;
case FlowContext.IN_COMPARISON_NON_NULL:
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
- scope.problemReporter().variableNullReference(var, reference);
+ scope.problemReporter().localVariableNullReference(local, reference);
return;
}
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableNullComparedToNonNull(var, reference);
+ scope.problemReporter().localVariableNullComparedToNonNull(local, reference);
}
- if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(var)) {
+ if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
return;
case FlowContext.IN_ASSIGNMENT:
- scope.problemReporter().variableRedundantNullAssignment(var, reference);
+ scope.problemReporter().localVariableRedundantNullAssignment(local, reference);
return;
case FlowContext.IN_INSTANCEOF:
- scope.problemReporter().variableNullInstanceof(var, reference);
+ scope.problemReporter().localVariableNullInstanceof(local, reference);
return;
}
- } else if (flowInfo.isPotentiallyNull(var)) {
+ } else if (flowInfo.isPotentiallyNull(local)) {
switch(checkType & CONTEXT_MASK) {
case FlowContext.IN_COMPARISON_NULL:
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
- scope.problemReporter().variablePotentialNullReference(var, reference);
+ scope.problemReporter().localVariablePotentialNullReference(local, reference);
return;
}
break;
case FlowContext.IN_COMPARISON_NON_NULL:
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
- scope.problemReporter().variablePotentialNullReference(var, reference);
+ scope.problemReporter().localVariablePotentialNullReference(local, reference);
return;
}
break;
@@ -308,11 +314,11 @@
}
break;
case MAY_NULL :
- if (flowInfo.cannotBeNull(var)) {
+ if (flowInfo.cannotBeNull(local)) {
return;
}
- if (flowInfo.canOnlyBeNull(var)) {
- scope.problemReporter().variableNullReference(var, reference);
+ if (flowInfo.canOnlyBeNull(local)) {
+ scope.problemReporter().localVariableNullReference(local, location);
return;
}
break;
@@ -324,19 +330,19 @@
switch (checkType) {
case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL:
case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL:
- if (flowInfo.isDefinitelyNonNull(var)) {
+ if (flowInfo.isDefinitelyNonNull(local)) {
if (checkType == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) {
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableRedundantCheckOnNonNull(var, reference);
+ scope.problemReporter().localVariableRedundantCheckOnNonNull(local, location);
}
- if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(var)) {
+ if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
} else {
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableNonNullComparedToNull(var, reference);
+ scope.problemReporter().localVariableNonNullComparedToNull(local, location);
}
- if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(var)) {
+ if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
}
@@ -347,50 +353,51 @@
case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL:
case CAN_ONLY_NULL | IN_ASSIGNMENT:
case CAN_ONLY_NULL | IN_INSTANCEOF:
- if (flowInfo.isDefinitelyNull(var)) {
+ Expression reference = (Expression) location;
+ if (flowInfo.isDefinitelyNull(local)) {
switch(checkType & CONTEXT_MASK) {
case FlowContext.IN_COMPARISON_NULL:
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
- scope.problemReporter().variableNullReference(var, reference);
+ scope.problemReporter().localVariableNullReference(local, reference);
return;
}
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableRedundantCheckOnNull(var, reference);
+ scope.problemReporter().localVariableRedundantCheckOnNull(local, reference);
}
- if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(var)) {
+ if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
return;
case FlowContext.IN_COMPARISON_NON_NULL:
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
- scope.problemReporter().variableNullReference(var, reference);
+ scope.problemReporter().localVariableNullReference(local, reference);
return;
}
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableNullComparedToNonNull(var, reference);
+ scope.problemReporter().localVariableNullComparedToNonNull(local, reference);
}
- if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(var)) {
+ if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
return;
case FlowContext.IN_ASSIGNMENT:
- scope.problemReporter().variableRedundantNullAssignment(var, reference);
+ scope.problemReporter().localVariableRedundantNullAssignment(local, reference);
return;
case FlowContext.IN_INSTANCEOF:
- scope.problemReporter().variableNullInstanceof(var, reference);
+ scope.problemReporter().localVariableNullInstanceof(local, reference);
return;
}
- } else if (flowInfo.isPotentiallyNull(var)) {
+ } else if (flowInfo.isPotentiallyNull(local)) {
switch(checkType & CONTEXT_MASK) {
case FlowContext.IN_COMPARISON_NULL:
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
- scope.problemReporter().variablePotentialNullReference(var, reference);
+ scope.problemReporter().localVariablePotentialNullReference(local, reference);
return;
}
break;
case FlowContext.IN_COMPARISON_NON_NULL:
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
- scope.problemReporter().variablePotentialNullReference(var, reference);
+ scope.problemReporter().localVariablePotentialNullReference(local, reference);
return;
}
break;
@@ -398,15 +405,15 @@
}
break;
case MAY_NULL :
- if (flowInfo.isDefinitelyNull(var)) {
- scope.problemReporter().variableNullReference(var, reference);
+ if (flowInfo.isDefinitelyNull(local)) {
+ scope.problemReporter().localVariableNullReference(local, location);
return;
}
- if (flowInfo.isPotentiallyNull(var)) {
- scope.problemReporter().variablePotentialNullReference(var, reference);
+ if (flowInfo.isPotentiallyNull(local)) {
+ scope.problemReporter().localVariablePotentialNullReference(local, location);
return;
}
- if (flowInfo.isDefinitelyNonNull(var)) {
+ if (flowInfo.isDefinitelyNonNull(local)) {
return; // shortcut: cannot be null
}
break;
@@ -419,7 +426,7 @@
if(((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) || checkType == MAY_NULL
|| (checkType & CONTEXT_MASK) == FlowContext.IN_ASSIGNMENT
|| (checkType & CONTEXT_MASK) == FlowContext.IN_INSTANCEOF) {
- recordNullReference(var, reference, checkType);
+ recordNullReference(local, location, checkType);
}
// prepare to re-check with try/catch flow info
}
@@ -435,17 +442,17 @@
}
}
-protected void recordNullReference(VariableBinding var,
- Expression expression, int status) {
+protected void recordNullReference(LocalVariableBinding local,
+ ASTNode expression, int status) {
if (this.nullCount == 0) {
- this.nullVariables = new VariableBinding[5];
+ this.nullLocals = new LocalVariableBinding[5];
this.nullReferences = new Expression[5];
this.nullCheckTypes = new int[5];
}
- else if (this.nullCount == this.nullVariables.length) {
+ else if (this.nullCount == this.nullLocals.length) {
int newLength = this.nullCount * 2;
- System.arraycopy(this.nullVariables, 0,
- this.nullVariables = new VariableBinding[newLength], 0,
+ System.arraycopy(this.nullLocals, 0,
+ this.nullLocals = new LocalVariableBinding[newLength], 0,
this.nullCount);
System.arraycopy(this.nullReferences, 0,
this.nullReferences = new Expression[newLength], 0,
@@ -454,7 +461,7 @@
this.nullCheckTypes = new int[newLength], 0,
this.nullCount);
}
- this.nullVariables[this.nullCount] = var;
+ this.nullLocals[this.nullCount] = local;
this.nullReferences[this.nullCount] = expression;
this.nullCheckTypes[this.nullCount++] = status;
}
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 33fd6c5..489bb1d 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 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
@@ -10,6 +10,7 @@
* Stephan Herrmann - Contributions for
* bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis
* bug 186342 - [compiler][null] Using annotations for null checking
+ * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.flow;
@@ -19,6 +20,7 @@
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.FakedTrackingVariable;
import org.eclipse.jdt.internal.compiler.ast.LabeledStatement;
import org.eclipse.jdt.internal.compiler.ast.Reference;
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
@@ -74,6 +76,8 @@
public static final int MAY_NULL = 0x0003;
//check binding a value to a @NonNull variable
public final static int ASSIGN_TO_NONNULL = 0x0080;
+//check against unclosed resource at early exit:
+public static final int EXIT_RESOURCE = 0x0800;
// check against null, with potential values -- NPE guard
public static final int CHECK_MASK = 0x00FF;
public static final int IN_COMPARISON_NULL = 0x0100;
@@ -556,6 +560,18 @@
// default implementation: do nothing
}
+/**
+ * Record that we found an early exit from a method while a resource is in scope.
+ * @param scope enclosing scope
+ * @param flowInfo flowInfo at the point of the early exit
+ * @param trackingVar representation of the resource
+ * @param reference the return or throw statement marking the early exit
+ * @return true if the situation has been handled by this flow context.
+ */
+public boolean recordExitAgainstResource(BlockScope scope, FlowInfo flowInfo, FakedTrackingVariable trackingVar, ASTNode reference) {
+ return false; // not handled
+}
+
protected void recordExpectedType(TypeBinding expectedType, int nullCount) {
if (nullCount == 0) {
this.expectedTypes = new TypeBinding[5];
@@ -580,7 +596,9 @@
* Record a null reference for use by deferred checks. Only looping or
* finally contexts really record that information.
* @param local the local variable involved in the check
- * @param expression the expression within which local lays
+ * @param location the location triggering the analysis, for normal null dereference
+ * this is an expression resolving to 'local', for resource leaks it is an
+ * early exit statement.
* @param status the status against which the check must be performed; one of
* {@link #CAN_ONLY_NULL CAN_ONLY_NULL}, {@link #CAN_ONLY_NULL_NON_NULL
* CAN_ONLY_NULL_NON_NULL}, {@link #MAY_NULL MAY_NULL},
@@ -588,8 +606,8 @@
* combined with a context indicator (one of {@link #IN_COMPARISON_NULL},
* {@link #IN_COMPARISON_NON_NULL}, {@link #IN_ASSIGNMENT} or {@link #IN_INSTANCEOF})
*/
-protected void recordNullReference(VariableBinding local,
- Expression expression, int status) {
+protected void recordNullReference(LocalVariableBinding local,
+ ASTNode location, int status) {
// default implementation: do nothing
}
@@ -620,7 +638,9 @@
* context).
* @param scope the scope into which the check is performed
* @param local the local variable involved in the check
- * @param reference the expression within which local lies
+ * @param location the location triggering the analysis, for normal null dereference
+ * this is an expression resolving to 'local', for resource leaks it is an
+ * early exit statement.
* @param checkType the status against which the check must be performed; one
* of {@link #CAN_ONLY_NULL CAN_ONLY_NULL}, {@link #CAN_ONLY_NULL_NON_NULL
* CAN_ONLY_NULL_NON_NULL}, {@link #MAY_NULL MAY_NULL}, potentially
@@ -631,8 +651,8 @@
* be known at the time of calling this method (they are influenced by
* code that follows the current point)
*/
-public void recordUsingNullReference(Scope scope, VariableBinding local,
- Expression reference, int checkType, FlowInfo flowInfo) {
+public void recordUsingNullReference(Scope scope, LocalVariableBinding local,
+ ASTNode location, int checkType, FlowInfo flowInfo) {
if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0 ||
flowInfo.isDefinitelyUnknown(local)) {
return;
@@ -643,14 +663,14 @@
if (flowInfo.isDefinitelyNonNull(local)) {
if (checkType == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) {
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableRedundantCheckOnNonNull(local, reference);
+ scope.problemReporter().localVariableRedundantCheckOnNonNull(local, location);
}
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
} else {
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableNonNullComparedToNull(local, reference);
+ scope.problemReporter().localVariableNonNullComparedToNull(local, location);
}
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
@@ -666,15 +686,16 @@
case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL:
case CAN_ONLY_NULL | IN_ASSIGNMENT:
case CAN_ONLY_NULL | IN_INSTANCEOF:
+ Expression reference = (Expression)location;
if (flowInfo.isDefinitelyNull(local)) {
switch(checkType & CONTEXT_MASK) {
case FlowContext.IN_COMPARISON_NULL:
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
- scope.problemReporter().variableNullReference(local, reference);
+ scope.problemReporter().localVariableNullReference(local, reference);
return;
}
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableRedundantCheckOnNull(local, reference);
+ scope.problemReporter().localVariableRedundantCheckOnNull(local, reference);
}
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
@@ -682,34 +703,34 @@
return;
case FlowContext.IN_COMPARISON_NON_NULL:
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
- scope.problemReporter().variableNullReference(local, reference);
+ scope.problemReporter().localVariableNullReference(local, reference);
return;
}
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableNullComparedToNonNull(local, reference);
+ scope.problemReporter().localVariableNullComparedToNonNull(local, reference);
}
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
return;
case FlowContext.IN_ASSIGNMENT:
- scope.problemReporter().variableRedundantNullAssignment(local, reference);
+ scope.problemReporter().localVariableRedundantNullAssignment(local, reference);
return;
case FlowContext.IN_INSTANCEOF:
- scope.problemReporter().variableNullInstanceof(local, reference);
+ scope.problemReporter().localVariableNullInstanceof(local, reference);
return;
}
} else if (flowInfo.isPotentiallyNull(local)) {
switch(checkType & CONTEXT_MASK) {
case FlowContext.IN_COMPARISON_NULL:
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
- scope.problemReporter().variablePotentialNullReference(local, reference);
+ scope.problemReporter().localVariablePotentialNullReference(local, reference);
return;
}
break;
case FlowContext.IN_COMPARISON_NON_NULL:
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
- scope.problemReporter().variablePotentialNullReference(local, reference);
+ scope.problemReporter().localVariablePotentialNullReference(local, reference);
return;
}
break;
@@ -720,11 +741,11 @@
break;
case MAY_NULL :
if (flowInfo.isDefinitelyNull(local)) {
- scope.problemReporter().variableNullReference(local, reference);
+ scope.problemReporter().localVariableNullReference(local, location);
return;
}
if (flowInfo.isPotentiallyNull(local)) {
- scope.problemReporter().variablePotentialNullReference(local, reference);
+ scope.problemReporter().localVariablePotentialNullReference(local, location);
return;
}
break;
@@ -732,7 +753,7 @@
// never happens
}
if (this.parent != null) {
- this.parent.recordUsingNullReference(scope, local, reference, checkType,
+ this.parent.recordUsingNullReference(scope, local, location, checkType,
flowInfo);
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java
index 1328b34..177ceaf 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 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
@@ -20,7 +20,6 @@
import org.eclipse.jdt.internal.compiler.ast.IfStatement;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
-import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.BaseCallTrackingVariable;
/**
@@ -65,7 +64,7 @@
DEAD_END = new UnconditionalFlowInfo();
DEAD_END.tagBits = UNREACHABLE;
}
-
+
/**
* Add other inits to this flow info, then return this. The operation semantics
* are to match as closely as possible the application to this flow info of all
@@ -107,42 +106,39 @@
}
/**
- * Check whether a given field or local variable is known to be unable to gain a definite
+ * Check whether a given local variable is known to be unable to gain a definite
* non null or definite null status by the use of an enclosing flow info. The
* semantics are that if the current flow info marks the variable as potentially
* unknown or else as being both potentially null and potentially non null,
* then it won't ever be promoted as definitely null or definitely non null. (It
* could still get promoted to definite unknown).
- * @param binding the field or local variable to check
- * @return true iff this flow info prevents field or local from being promoted to
+ * @param local the variable to check
+ * @return true iff this flow info prevents local from being promoted to
* definite non null or definite null against an enclosing flow info
*/
-public boolean cannotBeDefinitelyNullOrNonNull(VariableBinding binding) {
- return isPotentiallyUnknown(binding) ||
- isPotentiallyNonNull(binding) && isPotentiallyNull(binding);
+public boolean cannotBeDefinitelyNullOrNonNull(LocalVariableBinding local) {
+ return isPotentiallyUnknown(local) ||
+ isPotentiallyNonNull(local) && isPotentiallyNull(local);
}
/**
- * Check whether a given field or local variable is known to be non null, either because
+ * Check whether a given local variable is known to be non null, either because
* it is definitely non null, or because is has been tested against non null.
- * @param binding the field or local to check
- * @return true iff field or local cannot be null for this flow info
+ * @param local the variable to ckeck
+ * @return true iff local cannot be null for this flow info
*/
-public boolean cannotBeNull(VariableBinding binding) {
- return isDefinitelyNonNull(binding) || isProtectedNonNull(binding);
+public boolean cannotBeNull(LocalVariableBinding local) {
+ return isDefinitelyNonNull(local) || isProtectedNonNull(local);
}
/**
- * Check whether a given field or local variable is known to be null, either because it
- * is definitely null, or because is has been tested against null. Note that for fields,
- * this method only takes compile time analysis into account and there's no
- * guarantee of the field being definitely null during runtime
- * since it can be modified in some other thread.
- * @param binding the field or local to check
- * @return true iff field or local can only be null for this flow info
+ * Check whether a given local variable is known to be null, either because it
+ * is definitely null, or because is has been tested against null.
+ * @param local the variable to ckeck
+ * @return true iff local can only be null for this flow info
*/
-public boolean canOnlyBeNull(VariableBinding binding) {
- return isDefinitelyNull(binding) || isProtectedNull(binding);
+public boolean canOnlyBeNull(LocalVariableBinding local) {
+ return isDefinitelyNull(local) || isProtectedNull(local);
}
/**
@@ -154,7 +150,6 @@
public static UnconditionalFlowInfo initial(int maxFieldCount) {
UnconditionalFlowInfo info = new UnconditionalFlowInfo();
info.maxFieldCount = maxFieldCount;
- info.constantFieldsMask = 0L;
return info;
}
@@ -181,202 +176,196 @@
abstract public FlowInfo initsWhenTrue();
/**
- * Check status of definite assignment for a local or field.
+ * Check status of definite assignment for a field.
*/
- abstract public boolean isDefinitelyAssigned(VariableBinding var);
-
-/**
- * Check status of definite non-null value for a given field or local variable. Note that for fields, this method only
- * takes compile time analysis into account and there's no guarantee of the field being definitely non null during runtime
- * since it can be modified in some other thread.
- * @param binding the field or local to check
- * @return true iff field or local is definitely non null for this flow info
- */
- public abstract boolean isDefinitelyNonNull(VariableBinding binding);
-
-/**
- * Check status of definite null value for a given field or local variable. Note that for fields, this method only
- * takes compile time analysis into account and there's no guarantee of the field being definitely null during runtime
- * since it can be modified in some other thread.
- * @param binding the field or local to check
- * @return true iff field or local is definitely null for this flow info
- */
-public abstract boolean isDefinitelyNull(VariableBinding binding);
-
-/**
- * Check status of definite unknown value for a given field or local variable.
- * @param binding the field or local to check
- * @return true iff field or local is definitely unknown for this flow info
- */
-public abstract boolean isDefinitelyUnknown(VariableBinding binding);
+ abstract public boolean isDefinitelyAssigned(FieldBinding field);
/**
- * Check status of potential assignment for a local variable or a field.
+ * Check status of definite assignment for a local.
+ */
+ public abstract boolean isDefinitelyAssigned(LocalVariableBinding local);
+
+/**
+ * Check status of definite non-null value for a given local variable.
+ * @param local the variable to ckeck
+ * @return true iff local is definitely non null for this flow info
+ */
+ public abstract boolean isDefinitelyNonNull(LocalVariableBinding local);
+
+/**
+ * Check status of definite null value for a given local variable.
+ * @param local the variable to ckeck
+ * @return true iff local is definitely null for this flow info
+ */
+public abstract boolean isDefinitelyNull(LocalVariableBinding local);
+
+/**
+ * Check status of definite unknown value for a given local variable.
+ * @param local the variable to ckeck
+ * @return true iff local is definitely unknown for this flow info
+ */
+public abstract boolean isDefinitelyUnknown(LocalVariableBinding local);
+
+ /**
+ * Check status of potential assignment for a field.
+ */
+ abstract public boolean isPotentiallyAssigned(FieldBinding field);
+
+ /**
+ * Check status of potential assignment for a local variable.
*/
- abstract public boolean isPotentiallyAssigned(VariableBinding var);
+ abstract public boolean isPotentiallyAssigned(LocalVariableBinding field);
/**
- * Check status of potential null assignment for a field or local. Return true if there
+ * Check status of potential null assignment for a local. Return true if there
* is a reasonable expectation that the variable be non null at this point.
- * @param binding VariableBinding - the binding for the checked field or local
- * @return true if there is a reasonable expectation that the field or local be non null at
+ * @param local LocalVariableBinding - the binding for the checked local
+ * @return true if there is a reasonable expectation that local be non null at
* this point
*/
-public abstract boolean isPotentiallyNonNull(VariableBinding binding);
+public abstract boolean isPotentiallyNonNull(LocalVariableBinding local);
/**
- * Check status of potential null assignment for a field or local. Return true if there
+ * Check status of potential null assignment for a local. Return true if there
* is a reasonable expectation that the variable be null at this point. This
* includes the protected null case, so as to augment diagnostics, but does not
* really check that someone deliberately assigned to null on any specific
* path
- * @param binding VariableBinding - the binding for the checked field or local
- * @return true if there is a reasonable expectation that the field or local be null at
+ * @param local LocalVariableBinding - the binding for the checked local
+ * @return true if there is a reasonable expectation that local be null at
* this point
*/
-public abstract boolean isPotentiallyNull(VariableBinding binding);
+public abstract boolean isPotentiallyNull(LocalVariableBinding local);
/**
- * Return true if the given field or local may have been assigned to an unknown value.
- * @param binding the field or local to check
- * @return true if the given field or local may have been assigned to an unknown value
+ * Return true if the given local may have been assigned to an unknown value.
+ * @param local the local to check
+ * @return true if the given local may have been assigned to an unknown value
*/
-public abstract boolean isPotentiallyUnknown(VariableBinding binding);
+public abstract boolean isPotentiallyUnknown(LocalVariableBinding local);
/**
- * Return true if the given field or local is protected by a test against a non null
+ * Return true if the given local is protected by a test against a non null
* value.
- * @param binding the field or local to check
- * @return true if the given field or local is protected by a test against a non null
+ * @param local the local to check
+ * @return true if the given local is protected by a test against a non null
*/
-public abstract boolean isProtectedNonNull(VariableBinding binding);
+public abstract boolean isProtectedNonNull(LocalVariableBinding local);
/**
- * Return true if the given field or local is protected by a test against null.
- * @param binding the field or local to check
- * @return true if the given field or local is protected by a test against null
+ * Return true if the given local is protected by a test against null.
+ * @param local the local to check
+ * @return true if the given local is protected by a test against null
*/
-public abstract boolean isProtectedNull(VariableBinding binding);
+public abstract boolean isProtectedNull(LocalVariableBinding local);
/**
- * Record that a field or local variable got checked to be non null.
- * @param binding the checked field or local variable
+ * Record that a local variable got checked to be non null.
+ * @param local the checked local variable
*/
-abstract public void markAsComparedEqualToNonNull(VariableBinding binding);
+abstract public void markAsComparedEqualToNonNull(LocalVariableBinding local);
/**
- * Record that a field or local variable got checked to be null.
- * @param binding the checked field or local variable
+ * Record that a local variable got checked to be null.
+ * @param local the checked local variable
*/
-abstract public void markAsComparedEqualToNull(VariableBinding binding);
+abstract public void markAsComparedEqualToNull(LocalVariableBinding local);
/**
- * Record a field or local got definitely assigned to a non-null value.
+ * Record a field got definitely assigned.
*/
- abstract public void markAsDefinitelyNonNull(VariableBinding binding);
+ abstract public void markAsDefinitelyAssigned(FieldBinding field);
/**
- * Record a field or local got definitely assigned to null.
+ * Record a local got definitely assigned to a non-null value.
*/
- abstract public void markAsDefinitelyNull(VariableBinding binding);
+ abstract public void markAsDefinitelyNonNull(LocalVariableBinding local);
/**
- * Reset all null-information about a given field or local.
+ * Record a local got definitely assigned to null.
*/
- abstract public void resetNullInfo(VariableBinding binding);
+ abstract public void markAsDefinitelyNull(LocalVariableBinding local);
/**
- * variant of {@link #resetNullInfo(VariableBinding)} for resetting null info for all fields
- * Note that each fields status after the reset will become def. unknown i.e. 1001
- * Also this method does not reset constant fields
+ * Reset all null-information about a given local.
*/
- abstract public void resetNullInfoForFields();
-
- /**
- * exclude a new field from being reset by {@link #resetNullInfoForFields()}
- */
- abstract public void updateConstantFieldsMask(FieldBinding field);
-
- /**
- * add the constant fields info from the other flow info
- */
- abstract public void addConstantFieldsMask(UnconditionalFlowInfo other);
-
- /**
- * Record a field or local may have got assigned to unknown (set the bit on existing info).
- */
- abstract public void markPotentiallyUnknownBit(VariableBinding binding);
+ abstract public void resetNullInfo(LocalVariableBinding local);
/**
- * Record a field or local may have got assigned to null (set the bit on existing info).
+ * Record a local may have got assigned to unknown (set the bit on existing info).
*/
- abstract public void markPotentiallyNullBit(VariableBinding binding);
+ abstract public void markPotentiallyUnknownBit(LocalVariableBinding local);
/**
- * Record a field or local may have got assigned to non-null (set the bit on existing info).
+ * Record a local may have got assigned to null (set the bit on existing info).
*/
- abstract public void markPotentiallyNonNullBit(VariableBinding binding);
+ abstract public void markPotentiallyNullBit(LocalVariableBinding local);
/**
- * Record a local or field got definitely assigned.
+ * Record a local may have got assigned to non-null (set the bit on existing info).
*/
- abstract public void markAsDefinitelyAssigned(VariableBinding var);
+ abstract public void markPotentiallyNonNullBit(LocalVariableBinding local);
+
+ /**
+ * Record a local got definitely assigned.
+ */
+ abstract public void markAsDefinitelyAssigned(LocalVariableBinding local);
/**
- * Record a field or local got definitely assigned to an unknown value.
+ * Record a local got definitely assigned to an unknown value.
*/
-abstract public void markAsDefinitelyUnknown(VariableBinding binding);
+abstract public void markAsDefinitelyUnknown(LocalVariableBinding local);
/**
- * Mark the null status of the given field or local according to the given status
- * @param binding
+ * Mark the null status of the given local according to the given status
+ * @param local
* @param nullStatus bitset of FLowInfo.UNKNOWN ... FlowInfo.POTENTIALLY_NON_NULL
*/
-public void markNullStatus(VariableBinding binding, int nullStatus) {
+public void markNullStatus(LocalVariableBinding local, int nullStatus) {
switch(nullStatus) {
// definite status?
case FlowInfo.UNKNOWN :
- markAsDefinitelyUnknown(binding);
+ markAsDefinitelyUnknown(local);
break;
case FlowInfo.NULL :
- markAsDefinitelyNull(binding);
+ markAsDefinitelyNull(local);
break;
case FlowInfo.NON_NULL :
- markAsDefinitelyNonNull(binding);
+ markAsDefinitelyNonNull(local);
break;
default:
// collect potential status:
- resetNullInfo(binding);
+ resetNullInfo(local);
if ((nullStatus & FlowInfo.POTENTIALLY_UNKNOWN) != 0)
- markPotentiallyUnknownBit(binding);
+ markPotentiallyUnknownBit(local);
if ((nullStatus & FlowInfo.POTENTIALLY_NULL) != 0)
- markPotentiallyNullBit(binding);
+ markPotentiallyNullBit(local);
if ((nullStatus & FlowInfo.POTENTIALLY_NON_NULL) != 0)
- markPotentiallyNonNullBit(binding);
+ markPotentiallyNonNullBit(local);
if ((nullStatus & (FlowInfo.POTENTIALLY_NULL|FlowInfo.POTENTIALLY_NON_NULL|FlowInfo.POTENTIALLY_UNKNOWN)) == 0)
- markAsDefinitelyUnknown(binding);
+ markAsDefinitelyUnknown(local);
}
}
/**
- * Answer the null status of the given field or local
- * @param binding
+ * Answer the null status of the given local
+ * @param local
* @return bitset of FlowInfo.UNKNOWN ... FlowInfo.POTENTIALLY_NON_NULL
*/
-public int nullStatus(VariableBinding binding) {
- if (isDefinitelyUnknown(binding))
+public int nullStatus(LocalVariableBinding local) {
+ if (isDefinitelyUnknown(local))
return FlowInfo.UNKNOWN;
- if (isDefinitelyNull(binding))
+ if (isDefinitelyNull(local))
return FlowInfo.NULL;
- if (isDefinitelyNonNull(binding))
+ if (isDefinitelyNonNull(local))
return FlowInfo.NON_NULL;
int status = 0;
- if (isPotentiallyUnknown(binding))
+ if (isPotentiallyUnknown(local))
status |= FlowInfo.POTENTIALLY_UNKNOWN;
- if (isPotentiallyNull(binding))
+ if (isPotentiallyNull(local))
status |= FlowInfo.POTENTIALLY_NULL;
- if (isPotentiallyNonNull(binding))
+ if (isPotentiallyNonNull(local))
status |= FlowInfo.POTENTIALLY_NON_NULL;
if (status > 0)
return status;
@@ -624,14 +613,14 @@
* where this variable is being checked against null
*/
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=303448
-abstract public void markedAsNullOrNonNullInAssertExpression(VariableBinding binding);
+abstract public void markedAsNullOrNonNullInAssertExpression(LocalVariableBinding local);
/**
* Returns true if the local variable being checked for was marked as null or not null
* inside an assert expression due to comparison against null.
*/
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=303448
-abstract public boolean isMarkedAsNullOrNonNullInAssertExpression(VariableBinding binding);
+abstract public boolean isMarkedAsNullOrNonNullInAssertExpression(LocalVariableBinding local);
/**
* Resets the definite and potential initialization info for the given local variable
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java
index cbf63e5..2257835 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java
@@ -11,6 +11,7 @@
* bug 336428 - [compiler][null] bogus warning "redundant null check" in condition of do {} while() loop
* bug 186342 - [compiler][null] Using annotations for null checking
* bug 365519 - editorial cleanup after bug 186342 and bug 365387
+ * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.flow;
@@ -18,6 +19,7 @@
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.FakedTrackingVariable;
import org.eclipse.jdt.internal.compiler.ast.Reference;
import org.eclipse.jdt.internal.compiler.codegen.BranchLabel;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
@@ -48,8 +50,10 @@
VariableBinding finalVariables[];
int assignCount = 0;
- VariableBinding[] nullVariables;
- Expression[] nullReferences;
+ // the following three arrays are in sync regarding their indices:
+ LocalVariableBinding[] nullLocals;
+ ASTNode[] nullReferences; // Expressions for null checking, Statements for resource analysis
+ // cast to Expression is safe if corresponding nullCheckType != EXIT_RESOURCE
int[] nullCheckTypes;
int nullCount;
// see also the related field FlowContext#expectedTypes
@@ -101,14 +105,14 @@
if (variable == null) continue;
boolean complained = false; // remember if have complained on this final assignment
if (variable instanceof FieldBinding) {
- if (flowInfo.isPotentiallyAssigned(variable)) {
+ if (flowInfo.isPotentiallyAssigned((FieldBinding)variable)) {
complained = true;
scope.problemReporter().duplicateInitializationOfBlankFinalField(
(FieldBinding) variable,
this.finalAssignments[i]);
}
} else {
- if (flowInfo.isPotentiallyAssigned(variable)) {
+ if (flowInfo.isPotentiallyAssigned((LocalVariableBinding)variable)) {
complained = true;
scope.problemReporter().duplicateInitializationOfFinalLocal(
(LocalVariableBinding) variable,
@@ -145,8 +149,8 @@
if ((this.tagBits & FlowContext.DEFER_NULL_DIAGNOSTIC) != 0) {
// check only immutable null checks on innermost looping context
for (int i = 0; i < this.nullCount; i++) {
- VariableBinding local = this.nullVariables[i];
- Expression expression = this.nullReferences[i];
+ LocalVariableBinding local = this.nullLocals[i];
+ ASTNode location = this.nullReferences[i];
// final local variable
switch (this.nullCheckTypes[i]) {
case CAN_ONLY_NON_NULL | IN_COMPARISON_NULL:
@@ -155,11 +159,11 @@
this.nullReferences[i] = null;
if (this.nullCheckTypes[i] == (CAN_ONLY_NON_NULL | IN_COMPARISON_NON_NULL)) {
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableRedundantCheckOnNonNull(local, expression);
+ scope.problemReporter().localVariableRedundantCheckOnNonNull(local, location);
}
} else {
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableNonNullComparedToNull(local, expression);
+ scope.problemReporter().localVariableNonNullComparedToNull(local, location);
}
}
continue;
@@ -171,11 +175,11 @@
this.nullReferences[i] = null;
if (this.nullCheckTypes[i] == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) {
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableRedundantCheckOnNonNull(local, expression);
+ scope.problemReporter().localVariableRedundantCheckOnNonNull(local, location);
}
} else {
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableNonNullComparedToNull(local, expression);
+ scope.problemReporter().localVariableNonNullComparedToNull(local, location);
}
}
continue;
@@ -184,11 +188,11 @@
this.nullReferences[i] = null;
if (this.nullCheckTypes[i] == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL)) {
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableRedundantCheckOnNull(local, expression);
+ scope.problemReporter().localVariableRedundantCheckOnNull(local, location);
}
} else {
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableNullComparedToNonNull(local, expression);
+ scope.problemReporter().localVariableNullComparedToNonNull(local, location);
}
}
continue;
@@ -198,32 +202,33 @@
case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL:
case CAN_ONLY_NULL | IN_ASSIGNMENT:
case CAN_ONLY_NULL | IN_INSTANCEOF:
+ Expression expression = (Expression)location;
if (flowInfo.isDefinitelyNull(local)) {
this.nullReferences[i] = null;
switch(this.nullCheckTypes[i] & CONTEXT_MASK) {
case FlowContext.IN_COMPARISON_NULL:
if (((this.nullCheckTypes[i] & CHECK_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
- scope.problemReporter().variableNullReference(local, expression);
+ scope.problemReporter().localVariableNullReference(local, expression);
continue;
}
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableRedundantCheckOnNull(local, expression);
+ scope.problemReporter().localVariableRedundantCheckOnNull(local, expression);
}
continue;
case FlowContext.IN_COMPARISON_NON_NULL:
if (((this.nullCheckTypes[i] & CHECK_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
- scope.problemReporter().variableNullReference(local, expression);
+ scope.problemReporter().localVariableNullReference(local, expression);
continue;
}
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableNullComparedToNonNull(local, expression);
+ scope.problemReporter().localVariableNullComparedToNonNull(local, expression);
}
continue;
case FlowContext.IN_ASSIGNMENT:
- scope.problemReporter().variableRedundantNullAssignment(local, expression);
+ scope.problemReporter().localVariableRedundantNullAssignment(local, expression);
continue;
case FlowContext.IN_INSTANCEOF:
- scope.problemReporter().variableNullInstanceof(local, expression);
+ scope.problemReporter().localVariableNullInstanceof(local, expression);
continue;
}
} else if (flowInfo.isPotentiallyNull(local)) {
@@ -231,14 +236,14 @@
case FlowContext.IN_COMPARISON_NULL:
this.nullReferences[i] = null;
if (((this.nullCheckTypes[i] & CHECK_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
- scope.problemReporter().variablePotentialNullReference(local, expression);
+ scope.problemReporter().localVariablePotentialNullReference(local, expression);
continue;
}
break;
case FlowContext.IN_COMPARISON_NON_NULL:
this.nullReferences[i] = null;
if (((this.nullCheckTypes[i] & CHECK_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
- scope.problemReporter().variablePotentialNullReference(local, expression);
+ scope.problemReporter().localVariablePotentialNullReference(local, expression);
continue;
}
break;
@@ -248,26 +253,41 @@
case MAY_NULL:
if (flowInfo.isDefinitelyNull(local)) {
this.nullReferences[i] = null;
- scope.problemReporter().variableNullReference(local, expression);
+ scope.problemReporter().localVariableNullReference(local, location);
continue;
}
break;
case ASSIGN_TO_NONNULL:
- this.parent.recordNullityMismatch(scope, expression, flowInfo.nullStatus(local), this.expectedTypes[i]);
+ this.parent.recordNullityMismatch(scope, (Expression)location, flowInfo.nullStatus(local), this.expectedTypes[i]);
+ break;
+ case EXIT_RESOURCE:
+ FakedTrackingVariable trackingVar = local.closeTracker;
+ if (trackingVar != null) {
+ if (trackingVar.hasDefinitelyNoResource(flowInfo)) {
+ continue; // no resource - no warning.
+ }
+ if (trackingVar.isClosedInFinallyOfEnclosing(scope)) {
+ continue;
+ }
+ if (this.parent.recordExitAgainstResource(scope, flowInfo, trackingVar, location)) {
+ this.nullReferences[i] = null;
+ continue;
+ }
+ }
break;
default:
// never happens
}
- this.parent.recordUsingNullReference(scope, local, expression,
+ this.parent.recordUsingNullReference(scope, local, location,
this.nullCheckTypes[i], flowInfo);
}
}
else {
// check inconsistent null checks on outermost looping context
for (int i = 0; i < this.nullCount; i++) {
- Expression expression = this.nullReferences[i];
+ ASTNode location = this.nullReferences[i];
// final local variable
- VariableBinding local = this.nullVariables[i];
+ LocalVariableBinding local = this.nullLocals[i];
switch (this.nullCheckTypes[i]) {
case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL:
case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL:
@@ -275,11 +295,11 @@
this.nullReferences[i] = null;
if (this.nullCheckTypes[i] == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) {
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableRedundantCheckOnNonNull(local, expression);
+ scope.problemReporter().localVariableRedundantCheckOnNonNull(local, location);
}
} else {
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableNonNullComparedToNull(local, expression);
+ scope.problemReporter().localVariableNonNullComparedToNull(local, location);
}
}
continue;
@@ -289,32 +309,33 @@
case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL:
case CAN_ONLY_NULL | IN_ASSIGNMENT:
case CAN_ONLY_NULL | IN_INSTANCEOF:
+ Expression expression = (Expression) location;
if (flowInfo.isDefinitelyNull(local)) {
this.nullReferences[i] = null;
switch(this.nullCheckTypes[i] & CONTEXT_MASK) {
case FlowContext.IN_COMPARISON_NULL:
if (((this.nullCheckTypes[i] & CHECK_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
- scope.problemReporter().variableNullReference(local, expression);
+ scope.problemReporter().localVariableNullReference(local, expression);
continue;
}
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableRedundantCheckOnNull(local, expression);
+ scope.problemReporter().localVariableRedundantCheckOnNull(local, expression);
}
continue;
case FlowContext.IN_COMPARISON_NON_NULL:
if (((this.nullCheckTypes[i] & CHECK_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
- scope.problemReporter().variableNullReference(local, expression);
+ scope.problemReporter().localVariableNullReference(local, expression);
continue;
}
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableNullComparedToNonNull(local, expression);
+ scope.problemReporter().localVariableNullComparedToNonNull(local, expression);
}
continue;
case FlowContext.IN_ASSIGNMENT:
- scope.problemReporter().variableRedundantNullAssignment(local, expression);
+ scope.problemReporter().localVariableRedundantNullAssignment(local, expression);
continue;
case FlowContext.IN_INSTANCEOF:
- scope.problemReporter().variableNullInstanceof(local, expression);
+ scope.problemReporter().localVariableNullInstanceof(local, expression);
continue;
}
} else if (flowInfo.isPotentiallyNull(local)) {
@@ -322,14 +343,14 @@
case FlowContext.IN_COMPARISON_NULL:
this.nullReferences[i] = null;
if (((this.nullCheckTypes[i] & CHECK_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
- scope.problemReporter().variablePotentialNullReference(local, expression);
+ scope.problemReporter().localVariablePotentialNullReference(local, expression);
continue;
}
break;
case FlowContext.IN_COMPARISON_NON_NULL:
this.nullReferences[i] = null;
if (((this.nullCheckTypes[i] & CHECK_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
- scope.problemReporter().variablePotentialNullReference(local, expression);
+ scope.problemReporter().localVariablePotentialNullReference(local, expression);
continue;
}
break;
@@ -339,12 +360,12 @@
case MAY_NULL:
if (flowInfo.isDefinitelyNull(local)) {
this.nullReferences[i] = null;
- scope.problemReporter().variableNullReference(local, expression);
+ scope.problemReporter().localVariableNullReference(local, location);
continue;
}
if (flowInfo.isPotentiallyNull(local)) {
this.nullReferences[i] = null;
- scope.problemReporter().variablePotentialNullReference(local, expression);
+ scope.problemReporter().localVariablePotentialNullReference(local, location);
continue;
}
break;
@@ -352,7 +373,26 @@
int nullStatus = flowInfo.nullStatus(local);
if (nullStatus != FlowInfo.NON_NULL) {
char[][] annotationName = scope.environment().getNonNullAnnotationName();
- scope.problemReporter().nullityMismatch(expression, this.expectedTypes[i], nullStatus, annotationName);
+ scope.problemReporter().nullityMismatch((Expression) location, this.expectedTypes[i], nullStatus, annotationName);
+ }
+ break;
+ case EXIT_RESOURCE:
+ nullStatus = flowInfo.nullStatus(local);
+ if (nullStatus != FlowInfo.NON_NULL) {
+ FakedTrackingVariable closeTracker = local.closeTracker;
+ if (closeTracker != null) {
+ if (closeTracker.hasDefinitelyNoResource(flowInfo)) {
+ continue; // no resource - no warning.
+ }
+ if (closeTracker.isClosedInFinallyOfEnclosing(scope)) {
+ continue;
+ }
+ nullStatus = closeTracker.findMostSpecificStatus(flowInfo, scope, null);
+ closeTracker.recordErrorLocation(this.nullReferences[i], nullStatus);
+ closeTracker.reportRecordedErrors(scope, nullStatus);
+ this.nullReferences[i] = null;
+ continue;
+ }
}
break;
default:
@@ -476,28 +516,46 @@
return true;
}
-protected void recordNullReference(VariableBinding local,
- Expression expression, int status) {
+protected void recordNullReference(LocalVariableBinding local,
+ ASTNode expression, int status) {
if (this.nullCount == 0) {
- this.nullVariables = new VariableBinding[5];
- this.nullReferences = new Expression[5];
+ this.nullLocals = new LocalVariableBinding[5];
+ this.nullReferences = new ASTNode[5];
this.nullCheckTypes = new int[5];
}
- else if (this.nullCount == this.nullVariables.length) {
- System.arraycopy(this.nullVariables, 0,
- this.nullVariables = new VariableBinding[this.nullCount * 2], 0, this.nullCount);
+ else if (this.nullCount == this.nullLocals.length) {
+ System.arraycopy(this.nullLocals, 0,
+ this.nullLocals = new LocalVariableBinding[this.nullCount * 2], 0, this.nullCount);
System.arraycopy(this.nullReferences, 0,
- this.nullReferences = new Expression[this.nullCount * 2], 0, this.nullCount);
+ this.nullReferences = new ASTNode[this.nullCount * 2], 0, this.nullCount);
System.arraycopy(this.nullCheckTypes, 0,
this.nullCheckTypes = new int[this.nullCount * 2], 0, this.nullCount);
}
- this.nullVariables[this.nullCount] = local;
+ this.nullLocals[this.nullCount] = local;
this.nullReferences[this.nullCount] = expression;
this.nullCheckTypes[this.nullCount++] = status;
}
-public void recordUsingNullReference(Scope scope, VariableBinding local,
- Expression reference, int checkType, FlowInfo flowInfo) {
+/** Record the fact that we see an early exit (in 'reference') while 'trackingVar' is in scope and may be unclosed. */
+public boolean recordExitAgainstResource(BlockScope scope, FlowInfo flowInfo, FakedTrackingVariable trackingVar, ASTNode reference) {
+ LocalVariableBinding local = trackingVar.binding;
+ if (flowInfo.isDefinitelyNonNull(local)) {
+ return false;
+ }
+ if (flowInfo.isDefinitelyNull(local)) {
+ scope.problemReporter().unclosedCloseable(trackingVar, reference);
+ return true; // handled
+ }
+ if (flowInfo.isPotentiallyNull(local)) {
+ scope.problemReporter().potentiallyUnclosedCloseable(trackingVar, reference);
+ return true; // handled
+ }
+ recordNullReference(trackingVar.binding, reference, EXIT_RESOURCE);
+ return true; // handled
+}
+
+public void recordUsingNullReference(Scope scope, LocalVariableBinding local,
+ ASTNode location, int checkType, FlowInfo flowInfo) {
if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0 ||
flowInfo.isDefinitelyUnknown(local)) {
return;
@@ -505,17 +563,18 @@
switch (checkType) {
case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL:
case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL:
+ Expression reference = (Expression)location;
if (flowInfo.isDefinitelyNonNull(local)) {
if (checkType == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) {
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableRedundantCheckOnNonNull(local, reference);
+ scope.problemReporter().localVariableRedundantCheckOnNonNull(local, reference);
}
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
} else {
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableNonNullComparedToNull(local, reference);
+ scope.problemReporter().localVariableNonNullComparedToNull(local, reference);
}
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
@@ -524,14 +583,14 @@
} else if (flowInfo.isDefinitelyNull(local)) {
if (checkType == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL)) {
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableRedundantCheckOnNull(local, reference);
+ scope.problemReporter().localVariableRedundantCheckOnNull(local, reference);
}
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
} else {
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableNullComparedToNonNull(local, reference);
+ scope.problemReporter().localVariableNullComparedToNonNull(local, reference);
}
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
@@ -564,6 +623,7 @@
case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL:
case CAN_ONLY_NULL | IN_ASSIGNMENT:
case CAN_ONLY_NULL | IN_INSTANCEOF:
+ reference = (Expression)location;
if (flowInfo.isPotentiallyNonNull(local)
|| flowInfo.isPotentiallyUnknown(local)
|| flowInfo.isProtectedNonNull(local)) {
@@ -575,11 +635,11 @@
switch(checkType & CONTEXT_MASK) {
case FlowContext.IN_COMPARISON_NULL:
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
- scope.problemReporter().variableNullReference(local, reference);
+ scope.problemReporter().localVariableNullReference(local, reference);
return;
}
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableRedundantCheckOnNull(local, reference);
+ scope.problemReporter().localVariableRedundantCheckOnNull(local, reference);
}
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
@@ -587,34 +647,34 @@
return;
case FlowContext.IN_COMPARISON_NON_NULL:
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
- scope.problemReporter().variableNullReference(local, reference);
+ scope.problemReporter().localVariableNullReference(local, reference);
return;
}
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
- scope.problemReporter().variableNullComparedToNonNull(local, reference);
+ scope.problemReporter().localVariableNullComparedToNonNull(local, reference);
}
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
}
return;
case FlowContext.IN_ASSIGNMENT:
- scope.problemReporter().variableRedundantNullAssignment(local, reference);
+ scope.problemReporter().localVariableRedundantNullAssignment(local, reference);
return;
case FlowContext.IN_INSTANCEOF:
- scope.problemReporter().variableNullInstanceof(local, reference);
+ scope.problemReporter().localVariableNullInstanceof(local, reference);
return;
}
} else if (flowInfo.isPotentiallyNull(local)) {
switch(checkType & CONTEXT_MASK) {
case FlowContext.IN_COMPARISON_NULL:
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
- scope.problemReporter().variablePotentialNullReference(local, reference);
+ scope.problemReporter().localVariablePotentialNullReference(local, reference);
return;
}
break;
case FlowContext.IN_COMPARISON_NON_NULL:
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
- scope.problemReporter().variablePotentialNullReference(local, reference);
+ scope.problemReporter().localVariablePotentialNullReference(local, reference);
return;
}
break;
@@ -633,14 +693,14 @@
return;
}
if (flowInfo.isDefinitelyNull(local)) {
- scope.problemReporter().variableNullReference(local, reference);
+ scope.problemReporter().localVariableNullReference(local, location);
return;
}
if (flowInfo.isPotentiallyNull(local)) {
- scope.problemReporter().variablePotentialNullReference(local, reference);
+ scope.problemReporter().localVariablePotentialNullReference(local, location);
return;
}
- recordNullReference(local, reference, checkType);
+ recordNullReference(local, location, checkType);
return;
default:
// never happens
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/NullInfoRegistry.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/NullInfoRegistry.java
index 99dd2fe..a2abb6b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/NullInfoRegistry.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/NullInfoRegistry.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2012 IBM Corporation and others.
+ * Copyright (c) 2006, 2011 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,8 +11,7 @@
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.flow;
-import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
-import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
/**
* A degenerate form of UnconditionalFlowInfo explicitly meant to capture
@@ -41,8 +40,6 @@
*/
public NullInfoRegistry(UnconditionalFlowInfo upstream) {
this.maxFieldCount = upstream.maxFieldCount;
- this.constantFieldsMask = upstream.constantFieldsMask;
- this.extraConstantFieldMask = upstream.extraConstantFieldMask;
if ((upstream.tagBits & NULL_FLAG_MASK) != 0) {
long u1, u2, u3, u4, nu2, nu3, nu4;
this.nullBit2 = (u1 = upstream.nullBit1)
@@ -90,8 +87,6 @@
this.nullBit2 |= other.nullBit2;
this.nullBit3 |= other.nullBit3;
this.nullBit4 |= other.nullBit4;
- this.maxFieldCount = other.maxFieldCount;
- this.addConstantFieldsMask(other);
if (other.extra != null) {
if (this.extra == null) {
this.extra = new long[extraLength][];
@@ -121,21 +116,13 @@
return this;
}
-public void markAsComparedEqualToNonNull(VariableBinding local) {
+public void markAsComparedEqualToNonNull(LocalVariableBinding local) {
// protected from non-object locals in calling methods
if (this != DEAD_END) {
this.tagBits |= NULL_FLAG_MASK;
int position;
- if (local instanceof FieldBinding && ((local.modifiers & AccConstant) == AccConstant)) {
- // non-final fields may be modified in separate threads and we cannot be sure about their
- // definite nullness. Hence, marking as definitely unknown to avoid deferring null check for these fields.
- this.markAsDefinitelyUnknown(local);
- return;
- } else {
- position = local.getAnalysisId(this.maxFieldCount);
- }
// position is zero-based
- if (position < BitCacheSize) { // use bits
+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) { // use bits
// set protected non null
this.nullBit1 |= (1L << position);
if (COVERAGE_TEST_FLAG) {
@@ -174,20 +161,13 @@
}
}
-public void markAsDefinitelyNonNull(VariableBinding local) {
+public void markAsDefinitelyNonNull(LocalVariableBinding local) {
// protected from non-object locals in calling methods
if (this != DEAD_END) {
this.tagBits |= NULL_FLAG_MASK;
int position;
- if (local instanceof FieldBinding && ((local.modifiers & AccConstant) == AccConstant)) {
- // non-final fields may be modified in separate threads and we cannot be sure about their
- // definite nullness. Hence, marking as definitely unknown to avoid deferring null check for these fields.
- this.markAsDefinitelyUnknown(local);
- return;
- } else {
- position = local.getAnalysisId(this.maxFieldCount);
- }
- if (position < BitCacheSize) { // use bits
+ // position is zero-based
+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) { // use bits
// set assigned non null
this.nullBit3 |= (1L << position);
if (COVERAGE_TEST_FLAG) {
@@ -227,21 +207,13 @@
}
// PREMATURE consider ignoring extra 0 to 2 included - means a1 should not be used either
// PREMATURE project protected non null onto something else
-public void markAsDefinitelyNull(VariableBinding local) {
+public void markAsDefinitelyNull(LocalVariableBinding local) {
// protected from non-object locals in calling methods
if (this != DEAD_END) {
this.tagBits |= NULL_FLAG_MASK;
int position;
- if (local instanceof FieldBinding && ((local.modifiers & AccConstant) == AccConstant)) {
- // non-final fields may be modified in separate threads and we cannot be sure about their
- // definite nullness. Hence, marking as potential null.
- this.markNullStatus(local, FlowInfo.POTENTIALLY_NULL);
- return;
- } else {
- position = local.getAnalysisId(this.maxFieldCount);
- }
// position is zero-based
- if (position < BitCacheSize) { // use bits
+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) { // use bits
// set assigned null
this.nullBit2 |= (1L << position);
if (COVERAGE_TEST_FLAG) {
@@ -280,13 +252,13 @@
}
}
-public void markAsDefinitelyUnknown(VariableBinding local) {
+public void markAsDefinitelyUnknown(LocalVariableBinding local) {
// protected from non-object locals in calling methods
if (this != DEAD_END) {
this.tagBits |= NULL_FLAG_MASK;
- int position = local.getAnalysisId(this.maxFieldCount);
+ int position;
// position is zero-based
- if (position < BitCacheSize) { // use bits
+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) { // use bits
// set assigned unknown
this.nullBit4 |= (1L << position);
if (COVERAGE_TEST_FLAG) {
@@ -435,13 +407,13 @@
* Mark a local as potentially having been assigned to an unknown value.
* @param local the local to mark
*/
-public void markPotentiallyUnknownBit(VariableBinding local) {
+public void markPotentiallyUnknownBit(LocalVariableBinding local) {
// protected from non-object locals in calling methods
if (this != DEAD_END) {
this.tagBits |= NULL_FLAG_MASK;
+ int position;
long mask;
- int position = local.getAnalysisId(this.maxFieldCount);
- if (position < BitCacheSize) {
+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
// use bits
mask = 1L << position;
isTrue((this.nullBit1 & mask) == 0, "Adding 'unknown' mark in unexpected state"); //$NON-NLS-1$
@@ -482,12 +454,12 @@
}
}
-public void markPotentiallyNullBit(VariableBinding local) {
+public void markPotentiallyNullBit(LocalVariableBinding local) {
if (this != DEAD_END) {
this.tagBits |= NULL_FLAG_MASK;
- long mask;
- int position = local.getAnalysisId(this.maxFieldCount);
- if (position < BitCacheSize) {
+ int position;
+ long mask;
+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
// use bits
mask = 1L << position;
isTrue((this.nullBit1 & mask) == 0, "Adding 'potentially null' mark in unexpected state"); //$NON-NLS-1$
@@ -528,12 +500,12 @@
}
}
-public void markPotentiallyNonNullBit(VariableBinding local) {
+public void markPotentiallyNonNullBit(LocalVariableBinding local) {
if (this != DEAD_END) {
this.tagBits |= NULL_FLAG_MASK;
+ int position;
long mask;
- int position = local.getAnalysisId(this.maxFieldCount);
- if (position < BitCacheSize) {
+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
// use bits
mask = 1L << position;
isTrue((this.nullBit1 & mask) == 0, "Adding 'potentially non-null' mark in unexpected state"); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java
index 5532e44..30b2bcf 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 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
@@ -20,13 +20,11 @@
package org.eclipse.jdt.internal.compiler.flow;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
-import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.TagBits;
-import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.BaseCallTrackingVariable;
/**
@@ -92,20 +90,17 @@
// extra segments
public static final int extraLength = 6;
- // extra bit fields for larger numbers of fields/variables
- // extra[0] holds definiteInits values, extra[1] potentialInits, etc.
- // lifecycle is extra == null or else all extra[]'s are allocated
- // arrays which have the same size
public long extra[][];
-
+ // extra bit fields for larger numbers of fields/variables
+ // extra[0] holds definiteInits values, extra[1] potentialInits, etc.
+ // lifecycle is extra == null or else all extra[]'s are allocated
+ // arrays which have the same size
+
public int maxFieldCount; // limit between fields and locals
// Constants
public static final int BitCacheSize = 64; // 64 bits in a long.
public int[] nullStatusChangedInAssert; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=303448
- public long constantFieldsMask; // record positions of constant fields so that they don't get reset in resetNullInfoForFields()
- public long extraConstantFieldMask[]; // extra mask for larger number of fields
- protected static final int AccConstant = ClassFileConstants.AccStatic|ClassFileConstants.AccFinal;
public FlowInfo addInitializationsFrom(FlowInfo inits) {
return addInfoFrom(inits, true);
@@ -535,13 +530,13 @@
return this;
}
-final public boolean cannotBeDefinitelyNullOrNonNull(VariableBinding var) {
+final public boolean cannotBeDefinitelyNullOrNonNull(LocalVariableBinding local) {
if ((this.tagBits & NULL_FLAG_MASK) == 0 ||
- (var.type.tagBits & TagBits.IsBaseType) != 0) {
+ (local.type.tagBits & TagBits.IsBaseType) != 0) {
return false;
}
- int position = var.getAnalysisId(this.maxFieldCount);
- if (position < BitCacheSize) {
+ int position;
+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
// use bits
return (
(~this.nullBit1
@@ -566,13 +561,13 @@
& (1L << (position % BitCacheSize))) != 0;
}
-final public boolean cannotBeNull(VariableBinding var) {
+final public boolean cannotBeNull(LocalVariableBinding local) {
if ((this.tagBits & NULL_FLAG_MASK) == 0 ||
- (var.type.tagBits & TagBits.IsBaseType) != 0) {
+ (local.type.tagBits & TagBits.IsBaseType) != 0) {
return false;
}
- int position = var.getAnalysisId(this.maxFieldCount);
- if (position < BitCacheSize) {
+ int position;
+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
// use bits
return (this.nullBit1 & this.nullBit3
& ((this.nullBit2 & this.nullBit4) | ~this.nullBit2)
@@ -593,13 +588,13 @@
& (1L << (position % BitCacheSize))) != 0;
}
-final public boolean canOnlyBeNull(VariableBinding var) {
+final public boolean canOnlyBeNull(LocalVariableBinding local) {
if ((this.tagBits & NULL_FLAG_MASK) == 0 ||
- (var.type.tagBits & TagBits.IsBaseType) != 0) {
+ (local.type.tagBits & TagBits.IsBaseType) != 0) {
return false;
}
- int position = var.getAnalysisId(this.maxFieldCount);
- if (position < BitCacheSize) {
+ int position;
+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
// use bits
return (this.nullBit1 & this.nullBit2
& (~this.nullBit3 | ~this.nullBit4)
@@ -637,8 +632,6 @@
}
copy.tagBits = this.tagBits;
copy.maxFieldCount = this.maxFieldCount;
- copy.constantFieldsMask = this.constantFieldsMask;
- copy.extraConstantFieldMask = this.extraConstantFieldMask;
if (this.extra != null) {
int length;
copy.extra = new long[extraLength][];
@@ -756,47 +749,32 @@
if ((this.tagBits & UNREACHABLE_OR_DEAD) != 0) {
return true;
}
- //{ObjectTeams: if it is copied don't require definite assignment again
- if (field.copyInheritanceSrc != null)
- return true;
- // SH}
- return isDefinitelyAssigned(field.getAnalysisId(this.maxFieldCount));
+//{ObjectTeams: if it is copied don't require definite assignment again
+ if (field.copyInheritanceSrc != null)
+ return true;
+// SH}
+ return isDefinitelyAssigned(field.id);
}
-final public boolean isDefinitelyAssigned(LocalVariableBinding var) {
+final public boolean isDefinitelyAssigned(LocalVariableBinding local) {
// do not want to complain in unreachable code if local declared in reachable code
- if ((this.tagBits & UNREACHABLE_OR_DEAD) != 0 && (var.declaration.bits & ASTNode.IsLocalDeclarationReachable) != 0) {
+ if ((this.tagBits & UNREACHABLE_OR_DEAD) != 0 && (local.declaration.bits & ASTNode.IsLocalDeclarationReachable) != 0) {
return true;
}
- return isDefinitelyAssigned(var.id + this.maxFieldCount);
+ return isDefinitelyAssigned(local.id + this.maxFieldCount);
}
-final public boolean isDefinitelyAssigned(VariableBinding var) {
- if (var instanceof FieldBinding) {
- return this.isDefinitelyAssigned((FieldBinding)var);
- } else {
- return this.isDefinitelyAssigned((LocalVariableBinding)var);
- }
-}
-
-final public boolean isDefinitelyNonNull(VariableBinding var) {
- boolean isField = var instanceof FieldBinding;
- if (isField && (this.tagBits & NULL_FLAG_MASK) == 0) {
- // no local yet in scope. Came here because of a field being queried for non null
- // will only happen for final fields, since they are assigned in a constructor or static block
- // and we may currently be in some other method
- this.tagBits |= NULL_FLAG_MASK;
- }
+final public boolean isDefinitelyNonNull(LocalVariableBinding local) {
// do not want to complain in unreachable code
if ((this.tagBits & UNREACHABLE) != 0 ||
(this.tagBits & NULL_FLAG_MASK) == 0) {
return false;
}
- if ((var.type.tagBits & TagBits.IsBaseType) != 0 ||
- var.constant() != Constant.NotAConstant) { // String instances
+ if ((local.type.tagBits & TagBits.IsBaseType) != 0 ||
+ local.constant() != Constant.NotAConstant) { // String instances
return true;
}
- int position = var.getAnalysisId(this.maxFieldCount);
+ int position = local.id + this.maxFieldCount;
if (position < BitCacheSize) { // use bits
return ((this.nullBit1 & this.nullBit3 & (~this.nullBit2 | this.nullBit4))
& (1L << position)) != 0;
@@ -815,21 +793,14 @@
& (1L << (position % BitCacheSize))) != 0;
}
-final public boolean isDefinitelyNull(VariableBinding var) {
- boolean isField = var instanceof FieldBinding;
- if (isField && (this.tagBits & NULL_FLAG_MASK) == 0) {
- // no local yet in scope. Came here because of a field being queried for non null
- // will only happen for final fields, since they are assigned in a constructor or static block
- // and we may currently be in some other method
- this.tagBits |= NULL_FLAG_MASK;
- }
+final public boolean isDefinitelyNull(LocalVariableBinding local) {
// do not want to complain in unreachable code
if ((this.tagBits & UNREACHABLE) != 0 ||
(this.tagBits & NULL_FLAG_MASK) == 0 ||
- (var.type.tagBits & TagBits.IsBaseType) != 0) {
+ (local.type.tagBits & TagBits.IsBaseType) != 0) {
return false;
}
- int position = var.getAnalysisId(this.maxFieldCount);
+ int position = local.id + this.maxFieldCount;
if (position < BitCacheSize) { // use bits
return ((this.nullBit1 & this.nullBit2
& (~this.nullBit3 | ~this.nullBit4))
@@ -849,13 +820,13 @@
& (1L << (position % BitCacheSize))) != 0;
}
-final public boolean isDefinitelyUnknown(VariableBinding var) {
+final public boolean isDefinitelyUnknown(LocalVariableBinding local) {
// do not want to complain in unreachable code
if ((this.tagBits & UNREACHABLE) != 0 ||
(this.tagBits & NULL_FLAG_MASK) == 0) {
return false;
}
- int position = var.getAnalysisId(this.maxFieldCount);
+ int position = local.id + this.maxFieldCount;
if (position < BitCacheSize) { // use bits
return ((this.nullBit1 & this.nullBit4
& ~this.nullBit2 & ~this.nullBit3) & (1L << position)) != 0;
@@ -904,7 +875,7 @@
}
final public boolean isPotentiallyAssigned(FieldBinding field) {
- return isPotentiallyAssigned(field.getAnalysisId(this.maxFieldCount));
+ return isPotentiallyAssigned(field.id);
}
final public boolean isPotentiallyAssigned(LocalVariableBinding local) {
@@ -915,22 +886,14 @@
return isPotentiallyAssigned(local.id + this.maxFieldCount);
}
-final public boolean isPotentiallyAssigned(VariableBinding var) {
- if (var instanceof FieldBinding) {
- return this.isPotentiallyAssigned((FieldBinding)var);
- } else {
- return this.isPotentiallyAssigned((LocalVariableBinding)var);
- }
-}
-
// TODO (Ayush) Check why this method does not return true for protected non null (1111)
-final public boolean isPotentiallyNonNull(VariableBinding var) {
+final public boolean isPotentiallyNonNull(LocalVariableBinding local) {
if ((this.tagBits & NULL_FLAG_MASK) == 0 ||
- (var.type.tagBits & TagBits.IsBaseType) != 0) {
+ (local.type.tagBits & TagBits.IsBaseType) != 0) {
return false;
}
- int position = var.getAnalysisId(this.maxFieldCount);
- if (position < BitCacheSize) { // use bits
+ int position;
+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
// use bits
return ((this.nullBit3 & (~this.nullBit1 | ~this.nullBit2))
& (1L << position)) != 0;
@@ -950,13 +913,13 @@
}
// TODO (Ayush) Check why this method does not return true for protected null
-final public boolean isPotentiallyNull(VariableBinding var) {
+final public boolean isPotentiallyNull(LocalVariableBinding local) {
if ((this.tagBits & NULL_FLAG_MASK) == 0 ||
- (var.type.tagBits & TagBits.IsBaseType) != 0) {
+ (local.type.tagBits & TagBits.IsBaseType) != 0) {
return false;
}
- int position = var.getAnalysisId(this.maxFieldCount);
- if (position < BitCacheSize) {
+ int position;
+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
// use bits
return ((this.nullBit2 & (~this.nullBit1 | ~this.nullBit3))
& (1L << position)) != 0;
@@ -975,13 +938,13 @@
& (1L << (position % BitCacheSize))) != 0;
}
-final public boolean isPotentiallyUnknown(VariableBinding var) {
+final public boolean isPotentiallyUnknown(LocalVariableBinding local) {
// do not want to complain in unreachable code
if ((this.tagBits & UNREACHABLE) != 0 ||
(this.tagBits & NULL_FLAG_MASK) == 0) {
return false;
}
- int position = var.getAnalysisId(this.maxFieldCount);
+ int position = local.id + this.maxFieldCount;
if (position < BitCacheSize) { // use bits
return (this.nullBit4
& (~this.nullBit1 | ~this.nullBit2 & ~this.nullBit3)
@@ -1002,13 +965,14 @@
& (1L << (position % BitCacheSize))) != 0;
}
-final public boolean isProtectedNonNull(VariableBinding var) {
+final public boolean isProtectedNonNull(LocalVariableBinding local) {
if ((this.tagBits & NULL_FLAG_MASK) == 0 ||
- (var.type.tagBits & TagBits.IsBaseType) != 0) {
+ (local.type.tagBits & TagBits.IsBaseType) != 0) {
return false;
}
- int position = var.getAnalysisId(this.maxFieldCount);
- if (position < BitCacheSize) { // use bits
+ int position;
+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
+ // use bits
return (this.nullBit1 & this.nullBit3 & this.nullBit4 & (1L << position)) != 0;
}
// use extra vector
@@ -1026,13 +990,13 @@
& (1L << (position % BitCacheSize))) != 0;
}
-final public boolean isProtectedNull(VariableBinding var) {
+final public boolean isProtectedNull(LocalVariableBinding local) {
if ((this.tagBits & NULL_FLAG_MASK) == 0 ||
- (var.type.tagBits & TagBits.IsBaseType) != 0) {
+ (local.type.tagBits & TagBits.IsBaseType) != 0) {
return false;
}
- int position = var.getAnalysisId(this.maxFieldCount);
- if (position < BitCacheSize) {
+ int position;
+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
// use bits
return (this.nullBit1 & this.nullBit2
& (this.nullBit3 ^ this.nullBit4)
@@ -1065,27 +1029,15 @@
throw new AssertionFailedException("assertion failed: " + message); //$NON-NLS-1$
return expression;
}
-public void markAsComparedEqualToNonNull(VariableBinding var) {
+public void markAsComparedEqualToNonNull(LocalVariableBinding local) {
// protected from non-object locals in calling methods
if (this != DEAD_END) {
this.tagBits |= NULL_FLAG_MASK;
int position;
- if (var instanceof FieldBinding) {
- if ((var.modifiers & AccConstant) == AccConstant) {
- position = var.getAnalysisId(this.maxFieldCount);
- } else {
- // non-final fields may be modified in separate threads and we cannot be sure about their
- // definite nullness. Hence, marking as definitely unknown to avoid deferring null check for these fields
- this.markAsDefinitelyUnknown(var);
- return;
- }
- } else {
- position = var.id + this.maxFieldCount;
- }
long mask;
long a1, a2, a3, a4, na2;
// position is zero-based
- if (position < BitCacheSize) {
+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
// use bits
if (((mask = 1L << position)
& (a1 = this.nullBit1)
@@ -1174,26 +1126,14 @@
}
}
-public void markAsComparedEqualToNull(VariableBinding var) {
+public void markAsComparedEqualToNull(LocalVariableBinding local) {
// protected from non-object locals in calling methods
if (this != DEAD_END) {
this.tagBits |= NULL_FLAG_MASK;
int position;
long mask;
// position is zero-based
- if (var instanceof FieldBinding) {
- if ((var.modifiers & AccConstant) == AccConstant) {
- position = var.getAnalysisId(this.maxFieldCount);
- } else {
- // non-final fields may be modified in separate threads and we cannot be sure about their
- // definite nullness. Hence, marking as potential null.
- this.markNullStatus(var, FlowInfo.POTENTIALLY_NULL);
- return;
- }
- } else {
- position = var.id + this.maxFieldCount;
- }
- if (position < BitCacheSize) {
+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
// use bits
if (((mask = 1L << position) & this.nullBit1) != 0) {
if ((mask
@@ -1314,31 +1254,24 @@
}
}
-public void markAsDefinitelyAssigned(VariableBinding var) {
+public void markAsDefinitelyAssigned(FieldBinding field) {
if (this != DEAD_END)
- markAsDefinitelyAssigned(var.getAnalysisId(this.maxFieldCount));
+ markAsDefinitelyAssigned(field.id);
}
-public void markAsDefinitelyNonNull(VariableBinding var) {
+public void markAsDefinitelyAssigned(LocalVariableBinding local) {
+ if (this != DEAD_END)
+ markAsDefinitelyAssigned(local.id + this.maxFieldCount);
+}
+
+public void markAsDefinitelyNonNull(LocalVariableBinding local) {
// protected from non-object locals in calling methods
if (this != DEAD_END) {
this.tagBits |= NULL_FLAG_MASK;
long mask;
int position;
// position is zero-based
- if (var instanceof FieldBinding) {
- if ((var.modifiers & AccConstant) == AccConstant) {
- position = var.getAnalysisId(this.maxFieldCount);
- } else {
- // non-final fields may be modified in separate threads and we cannot be sure about their
- // definite nullness. Hence, marking as definitely unknown to avoid deferring null check for these fields.
- this.markAsDefinitelyUnknown(var);
- return;
- }
- } else {
- position = var.id + this.maxFieldCount;
- }
- if (position < BitCacheSize) { // use bits
+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) { // use bits
// set assigned non null
this.nullBit1 |= (mask = 1L << position);
this.nullBit3 |= mask;
@@ -1385,26 +1318,14 @@
}
}
-public void markAsDefinitelyNull(VariableBinding var) {
+public void markAsDefinitelyNull(LocalVariableBinding local) {
// protected from non-object locals in calling methods
if (this != DEAD_END) {
this.tagBits |= NULL_FLAG_MASK;
long mask;
int position;
// position is zero-based
- if (var instanceof FieldBinding) {
- if ((var.modifiers & AccConstant) == AccConstant) {
- position = var.getAnalysisId(this.maxFieldCount);
- } else {
- // non-final fields may be modified in separate threads and we cannot be sure about their
- // definite nullness. Hence, marking as potential null.
- this.markNullStatus(var, FlowInfo.POTENTIALLY_NULL);
- return;
- }
- } else {
- position = var.id + this.maxFieldCount;
- }
- if (position < BitCacheSize) { // use bits
+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) { // use bits
// mark assigned null
this.nullBit1 |= (mask = 1L << position);
this.nullBit2 |= mask;
@@ -1453,17 +1374,18 @@
/**
* Mark a local as having been assigned to an unknown value.
- * @param var the local to mark
+ * @param local the local to mark
*/
// PREMATURE may try to get closer to markAsDefinitelyAssigned, but not
// obvious
-public void markAsDefinitelyUnknown(VariableBinding var) {
+public void markAsDefinitelyUnknown(LocalVariableBinding local) {
// protected from non-object locals in calling methods
if (this != DEAD_END) {
this.tagBits |= NULL_FLAG_MASK;
long mask;
- int position = var.getAnalysisId(this.maxFieldCount);
- if (position < BitCacheSize) {
+ int position;
+ // position is zero-based
+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
// use bits
// mark assigned null
this.nullBit1 |= (mask = 1L << position);
@@ -1511,12 +1433,12 @@
}
}
-public void resetNullInfo(VariableBinding var) {
+public void resetNullInfo(LocalVariableBinding local) {
if (this != DEAD_END) {
this.tagBits |= NULL_FLAG_MASK;
+ int position;
long mask;
- int position = var.getAnalysisId(this.maxFieldCount);
- if (position < BitCacheSize) {
+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
// use bits
this.nullBit1 &= (mask = ~(1L << position));
this.nullBit2 &= mask;
@@ -1539,132 +1461,17 @@
}
}
-public void resetNullInfoForFields() {
- if (this != DEAD_END) {
- long mask = this.maxFieldCount < BitCacheSize ? (-1L << this.maxFieldCount) : 0L;
- mask |= this.constantFieldsMask;
- // first reset normal bits:
- this.nullBit1 |= ~mask;
- this.nullBit2 &= mask;
- this.nullBit3 &= mask;
- this.nullBit4 |= ~mask;
- if (this.maxFieldCount >= BitCacheSize && this.extra != null) {
- // use extra vector
- int localsStartIndex = this.maxFieldCount/BitCacheSize - 1;
- int localsStartOffset = this.maxFieldCount % BitCacheSize;
- int len = Math.min(localsStartIndex+1, this.extra[2].length);
- if (this.extraConstantFieldMask != null){
- for (int vectorIndex = 0; vectorIndex < len; vectorIndex++) {
- if (vectorIndex >= this.extraConstantFieldMask.length) {
- // no constant fields after this, just mask all fields
- if (vectorIndex == localsStartIndex) {
- // some locals, some fields at this vectorIndex
- mask = -1L << localsStartOffset;
- } else {
- // all fields here
- mask = 0L;
- }
- } else {
- if (vectorIndex == localsStartIndex) {
- // some locals, some fields at this vectorIndex
- mask = ((-1 << localsStartOffset) | this.extraConstantFieldMask[vectorIndex]);
- } else {
- // all fields here
- mask = 0L | this.extraConstantFieldMask[vectorIndex];
- }
-
- }
- this.extra[2][vectorIndex]
- |= ~mask;
- this.extra[3][vectorIndex] &= mask;
- this.extra[4][vectorIndex] &= mask;
- this.extra[5][vectorIndex] |= ~mask;
- }
- } else {
- // no constant fields
- for (int vectorIndex = 0; vectorIndex < len; vectorIndex++) {
- if (vectorIndex == localsStartIndex) {
- // some locals, some fields at this vectorIndex
- mask = -1L << localsStartOffset;
- } else {
- // all fields here
- mask = 0L;
- }
- this.extra[2][vectorIndex]
- |= ~mask;
- this.extra[3][vectorIndex] &= mask;
- this.extra[4][vectorIndex] &= mask;
- this.extra[5][vectorIndex] |= ~mask;
- }
- }
- }
- }
-}
-
-public void updateConstantFieldsMask(FieldBinding field) {
- int position = field.getAnalysisId(this.maxFieldCount);
- long mask = 1L << (position % BitCacheSize);
- if (position < BitCacheSize) {
- this.constantFieldsMask |= 1L << position; // exclude this field from being reset
- } else {
- // use extra vector
- int vectorIndex = (position / BitCacheSize) - 1;
- if (this.extraConstantFieldMask == null) {
- // extra array not created. Create constant field mask bit streams.
- int length = vectorIndex + 1;
- this.extraConstantFieldMask = new long[length];
- }
- else {
- int oldLength; // might need to grow the arrays
- if (vectorIndex >= (oldLength = this.extraConstantFieldMask.length)) {
- System.arraycopy(this.extraConstantFieldMask, 0, (this.extraConstantFieldMask = new long[vectorIndex + 1]), 0, oldLength);
- }
- }
- this.extraConstantFieldMask[vectorIndex] |= mask; // exclude this field from resetNullInfoForFields
- }
-}
-
-/**
- * All the infos originate in TypeDeclaration.analyseCode(). So making sure that this method is called for every info that is sent into
- * methods/constructors should be sufficient
- */
-public void addConstantFieldsMask(UnconditionalFlowInfo other) {
- this.constantFieldsMask |= other.constantFieldsMask;
- if (other.extraConstantFieldMask != null) {
- int oldLength = 0;
- int otherLen = other.extraConstantFieldMask.length;
- if (this.extraConstantFieldMask != null) {
- oldLength = this.extraConstantFieldMask.length;
- if (otherLen > (oldLength = this.extraConstantFieldMask.length)) {
- System.arraycopy(this.extraConstantFieldMask, 0, (this.extraConstantFieldMask = new long[otherLen]), 0, oldLength);
- for (int i = 0; i < oldLength; i++) {
- this.extraConstantFieldMask[i] |= other.extraConstantFieldMask[i];
- }
- } else {
- for (int i = 0; i < otherLen; i++) {
- this.extraConstantFieldMask[i] |= other.extraConstantFieldMask[i];
- }
- }
- } else {
- this.extraConstantFieldMask = new long[otherLen];
- }
- for (int i = oldLength; i < otherLen; i++) {
- this.extraConstantFieldMask[i] = other.extraConstantFieldMask[i];
- }
- }
-}
-
/**
* Mark a local as potentially having been assigned to an unknown value.
- * @param var the local to mark
+ * @param local the local to mark
*/
-public void markPotentiallyUnknownBit(VariableBinding var) {
+public void markPotentiallyUnknownBit(LocalVariableBinding local) {
// protected from non-object locals in calling methods
if (this != DEAD_END) {
this.tagBits |= NULL_FLAG_MASK;
+ int position;
long mask;
- int position = var.getAnalysisId(this.maxFieldCount);
- if (position < BitCacheSize) {
+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
// use bits
mask = 1L << position;
isTrue((this.nullBit1 & mask) == 0, "Adding 'unknown' mark in unexpected state"); //$NON-NLS-1$
@@ -1706,12 +1513,12 @@
}
}
-public void markPotentiallyNullBit(VariableBinding var) {
+public void markPotentiallyNullBit(LocalVariableBinding local) {
if (this != DEAD_END) {
this.tagBits |= NULL_FLAG_MASK;
+ int position;
long mask;
- int position = var.getAnalysisId(this.maxFieldCount);
- if (position < BitCacheSize) {
+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
// use bits
mask = 1L << position;
isTrue((this.nullBit1 & mask) == 0, "Adding 'potentially null' mark in unexpected state"); //$NON-NLS-1$
@@ -1753,12 +1560,12 @@
}
}
-public void markPotentiallyNonNullBit(VariableBinding var) {
+public void markPotentiallyNonNullBit(LocalVariableBinding local) {
if (this != DEAD_END) {
this.tagBits |= NULL_FLAG_MASK;
+ int position;
long mask;
- int position = var.getAnalysisId(this.maxFieldCount);
- if (position < BitCacheSize) {
+ if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
// use bits
mask = 1L << position;
isTrue((this.nullBit1 & mask) == 0, "Adding 'potentially non-null' mark in unexpected state"); //$NON-NLS-1$
@@ -2115,8 +1922,6 @@
copy.tagBits = this.tagBits & ~NULL_FLAG_MASK;
copy.maxFieldCount = this.maxFieldCount;
copy.nullStatusChangedInAssert = this.nullStatusChangedInAssert;
- copy.constantFieldsMask = this.constantFieldsMask;
- copy.extraConstantFieldMask = this.extraConstantFieldMask;
if (this.extra != null) {
int length;
copy.extra = new long[extraLength][];
@@ -2239,8 +2044,6 @@
UnconditionalFlowInfo copy = new UnconditionalFlowInfo();
copy.tagBits = this.tagBits;
copy.maxFieldCount = this.maxFieldCount;
- copy.constantFieldsMask = this.constantFieldsMask;
- copy.extraConstantFieldMask = this.extraConstantFieldMask;
int limit = this.maxFieldCount;
if (limit < BitCacheSize) {
long mask;
@@ -2295,8 +2098,8 @@
return this;
}
-public void markedAsNullOrNonNullInAssertExpression(VariableBinding binding) {
- int position = binding.getAnalysisId(this.maxFieldCount);
+public void markedAsNullOrNonNullInAssertExpression(LocalVariableBinding local) {
+ int position = local.id + this.maxFieldCount;
int oldLength;
if (this.nullStatusChangedInAssert == null) {
this.nullStatusChangedInAssert = new int[position + 1];
@@ -2309,8 +2112,8 @@
this.nullStatusChangedInAssert[position] = 1;
}
-public boolean isMarkedAsNullOrNonNullInAssertExpression(VariableBinding binding) {
- int position = binding.getAnalysisId(this.maxFieldCount);
+public boolean isMarkedAsNullOrNonNullInAssertExpression(LocalVariableBinding local) {
+ int position = local.id + this.maxFieldCount;
if(this.nullStatusChangedInAssert == null || position >= this.nullStatusChangedInAssert.length) {
return false;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
index 3d3e18c..72ca121 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
@@ -15,6 +15,8 @@
* bug 295551 - Add option to automatically promote all warnings to errors
* bug 349326 - [1.7] new warning for missing try-with-resources
* bug 186342 - [compiler][null] Using annotations for null checking
+ * bug 370639 - [compiler][resource] restore the default for resource leak warnings
+ * bug 366063 - Compiler should not add synthetic @NonNull annotations
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.impl;
@@ -147,7 +149,6 @@
public static final String OPTION_ReportTasks = "org.eclipse.jdt.core.compiler.problem.tasks"; //$NON-NLS-1$
public static final String OPTION_ReportUnusedObjectAllocation = "org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation"; //$NON-NLS-1$
public static final String OPTION_IncludeNullInfoFromAsserts = "org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts"; //$NON-NLS-1$
- public static final String OPTION_IncludeFieldsInNullAnalysis = "org.eclipse.jdt.core.compiler.problem.includeFieldsInNullAnalysis"; //$NON-NLS-1$
public static final String OPTION_ReportMethodCanBeStatic = "org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic"; //$NON-NLS-1$
public static final String OPTION_ReportMethodCanBePotentiallyStatic = "org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic"; //$NON-NLS-1$
public static final String OPTION_ReportRedundantSpecificationOfTypeArguments = "org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments"; //$NON-NLS-1$
@@ -490,8 +491,6 @@
public boolean ignoreMethodBodies;
/** Raise null related warnings for variables tainted inside an assert statement (java 1.4 and above)*/
public boolean includeNullInfoFromAsserts;
- /** Specify if fields are to be included in null analysis */
- public boolean includeFieldsInNullAnalysis;
/** Controls whether forced generic type problems get reported */
public boolean reportUnavoidableGenericTypeProblems;
@@ -514,7 +513,9 @@
/** Fully qualified name of annotation to use as marker for default nonnull. */
public char[][] nonNullByDefaultAnnotationName;
/** TagBits-encoded default for non-annotated types. */
- public long defaultNonNullness; // 0 or TagBits#AnnotationNonNull
+ public long intendedDefaultNonNullness; // 0 or TagBits#AnnotationNonNull
+ /** Should resources (objects of type Closeable) be analysed for matching calls to close()? */
+ public boolean analyseResourceLeaks;
// keep in sync with warningTokenToIrritant and warningTokenFromIrritant
public final static String[] warningTokens = {
@@ -1364,7 +1365,6 @@
optionsMap.put(OPTION_ReportTasks, getSeverityString(Tasks));
optionsMap.put(OPTION_ReportUnusedObjectAllocation, getSeverityString(UnusedObjectAllocation));
optionsMap.put(OPTION_IncludeNullInfoFromAsserts, this.includeNullInfoFromAsserts ? ENABLED : DISABLED);
- optionsMap.put(OPTION_IncludeFieldsInNullAnalysis, this.includeFieldsInNullAnalysis ? ENABLED : DISABLED);
optionsMap.put(OPTION_ReportMethodCanBeStatic, getSeverityString(MethodCanBeStatic));
optionsMap.put(OPTION_ReportMethodCanBePotentiallyStatic, getSeverityString(MethodCanBePotentiallyStatic));
optionsMap.put(OPTION_ReportRedundantSpecificationOfTypeArguments, getSeverityString(RedundantSpecificationOfTypeArguments));
@@ -1411,7 +1411,7 @@
optionsMap.put(OPTION_NullableAnnotationName, String.valueOf(CharOperation.concatWith(this.nullableAnnotationName, '.')));
optionsMap.put(OPTION_NonNullAnnotationName, String.valueOf(CharOperation.concatWith(this.nonNullAnnotationName, '.')));
optionsMap.put(OPTION_NonNullByDefaultAnnotationName, String.valueOf(CharOperation.concatWith(this.nonNullByDefaultAnnotationName, '.')));
- if (this.defaultNonNullness == TagBits.AnnotationNonNull)
+ if (this.intendedDefaultNonNullness == TagBits.AnnotationNonNull)
optionsMap.put(OPTION_NonNullIsDefault, CompilerOptions.ENABLED);
else
optionsMap.put(OPTION_NonNullIsDefault, CompilerOptions.DISABLED);
@@ -1566,14 +1566,13 @@
// allow null info from asserts to be considered downstream by default
this.includeNullInfoFromAsserts = false;
- // null analysis for fields
- this.includeFieldsInNullAnalysis = false;
-
this.isAnnotationBasedNullAnalysisEnabled = false;
this.nullableAnnotationName = DEFAULT_NULLABLE_ANNOTATION_NAME;
this.nonNullAnnotationName = DEFAULT_NONNULL_ANNOTATION_NAME;
this.nonNullByDefaultAnnotationName = DEFAULT_NONNULLBYDEFAULT_ANNOTATION_NAME;
- this.defaultNonNullness = 0;
+ this.intendedDefaultNonNullness = 0;
+
+ this.analyseResourceLeaks = true;
}
public void set(Map optionsMap) {
@@ -1794,13 +1793,6 @@
this.includeNullInfoFromAsserts = false;
}
}
- if ((optionValue = optionsMap.get(OPTION_IncludeFieldsInNullAnalysis)) != null) {
- if (ENABLED.equals(optionValue)) {
- this.includeFieldsInNullAnalysis = true;
- } else if (DISABLED.equals(optionValue)) {
- this.includeFieldsInNullAnalysis = false;
- }
- }
if ((optionValue = optionsMap.get(OPTION_ReportMethodWithConstructorName)) != null) updateSeverity(MethodWithConstructorName, optionValue);
if ((optionValue = optionsMap.get(OPTION_ReportOverridingPackageDefaultMethod)) != null) updateSeverity(OverriddenPackageDefaultMethod, optionValue);
if ((optionValue = optionsMap.get(OPTION_ReportDeprecation)) != null) updateSeverity(UsingDeprecatedAPI, optionValue);
@@ -1864,6 +1856,13 @@
if ((optionValue = optionsMap.get(OPTION_ReportUnclosedCloseable)) != null) updateSeverity(UnclosedCloseable, optionValue);
if ((optionValue = optionsMap.get(OPTION_ReportPotentiallyUnclosedCloseable)) != null) updateSeverity(PotentiallyUnclosedCloseable, optionValue);
if ((optionValue = optionsMap.get(OPTION_ReportExplicitlyClosedAutoCloseable)) != null) updateSeverity(ExplicitlyClosedAutoCloseable, optionValue);
+ if (getSeverity(UnclosedCloseable) == ProblemSeverities.Ignore
+ && getSeverity(PotentiallyUnclosedCloseable) == ProblemSeverities.Ignore
+ && getSeverity(ExplicitlyClosedAutoCloseable) == ProblemSeverities.Ignore) {
+ this.analyseResourceLeaks = false;
+ } else {
+ this.analyseResourceLeaks = true;
+ }
//{ObjectTeams:
if ((optionValue = optionsMap.get(OPTION_ReportNotExactlyOneBasecall)) != null) updateSeverity(NotExactlyOneBasecall, optionValue);
if ((optionValue = optionsMap.get(OPTION_ReportBaseclassCycle)) != null) updateSeverity(BaseclassCycle, optionValue);
@@ -1939,9 +1938,9 @@
}
if ((optionValue = optionsMap.get(OPTION_NonNullIsDefault)) != null) {
if (CompilerOptions.ENABLED.equals(optionValue))
- this.defaultNonNullness = TagBits.AnnotationNonNull;
+ this.intendedDefaultNonNullness = TagBits.AnnotationNonNull;
else if (CompilerOptions.DISABLED.equals(optionValue))
- this.defaultNonNullness = 0;
+ this.intendedDefaultNonNullness = 0;
}
}
@@ -2138,7 +2137,6 @@
buf.append("\n\t- missing @Deprecated annotation: ").append(getSeverityString(MissingDeprecatedAnnotation)); //$NON-NLS-1$
buf.append("\n\t- incomplete enum switch: ").append(getSeverityString(IncompleteEnumSwitch)); //$NON-NLS-1$
buf.append("\n\t- raise null related warnings for variables tainted in assert statements: ").append(this.includeNullInfoFromAsserts ? ENABLED : DISABLED); //$NON-NLS-1$
- buf.append("\n\t- include fields in null analysis: ").append(this.includeFieldsInNullAnalysis ? ENABLED : DISABLED); //$NON-NLS-1$
buf.append("\n\t- suppress warnings: ").append(this.suppressWarnings ? ENABLED : DISABLED); //$NON-NLS-1$
buf.append("\n\t- suppress optional errors: ").append(this.suppressOptionalErrors ? ENABLED : DISABLED); //$NON-NLS-1$
buf.append("\n\t- unhandled warning token: ").append(getSeverityString(UnhandledWarningToken)); //$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 ef5f4a2..aa76152 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 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,6 +11,7 @@
* Stephan Herrmann - Contributions for
* bug 349326 - [1.7] new warning for missing try-with-resources
* bug 186342 - [compiler][null] Using annotations for null checking
+ * bug 370639 - [compiler][resource] restore the default for resource leak warnings
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.impl;
@@ -180,6 +181,7 @@
.set(
CompilerOptions.DeadCode
|CompilerOptions.Tasks
+ |CompilerOptions.UnclosedCloseable
|CompilerOptions.NullSpecInsufficientInfo
|CompilerOptions.RedundantNullAnnotation);
// default errors IF AnnotationBasedNullAnalysis is enabled:
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 1648cff..4af69a3 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
@@ -15,6 +15,7 @@
* bug 364890 - BinaryTypeBinding should use char constants from Util
* bug 365387 - [compiler][null] bug 186342: Issues to follow up post review and verification.
* bug 358903 - Filter practically unimportant resource leak warnings
+ * bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -552,6 +553,11 @@
}
}
+ // need type annotations before processing methods (for @NonNullByDefault)
+ if (this.environment.globalOptions.isAnnotationBasedNullAnalysisEnabled) {
+ scanTypeForNullDefaultAnnotation(binaryType);
+ }
+
if (needFieldsAndMethods) {
createFields(binaryType.getFields(), sourceLevel, missingTypeNames);
createMethods(binaryType.getMethods(), sourceLevel, missingTypeNames);
@@ -581,14 +587,6 @@
// SH}
if (this.environment.globalOptions.storeAnnotations)
setAnnotations(createAnnotations(binaryType.getAnnotations(), this.environment, missingTypeNames));
-
- if (this.environment.globalOptions.isAnnotationBasedNullAnalysisEnabled
- && CharOperation.equals(TypeConstants.PACKAGE_INFO_NAME, binaryType.getSourceName()))
- {
- // only for package-info.java can type-level null-annotations (i.e., @NonNullByDefault)
- // on a binary type influence the compilation
- scanPackageInfoForNullDefaultAnnotation(binaryType);
- }
} finally {
// protect against incorrect use of the needFieldsAndMethods flag, see 48459
if (this.fields == null)
@@ -1586,65 +1584,93 @@
return;
char[][] nullableAnnotationName = this.environment.getNullableAnnotationName();
char[][] nonNullAnnotationName = this.environment.getNonNullAnnotationName();
- if (nullableAnnotationName == null || nonNullAnnotationName == null)
+ char[][] nonNullByDefaultAnnotationName = this.environment.getNonNullByDefaultAnnotationName();
+ if (nullableAnnotationName == null || nonNullAnnotationName == null || nonNullByDefaultAnnotationName == null)
return; // not well-configured to use null annotations
+ int currentDefault = NO_NULL_DEFAULT;
+ if ((this.tagBits & TagBits.AnnotationNonNullByDefault) != 0) {
+ currentDefault = NONNULL_BY_DEFAULT;
+ } else if ((this.tagBits & TagBits.AnnotationNullUnspecifiedByDefault) != 0) {
+ currentDefault = NULL_UNSPECIFIED_BY_DEFAULT;
+ }
+
// return:
IBinaryAnnotation[] annotations = method.getAnnotations();
+ boolean explicitNullness = false;
if (annotations != null) {
for (int i = 0; i < annotations.length; i++) {
char[] annotationTypeName = annotations[i].getTypeName();
if (annotationTypeName[0] != Util.C_RESOLVED)
continue;
char[][] typeName = CharOperation.splitOn('/', annotationTypeName, 1, annotationTypeName.length-1); // cut of leading 'L' and trailing ';'
- if (CharOperation.equals(typeName, nonNullAnnotationName)) {
- methodBinding.tagBits |= TagBits.AnnotationNonNull;
- break;
+ if (CharOperation.equals(typeName, nonNullByDefaultAnnotationName)) {
+ methodBinding.tagBits |= TagBits.AnnotationNonNullByDefault;
+ currentDefault = NONNULL_BY_DEFAULT;
}
- if (CharOperation.equals(typeName, nullableAnnotationName)) {
+ if (!explicitNullness && CharOperation.equals(typeName, nonNullAnnotationName)) {
+ methodBinding.tagBits |= TagBits.AnnotationNonNull;
+ explicitNullness = true;
+ }
+ if (!explicitNullness && CharOperation.equals(typeName, nullableAnnotationName)) {
methodBinding.tagBits |= TagBits.AnnotationNullable;
- break;
+ explicitNullness = true;
}
}
}
+ if (!explicitNullness && currentDefault == NONNULL_BY_DEFAULT) {
+ methodBinding.tagBits |= TagBits.AnnotationNonNull;
+ }
// parameters:
TypeBinding[] parameters = methodBinding.parameters;
int numVisibleParams = parameters.length;
int numParamAnnotations = method.getAnnotatedParametersCount();
- if (numParamAnnotations > 0) {
- int startIndex = numParamAnnotations - numVisibleParams;
+ if (numParamAnnotations > 0 || currentDefault == NONNULL_BY_DEFAULT) {
for (int j = 0; j < numVisibleParams; j++) {
- IBinaryAnnotation[] paramAnnotations = method.getParameterAnnotations(j+startIndex);
- if (paramAnnotations != null) {
- for (int i = 0; i < paramAnnotations.length; i++) {
- char[] annotationTypeName = paramAnnotations[i].getTypeName();
- if (annotationTypeName[0] != Util.C_RESOLVED)
- continue;
- char[][] typeName = CharOperation.splitOn('/', annotationTypeName, 1, annotationTypeName.length-1); // cut of leading 'L' and trailing ';'
- if (CharOperation.equals(typeName, nonNullAnnotationName)) {
- if (methodBinding.parameterNonNullness == null)
- methodBinding.parameterNonNullness = new Boolean[numVisibleParams];
- methodBinding.parameterNonNullness[j] = Boolean.TRUE;
- break;
- } else if (CharOperation.equals(typeName, nullableAnnotationName)) {
- if (methodBinding.parameterNonNullness == null)
- methodBinding.parameterNonNullness = new Boolean[numVisibleParams];
- methodBinding.parameterNonNullness[j] = Boolean.FALSE;
- break;
+ explicitNullness = false;
+ if (numParamAnnotations > 0) {
+ int startIndex = numParamAnnotations - numVisibleParams;
+ IBinaryAnnotation[] paramAnnotations = method.getParameterAnnotations(j+startIndex);
+ if (paramAnnotations != null) {
+ for (int i = 0; i < paramAnnotations.length; i++) {
+ char[] annotationTypeName = paramAnnotations[i].getTypeName();
+ if (annotationTypeName[0] != Util.C_RESOLVED)
+ continue;
+ char[][] typeName = CharOperation.splitOn('/', annotationTypeName, 1, annotationTypeName.length-1); // cut of leading 'L' and trailing ';'
+ if (CharOperation.equals(typeName, nonNullAnnotationName)) {
+ if (methodBinding.parameterNonNullness == null)
+ methodBinding.parameterNonNullness = new Boolean[numVisibleParams];
+ methodBinding.parameterNonNullness[j] = Boolean.TRUE;
+ explicitNullness = true;
+ break;
+ } else if (CharOperation.equals(typeName, nullableAnnotationName)) {
+ if (methodBinding.parameterNonNullness == null)
+ methodBinding.parameterNonNullness = new Boolean[numVisibleParams];
+ methodBinding.parameterNonNullness[j] = Boolean.FALSE;
+ explicitNullness = true;
+ break;
+ }
}
}
}
+ if (!explicitNullness && currentDefault == NONNULL_BY_DEFAULT) {
+ if (methodBinding.parameterNonNullness == null)
+ methodBinding.parameterNonNullness = new Boolean[numVisibleParams];
+ methodBinding.parameterNonNullness[j] = Boolean.TRUE;
+ }
}
}
}
-void scanPackageInfoForNullDefaultAnnotation(IBinaryType binaryType) {
+void scanTypeForNullDefaultAnnotation(IBinaryType binaryType) {
char[][] nonNullByDefaultAnnotationName = this.environment.getNonNullByDefaultAnnotationName();
if (nonNullByDefaultAnnotationName == null)
return; // not well-configured to use null annotations
IBinaryAnnotation[] annotations = binaryType.getAnnotations();
if (annotations != null) {
+ long annotationBit = 0L;
+ int nullness = NO_NULL_DEFAULT;
int length = annotations.length;
for (int i = 0; i < length; i++) {
char[] annotationTypeName = annotations[i].getTypeName();
@@ -1659,13 +1685,28 @@
&& !((BooleanConstant)value).booleanValue())
{
// parameter is 'false': this means we cancel defaults from outer scopes:
- this.getPackage().nullnessDefaultAnnotation = ReferenceBinding.NULL_UNSPECIFIED;
- return;
+ annotationBit = TagBits.AnnotationNullUnspecifiedByDefault;
+ nullness = NULL_UNSPECIFIED_BY_DEFAULT;
+ break;
}
}
- this.getPackage().nullnessDefaultAnnotation =
- this.environment.getNullAnnotationBinding(TagBits.AnnotationNonNull, false/*resolve*/);
- return;
+ annotationBit = TagBits.AnnotationNonNullByDefault;
+ nullness = NONNULL_BY_DEFAULT;
+ break;
+ }
+ }
+ if (annotationBit != 0L) {
+ this.tagBits |= annotationBit;
+ if (CharOperation.equals(this.sourceName(), TypeConstants.PACKAGE_INFO_NAME))
+ this.getPackage().defaultNullness = nullness;
+ } else {
+ switch (this.getPackage().defaultNullness) {
+ case NONNULL_BY_DEFAULT :
+ this.tagBits |= TagBits.AnnotationNonNullByDefault;
+ break;
+ case NULL_UNSPECIFIED_BY_DEFAULT :
+ this.tagBits |= TagBits.AnnotationNullUnspecifiedByDefault;
+ break;
}
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.java
index ea41433..f4c04c2 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.java
@@ -10,6 +10,8 @@
* IBM Corporation - initial API and implementation
* Fraunhofer FIRST - extended API and implementation
* Technical University Berlin - extended API and implementation
+ * Stephan Herrmann - Contribution for
+ * bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -68,6 +70,11 @@
public static final MethodBinding[] UNINITIALIZED_METHODS = new MethodBinding[0];
public static final ReferenceBinding[] UNINITIALIZED_REFERENCE_TYPES = new ReferenceBinding[0];
+ // Nullness defaults:
+ public static final int NO_NULL_DEFAULT = 0;
+ public static final int NULL_UNSPECIFIED_BY_DEFAULT = 1;
+ public static final int NONNULL_BY_DEFAULT = 2;
+
/*
* Answer the receiver's binding type from Binding.BindingID.
*/
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 ba128f1..5df6a31 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
@@ -14,6 +14,8 @@
* bug 349326 - [1.7] new warning for missing try-with-resources
* bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points
* bug 358903 - Filter practically unimportant resource leak warnings
+ * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+ * bug 370639 - [compiler][resource] restore the default for resource leak warnings
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -28,6 +30,7 @@
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration.WrapperKind;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
@@ -1156,11 +1159,12 @@
* At the end of a block check the closing-status of all tracked closeables that are declared in this block.
* Also invoked when entering unreachable code.
*/
-public void checkUnclosedCloseables(FlowInfo flowInfo, ASTNode location, BlockScope locationScope) {
+public void checkUnclosedCloseables(FlowInfo flowInfo, FlowContext flowContext, ASTNode location, BlockScope locationScope) {
+ if (!compilerOptions().analyseResourceLeaks) return;
if (this.trackingVariables == null) {
// at a method return we also consider enclosing scopes
if (location != null && this.parent instanceof BlockScope)
- ((BlockScope) this.parent).checkUnclosedCloseables(flowInfo, location, locationScope);
+ ((BlockScope) this.parent).checkUnclosedCloseables(flowInfo, flowContext, location, locationScope);
return;
}
if (location != null && flowInfo.reachMode() != 0) return;
@@ -1177,9 +1181,14 @@
continue;
}
- if (location != null && trackingVar.originalBinding != null && flowInfo.isDefinitelyNull(trackingVar.originalBinding))
- continue; // reporting against a specific location, resource is null at this flow, don't complain
-
+ if (location != null && trackingVar.hasDefinitelyNoResource(flowInfo)) {
+ continue; // reporting against a specific location, there is no resource at this flow, don't complain
+ }
+
+ if (location != null && flowContext != null && flowContext.recordExitAgainstResource(this, flowInfo, trackingVar, location)) {
+ continue; // handled by the flow context
+ }
+
// compute the most specific null status for this resource,
int status = trackingVar.findMostSpecificStatus(flowInfo, this, locationScope);
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 b82025b..f8ec700 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
@@ -139,6 +139,7 @@
public TypeDeclaration referenceContext;
public TypeReference superTypeReference;
java.util.ArrayList deferredBoundChecks;
+
public ClassScope(Scope parent, TypeDeclaration context) {
super(Scope.CLASS_SCOPE, parent);
this.referenceContext = context;
@@ -179,7 +180,6 @@
}
}
}
- this.referenceContext.binding.cumulativeFieldCount += outerMostMethodScope().analysisIndex;
connectMemberTypes();
buildFieldsAndMethods();
//{ObjectTeams: catchup also in OT-specific process (see class comment concerning local types in Dependencies):
@@ -271,7 +271,6 @@
// remove duplicate fields
if (count != fieldBindings.length)
System.arraycopy(fieldBindings, 0, fieldBindings = new FieldBinding[count], 0, count);
- sourceType.cumulativeFieldCount += count;
sourceType.tagBits &= ~(TagBits.AreFieldsSorted|TagBits.AreFieldsComplete); // in case some static imports reached already into this type
sourceType.setFields(fieldBindings);
}
@@ -412,7 +411,6 @@
checkParameterizedTypeBounds();
checkParameterizedSuperTypeCollisions();
}
- this.referenceContext.binding.cumulativeFieldCount += outerMostMethodScope().analysisIndex;
buildFieldsAndMethods();
//{ObjectTeams: catchup also in OT-specific process (see class comment concerning local types in Dependencies).
if (this.referenceContext.isRole()) {
@@ -842,8 +840,6 @@
fieldDeclaration, null, fieldDeclaration.modifiers|ExtraCompilerModifiers.AccUnresolved, sourceType);
sourceType.addField(fieldBinding);
- sourceType.cumulativeFieldCount++;
- this.referenceContext.updateMaxFieldCount();
checkAndSetModifiersForField(fieldBinding, fieldDeclaration);
// FIXME(SH): does this improve robustness?
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/FieldBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/FieldBinding.java
index 5d20c1d..28818d7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/FieldBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/FieldBinding.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 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
@@ -351,13 +351,6 @@
return originalField.tagBits;
}
-public int getAnalysisId(int maxFieldCount) {
- TypeBinding original = this.declaringClass.original();
- if (original instanceof SourceTypeBinding)
- return ((SourceTypeBinding)original).fieldAnalysisOffset + this.id;
- return this.id;
-}
-
public final boolean isDefault() {
return !isPublic() && !isProtected() && !isPrivate();
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
index 8951528..8e8fa94 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 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,6 +12,7 @@
* Stephan Herrmann - contributions for
* bug 337868 - [compiler][model] incomplete support for package-info.java when using SearchableEnvironment
* bug 186342 - [compiler][null] Using annotations for null checking
+ * bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -1301,59 +1302,6 @@
return this.globalOptions.nonNullByDefaultAnnotationName;
}
-/**
- * Answer the type binding representing the null-annotation identified by the given tag bits.
- * @param annotationTagBit tag bits potentially denoting a null-annotation
- * @param resolve should the resulting type binding be resolved?
- * @return the corresponding annotation type binding
- * or <code>null</code> if no annotation bits are contained in the given tag bits.
- */
-public TypeBinding getNullAnnotationBinding(long annotationTagBit, boolean resolve) {
- char[][] name = null;
- if (annotationTagBit == TagBits.AnnotationNonNull)
- name = getNonNullAnnotationName();
- else if (annotationTagBit == TagBits.AnnotationNullable)
- name = getNullableAnnotationName();
- else
- return null;
- if (resolve)
- return getType(name);
- else
- return getTypeFromCompoundName(name, false, false);
-}
-
-/**
- * Inspect the given tag bits and answer a corresponding null annotation type binding
- * @param defaultTagBit tag bits representing the default applicable at the current code location
- * @param resolve should the resulting type binding be resolved?
- * @return the corresponding concrete annotation type binding (<code>@NonNull</code> or <code>@Nullable</code>)
- * or <code>null</code> if no bits of a default-annotation are contained in the given tag bits.
- */
-public TypeBinding getNullAnnotationBindingFromDefault(long defaultTagBit, boolean resolve) {
- if ((defaultTagBit & TagBits.AnnotationNullUnspecifiedByDefault) != 0)
- return ReferenceBinding.NULL_UNSPECIFIED;
- if ((defaultTagBit & TagBits.AnnotationNonNullByDefault) != 0)
- return getNullAnnotationBinding(TagBits.AnnotationNonNull, resolve);
- return null;
-}
-
-TypeBinding getNullAnnotationResolved(TypeBinding nullAnnotation, Scope scope) {
- // avoid unspecific error "The type in.valid cannot be resolved. It is indirectly referenced from required .class files"
- boolean tolerateMissing = this.mayTolerateMissingType;
- this.mayTolerateMissingType = true;
- try {
- nullAnnotation = BinaryTypeBinding.resolveType(nullAnnotation, this, false);
- } finally {
- this.mayTolerateMissingType = tolerateMissing;
- }
- if (nullAnnotation instanceof MissingTypeBinding) {
- // convert error into a specific one:
- scope.problemReporter().missingNullAnnotationType(((MissingTypeBinding)nullAnnotation).compoundName);
- return null;
- }
- return nullAnnotation;
-}
-
/* Answer the top level package named name if it exists in the cache.
* Answer theNotFoundPackage if it could not be resolved the first time
* it was looked up, otherwise answer null.
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 d49b303..da2f175 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
@@ -14,6 +14,7 @@
* bug 367203 - [compiler][null] detect assigning null to nonnull argument
* bug 365519 - editorial cleanup after bug 186342 and bug 365387
* bug 365662 - [compiler][null] warn on contradictory and redundant null annotations
+ * bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -854,10 +855,9 @@
}
/**
- * After method verifier has finished, fill in missing nullness values from the applicable default.
- * @param annotationBinding the null annotation specified to be the default at the current code location.
+ * After method verifier has finished, fill in missing @NonNull specification from the applicable default.
*/
-protected void fillInDefaultNonNullness(TypeBinding annotationBinding) {
+protected void fillInDefaultNonNullness() {
if (this.parameterNonNullness == null)
this.parameterNonNullness = new Boolean[this.parameters.length];
AbstractMethodDeclaration sourceMethod = sourceMethod();
@@ -870,9 +870,7 @@
added = true;
this.parameterNonNullness[i] = Boolean.TRUE;
if (sourceMethod != null) {
- Argument argument = sourceMethod.arguments[i];
- sourceMethod.addParameterNonNullAnnotation(argument, (ReferenceBinding)annotationBinding);
- argument.binding.tagBits |= TagBits.AnnotationNonNull;
+ sourceMethod.arguments[i].binding.tagBits |= TagBits.AnnotationNonNull;
}
} else if (this.parameterNonNullness[i].booleanValue()) {
sourceMethod.scope.problemReporter().nullAnnotationIsRedundant(sourceMethod, i);
@@ -885,8 +883,6 @@
&& (this.tagBits & (TagBits.AnnotationNonNull|TagBits.AnnotationNullable)) == 0)
{
this.tagBits |= TagBits.AnnotationNonNull;
- if (sourceMethod != null)
- sourceMethod.addNonNullAnnotation((ReferenceBinding)annotationBinding);
} else if ((this.tagBits & TagBits.AnnotationNonNull) != 0) {
sourceMethod.scope.problemReporter().nullAnnotationIsRedundant(sourceMethod, -1/*signifies method return*/);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java
index a7cc75a..0c6cd25 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java
@@ -13,6 +13,7 @@
* Stephan Herrmann - Contributions for
* bug 186342 - [compiler][null] Using annotations for null checking
* bug 365519 - editorial cleanup after bug 186342 and bug 365387
+ * bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -35,8 +36,9 @@
HashtableOfType knownTypes;
HashtableOfPackage knownPackages;
- // annotation type binding representing the default that has been defined for this package (using @NonNullByDefault)
- protected TypeBinding nullnessDefaultAnnotation;
+ // code representing the default that has been defined for this package (using @NonNullByDefault)
+ // one of Binding.{NO_NULL_DEFAULT,NULL_UNSPECIFIED_BY_DEFAULT,NONNULL_BY_DEFAULT}
+ protected int defaultNullness = NO_NULL_DEFAULT;
protected PackageBinding() {
// for creating problem package
@@ -297,12 +299,6 @@
}
}
-public TypeBinding getNullnessDefaultAnnotation(Scope scope) {
- if (this.nullnessDefaultAnnotation instanceof UnresolvedReferenceBinding)
- return this.nullnessDefaultAnnotation = this.environment.getNullAnnotationResolved(this.nullnessDefaultAnnotation, scope);
- return this.nullnessDefaultAnnotation;
-}
-
public char[] readableName() /*java.lang*/ {
return CharOperation.concatWith(this.compoundName, '.');
}
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 22e8ec9..fe876d5 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
@@ -14,6 +14,7 @@
* bug 186342 - [compiler][null] Using annotations for null checking
* bug 365519 - editorial cleanup after bug 186342 and bug 365387
* bug 358903 - Filter practically unimportant resource leak warnings
+ * bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -101,14 +102,6 @@
public boolean hasTypeBit(int bit) { return false; }
};
- /**
- * This faked annotation type binding marks types with unspecified nullness.
- * For use in {@link PackageBinding#nullnessDefaultAnnotation} and SourceTypeBinding#nullnessDefaultAnnotation
- */
- final static ReferenceBinding NULL_UNSPECIFIED = new ReferenceBinding() { /* faked type binding */
- public boolean hasTypeBit(int bit) { return false; }
- };
-
private static final Comparator FIELD_COMPARATOR = new Comparator() {
public int compare(Object o1, Object o2) {
char[] n1 = ((FieldBinding) o1).name;
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 07d1434..dc57ce7 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
@@ -16,6 +16,8 @@
* bug 365836 - [compiler][null] Incomplete propagation of null defaults.
* bug 365519 - editorial cleanup after bug 186342 and bug 365387
* bug 365662 - [compiler][null] warn on contradictory and redundant null annotations
+ * bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
+ * bug 366063 - Compiler should not add synthetic @NonNull annotations
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -107,8 +109,6 @@
// SH}
public ClassScope scope;
- public int fieldAnalysisOffset; // an offset for ids of fields of this class (id to be used for flow analysis)
- public int cumulativeFieldCount; // cumulative field count from all enclosing types, used to build unique field id's for member types.
// Synthetics are separated into 4 categories: methods, super methods, fields, class literals and bridge methods
// if a new category is added, also increment MAX_SYNTHETICS
@@ -139,7 +139,7 @@
private SimpleLookupTable storedAnnotations = null; // keys are this ReferenceBinding & its fields and methods, value is an AnnotationHolder
- private TypeBinding nullnessDefaultAnnotation;
+ private int defaultNullness;
private int nullnessDefaultInitialized = 0; // 0: nothing; 1: type; 2: package
public SourceTypeBinding(char[][] compoundName, PackageBinding fPackage, ClassScope scope) {
@@ -158,7 +158,6 @@
// SH}
this.sourceName = scope.referenceContext.name;
this.scope = scope;
- this.cumulativeFieldCount = 0;
//{ObjectTeams: ROFI create a package binding for our role files (if any):
maybeSetTeamPackage(compoundName, fPackage, scope.environment());
// SH}
@@ -2376,9 +2375,9 @@
if (methodDecl != null) {
if (method.parameters != Binding.NO_PARAMETERS)
methodDecl.createArgumentBindings();
- TypeBinding annotationBinding = findDefaultNullness(methodDecl.scope, methodDecl.scope.environment());
- if (annotationBinding != null && annotationBinding.id == TypeIds.T_ConfiguredAnnotationNonNull)
- method.fillInDefaultNonNullness(annotationBinding);
+ if ((findNonNullDefault(methodDecl.scope, methodDecl.scope.environment()) == NONNULL_BY_DEFAULT)) {
+ method.fillInDefaultNonNullness();
+ }
}
}
private void evaluateNullAnnotations(long annotationTagBits) {
@@ -2386,18 +2385,16 @@
return;
this.nullnessDefaultInitialized = 1;
// transfer nullness info from tagBits to this.nullnessDefaultAnnotation
- TypeBinding defaultAnnotation = getPackage().environment
- .getNullAnnotationBindingFromDefault(annotationTagBits, false/*resolve*/);
- if (defaultAnnotation != null) {
+ int newDefaultNullness = NO_NULL_DEFAULT;
+ if ((annotationTagBits & TagBits.AnnotationNullUnspecifiedByDefault) != 0)
+ newDefaultNullness = NULL_UNSPECIFIED_BY_DEFAULT;
+ else if ((annotationTagBits & TagBits.AnnotationNonNullByDefault) != 0)
+ newDefaultNullness = NONNULL_BY_DEFAULT;
+ if (newDefaultNullness != NO_NULL_DEFAULT) {
if (CharOperation.equals(this.sourceName, TypeConstants.PACKAGE_INFO_NAME)) {
- getPackage().nullnessDefaultAnnotation = defaultAnnotation;
- long globalDefault = this.scope.compilerOptions().defaultNonNullness;
- if (globalDefault == TagBits.AnnotationNonNull && (annotationTagBits & TagBits.AnnotationNonNullByDefault) != 0) {
- TypeDeclaration typeDecl = this.scope.referenceContext;
- this.scope.problemReporter().nullDefaultAnnotationIsRedundant(typeDecl, typeDecl.annotations, null);
- }
+ getPackage().defaultNullness = newDefaultNullness;
} else {
- this.nullnessDefaultAnnotation = defaultAnnotation;
+ this.defaultNullness = newDefaultNullness;
TypeDeclaration typeDecl = this.scope.referenceContext;
long nullDefaultBits = annotationTagBits & (TagBits.AnnotationNullUnspecifiedByDefault|TagBits.AnnotationNonNullByDefault);
checkRedundantNullnessDefaultRecurse(typeDecl, typeDecl.annotations, nullDefaultBits);
@@ -2406,25 +2403,20 @@
}
protected void checkRedundantNullnessDefaultRecurse(ASTNode location, Annotation[] annotations, long annotationTagBits) {
- if (this.fPackage.nullnessDefaultAnnotation != null) {
- if ((this.fPackage.nullnessDefaultAnnotation.id == TypeIds.T_ConfiguredAnnotationNonNull
+ if (this.fPackage.defaultNullness != NO_NULL_DEFAULT) {
+ if ((this.fPackage.defaultNullness == NONNULL_BY_DEFAULT
&& ((annotationTagBits & TagBits.AnnotationNonNullByDefault) != 0))) {
this.scope.problemReporter().nullDefaultAnnotationIsRedundant(location, annotations, this.fPackage);
}
return;
}
- long globalDefault = this.scope.compilerOptions().defaultNonNullness;
- if (globalDefault == TagBits.AnnotationNonNull && annotationTagBits == TagBits.AnnotationNonNullByDefault) {
- this.scope.problemReporter().nullDefaultAnnotationIsRedundant(location, annotations, null);
- }
}
// return: should caller continue searching?
protected boolean checkRedundantNullnessDefaultOne(ASTNode location, Annotation[] annotations, long annotationTagBits) {
- TypeBinding thisDefault = this.nullnessDefaultAnnotation;
- if (thisDefault != null) {
- if (thisDefault.id == TypeIds.T_ConfiguredAnnotationNonNull
- && ((annotationTagBits & TagBits.AnnotationNonNullByDefault) != 0)) {
+ int thisDefault = this.defaultNullness;
+ if (thisDefault == NONNULL_BY_DEFAULT) {
+ if ((annotationTagBits & TagBits.AnnotationNonNullByDefault) != 0) {
this.scope.problemReporter().nullDefaultAnnotationIsRedundant(location, annotations, this);
}
return false; // different default means inner default is not redundant -> we're done
@@ -2432,42 +2424,35 @@
return true;
}
-private TypeBinding getNullnessDefaultAnnotation() {
- if (this.nullnessDefaultAnnotation instanceof UnresolvedReferenceBinding)
- this.nullnessDefaultAnnotation = this.scope.environment().getNullAnnotationResolved(this.nullnessDefaultAnnotation, this.scope);
- return this.nullnessDefaultAnnotation;
-}
/**
* Answer the nullness default applicable at the given method binding.
- * Possible values:<ul>
- * <li>the type binding for @NonNulByDefault</li>
- * <li>the synthetic type {@link ReferenceBinding#NULL_UNSPECIFIED} if a default from outer scope has been canceled</li>
- * <li>null if no default has been defined</li>
- * </ul>
+ * Possible values: {@link Binding#NO_NULL_DEFAULT}, {@link Binding#NULL_UNSPECIFIED_BY_DEFAULT}, {@link Binding#NONNULL_BY_DEFAULT}.
* @param currentScope where to start search for lexically enclosing default
- * @param environment gateway to options and configured annotation types
+ * @param environment gateway to options
*/
-private TypeBinding findDefaultNullness(Scope currentScope, LookupEnvironment environment) {
+private int findNonNullDefault(Scope currentScope, LookupEnvironment environment) {
// find the applicable default inside->out:
SourceTypeBinding currentType = null;
- TypeBinding annotationBinding;
while (currentScope != null) {
switch (currentScope.kind) {
case Scope.METHOD_SCOPE:
AbstractMethodDeclaration referenceMethod = ((MethodScope)currentScope).referenceMethod();
if (referenceMethod != null && referenceMethod.binding != null) {
- annotationBinding = environment.getNullAnnotationBindingFromDefault(referenceMethod.binding.tagBits, true/*resolve*/);
- if (annotationBinding != null)
- return annotationBinding;
+ long methodTagBits = referenceMethod.binding.tagBits;
+ if ((methodTagBits & TagBits.AnnotationNonNullByDefault) != 0)
+ return NONNULL_BY_DEFAULT;
+ if ((methodTagBits & TagBits.AnnotationNullUnspecifiedByDefault) != 0)
+ return NULL_UNSPECIFIED_BY_DEFAULT;
}
break;
case Scope.CLASS_SCOPE:
currentType = ((ClassScope)currentScope).referenceContext.binding;
if (currentType != null) {
- annotationBinding = currentType.getNullnessDefaultAnnotation();
- if (annotationBinding != null)
- return annotationBinding;
+ int foundDefaultNullness = currentType.defaultNullness;
+ if (foundDefaultNullness != NO_NULL_DEFAULT) {
+ return foundDefaultNullness;
+ }
}
break;
}
@@ -2476,28 +2461,13 @@
// package
if (currentType != null) {
- annotationBinding = currentType.getPackage().getNullnessDefaultAnnotation(this.scope);
- if (annotationBinding != null)
- return annotationBinding;
+ int foundDefaultNullness = currentType.getPackage().defaultNullness;
+ if (foundDefaultNullness != NO_NULL_DEFAULT) {
+ return foundDefaultNullness;
+ }
}
- // global
- long defaultNullness = environment.globalOptions.defaultNonNullness;
- if (defaultNullness != 0) {
- // we have a default, so we need an annotation type to record this during compile and in the byte code
- annotationBinding = environment.getNullAnnotationBinding(defaultNullness, true/*resolve*/);
- if (annotationBinding != null)
- return annotationBinding;
-
- // on this branch default was not defined using an annotation, thus annotation type can still be missing
- if (defaultNullness == TagBits.AnnotationNonNull)
- this.scope.problemReporter().missingNullAnnotationType(environment.getNonNullAnnotationName());
- else
- this.scope.problemReporter().abortDueToInternalError("Illegal default nullness value: "+defaultNullness); //$NON-NLS-1$
- // reset default to avoid duplicate errors:
- environment.globalOptions.defaultNonNullness = 0;
- }
- return null;
+ return NO_NULL_DEFAULT;
}
//{ObjectTeams: helper to find args allowing baseclass decapsulation:
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/VariableBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/VariableBinding.java
index ae9a809..d11f88d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/VariableBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/VariableBinding.java
@@ -60,10 +60,6 @@
return this.constant;
}
- public int getAnalysisId(int maxFieldCount) {
- return this.id + maxFieldCount;
- }
-
public abstract AnnotationBinding[] getAnnotations();
public final boolean isBlankFinal(){
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 7276e84..a542af5 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 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
@@ -921,6 +921,7 @@
// used for recovery
protected int lastJavadocEnd;
public org.eclipse.jdt.internal.compiler.ReadManager readManager;
+private boolean shouldDeferRecovery = false; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=291040
//{ObjectTeams: context info while parsing separate role files:
@@ -3042,6 +3043,7 @@
// ClassBodyopt ::= $empty
pushOnAstStack(null);
this.endPosition = this.rParenPos;
+ this.shouldDeferRecovery = false;
}
protected void consumeClassDeclaration() {
// ClassDeclaration ::= ClassHeader ClassBody
@@ -3998,6 +4000,7 @@
iteratorForStatement.sourceEnd = localDeclaration.declarationSourceEnd;
}
protected void consumeEnterAnonymousClassBody(boolean qualified) {
+ this.shouldDeferRecovery = false;
// EnterAnonymousClassBody ::= $empty
TypeReference typeReference = getTypeReference(0);
@@ -7013,7 +7016,6 @@
// PushRPAREN ::= ')'
pushOnIntStack(this.rParenPos);
}
-//CLOVER OFF
// This method is part of an automatic generation : do NOT edit-modify
protected void consumeRule(int act) {
switch ( act ) {
@@ -8027,7 +8029,7 @@
consumeClassInstanceCreationExpressionWithTypeArguments();
break;
- case 486 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new ClassType LPAREN"); } //$NON-NLS-1$
+ case 486 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new ClassType..."); } //$NON-NLS-1$
consumeClassInstanceCreationExpression();
break;
@@ -8047,1110 +8049,1115 @@
consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() ;
break;
- case 491 : if (DEBUG) { System.out.println("ClassInstanceCreationExpressionName ::= Name DOT"); } //$NON-NLS-1$
+ case 491 : if (DEBUG) { System.out.println("EnterInstanceCreationArgumentList ::="); } //$NON-NLS-1$
+ consumeEnterInstanceCreationArgumentList();
+ break;
+
+ case 492 : if (DEBUG) { System.out.println("ClassInstanceCreationExpressionName ::= Name DOT"); } //$NON-NLS-1$
consumeClassInstanceCreationExpressionName() ;
break;
- case 492 : if (DEBUG) { System.out.println("UnqualifiedClassBodyopt ::="); } //$NON-NLS-1$
+ case 493 : if (DEBUG) { System.out.println("UnqualifiedClassBodyopt ::="); } //$NON-NLS-1$
consumeClassBodyopt();
break;
- case 494 : if (DEBUG) { System.out.println("UnqualifiedEnterAnonymousClassBody ::="); } //$NON-NLS-1$
+ case 495 : if (DEBUG) { System.out.println("UnqualifiedEnterAnonymousClassBody ::="); } //$NON-NLS-1$
consumeEnterAnonymousClassBody(false);
break;
- case 495 : if (DEBUG) { System.out.println("QualifiedClassBodyopt ::="); } //$NON-NLS-1$
+ case 496 : if (DEBUG) { System.out.println("QualifiedClassBodyopt ::="); } //$NON-NLS-1$
consumeClassBodyopt();
break;
- case 497 : if (DEBUG) { System.out.println("QualifiedEnterAnonymousClassBody ::="); } //$NON-NLS-1$
+ case 498 : if (DEBUG) { System.out.println("QualifiedEnterAnonymousClassBody ::="); } //$NON-NLS-1$
consumeEnterAnonymousClassBody(true);
break;
- case 499 : if (DEBUG) { System.out.println("ArgumentList ::= ArgumentList COMMA Expression"); } //$NON-NLS-1$
+ case 500 : if (DEBUG) { System.out.println("ArgumentList ::= ArgumentList COMMA Expression"); } //$NON-NLS-1$
consumeArgumentList();
break;
- case 500 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new PrimitiveType..."); } //$NON-NLS-1$
+ case 501 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new PrimitiveType..."); } //$NON-NLS-1$
consumeArrayCreationHeader();
break;
- case 501 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new ClassOrInterfaceType..."); } //$NON-NLS-1$
+ case 502 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new ClassOrInterfaceType..."); } //$NON-NLS-1$
consumeArrayCreationHeader();
break;
- case 502 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); } //$NON-NLS-1$
+ case 503 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); } //$NON-NLS-1$
consumeArrayCreationExpressionWithoutInitializer();
break;
- case 503 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new PrimitiveType"); } //$NON-NLS-1$
+ case 504 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new PrimitiveType"); } //$NON-NLS-1$
consumeArrayCreationExpressionWithInitializer();
break;
- case 504 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); } //$NON-NLS-1$
+ case 505 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); } //$NON-NLS-1$
consumeArrayCreationExpressionWithoutInitializer();
break;
- case 505 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new..."); } //$NON-NLS-1$
+ case 506 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new..."); } //$NON-NLS-1$
consumeArrayCreationExpressionWithInitializer();
break;
- case 507 : if (DEBUG) { System.out.println("DimWithOrWithOutExprs ::= DimWithOrWithOutExprs..."); } //$NON-NLS-1$
+ case 508 : if (DEBUG) { System.out.println("DimWithOrWithOutExprs ::= DimWithOrWithOutExprs..."); } //$NON-NLS-1$
consumeDimWithOrWithOutExprs();
break;
- case 509 : if (DEBUG) { System.out.println("DimWithOrWithOutExpr ::= LBRACKET RBRACKET"); } //$NON-NLS-1$
+ case 510 : if (DEBUG) { System.out.println("DimWithOrWithOutExpr ::= LBRACKET RBRACKET"); } //$NON-NLS-1$
consumeDimWithOrWithOutExpr();
break;
- case 510 : if (DEBUG) { System.out.println("Dims ::= DimsLoop"); } //$NON-NLS-1$
+ case 511 : if (DEBUG) { System.out.println("Dims ::= DimsLoop"); } //$NON-NLS-1$
consumeDims();
break;
- case 513 : if (DEBUG) { System.out.println("OneDimLoop ::= LBRACKET RBRACKET"); } //$NON-NLS-1$
+ case 514 : if (DEBUG) { System.out.println("OneDimLoop ::= LBRACKET RBRACKET"); } //$NON-NLS-1$
consumeOneDimLoop();
break;
- case 514 : if (DEBUG) { System.out.println("FieldAccess ::= Primary DOT Identifier"); } //$NON-NLS-1$
+ case 515 : if (DEBUG) { System.out.println("FieldAccess ::= Primary DOT Identifier"); } //$NON-NLS-1$
consumeFieldAccess(false);
break;
- case 515 : if (DEBUG) { System.out.println("FieldAccess ::= super DOT Identifier"); } //$NON-NLS-1$
+ case 516 : if (DEBUG) { System.out.println("FieldAccess ::= super DOT Identifier"); } //$NON-NLS-1$
consumeFieldAccess(true);
break;
- case 516 : if (DEBUG) { System.out.println("MethodInvocation ::= Name LPAREN ArgumentListopt RPAREN"); } //$NON-NLS-1$
+ case 517 : if (DEBUG) { System.out.println("MethodInvocation ::= Name LPAREN ArgumentListopt RPAREN"); } //$NON-NLS-1$
consumeMethodInvocationName();
break;
- case 517 : if (DEBUG) { System.out.println("MethodInvocation ::= Name DOT OnlyTypeArguments..."); } //$NON-NLS-1$
+ case 518 : if (DEBUG) { System.out.println("MethodInvocation ::= Name DOT OnlyTypeArguments..."); } //$NON-NLS-1$
consumeMethodInvocationNameWithTypeArguments();
break;
- case 518 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT OnlyTypeArguments..."); } //$NON-NLS-1$
+ case 519 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT OnlyTypeArguments..."); } //$NON-NLS-1$
consumeMethodInvocationPrimaryWithTypeArguments();
break;
- case 519 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT Identifier LPAREN..."); } //$NON-NLS-1$
+ case 520 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT Identifier LPAREN..."); } //$NON-NLS-1$
consumeMethodInvocationPrimary();
break;
- case 520 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT OnlyTypeArguments..."); } //$NON-NLS-1$
+ case 521 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT OnlyTypeArguments..."); } //$NON-NLS-1$
consumeMethodInvocationSuperWithTypeArguments();
break;
- case 521 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT Identifier LPAREN..."); } //$NON-NLS-1$
+ case 522 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT Identifier LPAREN..."); } //$NON-NLS-1$
consumeMethodInvocationSuper();
break;
- case 522 : if (DEBUG) { System.out.println("MethodInvocation ::= tsuper DOT Identifier LPAREN..."); } //$NON-NLS-1$
+ case 523 : if (DEBUG) { System.out.println("MethodInvocation ::= tsuper DOT Identifier LPAREN..."); } //$NON-NLS-1$
consumeMethodInvocationTSuper(UNQUALIFIED);
break;
- case 523 : if (DEBUG) { System.out.println("MethodInvocation ::= tsuper DOT OnlyTypeArguments..."); } //$NON-NLS-1$
+ case 524 : if (DEBUG) { System.out.println("MethodInvocation ::= tsuper DOT OnlyTypeArguments..."); } //$NON-NLS-1$
consumeMethodInvocationTSuperWithTypeArguments(0);
break;
- case 524 : if (DEBUG) { System.out.println("MethodInvocation ::= Name DOT tsuper DOT Identifier..."); } //$NON-NLS-1$
+ case 525 : if (DEBUG) { System.out.println("MethodInvocation ::= Name DOT tsuper DOT Identifier..."); } //$NON-NLS-1$
consumeMethodInvocationTSuper(QUALIFIED);
break;
- case 525 : if (DEBUG) { System.out.println("MethodInvocation ::= Name DOT tsuper DOT..."); } //$NON-NLS-1$
+ case 526 : if (DEBUG) { System.out.println("MethodInvocation ::= Name DOT tsuper DOT..."); } //$NON-NLS-1$
consumeMethodInvocationTSuperWithTypeArguments(2);
break;
- case 526 : if (DEBUG) { System.out.println("MethodInvocation ::= base DOT Identifier LPAREN..."); } //$NON-NLS-1$
+ case 527 : if (DEBUG) { System.out.println("MethodInvocation ::= base DOT Identifier LPAREN..."); } //$NON-NLS-1$
consumeMethodInvocationBase(false);
break;
- case 527 : if (DEBUG) { System.out.println("MethodInvocation ::= base DOT OnlyTypeArguments..."); } //$NON-NLS-1$
+ case 528 : if (DEBUG) { System.out.println("MethodInvocation ::= base DOT OnlyTypeArguments..."); } //$NON-NLS-1$
consumeMethodInvocationBaseWithTypeArguments(false);
break;
- case 528 : if (DEBUG) { System.out.println("MethodInvocation ::= base DOT super DOT Identifier..."); } //$NON-NLS-1$
+ case 529 : if (DEBUG) { System.out.println("MethodInvocation ::= base DOT super DOT Identifier..."); } //$NON-NLS-1$
consumeMethodInvocationBase(true);
break;
- case 529 : if (DEBUG) { System.out.println("MethodInvocation ::= base DOT super DOT..."); } //$NON-NLS-1$
+ case 530 : if (DEBUG) { System.out.println("MethodInvocation ::= base DOT super DOT..."); } //$NON-NLS-1$
consumeMethodInvocationBaseWithTypeArguments(true);
break;
- case 530 : if (DEBUG) { System.out.println("ArrayAccess ::= Name LBRACKET Expression RBRACKET"); } //$NON-NLS-1$
+ case 531 : if (DEBUG) { System.out.println("ArrayAccess ::= Name LBRACKET Expression RBRACKET"); } //$NON-NLS-1$
consumeArrayAccess(true);
break;
- case 531 : if (DEBUG) { System.out.println("ArrayAccess ::= PrimaryNoNewArray LBRACKET Expression..."); } //$NON-NLS-1$
+ case 532 : if (DEBUG) { System.out.println("ArrayAccess ::= PrimaryNoNewArray LBRACKET Expression..."); } //$NON-NLS-1$
consumeArrayAccess(false);
break;
- case 532 : if (DEBUG) { System.out.println("ArrayAccess ::= ArrayCreationWithArrayInitializer..."); } //$NON-NLS-1$
+ case 533 : if (DEBUG) { System.out.println("ArrayAccess ::= ArrayCreationWithArrayInitializer..."); } //$NON-NLS-1$
consumeArrayAccess(false);
break;
- case 534 : if (DEBUG) { System.out.println("PostfixExpression ::= Name"); } //$NON-NLS-1$
+ case 535 : if (DEBUG) { System.out.println("PostfixExpression ::= Name"); } //$NON-NLS-1$
consumePostfixExpression();
break;
- case 537 : if (DEBUG) { System.out.println("PostIncrementExpression ::= PostfixExpression PLUS_PLUS"); } //$NON-NLS-1$
+ case 538 : if (DEBUG) { System.out.println("PostIncrementExpression ::= PostfixExpression PLUS_PLUS"); } //$NON-NLS-1$
consumeUnaryExpression(OperatorIds.PLUS,true);
break;
- case 538 : if (DEBUG) { System.out.println("PostDecrementExpression ::= PostfixExpression..."); } //$NON-NLS-1$
+ case 539 : if (DEBUG) { System.out.println("PostDecrementExpression ::= PostfixExpression..."); } //$NON-NLS-1$
consumeUnaryExpression(OperatorIds.MINUS,true);
break;
- case 539 : if (DEBUG) { System.out.println("PushPosition ::="); } //$NON-NLS-1$
+ case 540 : if (DEBUG) { System.out.println("PushPosition ::="); } //$NON-NLS-1$
consumePushPosition();
break;
- case 542 : if (DEBUG) { System.out.println("UnaryExpression ::= PLUS PushPosition UnaryExpression"); } //$NON-NLS-1$
+ case 543 : if (DEBUG) { System.out.println("UnaryExpression ::= PLUS PushPosition UnaryExpression"); } //$NON-NLS-1$
consumeUnaryExpression(OperatorIds.PLUS);
break;
- case 543 : if (DEBUG) { System.out.println("UnaryExpression ::= MINUS PushPosition UnaryExpression"); } //$NON-NLS-1$
+ case 544 : if (DEBUG) { System.out.println("UnaryExpression ::= MINUS PushPosition UnaryExpression"); } //$NON-NLS-1$
consumeUnaryExpression(OperatorIds.MINUS);
break;
- case 545 : if (DEBUG) { System.out.println("PreIncrementExpression ::= PLUS_PLUS PushPosition..."); } //$NON-NLS-1$
+ case 546 : if (DEBUG) { System.out.println("PreIncrementExpression ::= PLUS_PLUS PushPosition..."); } //$NON-NLS-1$
consumeUnaryExpression(OperatorIds.PLUS,false);
break;
- case 546 : if (DEBUG) { System.out.println("PreDecrementExpression ::= MINUS_MINUS PushPosition..."); } //$NON-NLS-1$
+ case 547 : if (DEBUG) { System.out.println("PreDecrementExpression ::= MINUS_MINUS PushPosition..."); } //$NON-NLS-1$
consumeUnaryExpression(OperatorIds.MINUS,false);
break;
- case 548 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= TWIDDLE PushPosition..."); } //$NON-NLS-1$
+ case 549 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= TWIDDLE PushPosition..."); } //$NON-NLS-1$
consumeUnaryExpression(OperatorIds.TWIDDLE);
break;
- case 549 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= NOT PushPosition..."); } //$NON-NLS-1$
+ case 550 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= NOT PushPosition..."); } //$NON-NLS-1$
consumeUnaryExpression(OperatorIds.NOT);
break;
- case 551 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN PrimitiveType Dimsopt..."); } //$NON-NLS-1$
+ case 552 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN PrimitiveType Dimsopt..."); } //$NON-NLS-1$
consumeCastExpressionWithPrimitiveType();
break;
- case 552 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); } //$NON-NLS-1$
+ case 553 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); } //$NON-NLS-1$
consumeCastExpressionWithGenericsArray();
break;
- case 553 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); } //$NON-NLS-1$
+ case 554 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); } //$NON-NLS-1$
consumeCastExpressionWithQualifiedGenericsArray();
break;
- case 554 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name PushRPAREN..."); } //$NON-NLS-1$
+ case 555 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name PushRPAREN..."); } //$NON-NLS-1$
consumeCastExpressionLL1();
break;
- case 555 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name Dims PushRPAREN..."); } //$NON-NLS-1$
+ case 556 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name Dims PushRPAREN..."); } //$NON-NLS-1$
consumeCastExpressionWithNameArray();
break;
- case 556 : if (DEBUG) { System.out.println("OnlyTypeArgumentsForCastExpression ::= OnlyTypeArguments"); } //$NON-NLS-1$
+ case 557 : if (DEBUG) { System.out.println("OnlyTypeArgumentsForCastExpression ::= OnlyTypeArguments"); } //$NON-NLS-1$
consumeOnlyTypeArgumentsForCastExpression();
break;
- case 557 : if (DEBUG) { System.out.println("InsideCastExpression ::="); } //$NON-NLS-1$
+ case 558 : if (DEBUG) { System.out.println("InsideCastExpression ::="); } //$NON-NLS-1$
consumeInsideCastExpression();
break;
- case 558 : if (DEBUG) { System.out.println("InsideCastExpressionLL1 ::="); } //$NON-NLS-1$
+ case 559 : if (DEBUG) { System.out.println("InsideCastExpressionLL1 ::="); } //$NON-NLS-1$
consumeInsideCastExpressionLL1();
break;
- case 559 : if (DEBUG) { System.out.println("InsideCastExpressionWithQualifiedGenerics ::="); } //$NON-NLS-1$
+ case 560 : if (DEBUG) { System.out.println("InsideCastExpressionWithQualifiedGenerics ::="); } //$NON-NLS-1$
consumeInsideCastExpressionWithQualifiedGenerics();
break;
- case 561 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); } //$NON-NLS-1$
- consumeBinaryExpression(OperatorIds.MULTIPLY);
- break;
-
case 562 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); } //$NON-NLS-1$
- consumeBinaryExpression(OperatorIds.DIVIDE);
+ consumeBinaryExpression(OperatorIds.MULTIPLY);
break;
case 563 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); } //$NON-NLS-1$
- consumeBinaryExpression(OperatorIds.REMAINDER);
- break;
-
- case 565 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression PLUS..."); } //$NON-NLS-1$
- consumeBinaryExpression(OperatorIds.PLUS);
- break;
-
- case 566 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression MINUS..."); } //$NON-NLS-1$
- consumeBinaryExpression(OperatorIds.MINUS);
- break;
-
- case 568 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression LEFT_SHIFT..."); } //$NON-NLS-1$
- consumeBinaryExpression(OperatorIds.LEFT_SHIFT);
- break;
-
- case 569 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression RIGHT_SHIFT..."); } //$NON-NLS-1$
- consumeBinaryExpression(OperatorIds.RIGHT_SHIFT);
- break;
-
- case 570 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression UNSIGNED_RIGHT_SHIFT"); } //$NON-NLS-1$
- consumeBinaryExpression(OperatorIds.UNSIGNED_RIGHT_SHIFT);
- break;
-
- case 572 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS..."); } //$NON-NLS-1$
- consumeBinaryExpression(OperatorIds.LESS);
- break;
-
- case 573 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression GREATER..."); } //$NON-NLS-1$
- consumeBinaryExpression(OperatorIds.GREATER);
- break;
-
- case 574 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS_EQUAL"); } //$NON-NLS-1$
- consumeBinaryExpression(OperatorIds.LESS_EQUAL);
- break;
-
- case 575 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression..."); } //$NON-NLS-1$
- consumeBinaryExpression(OperatorIds.GREATER_EQUAL);
- break;
-
- case 577 : if (DEBUG) { System.out.println("InstanceofExpression ::= InstanceofExpression instanceof"); } //$NON-NLS-1$
- consumeInstanceOfExpression();
- break;
-
- case 579 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression EQUAL_EQUAL..."); } //$NON-NLS-1$
- consumeEqualityExpression(OperatorIds.EQUAL_EQUAL);
- break;
-
- case 580 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression NOT_EQUAL..."); } //$NON-NLS-1$
- consumeEqualityExpression(OperatorIds.NOT_EQUAL);
- break;
-
- case 582 : if (DEBUG) { System.out.println("AndExpression ::= AndExpression AND EqualityExpression"); } //$NON-NLS-1$
- consumeBinaryExpression(OperatorIds.AND);
- break;
-
- case 584 : if (DEBUG) { System.out.println("ExclusiveOrExpression ::= ExclusiveOrExpression XOR..."); } //$NON-NLS-1$
- consumeBinaryExpression(OperatorIds.XOR);
- break;
-
- case 586 : if (DEBUG) { System.out.println("InclusiveOrExpression ::= InclusiveOrExpression OR..."); } //$NON-NLS-1$
- consumeBinaryExpression(OperatorIds.OR);
- break;
-
- case 588 : if (DEBUG) { System.out.println("ConditionalAndExpression ::= ConditionalAndExpression..."); } //$NON-NLS-1$
- consumeBinaryExpression(OperatorIds.AND_AND);
- break;
-
- case 590 : if (DEBUG) { System.out.println("ConditionalOrExpression ::= ConditionalOrExpression..."); } //$NON-NLS-1$
- consumeBinaryExpression(OperatorIds.OR_OR);
- break;
-
- case 592 : if (DEBUG) { System.out.println("ConditionalExpression ::= ConditionalOrExpression..."); } //$NON-NLS-1$
- consumeConditionalExpression(OperatorIds.QUESTIONCOLON) ;
- break;
-
- case 595 : if (DEBUG) { System.out.println("Assignment ::= PostfixExpression AssignmentOperator..."); } //$NON-NLS-1$
- consumeAssignment();
- break;
-
- case 597 : if (DEBUG) { System.out.println("Assignment ::= InvalidArrayInitializerAssignement"); } //$NON-NLS-1$
- ignoreExpressionAssignment();
- break;
-
- case 598 : if (DEBUG) { System.out.println("AssignmentOperator ::= EQUAL"); } //$NON-NLS-1$
- consumeAssignmentOperator(EQUAL);
- break;
-
- case 599 : if (DEBUG) { System.out.println("AssignmentOperator ::= MULTIPLY_EQUAL"); } //$NON-NLS-1$
- consumeAssignmentOperator(MULTIPLY);
- break;
-
- case 600 : if (DEBUG) { System.out.println("AssignmentOperator ::= DIVIDE_EQUAL"); } //$NON-NLS-1$
- consumeAssignmentOperator(DIVIDE);
- break;
-
- case 601 : if (DEBUG) { System.out.println("AssignmentOperator ::= REMAINDER_EQUAL"); } //$NON-NLS-1$
- consumeAssignmentOperator(REMAINDER);
- break;
-
- case 602 : if (DEBUG) { System.out.println("AssignmentOperator ::= PLUS_EQUAL"); } //$NON-NLS-1$
- consumeAssignmentOperator(PLUS);
- break;
-
- case 603 : if (DEBUG) { System.out.println("AssignmentOperator ::= MINUS_EQUAL"); } //$NON-NLS-1$
- consumeAssignmentOperator(MINUS);
- break;
-
- case 604 : if (DEBUG) { System.out.println("AssignmentOperator ::= LEFT_SHIFT_EQUAL"); } //$NON-NLS-1$
- consumeAssignmentOperator(LEFT_SHIFT);
- break;
-
- case 605 : if (DEBUG) { System.out.println("AssignmentOperator ::= RIGHT_SHIFT_EQUAL"); } //$NON-NLS-1$
- consumeAssignmentOperator(RIGHT_SHIFT);
- break;
-
- case 606 : if (DEBUG) { System.out.println("AssignmentOperator ::= UNSIGNED_RIGHT_SHIFT_EQUAL"); } //$NON-NLS-1$
- consumeAssignmentOperator(UNSIGNED_RIGHT_SHIFT);
- break;
-
- case 607 : if (DEBUG) { System.out.println("AssignmentOperator ::= AND_EQUAL"); } //$NON-NLS-1$
- consumeAssignmentOperator(AND);
- break;
-
- case 608 : if (DEBUG) { System.out.println("AssignmentOperator ::= XOR_EQUAL"); } //$NON-NLS-1$
- consumeAssignmentOperator(XOR);
- break;
-
- case 609 : if (DEBUG) { System.out.println("AssignmentOperator ::= OR_EQUAL"); } //$NON-NLS-1$
- consumeAssignmentOperator(OR);
- break;
-
- case 613 : if (DEBUG) { System.out.println("Expressionopt ::="); } //$NON-NLS-1$
- consumeEmptyExpression();
- break;
-
- case 618 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::="); } //$NON-NLS-1$
- consumeEmptyClassBodyDeclarationsopt();
- break;
-
- case 619 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::= NestedType..."); } //$NON-NLS-1$
- consumeClassBodyDeclarationsopt();
- break;
-
- case 620 : if (DEBUG) { System.out.println("Modifiersopt ::="); } //$NON-NLS-1$
- consumeDefaultModifiers();
- break;
-
- case 621 : if (DEBUG) { System.out.println("Modifiersopt ::= Modifiers"); } //$NON-NLS-1$
- consumeModifiers();
- break;
-
- case 622 : if (DEBUG) { System.out.println("BlockStatementsopt ::="); } //$NON-NLS-1$
- consumeEmptyBlockStatementsopt();
- break;
-
- case 624 : if (DEBUG) { System.out.println("Dimsopt ::="); } //$NON-NLS-1$
- consumeEmptyDimsopt();
- break;
-
- case 626 : if (DEBUG) { System.out.println("ArgumentListopt ::="); } //$NON-NLS-1$
- consumeEmptyArgumentListopt();
- break;
-
- case 630 : if (DEBUG) { System.out.println("FormalParameterListopt ::="); } //$NON-NLS-1$
- consumeFormalParameterListopt();
- break;
-
- case 634 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::="); } //$NON-NLS-1$
- consumeEmptyInterfaceMemberDeclarationsopt();
- break;
-
- case 635 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::= NestedType..."); } //$NON-NLS-1$
- consumeInterfaceMemberDeclarationsopt();
- break;
-
- case 636 : if (DEBUG) { System.out.println("NestedType ::="); } //$NON-NLS-1$
- consumeNestedType();
- break;
-
- case 637 : if (DEBUG) { System.out.println("ForInitopt ::="); } //$NON-NLS-1$
- consumeEmptyForInitopt();
- break;
-
- case 639 : if (DEBUG) { System.out.println("ForUpdateopt ::="); } //$NON-NLS-1$
- consumeEmptyForUpdateopt();
- break;
-
- case 643 : if (DEBUG) { System.out.println("Catchesopt ::="); } //$NON-NLS-1$
- consumeEmptyCatchesopt();
- break;
-
- case 645 : if (DEBUG) { System.out.println("EnumDeclaration ::= EnumHeader EnumBody"); } //$NON-NLS-1$
- consumeEnumDeclaration();
- break;
-
- case 646 : if (DEBUG) { System.out.println("EnumHeader ::= EnumHeaderName ClassHeaderImplementsopt"); } //$NON-NLS-1$
- consumeEnumHeader();
- break;
-
- case 647 : if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier"); } //$NON-NLS-1$
- consumeEnumHeaderName();
- break;
-
- case 648 : if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier..."); } //$NON-NLS-1$
- consumeEnumHeaderNameWithTypeParameters();
- break;
-
- case 649 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumBodyDeclarationsopt RBRACE"); } //$NON-NLS-1$
- consumeEnumBodyNoConstants();
- break;
-
- case 650 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE COMMA EnumBodyDeclarationsopt..."); } //$NON-NLS-1$
- consumeEnumBodyNoConstants();
- break;
-
- case 651 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants COMMA..."); } //$NON-NLS-1$
- consumeEnumBodyWithConstants();
- break;
-
- case 652 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants..."); } //$NON-NLS-1$
- consumeEnumBodyWithConstants();
- break;
-
- case 654 : if (DEBUG) { System.out.println("EnumConstants ::= EnumConstants COMMA EnumConstant"); } //$NON-NLS-1$
- consumeEnumConstants();
- break;
-
- case 655 : if (DEBUG) { System.out.println("EnumConstantHeaderName ::= Modifiersopt Identifier"); } //$NON-NLS-1$
- consumeEnumConstantHeaderName();
- break;
-
- case 656 : if (DEBUG) { System.out.println("EnumConstantHeader ::= EnumConstantHeaderName..."); } //$NON-NLS-1$
- consumeEnumConstantHeader();
- break;
-
- case 657 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader ForceNoDiet..."); } //$NON-NLS-1$
- consumeEnumConstantWithClassBody();
- break;
-
- case 658 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader"); } //$NON-NLS-1$
- consumeEnumConstantNoClassBody();
- break;
-
- case 659 : if (DEBUG) { System.out.println("Arguments ::= LPAREN ArgumentListopt RPAREN"); } //$NON-NLS-1$
- consumeArguments();
- break;
-
- case 660 : if (DEBUG) { System.out.println("Argumentsopt ::="); } //$NON-NLS-1$
- consumeEmptyArguments();
- break;
-
- case 662 : if (DEBUG) { System.out.println("EnumDeclarations ::= SEMICOLON ClassBodyDeclarationsopt"); } //$NON-NLS-1$
- consumeEnumDeclarations();
- break;
-
- case 663 : if (DEBUG) { System.out.println("EnumBodyDeclarationsopt ::="); } //$NON-NLS-1$
- consumeEmptyEnumDeclarations();
- break;
-
- case 665 : if (DEBUG) { System.out.println("EnhancedForStatement ::= EnhancedForStatementHeader..."); } //$NON-NLS-1$
- consumeEnhancedForStatement();
- break;
-
- case 666 : if (DEBUG) { System.out.println("EnhancedForStatementNoShortIf ::=..."); } //$NON-NLS-1$
- consumeEnhancedForStatement();
- break;
-
- case 667 : if (DEBUG) { System.out.println("EnhancedForStatementHeaderInit ::= for LPAREN Type..."); } //$NON-NLS-1$
- consumeEnhancedForStatementHeaderInit(false);
- break;
-
- case 668 : if (DEBUG) { System.out.println("EnhancedForStatementHeaderInit ::= for LPAREN Modifiers"); } //$NON-NLS-1$
- consumeEnhancedForStatementHeaderInit(true);
- break;
-
- case 669 : if (DEBUG) { System.out.println("EnhancedForStatementHeader ::=..."); } //$NON-NLS-1$
- consumeEnhancedForStatementHeader();
- break;
-
- case 670 : if (DEBUG) { System.out.println("SingleBaseImportDeclaration ::=..."); } //$NON-NLS-1$
- consumeImportDeclaration();
- break;
-
- case 671 : if (DEBUG) { System.out.println("SingleBaseImportDeclarationName ::= import base Name"); } //$NON-NLS-1$
- consumeSingleBaseImportDeclarationName();
- break;
-
- case 672 : if (DEBUG) { System.out.println("SingleStaticImportDeclaration ::=..."); } //$NON-NLS-1$
- consumeImportDeclaration();
- break;
-
- case 673 : if (DEBUG) { System.out.println("SingleStaticImportDeclarationName ::= import static Name"); } //$NON-NLS-1$
- consumeSingleStaticImportDeclarationName();
- break;
-
- case 674 : if (DEBUG) { System.out.println("StaticImportOnDemandDeclaration ::=..."); } //$NON-NLS-1$
- consumeImportDeclaration();
- break;
-
- case 675 : if (DEBUG) { System.out.println("StaticImportOnDemandDeclarationName ::= import static..."); } //$NON-NLS-1$
- consumeStaticImportOnDemandDeclarationName();
- break;
-
- case 676 : if (DEBUG) { System.out.println("TypeArguments ::= LESS TypeArgumentList1"); } //$NON-NLS-1$
- consumeTypeArguments();
- break;
-
- case 677 : if (DEBUG) { System.out.println("OnlyTypeArguments ::= LESS TypeArgumentList1"); } //$NON-NLS-1$
- consumeOnlyTypeArguments();
- break;
-
- case 679 : if (DEBUG) { System.out.println("TypeArgumentList1 ::= TypeArgumentList COMMA..."); } //$NON-NLS-1$
- consumeTypeArgumentList1();
- break;
-
- case 681 : if (DEBUG) { System.out.println("TypeArgumentList ::= TypeArgumentList COMMA TypeArgument"); } //$NON-NLS-1$
- consumeTypeArgumentList();
- break;
-
- case 682 : if (DEBUG) { System.out.println("TypeArgument ::= ReferenceType"); } //$NON-NLS-1$
- consumeTypeArgument();
- break;
-
- case 687 : if (DEBUG) { System.out.println("TypeAnchor ::= AT Name"); } //$NON-NLS-1$
- consumeTypeAnchor(false);
- break;
-
- case 688 : if (DEBUG) { System.out.println("TypeAnchor ::= AT base"); } //$NON-NLS-1$
- consumeTypeAnchor(true);
- break;
-
- case 689 : if (DEBUG) { System.out.println("TypeAnchor ::= AT this"); } //$NON-NLS-1$
- skipThisAnchor();
- break;
-
- case 690 : if (DEBUG) { System.out.println("TypeAnchor ::= AT Name DOT base"); } //$NON-NLS-1$
- consumeQualifiedBaseTypeAnchor();
- break;
-
- case 693 : if (DEBUG) { System.out.println("ReferenceType1 ::= ReferenceType GREATER"); } //$NON-NLS-1$
- consumeReferenceType1();
- break;
-
- case 694 : if (DEBUG) { System.out.println("ReferenceType1 ::= ClassOrInterface LESS..."); } //$NON-NLS-1$
- consumeTypeArgumentReferenceType1();
- break;
-
- case 696 : if (DEBUG) { System.out.println("TypeArgumentList2 ::= TypeArgumentList COMMA..."); } //$NON-NLS-1$
- consumeTypeArgumentList2();
- break;
-
- case 699 : if (DEBUG) { System.out.println("ReferenceType2 ::= ReferenceType RIGHT_SHIFT"); } //$NON-NLS-1$
- consumeReferenceType2();
- break;
-
- case 700 : if (DEBUG) { System.out.println("ReferenceType2 ::= ClassOrInterface LESS..."); } //$NON-NLS-1$
- consumeTypeArgumentReferenceType2();
- break;
-
- case 702 : if (DEBUG) { System.out.println("TypeArgumentList3 ::= TypeArgumentList COMMA..."); } //$NON-NLS-1$
- consumeTypeArgumentList3();
- break;
-
- case 705 : if (DEBUG) { System.out.println("ReferenceType3 ::= ReferenceType UNSIGNED_RIGHT_SHIFT"); } //$NON-NLS-1$
- consumeReferenceType3();
- break;
-
- case 706 : if (DEBUG) { System.out.println("Wildcard ::= QUESTION"); } //$NON-NLS-1$
- consumeWildcard();
- break;
-
- case 707 : if (DEBUG) { System.out.println("Wildcard ::= QUESTION WildcardBounds"); } //$NON-NLS-1$
- consumeWildcardWithBounds();
- break;
-
- case 708 : if (DEBUG) { System.out.println("WildcardBounds ::= extends ReferenceType"); } //$NON-NLS-1$
- consumeWildcardBoundsExtends();
- break;
-
- case 709 : if (DEBUG) { System.out.println("WildcardBounds ::= super ReferenceType"); } //$NON-NLS-1$
- consumeWildcardBoundsSuper();
- break;
-
- case 710 : if (DEBUG) { System.out.println("Wildcard1 ::= QUESTION GREATER"); } //$NON-NLS-1$
- consumeWildcard1();
- break;
-
- case 711 : if (DEBUG) { System.out.println("Wildcard1 ::= QUESTION WildcardBounds1"); } //$NON-NLS-1$
- consumeWildcard1WithBounds();
- break;
-
- case 712 : if (DEBUG) { System.out.println("WildcardBounds1 ::= extends ReferenceType1"); } //$NON-NLS-1$
- consumeWildcardBounds1Extends();
- break;
-
- case 713 : if (DEBUG) { System.out.println("WildcardBounds1 ::= super ReferenceType1"); } //$NON-NLS-1$
- consumeWildcardBounds1Super();
- break;
-
- case 714 : if (DEBUG) { System.out.println("Wildcard2 ::= QUESTION RIGHT_SHIFT"); } //$NON-NLS-1$
- consumeWildcard2();
- break;
-
- case 715 : if (DEBUG) { System.out.println("Wildcard2 ::= QUESTION WildcardBounds2"); } //$NON-NLS-1$
- consumeWildcard2WithBounds();
- break;
-
- case 716 : if (DEBUG) { System.out.println("WildcardBounds2 ::= extends ReferenceType2"); } //$NON-NLS-1$
- consumeWildcardBounds2Extends();
- break;
-
- case 717 : if (DEBUG) { System.out.println("WildcardBounds2 ::= super ReferenceType2"); } //$NON-NLS-1$
- consumeWildcardBounds2Super();
- break;
-
- case 718 : if (DEBUG) { System.out.println("Wildcard3 ::= QUESTION UNSIGNED_RIGHT_SHIFT"); } //$NON-NLS-1$
- consumeWildcard3();
- break;
-
- case 719 : if (DEBUG) { System.out.println("Wildcard3 ::= QUESTION WildcardBounds3"); } //$NON-NLS-1$
- consumeWildcard3WithBounds();
- break;
-
- case 720 : if (DEBUG) { System.out.println("WildcardBounds3 ::= extends ReferenceType3"); } //$NON-NLS-1$
- consumeWildcardBounds3Extends();
- break;
-
- case 721 : if (DEBUG) { System.out.println("WildcardBounds3 ::= super ReferenceType3"); } //$NON-NLS-1$
- consumeWildcardBounds3Super();
- break;
-
- case 722 : if (DEBUG) { System.out.println("TypeParameterHeader ::= Identifier"); } //$NON-NLS-1$
- consumeTypeParameterHeader();
- break;
-
- case 723 : if (DEBUG) { System.out.println("TypeParameters ::= LESS TypeParameterList1"); } //$NON-NLS-1$
- consumeTypeParameters();
- break;
-
- case 725 : if (DEBUG) { System.out.println("TypeParameterList ::= TypeParameterList COMMA..."); } //$NON-NLS-1$
- consumeTypeParameterList();
- break;
-
- case 727 : if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader extends..."); } //$NON-NLS-1$
- consumeTypeParameterWithExtends();
- break;
-
- case 728 : if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader extends..."); } //$NON-NLS-1$
- consumeTypeParameterWithExtendsAndBounds();
- break;
-
- case 729 : if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader base ReferenceType"); } //$NON-NLS-1$
- consumeTypeParameterWithBase();
- break;
-
- case 733 : if (DEBUG) { System.out.println("TypeValueParameter ::= TypeParameterHeader Identifier"); } //$NON-NLS-1$
- consumeTypeValueParameter();
- break;
-
- case 738 : if (DEBUG) { System.out.println("TypeBoundOpt ::= extends ReferenceType"); } //$NON-NLS-1$
- consumeBoundsOfAnchoredTypeParameter();
- break;
-
- case 740 : if (DEBUG) { System.out.println("TypeBoundOpt1 ::= extends ReferenceType1"); } //$NON-NLS-1$
- consumeBoundsOfAnchoredTypeParameter();
- break;
-
- case 741 : if (DEBUG) { System.out.println("AnchoredTypeParameterHeader0 ::= TypeParameterHeader..."); } //$NON-NLS-1$
- consumeAnchoredTypeParameter();
- break;
-
- case 743 : if (DEBUG) { System.out.println("AdditionalBoundList ::= AdditionalBoundList..."); } //$NON-NLS-1$
- consumeAdditionalBoundList();
- break;
-
- case 744 : if (DEBUG) { System.out.println("AdditionalBound ::= AND ReferenceType"); } //$NON-NLS-1$
- consumeAdditionalBound();
- break;
-
- case 746 : if (DEBUG) { System.out.println("TypeParameterList1 ::= TypeParameterList COMMA..."); } //$NON-NLS-1$
- consumeTypeParameterList1();
- break;
-
- case 747 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader GREATER"); } //$NON-NLS-1$
- consumeTypeParameter1();
- break;
-
- case 748 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader extends..."); } //$NON-NLS-1$
- consumeTypeParameter1WithExtends();
- break;
-
- case 749 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader base..."); } //$NON-NLS-1$
- consumeTypeParameter1WithBase();
- break;
-
- case 750 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader extends..."); } //$NON-NLS-1$
- consumeTypeParameter1WithExtendsAndBounds();
- break;
-
- case 752 : if (DEBUG) { System.out.println("AdditionalBoundList1 ::= AdditionalBoundList..."); } //$NON-NLS-1$
- consumeAdditionalBoundList1();
- break;
-
- case 753 : if (DEBUG) { System.out.println("AdditionalBound1 ::= AND ReferenceType1"); } //$NON-NLS-1$
- consumeAdditionalBound1();
- break;
-
- case 759 : if (DEBUG) { System.out.println("UnaryExpression_NotName ::= PLUS PushPosition..."); } //$NON-NLS-1$
- consumeUnaryExpression(OperatorIds.PLUS);
- break;
-
- case 760 : if (DEBUG) { System.out.println("UnaryExpression_NotName ::= MINUS PushPosition..."); } //$NON-NLS-1$
- consumeUnaryExpression(OperatorIds.MINUS);
- break;
-
- case 763 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus_NotName ::= TWIDDLE..."); } //$NON-NLS-1$
- consumeUnaryExpression(OperatorIds.TWIDDLE);
- break;
-
- case 764 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus_NotName ::= NOT PushPosition"); } //$NON-NLS-1$
- consumeUnaryExpression(OperatorIds.NOT);
- break;
-
- case 767 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); } //$NON-NLS-1$
- consumeBinaryExpression(OperatorIds.MULTIPLY);
- break;
-
- case 768 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name MULTIPLY..."); } //$NON-NLS-1$
- consumeBinaryExpressionWithName(OperatorIds.MULTIPLY);
- break;
-
- case 769 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); } //$NON-NLS-1$
consumeBinaryExpression(OperatorIds.DIVIDE);
break;
- case 770 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name DIVIDE..."); } //$NON-NLS-1$
- consumeBinaryExpressionWithName(OperatorIds.DIVIDE);
- break;
-
- case 771 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); } //$NON-NLS-1$
+ case 564 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); } //$NON-NLS-1$
consumeBinaryExpression(OperatorIds.REMAINDER);
break;
- case 772 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name REMAINDER..."); } //$NON-NLS-1$
- consumeBinaryExpressionWithName(OperatorIds.REMAINDER);
- break;
-
- case 774 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::=..."); } //$NON-NLS-1$
+ case 566 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression PLUS..."); } //$NON-NLS-1$
consumeBinaryExpression(OperatorIds.PLUS);
break;
- case 775 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::= Name PLUS..."); } //$NON-NLS-1$
- consumeBinaryExpressionWithName(OperatorIds.PLUS);
- break;
-
- case 776 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::=..."); } //$NON-NLS-1$
+ case 567 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression MINUS..."); } //$NON-NLS-1$
consumeBinaryExpression(OperatorIds.MINUS);
break;
- case 777 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::= Name MINUS..."); } //$NON-NLS-1$
- consumeBinaryExpressionWithName(OperatorIds.MINUS);
- break;
-
- case 779 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); } //$NON-NLS-1$
+ case 569 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression LEFT_SHIFT..."); } //$NON-NLS-1$
consumeBinaryExpression(OperatorIds.LEFT_SHIFT);
break;
- case 780 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name LEFT_SHIFT..."); } //$NON-NLS-1$
- consumeBinaryExpressionWithName(OperatorIds.LEFT_SHIFT);
- break;
-
- case 781 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); } //$NON-NLS-1$
+ case 570 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression RIGHT_SHIFT..."); } //$NON-NLS-1$
consumeBinaryExpression(OperatorIds.RIGHT_SHIFT);
break;
- case 782 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name RIGHT_SHIFT..."); } //$NON-NLS-1$
- consumeBinaryExpressionWithName(OperatorIds.RIGHT_SHIFT);
- break;
-
- case 783 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); } //$NON-NLS-1$
+ case 571 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression UNSIGNED_RIGHT_SHIFT"); } //$NON-NLS-1$
consumeBinaryExpression(OperatorIds.UNSIGNED_RIGHT_SHIFT);
break;
- case 784 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name UNSIGNED_RIGHT_SHIFT..."); } //$NON-NLS-1$
- consumeBinaryExpressionWithName(OperatorIds.UNSIGNED_RIGHT_SHIFT);
- break;
-
- case 786 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= ShiftExpression_NotName"); } //$NON-NLS-1$
+ case 573 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS..."); } //$NON-NLS-1$
consumeBinaryExpression(OperatorIds.LESS);
break;
- case 787 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name LESS..."); } //$NON-NLS-1$
- consumeBinaryExpressionWithName(OperatorIds.LESS);
- break;
-
- case 788 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= ShiftExpression_NotName"); } //$NON-NLS-1$
+ case 574 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression GREATER..."); } //$NON-NLS-1$
consumeBinaryExpression(OperatorIds.GREATER);
break;
- case 789 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name GREATER..."); } //$NON-NLS-1$
- consumeBinaryExpressionWithName(OperatorIds.GREATER);
- break;
-
- case 790 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::=..."); } //$NON-NLS-1$
+ case 575 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS_EQUAL"); } //$NON-NLS-1$
consumeBinaryExpression(OperatorIds.LESS_EQUAL);
break;
- case 791 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name LESS_EQUAL..."); } //$NON-NLS-1$
- consumeBinaryExpressionWithName(OperatorIds.LESS_EQUAL);
- break;
-
- case 792 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::=..."); } //$NON-NLS-1$
+ case 576 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression..."); } //$NON-NLS-1$
consumeBinaryExpression(OperatorIds.GREATER_EQUAL);
break;
- case 793 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name GREATER_EQUAL..."); } //$NON-NLS-1$
- consumeBinaryExpressionWithName(OperatorIds.GREATER_EQUAL);
- break;
-
- case 795 : if (DEBUG) { System.out.println("InstanceofExpression_NotName ::= Name instanceof..."); } //$NON-NLS-1$
- consumeInstanceOfExpressionWithName();
- break;
-
- case 796 : if (DEBUG) { System.out.println("InstanceofExpression_NotName ::=..."); } //$NON-NLS-1$
+ case 578 : if (DEBUG) { System.out.println("InstanceofExpression ::= InstanceofExpression instanceof"); } //$NON-NLS-1$
consumeInstanceOfExpression();
break;
- case 798 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::=..."); } //$NON-NLS-1$
+ case 580 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression EQUAL_EQUAL..."); } //$NON-NLS-1$
consumeEqualityExpression(OperatorIds.EQUAL_EQUAL);
break;
- case 799 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::= Name EQUAL_EQUAL..."); } //$NON-NLS-1$
- consumeEqualityExpressionWithName(OperatorIds.EQUAL_EQUAL);
- break;
-
- case 800 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::=..."); } //$NON-NLS-1$
+ case 581 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression NOT_EQUAL..."); } //$NON-NLS-1$
consumeEqualityExpression(OperatorIds.NOT_EQUAL);
break;
- case 801 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::= Name NOT_EQUAL..."); } //$NON-NLS-1$
- consumeEqualityExpressionWithName(OperatorIds.NOT_EQUAL);
- break;
-
- case 803 : if (DEBUG) { System.out.println("AndExpression_NotName ::= AndExpression_NotName AND..."); } //$NON-NLS-1$
+ case 583 : if (DEBUG) { System.out.println("AndExpression ::= AndExpression AND EqualityExpression"); } //$NON-NLS-1$
consumeBinaryExpression(OperatorIds.AND);
break;
- case 804 : if (DEBUG) { System.out.println("AndExpression_NotName ::= Name AND EqualityExpression"); } //$NON-NLS-1$
- consumeBinaryExpressionWithName(OperatorIds.AND);
- break;
-
- case 806 : if (DEBUG) { System.out.println("ExclusiveOrExpression_NotName ::=..."); } //$NON-NLS-1$
+ case 585 : if (DEBUG) { System.out.println("ExclusiveOrExpression ::= ExclusiveOrExpression XOR..."); } //$NON-NLS-1$
consumeBinaryExpression(OperatorIds.XOR);
break;
- case 807 : if (DEBUG) { System.out.println("ExclusiveOrExpression_NotName ::= Name XOR AndExpression"); } //$NON-NLS-1$
- consumeBinaryExpressionWithName(OperatorIds.XOR);
- break;
-
- case 809 : if (DEBUG) { System.out.println("InclusiveOrExpression_NotName ::=..."); } //$NON-NLS-1$
+ case 587 : if (DEBUG) { System.out.println("InclusiveOrExpression ::= InclusiveOrExpression OR..."); } //$NON-NLS-1$
consumeBinaryExpression(OperatorIds.OR);
break;
- case 810 : if (DEBUG) { System.out.println("InclusiveOrExpression_NotName ::= Name OR..."); } //$NON-NLS-1$
- consumeBinaryExpressionWithName(OperatorIds.OR);
- break;
-
- case 812 : if (DEBUG) { System.out.println("ConditionalAndExpression_NotName ::=..."); } //$NON-NLS-1$
+ case 589 : if (DEBUG) { System.out.println("ConditionalAndExpression ::= ConditionalAndExpression..."); } //$NON-NLS-1$
consumeBinaryExpression(OperatorIds.AND_AND);
break;
- case 813 : if (DEBUG) { System.out.println("ConditionalAndExpression_NotName ::= Name AND_AND..."); } //$NON-NLS-1$
- consumeBinaryExpressionWithName(OperatorIds.AND_AND);
- break;
-
- case 815 : if (DEBUG) { System.out.println("ConditionalOrExpression_NotName ::=..."); } //$NON-NLS-1$
+ case 591 : if (DEBUG) { System.out.println("ConditionalOrExpression ::= ConditionalOrExpression..."); } //$NON-NLS-1$
consumeBinaryExpression(OperatorIds.OR_OR);
break;
- case 816 : if (DEBUG) { System.out.println("ConditionalOrExpression_NotName ::= Name OR_OR..."); } //$NON-NLS-1$
- consumeBinaryExpressionWithName(OperatorIds.OR_OR);
- break;
-
- case 818 : if (DEBUG) { System.out.println("ConditionalExpression_NotName ::=..."); } //$NON-NLS-1$
+ case 593 : if (DEBUG) { System.out.println("ConditionalExpression ::= ConditionalOrExpression..."); } //$NON-NLS-1$
consumeConditionalExpression(OperatorIds.QUESTIONCOLON) ;
break;
- case 819 : if (DEBUG) { System.out.println("ConditionalExpression_NotName ::= Name QUESTION..."); } //$NON-NLS-1$
+ case 596 : if (DEBUG) { System.out.println("Assignment ::= PostfixExpression AssignmentOperator..."); } //$NON-NLS-1$
+ consumeAssignment();
+ break;
+
+ case 598 : if (DEBUG) { System.out.println("Assignment ::= InvalidArrayInitializerAssignement"); } //$NON-NLS-1$
+ ignoreExpressionAssignment();
+ break;
+
+ case 599 : if (DEBUG) { System.out.println("AssignmentOperator ::= EQUAL"); } //$NON-NLS-1$
+ consumeAssignmentOperator(EQUAL);
+ break;
+
+ case 600 : if (DEBUG) { System.out.println("AssignmentOperator ::= MULTIPLY_EQUAL"); } //$NON-NLS-1$
+ consumeAssignmentOperator(MULTIPLY);
+ break;
+
+ case 601 : if (DEBUG) { System.out.println("AssignmentOperator ::= DIVIDE_EQUAL"); } //$NON-NLS-1$
+ consumeAssignmentOperator(DIVIDE);
+ break;
+
+ case 602 : if (DEBUG) { System.out.println("AssignmentOperator ::= REMAINDER_EQUAL"); } //$NON-NLS-1$
+ consumeAssignmentOperator(REMAINDER);
+ break;
+
+ case 603 : if (DEBUG) { System.out.println("AssignmentOperator ::= PLUS_EQUAL"); } //$NON-NLS-1$
+ consumeAssignmentOperator(PLUS);
+ break;
+
+ case 604 : if (DEBUG) { System.out.println("AssignmentOperator ::= MINUS_EQUAL"); } //$NON-NLS-1$
+ consumeAssignmentOperator(MINUS);
+ break;
+
+ case 605 : if (DEBUG) { System.out.println("AssignmentOperator ::= LEFT_SHIFT_EQUAL"); } //$NON-NLS-1$
+ consumeAssignmentOperator(LEFT_SHIFT);
+ break;
+
+ case 606 : if (DEBUG) { System.out.println("AssignmentOperator ::= RIGHT_SHIFT_EQUAL"); } //$NON-NLS-1$
+ consumeAssignmentOperator(RIGHT_SHIFT);
+ break;
+
+ case 607 : if (DEBUG) { System.out.println("AssignmentOperator ::= UNSIGNED_RIGHT_SHIFT_EQUAL"); } //$NON-NLS-1$
+ consumeAssignmentOperator(UNSIGNED_RIGHT_SHIFT);
+ break;
+
+ case 608 : if (DEBUG) { System.out.println("AssignmentOperator ::= AND_EQUAL"); } //$NON-NLS-1$
+ consumeAssignmentOperator(AND);
+ break;
+
+ case 609 : if (DEBUG) { System.out.println("AssignmentOperator ::= XOR_EQUAL"); } //$NON-NLS-1$
+ consumeAssignmentOperator(XOR);
+ break;
+
+ case 610 : if (DEBUG) { System.out.println("AssignmentOperator ::= OR_EQUAL"); } //$NON-NLS-1$
+ consumeAssignmentOperator(OR);
+ break;
+
+ case 614 : if (DEBUG) { System.out.println("Expressionopt ::="); } //$NON-NLS-1$
+ consumeEmptyExpression();
+ break;
+
+ case 619 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::="); } //$NON-NLS-1$
+ consumeEmptyClassBodyDeclarationsopt();
+ break;
+
+ case 620 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::= NestedType..."); } //$NON-NLS-1$
+ consumeClassBodyDeclarationsopt();
+ break;
+
+ case 621 : if (DEBUG) { System.out.println("Modifiersopt ::="); } //$NON-NLS-1$
+ consumeDefaultModifiers();
+ break;
+
+ case 622 : if (DEBUG) { System.out.println("Modifiersopt ::= Modifiers"); } //$NON-NLS-1$
+ consumeModifiers();
+ break;
+
+ case 623 : if (DEBUG) { System.out.println("BlockStatementsopt ::="); } //$NON-NLS-1$
+ consumeEmptyBlockStatementsopt();
+ break;
+
+ case 625 : if (DEBUG) { System.out.println("Dimsopt ::="); } //$NON-NLS-1$
+ consumeEmptyDimsopt();
+ break;
+
+ case 627 : if (DEBUG) { System.out.println("ArgumentListopt ::="); } //$NON-NLS-1$
+ consumeEmptyArgumentListopt();
+ break;
+
+ case 631 : if (DEBUG) { System.out.println("FormalParameterListopt ::="); } //$NON-NLS-1$
+ consumeFormalParameterListopt();
+ break;
+
+ case 635 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::="); } //$NON-NLS-1$
+ consumeEmptyInterfaceMemberDeclarationsopt();
+ break;
+
+ case 636 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::= NestedType..."); } //$NON-NLS-1$
+ consumeInterfaceMemberDeclarationsopt();
+ break;
+
+ case 637 : if (DEBUG) { System.out.println("NestedType ::="); } //$NON-NLS-1$
+ consumeNestedType();
+ break;
+
+ case 638 : if (DEBUG) { System.out.println("ForInitopt ::="); } //$NON-NLS-1$
+ consumeEmptyForInitopt();
+ break;
+
+ case 640 : if (DEBUG) { System.out.println("ForUpdateopt ::="); } //$NON-NLS-1$
+ consumeEmptyForUpdateopt();
+ break;
+
+ case 644 : if (DEBUG) { System.out.println("Catchesopt ::="); } //$NON-NLS-1$
+ consumeEmptyCatchesopt();
+ break;
+
+ case 646 : if (DEBUG) { System.out.println("EnumDeclaration ::= EnumHeader EnumBody"); } //$NON-NLS-1$
+ consumeEnumDeclaration();
+ break;
+
+ case 647 : if (DEBUG) { System.out.println("EnumHeader ::= EnumHeaderName ClassHeaderImplementsopt"); } //$NON-NLS-1$
+ consumeEnumHeader();
+ break;
+
+ case 648 : if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier"); } //$NON-NLS-1$
+ consumeEnumHeaderName();
+ break;
+
+ case 649 : if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier..."); } //$NON-NLS-1$
+ consumeEnumHeaderNameWithTypeParameters();
+ break;
+
+ case 650 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumBodyDeclarationsopt RBRACE"); } //$NON-NLS-1$
+ consumeEnumBodyNoConstants();
+ break;
+
+ case 651 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE COMMA EnumBodyDeclarationsopt..."); } //$NON-NLS-1$
+ consumeEnumBodyNoConstants();
+ break;
+
+ case 652 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants COMMA..."); } //$NON-NLS-1$
+ consumeEnumBodyWithConstants();
+ break;
+
+ case 653 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants..."); } //$NON-NLS-1$
+ consumeEnumBodyWithConstants();
+ break;
+
+ case 655 : if (DEBUG) { System.out.println("EnumConstants ::= EnumConstants COMMA EnumConstant"); } //$NON-NLS-1$
+ consumeEnumConstants();
+ break;
+
+ case 656 : if (DEBUG) { System.out.println("EnumConstantHeaderName ::= Modifiersopt Identifier"); } //$NON-NLS-1$
+ consumeEnumConstantHeaderName();
+ break;
+
+ case 657 : if (DEBUG) { System.out.println("EnumConstantHeader ::= EnumConstantHeaderName..."); } //$NON-NLS-1$
+ consumeEnumConstantHeader();
+ break;
+
+ case 658 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader ForceNoDiet..."); } //$NON-NLS-1$
+ consumeEnumConstantWithClassBody();
+ break;
+
+ case 659 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader"); } //$NON-NLS-1$
+ consumeEnumConstantNoClassBody();
+ break;
+
+ case 660 : if (DEBUG) { System.out.println("Arguments ::= LPAREN ArgumentListopt RPAREN"); } //$NON-NLS-1$
+ consumeArguments();
+ break;
+
+ case 661 : if (DEBUG) { System.out.println("Argumentsopt ::="); } //$NON-NLS-1$
+ consumeEmptyArguments();
+ break;
+
+ case 663 : if (DEBUG) { System.out.println("EnumDeclarations ::= SEMICOLON ClassBodyDeclarationsopt"); } //$NON-NLS-1$
+ consumeEnumDeclarations();
+ break;
+
+ case 664 : if (DEBUG) { System.out.println("EnumBodyDeclarationsopt ::="); } //$NON-NLS-1$
+ consumeEmptyEnumDeclarations();
+ break;
+
+ case 666 : if (DEBUG) { System.out.println("EnhancedForStatement ::= EnhancedForStatementHeader..."); } //$NON-NLS-1$
+ consumeEnhancedForStatement();
+ break;
+
+ case 667 : if (DEBUG) { System.out.println("EnhancedForStatementNoShortIf ::=..."); } //$NON-NLS-1$
+ consumeEnhancedForStatement();
+ break;
+
+ case 668 : if (DEBUG) { System.out.println("EnhancedForStatementHeaderInit ::= for LPAREN Type..."); } //$NON-NLS-1$
+ consumeEnhancedForStatementHeaderInit(false);
+ break;
+
+ case 669 : if (DEBUG) { System.out.println("EnhancedForStatementHeaderInit ::= for LPAREN Modifiers"); } //$NON-NLS-1$
+ consumeEnhancedForStatementHeaderInit(true);
+ break;
+
+ case 670 : if (DEBUG) { System.out.println("EnhancedForStatementHeader ::=..."); } //$NON-NLS-1$
+ consumeEnhancedForStatementHeader();
+ break;
+
+ case 671 : if (DEBUG) { System.out.println("SingleBaseImportDeclaration ::=..."); } //$NON-NLS-1$
+ consumeImportDeclaration();
+ break;
+
+ case 672 : if (DEBUG) { System.out.println("SingleBaseImportDeclarationName ::= import base Name"); } //$NON-NLS-1$
+ consumeSingleBaseImportDeclarationName();
+ break;
+
+ case 673 : if (DEBUG) { System.out.println("SingleStaticImportDeclaration ::=..."); } //$NON-NLS-1$
+ consumeImportDeclaration();
+ break;
+
+ case 674 : if (DEBUG) { System.out.println("SingleStaticImportDeclarationName ::= import static Name"); } //$NON-NLS-1$
+ consumeSingleStaticImportDeclarationName();
+ break;
+
+ case 675 : if (DEBUG) { System.out.println("StaticImportOnDemandDeclaration ::=..."); } //$NON-NLS-1$
+ consumeImportDeclaration();
+ break;
+
+ case 676 : if (DEBUG) { System.out.println("StaticImportOnDemandDeclarationName ::= import static..."); } //$NON-NLS-1$
+ consumeStaticImportOnDemandDeclarationName();
+ break;
+
+ case 677 : if (DEBUG) { System.out.println("TypeArguments ::= LESS TypeArgumentList1"); } //$NON-NLS-1$
+ consumeTypeArguments();
+ break;
+
+ case 678 : if (DEBUG) { System.out.println("OnlyTypeArguments ::= LESS TypeArgumentList1"); } //$NON-NLS-1$
+ consumeOnlyTypeArguments();
+ break;
+
+ case 680 : if (DEBUG) { System.out.println("TypeArgumentList1 ::= TypeArgumentList COMMA..."); } //$NON-NLS-1$
+ consumeTypeArgumentList1();
+ break;
+
+ case 682 : if (DEBUG) { System.out.println("TypeArgumentList ::= TypeArgumentList COMMA TypeArgument"); } //$NON-NLS-1$
+ consumeTypeArgumentList();
+ break;
+
+ case 683 : if (DEBUG) { System.out.println("TypeArgument ::= ReferenceType"); } //$NON-NLS-1$
+ consumeTypeArgument();
+ break;
+
+ case 688 : if (DEBUG) { System.out.println("TypeAnchor ::= AT Name"); } //$NON-NLS-1$
+ consumeTypeAnchor(false);
+ break;
+
+ case 689 : if (DEBUG) { System.out.println("TypeAnchor ::= AT base"); } //$NON-NLS-1$
+ consumeTypeAnchor(true);
+ break;
+
+ case 690 : if (DEBUG) { System.out.println("TypeAnchor ::= AT this"); } //$NON-NLS-1$
+ skipThisAnchor();
+ break;
+
+ case 691 : if (DEBUG) { System.out.println("TypeAnchor ::= AT Name DOT base"); } //$NON-NLS-1$
+ consumeQualifiedBaseTypeAnchor();
+ break;
+
+ case 694 : if (DEBUG) { System.out.println("ReferenceType1 ::= ReferenceType GREATER"); } //$NON-NLS-1$
+ consumeReferenceType1();
+ break;
+
+ case 695 : if (DEBUG) { System.out.println("ReferenceType1 ::= ClassOrInterface LESS..."); } //$NON-NLS-1$
+ consumeTypeArgumentReferenceType1();
+ break;
+
+ case 697 : if (DEBUG) { System.out.println("TypeArgumentList2 ::= TypeArgumentList COMMA..."); } //$NON-NLS-1$
+ consumeTypeArgumentList2();
+ break;
+
+ case 700 : if (DEBUG) { System.out.println("ReferenceType2 ::= ReferenceType RIGHT_SHIFT"); } //$NON-NLS-1$
+ consumeReferenceType2();
+ break;
+
+ case 701 : if (DEBUG) { System.out.println("ReferenceType2 ::= ClassOrInterface LESS..."); } //$NON-NLS-1$
+ consumeTypeArgumentReferenceType2();
+ break;
+
+ case 703 : if (DEBUG) { System.out.println("TypeArgumentList3 ::= TypeArgumentList COMMA..."); } //$NON-NLS-1$
+ consumeTypeArgumentList3();
+ break;
+
+ case 706 : if (DEBUG) { System.out.println("ReferenceType3 ::= ReferenceType UNSIGNED_RIGHT_SHIFT"); } //$NON-NLS-1$
+ consumeReferenceType3();
+ break;
+
+ case 707 : if (DEBUG) { System.out.println("Wildcard ::= QUESTION"); } //$NON-NLS-1$
+ consumeWildcard();
+ break;
+
+ case 708 : if (DEBUG) { System.out.println("Wildcard ::= QUESTION WildcardBounds"); } //$NON-NLS-1$
+ consumeWildcardWithBounds();
+ break;
+
+ case 709 : if (DEBUG) { System.out.println("WildcardBounds ::= extends ReferenceType"); } //$NON-NLS-1$
+ consumeWildcardBoundsExtends();
+ break;
+
+ case 710 : if (DEBUG) { System.out.println("WildcardBounds ::= super ReferenceType"); } //$NON-NLS-1$
+ consumeWildcardBoundsSuper();
+ break;
+
+ case 711 : if (DEBUG) { System.out.println("Wildcard1 ::= QUESTION GREATER"); } //$NON-NLS-1$
+ consumeWildcard1();
+ break;
+
+ case 712 : if (DEBUG) { System.out.println("Wildcard1 ::= QUESTION WildcardBounds1"); } //$NON-NLS-1$
+ consumeWildcard1WithBounds();
+ break;
+
+ case 713 : if (DEBUG) { System.out.println("WildcardBounds1 ::= extends ReferenceType1"); } //$NON-NLS-1$
+ consumeWildcardBounds1Extends();
+ break;
+
+ case 714 : if (DEBUG) { System.out.println("WildcardBounds1 ::= super ReferenceType1"); } //$NON-NLS-1$
+ consumeWildcardBounds1Super();
+ break;
+
+ case 715 : if (DEBUG) { System.out.println("Wildcard2 ::= QUESTION RIGHT_SHIFT"); } //$NON-NLS-1$
+ consumeWildcard2();
+ break;
+
+ case 716 : if (DEBUG) { System.out.println("Wildcard2 ::= QUESTION WildcardBounds2"); } //$NON-NLS-1$
+ consumeWildcard2WithBounds();
+ break;
+
+ case 717 : if (DEBUG) { System.out.println("WildcardBounds2 ::= extends ReferenceType2"); } //$NON-NLS-1$
+ consumeWildcardBounds2Extends();
+ break;
+
+ case 718 : if (DEBUG) { System.out.println("WildcardBounds2 ::= super ReferenceType2"); } //$NON-NLS-1$
+ consumeWildcardBounds2Super();
+ break;
+
+ case 719 : if (DEBUG) { System.out.println("Wildcard3 ::= QUESTION UNSIGNED_RIGHT_SHIFT"); } //$NON-NLS-1$
+ consumeWildcard3();
+ break;
+
+ case 720 : if (DEBUG) { System.out.println("Wildcard3 ::= QUESTION WildcardBounds3"); } //$NON-NLS-1$
+ consumeWildcard3WithBounds();
+ break;
+
+ case 721 : if (DEBUG) { System.out.println("WildcardBounds3 ::= extends ReferenceType3"); } //$NON-NLS-1$
+ consumeWildcardBounds3Extends();
+ break;
+
+ case 722 : if (DEBUG) { System.out.println("WildcardBounds3 ::= super ReferenceType3"); } //$NON-NLS-1$
+ consumeWildcardBounds3Super();
+ break;
+
+ case 723 : if (DEBUG) { System.out.println("TypeParameterHeader ::= Identifier"); } //$NON-NLS-1$
+ consumeTypeParameterHeader();
+ break;
+
+ case 724 : if (DEBUG) { System.out.println("TypeParameters ::= LESS TypeParameterList1"); } //$NON-NLS-1$
+ consumeTypeParameters();
+ break;
+
+ case 726 : if (DEBUG) { System.out.println("TypeParameterList ::= TypeParameterList COMMA..."); } //$NON-NLS-1$
+ consumeTypeParameterList();
+ break;
+
+ case 728 : if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader extends..."); } //$NON-NLS-1$
+ consumeTypeParameterWithExtends();
+ break;
+
+ case 729 : if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader extends..."); } //$NON-NLS-1$
+ consumeTypeParameterWithExtendsAndBounds();
+ break;
+
+ case 730 : if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader base ReferenceType"); } //$NON-NLS-1$
+ consumeTypeParameterWithBase();
+ break;
+
+ case 734 : if (DEBUG) { System.out.println("TypeValueParameter ::= TypeParameterHeader Identifier"); } //$NON-NLS-1$
+ consumeTypeValueParameter();
+ break;
+
+ case 739 : if (DEBUG) { System.out.println("TypeBoundOpt ::= extends ReferenceType"); } //$NON-NLS-1$
+ consumeBoundsOfAnchoredTypeParameter();
+ break;
+
+ case 741 : if (DEBUG) { System.out.println("TypeBoundOpt1 ::= extends ReferenceType1"); } //$NON-NLS-1$
+ consumeBoundsOfAnchoredTypeParameter();
+ break;
+
+ case 742 : if (DEBUG) { System.out.println("AnchoredTypeParameterHeader0 ::= TypeParameterHeader..."); } //$NON-NLS-1$
+ consumeAnchoredTypeParameter();
+ break;
+
+ case 744 : if (DEBUG) { System.out.println("AdditionalBoundList ::= AdditionalBoundList..."); } //$NON-NLS-1$
+ consumeAdditionalBoundList();
+ break;
+
+ case 745 : if (DEBUG) { System.out.println("AdditionalBound ::= AND ReferenceType"); } //$NON-NLS-1$
+ consumeAdditionalBound();
+ break;
+
+ case 747 : if (DEBUG) { System.out.println("TypeParameterList1 ::= TypeParameterList COMMA..."); } //$NON-NLS-1$
+ consumeTypeParameterList1();
+ break;
+
+ case 748 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader GREATER"); } //$NON-NLS-1$
+ consumeTypeParameter1();
+ break;
+
+ case 749 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader extends..."); } //$NON-NLS-1$
+ consumeTypeParameter1WithExtends();
+ break;
+
+ case 750 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader base..."); } //$NON-NLS-1$
+ consumeTypeParameter1WithBase();
+ break;
+
+ case 751 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader extends..."); } //$NON-NLS-1$
+ consumeTypeParameter1WithExtendsAndBounds();
+ break;
+
+ case 753 : if (DEBUG) { System.out.println("AdditionalBoundList1 ::= AdditionalBoundList..."); } //$NON-NLS-1$
+ consumeAdditionalBoundList1();
+ break;
+
+ case 754 : if (DEBUG) { System.out.println("AdditionalBound1 ::= AND ReferenceType1"); } //$NON-NLS-1$
+ consumeAdditionalBound1();
+ break;
+
+ case 760 : if (DEBUG) { System.out.println("UnaryExpression_NotName ::= PLUS PushPosition..."); } //$NON-NLS-1$
+ consumeUnaryExpression(OperatorIds.PLUS);
+ break;
+
+ case 761 : if (DEBUG) { System.out.println("UnaryExpression_NotName ::= MINUS PushPosition..."); } //$NON-NLS-1$
+ consumeUnaryExpression(OperatorIds.MINUS);
+ break;
+
+ case 764 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus_NotName ::= TWIDDLE..."); } //$NON-NLS-1$
+ consumeUnaryExpression(OperatorIds.TWIDDLE);
+ break;
+
+ case 765 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus_NotName ::= NOT PushPosition"); } //$NON-NLS-1$
+ consumeUnaryExpression(OperatorIds.NOT);
+ break;
+
+ case 768 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); } //$NON-NLS-1$
+ consumeBinaryExpression(OperatorIds.MULTIPLY);
+ break;
+
+ case 769 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name MULTIPLY..."); } //$NON-NLS-1$
+ consumeBinaryExpressionWithName(OperatorIds.MULTIPLY);
+ break;
+
+ case 770 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); } //$NON-NLS-1$
+ consumeBinaryExpression(OperatorIds.DIVIDE);
+ break;
+
+ case 771 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name DIVIDE..."); } //$NON-NLS-1$
+ consumeBinaryExpressionWithName(OperatorIds.DIVIDE);
+ break;
+
+ case 772 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); } //$NON-NLS-1$
+ consumeBinaryExpression(OperatorIds.REMAINDER);
+ break;
+
+ case 773 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name REMAINDER..."); } //$NON-NLS-1$
+ consumeBinaryExpressionWithName(OperatorIds.REMAINDER);
+ break;
+
+ case 775 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::=..."); } //$NON-NLS-1$
+ consumeBinaryExpression(OperatorIds.PLUS);
+ break;
+
+ case 776 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::= Name PLUS..."); } //$NON-NLS-1$
+ consumeBinaryExpressionWithName(OperatorIds.PLUS);
+ break;
+
+ case 777 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::=..."); } //$NON-NLS-1$
+ consumeBinaryExpression(OperatorIds.MINUS);
+ break;
+
+ case 778 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::= Name MINUS..."); } //$NON-NLS-1$
+ consumeBinaryExpressionWithName(OperatorIds.MINUS);
+ break;
+
+ case 780 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); } //$NON-NLS-1$
+ consumeBinaryExpression(OperatorIds.LEFT_SHIFT);
+ break;
+
+ case 781 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name LEFT_SHIFT..."); } //$NON-NLS-1$
+ consumeBinaryExpressionWithName(OperatorIds.LEFT_SHIFT);
+ break;
+
+ case 782 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); } //$NON-NLS-1$
+ consumeBinaryExpression(OperatorIds.RIGHT_SHIFT);
+ break;
+
+ case 783 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name RIGHT_SHIFT..."); } //$NON-NLS-1$
+ consumeBinaryExpressionWithName(OperatorIds.RIGHT_SHIFT);
+ break;
+
+ case 784 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); } //$NON-NLS-1$
+ consumeBinaryExpression(OperatorIds.UNSIGNED_RIGHT_SHIFT);
+ break;
+
+ case 785 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name UNSIGNED_RIGHT_SHIFT..."); } //$NON-NLS-1$
+ consumeBinaryExpressionWithName(OperatorIds.UNSIGNED_RIGHT_SHIFT);
+ break;
+
+ case 787 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= ShiftExpression_NotName"); } //$NON-NLS-1$
+ consumeBinaryExpression(OperatorIds.LESS);
+ break;
+
+ case 788 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name LESS..."); } //$NON-NLS-1$
+ consumeBinaryExpressionWithName(OperatorIds.LESS);
+ break;
+
+ case 789 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= ShiftExpression_NotName"); } //$NON-NLS-1$
+ consumeBinaryExpression(OperatorIds.GREATER);
+ break;
+
+ case 790 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name GREATER..."); } //$NON-NLS-1$
+ consumeBinaryExpressionWithName(OperatorIds.GREATER);
+ break;
+
+ case 791 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::=..."); } //$NON-NLS-1$
+ consumeBinaryExpression(OperatorIds.LESS_EQUAL);
+ break;
+
+ case 792 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name LESS_EQUAL..."); } //$NON-NLS-1$
+ consumeBinaryExpressionWithName(OperatorIds.LESS_EQUAL);