Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 207019 Details for
Bug 247564
[compiler][null] Detecting null field reference
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
[patch]
improved handling of field ids (relative patch)
Bug_247564_delta.patch (text/plain), 28.64 KB, created by
Stephan Herrmann
on 2011-11-15 07:02:41 EST
(
hide
)
Description:
improved handling of field ids (relative patch)
Filename:
MIME Type:
Creator:
Stephan Herrmann
Created:
2011-11-15 07:02:41 EST
Size:
28.64 KB
patch
obsolete
>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 f197e7d..ff155c6 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 >@@ -31,7 +31,7 @@ > > public class FlowAnalysisTest extends AbstractRegressionTest { > static { >-// TESTS_NAMES = new String[] { "testLocalClassInInitializer1" }; >+// TESTS_NAMES = new String[] { "testFinalFieldInNested1" }; > // TESTS_NUMBERS = new int[] { 69 }; > } > public FlowAnalysisTest(String name) { >@@ -2490,6 +2490,31 @@ > "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"); >+} > public static Class testClass() { > return FlowAnalysisTest.class; > } >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 b6566bf..66f8d02 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 >@@ -199,7 +199,6 @@ > 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; >@@ -215,8 +214,6 @@ > if (this.ignoreFurtherInvestigation) > return; > try { >- // propagate down the max field count >- updateMaxFieldCount(); > internalAnalyseCode(null, FlowInfo.initial(this.maxFieldCount)); > } catch (AbortType e) { > this.ignoreFurtherInvestigation = true; >@@ -237,7 +234,6 @@ > 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; >@@ -651,7 +647,7 @@ > // branch, since the previous initializer already got the blame. > if (staticFieldInfo == FlowInfo.DEAD_END) { > this.staticInitializerScope.problemReporter().initializerMustCompleteNormally(field); >- staticFieldInfo = FlowInfo.initial(this.scope.cumulativeFieldCount).setReachMode(FlowInfo.UNREACHABLE); >+ staticFieldInfo = FlowInfo.initial(this.maxFieldCount).setReachMode(FlowInfo.UNREACHABLE); > } > } else { > if ((nonStaticFieldInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) >@@ -667,7 +663,7 @@ > // branch, since the previous initializer already got the blame. > if (nonStaticFieldInfo == FlowInfo.DEAD_END) { > this.initializerScope.problemReporter().initializerMustCompleteNormally(field); >- nonStaticFieldInfo = FlowInfo.initial(this.scope.cumulativeFieldCount).setReachMode(FlowInfo.UNREACHABLE); >+ nonStaticFieldInfo = FlowInfo.initial(this.maxFieldCount).setReachMode(FlowInfo.UNREACHABLE); > } > } > } >@@ -1049,22 +1045,38 @@ > this.typeParameters[i].resolve(this.scope); > } > } >- // field count from supertypes should be included in maxFieldCount, >- // so that a field from supertype doesn't end up with same id as a local variable >- // in a method being analyzed. >+ // field count from enclosing and supertypes should be included in maxFieldCount, >+ // to make field-ids unique among all fields in scope. >+ // 1.: enclosing: >+ if (sourceType instanceof NestedTypeBinding) { >+ // note: local types have no enclosingType in the AST but only in the binding: >+ sourceType.cumulativeFieldCount += ((NestedTypeBinding)sourceType).enclosingType.cumulativeFieldCount; >+ } >+ // 2.: supers: > int superFieldsCount = 0; > ReferenceBinding superClassBinding = sourceType.superclass; > while (superClassBinding != null) { >+// TODO(stephan): this part is pending a discussion how deep we want to go into super types. >+// 1.: consistently avoid calling fields() (also from findFieldCountFromSuperInterfaces()) >+// 2.: consistently check field.kind() (also in findFieldCountFromSuperInterfaces())? > FieldBinding[] unResolvedFields = superClassBinding.unResolvedFields(); > if (unResolvedFields != null) { >- superFieldsCount += unResolvedFields.length; >+ for (int i=unResolvedFields.length-1; i>=0; i--) { >+ switch (unResolvedFields[i].kind()) { >+ case AbstractVariableDeclaration.FIELD: >+ case AbstractVariableDeclaration.ENUM_CONSTANT: >+ superFieldsCount++; >+ } >+ } > } >+// superFieldsCount += superClassBinding.fieldCount(); > superFieldsCount += findFieldCountFromSuperInterfaces(superClassBinding.superInterfaces()); > superClassBinding = superClassBinding.superclass(); > } > ReferenceBinding[] superInterfacesBinding = this.binding.superInterfaces; > superFieldsCount += findFieldCountFromSuperInterfaces(superInterfacesBinding); >- this.scope.cumulativeFieldCount += superFieldsCount; >+ this.binding.cumulativeFieldCount += superFieldsCount; >+ > if (this.fields != null) { > for (int i = 0, count = this.fields.length; i < count; i++) { > FieldDeclaration field = this.fields[i]; >@@ -1085,7 +1097,6 @@ > this.ignoreFurtherInvestigation = true; > continue; > } >- field.binding.id += superFieldsCount; > if (needSerialVersion > && ((fieldBinding.modifiers & (ClassFileConstants.AccStatic | ClassFileConstants.AccFinal)) == (ClassFileConstants.AccStatic | ClassFileConstants.AccFinal)) > && CharOperation.equals(TypeConstants.SERIALVERSIONUID, fieldBinding.name) >@@ -1102,10 +1113,7 @@ > field.resolve(field.isStatic() ? this.staticInitializerScope : this.initializerScope); > } > } >- // if (this.maxFieldCount < localMaxFieldCount) { >- // this.maxFieldCount = localMaxFieldCount; >- // } >- this.maxFieldCount = this.scope.cumulativeFieldCount; >+ this.maxFieldCount = sourceType.cumulativeFieldCount; > if (this.memberTypes != null) { > for (int i = 0, count = this.memberTypes.length; i < count; i++) { > this.memberTypes[i].resolve(this.scope); >@@ -1202,6 +1210,7 @@ > if (superinterfaces == null) > return numOfFields ; > for (int i = 0; i < superinterfaces.length; i++) { >+ // FIXME(stephan): check indirect usage of fields() -> resolveTypeFor(FieldBinding) > numOfFields += superinterfaces[i].fieldCount(); > numOfFields += findFieldCountFromSuperInterfaces(superinterfaces[i].superInterfaces()); > } >@@ -1468,12 +1477,11 @@ > /** > * MaxFieldCount's computation is necessary so as to reserve space for > * the flow info field portions. It corresponds to the maximum amount of >- * fields this class or one of its innertypes have. >+ * accumulated fields this class or one of its innertypes have. > * >- * 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. >+ * 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. > */ > void updateMaxFieldCount() { > if (this.binding == null) >@@ -1481,8 +1489,6 @@ > 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/NullInfoRegistry.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/NullInfoRegistry.java >index 296b7e3..09b442f 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 >@@ -11,7 +11,6 @@ > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.flow; > >-import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; > import org.eclipse.jdt.internal.compiler.lookup.VariableBinding; > > /** >@@ -121,12 +120,7 @@ > // protected from non-object locals in calling methods > if (this != DEAD_END) { > this.tagBits |= NULL_FLAG_MASK; >- int position; >- if (local instanceof FieldBinding) { >- position = local.id; >- } else { >- position = local.id + this.maxFieldCount; >- } >+ int position = local.getAnalysisId(this.maxFieldCount); > // position is zero-based > if (position < BitCacheSize) { // use bits > // set protected non null >@@ -171,13 +165,7 @@ > // protected from non-object locals in calling methods > if (this != DEAD_END) { > this.tagBits |= NULL_FLAG_MASK; >- int position; >- // position is zero-based >- if (local instanceof FieldBinding) { >- position = local.id; >- } else { >- position = local.id + this.maxFieldCount; >- } >+ int position = local.getAnalysisId(this.maxFieldCount); > if (position < BitCacheSize) { // use bits > // set assigned non null > this.nullBit3 |= (1L << position); >@@ -222,12 +210,7 @@ > // protected from non-object locals in calling methods > if (this != DEAD_END) { > this.tagBits |= NULL_FLAG_MASK; >- int position; >- if (local instanceof FieldBinding) { >- position = local.id; >- } else { >- position = local.id + this.maxFieldCount; >- } >+ int position = local.getAnalysisId(this.maxFieldCount); > // position is zero-based > if (position < BitCacheSize) { // use bits > // set assigned null >@@ -272,12 +255,7 @@ > // protected from non-object locals in calling methods > if (this != DEAD_END) { > this.tagBits |= NULL_FLAG_MASK; >- int position; >- if (local instanceof FieldBinding) { >- position = local.id; >- } else { >- position = local.id + this.maxFieldCount; >- } >+ int position = local.getAnalysisId(this.maxFieldCount); > // position is zero-based > if (position < BitCacheSize) { // use bits > // set assigned unknown >@@ -432,13 +410,8 @@ > // protected from non-object locals in calling methods > if (this != DEAD_END) { > this.tagBits |= NULL_FLAG_MASK; >- int position; > long mask; >- if (local instanceof FieldBinding) { >- position = local.id; >- } else { >- position = local.id + this.maxFieldCount; >- } >+ int position = local.getAnalysisId(this.maxFieldCount); > if (position < BitCacheSize) { > // use bits > mask = 1L << position; >@@ -483,13 +456,8 @@ > public void markPotentiallyNullBit(VariableBinding local) { > if (this != DEAD_END) { > this.tagBits |= NULL_FLAG_MASK; >- int position; >- long mask; >- if (local instanceof FieldBinding) { >- position = local.id; >- } else { >- position = local.id + this.maxFieldCount; >- } >+ long mask; >+ int position = local.getAnalysisId(this.maxFieldCount); > if (position < BitCacheSize) { > // use bits > mask = 1L << position; >@@ -534,13 +502,8 @@ > public void markPotentiallyNonNullBit(VariableBinding local) { > if (this != DEAD_END) { > this.tagBits |= NULL_FLAG_MASK; >- int position; > long mask; >- if (local instanceof FieldBinding) { >- position = local.id; >- } else { >- position = local.id + this.maxFieldCount; >- } >+ int position = local.getAnalysisId(this.maxFieldCount); > if (position < BitCacheSize) { > // use bits > mask = 1L << position; >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 74eecbf..08bcb3a 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 >@@ -526,12 +526,7 @@ > (local.type.tagBits & TagBits.IsBaseType) != 0) { > return false; > } >- int position; >- if (local instanceof FieldBinding) { >- position = local.id; >- } else { >- position = local.id + this.maxFieldCount; >- } >+ int position = local.getAnalysisId(this.maxFieldCount); > if (position < BitCacheSize) { > // use bits > return ( >@@ -562,12 +557,7 @@ > (local.type.tagBits & TagBits.IsBaseType) != 0) { > return false; > } >- int position; >- if (local instanceof FieldBinding) { >- position = local.id; >- } else { >- position = local.id + this.maxFieldCount; >- } >+ int position = local.getAnalysisId(this.maxFieldCount); > if (position < BitCacheSize) { > // use bits > return (this.nullBit1 & this.nullBit3 >@@ -594,12 +584,7 @@ > (local.type.tagBits & TagBits.IsBaseType) != 0) { > return false; > } >- int position; >- if (local instanceof FieldBinding) { >- position = local.id; >- } else { >- position = local.id + this.maxFieldCount; >- } >+ int position = local.getAnalysisId(this.maxFieldCount); > if (position < BitCacheSize) { > // use bits > return (this.nullBit1 & this.nullBit2 >@@ -755,7 +740,7 @@ > if ((this.tagBits & UNREACHABLE_OR_DEAD) != 0) { > return true; > } >- return isDefinitelyAssigned(field.id); >+ return isDefinitelyAssigned(field.getAnalysisId(this.maxFieldCount)); > } > > final public boolean isDefinitelyAssigned(LocalVariableBinding local) { >@@ -782,16 +767,13 @@ > local.constant() != Constant.NotAConstant) { // String instances > return true; > } >- int position; > if (local instanceof FieldBinding) { > if (local.isFinal() && ((FieldBinding)local).isStatic()) { > // static final field's null status may not be in the flow info > return (((FieldBinding) local).getNullStatusForStaticFinalField() == FlowInfo.NON_NULL); > } >- position = local.id; >- } else { >- position = local.id + this.maxFieldCount; > } >+ int position = local.getAnalysisId(this.maxFieldCount); > if (position < BitCacheSize) { // use bits > return ((this.nullBit1 & this.nullBit3 & (~this.nullBit2 | this.nullBit4)) > & (1L << position)) != 0; >@@ -823,16 +805,13 @@ > (local.type.tagBits & TagBits.IsBaseType) != 0) { > return false; > } >- int position; > if (local instanceof FieldBinding) { > if (local.isFinal() && ((FieldBinding)local).isStatic()) { > // static final field's null status may not be in the flow info > return (((FieldBinding) local).getNullStatusForStaticFinalField() == FlowInfo.NULL); > } >- position = local.id; >- } else { >- position = local.id + this.maxFieldCount; > } >+ int position = local.getAnalysisId(this.maxFieldCount); > if (position < BitCacheSize) { // use bits > return ((this.nullBit1 & this.nullBit2 > & (~this.nullBit3 | ~this.nullBit4)) >@@ -858,12 +837,7 @@ > (this.tagBits & NULL_FLAG_MASK) == 0) { > return false; > } >- int position; >- if (local instanceof FieldBinding) { >- position = local.id; >- } else { >- position = local.id + this.maxFieldCount; >- } >+ int position = local.getAnalysisId(this.maxFieldCount); > if (position < BitCacheSize) { // use bits > return ((this.nullBit1 & this.nullBit4 > & ~this.nullBit2 & ~this.nullBit3) & (1L << position)) != 0; >@@ -905,7 +879,7 @@ > } > > final public boolean isPotentiallyAssigned(FieldBinding field) { >- return isPotentiallyAssigned(field.id); >+ return isPotentiallyAssigned(field.getAnalysisId(this.maxFieldCount)); > } > > final public boolean isPotentiallyAssigned(LocalVariableBinding local) { >@@ -922,12 +896,7 @@ > (local.type.tagBits & TagBits.IsBaseType) != 0) { > return false; > } >- int position; >- if (local instanceof FieldBinding) { >- position = local.id; >- } else { >- position = local.id + this.maxFieldCount; >- } >+ int position = local.getAnalysisId(this.maxFieldCount); > if (position < BitCacheSize) { // use bits > // use bits > return ((this.nullBit3 & (~this.nullBit1 | ~this.nullBit2)) >@@ -953,16 +922,13 @@ > (local.type.tagBits & TagBits.IsBaseType) != 0) { > return false; > } >- int position; > if (local instanceof FieldBinding) { > if (local.isFinal() && ((FieldBinding)local).isStatic()) { > // static final field's null status may not be in the flow info > return (((FieldBinding) local).getNullStatusForStaticFinalField() == FlowInfo.POTENTIALLY_NULL); > } >- position = local.id; >- } else { >- position = local.id + this.maxFieldCount; > } >+ int position = local.getAnalysisId(this.maxFieldCount); > if (position < BitCacheSize) { > // use bits > return ((this.nullBit2 & (~this.nullBit1 | ~this.nullBit3)) >@@ -988,12 +954,7 @@ > (this.tagBits & NULL_FLAG_MASK) == 0) { > return false; > } >- int position; >- if (local instanceof FieldBinding) { >- position = local.id; >- } else { >- position = local.id + this.maxFieldCount; >- } >+ int position = local.getAnalysisId(this.maxFieldCount); > if (position < BitCacheSize) { // use bits > return (this.nullBit4 > & (~this.nullBit1 | ~this.nullBit2 & ~this.nullBit3) >@@ -1019,12 +980,7 @@ > (local.type.tagBits & TagBits.IsBaseType) != 0) { > return false; > } >- int position; >- if (local instanceof FieldBinding) { >- position = local.id; >- } else { >- position = local.id + this.maxFieldCount; >- } >+ int position = local.getAnalysisId(this.maxFieldCount); > if (position < BitCacheSize) { // use bits > return (this.nullBit1 & this.nullBit3 & this.nullBit4 & (1L << position)) != 0; > } >@@ -1048,12 +1004,7 @@ > (local.type.tagBits & TagBits.IsBaseType) != 0) { > return false; > } >- int position; >- if (local instanceof FieldBinding) { >- position = local.id; >- } else { >- position = local.id + this.maxFieldCount; >- } >+ int position = local.getAnalysisId(this.maxFieldCount); > if (position < BitCacheSize) { > // use bits > return (this.nullBit1 & this.nullBit2 >@@ -1326,7 +1277,7 @@ > > public void markAsDefinitelyAssigned(FieldBinding field) { > if (this != DEAD_END) >- markAsDefinitelyAssigned(field.id); >+ markAsDefinitelyAssigned(field.getAnalysisId(this.maxFieldCount)); > } > > public void markAsDefinitelyAssigned(LocalVariableBinding local) { >@@ -1465,13 +1416,7 @@ > if (this != DEAD_END) { > this.tagBits |= NULL_FLAG_MASK; > long mask; >- int position; >- // position is zero-based >- if (local instanceof FieldBinding) { >- position = local.id; >- } else { >- position = local.id + this.maxFieldCount; >- } >+ int position = local.getAnalysisId(this.maxFieldCount); > if (position < BitCacheSize) { > // use bits > // mark assigned null >@@ -1523,13 +1468,8 @@ > public void resetNullInfo(VariableBinding local) { > if (this != DEAD_END) { > this.tagBits |= NULL_FLAG_MASK; >- int position; > long mask; >- if (local instanceof FieldBinding) { >- position = local.id; >- } else { >- position = local.id + this.maxFieldCount; >- } >+ int position = local.getAnalysisId(this.maxFieldCount); > if (position < BitCacheSize) { > // use bits > this.nullBit1 &= (mask = ~(1L << position)); >@@ -1593,13 +1533,8 @@ > // protected from non-object locals in calling methods > if (this != DEAD_END) { > this.tagBits |= NULL_FLAG_MASK; >- int position; > long mask; >- if (local instanceof FieldBinding) { >- position = local.id; >- } else { >- position = local.id + this.maxFieldCount; >- } >+ int position = local.getAnalysisId(this.maxFieldCount); > if (position < BitCacheSize) { > // use bits > mask = 1L << position; >@@ -1645,13 +1580,8 @@ > public void markPotentiallyNullBit(VariableBinding local) { > if (this != DEAD_END) { > this.tagBits |= NULL_FLAG_MASK; >- int position; > long mask; >- if (local instanceof FieldBinding) { >- position = local.id; >- } else { >- position = local.id + this.maxFieldCount; >- } >+ int position = local.getAnalysisId(this.maxFieldCount); > if (position < BitCacheSize) { > // use bits > mask = 1L << position; >@@ -1697,13 +1627,8 @@ > public void markPotentiallyNonNullBit(VariableBinding local) { > if (this != DEAD_END) { > this.tagBits |= NULL_FLAG_MASK; >- int position; > long mask; >- if (local instanceof FieldBinding) { >- position = local.id; >- } else { >- position = local.id + this.maxFieldCount; >- } >+ int position = local.getAnalysisId(this.maxFieldCount); > if (position < BitCacheSize) { > // use bits > mask = 1L << position; >@@ -2238,12 +2163,7 @@ > } > > public void markedAsNullOrNonNullInAssertExpression(VariableBinding binding) { >- int position; >- if (binding instanceof FieldBinding) { >- position = binding.id; >- } else { >- position = binding.id + this.maxFieldCount; >- } >+ int position = binding.getAnalysisId(this.maxFieldCount); > int oldLength; > if (this.nullStatusChangedInAssert == null) { > this.nullStatusChangedInAssert = new int[position + 1]; >@@ -2257,12 +2177,7 @@ > } > > public boolean isMarkedAsNullOrNonNullInAssertExpression(VariableBinding binding) { >- int position; >- if (binding instanceof FieldBinding) { >- position = binding.id; >- } else { >- position = binding.id + this.maxFieldCount; >- } >+ int position = binding.getAnalysisId(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/lookup/ClassScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java >index 16c3b5c..298a10f 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 >@@ -39,13 +39,10 @@ > public TypeDeclaration referenceContext; > public TypeReference superTypeReference; > java.util.ArrayList deferredBoundChecks; >- public int cumulativeFieldCount; // cumulative field count from all enclosing types, used to build unique field id's for member types. >- public int localTypeFieldIdStart; > public ClassScope(Scope parent, TypeDeclaration context) { > super(Scope.CLASS_SCOPE, parent); > this.referenceContext = context; > this.deferredBoundChecks = null; // initialized if required >- this.localTypeFieldIdStart = this.cumulativeFieldCount = 0; > } > > void buildAnonymousTypeBinding(SourceTypeBinding enclosingType, ReferenceBinding supertype) { >@@ -82,8 +79,7 @@ > } > } > } >- this.cumulativeFieldCount += outerMostMethodScope().analysisIndex; >- this.localTypeFieldIdStart = outerMostMethodScope().analysisIndex; >+ this.referenceContext.binding.cumulativeFieldCount += outerMostMethodScope().analysisIndex; > connectMemberTypes(); > buildFieldsAndMethods(); > anonymousType.faultInTypesForFieldsAndMethods(); >@@ -113,23 +109,6 @@ > FieldBinding[] fieldBindings = new FieldBinding[count]; > HashtableOfObject knownFieldNames = new HashtableOfObject(count); > count = 0; >- ClassScope enclosingClass = this.enclosingClassScope(); >- if (enclosingClass != null) { >- this.cumulativeFieldCount += enclosingClass.cumulativeFieldCount; >- } >-// SourceTypeBinding enclosingSourceType = this.enclosingSourceType(); >-// if (enclosingSourceType != null) { >-// ReferenceBinding superClassBinding = sourceType.superclass; >-// while (superClassBinding != null) { >-// FieldBinding[] unResolvedFields = superClassBinding.unResolvedFields(); >-// if (unResolvedFields != null) { >-// this.cumulativeFieldCount += unResolvedFields.length; >-// } >-// superClassBinding = superClassBinding.superclass(); >-// } >-// ReferenceBinding[] superInterfacesBinding = enclosingSourceType.superInterfaces; >-// this.cumulativeFieldCount += findFieldCountFromSuperInterfaces(superInterfacesBinding); >-// } > for (int i = 0; i < size; i++) { > FieldDeclaration field = fields[i]; > if (field.getKind() == AbstractVariableDeclaration.INITIALIZER) { >@@ -137,7 +116,7 @@ > // now this error reporting is moved into the parser itself. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=212713 > } else { > FieldBinding fieldBinding = new FieldBinding(field, null, field.modifiers | ExtraCompilerModifiers.AccUnresolved, sourceType); >- fieldBinding.id = count + this.cumulativeFieldCount; >+ fieldBinding.id = count; > // field's type will be resolved when needed for top level types > checkAndSetModifiersForField(fieldBinding, field); > >@@ -165,7 +144,7 @@ > // remove duplicate fields > if (count != fieldBindings.length) > System.arraycopy(fieldBindings, 0, fieldBindings = new FieldBinding[count], 0, count); >- this.cumulativeFieldCount += count; >+ sourceType.cumulativeFieldCount += count; > sourceType.tagBits &= ~(TagBits.AreFieldsSorted|TagBits.AreFieldsComplete); // in case some static imports reached already into this type > sourceType.setFields(fieldBindings); > } >@@ -248,8 +227,7 @@ > checkParameterizedTypeBounds(); > checkParameterizedSuperTypeCollisions(); > } >- this.cumulativeFieldCount += outerMostMethodScope().analysisIndex; >- this.localTypeFieldIdStart = outerMostMethodScope().analysisIndex; >+ this.referenceContext.binding.cumulativeFieldCount += outerMostMethodScope().analysisIndex; > buildFieldsAndMethods(); > localType.faultInTypesForFieldsAndMethods(); > >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 dc36d91..17337e7 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 >@@ -279,6 +279,12 @@ > return originalField.tagBits; > } > >+public int getAnalysisId(int maxFieldCount) { >+ if (this.declaringClass instanceof NestedTypeBinding) >+ return ((NestedTypeBinding) this.declaringClass).enclosingType.cumulativeFieldCount + 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/SourceTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java >index d1f9cf4..1a7935b 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 >@@ -41,6 +41,7 @@ > public TypeVariableBinding[] typeVariables; > > public ClassScope scope; >+ 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 >@@ -62,6 +63,7 @@ > this.modifiers = scope.referenceContext.modifiers; > this.sourceName = scope.referenceContext.name; > this.scope = scope; >+ this.cumulativeFieldCount = 0; > > // expect the fields & methods to be initialized correctly later > this.fields = Binding.UNINITIALIZED_FIELDS; >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 dc39e36..273f2af 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 >@@ -37,6 +37,10 @@ > return this.constant; > } > >+ public int getAnalysisId(int maxFieldCount) { >+ return this.id + maxFieldCount; >+ } >+ > public abstract AnnotationBinding[] getAnnotations(); > > public final boolean isBlankFinal(){
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 247564
:
185536
|
185729
|
186938
|
187094
|
188023
|
206514
|
206570
|
206572
| 207019 |
209475
|
209486
|
209552
|
209734
|
209741
|
209759
|
209774
|
209775