### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core.tests Index: Eclipse Java Tests Compiler/org/eclipse/jdt/tests/compiler/regression/InitializationTest.java =================================================================== RCS file: /home/cvs/numbat/org.eclipse.jdt.core.tests/Eclipse Java Tests Compiler/org/eclipse/jdt/tests/compiler/regression/InitializationTest.java,v retrieving revision 1.122 diff -u -r1.122 InitializationTest.java --- Eclipse Java Tests Compiler/org/eclipse/jdt/tests/compiler/regression/InitializationTest.java 28 Jan 2009 14:02:29 -0000 1.122 +++ Eclipse Java Tests Compiler/org/eclipse/jdt/tests/compiler/regression/InitializationTest.java 29 Jan 2009 13:33:34 -0000 @@ -5921,8 +5921,8 @@ "----------\n"); } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=257716 -public void _test196() { - this.runNegativeTest( +public void test196() { + this.runConformTest( new String[] { "X.java", "public class X {\n" + @@ -5933,11 +5933,48 @@ " int i = hello;\n" + " };\n" + " }\n" + + "}\n" + }, + ""); +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=257716 +public void test197() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " final int hello;\n" + " public X(int i) {\n" + " new Object() {\n" + " int j = hello;\n" + " };\n" + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 3)\n" + + " public X(int i) {\n" + + " ^^^^^^^^\n" + + "The blank final field hello may not have been initialized\n" + + "----------\n" + + "2. WARNING in X.java (at line 5)\n" + + " int j = hello;\n" + + " ^\n" + + "The field new Object(){}.j is never read locally\n" + + "----------\n" + + "3. ERROR in X.java (at line 5)\n" + + " int j = hello;\n" + + " ^^^^^\n" + + "The blank final field hello may not have been initialized\n" + + "----------\n"); +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=257716 +public void test198() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " final int hello;\n" + " public X(long l) {\n" + " if (l > 0) {\n" + " new Object() {\n" + @@ -5947,7 +5984,259 @@ " } \n" + "}\n" }, - "xx"); + "----------\n" + + "1. ERROR in X.java (at line 3)\n" + + " public X(long l) {\n" + + " ^^^^^^^^^\n" + + "The blank final field hello may not have been initialized\n" + + "----------\n" + + "2. WARNING in X.java (at line 6)\n" + + " int j = hello;\n" + + " ^\n" + + "The field new Object(){}.j is never read locally\n" + + "----------\n" + + "3. ERROR in X.java (at line 6)\n" + + " int j = hello;\n" + + " ^^^^^\n" + + "The blank final field hello may not have been initialized\n" + + "----------\n"); +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=257716 - variation +public void test199() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " final int hello;\n" + + " public X() {\n" + + " hello = 0;\n" + + " new Object() {\n" + + " int i = X.this.hello;\n" + + " };\n" + + " }\n" + + " public X(int a) {\n" + + " new Object() {\n" + + " int j = X.this.hello;\n" + + " };\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. WARNING in X.java (at line 6)\n" + + " int i = X.this.hello;\n" + + " ^\n" + + "The field new Object(){}.i is never read locally\n" + + "----------\n" + + "2. ERROR in X.java (at line 9)\n" + + " public X(int a) {\n" + + " ^^^^^^^^\n" + + "The blank final field hello may not have been initialized\n" + + "----------\n" + + "3. WARNING in X.java (at line 11)\n" + + " int j = X.this.hello;\n" + + " ^\n" + + "The field new Object(){}.j is never read locally\n" + + "----------\n"); +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=257716 - variation +public void test200() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " final int hello;\n" + + " public X() {\n" + + " hello = 0;\n" + + " new Object() {\n" + + " X x = X.this;\n" + + " int i = x.hello;\n" + + " };\n" + + " }\n" + + " public X(int a) {\n" + + " new Object() {\n" + + " X x = X.this;\n" + + " int j = x.hello;\n" + + " };\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. WARNING in X.java (at line 7)\n" + + " int i = x.hello;\n" + + " ^\n" + + "The field new Object(){}.i is never read locally\n" + + "----------\n" + + "2. ERROR in X.java (at line 10)\n" + + " public X(int a) {\n" + + " ^^^^^^^^\n" + + "The blank final field hello may not have been initialized\n" + + "----------\n" + + "3. WARNING in X.java (at line 13)\n" + + " int j = x.hello;\n" + + " ^\n" + + "The field new Object(){}.j is never read locally\n" + + "----------\n"); +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=257716 - variation +public void test201() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " final int hello;\n" + + " class M {\n" + + " public M() {\n" + + " hello = 0;\n" + + " new Object() {\n" + + " int i = hello;\n" + + " };\n" + + " }\n" + + " public M(int a) {\n" + + " new Object() {\n" + + " int j = hello;\n" + + " };\n" + + " }\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 1)\n" + + " public class X {\n" + + " ^\n" + + "The blank final field hello may not have been initialized\n" + + "----------\n" + + "2. ERROR in X.java (at line 5)\n" + + " hello = 0;\n" + + " ^^^^^\n" + + "The final field X.hello cannot be assigned\n" + + "----------\n" + + "3. WARNING in X.java (at line 7)\n" + + " int i = hello;\n" + + " ^\n" + + "The field new Object(){}.i is never read locally\n" + + "----------\n" + + "4. WARNING in X.java (at line 12)\n" + + " int j = hello;\n" + + " ^\n" + + "The field new Object(){}.j is never read locally\n" + + "----------\n"); +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=257716 - variation +public void test202() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " final int hello;\n" + + " public X() {\n" + + " hello = 0;\n" + + " class Local {\n" + + " Object o = new Object() {\n" + + " int i = hello;\n" + + " };\n" + + " }\n" + + " }\n" + + " public X(int a) {\n" + + " class Local {\n" + + " Object o = new Object() {\n" + + " int j = hello;\n" + + " };\n" + + " }\n" + + " }\n" + + "}\n" + + }, + "----------\n" + + "1. WARNING in X.java (at line 5)\n" + + " class Local {\n" + + " ^^^^^\n" + + "The type Local is never used locally\n" + + "----------\n" + + "2. WARNING in X.java (at line 6)\n" + + " Object o = new Object() {\n" + + " ^\n" + + "The field Local.o is never read locally\n" + + "----------\n" + + "3. WARNING in X.java (at line 7)\n" + + " int i = hello;\n" + + " ^\n" + + "The field new Object(){}.i is never read locally\n" + + "----------\n" + + "4. ERROR in X.java (at line 11)\n" + + " public X(int a) {\n" + + " ^^^^^^^^\n" + + "The blank final field hello may not have been initialized\n" + + "----------\n" + + "5. WARNING in X.java (at line 12)\n" + + " class Local {\n" + + " ^^^^^\n" + + "The type Local is never used locally\n" + + "----------\n" + + "6. WARNING in X.java (at line 13)\n" + + " Object o = new Object() {\n" + + " ^\n" + + "The field Local.o is never read locally\n" + + "----------\n" + + "7. WARNING in X.java (at line 14)\n" + + " int j = hello;\n" + + " ^\n" + + "The field new Object(){}.j is never read locally\n" + + "----------\n"); +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=257716 - variation +public void test203() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " final int hello;\n" + + " public X() {\n" + + " hello = 0;\n" + + " new X() {\n" + + " final int world;\n" + + " {\n" + + " world = 0;\n" + + " }\n" + + " int i = new Object() {\n" + + " int j = hello + world; \n" + + " }.j;\n" + + " };\n" + + " }\n" + + " public X(int i) {\n" + + " new X() {\n" + + " final int world;\n" + + " {\n" + + " world = 0;\n" + + " } \n" + + " int k = new Object() { \n" + + " int l = hello + world; \n" + + " }.l;\n" + + " };\n" + + " }\n" + + "}\n" + + }, + "----------\n" + + "1. WARNING in X.java (at line 10)\n" + + " int i = new Object() {\n" + + " ^\n" + + "The field new X(){}.i is never read locally\n" + + "----------\n" + + "2. ERROR in X.java (at line 15)\n" + + " public X(int i) {\n" + + " ^^^^^^^^\n" + + "The blank final field hello may not have been initialized\n" + + "----------\n" + + "3. WARNING in X.java (at line 21)\n" + + " int k = new Object() { \n" + + " ^\n" + + "The field new X(){}.k is never read locally\n" + + "----------\n" + + "4. ERROR in X.java (at line 22)\n" + + " int l = hello + world; \n" + + " ^^^^^\n" + + "The blank final field hello may not have been initialized\n" + + "----------\n"); } public static Class testClass() { return InitializationTest.class; #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java,v retrieving revision 1.153 diff -u -r1.153 TypeDeclaration.java --- compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java 8 Jan 2009 20:51:05 -0000 1.153 +++ compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java 29 Jan 2009 13:33:33 -0000 @@ -616,8 +616,8 @@ this.scope.problemReporter().unusedPrivateType(this); } } - InitializationFlowContext initializerContext = new InitializationFlowContext(null, this, this.initializerScope); - InitializationFlowContext staticInitializerContext = new InitializationFlowContext(null, this, this.staticInitializerScope); + InitializationFlowContext initializerContext = new InitializationFlowContext(null, this, flowInfo, flowContext, this.initializerScope); + InitializationFlowContext staticInitializerContext = new InitializationFlowContext(null, this, flowInfo, flowContext, this.staticInitializerScope); FlowInfo nonStaticFieldInfo = flowInfo.unconditionalFieldLessCopy(); FlowInfo staticFieldInfo = flowInfo.unconditionalFieldLessCopy(); if (this.fields != null) { @@ -632,11 +632,7 @@ } else {*/ staticInitializerContext.handledExceptions = Binding.ANY_EXCEPTION; // tolerate them all, and record them /*}*/ - staticFieldInfo = - field.analyseCode( - this.staticInitializerScope, - staticInitializerContext, - staticFieldInfo); + staticFieldInfo = field.analyseCode(this.staticInitializerScope, staticInitializerContext, staticFieldInfo); // 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) { @@ -652,8 +648,7 @@ } else {*/ initializerContext.handledExceptions = Binding.ANY_EXCEPTION; // tolerate them all, and record them /*}*/ - nonStaticFieldInfo = - field.analyseCode(this.initializerScope, initializerContext, nonStaticFieldInfo); + nonStaticFieldInfo = field.analyseCode(this.initializerScope, initializerContext, nonStaticFieldInfo); // 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 (nonStaticFieldInfo == FlowInfo.DEAD_END) { Index: compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java,v retrieving revision 1.54 diff -u -r1.54 Clinit.java --- compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java 25 Sep 2008 23:10:29 -0000 1.54 +++ compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java 29 Jan 2009 13:33:32 -0000 @@ -54,6 +54,7 @@ staticInitializerFlowContext.parent, this, Binding.NO_EXCEPTIONS, + staticInitializerFlowContext, this.scope, FlowInfo.DEAD_END); Index: compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java,v retrieving revision 1.111 diff -u -r1.111 TryStatement.java --- compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java 14 Oct 2008 16:04:56 -0000 1.111 +++ compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java 29 Jan 2009 13:33:33 -0000 @@ -87,6 +87,7 @@ flowContext, this, this.caughtExceptionTypes, + null, this.scope, flowInfo.unconditionalInits()); handlingContext.initsOnFinally = @@ -198,6 +199,7 @@ insideSubContext, this, this.caughtExceptionTypes, + null, this.scope, flowInfo.unconditionalInits()); handlingContext.initsOnFinally = Index: compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java,v retrieving revision 1.99 diff -u -r1.99 ConstructorDeclaration.java --- compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java 24 Nov 2008 13:13:43 -0000 1.99 +++ compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java 29 Jan 2009 13:33:32 -0000 @@ -77,6 +77,7 @@ initializerFlowContext.parent, this, this.binding.thrownExceptions, + initializerFlowContext, this.scope, FlowInfo.DEAD_END); initializerFlowContext.checkInitializerExceptions( Index: compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java,v retrieving revision 1.114 diff -u -r1.114 SingleNameReference.java --- compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java 18 Nov 2008 20:23:10 -0000 1.114 +++ compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java 29 Jan 2009 13:33:33 -0000 @@ -63,7 +63,8 @@ FieldBinding fieldBinding; if ((fieldBinding = (FieldBinding) this.binding).isBlankFinal() && currentScope.needBlankFinalFieldInitializationCheck(fieldBinding)) { - if (!flowInfo.isDefinitelyAssigned(fieldBinding)) { + FlowInfo fieldInits = flowContext.getInitsForFinalBlankInitializationCheck(fieldBinding.declaringClass, flowInfo); + if (!fieldInits.isDefinitelyAssigned(fieldBinding)) { currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this); } } @@ -149,7 +150,8 @@ // check if reading a final blank field FieldBinding fieldBinding = (FieldBinding) this.binding; if (fieldBinding.isBlankFinal() && currentScope.needBlankFinalFieldInitializationCheck(fieldBinding)) { - if (!flowInfo.isDefinitelyAssigned(fieldBinding)) { + FlowInfo fieldInits = flowContext.getInitsForFinalBlankInitializationCheck(fieldBinding.declaringClass, flowInfo); + if (!fieldInits.isDefinitelyAssigned(fieldBinding)) { currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this); } } Index: compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java,v retrieving revision 1.125 diff -u -r1.125 FieldReference.java --- compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java 8 Jan 2009 20:51:05 -0000 1.125 +++ compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java 29 Jan 2009 13:33:32 -0000 @@ -56,15 +56,17 @@ } -public FlowInfo analyseAssignment(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, Assignment assignment, boolean isCompound) { +public FlowInfo analyseAssignment(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, Assignment assignment, boolean isCompound) { // compound assignment extra work if (isCompound) { // check the variable part is initialized if blank final if (this.binding.isBlankFinal() && this.receiver.isThis() - && currentScope.needBlankFinalFieldInitializationCheck(this.binding) - && (!flowInfo.isDefinitelyAssigned(this.binding))) { - currentScope.problemReporter().uninitializedBlankFinalField(this.binding, this); - // we could improve error msg here telling "cannot use compound assignment on final blank field" + && currentScope.needBlankFinalFieldInitializationCheck(this.binding)) { + FlowInfo fieldInits = flowContext.getInitsForFinalBlankInitializationCheck(this.binding.declaringClass, flowInfo); + if (!fieldInits.isDefinitelyAssigned(this.binding)) { + currentScope.problemReporter().uninitializedBlankFinalField(this.binding, this); + // we could improve error msg here telling "cannot use compound assignment on final blank field" + } } manageSyntheticAccessIfNecessary(currentScope, flowInfo, true /*read-access*/); } Index: compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java,v retrieving revision 1.68 diff -u -r1.68 MethodDeclaration.java --- compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java 24 Nov 2008 13:13:43 -0000 1.68 +++ compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java 29 Jan 2009 13:33:32 -0000 @@ -68,6 +68,7 @@ initializationContext, this, this.binding.thrownExceptions, + null, this.scope, FlowInfo.DEAD_END); Index: compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java,v retrieving revision 1.137 diff -u -r1.137 QualifiedNameReference.java --- compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java 18 Nov 2008 20:23:10 -0000 1.137 +++ compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java 29 Jan 2009 13:33:32 -0000 @@ -75,10 +75,9 @@ if (lastFieldBinding.isBlankFinal() && this.otherBindings != null // the last field binding is only assigned && currentScope.needBlankFinalFieldInitializationCheck(lastFieldBinding)) { - if (!flowInfo.isDefinitelyAssigned(lastFieldBinding)) { - currentScope.problemReporter().uninitializedBlankFinalField( - lastFieldBinding, - this); + FlowInfo fieldInits = flowContext.getInitsForFinalBlankInitializationCheck(lastFieldBinding.declaringClass, flowInfo); + if (!fieldInits.isDefinitelyAssigned(lastFieldBinding)) { + currentScope.problemReporter().uninitializedBlankFinalField(lastFieldBinding, this); } } break; @@ -116,9 +115,11 @@ if (isCompound) { if (otherBindingsCount == 0 && lastFieldBinding.isBlankFinal() - && currentScope.needBlankFinalFieldInitializationCheck(lastFieldBinding) - && (!flowInfo.isDefinitelyAssigned(lastFieldBinding))) { - currentScope.problemReporter().uninitializedBlankFinalField(lastFieldBinding, this); + && currentScope.needBlankFinalFieldInitializationCheck(lastFieldBinding)) { + FlowInfo fieldInits = flowContext.getInitsForFinalBlankInitializationCheck(lastFieldBinding.declaringClass, flowInfo); + if (!fieldInits.isDefinitelyAssigned(lastFieldBinding)) { + currentScope.problemReporter().uninitializedBlankFinalField(lastFieldBinding, this); + } } manageSyntheticAccessIfNecessary(currentScope, lastFieldBinding, otherBindingsCount, flowInfo); } @@ -176,9 +177,11 @@ FieldBinding fieldBinding = (FieldBinding) this.binding; // check if reading a final blank field if (fieldBinding.isBlankFinal() - && currentScope.needBlankFinalFieldInitializationCheck(fieldBinding) - && !flowInfo.isDefinitelyAssigned(fieldBinding)) { - currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this); + && currentScope.needBlankFinalFieldInitializationCheck(fieldBinding)) { + FlowInfo fieldInits = flowContext.getInitsForFinalBlankInitializationCheck(fieldBinding.declaringClass, flowInfo); + if (!fieldInits.isDefinitelyAssigned(fieldBinding)) { + currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this); + } } } break; Index: eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java,v retrieving revision 1.56 diff -u -r1.56 CodeSnippetSingleNameReference.java --- eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java 25 Sep 2008 23:10:29 -0000 1.56 +++ eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java 29 Jan 2009 13:33:33 -0000 @@ -59,7 +59,8 @@ FieldBinding fieldBinding; if ((fieldBinding = (FieldBinding) this.binding).isBlankFinal() && currentScope.needBlankFinalFieldInitializationCheck(fieldBinding)) { - if (!flowInfo.isDefinitelyAssigned(fieldBinding)) { + FlowInfo fieldInits = flowContext.getInitsForFinalBlankInitializationCheck(fieldBinding.declaringClass, flowInfo); + if (!fieldInits.isDefinitelyAssigned(fieldBinding)) { currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this); } } Index: compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java,v retrieving revision 1.43 diff -u -r1.43 ExceptionHandlingFlowContext.java --- compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java 27 Jun 2008 16:04:13 -0000 1.43 +++ compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java 29 Jan 2009 13:33:33 -0000 @@ -41,7 +41,8 @@ boolean isMethodContext; public UnconditionalFlowInfo initsOnReturn; - + public FlowContext initializationParent; // special parent relationship only for initialization purpose + // for dealing with anonymous constructor thrown exceptions public ArrayList extendedExceptions; @@ -49,6 +50,7 @@ FlowContext parent, ASTNode associatedNode, ReferenceBinding[] handledExceptions, + FlowContext initializationParent, BlockScope scope, UnconditionalFlowInfo flowInfo) { @@ -79,6 +81,7 @@ System.arraycopy(this.isReached, 0, this.isNeeded, 0, cacheSize); } this.initsOnReturn = FlowInfo.DEAD_END; + this. initializationParent = initializationParent; } public void complainIfUnusedExceptionHandlers(AbstractMethodDeclaration method) { Index: compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java,v retrieving revision 1.59 diff -u -r1.59 FlowContext.java --- compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java 12 Sep 2008 19:23:10 -0000 1.59 +++ compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java 29 Jan 2009 13:33:33 -0000 @@ -18,6 +18,7 @@ import org.eclipse.jdt.internal.compiler.ast.Reference; import org.eclipse.jdt.internal.compiler.ast.SubRoutineStatement; import org.eclipse.jdt.internal.compiler.ast.TryStatement; +import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.compiler.codegen.BranchLabel; import org.eclipse.jdt.internal.compiler.lookup.Binding; import org.eclipse.jdt.internal.compiler.lookup.BlockScope; @@ -44,6 +45,25 @@ boolean deferNullDiagnostic, preemptNullDiagnostic; +public static final int + CAN_ONLY_NULL_NON_NULL = 0x0000, + // check against null and non null, with definite values -- comparisons + CAN_ONLY_NULL = 0x0001, + // check against null, with definite values -- comparisons + CAN_ONLY_NON_NULL = 0x0002, + // check against non null, with definite values -- comparisons + MAY_NULL = 0x0003, + // check against null, with potential values -- NPE guard + CHECK_MASK = 0x00FF, + IN_COMPARISON_NULL = 0x0100, + IN_COMPARISON_NON_NULL = 0x0200, + // check happened in a comparison + IN_ASSIGNMENT = 0x0300, + // check happened in an assignment + IN_INSTANCEOF = 0x0400, + // check happened in an instanceof expression + CONTEXT_MASK = ~CHECK_MASK; + public FlowContext(FlowContext parent, ASTNode associatedNode) { this.parent = parent; this.associatedNode = associatedNode; @@ -287,6 +307,28 @@ return null; } +public FlowInfo getInitsForFinalBlankInitializationCheck(ReferenceBinding declaringType, FlowInfo flowInfo) { + FlowContext current = this; + FlowInfo inits = flowInfo; + do { + if (current instanceof InitializationFlowContext) { + InitializationFlowContext initializationContext = (InitializationFlowContext) current; + if (((TypeDeclaration)initializationContext.associatedNode).binding == declaringType) { + return inits; + } + inits = initializationContext.initsBeforeContext; + current = initializationContext.initializationParent; + } else if (current instanceof ExceptionHandlingFlowContext) { + ExceptionHandlingFlowContext exceptionContext = (ExceptionHandlingFlowContext) current; + current = exceptionContext.initializationParent == null ? exceptionContext.parent : exceptionContext.initializationParent; + } else { + current = current.parent; + } + } while (current != null); + // not found + return null; +} + /* * lookup through break labels */ @@ -468,25 +510,6 @@ } } -public static final int - CAN_ONLY_NULL_NON_NULL = 0x0000, - // check against null and non null, with definite values -- comparisons - CAN_ONLY_NULL = 0x0001, - // check against null, with definite values -- comparisons - CAN_ONLY_NON_NULL = 0x0002, - // check against non null, with definite values -- comparisons - MAY_NULL = 0x0003, - // check against null, with potential values -- NPE guard - CHECK_MASK = 0x00FF, - IN_COMPARISON_NULL = 0x0100, - IN_COMPARISON_NON_NULL = 0x0200, - // check happened in a comparison - IN_ASSIGNMENT = 0x0300, - // check happened in an assignment - IN_INSTANCEOF = 0x0400, - // check happened in an instanceof expression - CONTEXT_MASK = ~CHECK_MASK; - /** * Record a null reference for use by deferred checks. Only looping or * finally contexts really record that information. The context may Index: compiler/org/eclipse/jdt/internal/compiler/flow/InitializationFlowContext.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/InitializationFlowContext.java,v retrieving revision 1.17 diff -u -r1.17 InitializationFlowContext.java --- compiler/org/eclipse/jdt/internal/compiler/flow/InitializationFlowContext.java 27 Jun 2008 16:04:13 -0000 1.17 +++ compiler/org/eclipse/jdt/internal/compiler/flow/InitializationFlowContext.java 29 Jan 2009 13:33:33 -0000 @@ -21,22 +21,21 @@ * try statements, exception handlers, etc... */ public class InitializationFlowContext extends ExceptionHandlingFlowContext { - public int exceptionCount; public TypeBinding[] thrownExceptions = new TypeBinding[5]; public ASTNode[] exceptionThrowers = new ASTNode[5]; public FlowInfo[] exceptionThrowerFlowInfos = new FlowInfo[5]; - - public InitializationFlowContext( - FlowContext parent, - ASTNode associatedNode, - BlockScope scope) { + public FlowInfo initsBeforeContext; + + public InitializationFlowContext(FlowContext parent, ASTNode associatedNode, FlowInfo initsBeforeContext, FlowContext initializationParent, BlockScope scope) { super( parent, associatedNode, Binding.NO_EXCEPTIONS, // no exception allowed by default + initializationParent, scope, FlowInfo.DEAD_END); + this.initsBeforeContext = initsBeforeContext; } public void checkInitializerExceptions(