### 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 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 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; } }