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 63595 Details for
Bug 146556
Should refactor boolean fields into bits
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
Proposed patch for a subset of the issues
146556.txt (text/plain), 42.59 KB, created by
Philipe Mulet
on 2007-04-12 06:35:48 EDT
(
hide
)
Description:
Proposed patch for a subset of the issues
Filename:
MIME Type:
Creator:
Philipe Mulet
Created:
2007-04-12 06:35:48 EDT
Size:
42.59 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.jdt.core >Index: compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java,v >retrieving revision 1.81 >diff -u -r1.81 ASTNode.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java 6 Mar 2007 02:38:48 -0000 1.81 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java 12 Apr 2007 10:34:50 -0000 >@@ -27,7 +27,7 @@ > public final static int Bit2 = 0x2; // return type (operator) | name reference kind (name ref) | has local type (type, method, field decl) > public final static int Bit3 = 0x4; // return type (operator) | name reference kind (name ref) | implicit this (this ref) > public final static int Bit4 = 0x8; // return type (operator) | first assignment to local (name ref,local decl) | undocumented empty block (block, type and method decl) >- public final static int Bit5 = 0x10; // value for return (expression) | has all method bodies (unit) | supertype ref (type ref) >+ public final static int Bit5 = 0x10; // value for return (expression) | has all method bodies (unit) | supertype ref (type ref) | resolved (field decl) > public final static int Bit6 = 0x20; // depth (name ref, msg) | ignore need cast check (cast expression) > public final static int Bit7 = 0x40; // depth (name ref, msg) | operator (operator) | need runtime checkcast (cast expression) | label used (labelStatement) > public final static int Bit8 = 0x80; // depth (name ref, msg) | operator (operator) | unsafe cast (cast expression) >@@ -36,7 +36,7 @@ > public final static int Bit11 = 0x400; // depth (name ref, msg) | operator (operator) | is member type (type decl) > public final static int Bit12 = 0x800; // depth (name ref, msg) | operator (operator) | has abstract methods (type decl) > public final static int Bit13 = 0x1000; // depth (name ref, msg) | is secondary type (type decl) >- public final static int Bit14 = 0x2000; // strictly assigned (reference lhs) >+ public final static int Bit14 = 0x2000; // strictly assigned (reference lhs) | discard enclosing instance (explicit constr call) > public final static int Bit15 = 0x4000; // is unnecessary cast (expression) | is varargs (type ref) | isSubRoutineEscaping (try statement) > public final static int Bit16 = 0x8000; // in javadoc comment (name ref, type ref, msg) > public final static int Bit17 = 0x10000; // compound assigned (reference lhs) >@@ -141,6 +141,7 @@ > > // for type, method and field declarations > public static final int HasLocalType = Bit2; // cannot conflict with AddAssertionMASK >+ public static final int HasBeenResolved = Bit5; // field decl only (to handle forward references) > > // for expression > public static final int ParenthesizedSHIFT = 21; // Bit22 -> Bit29 >@@ -151,6 +152,9 @@ > public static final int IsStrictlyAssigned = Bit14; // set only for true assignments, as opposed to compound ones > public static final int IsCompoundAssigned = Bit17; // set only for compound assignments, as opposed to other ones > >+ // for explicit constructor call >+ public static final int DiscardEnclosingInstance = Bit14; // used for codegen >+ > // for empty statement > public static final int IsUsefulEmptyStatement = Bit1; > >Index: compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java,v >retrieving revision 1.81 >diff -u -r1.81 FieldDeclaration.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java 6 Mar 2007 02:38:48 -0000 1.81 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java 12 Apr 2007 10:34:50 -0000 >@@ -20,7 +20,6 @@ > public class FieldDeclaration extends AbstractVariableDeclaration { > > public FieldBinding binding; >- boolean hasBeenResolved = false; // TODO (philippe) should use a tagBit instead > public Javadoc javadoc; > > //allows to retrieve both the "type" part of the declaration (part1) >@@ -34,270 +33,257 @@ > public int endPart1Position; > public int endPart2Position; > >- public FieldDeclaration() { >- // for subtypes or conversion >- } >+public FieldDeclaration() { >+ // for subtypes or conversion >+} > >- public FieldDeclaration( >- char[] name, >- int sourceStart, >- int sourceEnd) { >- >- this.name = name; >- >- //due to some declaration like >- // int x, y = 3, z , x ; >- //the sourceStart and the sourceEnd is ONLY on the name >- this.sourceStart = sourceStart; >- this.sourceEnd = sourceEnd; >- } >+public FieldDeclaration( char[] name, int sourceStart, int sourceEnd) { >+ this.name = name; >+ //due to some declaration like >+ // int x, y = 3, z , x ; >+ //the sourceStart and the sourceEnd is ONLY on the name >+ this.sourceStart = sourceStart; >+ this.sourceEnd = sourceEnd; >+} > >- public FlowInfo analyseCode( >- MethodScope initializationScope, >- FlowContext flowContext, >- FlowInfo flowInfo) { >- >- if (this.binding != null && !this.binding.isUsed()) { >- if (this.binding.isPrivate() || (this.binding.declaringClass != null && this.binding.declaringClass.isLocalType())) { >- if (!initializationScope.referenceCompilationUnit().compilationResult.hasSyntaxError) { >- initializationScope.problemReporter().unusedPrivateField(this); >- } >+public FlowInfo analyseCode(MethodScope initializationScope, FlowContext flowContext, FlowInfo flowInfo) { >+ if (this.binding != null && !this.binding.isUsed()) { >+ if (this.binding.isPrivate() || (this.binding.declaringClass != null && this.binding.declaringClass.isLocalType())) { >+ if (!initializationScope.referenceCompilationUnit().compilationResult.hasSyntaxError) { >+ initializationScope.problemReporter().unusedPrivateField(this); > } > } >- // cannot define static non-constant field inside nested class >- if (this.binding != null >- && this.binding.isValidBinding() >- && this.binding.isStatic() >- && this.binding.constant() == Constant.NotAConstant >- && this.binding.declaringClass.isNestedType() >- && !this.binding.declaringClass.isStatic()) { >- initializationScope.problemReporter().unexpectedStaticModifierForField( >- (SourceTypeBinding) this.binding.declaringClass, >- this); >- } >- >- if (this.initialization != null) { >- flowInfo = >- this.initialization >- .analyseCode(initializationScope, flowContext, flowInfo) >- .unconditionalInits(); >- flowInfo.markAsDefinitelyAssigned(this.binding); >- } >- return flowInfo; > } >- >- /** >- * Code generation for a field declaration: >- * standard assignment to a field >- * >- * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope >- * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream >- */ >- public void generateCode(BlockScope currentScope, CodeStream codeStream) { >- >- if ((this.bits & IsReachable) == 0) { >- return; >- } >- // do not generate initialization code if final and static (constant is then >- // recorded inside the field itself). >- int pc = codeStream.position; >- boolean isStatic; >- if (this.initialization != null >- && !((isStatic = this.binding.isStatic()) && this.binding.constant() != Constant.NotAConstant)) { >- // non-static field, need receiver >- if (!isStatic) >- codeStream.aload_0(); >- // generate initialization value >- this.initialization.generateCode(currentScope, codeStream, true); >- // store into field >- if (isStatic) { >- codeStream.putstatic(this.binding); >- } else { >- codeStream.putfield(this.binding); >- } >- } >- codeStream.recordPositionsFrom(pc, this.sourceStart); >+ // cannot define static non-constant field inside nested class >+ if (this.binding != null >+ && this.binding.isValidBinding() >+ && this.binding.isStatic() >+ && this.binding.constant() == Constant.NotAConstant >+ && this.binding.declaringClass.isNestedType() >+ && !this.binding.declaringClass.isStatic()) { >+ initializationScope.problemReporter().unexpectedStaticModifierForField( >+ (SourceTypeBinding) this.binding.declaringClass, >+ this); > } > >- /** >- * @see org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration#getKind() >- */ >- public int getKind() { >- return this.type == null ? ENUM_CONSTANT : FIELD; >+ if (this.initialization != null) { >+ flowInfo = >+ this.initialization >+ .analyseCode(initializationScope, flowContext, flowInfo) >+ .unconditionalInits(); >+ flowInfo.markAsDefinitelyAssigned(this.binding); > } >- >- public boolean isStatic() { >+ return flowInfo; >+} > >- if (this.binding != null) >- return this.binding.isStatic(); >- return (this.modifiers & ClassFileConstants.AccStatic) != 0; >+/** >+ * Code generation for a field declaration: >+ * standard assignment to a field >+ * >+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope >+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream >+ */ >+public void generateCode(BlockScope currentScope, CodeStream codeStream) { >+ if ((this.bits & IsReachable) == 0) { >+ return; > } >- >- public StringBuffer printStatement(int indent, StringBuffer output) { >- if (this.javadoc != null) { >- this.javadoc.print(indent, output); >+ // do not generate initialization code if final and static (constant is then >+ // recorded inside the field itself). >+ int pc = codeStream.position; >+ boolean isStatic; >+ if (this.initialization != null >+ && !((isStatic = this.binding.isStatic()) && this.binding.constant() != Constant.NotAConstant)) { >+ // non-static field, need receiver >+ if (!isStatic) >+ codeStream.aload_0(); >+ // generate initialization value >+ this.initialization.generateCode(currentScope, codeStream, true); >+ // store into field >+ if (isStatic) { >+ codeStream.putstatic(this.binding); >+ } else { >+ codeStream.putfield(this.binding); > } >- return super.printStatement(indent, output); > } >+ codeStream.recordPositionsFrom(pc, this.sourceStart); >+} > >- public void resolve(MethodScope initializationScope) { >+/** >+ * @see org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration#getKind() >+ */ >+public int getKind() { >+ return this.type == null ? ENUM_CONSTANT : FIELD; >+} > >- // the two <constant = Constant.NotAConstant> could be regrouped into >- // a single line but it is clearer to have two lines while the reason of their >- // existence is not at all the same. See comment for the second one. >+public boolean isStatic() { >+ if (this.binding != null) >+ return this.binding.isStatic(); >+ return (this.modifiers & ClassFileConstants.AccStatic) != 0; >+} > >- //-------------------------------------------------------- >- if (!this.hasBeenResolved && this.binding != null && this.binding.isValidBinding()) { >+public StringBuffer printStatement(int indent, StringBuffer output) { >+ if (this.javadoc != null) { >+ this.javadoc.print(indent, output); >+ } >+ return super.printStatement(indent, output); >+} > >- this.hasBeenResolved = true; >+public void resolve(MethodScope initializationScope) { >+ // the two <constant = Constant.NotAConstant> could be regrouped into >+ // a single line but it is clearer to have two lines while the reason of their >+ // existence is not at all the same. See comment for the second one. >+ >+ //-------------------------------------------------------- >+ if ((this.bits & ASTNode.HasBeenResolved) != 0) return; >+ if (this.binding == null || !this.binding.isValidBinding()) return; >+ >+ this.bits |= ASTNode.HasBeenResolved; > >- // check if field is hiding some variable - issue is that field binding already got inserted in scope >- // thus must lookup separately in super type and outer context >- ClassScope classScope = initializationScope.enclosingClassScope(); >- >- if (classScope != null) { >- checkHiding: { >- SourceTypeBinding declaringType = classScope.enclosingSourceType(); >- checkHidingSuperField: { >- if (declaringType.superclass == null) break checkHidingSuperField; >- Binding existingVariable = classScope.findField(declaringType.superclass, this.name, this, false /*do not resolve hidden field*/); >- if (existingVariable == null) break checkHidingSuperField; // keep checking outer scenario >- if (!existingVariable.isValidBinding()) break checkHidingSuperField; // keep checking outer scenario >- if (existingVariable instanceof FieldBinding) { >- FieldBinding existingField = (FieldBinding) existingVariable; >- if (existingField.original() == this.binding) break checkHidingSuperField; // keep checking outer scenario >- } >- // collision with supertype field >- initializationScope.problemReporter().fieldHiding(this, existingVariable); >- break checkHiding; // already found a matching field >- } >- // only corner case is: lookup of outer field through static declaringType, which isn't detected by #getBinding as lookup starts >- // from outer scope. Subsequent static contexts are detected for free. >- Scope outerScope = classScope.parent; >- if (outerScope.kind == Scope.COMPILATION_UNIT_SCOPE) break checkHiding; >- Binding existingVariable = outerScope.getBinding(this.name, Binding.VARIABLE, this, false /*do not resolve hidden field*/); >- if (existingVariable == null) break checkHiding; >- if (!existingVariable.isValidBinding()) break checkHiding; >- if (existingVariable == this.binding) break checkHiding; >- if (existingVariable instanceof FieldBinding) { >- FieldBinding existingField = (FieldBinding) existingVariable; >- if (existingField.original() == this.binding) break checkHiding; >- if (!existingField.isStatic() && declaringType.isStatic()) break checkHiding; >- } >- // collision with outer field or local variable >- initializationScope.problemReporter().fieldHiding(this, existingVariable); >+ // check if field is hiding some variable - issue is that field binding already got inserted in scope >+ // thus must lookup separately in super type and outer context >+ ClassScope classScope = initializationScope.enclosingClassScope(); >+ >+ if (classScope != null) { >+ checkHiding: { >+ SourceTypeBinding declaringType = classScope.enclosingSourceType(); >+ checkHidingSuperField: { >+ if (declaringType.superclass == null) break checkHidingSuperField; >+ Binding existingVariable = classScope.findField(declaringType.superclass, this.name, this, false /*do not resolve hidden field*/); >+ if (existingVariable == null) break checkHidingSuperField; // keep checking outer scenario >+ if (!existingVariable.isValidBinding()) break checkHidingSuperField; // keep checking outer scenario >+ if (existingVariable instanceof FieldBinding) { >+ FieldBinding existingField = (FieldBinding) existingVariable; >+ if (existingField.original() == this.binding) break checkHidingSuperField; // keep checking outer scenario > } >+ // collision with supertype field >+ initializationScope.problemReporter().fieldHiding(this, existingVariable); >+ break checkHiding; // already found a matching field >+ } >+ // only corner case is: lookup of outer field through static declaringType, which isn't detected by #getBinding as lookup starts >+ // from outer scope. Subsequent static contexts are detected for free. >+ Scope outerScope = classScope.parent; >+ if (outerScope.kind == Scope.COMPILATION_UNIT_SCOPE) break checkHiding; >+ Binding existingVariable = outerScope.getBinding(this.name, Binding.VARIABLE, this, false /*do not resolve hidden field*/); >+ if (existingVariable == null) break checkHiding; >+ if (!existingVariable.isValidBinding()) break checkHiding; >+ if (existingVariable == this.binding) break checkHiding; >+ if (existingVariable instanceof FieldBinding) { >+ FieldBinding existingField = (FieldBinding) existingVariable; >+ if (existingField.original() == this.binding) break checkHiding; >+ if (!existingField.isStatic() && declaringType.isStatic()) break checkHiding; > } >+ // collision with outer field or local variable >+ initializationScope.problemReporter().fieldHiding(this, existingVariable); >+ } >+ } >+ >+ if (this.type != null ) { // enum constants have no declared type >+ this.type.resolvedType = this.binding.type; // update binding for type reference >+ } >+ >+ FieldBinding previousField = initializationScope.initializedField; >+ int previousFieldID = initializationScope.lastVisibleFieldID; >+ try { >+ initializationScope.initializedField = this.binding; >+ initializationScope.lastVisibleFieldID = this.binding.id; >+ >+ resolveAnnotations(initializationScope, this.annotations, this.binding); >+ // check @Deprecated annotation presence >+ if ((this.binding.getAnnotationTagBits() & TagBits.AnnotationDeprecated) == 0 >+ && (this.binding.modifiers & ClassFileConstants.AccDeprecated) != 0 >+ && initializationScope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) { >+ initializationScope.problemReporter().missingDeprecatedAnnotationForField(this); >+ } >+ // the resolution of the initialization hasn't been done >+ if (this.initialization == null) { >+ this.binding.setConstant(Constant.NotAConstant); >+ } else { >+ // break dead-lock cycles by forcing constant to NotAConstant >+ this.binding.setConstant(Constant.NotAConstant); > >- if (this.type != null ) { // enum constants have no declared type >- this.type.resolvedType = this.binding.type; // update binding for type reference >- } >+ TypeBinding fieldType = this.binding.type; >+ TypeBinding initializationType; >+ this.initialization.setExpectedType(fieldType); // needed in case of generic method invocation >+ if (this.initialization instanceof ArrayInitializer) { >+ >+ if ((initializationType = this.initialization.resolveTypeExpecting(initializationScope, fieldType)) != null) { >+ ((ArrayInitializer) this.initialization).binding = (ArrayBinding) initializationType; >+ this.initialization.computeConversion(initializationScope, fieldType, initializationType); >+ } >+ } else if ((initializationType = this.initialization.resolveType(initializationScope)) != null) { > >- FieldBinding previousField = initializationScope.initializedField; >- int previousFieldID = initializationScope.lastVisibleFieldID; >- try { >- initializationScope.initializedField = this.binding; >- initializationScope.lastVisibleFieldID = this.binding.id; >- >- resolveAnnotations(initializationScope, this.annotations, this.binding); >- // check @Deprecated annotation presence >- if ((this.binding.getAnnotationTagBits() & TagBits.AnnotationDeprecated) == 0 >- && (this.binding.modifiers & ClassFileConstants.AccDeprecated) != 0 >- && initializationScope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) { >- initializationScope.problemReporter().missingDeprecatedAnnotationForField(this); >- } >- // the resolution of the initialization hasn't been done >- if (this.initialization == null) { >- this.binding.setConstant(Constant.NotAConstant); >- } else { >- // break dead-lock cycles by forcing constant to NotAConstant >- this.binding.setConstant(Constant.NotAConstant); >- >- TypeBinding fieldType = this.binding.type; >- TypeBinding initializationType; >- this.initialization.setExpectedType(fieldType); // needed in case of generic method invocation >- if (this.initialization instanceof ArrayInitializer) { >- >- if ((initializationType = this.initialization.resolveTypeExpecting(initializationScope, fieldType)) != null) { >- ((ArrayInitializer) this.initialization).binding = (ArrayBinding) initializationType; >- this.initialization.computeConversion(initializationScope, fieldType, initializationType); >- } >- } else if ((initializationType = this.initialization.resolveType(initializationScope)) != null) { >- >- if (fieldType != initializationType) // must call before computeConversion() and typeMismatchError() >- initializationScope.compilationUnitScope().recordTypeConversion(fieldType, initializationType); >- if (this.initialization.isConstantValueOfTypeAssignableToType(initializationType, fieldType) >- || (fieldType.isBaseType() && BaseTypeBinding.isWidening(fieldType.id, initializationType.id)) >- || initializationType.isCompatibleWith(fieldType)) { >- this.initialization.computeConversion(initializationScope, fieldType, initializationType); >- if (initializationType.needsUncheckedConversion(fieldType)) { >- initializationScope.problemReporter().unsafeTypeConversion(this.initialization, initializationType, fieldType); >- } >- if (this.initialization instanceof CastExpression >- && (this.initialization.bits & ASTNode.UnnecessaryCast) == 0) { >- CastExpression.checkNeedForAssignedCast(initializationScope, fieldType, (CastExpression) this.initialization); >- } >- } else if (initializationScope.isBoxingCompatibleWith(initializationType, fieldType) >- || (initializationType.isBaseType() // narrowing then boxing ? >- && initializationScope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5 // autoboxing >- && !fieldType.isBaseType() >- && initialization.isConstantValueOfTypeAssignableToType(initializationType, initializationScope.environment().computeBoxingType(fieldType)))) { >- this.initialization.computeConversion(initializationScope, fieldType, initializationType); >- if (this.initialization instanceof CastExpression >- && (this.initialization.bits & ASTNode.UnnecessaryCast) == 0) { >- CastExpression.checkNeedForAssignedCast(initializationScope, fieldType, (CastExpression) this.initialization); >- } >- } else { >- initializationScope.problemReporter().typeMismatchError(initializationType, fieldType, this); >- } >- if (this.binding.isFinal()){ // cast from constant actual type to variable type >- this.binding.setConstant(this.initialization.constant.castTo((this.binding.type.id << 4) + this.initialization.constant.typeID())); >- } >- } else { >- this.binding.setConstant(Constant.NotAConstant); >+ if (fieldType != initializationType) // must call before computeConversion() and typeMismatchError() >+ initializationScope.compilationUnitScope().recordTypeConversion(fieldType, initializationType); >+ if (this.initialization.isConstantValueOfTypeAssignableToType(initializationType, fieldType) >+ || (fieldType.isBaseType() && BaseTypeBinding.isWidening(fieldType.id, initializationType.id)) >+ || initializationType.isCompatibleWith(fieldType)) { >+ this.initialization.computeConversion(initializationScope, fieldType, initializationType); >+ if (initializationType.needsUncheckedConversion(fieldType)) { >+ initializationScope.problemReporter().unsafeTypeConversion(this.initialization, initializationType, fieldType); > } >- // check for assignment with no effect >- if (this.binding == Assignment.getDirectBinding(this.initialization)) { >- initializationScope.problemReporter().assignmentHasNoEffect(this, this.name); >- } >+ if (this.initialization instanceof CastExpression >+ && (this.initialization.bits & ASTNode.UnnecessaryCast) == 0) { >+ CastExpression.checkNeedForAssignedCast(initializationScope, fieldType, (CastExpression) this.initialization); >+ } >+ } else if (initializationScope.isBoxingCompatibleWith(initializationType, fieldType) >+ || (initializationType.isBaseType() // narrowing then boxing ? >+ && initializationScope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5 // autoboxing >+ && !fieldType.isBaseType() >+ && initialization.isConstantValueOfTypeAssignableToType(initializationType, initializationScope.environment().computeBoxingType(fieldType)))) { >+ this.initialization.computeConversion(initializationScope, fieldType, initializationType); >+ if (this.initialization instanceof CastExpression >+ && (this.initialization.bits & ASTNode.UnnecessaryCast) == 0) { >+ CastExpression.checkNeedForAssignedCast(initializationScope, fieldType, (CastExpression) this.initialization); >+ } >+ } else { >+ initializationScope.problemReporter().typeMismatchError(initializationType, fieldType, this); > } >- // Resolve Javadoc comment if one is present >- if (this.javadoc != null) { >- /* >- if (classScope != null) { >- this.javadoc.resolve(classScope); >- } >- */ >- this.javadoc.resolve(initializationScope); >- } else if (this.binding.declaringClass != null && !this.binding.declaringClass.isLocalType()) { >- initializationScope.problemReporter().javadocMissing(this.sourceStart, this.sourceEnd, this.binding.modifiers); >+ if (this.binding.isFinal()){ // cast from constant actual type to variable type >+ this.binding.setConstant(this.initialization.constant.castTo((this.binding.type.id << 4) + this.initialization.constant.typeID())); > } >- } finally { >- initializationScope.initializedField = previousField; >- initializationScope.lastVisibleFieldID = previousFieldID; >- if (this.binding.constant() == null) >- this.binding.setConstant(Constant.NotAConstant); >+ } else { >+ this.binding.setConstant(Constant.NotAConstant); > } >+ // check for assignment with no effect >+ if (this.binding == Assignment.getDirectBinding(this.initialization)) { >+ initializationScope.problemReporter().assignmentHasNoEffect(this, this.name); >+ } > } >+ // Resolve Javadoc comment if one is present >+ if (this.javadoc != null) { >+ /* >+ if (classScope != null) { >+ this.javadoc.resolve(classScope); >+ } >+ */ >+ this.javadoc.resolve(initializationScope); >+ } else if (this.binding.declaringClass != null && !this.binding.declaringClass.isLocalType()) { >+ initializationScope.problemReporter().javadocMissing(this.sourceStart, this.sourceEnd, this.binding.modifiers); >+ } >+ } finally { >+ initializationScope.initializedField = previousField; >+ initializationScope.lastVisibleFieldID = previousFieldID; >+ if (this.binding.constant() == null) >+ this.binding.setConstant(Constant.NotAConstant); > } >+} > >- public void traverse(ASTVisitor visitor, MethodScope scope) { >- >- if (visitor.visit(this, scope)) { >- if (this.javadoc != null) { >- this.javadoc.traverse(visitor, scope); >- } >- if (this.annotations != null) { >- int annotationsLength = this.annotations.length; >- for (int i = 0; i < annotationsLength; i++) >- this.annotations[i].traverse(visitor, scope); >- } >- if (this.type != null) { >- this.type.traverse(visitor, scope); >- } >- if (this.initialization != null) >- this.initialization.traverse(visitor, scope); >+public void traverse(ASTVisitor visitor, MethodScope scope) { >+ if (visitor.visit(this, scope)) { >+ if (this.javadoc != null) { >+ this.javadoc.traverse(visitor, scope); > } >- visitor.endVisit(this, scope); >+ if (this.annotations != null) { >+ int annotationsLength = this.annotations.length; >+ for (int i = 0; i < annotationsLength; i++) >+ this.annotations[i].traverse(visitor, scope); >+ } >+ if (this.type != null) { >+ this.type.traverse(visitor, scope); >+ } >+ if (this.initialization != null) >+ this.initialization.traverse(visitor, scope); > } >+ visitor.endVisit(this, scope); >+} > } >Index: compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java,v >retrieving revision 1.58 >diff -u -r1.58 ExplicitConstructorCall.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java 2 Apr 2007 10:48:12 -0000 1.58 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java 12 Apr 2007 10:34:50 -0000 >@@ -32,7 +32,7 @@ > public final static int This = 3; > > public VariableBinding[][] implicitArguments; >- boolean discardEnclosingInstance; >+// boolean discardEnclosingInstance; > > // TODO Remove once DOMParser is activated > public int typeArgumentsSourceStart; >@@ -117,7 +117,7 @@ > codeStream.generateSyntheticEnclosingInstanceValues( > currentScope, > targetType, >- discardEnclosingInstance ? null : qualification, >+ (this.bits & ASTNode.DiscardEnclosingInstance) != 0 ? null : qualification, > this); > } > // generate arguments >@@ -296,7 +296,7 @@ > scope.problemReporter().unnecessaryEnclosingInstanceSpecification( > qualification, > receiverType); >- discardEnclosingInstance = true; >+ this.bits |= ASTNode.DiscardEnclosingInstance; > } else { > TypeBinding qTb = qualification.resolveTypeExpecting(scope, enclosingType); > qualification.computeConversion(scope, qTb, qTb); >Index: compiler/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java,v >retrieving revision 1.27 >diff -u -r1.27 CaseStatement.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java 4 Sep 2006 17:05:32 -0000 1.27 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java 12 Apr 2007 10:34:50 -0000 >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2006 IBM Corporation and others. >+ * Copyright (c) 2000, 2007 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,138 +11,138 @@ > package org.eclipse.jdt.internal.compiler.ast; > > import org.eclipse.jdt.internal.compiler.ASTVisitor; >-import org.eclipse.jdt.internal.compiler.impl.*; > import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; >-import org.eclipse.jdt.internal.compiler.codegen.*; >-import org.eclipse.jdt.internal.compiler.flow.*; >-import org.eclipse.jdt.internal.compiler.lookup.*; >+import org.eclipse.jdt.internal.compiler.codegen.CaseLabel; >+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.impl.IntConstant; >+import org.eclipse.jdt.internal.compiler.lookup.Binding; >+import org.eclipse.jdt.internal.compiler.lookup.BlockScope; >+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; >+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; >+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; > > public class CaseStatement extends Statement { > > public Expression constantExpression; > public CaseLabel targetLabel; >- public boolean isEnumConstant; > >- public CaseStatement(Expression constantExpression, int sourceEnd, int sourceStart) { >- this.constantExpression = constantExpression; >- this.sourceEnd = sourceEnd; >- this.sourceStart = sourceStart; >- } >+public CaseStatement(Expression constantExpression, int sourceEnd, int sourceStart) { >+ this.constantExpression = constantExpression; >+ this.sourceEnd = sourceEnd; >+ this.sourceStart = sourceStart; >+} > >- public FlowInfo analyseCode( >- BlockScope currentScope, >- FlowContext flowContext, >- FlowInfo flowInfo) { >- >- if (constantExpression != null) { >- if (!this.isEnumConstant && constantExpression.constant == Constant.NotAConstant) { >- currentScope.problemReporter().caseExpressionMustBeConstant(constantExpression); >- } >- this.constantExpression.analyseCode(currentScope, flowContext, flowInfo); >+public FlowInfo analyseCode( >+ BlockScope currentScope, >+ FlowContext flowContext, >+ FlowInfo flowInfo) { >+ >+ if (this.constantExpression != null) { >+ if (this.constantExpression.constant == Constant.NotAConstant >+ && !this.constantExpression.resolvedType.isEnum()) { >+ currentScope.problemReporter().caseExpressionMustBeConstant(this.constantExpression); > } >- return flowInfo; >+ this.constantExpression.analyseCode(currentScope, flowContext, flowInfo); > } >+ return flowInfo; >+} > >- public StringBuffer printStatement(int tab, StringBuffer output) { >- >- printIndent(tab, output); >- if (constantExpression == null) { >- output.append("default : "); //$NON-NLS-1$ >- } else { >- output.append("case "); //$NON-NLS-1$ >- constantExpression.printExpression(0, output).append(" : "); //$NON-NLS-1$ >- } >- return output.append(';'); >+public StringBuffer printStatement(int tab, StringBuffer output) { >+ printIndent(tab, output); >+ if (this.constantExpression == null) { >+ output.append("default : "); //$NON-NLS-1$ >+ } else { >+ output.append("case "); //$NON-NLS-1$ >+ this.constantExpression.printExpression(0, output).append(" : "); //$NON-NLS-1$ > } >- >- /** >- * Case code generation >- * >- */ >- public void generateCode(BlockScope currentScope, CodeStream codeStream) { >+ return output.append(';'); >+} > >- if ((bits & IsReachable) == 0) { >- return; >- } >- int pc = codeStream.position; >- targetLabel.place(); >- codeStream.recordPositionsFrom(pc, this.sourceStart); >- } >- >- /** >- * No-op : should use resolveCase(...) instead. >- */ >- public void resolve(BlockScope scope) { >- // no-op : should use resolveCase(...) instead. >- } >- >- /** >- * Returns the constant intValue or ordinal for enum constants. If constant is NotAConstant, then answers Float.MIN_VALUE >- * @see org.eclipse.jdt.internal.compiler.ast.Statement#resolveCase(org.eclipse.jdt.internal.compiler.lookup.BlockScope, org.eclipse.jdt.internal.compiler.lookup.TypeBinding, org.eclipse.jdt.internal.compiler.ast.SwitchStatement) >- */ >- public Constant resolveCase(BlockScope scope, TypeBinding switchExpressionType, SwitchStatement switchStatement) { >- // switchExpressionType maybe null in error case >- scope.enclosingCase = this; // record entering in a switch case block >- >- if (constantExpression == null) { >- // remember the default case into the associated switch statement >- if (switchStatement.defaultCase != null) >- scope.problemReporter().duplicateDefaultCase(this); >- >- // on error the last default will be the selected one ... >- switchStatement.defaultCase = this; >- return Constant.NotAConstant; >- } >- // add into the collection of cases of the associated switch statement >- switchStatement.cases[switchStatement.caseCount++] = this; >- // tag constant name with enum type for privileged access to its members >- if (switchExpressionType != null && switchExpressionType.isEnum() && (constantExpression instanceof SingleNameReference)) { >- ((SingleNameReference) constantExpression).setActualReceiverType((ReferenceBinding)switchExpressionType); >- } >- TypeBinding caseType = constantExpression.resolveType(scope); >- if (caseType == null || switchExpressionType == null) return Constant.NotAConstant; >- if (constantExpression.isConstantValueOfTypeAssignableToType(caseType, switchExpressionType) >- || caseType.isCompatibleWith(switchExpressionType)) { >- if (caseType.isEnum()) { >- this.isEnumConstant = true; >- if (((this.constantExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) != 0) { >- scope.problemReporter().enumConstantsCannotBeSurroundedByParenthesis(this.constantExpression); >- } >+/** >+ * Case code generation >+ * >+ */ >+public void generateCode(BlockScope currentScope, CodeStream codeStream) { >+ if ((this.bits & ASTNode.IsReachable) == 0) { >+ return; >+ } >+ int pc = codeStream.position; >+ this.targetLabel.place(); >+ codeStream.recordPositionsFrom(pc, this.sourceStart); >+} >+ >+/** >+ * No-op : should use resolveCase(...) instead. >+ */ >+public void resolve(BlockScope scope) { >+ // no-op : should use resolveCase(...) instead. >+} >+ >+/** >+ * Returns the constant intValue or ordinal for enum constants. If constant is NotAConstant, then answers Float.MIN_VALUE >+ * @see org.eclipse.jdt.internal.compiler.ast.Statement#resolveCase(org.eclipse.jdt.internal.compiler.lookup.BlockScope, org.eclipse.jdt.internal.compiler.lookup.TypeBinding, org.eclipse.jdt.internal.compiler.ast.SwitchStatement) >+ */ >+public Constant resolveCase(BlockScope scope, TypeBinding switchExpressionType, SwitchStatement switchStatement) { >+ // switchExpressionType maybe null in error case >+ scope.enclosingCase = this; // record entering in a switch case block >+ >+ if (this.constantExpression == null) { >+ // remember the default case into the associated switch statement >+ if (switchStatement.defaultCase != null) >+ scope.problemReporter().duplicateDefaultCase(this); >+ >+ // on error the last default will be the selected one ... >+ switchStatement.defaultCase = this; >+ return Constant.NotAConstant; >+ } >+ // add into the collection of cases of the associated switch statement >+ switchStatement.cases[switchStatement.caseCount++] = this; >+ // tag constant name with enum type for privileged access to its members >+ if (switchExpressionType != null && switchExpressionType.isEnum() && (this.constantExpression instanceof SingleNameReference)) { >+ ((SingleNameReference) this.constantExpression).setActualReceiverType((ReferenceBinding)switchExpressionType); >+ } >+ TypeBinding caseType = this.constantExpression.resolveType(scope); >+ if (caseType == null || switchExpressionType == null) return Constant.NotAConstant; >+ if (this.constantExpression.isConstantValueOfTypeAssignableToType(caseType, switchExpressionType) >+ || caseType.isCompatibleWith(switchExpressionType)) { >+ if (caseType.isEnum()) { >+ if (((this.constantExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) != 0) { >+ scope.problemReporter().enumConstantsCannotBeSurroundedByParenthesis(this.constantExpression); >+ } > >- if (constantExpression instanceof NameReference >- && (constantExpression.bits & RestrictiveFlagMASK) == Binding.FIELD) { >- NameReference reference = (NameReference) constantExpression; >- FieldBinding field = reference.fieldBinding(); >- if ((field.modifiers & ClassFileConstants.AccEnum) == 0) { >- scope.problemReporter().enumSwitchCannotTargetField(reference, field); >- } else if (reference instanceof QualifiedNameReference) { >- scope.problemReporter().cannotUseQualifiedEnumConstantInCaseLabel(reference, field); >- } >- return IntConstant.fromValue(field.original().id + 1); // (ordinal value + 1) zero should not be returned see bug 141810 >+ if (this.constantExpression instanceof NameReference >+ && (this.constantExpression.bits & ASTNode.RestrictiveFlagMASK) == Binding.FIELD) { >+ NameReference reference = (NameReference) this.constantExpression; >+ FieldBinding field = reference.fieldBinding(); >+ if ((field.modifiers & ClassFileConstants.AccEnum) == 0) { >+ scope.problemReporter().enumSwitchCannotTargetField(reference, field); >+ } else if (reference instanceof QualifiedNameReference) { >+ scope.problemReporter().cannotUseQualifiedEnumConstantInCaseLabel(reference, field); > } >- } else { >- return constantExpression.constant; >+ return IntConstant.fromValue(field.original().id + 1); // (ordinal value + 1) zero should not be returned see bug 141810 > } >- } else if (scope.isBoxingCompatibleWith(caseType, switchExpressionType) >- || (caseType.isBaseType() // narrowing then boxing ? >- && scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5 // autoboxing >- && !switchExpressionType.isBaseType() >- && constantExpression.isConstantValueOfTypeAssignableToType(caseType, scope.environment().computeBoxingType(switchExpressionType)))) { >- // constantExpression.computeConversion(scope, caseType, switchExpressionType); - do not report boxing/unboxing conversion >- return constantExpression.constant; >+ } else { >+ return this.constantExpression.constant; > } >- scope.problemReporter().typeMismatchError(caseType, switchExpressionType, constantExpression); >- return Constant.NotAConstant; >+ } else if (scope.isBoxingCompatibleWith(caseType, switchExpressionType) >+ || (caseType.isBaseType() // narrowing then boxing ? >+ && scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5 // autoboxing >+ && !switchExpressionType.isBaseType() >+ && this.constantExpression.isConstantValueOfTypeAssignableToType(caseType, scope.environment().computeBoxingType(switchExpressionType)))) { >+ // constantExpression.computeConversion(scope, caseType, switchExpressionType); - do not report boxing/unboxing conversion >+ return this.constantExpression.constant; > } >+ scope.problemReporter().typeMismatchError(caseType, switchExpressionType, this.constantExpression); >+ return Constant.NotAConstant; >+} > >- >- public void traverse( >- ASTVisitor visitor, >- BlockScope blockScope) { >- >- if (visitor.visit(this, blockScope)) { >- if (constantExpression != null) constantExpression.traverse(visitor, blockScope); >- } >- visitor.endVisit(this, blockScope); >+public void traverse(ASTVisitor visitor, BlockScope blockScope) { >+ if (visitor.visit(this, blockScope)) { >+ if (this.constantExpression != null) this.constantExpression.traverse(visitor, blockScope); > } >+ visitor.endVisit(this, blockScope); >+} > } >Index: codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java,v >retrieving revision 1.324 >diff -u -r1.324 CompletionEngine.java >--- codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java 12 Apr 2007 09:23:29 -0000 1.324 >+++ codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java 12 Apr 2007 10:34:50 -0000 >@@ -2282,7 +2282,9 @@ > char[][] alreadyUsedConstants = new char[switchStatement.caseCount][]; > int alreadyUsedConstantCount = 0; > for (int i = 0; i < switchStatement.caseCount; i++) { >- if(cases[i].isEnumConstant && cases[i].constantExpression instanceof SingleNameReference) { >+ Expression caseExpression = cases[i].constantExpression; >+ if((caseExpression instanceof SingleNameReference) >+ && (caseExpression.resolvedType != null && caseExpression.resolvedType.isEnum())) { > alreadyUsedConstants[alreadyUsedConstantCount++] = ((SingleNameReference)cases[i].constantExpression).token; > } > }
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 146556
: 63595 |
64883