### Eclipse Workspace Patch 1.0
#P org.eclipse.jdt.core
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.57
diff -u -r1.57 FlowContext.java
--- compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java 2 Apr 2007 11:05:51 -0000 1.57
+++ compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java 29 Jan 2009 17:06:52 -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(TypeBinding 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.16
diff -u -r1.16 InitializationFlowContext.java
--- compiler/org/eclipse/jdt/internal/compiler/flow/InitializationFlowContext.java 28 Mar 2006 20:32:37 -0000 1.16
+++ compiler/org/eclipse/jdt/internal/compiler/flow/InitializationFlowContext.java 29 Jan 2009 17:06:52 -0000
@@ -26,17 +26,17 @@
public TypeBinding[] thrownExceptions = new TypeBinding[5];
public ASTNode[] exceptionThrowers = new ASTNode[5];
public FlowInfo[] exceptionThrowerFlowInfos = new FlowInfo[5];
+ public FlowInfo initsBeforeContext;
- public InitializationFlowContext(
- FlowContext parent,
- ASTNode associatedNode,
- BlockScope scope) {
+ 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(
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.42
diff -u -r1.42 ExceptionHandlingFlowContext.java
--- compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java 5 Mar 2008 07:57:20 -0000 1.42
+++ compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java 29 Jan 2009 17:06:52 -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/ast/TypeDeclaration.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java,v
retrieving revision 1.148
diff -u -r1.148 TypeDeclaration.java
--- compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java 27 May 2008 22:21:13 -0000 1.148
+++ compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java 29 Jan 2009 17:06:52 -0000
@@ -594,8 +594,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) {
@@ -610,11 +610,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) {
@@ -630,8 +626,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.51.2.1
diff -u -r1.51.2.1 Clinit.java
--- compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java 1 Jul 2008 11:24:16 -0000 1.51.2.1
+++ compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java 29 Jan 2009 17:06:49 -0000
@@ -53,6 +53,7 @@
staticInitializerFlowContext.parent,
this,
Binding.NO_EXCEPTIONS,
+ staticInitializerFlowContext,
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.108
diff -u -r1.108 TryStatement.java
--- compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java 31 Aug 2007 19:41:31 -0000 1.108
+++ compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java 29 Jan 2009 17:06:51 -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.92.2.2
diff -u -r1.92.2.2 ConstructorDeclaration.java
--- compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java 8 Jul 2008 13:22:06 -0000 1.92.2.2
+++ compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java 29 Jan 2009 17:06:50 -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.103.2.3
diff -u -r1.103.2.3 SingleNameReference.java
--- compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java 27 Nov 2008 10:13:10 -0000 1.103.2.3
+++ compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java 29 Jan 2009 17:06:51 -0000
@@ -62,7 +62,8 @@
FieldBinding fieldBinding;
if ((fieldBinding = (FieldBinding) this.binding).isBlankFinal()
&& currentScope.needBlankFinalFieldInitializationCheck(fieldBinding)) {
- if (!flowInfo.isDefinitelyAssigned(fieldBinding)) {
+ FlowInfo fieldInits = flowContext.getInitsForFinalBlankInitializationCheck(fieldBinding.declaringClass.original(), flowInfo);
+ if (!fieldInits.isDefinitelyAssigned(fieldBinding)) {
currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this);
}
}
@@ -148,7 +149,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.original(), 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.116.2.2
diff -u -r1.116.2.2 FieldReference.java
--- compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java 2 Oct 2008 15:29:33 -0000 1.116.2.2
+++ compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java 29 Jan 2009 17:06:50 -0000
@@ -57,15 +57,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.original(), 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/QualifiedNameReference.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java,v
retrieving revision 1.125.2.3
diff -u -r1.125.2.3 QualifiedNameReference.java
--- compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java 27 Nov 2008 10:13:10 -0000 1.125.2.3
+++ compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java 29 Jan 2009 17:06:50 -0000
@@ -74,10 +74,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.original(), flowInfo);
+ if (!fieldInits.isDefinitelyAssigned(lastFieldBinding)) {
+ currentScope.problemReporter().uninitializedBlankFinalField(lastFieldBinding, this);
}
}
break;
@@ -122,9 +121,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.original(), flowInfo);
+ if (!fieldInits.isDefinitelyAssigned(lastFieldBinding)) {
+ currentScope.problemReporter().uninitializedBlankFinalField(lastFieldBinding, this);
+ }
}
TypeBinding lastReceiverType;
switch (otherBindingsCount) {
@@ -212,9 +213,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.original(), flowInfo);
+ if (!fieldInits.isDefinitelyAssigned(fieldBinding)) {
+ currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this);
+ }
}
}
break;
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.65
diff -u -r1.65 MethodDeclaration.java
--- compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java 27 May 2008 22:21:13 -0000 1.65
+++ compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java 29 Jan 2009 17:06:50 -0000
@@ -72,6 +72,7 @@
initializationContext,
this,
this.binding.thrownExceptions,
+ null,
this.scope,
FlowInfo.DEAD_END);
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.52
diff -u -r1.52 CodeSnippetSingleNameReference.java
--- eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java 27 May 2008 22:27:12 -0000 1.52
+++ eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java 29 Jan 2009 17:06:52 -0000
@@ -45,7 +45,8 @@
FieldBinding fieldBinding;
if ((fieldBinding = (FieldBinding) this.binding).isBlankFinal()
&& currentScope.needBlankFinalFieldInitializationCheck(fieldBinding)) {
- if (!flowInfo.isDefinitelyAssigned(fieldBinding)) {
+ FlowInfo fieldInits = flowContext.getInitsForFinalBlankInitializationCheck(fieldBinding.declaringClass.original(), flowInfo);
+ if (!fieldInits.isDefinitelyAssigned(fieldBinding)) {
currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this);
}
}