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 113351 Details for
Bug 247612
[compiler] Compiler could avoid allocating field bindings for receiver type change
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
More advanced patch
247612.txt (text/plain), 168.11 KB, created by
Philipe Mulet
on 2008-09-24 08:37:23 EDT
(
hide
)
Description:
More advanced patch
Filename:
MIME Type:
Creator:
Philipe Mulet
Created:
2008-09-24 08:37:23 EDT
Size:
168.11 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.jdt.core >Index: compiler/org/eclipse/jdt/internal/compiler/ast/NameReference.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NameReference.java,v >retrieving revision 1.19 >diff -u -r1.19 NameReference.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/NameReference.java 27 Jun 2008 16:03:55 -0000 1.19 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/NameReference.java 24 Sep 2008 12:36:50 -0000 >@@ -14,7 +14,7 @@ > > public abstract class NameReference extends Reference implements InvocationSite { > >- public Binding binding, codegenBinding; //may be aTypeBinding-aFieldBinding-aLocalVariableBinding >+ public Binding binding; //may be aTypeBinding-aFieldBinding-aLocalVariableBinding > > public TypeBinding actualReceiverType; // modified receiver type - actual one according to namelookup > >Index: compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java,v >retrieving revision 1.53 >diff -u -r1.53 Clinit.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java 7 Jul 2008 17:08:07 -0000 1.53 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java 24 Sep 2008 12:36:50 -0000 >@@ -16,6 +16,7 @@ > import org.eclipse.jdt.internal.compiler.codegen.BranchLabel; > import org.eclipse.jdt.internal.compiler.codegen.CodeStream; > import org.eclipse.jdt.internal.compiler.codegen.ConstantPool; >+import org.eclipse.jdt.internal.compiler.codegen.Opcodes; > import org.eclipse.jdt.internal.compiler.flow.ExceptionHandlingFlowContext; > import org.eclipse.jdt.internal.compiler.flow.FlowInfo; > import org.eclipse.jdt.internal.compiler.flow.InitializationFlowContext; >@@ -173,7 +174,7 @@ > falseLabel.place(); > codeStream.iconst_0(); > jumpLabel.place(); >- codeStream.putstatic(this.assertionSyntheticFieldBinding); >+ codeStream.fieldAccess0(Opcodes.OPC_putstatic, this.assertionSyntheticFieldBinding, null /* default declaringClass */); > } > // generate static fields/initializers/enum constants > final FieldDeclaration[] fieldDeclarations = declaringType.fields; >@@ -206,13 +207,13 @@ > if (fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) { > codeStream.dup(); > codeStream.generateInlinedValue(fieldDecl.binding.id); >- codeStream.getstatic(fieldDecl.binding); >+ codeStream.fieldAccess0(Opcodes.OPC_getstatic, fieldDecl.binding, null /* default declaringClass */); > codeStream.aastore(); > } > } > } > } >- codeStream.putstatic(declaringType.enumValuesSyntheticfield); >+ codeStream.fieldAccess0(Opcodes.OPC_putstatic, declaringType.enumValuesSyntheticfield, null /* default declaringClass */); > if (remainingFieldCount != 0) { > // if fields that are not enum constants need to be generated (static initializer/static field) > for (int i = 0, max = fieldDeclarations.length; i < max; i++) { >Index: compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java,v >retrieving revision 1.95 >diff -u -r1.95 ConstructorDeclaration.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java 8 Jul 2008 02:01:42 -0000 1.95 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java 24 Sep 2008 12:36:50 -0000 >@@ -228,7 +228,7 @@ > if ((syntheticArg = syntheticArgs[i]).matchingField != null) { > codeStream.aload_0(); > codeStream.load(syntheticArg); >- codeStream.putfield(syntheticArg.matchingField); >+ codeStream.fieldAccess0(Opcodes.OPC_putfield, syntheticArg.matchingField, null /* default declaringClass */); > } > } > syntheticArgs = nestedType.syntheticOuterLocalVariables(); >@@ -237,7 +237,7 @@ > if ((syntheticArg = syntheticArgs[i]).matchingField != null) { > codeStream.aload_0(); > codeStream.load(syntheticArg); >- codeStream.putfield(syntheticArg.matchingField); >+ codeStream.fieldAccess0(Opcodes.OPC_putfield, syntheticArg.matchingField, null /* default declaringClass */); > } > } > } >Index: compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java,v >retrieving revision 1.55 >diff -u -r1.55 AssertStatement.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java 12 Sep 2008 19:24:48 -0000 1.55 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java 24 Sep 2008 12:36:50 -0000 >@@ -101,7 +101,7 @@ > > if (this.assertionSyntheticFieldBinding != null) { > BranchLabel assertionActivationLabel = new BranchLabel(codeStream); >- codeStream.getstatic(this.assertionSyntheticFieldBinding); >+ codeStream.fieldAccess0(Opcodes.OPC_getstatic, this.assertionSyntheticFieldBinding, null /* default declaringClass */); > codeStream.ifne(assertionActivationLabel); > > BranchLabel falseLabel; >Index: compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java,v >retrieving revision 1.120 >diff -u -r1.120 FieldReference.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java 17 Sep 2008 09:08:38 -0000 1.120 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java 24 Sep 2008 12:36:50 -0000 >@@ -17,7 +17,6 @@ > import org.eclipse.jdt.internal.compiler.codegen.Opcodes; > import org.eclipse.jdt.internal.compiler.flow.FlowContext; > import org.eclipse.jdt.internal.compiler.flow.FlowInfo; >-import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; > import org.eclipse.jdt.internal.compiler.impl.Constant; > import org.eclipse.jdt.internal.compiler.lookup.Binding; > import org.eclipse.jdt.internal.compiler.lookup.BlockScope; >@@ -41,11 +40,10 @@ > public Expression receiver; > public char[] token; > public FieldBinding binding; // exact binding resulting from lookup >- protected FieldBinding codegenBinding; // actual binding used for code generation (if no synthetic accessor) > public MethodBinding[] syntheticAccessors; // [0]=read accessor [1]=write accessor > > public long nameSourcePosition; //(start<<32)+end >- public TypeBinding receiverType; >+ public TypeBinding actualReceiverType; > public TypeBinding genericCast; > > public FieldReference(char[] source, long pos) { >@@ -162,15 +160,16 @@ > > public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) { > int pc = codeStream.position; >+ FieldBinding codegenBinding = this.binding.original(); > this.receiver.generateCode( > currentScope, > codeStream, >- !this.codegenBinding.isStatic()); >+ !codegenBinding.isStatic()); > codeStream.recordPositionsFrom(pc, this.sourceStart); > assignment.expression.generateCode(currentScope, codeStream, true); > fieldStore( > codeStream, >- this.codegenBinding, >+ codegenBinding, > this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.WRITE], > valueRequired); > if (valueRequired) { >@@ -195,9 +194,10 @@ > codeStream.recordPositionsFrom(pc, this.sourceStart); > return; > } >- boolean isStatic = this.codegenBinding.isStatic(); >+ FieldBinding codegenBinding = this.binding.original(); >+ boolean isStatic = codegenBinding.isStatic(); > boolean isThisReceiver = this.receiver instanceof ThisReference; >- Constant fieldConstant = this.codegenBinding.constant(); >+ Constant fieldConstant = codegenBinding.constant(); > if (fieldConstant != Constant.NotAConstant) { > if (!isThisReceiver) { > this.receiver.generateCode(currentScope, codeStream, !isStatic); >@@ -218,7 +218,7 @@ > || (this.genericCast != null)) { > this.receiver.generateCode(currentScope, codeStream, !isStatic); > pc = codeStream.position; >- if (this.codegenBinding.declaringClass == null) { // array length >+ if (codegenBinding.declaringClass == null) { // array length > codeStream.arraylength(); > if (valueRequired) { > codeStream.generateImplicitConversion(this.implicitConversion); >@@ -228,10 +228,11 @@ > } > } else { > if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) { >+ TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis()); > if (isStatic) { >- codeStream.getstatic(this.codegenBinding); >+ codeStream.fieldAccess0(Opcodes.OPC_getstatic, codegenBinding, constantPoolDeclaringClass); > } else { >- codeStream.getfield(this.codegenBinding); >+ codeStream.fieldAccess0(Opcodes.OPC_getfield, codegenBinding, constantPoolDeclaringClass); > } > } else { > codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[FieldReference.READ], null /* default declaringClass */); >@@ -244,7 +245,7 @@ > boolean isUnboxing = (this.implicitConversion & TypeIds.UNBOXING) != 0; > // conversion only generated if unboxing > if (isUnboxing) codeStream.generateImplicitConversion(this.implicitConversion); >- switch (isUnboxing ? postConversionType(currentScope).id : this.codegenBinding.type.id) { >+ switch (isUnboxing ? postConversionType(currentScope).id : codegenBinding.type.id) { > case T_long : > case T_double : > codeStream.pop2(); >@@ -258,14 +259,15 @@ > if (isThisReceiver) { > if (isStatic){ > // if no valueRequired, still need possible side-effects of <clinit> invocation, if field belongs to different class >- if (this.binding.original().declaringClass != this.receiverType.erasure()) { >+ if (this.binding.original().declaringClass != this.actualReceiverType.erasure()) { > MethodBinding accessor = this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.READ]; > if (accessor == null) { >- codeStream.getstatic(this.codegenBinding); >+ TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis()); >+ codeStream.fieldAccess0(Opcodes.OPC_getstatic, codegenBinding, constantPoolDeclaringClass); > } else { > codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */); > } >- switch (this.codegenBinding.type.id) { >+ switch (codegenBinding.type.id) { > case T_long : > case T_double : > codeStream.pop2(); >@@ -288,20 +290,20 @@ > > public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) { > boolean isStatic; >- this.receiver.generateCode( >- currentScope, >- codeStream, >- !(isStatic = this.codegenBinding.isStatic())); >+ FieldBinding codegenBinding = this.binding.original(); >+ this.receiver.generateCode(currentScope, codeStream, !(isStatic = codegenBinding.isStatic())); > if (isStatic) { > if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) { >- codeStream.getstatic(this.codegenBinding); >+ TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis()); >+ codeStream.fieldAccess0(Opcodes.OPC_getstatic, codegenBinding, constantPoolDeclaringClass); > } else { > codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[FieldReference.READ], null /* default declaringClass */); > } > } else { > codeStream.dup(); > if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) { >- codeStream.getfield(this.codegenBinding); >+ TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis()); >+ codeStream.fieldAccess0(Opcodes.OPC_getfield, codegenBinding, constantPoolDeclaringClass); > } else { > codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[FieldReference.READ], null /* default declaringClass */); > } >@@ -329,30 +331,26 @@ > // cast the value back to the array reference type > codeStream.generateImplicitConversion(assignmentImplicitConversion); > } >- fieldStore( >- codeStream, >- this.codegenBinding, >- this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.WRITE], >- valueRequired); >+ fieldStore(codeStream, codegenBinding, this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.WRITE], valueRequired); > // no need for generic cast as value got dupped > } > > public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) { > boolean isStatic; >- this.receiver.generateCode( >- currentScope, >- codeStream, >- !(isStatic = this.codegenBinding.isStatic())); >+ FieldBinding codegenBinding = this.binding.original(); >+ this.receiver.generateCode(currentScope, codeStream, !(isStatic = codegenBinding.isStatic())); > if (isStatic) { > if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) { >- codeStream.getstatic(this.codegenBinding); >+ TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis()); >+ codeStream.fieldAccess0(Opcodes.OPC_getstatic, codegenBinding, constantPoolDeclaringClass); > } else { > codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[FieldReference.READ], null /* default declaringClass */); > } > } else { > codeStream.dup(); > if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) { >- codeStream.getfield(this.codegenBinding); >+ TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis()); >+ codeStream.fieldAccess0(Opcodes.OPC_getfield, codegenBinding, constantPoolDeclaringClass); > } else { > codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[FieldReference.READ], null /* default declaringClass */); > } >@@ -362,23 +360,29 @@ > codeStream.checkcast(this.genericCast); > operandType = this.genericCast; > } else { >- operandType = this.codegenBinding.type; >+ operandType = codegenBinding.type; > } > if (valueRequired) { > if (isStatic) { >- if ((operandType == TypeBinding.LONG) >- || (operandType == TypeBinding.DOUBLE)) { >- codeStream.dup2(); >- } else { >- codeStream.dup(); >- } >+ switch (operandType.id) { >+ case TypeIds.T_long : >+ case TypeIds.T_double : >+ codeStream.dup2(); >+ break; >+ default : >+ codeStream.dup(); >+ break; >+ } > } else { // Stack: [owner][old field value] ---> [old field value][owner][old field value] >- if ((operandType == TypeBinding.LONG) >- || (operandType == TypeBinding.DOUBLE)) { >- codeStream.dup2_x1(); >- } else { >- codeStream.dup_x1(); >- } >+ switch (operandType.id) { >+ case TypeIds.T_long : >+ case TypeIds.T_double : >+ codeStream.dup2_x1(); >+ break; >+ default : >+ codeStream.dup_x1(); >+ break; >+ } > } > } > codeStream.generateImplicitConversion(this.implicitConversion); >@@ -388,7 +392,7 @@ > codeStream.sendOperator(postIncrement.operator, this.implicitConversion & TypeIds.COMPILE_TYPE_MASK); > codeStream.generateImplicitConversion( > postIncrement.preAssignImplicitConversion); >- fieldStore(codeStream, this.codegenBinding, this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.WRITE], false); >+ fieldStore(codeStream, codegenBinding, this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.WRITE], false); > } > > /** >@@ -412,16 +416,16 @@ > if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return; > > // if field from parameterized type got found, use the original field at codegen time >- this.codegenBinding = this.binding.original(); >+ FieldBinding codegenBinding = this.binding.original(); > > if (this.binding.isPrivate()) { >- if ((currentScope.enclosingSourceType() != this.codegenBinding.declaringClass) >+ if ((currentScope.enclosingSourceType() != codegenBinding.declaringClass) > && this.binding.constant() == Constant.NotAConstant) { > if (this.syntheticAccessors == null) > this.syntheticAccessors = new MethodBinding[2]; > this.syntheticAccessors[isReadAccess ? FieldReference.READ : FieldReference.WRITE] = >- ((SourceTypeBinding) this.codegenBinding.declaringClass).addSyntheticMethod(this.codegenBinding, isReadAccess); >- currentScope.problemReporter().needToEmulateFieldAccess(this.codegenBinding, this, isReadAccess); >+ ((SourceTypeBinding) codegenBinding.declaringClass).addSyntheticMethod(codegenBinding, isReadAccess); >+ currentScope.problemReporter().needToEmulateFieldAccess(codegenBinding, this, isReadAccess); > return; > } > >@@ -433,8 +437,8 @@ > .currentCompatibleType); > if (this.syntheticAccessors == null) > this.syntheticAccessors = new MethodBinding[2]; >- this.syntheticAccessors[isReadAccess ? FieldReference.READ : FieldReference.WRITE] = destinationType.addSyntheticMethod(this.codegenBinding, isReadAccess); >- currentScope.problemReporter().needToEmulateFieldAccess(this.codegenBinding, this, isReadAccess); >+ this.syntheticAccessors[isReadAccess ? FieldReference.READ : FieldReference.WRITE] = destinationType.addSyntheticMethod(codegenBinding, isReadAccess); >+ currentScope.problemReporter().needToEmulateFieldAccess(codegenBinding, this, isReadAccess); > return; > > } else if (this.binding.isProtected()) { >@@ -449,31 +453,11 @@ > (this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT); > if (this.syntheticAccessors == null) > this.syntheticAccessors = new MethodBinding[2]; >- this.syntheticAccessors[isReadAccess ? FieldReference.READ : FieldReference.WRITE] = currentCompatibleType.addSyntheticMethod(this.codegenBinding, isReadAccess); >- currentScope.problemReporter().needToEmulateFieldAccess(this.codegenBinding, this, isReadAccess); >+ this.syntheticAccessors[isReadAccess ? FieldReference.READ : FieldReference.WRITE] = currentCompatibleType.addSyntheticMethod(codegenBinding, isReadAccess); >+ currentScope.problemReporter().needToEmulateFieldAccess(codegenBinding, this, isReadAccess); > return; > } > } >- // if the binding declaring class is not visible, need special action >- // for runtime compatibility on 1.2 VMs : change the declaring class of the binding >- // NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type >- // and not from Object or implicit static field access. >- if (this.binding.declaringClass != this.receiverType >- && !this.receiverType.isArrayType() >- && this.binding.declaringClass != null // array.length >- && this.binding.constant() == Constant.NotAConstant) { >- CompilerOptions options = currentScope.compilerOptions(); >- if ((options.targetJDK >= ClassFileConstants.JDK1_2 >- && (options.complianceLevel >= ClassFileConstants.JDK1_4 || !(this.receiver.isImplicitThis() && this.codegenBinding.isStatic())) >- && this.binding.declaringClass.id != TypeIds.T_JavaLangObject) // no change for Object fields >- || !this.binding.declaringClass.canBeSeenBy(currentScope)) { >- >- this.codegenBinding = >- currentScope.enclosingSourceType().getUpdatedFieldBinding( >- this.codegenBinding, >- (ReferenceBinding) this.receiverType.erasure()); >- } >- } > } > > public int nullStatus(FlowInfo flowInfo) { >@@ -546,35 +530,35 @@ > this.receiver.bits |= ASTNode.DisableUnnecessaryCastCheck; // will check later on > receiverCast = true; > } >- this.receiverType = this.receiver.resolveType(scope); >- if (this.receiverType == null) { >+ this.actualReceiverType = this.receiver.resolveType(scope); >+ if (this.actualReceiverType == null) { > this.constant = Constant.NotAConstant; > return null; > } > if (receiverCast) { > // due to change of declaring class with receiver type, only identity cast should be notified >- if (((CastExpression)this.receiver).expression.resolvedType == this.receiverType) { >+ if (((CastExpression)this.receiver).expression.resolvedType == this.actualReceiverType) { > scope.problemReporter().unnecessaryCast((CastExpression)this.receiver); > } > } > // the case receiverType.isArrayType and token = 'length' is handled by the scope API >- FieldBinding fieldBinding = this.codegenBinding = this.binding = scope.getField(this.receiverType, this.token, this); >+ FieldBinding fieldBinding = this.binding = scope.getField(this.actualReceiverType, this.token, this); > if (!fieldBinding.isValidBinding()) { > this.constant = Constant.NotAConstant; > if (this.receiver.resolvedType instanceof ProblemReferenceBinding) { > // problem already got signaled on receiver, do not report secondary problem > return null; > } >- scope.problemReporter().invalidField(this, this.receiverType); >+ scope.problemReporter().invalidField(this, this.actualReceiverType); > return null; > } >- TypeBinding receiverErasure = this.receiverType.erasure(); >+ TypeBinding receiverErasure = this.actualReceiverType.erasure(); > if (receiverErasure instanceof ReferenceBinding) { > if (receiverErasure.findSuperTypeOriginatingFrom(fieldBinding.declaringClass) == null) { >- this.receiverType = fieldBinding.declaringClass; // handle indirect inheritance thru variable secondary bound >+ this.actualReceiverType = fieldBinding.declaringClass; // handle indirect inheritance thru variable secondary bound > } > } >- this.receiver.computeConversion(scope, this.receiverType, this.receiverType); >+ this.receiver.computeConversion(scope, this.actualReceiverType, this.actualReceiverType); > if (isFieldUseDeprecated(fieldBinding, scope, (this.bits & ASTNode.IsStrictlyAssigned) !=0)) { > scope.problemReporter().deprecatedField(fieldBinding, this); > } >@@ -589,7 +573,7 @@ > } > ReferenceBinding declaringClass = this.binding.declaringClass; > if (!isImplicitThisRcv >- && declaringClass != this.receiverType >+ && declaringClass != this.actualReceiverType > && declaringClass.canBeSeenBy(scope)) { > scope.problemReporter().indirectAccessToStaticField(this, fieldBinding); > } >@@ -620,7 +604,7 @@ > } > > public void setActualReceiverType(ReferenceBinding receiverType) { >- // ignored >+ this.actualReceiverType = receiverType; > } > > public void setDepth(int depth) { >Index: compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java,v >retrieving revision 1.110 >diff -u -r1.110 SingleNameReference.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java 17 Sep 2008 09:08:38 -0000 1.110 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java 24 Sep 2008 12:36:51 -0000 >@@ -278,9 +278,9 @@ > } > switch (this.bits & ASTNode.RestrictiveFlagMASK) { > case Binding.FIELD : // assigning to a field >- FieldBinding fieldBinding; > int pc = codeStream.position; >- if (!(fieldBinding = (FieldBinding) this.codegenBinding).isStatic()) { // need a receiver? >+ FieldBinding codegenBinding = ((FieldBinding) this.binding).original(); >+ if (!codegenBinding.isStatic()) { // need a receiver? > if ((this.bits & ASTNode.DepthMASK) != 0) { > ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT); > Object[] emulationPath = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/); >@@ -291,14 +291,14 @@ > } > codeStream.recordPositionsFrom(pc, this.sourceStart); > assignment.expression.generateCode(currentScope, codeStream, true); >- fieldStore(codeStream, fieldBinding, this.syntheticAccessors == null ? null : this.syntheticAccessors[SingleNameReference.WRITE], valueRequired); >+ fieldStore(codeStream, codegenBinding, this.syntheticAccessors == null ? null : this.syntheticAccessors[SingleNameReference.WRITE], valueRequired); > if (valueRequired) { > codeStream.generateImplicitConversion(assignment.implicitConversion); > } > // no need for generic cast as value got dupped > return; > case Binding.LOCAL : // assigning to a local variable >- LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding; >+ LocalVariableBinding localBinding = (LocalVariableBinding) this.binding; > if (localBinding.resolvedPosition != -1) { > assignment.expression.generateCode(currentScope, codeStream, true); > } else { >@@ -354,8 +354,8 @@ > } else { > switch (this.bits & ASTNode.RestrictiveFlagMASK) { > case Binding.FIELD : // reading a field >- FieldBinding fieldBinding = (FieldBinding) this.codegenBinding; >- Constant fieldConstant = fieldBinding.constant(); >+ FieldBinding codegenField = ((FieldBinding) this.binding).original(); >+ Constant fieldConstant = codegenField.constant(); > if (fieldConstant != Constant.NotAConstant) { > // directly use inlined value for constant fields > if (valueRequired) { >@@ -364,7 +364,7 @@ > codeStream.recordPositionsFrom(pc, this.sourceStart); > return; > } >- if (fieldBinding.isStatic()) { >+ if (codegenField.isStatic()) { > if (!valueRequired > // if no valueRequired, still need possible side-effects of <clinit> invocation, if field belongs to different class > && ((FieldBinding)this.binding).original().declaringClass == this.actualReceiverType.erasure() >@@ -376,7 +376,8 @@ > } > // managing private access > if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) { >- codeStream.getstatic(fieldBinding); >+ TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenField, this.actualReceiverType, true /* implicit this */); >+ codeStream.fieldAccess0(Opcodes.OPC_getstatic, codegenField, constantPoolDeclaringClass); > } else { > codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */); > } >@@ -398,14 +399,15 @@ > } > // managing private access > if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) { >- codeStream.getfield(fieldBinding); >+ TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenField, this.actualReceiverType, true /* implicit this */); >+ codeStream.fieldAccess0(Opcodes.OPC_getfield, codegenField, constantPoolDeclaringClass); > } else { > codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */); > } > } > break; > case Binding.LOCAL : // reading a local >- LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding; >+ LocalVariableBinding localBinding = (LocalVariableBinding) this.binding; > if (!valueRequired && (this.implicitConversion & TypeIds.UNBOXING) == 0) { > // if no valueRequired, optimize out entire gen > codeStream.recordPositionsFrom(pc, this.sourceStart); >@@ -470,10 +472,11 @@ > public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, MethodBinding writeAccessor, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) { > switch (this.bits & ASTNode.RestrictiveFlagMASK) { > case Binding.FIELD : // assigning to a field >- FieldBinding fieldBinding; >- if ((fieldBinding = (FieldBinding) this.codegenBinding).isStatic()) { >+ FieldBinding codegenField = ((FieldBinding) this.binding).original(); >+ if (codegenField.isStatic()) { > if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) { >- codeStream.getstatic(fieldBinding); >+ TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenField, this.actualReceiverType, true /* implicit this */); >+ codeStream.fieldAccess0(Opcodes.OPC_getstatic, codegenField, constantPoolDeclaringClass); > } else { > codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */); > } >@@ -487,14 +490,15 @@ > } > codeStream.dup(); > if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) { >- codeStream.getfield(fieldBinding); >+ TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenField, this.actualReceiverType, true /* implicit this */); >+ codeStream.fieldAccess0(Opcodes.OPC_getfield, codegenField, constantPoolDeclaringClass); > } else { > codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */); > } > } > break; > case Binding.LOCAL : // assigning to a local variable (cannot assign to outer local) >- LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding; >+ LocalVariableBinding localBinding = (LocalVariableBinding) this.binding; > // using incr bytecode if possible > switch (localBinding.type.id) { > case T_JavaLangString : >@@ -564,16 +568,21 @@ > // store the result back into the variable > switch (this.bits & ASTNode.RestrictiveFlagMASK) { > case Binding.FIELD : // assigning to a field >- fieldStore(codeStream, (FieldBinding) this.codegenBinding, writeAccessor, valueRequired); >+ FieldBinding codegenField = ((FieldBinding) this.binding).original(); >+ fieldStore(codeStream, codegenField, writeAccessor, valueRequired); > // no need for generic cast as value got dupped > return; > case Binding.LOCAL : // assigning to a local variable >- LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding; >+ LocalVariableBinding localBinding = (LocalVariableBinding) this.binding; > if (valueRequired) { >- if ((localBinding.type == TypeBinding.LONG) || (localBinding.type == TypeBinding.DOUBLE)) { >- codeStream.dup2(); >- } else { >- codeStream.dup(); >+ switch (localBinding.type.id) { >+ case TypeIds.T_long : >+ case TypeIds.T_double : >+ codeStream.dup2(); >+ break; >+ default: >+ codeStream.dup(); >+ break; > } > } > codeStream.store(localBinding, false); >@@ -583,10 +592,11 @@ > public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) { > switch (this.bits & ASTNode.RestrictiveFlagMASK) { > case Binding.FIELD : // assigning to a field >- FieldBinding fieldBinding; >- if ((fieldBinding = (FieldBinding) this.codegenBinding).isStatic()) { >+ FieldBinding codegenField = (((FieldBinding)this.binding).original()); >+ if (codegenField.isStatic()) { > if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) { >- codeStream.getstatic(fieldBinding); >+ TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenField, this.actualReceiverType, true /* implicit this */); >+ codeStream.fieldAccess0(Opcodes.OPC_getstatic, codegenField, constantPoolDeclaringClass); > } else { > codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */); > } >@@ -600,7 +610,8 @@ > } > codeStream.dup(); > if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) { >- codeStream.getfield(fieldBinding); >+ TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenField, this.actualReceiverType, true /* implicit this */); >+ codeStream.fieldAccess0(Opcodes.OPC_getfield, codegenField, constantPoolDeclaringClass); > } else { > codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */); > } >@@ -610,20 +621,28 @@ > codeStream.checkcast(this.genericCast); > operandType = this.genericCast; > } else { >- operandType = fieldBinding.type; >+ operandType = codegenField.type; > } > if (valueRequired) { >- if (fieldBinding.isStatic()) { >- if ((operandType == TypeBinding.LONG) || (operandType == TypeBinding.DOUBLE)) { >- codeStream.dup2(); >- } else { >- codeStream.dup(); >- } >+ if (codegenField.isStatic()) { >+ switch (operandType.id) { >+ case TypeIds.T_long : >+ case TypeIds.T_double : >+ codeStream.dup2(); >+ break; >+ default: >+ codeStream.dup(); >+ break; >+ } > } else { // Stack: [owner][old field value] ---> [old field value][owner][old field value] >- if ((operandType == TypeBinding.LONG) || (operandType == TypeBinding.DOUBLE)) { >- codeStream.dup2_x1(); >- } else { >- codeStream.dup_x1(); >+ switch (operandType.id) { >+ case TypeIds.T_long : >+ case TypeIds.T_double : >+ codeStream.dup2_x1(); >+ break; >+ default: >+ codeStream.dup_x1(); >+ break; > } > } > } >@@ -631,11 +650,11 @@ > codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion); > codeStream.sendOperator(postIncrement.operator, this.implicitConversion & TypeIds.COMPILE_TYPE_MASK); > codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion); >- fieldStore(codeStream, fieldBinding, this.syntheticAccessors == null ? null : this.syntheticAccessors[SingleNameReference.WRITE], false); >+ fieldStore(codeStream, codegenField, this.syntheticAccessors == null ? null : this.syntheticAccessors[SingleNameReference.WRITE], false); > // no need for generic cast > return; > case Binding.LOCAL : // assigning to a local variable >- LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding; >+ LocalVariableBinding localBinding = (LocalVariableBinding) this.binding; > // using incr bytecode if possible > if (localBinding.type == TypeBinding.INT) { > if (valueRequired) { >@@ -649,11 +668,15 @@ > } else { > codeStream.load(localBinding); > if (valueRequired){ >- if ((localBinding.type == TypeBinding.LONG) || (localBinding.type == TypeBinding.DOUBLE)) { >- codeStream.dup2(); >- } else { >- codeStream.dup(); >- } >+ switch (localBinding.type.id) { >+ case TypeIds.T_long : >+ case TypeIds.T_double : >+ codeStream.dup2(); >+ break; >+ default: >+ codeStream.dup(); >+ break; >+ } > } > codeStream.generateImplicitConversion(this.implicitConversion); > codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion); >@@ -710,7 +733,6 @@ > if ((this.bits & Binding.FIELD) != 0) { > FieldBinding fieldBinding = (FieldBinding) this.binding; > FieldBinding codegenField = fieldBinding.original(); >- this.codegenBinding = codegenField; > if (((this.bits & ASTNode.DepthMASK) != 0) > && (codegenField.isPrivate() // private access > || (codegenField.isProtected() // implicit protected access >@@ -723,26 +745,6 @@ > currentScope.problemReporter().needToEmulateFieldAccess(codegenField, this, isReadAccess); > return; > } >- // if the binding declaring class is not visible, need special action >- // for runtime compatibility on 1.2 VMs : change the declaring class of the binding >- // NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type >- // and not from Object or implicit static field access. >- if (fieldBinding.declaringClass != this.actualReceiverType >- && !this.actualReceiverType.isArrayType() >- && fieldBinding.declaringClass != null // array.length >- && fieldBinding.constant() == Constant.NotAConstant) { >- CompilerOptions options = currentScope.compilerOptions(); >- if ((options.targetJDK >= ClassFileConstants.JDK1_2 >- && (options.complianceLevel >= ClassFileConstants.JDK1_4 || !fieldBinding.isStatic()) >- && fieldBinding.declaringClass.id != TypeIds.T_JavaLangObject) // no change for Object fields >- || !fieldBinding.declaringClass.canBeSeenBy(currentScope)) { >- >- this.codegenBinding = >- currentScope.enclosingSourceType().getUpdatedFieldBinding( >- codegenField, >- (ReferenceBinding)this.actualReceiverType.erasure()); >- } >- } > } > } > >@@ -832,7 +834,6 @@ > this.actualReceiverType = scope.enclosingSourceType(); > this.binding = scope.getBinding(this.token, this.bits & ASTNode.RestrictiveFlagMASK, this, true /*resolve*/); > } >- this.codegenBinding = this.binding; > if (this.binding.isValidBinding()) { > switch (this.bits & ASTNode.RestrictiveFlagMASK) { > case Binding.VARIABLE : // =========only variable============ >Index: compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java,v >retrieving revision 1.29 >diff -u -r1.29 Reference.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java 17 Sep 2008 09:08:38 -0000 1.29 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java 24 Sep 2008 12:36:51 -0000 >@@ -10,9 +10,14 @@ > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >-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.CodeStream; >+import org.eclipse.jdt.internal.compiler.codegen.Opcodes; >+import org.eclipse.jdt.internal.compiler.flow.FlowContext; >+import org.eclipse.jdt.internal.compiler.flow.FlowInfo; >+import org.eclipse.jdt.internal.compiler.lookup.BlockScope; >+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; >+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; >+import org.eclipse.jdt.internal.compiler.lookup.TypeIds; > > public abstract class Reference extends Expression { > /** >@@ -26,42 +31,53 @@ > public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { > return flowInfo; > } >+ > public FieldBinding fieldBinding() { > //this method should be sent one FIELD-tagged references > // (ref.bits & BindingIds.FIELD != 0)() > return null ; > } >+ > public void fieldStore(CodeStream codeStream, FieldBinding fieldBinding, MethodBinding syntheticWriteAccessor, boolean valueRequired) { > int pc = codeStream.position; > if (fieldBinding.isStatic()) { > if (valueRequired) { >- if ((fieldBinding.type == TypeBinding.LONG) || (fieldBinding.type == TypeBinding.DOUBLE)) { >- codeStream.dup2(); >- } else { >- codeStream.dup(); >+ switch (fieldBinding.type.id) { >+ case TypeIds.T_long : >+ case TypeIds.T_double : >+ codeStream.dup2(); >+ break; >+ default : >+ codeStream.dup(); >+ break; > } > } > if (syntheticWriteAccessor == null) { >- codeStream.putstatic(fieldBinding); >+ codeStream.fieldAccess0(Opcodes.OPC_putstatic, fieldBinding, null /* default declaringClass */); > } else { > codeStream.invoke(Opcodes.OPC_invokestatic, syntheticWriteAccessor, null /* default declaringClass */); > } > } else { // Stack: [owner][new field value] ---> [new field value][owner][new field value] > if (valueRequired) { >- if ((fieldBinding.type == TypeBinding.LONG) || (fieldBinding.type == TypeBinding.DOUBLE)) { >- codeStream.dup2_x1(); >- } else { >- codeStream.dup_x1(); >+ switch (fieldBinding.type.id) { >+ case TypeIds.T_long : >+ case TypeIds.T_double : >+ codeStream.dup2_x1(); >+ break; >+ default : >+ codeStream.dup_x1(); >+ break; > } > } > if (syntheticWriteAccessor == null) { >- codeStream.putfield(fieldBinding); >+ codeStream.fieldAccess0(Opcodes.OPC_putfield, fieldBinding, null /* default declaringClass */); > } else { > codeStream.invoke(Opcodes.OPC_invokestatic, syntheticWriteAccessor, null /* default declaringClass */); > } > } > codeStream.recordPositionsFrom(pc, this.sourceStart); > } >+ > public abstract void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired); > > public abstract void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired); >Index: compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java,v >retrieving revision 1.60 >diff -u -r1.60 Javadoc.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java 27 Jun 2008 16:03:55 -0000 1.60 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java 24 Sep 2008 12:36:50 -0000 >@@ -373,11 +373,11 @@ > if (scopeModifiers == -1) scopeModifiers = scope.getDeclarationModifiers(); > scope.problemReporter().javadocInvalidValueReference(fieldRef.sourceStart, fieldRef.sourceEnd, scopeModifiers); > } >- else if (fieldRef.receiverType != null) { >- if (scope.enclosingSourceType().isCompatibleWith(fieldRef.receiverType)) { >+ else if (fieldRef.actualReceiverType != null) { >+ if (scope.enclosingSourceType().isCompatibleWith(fieldRef.actualReceiverType)) { > fieldRef.bits |= ASTNode.SuperAccess; > } >- fieldRef.methodBinding = scope.findMethod((ReferenceBinding)fieldRef.receiverType, fieldRef.token, new TypeBinding[0], fieldRef); >+ fieldRef.methodBinding = scope.findMethod((ReferenceBinding)fieldRef.actualReceiverType, fieldRef.token, new TypeBinding[0], fieldRef); > } > } > >@@ -390,8 +390,8 @@ > } > > // Verify type references >- if (!hasProblems && fieldRef.binding != null && fieldRef.binding.isValidBinding() && fieldRef.receiverType instanceof ReferenceBinding) { >- ReferenceBinding resolvedType = (ReferenceBinding) fieldRef.receiverType; >+ if (!hasProblems && fieldRef.binding != null && fieldRef.binding.isValidBinding() && fieldRef.actualReceiverType instanceof ReferenceBinding) { >+ ReferenceBinding resolvedType = (ReferenceBinding) fieldRef.actualReceiverType; > verifyTypeReference(fieldRef, fieldRef.receiver, scope, source15, resolvedType, fieldRef.binding.modifiers); > } > >Index: compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java,v >retrieving revision 1.134 >diff -u -r1.134 MessageSend.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java 17 Sep 2008 11:11:09 -0000 1.134 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java 24 Sep 2008 12:36:50 -0000 >@@ -149,7 +149,7 @@ > > // actual message invocation > if (this.syntheticAccessor == null){ >- TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope); >+ TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis(), this.receiverGenericCast != null); > if (isStatic){ > codeStream.invoke(Opcodes.OPC_invokestatic, codegenBinding, constantPoolDeclaringClass); > } else if( (this.receiver.isSuper()) || codegenBinding.isPrivate()){ >@@ -193,35 +193,6 @@ > return this.genericTypeArguments; > } > >-protected TypeBinding getConstantPoolDeclaringClass(BlockScope currentScope) { >- // constantpool declaringClass >- MethodBinding codegenBinding = this.binding.original(); >- TypeBinding constantPoolDeclaringClass = codegenBinding.declaringClass; >- // Post 1.4.0 target, array clone() invocations are qualified with array type >- // This is handled in array type #clone method binding resolution (see Scope and UpdatedMethodBinding) >- if (codegenBinding == currentScope.environment().arrayClone) { >- CompilerOptions options = currentScope.compilerOptions(); >- if (options.sourceLevel > ClassFileConstants.JDK1_4 ) { >- constantPoolDeclaringClass = this.actualReceiverType.erasure(); >- } >- } else { >- // if the binding declaring class is not visible, need special action >- // for runtime compatibility on 1.2 VMs : change the declaring class of the binding >- // NOTE: from target 1.2 on, method's declaring class is touched if any different from receiver type >- // and not from Object or implicit static method call. >- if (constantPoolDeclaringClass != this.actualReceiverType && this.receiverGenericCast == null && !this.actualReceiverType.isArrayType()) { >- CompilerOptions options = currentScope.compilerOptions(); >- if ((options.targetJDK >= ClassFileConstants.JDK1_2 >- && (options.complianceLevel >= ClassFileConstants.JDK1_4 || !(this.receiver.isImplicitThis() && codegenBinding.isStatic())) >- && this.binding.declaringClass.id != TypeIds.T_JavaLangObject) // no change for Object methods >- || !this.binding.declaringClass.canBeSeenBy(currentScope)) { >- constantPoolDeclaringClass = this.actualReceiverType.erasure(); >- } >- } >- } >- return constantPoolDeclaringClass; >-} >- > public boolean isSuperAccess() { > return this.receiver.isSuper(); > } >Index: compiler/org/eclipse/jdt/internal/compiler/ast/JavadocFieldReference.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocFieldReference.java,v >retrieving revision 1.29 >diff -u -r1.29 JavadocFieldReference.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/JavadocFieldReference.java 27 Jun 2008 16:03:56 -0000 1.29 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/JavadocFieldReference.java 24 Sep 2008 12:36:50 -0000 >@@ -41,19 +41,19 @@ > > this.constant = Constant.NotAConstant; > if (this.receiver == null) { >- this.receiverType = scope.enclosingReceiverType(); >+ this.actualReceiverType = scope.enclosingReceiverType(); > } else if (scope.kind == Scope.CLASS_SCOPE) { >- this.receiverType = this.receiver.resolveType((ClassScope) scope); >+ this.actualReceiverType = this.receiver.resolveType((ClassScope) scope); > } else { >- this.receiverType = this.receiver.resolveType((BlockScope)scope); >+ this.actualReceiverType = this.receiver.resolveType((BlockScope)scope); > } >- if (this.receiverType == null) { >+ if (this.actualReceiverType == null) { > return null; > } > > Binding fieldBinding = (this.receiver != null && this.receiver.isThis()) > ? scope.classScope().getBinding(this.token, this.bits & RestrictiveFlagMASK, this, true /*resolve*/) >- : scope.getField(this.receiverType, this.token, this); >+ : scope.getField(this.actualReceiverType, this.token, this); > if (!fieldBinding.isValidBinding()) { > // implicit lookup may discover issues due to static/constructor contexts. javadoc must be resilient > switch (fieldBinding.problemId()) { >@@ -72,8 +72,8 @@ > // problem already got signaled on receiver, do not report secondary problem > return null; > } >- if (this.receiverType instanceof ReferenceBinding) { >- ReferenceBinding refBinding = (ReferenceBinding) this.receiverType; >+ if (this.actualReceiverType instanceof ReferenceBinding) { >+ ReferenceBinding refBinding = (ReferenceBinding) this.actualReceiverType; > MethodBinding possibleMethod = this.receiver.isThis() > ? scope.getImplicitMethod(this.token, Binding.NO_TYPES, this) > : scope.getMethod(refBinding, this.token, Binding.NO_TYPES, this); >@@ -82,7 +82,7 @@ > } else { > ProblemMethodBinding problemMethodBinding = (ProblemMethodBinding) possibleMethod; > if (problemMethodBinding.closestMatch == null) { >- scope.problemReporter().javadocInvalidField(this, fieldBinding, this.receiverType, scope.getDeclarationModifiers()); >+ scope.problemReporter().javadocInvalidField(this, fieldBinding, this.actualReceiverType, scope.getDeclarationModifiers()); > } else { > this.methodBinding = problemMethodBinding.closestMatch; > } >Index: compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java,v >retrieving revision 1.131 >diff -u -r1.131 QualifiedNameReference.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java 17 Sep 2008 09:08:38 -0000 1.131 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java 24 Sep 2008 12:36:51 -0000 >@@ -44,7 +44,7 @@ > > public char[][] tokens; > public long[] sourcePositions; >- public FieldBinding[] otherBindings, otherCodegenBindings; >+ public FieldBinding[] otherBindings; > int[] otherDepths; > public int indexOfFirstFieldBinding;//points (into tokens) for the first token that corresponds to first FieldBinding > public SyntheticMethodBinding syntheticWriteAccessor; >@@ -69,7 +69,7 @@ > case Binding.FIELD : // reading a field > lastFieldBinding = (FieldBinding) this.binding; > if (needValue || complyTo14) { >- manageSyntheticAccessIfNecessary(currentScope, lastFieldBinding, this.actualReceiverType, 0, flowInfo); >+ manageSyntheticAccessIfNecessary(currentScope, lastFieldBinding, 0, flowInfo); > } > // check if final blank field > if (lastFieldBinding.isBlankFinal() >@@ -107,14 +107,7 @@ > lastFieldBinding = this.otherBindings[i]; > needValue = !this.otherBindings[i+1].isStatic(); > if (needValue || complyTo14) { >- manageSyntheticAccessIfNecessary( >- currentScope, >- lastFieldBinding, >- i == 0 >- ? ((VariableBinding)this.binding).type >- : this.otherBindings[i-1].type, >- i + 1, >- flowInfo); >+ manageSyntheticAccessIfNecessary(currentScope, lastFieldBinding, i + 1, flowInfo); > } > } > lastFieldBinding = this.otherBindings[otherBindingsCount-1]; >@@ -127,24 +120,7 @@ > && (!flowInfo.isDefinitelyAssigned(lastFieldBinding))) { > currentScope.problemReporter().uninitializedBlankFinalField(lastFieldBinding, this); > } >- TypeBinding lastReceiverType; >- switch (otherBindingsCount) { >- case 0 : >- lastReceiverType = this.actualReceiverType; >- break; >- case 1 : >- lastReceiverType = ((VariableBinding)this.binding).type; >- break; >- default: >- lastReceiverType = this.otherBindings[otherBindingsCount-2].type; >- break; >- } >- manageSyntheticAccessIfNecessary( >- currentScope, >- lastFieldBinding, >- lastReceiverType, >- otherBindingsCount, >- flowInfo); >+ manageSyntheticAccessIfNecessary(currentScope, lastFieldBinding, otherBindingsCount, flowInfo); > } > > if (assignment.expression != null) { >@@ -176,20 +152,7 @@ > } > } > } >- // equivalent to valuesRequired[maxOtherBindings] >- TypeBinding lastReceiverType; >- switch (otherBindingsCount) { >- case 0 : >- lastReceiverType = this.actualReceiverType; >- break; >- case 1 : >- lastReceiverType = ((VariableBinding)this.binding).type; >- break; >- default : >- lastReceiverType = this.otherBindings[otherBindingsCount-2].type; >- break; >- } >- manageSyntheticAccessIfNecessary(currentScope, lastFieldBinding, lastReceiverType, -1 /*write-access*/, flowInfo); >+ manageSyntheticAccessIfNecessary(currentScope, lastFieldBinding, -1 /*write-access*/, flowInfo); > > return flowInfo; > } >@@ -207,7 +170,7 @@ > switch (this.bits & ASTNode.RestrictiveFlagMASK) { > case Binding.FIELD : // reading a field > if (needValue || complyTo14) { >- manageSyntheticAccessIfNecessary(currentScope, (FieldBinding) this.binding, this.actualReceiverType, 0, flowInfo); >+ manageSyntheticAccessIfNecessary(currentScope, (FieldBinding) this.binding, 0, flowInfo); > } > if (this.indexOfFirstFieldBinding == 1) { // was an implicit reference to the first field binding > FieldBinding fieldBinding = (FieldBinding) this.binding; >@@ -221,8 +184,7 @@ > break; > case Binding.LOCAL : // reading a local variable > LocalVariableBinding localBinding; >- if (!flowInfo >- .isDefinitelyAssigned(localBinding = (LocalVariableBinding) this.binding)) { >+ if (!flowInfo.isDefinitelyAssigned(localBinding = (LocalVariableBinding) this.binding)) { > currentScope.problemReporter().uninitializedLocalVariable(localBinding, this); > } > if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) { >@@ -240,20 +202,7 @@ > for (int i = 0; i < otherBindingsCount; i++) { > needValue = i < otherBindingsCount-1 ? !this.otherBindings[i+1].isStatic() : valueRequired; > if (needValue || complyTo14) { >- TypeBinding lastReceiverType = getGenericCast(i); >- if (lastReceiverType == null) { >- if (i == 0) { >- lastReceiverType = ((VariableBinding)this.binding).type; >- } else { >- lastReceiverType = this.otherBindings[i-1].type; >- } >- } >- manageSyntheticAccessIfNecessary( >- currentScope, >- this.otherBindings[i], >- lastReceiverType, >- i + 1, >- flowInfo); >+ manageSyntheticAccessIfNecessary(currentScope, this.otherBindings[i], i + 1, flowInfo); > } > } > } >@@ -376,7 +325,7 @@ > boolean isFirst = lastFieldBinding == this.binding > && (this.indexOfFirstFieldBinding == 1 || lastFieldBinding.declaringClass == currentScope.enclosingReceiverType()) > && this.otherBindings == null; // could be dup: next.next.next >- TypeBinding requiredGenericCast = getGenericCast(this.otherCodegenBindings == null ? 0 : this.otherCodegenBindings.length); >+ TypeBinding requiredGenericCast = getGenericCast(this.otherBindings == null ? 0 : this.otherBindings.length); > if (valueRequired > || (!isFirst && currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) > || ((this.implicitConversion & TypeIds.UNBOXING) != 0) >@@ -391,15 +340,13 @@ > codeStream.pop(); > } > } else { >- SyntheticMethodBinding accessor = >- this.syntheticReadAccessors == null >- ? null >- : this.syntheticReadAccessors[this.syntheticReadAccessors.length - 1]; >+ SyntheticMethodBinding accessor = this.syntheticReadAccessors == null ? null : this.syntheticReadAccessors[this.syntheticReadAccessors.length - 1]; > if (accessor == null) { >+ TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, lastFieldBinding, getFinalReceiverType(), isFirst); > if (isStatic) { >- codeStream.getstatic(lastFieldBinding); >+ codeStream.fieldAccess0(Opcodes.OPC_getstatic, lastFieldBinding, constantPoolDeclaringClass); > } else { >- codeStream.getfield(lastFieldBinding); >+ codeStream.fieldAccess0(Opcodes.OPC_getfield, lastFieldBinding, constantPoolDeclaringClass); > } > } else { > codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */); >@@ -436,29 +383,23 @@ > codeStream.recordPositionsFrom(pc, this.sourceStart); > } > >-public void generateCompoundAssignment( >- BlockScope currentScope, >- CodeStream codeStream, >- Expression expression, >- int operator, >- int assignmentImplicitConversion, >- boolean valueRequired) { >- >+public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) { > FieldBinding lastFieldBinding = generateReadSequence(currentScope, codeStream); >- SyntheticMethodBinding accessor = >- this.syntheticReadAccessors == null >- ? null >- : this.syntheticReadAccessors[this.syntheticReadAccessors.length - 1]; >+ boolean isFirst = lastFieldBinding == this.binding >+ && (this.indexOfFirstFieldBinding == 1 || lastFieldBinding.declaringClass == currentScope.enclosingReceiverType()) >+ && this.otherBindings == null; // could be dup: next.next.next >+ TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, lastFieldBinding, getFinalReceiverType(), isFirst); >+ SyntheticMethodBinding accessor = this.syntheticReadAccessors == null ? null : this.syntheticReadAccessors[this.syntheticReadAccessors.length - 1]; > if (lastFieldBinding.isStatic()) { > if (accessor == null) { >- codeStream.getstatic(lastFieldBinding); >+ codeStream.fieldAccess0(Opcodes.OPC_getstatic, lastFieldBinding, constantPoolDeclaringClass); > } else { > codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */); > } > } else { > codeStream.dup(); > if (accessor == null) { >- codeStream.getfield(lastFieldBinding); >+ codeStream.fieldAccess0(Opcodes.OPC_getfield, lastFieldBinding, constantPoolDeclaringClass); > } else { > codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */); > } >@@ -473,7 +414,7 @@ > codeStream.generateStringConcatenationAppend(currentScope, null, expression); > break; > default : >- TypeBinding requiredGenericCast = getGenericCast(this.otherCodegenBindings == null ? 0 : this.otherCodegenBindings.length); >+ TypeBinding requiredGenericCast = getGenericCast(this.otherBindings == null ? 0 : this.otherBindings.length); > if (requiredGenericCast != null) codeStream.checkcast(requiredGenericCast); > // promote the array reference to the suitable operation type > codeStream.generateImplicitConversion(this.implicitConversion); >@@ -495,24 +436,28 @@ > > public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) { > FieldBinding lastFieldBinding = generateReadSequence(currentScope, codeStream); >+ boolean isFirst = lastFieldBinding == this.binding >+ && (this.indexOfFirstFieldBinding == 1 || lastFieldBinding.declaringClass == currentScope.enclosingReceiverType()) >+ && this.otherBindings == null; // could be dup: next.next.next >+ TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, lastFieldBinding, getFinalReceiverType(), isFirst); > SyntheticMethodBinding accessor = this.syntheticReadAccessors == null > ? null > : this.syntheticReadAccessors[this.syntheticReadAccessors.length - 1]; > if (lastFieldBinding.isStatic()) { > if (accessor == null) { >- codeStream.getstatic(lastFieldBinding); >+ codeStream.fieldAccess0(Opcodes.OPC_getstatic, lastFieldBinding, constantPoolDeclaringClass); > } else { >- codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */); >+ codeStream.invoke(Opcodes.OPC_invokestatic, accessor, constantPoolDeclaringClass); > } > } else { > codeStream.dup(); > if (accessor == null) { >- codeStream.getfield(lastFieldBinding); >+ codeStream.fieldAccess0(Opcodes.OPC_getfield, lastFieldBinding, null /* default declaringClass */); > } else { > codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */); > } > } >- TypeBinding requiredGenericCast = getGenericCast(this.otherCodegenBindings == null ? 0 : this.otherCodegenBindings.length); >+ TypeBinding requiredGenericCast = getGenericCast(this.otherBindings == null ? 0 : this.otherBindings.length); > TypeBinding operandType; > if (requiredGenericCast != null) { > codeStream.checkcast(requiredGenericCast); >@@ -523,19 +468,25 @@ > // duplicate the old field value > if (valueRequired) { > if (lastFieldBinding.isStatic()) { >- if ((operandType == TypeBinding.LONG) >- || (operandType == TypeBinding.DOUBLE)) { >- codeStream.dup2(); >- } else { >- codeStream.dup(); >- } >+ switch (operandType.id) { >+ case TypeIds.T_long : >+ case TypeIds.T_double : >+ codeStream.dup2(); >+ break; >+ default: >+ codeStream.dup(); >+ break; >+ } > } else { // Stack: [owner][old field value] ---> [old field value][owner][old field value] >- if ((operandType == TypeBinding.LONG) >- || (operandType == TypeBinding.DOUBLE)) { >- codeStream.dup2_x1(); >- } else { >- codeStream.dup_x1(); >- } >+ switch (operandType.id) { >+ case TypeIds.T_long : >+ case TypeIds.T_double : >+ codeStream.dup2_x1(); >+ break; >+ default: >+ codeStream.dup_x1(); >+ break; >+ } > } > } > codeStream.generateImplicitConversion(this.implicitConversion); >@@ -554,16 +505,18 @@ > */ > public FieldBinding generateReadSequence(BlockScope currentScope, CodeStream codeStream) { > // determine the rank until which we now we do not need any actual value for the field access >- int otherBindingsCount = this.otherCodegenBindings == null ? 0 : this.otherCodegenBindings.length; >+ int otherBindingsCount = this.otherBindings == null ? 0 : this.otherBindings.length; > boolean needValue = otherBindingsCount == 0 || !this.otherBindings[0].isStatic(); >- FieldBinding lastFieldBinding = null; >- TypeBinding lastGenericCast = null; >+ FieldBinding lastFieldBinding; >+ TypeBinding lastGenericCast; >+ TypeBinding lastReceiverType; > boolean complyTo14 = currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4; > > switch (this.bits & ASTNode.RestrictiveFlagMASK) { > case Binding.FIELD : >- lastFieldBinding = (FieldBinding) this.codegenBinding; >+ lastFieldBinding = ((FieldBinding) this.binding).original(); > lastGenericCast = this.genericCast; >+ lastReceiverType = this.actualReceiverType; > // if first field is actually constant, we can inline it > if (lastFieldBinding.constant() != Constant.NotAConstant) { > break; >@@ -581,8 +534,11 @@ > } > break; > case Binding.LOCAL : // reading the first local variable >+ lastFieldBinding = null; >+ lastGenericCast = null; >+ lastReceiverType = null; > if (!needValue) break; // no value needed >- LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding; >+ LocalVariableBinding localBinding = (LocalVariableBinding) this.binding; > // regular local variable read > Constant localConstant = localBinding.constant(); > if (localConstant != Constant.NotAConstant) { >@@ -598,15 +554,19 @@ > codeStream.load(localBinding); > } > } >+ break; >+ default : // should not occur >+ return null; > } > > // all intermediate field accesses are read accesses > // only the last field binding is a write access > int positionsLength = this.sourcePositions.length; >- if (this.otherCodegenBindings != null) { >+ FieldBinding initialFieldBinding = lastFieldBinding; // can be null if initial was a local binding >+ if (this.otherBindings != null) { > for (int i = 0; i < otherBindingsCount; i++) { > int pc = codeStream.position; >- FieldBinding nextField = this.otherCodegenBindings[i]; >+ FieldBinding nextField = this.otherBindings[i].original(); > TypeBinding nextGenericCast = this.otherGenericCasts == null ? null : this.otherGenericCasts[i]; > if (lastFieldBinding != null) { > needValue = !nextField.isStatic(); >@@ -623,10 +583,11 @@ > if (needValue || (i > 0 && complyTo14) || lastGenericCast != null) { > MethodBinding accessor = this.syntheticReadAccessors == null ? null : this.syntheticReadAccessors[i]; > if (accessor == null) { >+ TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, lastFieldBinding, lastReceiverType, i == 0 && this.indexOfFirstFieldBinding == 1); > if (lastFieldBinding.isStatic()) { >- codeStream.getstatic(lastFieldBinding); >+ codeStream.fieldAccess0(Opcodes.OPC_getstatic, lastFieldBinding, constantPoolDeclaringClass); > } else { >- codeStream.getfield(lastFieldBinding); >+ codeStream.fieldAccess0(Opcodes.OPC_getfield, lastFieldBinding, constantPoolDeclaringClass); > } > } else { > codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */); >@@ -634,13 +595,14 @@ > if (lastGenericCast != null) codeStream.checkcast(lastGenericCast); > if (!needValue) codeStream.pop(); > } else { >- if (this.codegenBinding == lastFieldBinding) { >+ if (lastFieldBinding == initialFieldBinding) { > if (lastFieldBinding.isStatic()){ > // if no valueRequired, still need possible side-effects of <clinit> invocation, if field belongs to different class >- if (((FieldBinding)this.binding).original().declaringClass != this.actualReceiverType.erasure()) { >+ if (initialFieldBinding.declaringClass != this.actualReceiverType.erasure()) { > MethodBinding accessor = this.syntheticReadAccessors == null ? null : this.syntheticReadAccessors[i]; > if (accessor == null) { >- codeStream.getstatic(lastFieldBinding); >+ TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, lastFieldBinding, lastReceiverType, i == 0 && this.indexOfFirstFieldBinding == 1); >+ codeStream.fieldAccess0(Opcodes.OPC_getstatic, lastFieldBinding, constantPoolDeclaringClass); > } else { > codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */); > } >@@ -658,6 +620,7 @@ > } > } > } >+ lastReceiverType = lastFieldBinding.type; > lastFieldBinding = nextField; > lastGenericCast = nextGenericCast; > } >@@ -676,15 +639,30 @@ > return null; > } > >-// get the matching codegenBinding > protected FieldBinding getCodegenBinding(int index) { > if (index == 0){ >- return (FieldBinding)this.codegenBinding; >+ return ((FieldBinding)this.binding).original(); > } else { >- return this.otherCodegenBindings[index-1]; >+ return this.otherBindings[index-1].original(); > } > } > >+/** >+ * Returns the receiver type for the final field in sequence (i.e. the return type of the previous binding) >+ * @return receiver type for the final field in sequence >+ */ >+protected TypeBinding getFinalReceiverType() { >+ int otherBindingsCount = this.otherBindings == null ? 0 : this.otherBindings.length; >+ switch (otherBindingsCount) { >+ case 0 : >+ return this.actualReceiverType; >+ case 1 : >+ return ((VariableBinding)this.binding).type; >+ default: >+ return this.otherBindings[otherBindingsCount-2].type; >+ } >+} >+ > // get the matching generic cast > protected TypeBinding getGenericCast(int index) { > if (index == 0){ >@@ -694,7 +672,6 @@ > return this.otherGenericCasts[index-1]; > } > } >- > public TypeBinding getOtherFieldBindings(BlockScope scope) { > // At this point restrictiveFlag may ONLY have two potential value : FIELD LOCAL (i.e cast <<(VariableBinding) binding>> is valid) > int length = this.tokens.length; >@@ -730,7 +707,6 @@ > } > // allocation of the fieldBindings array and its respective constants > int otherBindingsLength = length - index; >- this.otherCodegenBindings = this.otherBindings = new FieldBinding[otherBindingsLength]; > this.otherDepths = new int[otherBindingsLength]; > > // fill the first constant (the one of the binding) >@@ -825,18 +801,12 @@ > /** > * index is <0 to denote write access emulation > */ >-public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FieldBinding fieldBinding, TypeBinding lastReceiverType, int index, FlowInfo flowInfo) { >+public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FieldBinding fieldBinding, int index, FlowInfo flowInfo) { > if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return; > // index == 0 denotes the first fieldBinding, index > 0 denotes one of the 'otherBindings', index < 0 denotes a write access (to last binding) > if (fieldBinding.constant() != Constant.NotAConstant) > return; > >- // if field from parameterized type got found, use the original field at codegen time >- FieldBinding originalField = fieldBinding.original(); >- if (originalField != fieldBinding) { >- setCodegenBinding(index < 0 ? (this.otherBindings == null ? 0 : this.otherBindings.length) : index, originalField); >- } >- > if (fieldBinding.isPrivate()) { // private access > FieldBinding someCodegenBinding = getCodegenBinding(index < 0 ? (this.otherBindings == null ? 0 : this.otherBindings.length) : index); > if (someCodegenBinding.declaringClass != currentScope.enclosingSourceType()) { >@@ -852,34 +822,13 @@ > > // implicit protected access > if (depth > 0 && (fieldBinding.declaringClass.getPackage() != currentScope.enclosingSourceType().getPackage())) { >- FieldBinding someCodegenBinding = getCodegenBinding(index < 0 ? (this.otherBindings == null ? 0 : this.otherBindings.length) : index); >+ FieldBinding codegenField = getCodegenBinding(index < 0 ? (this.otherBindings == null ? 0 : this.otherBindings.length) : index); > setSyntheticAccessor(fieldBinding, index, >- ((SourceTypeBinding) currentScope.enclosingSourceType().enclosingTypeAt(depth)).addSyntheticMethod(someCodegenBinding, index >= 0 /*read-access?*/)); >- currentScope.problemReporter().needToEmulateFieldAccess(someCodegenBinding, this, index >= 0 /*read-access?*/); >+ ((SourceTypeBinding) currentScope.enclosingSourceType().enclosingTypeAt(depth)).addSyntheticMethod(codegenField, index >= 0 /*read-access?*/)); >+ currentScope.problemReporter().needToEmulateFieldAccess(codegenField, this, index >= 0 /*read-access?*/); > return; > } > } >- // if the binding declaring class is not visible, need special action >- // for runtime compatibility on 1.2 VMs : change the declaring class of the binding >- // NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type >- // and not from Object or implicit static field access. >- if (fieldBinding.declaringClass != lastReceiverType >- && !lastReceiverType.isArrayType() >- && fieldBinding.declaringClass != null // array.length >- && fieldBinding.constant() == Constant.NotAConstant) { >- CompilerOptions options = currentScope.compilerOptions(); >- if ((options.targetJDK >= ClassFileConstants.JDK1_2 >- && (options.complianceLevel >= ClassFileConstants.JDK1_4 || !(index <= 1 && this.indexOfFirstFieldBinding == 1 && fieldBinding.isStatic())) >- && fieldBinding.declaringClass.id != TypeIds.T_JavaLangObject) // no change for Object fields >- || !fieldBinding.declaringClass.canBeSeenBy(currentScope)) { >- >- setCodegenBinding( >- index < 0 ? (this.otherBindings == null ? 0 : this.otherBindings.length) : index, >- currentScope.enclosingSourceType().getUpdatedFieldBinding( >- getCodegenBinding(index < 0 ? (this.otherBindings == null ? 0 : this.otherBindings.length) : index), >- (ReferenceBinding)lastReceiverType.erasure())); >- } >- } > } > > public int nullStatus(FlowInfo flowInfo) { >@@ -908,7 +857,7 @@ > */ > public TypeBinding postConversionType(Scope scope) { > TypeBinding convertedType = this.resolvedType; >- TypeBinding requiredGenericCast = getGenericCast(this.otherCodegenBindings == null ? 0 : this.otherCodegenBindings.length); >+ TypeBinding requiredGenericCast = getGenericCast(this.otherBindings == null ? 0 : this.otherBindings.length); > if (requiredGenericCast != null) > convertedType = requiredGenericCast; > int runtimeType = (this.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4; >@@ -973,7 +922,7 @@ > // the TC is Flag_Type Flag_LocalField and Flag_TypeLocalField > this.actualReceiverType = scope.enclosingReceiverType(); > this.constant = Constant.NotAConstant; >- if ((this.codegenBinding = this.binding = scope.getBinding(this.tokens, this.bits & ASTNode.RestrictiveFlagMASK, this, true /*resolve*/)).isValidBinding()) { >+ if ((this.binding = scope.getBinding(this.tokens, this.bits & ASTNode.RestrictiveFlagMASK, this, true /*resolve*/)).isValidBinding()) { > switch (this.bits & ASTNode.RestrictiveFlagMASK) { > case Binding.VARIABLE : //============only variable=========== > case Binding.TYPE | Binding.VARIABLE : >@@ -1056,19 +1005,6 @@ > return this.resolvedType = reportError(scope); > } > >-// set the matching codegenBinding and generic cast >-protected void setCodegenBinding(int index, FieldBinding someCodegenBinding) { >- if (index == 0){ >- this.codegenBinding = someCodegenBinding; >- } else { >- int length = this.otherBindings.length; >- if (this.otherCodegenBindings == this.otherBindings){ >- System.arraycopy(this.otherBindings, 0, this.otherCodegenBindings = new FieldBinding[length], 0, length); >- } >- this.otherCodegenBindings[index-1] = someCodegenBinding; >- } >-} >- > public void setFieldIndex(int index) { > this.indexOfFirstFieldBinding = index; > } >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.92 >diff -u -r1.92 FieldDeclaration.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java 11 Sep 2008 10:04:25 -0000 1.92 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java 24 Sep 2008 12:36:50 -0000 >@@ -104,9 +104,9 @@ > this.initialization.generateCode(currentScope, codeStream, true); > // store into field > if (isStatic) { >- codeStream.putstatic(this.binding); >+ codeStream.fieldAccess0(Opcodes.OPC_putstatic, this.binding, null /* default declaringClass */); > } else { >- codeStream.putfield(this.binding); >+ codeStream.fieldAccess0(Opcodes.OPC_putfield, this.binding, null /* default declaringClass */); > } > } > codeStream.recordPositionsFrom(pc, this.sourceStart); >Index: compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java,v >retrieving revision 1.161 >diff -u -r1.161 SourceTypeBinding.java >--- compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java 17 Sep 2008 09:33:00 -0000 1.161 >+++ compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java 24 Sep 2008 12:36:52 -0000 >@@ -1065,7 +1065,7 @@ > public ReferenceBinding[] memberTypes() { > return this.memberTypes; > } >-///** @deprecated */ >+/** @deprecated */ > public FieldBinding getUpdatedFieldBinding(FieldBinding targetField, ReferenceBinding newDeclaringClass) { > if (this.synthetics == null) > this.synthetics = new HashMap[MAX_SYNTHETICS]; >Index: compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java,v >retrieving revision 1.166 >diff -u -r1.166 CodeStream.java >--- compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java 17 Sep 2008 09:28:33 -0000 1.166 >+++ compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java 24 Sep 2008 12:36:52 -0000 >@@ -21,6 +21,7 @@ > import org.eclipse.jdt.internal.compiler.ast.OperatorIds; > import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; > import org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo; >+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; > import org.eclipse.jdt.internal.compiler.impl.Constant; > import org.eclipse.jdt.internal.compiler.lookup.*; > import org.eclipse.jdt.internal.compiler.problem.AbortMethod; >@@ -1214,6 +1215,65 @@ > this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_fdiv; > } > >+public void fieldAccess0(byte opcode, FieldBinding fieldBinding, TypeBinding declaringClass) { >+ if (declaringClass == null) declaringClass = fieldBinding.declaringClass; >+ if (declaringClass.leafComponentType().isNestedType()) { >+ this.classFile.recordInnerClasses(declaringClass); >+ } >+ TypeBinding returnType = fieldBinding.type; >+ int returnTypeSize; >+ switch (returnType.id) { >+ case TypeIds.T_long : >+ case TypeIds.T_double : >+ returnTypeSize = 2; >+ break; >+ default : >+ returnTypeSize = 1; >+ break; >+ } >+ this.fieldAccess(opcode, returnTypeSize, declaringClass.constantPoolName(), fieldBinding.name, returnType.signature()); >+} >+ >+private void fieldAccess(byte opcode, int returnTypeSize, char[] declaringClass, char[] fieldName, char[] signature) { >+ this.countLabels = 0; >+ switch(opcode) { >+ case Opcodes.OPC_getfield : >+ if (returnTypeSize == 2) { >+ this.stackDepth++; >+ } >+ break; >+ case Opcodes.OPC_getstatic : >+ if (returnTypeSize == 2) { >+ this.stackDepth += 2; >+ } else { >+ this.stackDepth++; >+ } >+ break; >+ case Opcodes.OPC_putfield : >+ if (returnTypeSize == 2) { >+ this.stackDepth -= 3; >+ } else { >+ this.stackDepth -= 2; >+ } >+ break; >+ case Opcodes.OPC_putstatic : >+ if (returnTypeSize == 2) { >+ this.stackDepth -= 2; >+ } else { >+ this.stackDepth--; >+ } >+ } >+ if (this.stackDepth > this.stackMax) { >+ this.stackMax = this.stackDepth; >+ } >+ if (this.classFileOffset + 2 >= this.bCodeStream.length) { >+ resizeByteArray(); >+ } >+ this.position++; >+ this.bCodeStream[this.classFileOffset++] = opcode; >+ writeUnsignedShort(this.constantPool.literalIndexForField(declaringClass, fieldName, signature)); >+} >+ > public void fload(int iArg) { > this.countLabels = 0; > this.stackDepth++; >@@ -1641,7 +1701,7 @@ > } else { > BranchLabel endLabel = new BranchLabel(this); > if (syntheticFieldBinding != null) { // non interface case >- getstatic(syntheticFieldBinding); >+ fieldAccess0(Opcodes.OPC_getstatic, syntheticFieldBinding, null /* default declaringClass */); > dup(); > ifnonnull(endLabel); > pop(); >@@ -1684,7 +1744,7 @@ > > if (syntheticFieldBinding != null) { // non interface case > dup(); >- putstatic(syntheticFieldBinding); >+ fieldAccess0(Opcodes.OPC_putstatic, syntheticFieldBinding, null /* default declaringClass */); > } > goto_(endLabel); > >@@ -1877,57 +1937,6 @@ > invokeAccessibleObjectSetAccessible(); > } > >-private void generateFieldAccess(byte opcode, int returnTypeSize, char[] declaringClass, char[] name, char[] signature) { >- this.countLabels = 0; >- switch(opcode) { >- case Opcodes.OPC_getfield : >- if (returnTypeSize == 2) { >- this.stackDepth++; >- } >- break; >- case Opcodes.OPC_getstatic : >- if (returnTypeSize == 2) { >- this.stackDepth += 2; >- } else { >- this.stackDepth++; >- } >- break; >- case Opcodes.OPC_putfield : >- if (returnTypeSize == 2) { >- this.stackDepth -= 3; >- } else { >- this.stackDepth -= 2; >- } >- break; >- case Opcodes.OPC_putstatic : >- if (returnTypeSize == 2) { >- this.stackDepth -= 2; >- } else { >- this.stackDepth--; >- } >- } >- if (this.stackDepth > this.stackMax) { >- this.stackMax = this.stackDepth; >- } >- if (this.classFileOffset + 2 >= this.bCodeStream.length) { >- resizeByteArray(); >- } >- this.position++; >- this.bCodeStream[this.classFileOffset++] = opcode; >- writeUnsignedShort(this.constantPool.literalIndexForField(declaringClass, name, signature)); >-} >- >-private void generateFieldAccess(byte opcode, int returnTypeSize, ReferenceBinding binding, char[] name, TypeBinding type) { >- if (binding.isNestedType()) { >- this.classFile.recordInnerClasses(binding); >- } >- TypeBinding leafComponentType = type.leafComponentType(); >- if (leafComponentType.isNestedType()) { >- this.classFile.recordInnerClasses(leafComponentType); >- } >- this.generateFieldAccess(opcode, returnTypeSize, binding.constantPoolName(), name, type.signature()); >-} >- > /** > * Generates the sequence of instructions which will perform the conversion of the expression > * on the stack into a different type (e.g. long l = someInt; --> i2l must be inserted). >@@ -2251,14 +2260,14 @@ > } else if (mappingSequence[0] instanceof FieldBinding) { > FieldBinding fieldBinding = (FieldBinding) mappingSequence[0]; > aload_0(); >- getfield(fieldBinding); >+ fieldAccess0(Opcodes.OPC_getfield, fieldBinding, null /* default declaringClass */); > } else { > load((LocalVariableBinding) mappingSequence[0]); > } > for (int i = 1, length = mappingSequence.length; i < length; i++) { > if (mappingSequence[i] instanceof FieldBinding) { > FieldBinding fieldBinding = (FieldBinding) mappingSequence[i]; >- getfield(fieldBinding); >+ fieldAccess0(Opcodes.OPC_getfield, fieldBinding, null /* default declaringClass */); > } else { > invoke(Opcodes.OPC_invokestatic, (MethodBinding) mappingSequence[i], null /* default declaringClass */); > } >@@ -2400,11 +2409,9 @@ > //} > public void generateSyntheticBodyForEnumValues(SyntheticMethodBinding methodBinding) { > ClassScope scope = ((SourceTypeBinding)methodBinding.declaringClass).scope; >- FieldBinding enumValuesSyntheticfield = scope.referenceContext.enumValuesSyntheticfield; > initializeMaxLocals(methodBinding); > TypeBinding enumArray = methodBinding.returnType; >- >- getstatic(enumValuesSyntheticfield); >+ fieldAccess0(Opcodes.OPC_getstatic, scope.referenceContext.enumValuesSyntheticfield, null /* default declaringClass */); > dup(); > astore_0(); > iconst_0(); >@@ -2425,11 +2432,11 @@ > public void generateSyntheticBodyForFieldReadAccess(SyntheticMethodBinding accessBinding) { > initializeMaxLocals(accessBinding); > FieldBinding fieldBinding = accessBinding.targetReadField; >- if (fieldBinding.isStatic()) >- getstatic(fieldBinding); >- else { >+ if (fieldBinding.isStatic()) { >+ fieldAccess0(Opcodes.OPC_getstatic, fieldBinding, null /* default declaringClass */); >+ } else { > aload_0(); >- getfield(fieldBinding); >+ fieldAccess0(Opcodes.OPC_getfield, fieldBinding, null /* default declaringClass */); > } > switch (fieldBinding.type.id) { > // case T_void : >@@ -2461,11 +2468,11 @@ > FieldBinding fieldBinding = accessBinding.targetWriteField; > if (fieldBinding.isStatic()) { > load(fieldBinding.type, 0); >- putstatic(fieldBinding); >+ fieldAccess0(Opcodes.OPC_putstatic, fieldBinding, null /* default declaringClass */); > } else { > aload_0(); > load(fieldBinding.type, 1); >- putfield(fieldBinding); >+ fieldAccess0(Opcodes.OPC_putfield, fieldBinding, null /* default declaringClass */); > } > return_(); > } >@@ -2551,7 +2558,7 @@ > initializeMaxLocals(methodBinding); > final BranchLabel nullLabel = new BranchLabel(this); > FieldBinding syntheticFieldBinding = methodBinding.targetReadField; >- getstatic(syntheticFieldBinding); >+ fieldAccess0(Opcodes.OPC_getstatic, syntheticFieldBinding, null /* default declaringClass */); > dup(); > ifnull(nullLabel); > areturn(); >@@ -2575,7 +2582,7 @@ > final ExceptionLabel anyExceptionHandler = new ExceptionLabel(this, TypeBinding.LONG /* represents NoSuchFieldError*/); > anyExceptionHandler.placeStart(); > aload_0(); >- getstatic(fieldBinding); >+ fieldAccess0(Opcodes.OPC_getstatic, fieldBinding, null /* default declaringClass */); > invokeEnumOrdinal(enumBinding.constantPoolName()); > this.generateInlinedValue(fieldBinding.id + 1); // zero should not be returned see bug 141810 > iastore(); >@@ -2591,7 +2598,7 @@ > } > aload_0(); > dup(); >- putstatic(syntheticFieldBinding); >+ fieldAccess0(Opcodes.OPC_putstatic, syntheticFieldBinding, null /* default declaringClass */); > areturn(); > removeVariable(localVariableBinding); > } >@@ -2868,116 +2875,155 @@ > return contents; > } > >-public void getfield(FieldBinding fieldBinding) { >- int returnTypeSize = 1; >- if ((fieldBinding.type.id == TypeIds.T_double) || (fieldBinding.type.id == TypeIds.T_long)) { >- returnTypeSize = 2; >- } >- generateFieldAccess( >- Opcodes.OPC_getfield, >- returnTypeSize, >- fieldBinding.declaringClass, >- fieldBinding.name, >- fieldBinding.type); >+/** >+ * Returns the type that should be substituted to original binding declaring class as the proper receiver type >+ * @param currentScope >+ * @param codegenBinding >+ * @param actualReceiverType >+ * @param isImplicitThisReceiver >+ * @return the receiver type to use in constant pool >+ */ >+public static TypeBinding getConstantPoolDeclaringClass(BlockScope currentScope, FieldBinding codegenBinding, TypeBinding actualReceiverType, boolean isImplicitThisReceiver) { >+ ReferenceBinding constantPoolDeclaringClass = codegenBinding.declaringClass; >+ // if the binding declaring class is not visible, need special action >+ // for runtime compatibility on 1.2 VMs : change the declaring class of the binding >+ // NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type >+ // and not from Object or implicit static field access. >+ if (constantPoolDeclaringClass != actualReceiverType.erasure() >+ && !actualReceiverType.isArrayType() >+ && constantPoolDeclaringClass != null // array.length >+ && codegenBinding.constant() == Constant.NotAConstant) { >+ CompilerOptions options = currentScope.compilerOptions(); >+ if ((options.targetJDK >= ClassFileConstants.JDK1_2 >+ && (options.complianceLevel >= ClassFileConstants.JDK1_4 || !(isImplicitThisReceiver && codegenBinding.isStatic())) >+ && constantPoolDeclaringClass.id != TypeIds.T_JavaLangObject) // no change for Object fields >+ || !constantPoolDeclaringClass.canBeSeenBy(currentScope)) { >+ >+ return actualReceiverType.erasure(); >+ } >+ } >+ return constantPoolDeclaringClass; > } > >+/** >+ * Returns the type that should be substituted to original binding declaring class as the proper receiver type >+ * @param currentScope >+ * @param codegenBinding >+ * @param actualReceiverType >+ * @param isImplicitThisReceiver >+ * @param hasGenericCast >+ * @return the receiver type to use in constant pool >+ */ >+public static TypeBinding getConstantPoolDeclaringClass(BlockScope currentScope, MethodBinding codegenBinding, TypeBinding actualReceiverType, boolean isImplicitThisReceiver, boolean hasGenericCast) { >+ TypeBinding constantPoolDeclaringClass = codegenBinding.declaringClass; >+ // Post 1.4.0 target, array clone() invocations are qualified with array type >+ // This is handled in array type #clone method binding resolution (see Scope and UpdatedMethodBinding) >+ if (codegenBinding == currentScope.environment().arrayClone) { >+ CompilerOptions options = currentScope.compilerOptions(); >+ if (options.sourceLevel > ClassFileConstants.JDK1_4 ) { >+ constantPoolDeclaringClass = actualReceiverType.erasure(); >+ } >+ } else { >+ // if the binding declaring class is not visible, need special action >+ // for runtime compatibility on 1.2 VMs : change the declaring class of the binding >+ // NOTE: from target 1.2 on, method's declaring class is touched if any different from receiver type >+ // and not from Object or implicit static method call. >+ if (constantPoolDeclaringClass != actualReceiverType.erasure() && !hasGenericCast && !actualReceiverType.isArrayType()) { >+ CompilerOptions options = currentScope.compilerOptions(); >+ if ((options.targetJDK >= ClassFileConstants.JDK1_2 >+ && (options.complianceLevel >= ClassFileConstants.JDK1_4 || !(isImplicitThisReceiver && codegenBinding.isStatic())) >+ && codegenBinding.declaringClass.id != TypeIds.T_JavaLangObject) // no change for Object methods >+ || !codegenBinding.declaringClass.canBeSeenBy(currentScope)) { >+ constantPoolDeclaringClass = actualReceiverType.erasure(); >+ } >+ } >+ } >+ return constantPoolDeclaringClass; >+} > protected int getPosition() { > return this.position; > } > >-public void getstatic(FieldBinding fieldBinding) { >- int returnTypeSize = 1; >- if ((fieldBinding.type.id == TypeIds.T_double) || (fieldBinding.type.id == TypeIds.T_long)) { >- returnTypeSize = 2; >- } >- generateFieldAccess( >- Opcodes.OPC_getstatic, >- returnTypeSize, >- fieldBinding.declaringClass, >- fieldBinding.name, >- fieldBinding.type); >-} >- > public void getTYPE(int baseTypeID) { > this.countLabels = 0; > switch (baseTypeID) { > case TypeIds.T_byte : > // getstatic: java.lang.Byte.TYPE >- generateFieldAccess( >+ fieldAccess( > Opcodes.OPC_getstatic, >- 1, >+ 1, // return type size > ConstantPool.JavaLangByteConstantPoolName, > ConstantPool.TYPE, > ConstantPool.JavaLangClassSignature); > break; > case TypeIds.T_short : > // getstatic: java.lang.Short.TYPE >- generateFieldAccess( >+ fieldAccess( > Opcodes.OPC_getstatic, >- 1, >+ 1, // return type size > ConstantPool.JavaLangShortConstantPoolName, > ConstantPool.TYPE, > ConstantPool.JavaLangClassSignature); > break; > case TypeIds.T_char : > // getstatic: java.lang.Character.TYPE >- generateFieldAccess( >+ fieldAccess( > Opcodes.OPC_getstatic, >- 1, >+ 1, // return type size > ConstantPool.JavaLangCharacterConstantPoolName, > ConstantPool.TYPE, > ConstantPool.JavaLangClassSignature); > break; > case TypeIds.T_int : > // getstatic: java.lang.Integer.TYPE >- generateFieldAccess( >+ fieldAccess( > Opcodes.OPC_getstatic, >- 1, >+ 1, // return type size > ConstantPool.JavaLangIntegerConstantPoolName, > ConstantPool.TYPE, > ConstantPool.JavaLangClassSignature); > break; > case TypeIds.T_long : > // getstatic: java.lang.Long.TYPE >- generateFieldAccess( >+ fieldAccess( > Opcodes.OPC_getstatic, >- 1, >+ 1, // return type size > ConstantPool.JavaLangLongConstantPoolName, > ConstantPool.TYPE, > ConstantPool.JavaLangClassSignature); > break; > case TypeIds.T_float : > // getstatic: java.lang.Float.TYPE >- generateFieldAccess( >+ fieldAccess( > Opcodes.OPC_getstatic, >- 1, >+ 1, // return type size > ConstantPool.JavaLangFloatConstantPoolName, > ConstantPool.TYPE, > ConstantPool.JavaLangClassSignature); > break; > case TypeIds.T_double : > // getstatic: java.lang.Double.TYPE >- generateFieldAccess( >+ fieldAccess( > Opcodes.OPC_getstatic, >- 1, >+ 1, // return type size > ConstantPool.JavaLangDoubleConstantPoolName, > ConstantPool.TYPE, > ConstantPool.JavaLangClassSignature); > break; > case TypeIds.T_boolean : > // getstatic: java.lang.Boolean.TYPE >- generateFieldAccess( >+ fieldAccess( > Opcodes.OPC_getstatic, >- 1, >+ 1, // return type size > ConstantPool.JavaLangBooleanConstantPoolName, > ConstantPool.TYPE, > ConstantPool.JavaLangClassSignature); > break; > case TypeIds.T_void : > // getstatic: java.lang.Void.TYPE >- generateFieldAccess( >+ fieldAccess( > Opcodes.OPC_getstatic, >- 1, >+ 1, // return type size > ConstantPool.JavaLangVoidConstantPoolName, > ConstantPool.TYPE, > ConstantPool.JavaLangClassSignature); >@@ -3740,6 +3786,35 @@ > writeUnsignedShort(this.constantPool.literalIndexForType(typeBinding)); > } > >+protected void invoke(byte opcode, int receiverAndArgsSize, int returnTypeSize, char[] declaringClass, char[] selector, char[] signature) { >+ this.countLabels = 0; >+ if (opcode == Opcodes.OPC_invokeinterface) { >+ // invokeinterface >+ if (this.classFileOffset + 4 >= this.bCodeStream.length) { >+ resizeByteArray(); >+ } >+ this.position +=3; >+ this.bCodeStream[this.classFileOffset++] = opcode; >+ writeUnsignedShort(this.constantPool.literalIndexForMethod(declaringClass, selector, signature, true)); >+ this.bCodeStream[this.classFileOffset++] = (byte) receiverAndArgsSize; >+ this.bCodeStream[this.classFileOffset++] = 0; >+ } else { >+ // invokespecial >+ // invokestatic >+ // invokevirtual >+ if (this.classFileOffset + 2 >= this.bCodeStream.length) { >+ resizeByteArray(); >+ } >+ this.position++; >+ this.bCodeStream[this.classFileOffset++] = opcode; >+ writeUnsignedShort(this.constantPool.literalIndexForMethod(declaringClass, selector, signature, false)); >+ } >+ this.stackDepth += returnTypeSize - receiverAndArgsSize; >+ if (this.stackDepth > this.stackMax) { >+ this.stackMax = this.stackDepth; >+ } >+} >+ > public void invoke(byte opcode, MethodBinding methodBinding, TypeBinding declaringClass) { > if (declaringClass == null) declaringClass = methodBinding.declaringClass; > if (declaringClass.isNestedType()) { >@@ -3835,35 +3910,6 @@ > methodBinding.signature(this.classFile)); > } > >-protected void invoke(byte opcode, int receiverAndArgsSize, int returnTypeSize, char[] declaringClass, char[] selector, char[] signature) { >- this.countLabels = 0; >- if (opcode == Opcodes.OPC_invokeinterface) { >- // invokeinterface >- if (this.classFileOffset + 4 >= this.bCodeStream.length) { >- resizeByteArray(); >- } >- this.position +=3; >- this.bCodeStream[this.classFileOffset++] = opcode; >- writeUnsignedShort(this.constantPool.literalIndexForMethod(declaringClass, selector, signature, true)); >- this.bCodeStream[this.classFileOffset++] = (byte) receiverAndArgsSize; >- this.bCodeStream[this.classFileOffset++] = 0; >- } else { >- // invokespecial >- // invokestatic >- // invokevirtual >- if (this.classFileOffset + 2 >= this.bCodeStream.length) { >- resizeByteArray(); >- } >- this.position++; >- this.bCodeStream[this.classFileOffset++] = opcode; >- writeUnsignedShort(this.constantPool.literalIndexForMethod(declaringClass, selector, signature, false)); >- } >- this.stackDepth += returnTypeSize - receiverAndArgsSize; >- if (this.stackDepth > this.stackMax) { >- this.stackMax = this.stackDepth; >- } >-} >- > protected void invokeAccessibleObjectSetAccessible() { > // invokevirtual: java.lang.reflect.AccessibleObject.setAccessible(Z)V; > invoke( >@@ -5142,7 +5188,7 @@ > load(localBinding.type, localBinding.resolvedPosition); > } > >-public final void load(TypeBinding typeBinding, int resolvedPosition) { >+protected final void load(TypeBinding typeBinding, int resolvedPosition) { > this.countLabels = 0; > // Using dedicated int bytecode > switch(typeBinding.id) { >@@ -5685,32 +5731,6 @@ > this.stackMax = this.stackDepth; > } > >-public void putfield(FieldBinding fieldBinding) { >- int returnTypeSize = 1; >- if ((fieldBinding.type.id == TypeIds.T_double) || (fieldBinding.type.id == TypeIds.T_long)) { >- returnTypeSize = 2; >- } >- generateFieldAccess( >- Opcodes.OPC_putfield, >- returnTypeSize, >- fieldBinding.declaringClass, >- fieldBinding.name, >- fieldBinding.type); >-} >- >-public void putstatic(FieldBinding fieldBinding) { >- int returnTypeSize = 1; >- if ((fieldBinding.type.id == TypeIds.T_double) || (fieldBinding.type.id == TypeIds.T_long)) { >- returnTypeSize = 2; >- } >- generateFieldAccess( >- Opcodes.OPC_putstatic, >- returnTypeSize, >- fieldBinding.declaringClass, >- fieldBinding.name, >- fieldBinding.type); >-} >- > public void record(LocalVariableBinding local) { > if ((this.generateAttributes & (ClassFileConstants.ATTR_VARS > | ClassFileConstants.ATTR_STACK_MAP_TABLE >Index: compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java,v >retrieving revision 1.25 >diff -u -r1.25 StackMapFrameCodeStream.java >--- compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java 8 Jul 2008 02:01:42 -0000 1.25 >+++ compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java 24 Sep 2008 12:36:52 -0000 >@@ -273,7 +273,7 @@ > // use in CLDC mode > BranchLabel endLabel = new BranchLabel(this); > if (syntheticFieldBinding != null) { // non interface case >- getstatic(syntheticFieldBinding); >+ fieldAccess0(Opcodes.OPC_getstatic, syntheticFieldBinding, null /* default declaringClass */); > dup(); > ifnonnull(endLabel); > pop(); >@@ -316,7 +316,7 @@ > > if (syntheticFieldBinding != null) { // non interface case > dup(); >- putstatic(syntheticFieldBinding); >+ fieldAccess0(Opcodes.OPC_putstatic, syntheticFieldBinding, null /* default declaringClass */); > } > int fromPC = this.position; > goto_(endLabel); >Index: eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java,v >retrieving revision 1.43 >diff -u -r1.43 CodeSnippetFieldReference.java >--- eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java 27 Jun 2008 16:04:07 -0000 1.43 >+++ eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java 24 Sep 2008 12:36:52 -0000 >@@ -15,19 +15,16 @@ > import org.eclipse.jdt.internal.compiler.ast.Expression; > import org.eclipse.jdt.internal.compiler.ast.FieldReference; > import org.eclipse.jdt.internal.compiler.ast.IntLiteral; >-import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; > import org.eclipse.jdt.internal.compiler.codegen.CodeStream; >+import org.eclipse.jdt.internal.compiler.codegen.Opcodes; > import org.eclipse.jdt.internal.compiler.flow.FlowInfo; >-import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; > import org.eclipse.jdt.internal.compiler.impl.Constant; > import org.eclipse.jdt.internal.compiler.lookup.BlockScope; > import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; >-import org.eclipse.jdt.internal.compiler.lookup.ParameterizedFieldBinding; > import org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding; > import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons; >-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; > import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; >-import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding; >+import org.eclipse.jdt.internal.compiler.lookup.TypeIds; > > public class CodeSnippetFieldReference extends FieldReference implements ProblemReasons, EvaluationConstants { > >@@ -43,26 +40,30 @@ > this.evaluationContext = evaluationContext; > } > public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) { >- >- if (this.codegenBinding.canBeSeenBy(this.receiverType, this, currentScope)) { >- this.receiver.generateCode(currentScope, codeStream, !this.codegenBinding.isStatic()); >+ FieldBinding codegenBinding = this.binding.original(); >+ if (codegenBinding.canBeSeenBy(this.actualReceiverType, this, currentScope)) { >+ this.receiver.generateCode(currentScope, codeStream, !codegenBinding.isStatic()); > assignment.expression.generateCode(currentScope, codeStream, true); >- fieldStore(codeStream, this.codegenBinding, null, valueRequired); >+ fieldStore(codeStream, codegenBinding, null, valueRequired); > } else { >- codeStream.generateEmulationForField(this.codegenBinding); >- this.receiver.generateCode(currentScope, codeStream, !this.codegenBinding.isStatic()); >- if (this.codegenBinding.isStatic()) { // need a receiver? >+ codeStream.generateEmulationForField(codegenBinding); >+ this.receiver.generateCode(currentScope, codeStream, !codegenBinding.isStatic()); >+ if (codegenBinding.isStatic()) { // need a receiver? > codeStream.aconst_null(); > } > assignment.expression.generateCode(currentScope, codeStream, true); > if (valueRequired) { >- if ((this.codegenBinding.type == TypeBinding.LONG) || (this.codegenBinding.type == TypeBinding.DOUBLE)) { >- codeStream.dup2_x2(); >- } else { >- codeStream.dup_x2(); >- } >+ switch (codegenBinding.type.id) { >+ case TypeIds.T_long : >+ case TypeIds.T_double : >+ codeStream.dup2_x2(); >+ break; >+ default : >+ codeStream.dup_x2(); >+ break; >+ } > } >- codeStream.generateEmulatedWriteAccessForField(this.codegenBinding); >+ codeStream.generateEmulatedWriteAccessForField(codegenBinding); > } > if (valueRequired){ > codeStream.generateImplicitConversion(assignment.implicitConversion); >@@ -76,33 +77,35 @@ > * @param valueRequired boolean > */ > public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { >- > int pc = codeStream.position; > if (this.constant != Constant.NotAConstant) { > if (valueRequired) { > codeStream.generateConstant(this.constant, this.implicitConversion); > } > } else { >- boolean isStatic = this.codegenBinding.isStatic(); >+ FieldBinding codegenBinding = this.binding.original(); >+ boolean isStatic = codegenBinding.isStatic(); > this.receiver.generateCode(currentScope, codeStream, !isStatic); > if (valueRequired) { >- Constant fieldConstant = this.codegenBinding.constant(); >+ Constant fieldConstant = codegenBinding.constant(); > if (fieldConstant == Constant.NotAConstant) { >- if (this.codegenBinding.declaringClass == null) { // array length >+ if (codegenBinding.declaringClass == null) { // array length > codeStream.arraylength(); > } else { >- if (this.codegenBinding.canBeSeenBy(this.receiverType, this, currentScope)) { >+ if (codegenBinding.canBeSeenBy(this.actualReceiverType, this, currentScope)) { >+ TypeBinding someReceiverType = this.delegateThis != null ? this.delegateThis.type : this.actualReceiverType; >+ TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenBinding, someReceiverType, this.receiver.isImplicitThis()); > if (isStatic) { >- codeStream.getstatic(this.codegenBinding); >+ codeStream.fieldAccess0(Opcodes.OPC_getstatic , codegenBinding, constantPoolDeclaringClass); > } else { >- codeStream.getfield(this.codegenBinding); >+ codeStream.fieldAccess0(Opcodes.OPC_getfield, codegenBinding, constantPoolDeclaringClass); > } > } else { > if (isStatic) { > // we need a null on the stack to use the reflect emulation > codeStream.aconst_null(); > } >- codeStream.generateEmulatedReadAccessForField(this.codegenBinding); >+ codeStream.generateEmulatedReadAccessForField(codegenBinding); > } > } > codeStream.generateImplicitConversion(this.implicitConversion); >@@ -124,15 +127,17 @@ > } > > public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) { >- > boolean isStatic; >- if (this.codegenBinding.canBeSeenBy(this.receiverType, this, currentScope)) { >- this.receiver.generateCode(currentScope, codeStream, !(isStatic = this.codegenBinding.isStatic())); >+ FieldBinding codegenBinding = this.binding.original(); >+ if (codegenBinding.canBeSeenBy(this.actualReceiverType, this, currentScope)) { >+ this.receiver.generateCode(currentScope, codeStream, !(isStatic = codegenBinding.isStatic())); >+ TypeBinding someReceiverType = this.delegateThis != null ? this.delegateThis.type : this.actualReceiverType; >+ TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenBinding, someReceiverType, this.receiver.isImplicitThis()); > if (isStatic) { >- codeStream.getstatic(this.codegenBinding); >+ codeStream.fieldAccess0(Opcodes.OPC_getstatic, codegenBinding, constantPoolDeclaringClass); > } else { > codeStream.dup(); >- codeStream.getfield(this.codegenBinding); >+ codeStream.fieldAccess0(Opcodes.OPC_getfield, codegenBinding, constantPoolDeclaringClass); > } > int operationTypeID; > switch(operationTypeID = (this.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) { >@@ -155,17 +160,17 @@ > // cast the value back to the array reference type > codeStream.generateImplicitConversion(assignmentImplicitConversion); > } >- fieldStore(codeStream, this.codegenBinding, null, valueRequired); >+ fieldStore(codeStream, codegenBinding, null, valueRequired); > } else { >- this.receiver.generateCode(currentScope, codeStream, !(isStatic = this.codegenBinding.isStatic())); >+ this.receiver.generateCode(currentScope, codeStream, !(isStatic = codegenBinding.isStatic())); > if (isStatic) { > // used to store the value >- codeStream.generateEmulationForField(this.codegenBinding); >+ codeStream.generateEmulationForField(codegenBinding); > codeStream.aconst_null(); > > // used to retrieve the actual value > codeStream.aconst_null(); >- codeStream.generateEmulatedReadAccessForField(this.codegenBinding); >+ codeStream.generateEmulatedReadAccessForField(codegenBinding); > } else { > // used to store the value > codeStream.generateEmulationForField(this.binding); >@@ -173,7 +178,7 @@ > > // used to retrieve the actual value > codeStream.dup(); >- codeStream.generateEmulatedReadAccessForField(this.codegenBinding); >+ codeStream.generateEmulatedReadAccessForField(codegenBinding); > } > int operationTypeID; > if ((operationTypeID = (this.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) == T_JavaLangString) { >@@ -195,7 +200,7 @@ > // current stack is: > // field receiver value > if (valueRequired) { >- if ((this.codegenBinding.type == TypeBinding.LONG) || (this.codegenBinding.type == TypeBinding.DOUBLE)) { >+ if ((codegenBinding.type == TypeBinding.LONG) || (codegenBinding.type == TypeBinding.DOUBLE)) { > codeStream.dup2_x2(); > } else { > codeStream.dup_x2(); >@@ -203,61 +208,69 @@ > } > // current stack is: > // value field receiver value >- codeStream.generateEmulatedWriteAccessForField(this.codegenBinding); >+ codeStream.generateEmulatedWriteAccessForField(codegenBinding); > } > } > public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) { > boolean isStatic; >- if (this.codegenBinding.canBeSeenBy(this.receiverType, this, currentScope)) { >+ FieldBinding codegenBinding = this.binding.original(); >+ if (codegenBinding.canBeSeenBy(this.actualReceiverType, this, currentScope)) { > super.generatePostIncrement(currentScope, codeStream, postIncrement, valueRequired); > } else { >- this.receiver.generateCode(currentScope, codeStream, !(isStatic = this.codegenBinding.isStatic())); >+ this.receiver.generateCode(currentScope, codeStream, !(isStatic = codegenBinding.isStatic())); > if (isStatic) { > codeStream.aconst_null(); > } > // the actual stack is: receiver > codeStream.dup(); > // the actual stack is: receiver receiver >- codeStream.generateEmulatedReadAccessForField(this.codegenBinding); >+ codeStream.generateEmulatedReadAccessForField(codegenBinding); > // the actual stack is: receiver value > // receiver value > // value receiver value dup_x1 or dup2_x1 if value required >- // value value receiver value dup_x1 or dup2_x1 >- // value value receiver pop or pop2 >+ // value value receiver value dup_x1 or dup2_x1 >+ // value value receiver pop or pop2 > // value value receiver field generateEmulationForField >- // value value field receiver swap >- // value field receiver value field receiver dup2_x1 or dup2_x2 >- // value field receiver value pop2 >- // value field receiver newvalue generate constant + op >- // value store >- if (valueRequired) { >- if ((this.codegenBinding.type == TypeBinding.LONG) || (this.codegenBinding.type == TypeBinding.DOUBLE)) { >+ // value value field receiver swap >+ // value field receiver value field receiver dup2_x1 or dup2_x2 >+ // value field receiver value pop2 >+ // value field receiver newvalue generate constant + op >+ // value store >+ int typeID; >+ switch (typeID = codegenBinding.type.id) { >+ case TypeIds.T_long : >+ case TypeIds.T_double : >+ if (valueRequired) { >+ codeStream.dup2_x1(); >+ } > codeStream.dup2_x1(); >- } else { >+ codeStream.pop2(); >+ break; >+ default : >+ if (valueRequired) { >+ codeStream.dup_x1(); >+ } > codeStream.dup_x1(); >- } >- } >- if ((this.codegenBinding.type == TypeBinding.LONG) || (this.codegenBinding.type == TypeBinding.DOUBLE)) { >- codeStream.dup2_x1(); >- codeStream.pop2(); >- } else { >- codeStream.dup_x1(); >- codeStream.pop(); >+ codeStream.pop(); >+ break; > } >- codeStream.generateEmulationForField(this.codegenBinding); >+ codeStream.generateEmulationForField(codegenBinding); > codeStream.swap(); >- >- if ((this.codegenBinding.type == TypeBinding.LONG) || (this.codegenBinding.type == TypeBinding.DOUBLE)) { >- codeStream.dup2_x2(); >- } else { >- codeStream.dup2_x1(); >+ switch (typeID) { >+ case TypeIds.T_long : >+ case TypeIds.T_double : >+ codeStream.dup2_x2(); >+ break; >+ default : >+ codeStream.dup2_x1(); >+ break; > } > codeStream.pop2(); > > codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion); >- codeStream.sendOperator(postIncrement.operator, this.codegenBinding.type.id); >+ codeStream.sendOperator(postIncrement.operator, codegenBinding.type.id); > codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion); >- codeStream.generateEmulatedWriteAccessForField(this.codegenBinding); >+ codeStream.generateEmulatedWriteAccessForField(codegenBinding); > } > } > /* >@@ -267,43 +280,6 @@ > // The private access will be managed through the code generation > > if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return; >- >- // if field from parameterized type got found, use the original field at codegen time >- if (this.binding instanceof ParameterizedFieldBinding) { >- ParameterizedFieldBinding parameterizedField = (ParameterizedFieldBinding) this.binding; >- this.codegenBinding = parameterizedField.originalField; >- // extra cast needed if field type was type variable >- if (this.codegenBinding.type.isTypeVariable()) { >- TypeVariableBinding variableReturnType = (TypeVariableBinding) this.codegenBinding.type; >- if (variableReturnType.firstBound != parameterizedField.type) { // no need for extra cast if same as first bound anyway >- this.genericCast = parameterizedField.type.erasure(); >- } >- } >- } else { >- this.codegenBinding = this.binding; >- } >- >- // if the binding declaring class is not visible, need special action >- // for runtime compatibility on 1.2 VMs : change the declaring class of the binding >- // NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type >- TypeBinding someReceiverType = this.delegateThis != null ? this.delegateThis.type : this.receiverType; >- if (this.binding.declaringClass != someReceiverType >- && !someReceiverType.isArrayType() >- && this.binding.declaringClass != null // array.length >- && this.binding.constant() == Constant.NotAConstant) { >- >- CompilerOptions options = currentScope.compilerOptions(); >- if ((options.targetJDK >= ClassFileConstants.JDK1_2 >- && (options.complianceLevel >= ClassFileConstants.JDK1_4 || !this.receiver.isImplicitThis() || !this.codegenBinding.isStatic()) >- && this.binding.declaringClass.id != T_JavaLangObject) // no change for Object fields >- || !this.binding.declaringClass.canBeSeenBy(currentScope)) { >- >- this.codegenBinding = >- currentScope.enclosingSourceType().getUpdatedFieldBinding( >- this.codegenBinding, >- (ReferenceBinding) someReceiverType.erasure()); >- } >- } > } > public TypeBinding resolveType(BlockScope scope) { > // Answer the signature type of the field. >@@ -311,13 +287,13 @@ > // and initialized with a (compile time) constant > > // regular receiver reference >- this.receiverType = this.receiver.resolveType(scope); >- if (this.receiverType == null){ >+ this.actualReceiverType = this.receiver.resolveType(scope); >+ if (this.actualReceiverType == null){ > this.constant = Constant.NotAConstant; > return null; > } > // the case receiverType.isArrayType and token = 'length' is handled by the scope API >- this.codegenBinding = this.binding = scope.getField(this.receiverType, this.token, this); >+ this.binding = scope.getField(this.actualReceiverType, this.token, this); > FieldBinding firstAttempt = this.binding; > boolean isNotVisible = false; > if (!this.binding.isValidBinding()) { >@@ -328,25 +304,25 @@ > this.delegateThis = scope.getField(scope.enclosingSourceType(), DELEGATE_THIS, this); > if (this.delegateThis == null){ // if not found then internal error, field should have been found > this.constant = Constant.NotAConstant; >- scope.problemReporter().invalidField(this, this.receiverType); >+ scope.problemReporter().invalidField(this, this.actualReceiverType); > return null; > } > } else { > this.constant = Constant.NotAConstant; >- scope.problemReporter().invalidField(this, this.receiverType); >+ scope.problemReporter().invalidField(this, this.actualReceiverType); > return null; > } > CodeSnippetScope localScope = new CodeSnippetScope(scope); >- this.codegenBinding = this.binding = localScope.getFieldForCodeSnippet(this.delegateThis.type, this.token, this); >+ this.binding = localScope.getFieldForCodeSnippet(this.delegateThis.type, this.token, this); > } > } > > if (!this.binding.isValidBinding()) { > this.constant = Constant.NotAConstant; > if (isNotVisible) { >- this.codegenBinding = this.binding = firstAttempt; >+ this.binding = firstAttempt; > } >- scope.problemReporter().invalidField(this, this.receiverType); >+ scope.problemReporter().invalidField(this, this.actualReceiverType); > return null; > } > >Index: eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java,v >retrieving revision 1.55 >diff -u -r1.55 CodeSnippetSingleNameReference.java >--- eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java 12 Sep 2008 13:28:54 -0000 1.55 >+++ eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java 24 Sep 2008 12:36:52 -0000 >@@ -16,13 +16,27 @@ > import org.eclipse.jdt.internal.compiler.ast.Expression; > import org.eclipse.jdt.internal.compiler.ast.IntLiteral; > import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; >-import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; > import org.eclipse.jdt.internal.compiler.codegen.CodeStream; >+import org.eclipse.jdt.internal.compiler.codegen.Opcodes; > import org.eclipse.jdt.internal.compiler.flow.FlowContext; > import org.eclipse.jdt.internal.compiler.flow.FlowInfo; >-import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; > import org.eclipse.jdt.internal.compiler.impl.Constant; >-import org.eclipse.jdt.internal.compiler.lookup.*; >+import org.eclipse.jdt.internal.compiler.lookup.Binding; >+import org.eclipse.jdt.internal.compiler.lookup.BlockScope; >+import org.eclipse.jdt.internal.compiler.lookup.ClassScope; >+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; >+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding; >+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; >+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedFieldBinding; >+import org.eclipse.jdt.internal.compiler.lookup.ProblemBinding; >+import org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding; >+import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons; >+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; >+import org.eclipse.jdt.internal.compiler.lookup.Scope; >+import org.eclipse.jdt.internal.compiler.lookup.TagBits; >+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; >+import org.eclipse.jdt.internal.compiler.lookup.TypeIds; >+import org.eclipse.jdt.internal.compiler.lookup.VariableBinding; > > /** > * A single name reference inside a code snippet can denote a field of a remote >@@ -108,11 +122,11 @@ > return; > } > if ((operation.right instanceof SingleNameReference) >- && ((operator == PLUS) || (operator == MULTIPLY)) // only commutative operations >- && ((variableReference = (SingleNameReference) operation.right).binding == this.binding) >- && (operation.left.constant != Constant.NotAConstant) // exclude non constant expressions, since could have side-effect >- && (((operation.left.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) != T_JavaLangString) // exclude string concatenation which would occur backwards >- && (((operation.right.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) != T_JavaLangString)) { // exclude string concatenation which would occur backwards >+ && ((operator == PLUS) || (operator == MULTIPLY)) // only commutative operations >+ && ((variableReference = (SingleNameReference) operation.right).binding == this.binding) >+ && (operation.left.constant != Constant.NotAConstant) // exclude non constant expressions, since could have side-effect >+ && (((operation.left.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) != T_JavaLangString) // exclude string concatenation which would occur backwards >+ && (((operation.right.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) != T_JavaLangString)) { // exclude string concatenation which would occur backwards > // i = value + i, then use the variable on the right hand side, since it has the correct implicit conversion > variableReference.generateCompoundAssignment(currentScope, codeStream, this.syntheticAccessors == null ? null : this.syntheticAccessors[WRITE], operation.left, operator, operation.implicitConversion, valueRequired); > if (valueRequired) { >@@ -123,9 +137,9 @@ > } > switch (this.bits & RestrictiveFlagMASK) { > case Binding.FIELD : // assigning to a field >- FieldBinding fieldBinding = (FieldBinding) this.codegenBinding; >- if (fieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) { >- if (!fieldBinding.isStatic()) { // need a receiver? >+ FieldBinding codegenField = ((FieldBinding) this.binding).original(); >+ if (codegenField.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) { >+ if (!codegenField.isStatic()) { // need a receiver? > if ((this.bits & DepthMASK) != 0) { > ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((this.bits & DepthMASK) >> DepthSHIFT); > Object[] emulationPath = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/); >@@ -135,13 +149,13 @@ > } > } > assignment.expression.generateCode(currentScope, codeStream, true); >- fieldStore(codeStream, fieldBinding, null, valueRequired); >+ fieldStore(codeStream, codegenField, null, valueRequired); > if (valueRequired) { > codeStream.generateImplicitConversion(assignment.implicitConversion); > } > } else { >- codeStream.generateEmulationForField(fieldBinding); >- if (!fieldBinding.isStatic()) { // need a receiver? >+ codeStream.generateEmulationForField(codegenField); >+ if (!codegenField.isStatic()) { // need a receiver? > if ((this.bits & DepthMASK) != 0) { > // internal error, per construction we should have found it > // not yet supported >@@ -154,20 +168,20 @@ > } > assignment.expression.generateCode(currentScope, codeStream, true); > if (valueRequired) { >- if ((fieldBinding.type == TypeBinding.LONG) || (fieldBinding.type == TypeBinding.DOUBLE)) { >+ if ((codegenField.type == TypeBinding.LONG) || (codegenField.type == TypeBinding.DOUBLE)) { > codeStream.dup2_x2(); > } else { > codeStream.dup_x2(); > } > } >- codeStream.generateEmulatedWriteAccessForField(fieldBinding); >+ codeStream.generateEmulatedWriteAccessForField(codegenField); > if (valueRequired) { > codeStream.generateImplicitConversion(assignment.implicitConversion); > } > } > return; > case Binding.LOCAL : // assigning to a local variable >- LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding; >+ LocalVariableBinding localBinding = (LocalVariableBinding) this.binding; > if (localBinding.resolvedPosition != -1) { > assignment.expression.generateCode(currentScope, codeStream, true); > } else { >@@ -214,13 +228,15 @@ > case Binding.FIELD : // reading a field > if (!valueRequired) > break; >- FieldBinding fieldBinding = (FieldBinding) this.codegenBinding; >- Constant fieldConstant = fieldBinding.constant(); >+ FieldBinding codegenField = ((FieldBinding) this.binding).original(); >+ Constant fieldConstant = codegenField.constant(); > if (fieldConstant == Constant.NotAConstant) { // directly use inlined value for constant fields >- if (fieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) { >- // directly use inlined value for constant fields >- boolean isStatic; >- if (!(isStatic = fieldBinding.isStatic())) { >+ if (codegenField.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) { >+ TypeBinding someReceiverType = this.delegateThis != null ? this.delegateThis.type : this.actualReceiverType; >+ TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenField, someReceiverType, true /* implicit this */); >+ if (codegenField.isStatic()) { >+ codeStream.fieldAccess0(Opcodes.OPC_getstatic, codegenField, constantPoolDeclaringClass); >+ } else { > if ((this.bits & DepthMASK) != 0) { > ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((this.bits & DepthMASK) >> DepthSHIFT); > Object[] emulationPath = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/); >@@ -228,16 +244,11 @@ > } else { > generateReceiver(codeStream); > } >- } >- // managing private access >- if (isStatic) { >- codeStream.getstatic(fieldBinding); >- } else { >- codeStream.getfield(fieldBinding); >+ codeStream.fieldAccess0(Opcodes.OPC_getfield, codegenField, constantPoolDeclaringClass); > } > } else { > // managing private access >- if (!fieldBinding.isStatic()) { >+ if (!codegenField.isStatic()) { > if ((this.bits & DepthMASK) != 0) { > // internal error, per construction we should have found it > // not yet supported >@@ -248,7 +259,7 @@ > } else { > codeStream.aconst_null(); > } >- codeStream.generateEmulatedReadAccessForField(fieldBinding); >+ codeStream.generateEmulatedReadAccessForField(codegenField); > } > if (this.genericCast != null) codeStream.checkcast(this.genericCast); > codeStream.generateImplicitConversion(this.implicitConversion); >@@ -257,7 +268,7 @@ > } > break; > case Binding.LOCAL : // reading a local >- LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding; >+ LocalVariableBinding localBinding = (LocalVariableBinding) this.binding; > if (!valueRequired) > break; > // outer local? >@@ -282,21 +293,23 @@ > public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, MethodBinding writeAccessor, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) { > switch (this.bits & RestrictiveFlagMASK) { > case Binding.FIELD : // assigning to a field >- FieldBinding fieldBinding = (FieldBinding) this.codegenBinding; >- if (fieldBinding.isStatic()) { >- if (fieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) { >- codeStream.getstatic(fieldBinding); >+ FieldBinding codegenField = ((FieldBinding) this.binding).original(); >+ if (codegenField.isStatic()) { >+ if (codegenField.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) { >+ TypeBinding someReceiverType = this.delegateThis != null ? this.delegateThis.type : this.actualReceiverType; >+ TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenField, someReceiverType, true /* implicit this */); >+ codeStream.fieldAccess0(Opcodes.OPC_getstatic, codegenField, constantPoolDeclaringClass); > } else { > // used to store the value >- codeStream.generateEmulationForField(fieldBinding); >+ codeStream.generateEmulationForField(codegenField); > codeStream.aconst_null(); > > // used to retrieve the actual value > codeStream.aconst_null(); >- codeStream.generateEmulatedReadAccessForField(fieldBinding); >+ codeStream.generateEmulatedReadAccessForField(codegenField); > } > } else { >- if (fieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) { >+ if (codegenField.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) { > if ((this.bits & DepthMASK) != 0) { > ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((this.bits & DepthMASK) >> DepthSHIFT); > Object[] emulationPath = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/); >@@ -305,7 +318,9 @@ > generateReceiver(codeStream); > } > codeStream.dup(); >- codeStream.getfield(fieldBinding); >+ TypeBinding someReceiverType = this.delegateThis != null ? this.delegateThis.type : this.actualReceiverType; >+ TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenField, someReceiverType, true /* implicit this */); >+ codeStream.fieldAccess0(Opcodes.OPC_getfield, codegenField, constantPoolDeclaringClass); > } else { > if ((this.bits & DepthMASK) != 0) { > // internal error, per construction we should have found it >@@ -313,17 +328,17 @@ > currentScope.problemReporter().needImplementation(this); > } > // used to store the value >- codeStream.generateEmulationForField(fieldBinding); >+ codeStream.generateEmulationForField(codegenField); > generateReceiver(codeStream); > > // used to retrieve the actual value > codeStream.dup(); >- codeStream.generateEmulatedReadAccessForField(fieldBinding); >+ codeStream.generateEmulatedReadAccessForField(codegenField); > } > } > break; > case Binding.LOCAL : // assigning to a local variable (cannot assign to outer local) >- LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding; >+ LocalVariableBinding localBinding = (LocalVariableBinding) this.binding; > // using incr bytecode if possible > switch (localBinding.type.id) { > case T_JavaLangString : >@@ -387,32 +402,40 @@ > // store the result back into the variable > switch (this.bits & RestrictiveFlagMASK) { > case Binding.FIELD : // assigning to a field >- FieldBinding fieldBinding = (FieldBinding) this.codegenBinding; >- if (fieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) { >- fieldStore(codeStream, fieldBinding, writeAccessor, valueRequired); >+ FieldBinding codegenField = ((FieldBinding) this.binding).original(); >+ if (codegenField.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) { >+ fieldStore(codeStream, codegenField, writeAccessor, valueRequired); > } else { > // current stack is: > // field receiver value > if (valueRequired) { >- if ((fieldBinding.type == TypeBinding.LONG) || (fieldBinding.type == TypeBinding.DOUBLE)) { >- codeStream.dup2_x2(); >- } else { >- codeStream.dup_x2(); >- } >+ switch (codegenField.type.id) { >+ case TypeIds.T_long : >+ case TypeIds.T_double : >+ codeStream.dup2_x2(); >+ break; >+ default: >+ codeStream.dup_x2(); >+ break; >+ } > } > // current stack is: > // value field receiver value >- codeStream.generateEmulatedWriteAccessForField(fieldBinding); >+ codeStream.generateEmulatedWriteAccessForField(codegenField); > } > return; > case Binding.LOCAL : // assigning to a local variable >- LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding; >+ LocalVariableBinding localBinding = (LocalVariableBinding) this.binding; > if (valueRequired) { >- if ((localBinding.type == TypeBinding.LONG) || (localBinding.type == TypeBinding.DOUBLE)) { >- codeStream.dup2(); >- } else { >- codeStream.dup(); >- } >+ switch (localBinding.type.id) { >+ case TypeIds.T_long : >+ case TypeIds.T_double : >+ codeStream.dup2(); >+ break; >+ default: >+ codeStream.dup(); >+ break; >+ } > } > codeStream.store(localBinding, false); > } >@@ -420,11 +443,11 @@ > public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) { > switch (this.bits & RestrictiveFlagMASK) { > case Binding.FIELD : // assigning to a field >- FieldBinding fieldBinding = (FieldBinding) this.codegenBinding; >- if (fieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) { >+ FieldBinding codegenField = ((FieldBinding) this.binding).original(); >+ if (codegenField.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) { > super.generatePostIncrement(currentScope, codeStream, postIncrement, valueRequired); > } else { >- if (fieldBinding.isStatic()) { >+ if (codegenField.isStatic()) { > codeStream.aconst_null(); > } else { > if ((this.bits & DepthMASK) != 0) { >@@ -435,40 +458,48 @@ > generateReceiver(codeStream); > } > } >- codeStream.generateEmulatedReadAccessForField(fieldBinding); >+ codeStream.generateEmulatedReadAccessForField(codegenField); > if (valueRequired) { >- if ((fieldBinding.type == TypeBinding.LONG) || (fieldBinding.type == TypeBinding.DOUBLE)) { >- codeStream.dup2(); >- } else { >- codeStream.dup(); >+ switch (codegenField.type.id) { >+ case TypeIds.T_long : >+ case TypeIds.T_double : >+ codeStream.dup2(); >+ break; >+ default: >+ codeStream.dup(); >+ break; > } > } >- codeStream.generateEmulationForField(fieldBinding); >- if ((fieldBinding.type == TypeBinding.LONG) || (fieldBinding.type == TypeBinding.DOUBLE)) { >- codeStream.dup_x2(); >- codeStream.pop(); >- if (fieldBinding.isStatic()) { >- codeStream.aconst_null(); >- } else { >- generateReceiver(codeStream); >- } >- codeStream.dup_x2(); >- codeStream.pop(); >- } else { >- codeStream.dup_x1(); >+ codeStream.generateEmulationForField(codegenField); >+ switch (codegenField.type.id) { >+ case TypeIds.T_long : >+ case TypeIds.T_double : >+ codeStream.dup_x2(); >+ codeStream.pop(); >+ if (codegenField.isStatic()) { >+ codeStream.aconst_null(); >+ } else { >+ generateReceiver(codeStream); >+ } >+ codeStream.dup_x2(); >+ codeStream.pop(); >+ break; >+ default: >+ codeStream.dup_x1(); > codeStream.pop(); >- if (fieldBinding.isStatic()) { >+ if (codegenField.isStatic()) { > codeStream.aconst_null(); > } else { > generateReceiver(codeStream); > } > codeStream.dup_x1(); > codeStream.pop(); >+ break; > } > codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion); >- codeStream.sendOperator(postIncrement.operator, fieldBinding.type.id); >+ codeStream.sendOperator(postIncrement.operator, codegenField.type.id); > codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion); >- codeStream.generateEmulatedWriteAccessForField(fieldBinding); >+ codeStream.generateEmulatedWriteAccessForField(codegenField); > } > return; > case Binding.LOCAL : // assigning to a local variable >@@ -478,7 +509,7 @@ > public void generateReceiver(CodeStream codeStream) { > codeStream.aload_0(); > if (this.delegateThis != null) { >- codeStream.getfield(this.delegateThis); // delegated field access >+ codeStream.fieldAccess0(Opcodes.OPC_getfield, this.delegateThis, null /* default declaringClass */); // delegate field access > } > } > /** >@@ -509,36 +540,12 @@ > // if field from parameterized type got found, use the original field at codegen time > if (this.binding instanceof ParameterizedFieldBinding) { > ParameterizedFieldBinding parameterizedField = (ParameterizedFieldBinding) this.binding; >- this.codegenBinding = parameterizedField.originalField; >- FieldBinding fieldCodegenBinding = (FieldBinding)this.codegenBinding; >+ FieldBinding codegenField = parameterizedField.originalField; > // extra cast needed if field type was type variable >- if ((fieldCodegenBinding.type.tagBits & TagBits.HasTypeVariable) != 0) { >- this.genericCast = fieldCodegenBinding.type.genericCast(currentScope.boxing(parameterizedField.type)); // runtimeType could be base type in boxing case >+ if ((codegenField.type.tagBits & TagBits.HasTypeVariable) != 0) { >+ this.genericCast = codegenField.type.genericCast(currentScope.boxing(parameterizedField.type)); // runtimeType could be base type in boxing case > } > } >- if ((this.bits & Binding.FIELD) != 0) { >- FieldBinding fieldBinding = (FieldBinding) this.binding; >- >- // if the binding declaring class is not visible, need special action >- // for runtime compatibility on 1.2 VMs : change the declaring class of the binding >- // NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type >- // and not from Object or implicit static field access. >- if (fieldBinding.declaringClass != this.delegateThis.type >- && fieldBinding.declaringClass != null // array.length >- && fieldBinding.constant() == Constant.NotAConstant) { >- CompilerOptions options = currentScope.compilerOptions(); >- if ((options.targetJDK >= ClassFileConstants.JDK1_2 >- && (options.complianceLevel >= ClassFileConstants.JDK1_4 || !fieldBinding.isStatic()) >- && fieldBinding.declaringClass.id != T_JavaLangObject) // no change for Object fields >- || !fieldBinding.declaringClass.canBeSeenBy(currentScope)) { >- >- this.codegenBinding = >- currentScope.enclosingSourceType().getUpdatedFieldBinding( >- (FieldBinding)this.codegenBinding, >- (ReferenceBinding)this.delegateThis.type.erasure()); >- } >- } >- } > } > /** > * Normal field binding did not work, try to bind to a field of the delegate receiver. >@@ -551,7 +558,7 @@ > this.delegateThis = scope.getField(scope.enclosingSourceType(), DELEGATE_THIS, this); > if (this.delegateThis != null){ // if not found then internal error, field should have been found > // will not support innerclass emulation inside delegate >- this.codegenBinding = this.binding = scope.getField(this.delegateThis.type, this.token, this); >+ this.binding = scope.getField(this.delegateThis.type, this.token, this); > if (!this.binding.isValidBinding()) { > return super.reportError(scope); > } >@@ -569,13 +576,13 @@ > if (((ProblemFieldBinding) fieldBinding).problemId() == NotVisible) { > // manage the access to a private field of the enclosing type > CodeSnippetScope localScope = new CodeSnippetScope(scope); >- this.codegenBinding = this.binding = localScope.getFieldForCodeSnippet(this.delegateThis.type, this.token, this); >+ this.binding = localScope.getFieldForCodeSnippet(this.delegateThis.type, this.token, this); > return checkFieldAccess(scope); > } else { > return super.reportError(scope); > } > } >- this.codegenBinding = this.binding = fieldBinding; >+ this.binding = fieldBinding; > return checkFieldAccess(scope); > } > } >Index: eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java,v >retrieving revision 1.58 >diff -u -r1.58 CodeSnippetMessageSend.java >--- eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java 17 Sep 2008 11:11:09 -0000 1.58 >+++ eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java 24 Sep 2008 12:36:52 -0000 >@@ -74,7 +74,7 @@ > // generate arguments > generateArguments(this.binding, this.arguments, currentScope, codeStream); > // actual message invocation >- TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope); >+ TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis(), this.receiverGenericCast != null); > if (isStatic) { > codeStream.invoke(Opcodes.OPC_invokestatic, codegenBinding, constantPoolDeclaringClass); > } else if( (this.receiver.isSuper()) || codegenBinding.isPrivate()){ >Index: eval/org/eclipse/jdt/internal/eval/CodeSnippetThisReference.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetThisReference.java,v >retrieving revision 1.34 >diff -u -r1.34 CodeSnippetThisReference.java >--- eval/org/eclipse/jdt/internal/eval/CodeSnippetThisReference.java 27 Jun 2008 16:04:06 -0000 1.34 >+++ eval/org/eclipse/jdt/internal/eval/CodeSnippetThisReference.java 24 Sep 2008 12:36:52 -0000 >@@ -12,6 +12,7 @@ > > import org.eclipse.jdt.internal.compiler.ast.ThisReference; > import org.eclipse.jdt.internal.compiler.codegen.CodeStream; >+import org.eclipse.jdt.internal.compiler.codegen.Opcodes; > import org.eclipse.jdt.internal.compiler.impl.Constant; > import org.eclipse.jdt.internal.compiler.lookup.BlockScope; > import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; >@@ -58,7 +59,7 @@ > int pc = codeStream.position; > if (valueRequired) { > codeStream.aload_0(); >- codeStream.getfield(this.delegateThis); >+ codeStream.fieldAccess0(Opcodes.OPC_getfield, this.delegateThis, null /* default declaringClass */); // delegate field access > } > codeStream.recordPositionsFrom(pc, this.sourceStart); > } >Index: eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java,v >retrieving revision 1.57 >diff -u -r1.57 CodeSnippetQualifiedNameReference.java >--- eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java 17 Sep 2008 09:08:39 -0000 1.57 >+++ eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java 24 Sep 2008 12:36:52 -0000 >@@ -15,25 +15,19 @@ > import org.eclipse.jdt.internal.compiler.ast.Expression; > import org.eclipse.jdt.internal.compiler.ast.IntLiteral; > import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference; >-import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; > import org.eclipse.jdt.internal.compiler.codegen.CodeStream; > import org.eclipse.jdt.internal.compiler.codegen.Opcodes; >-import org.eclipse.jdt.internal.compiler.flow.FlowInfo; >-import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; > import org.eclipse.jdt.internal.compiler.impl.Constant; > import org.eclipse.jdt.internal.compiler.lookup.Binding; > import org.eclipse.jdt.internal.compiler.lookup.BlockScope; > import org.eclipse.jdt.internal.compiler.lookup.ClassScope; > import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; >-import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding; > import org.eclipse.jdt.internal.compiler.lookup.ProblemBinding; > import org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding; > import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons; > import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; > import org.eclipse.jdt.internal.compiler.lookup.Scope; >-import org.eclipse.jdt.internal.compiler.lookup.SyntheticMethodBinding; > import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; >-import org.eclipse.jdt.internal.compiler.lookup.TypeIds; > import org.eclipse.jdt.internal.compiler.lookup.VariableBinding; > > public class CodeSnippetQualifiedNameReference extends QualifiedNameReference implements EvaluationConstants, ProblemReasons { >@@ -53,12 +47,12 @@ > /** > * Check and/or redirect the field access to the delegate receiver if any > */ >-public TypeBinding checkFieldAccess(BlockScope scope) { >- // check for forward references >- this.bits &= ~RestrictiveFlagMASK; // clear bits >- this.bits |= Binding.FIELD; >- return getOtherFieldBindings(scope); >-} >+//public TypeBinding checkFieldAccess(BlockScope scope) { >+// // check for forward references >+// this.bits &= ~RestrictiveFlagMASK; // clear bits >+// this.bits |= Binding.FIELD; >+// return getOtherFieldBindings(scope); >+//} > public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) { > > FieldBinding lastFieldBinding = generateReadSequence(currentScope, codeStream); >@@ -83,334 +77,102 @@ > codeStream.generateImplicitConversion(assignment.implicitConversion); > } > } >-public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { >- int pc = codeStream.position; >- if (this.constant != Constant.NotAConstant) { >- if (valueRequired) { >- codeStream.generateConstant(this.constant, this.implicitConversion); >- } >- } else { >- FieldBinding lastFieldBinding = generateReadSequence(currentScope, codeStream); >- if (valueRequired) { >- if (lastFieldBinding.declaringClass == null) { // array length >- codeStream.arraylength(); >- codeStream.generateImplicitConversion(this.implicitConversion); >- } else { >- Constant fieldConstant = lastFieldBinding.constant(); >- if (fieldConstant != Constant.NotAConstant) { >- if (!lastFieldBinding.isStatic()){ >- codeStream.invokeObjectGetClass(); >- codeStream.pop(); >- } >- // inline the last field constant >- codeStream.generateConstant(fieldConstant, this.implicitConversion); >- } else { >- if (lastFieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) { >- if (lastFieldBinding.isStatic()) { >- codeStream.getstatic(lastFieldBinding); >- } else { >- codeStream.getfield(lastFieldBinding); >- } >- } else { >- codeStream.generateEmulatedReadAccessForField(lastFieldBinding); >- } >- codeStream.generateImplicitConversion(this.implicitConversion); >- } >- } >- } else { >- if (lastFieldBinding != null && !lastFieldBinding.isStatic()){ >- codeStream.invokeObjectGetClass(); // perform null check >- codeStream.pop(); >- } >- } >- } >- codeStream.recordPositionsFrom(pc, this.sourceStart); >-} >-public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) { > >+public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) { > FieldBinding lastFieldBinding = generateReadSequence(currentScope, codeStream); > if (lastFieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) { >- if (lastFieldBinding.isStatic()){ >- codeStream.getstatic(lastFieldBinding); >- } else { >- codeStream.dup(); >- codeStream.getfield(lastFieldBinding); >- } >- // the last field access is a write access >- // perform the actual compound operation >- int operationTypeID; >- switch(operationTypeID = (this.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) { >- case T_JavaLangString : >- case T_JavaLangObject : >- case T_undefined : >- codeStream.generateStringConcatenationAppend(currentScope, null, expression); >- break; >- default : >- // promote the array reference to the suitable operation type >- codeStream.generateImplicitConversion(this.implicitConversion); >- // generate the increment value (will by itself be promoted to the operation value) >- if (expression == IntLiteral.One){ // prefix operation >- codeStream.generateConstant(expression.constant, this.implicitConversion); >- } else { >- expression.generateCode(currentScope, codeStream, true); >- } >- // perform the operation >- codeStream.sendOperator(operator, operationTypeID); >- // cast the value back to the array reference type >- codeStream.generateImplicitConversion(assignmentImplicitConversion); >- } >- // actual assignment >- fieldStore(codeStream, lastFieldBinding, null, valueRequired); >+ super.generateCompoundAssignment(currentScope, codeStream, expression, operator, assignmentImplicitConversion, valueRequired); >+ return; >+ } >+ codeStream.generateEmulationForField(lastFieldBinding); >+ codeStream.swap(); >+ if (lastFieldBinding.isStatic()){ >+ codeStream.aconst_null(); >+ codeStream.swap(); > } else { >- if (lastFieldBinding.isStatic()){ >- codeStream.generateEmulationForField(lastFieldBinding); >- codeStream.swap(); >- codeStream.aconst_null(); >- codeStream.swap(); >- >- codeStream.generateEmulatedReadAccessForField(lastFieldBinding); >- } else { >- codeStream.generateEmulationForField(lastFieldBinding); >- codeStream.swap(); >- codeStream.dup(); >- >- codeStream.generateEmulatedReadAccessForField(lastFieldBinding); >- } >- // the last field access is a write access >- // perform the actual compound operation >- int operationTypeID; >- if ((operationTypeID = (this.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) == T_JavaLangString) { >- codeStream.generateStringConcatenationAppend(currentScope, null, expression); >+ codeStream.dup(); >+ } >+ codeStream.generateEmulatedReadAccessForField(lastFieldBinding); >+ // the last field access is a write access >+ // perform the actual compound operation >+ int operationTypeID; >+ if ((operationTypeID = (this.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) == T_JavaLangString) { >+ codeStream.generateStringConcatenationAppend(currentScope, null, expression); >+ } else { >+ // promote the array reference to the suitable operation type >+ codeStream.generateImplicitConversion(this.implicitConversion); >+ // generate the increment value (will by itself be promoted to the operation value) >+ if (expression == IntLiteral.One){ // prefix operation >+ codeStream.generateConstant(expression.constant, this.implicitConversion); > } else { >- // promote the array reference to the suitable operation type >- codeStream.generateImplicitConversion(this.implicitConversion); >- // generate the increment value (will by itself be promoted to the operation value) >- if (expression == IntLiteral.One){ // prefix operation >- codeStream.generateConstant(expression.constant, this.implicitConversion); >- } else { >- expression.generateCode(currentScope, codeStream, true); >- } >- // perform the operation >- codeStream.sendOperator(operator, operationTypeID); >- // cast the value back to the array reference type >- codeStream.generateImplicitConversion(assignmentImplicitConversion); >+ expression.generateCode(currentScope, codeStream, true); > } >- // actual assignment >+ // perform the operation >+ codeStream.sendOperator(operator, operationTypeID); >+ // cast the value back to the array reference type >+ codeStream.generateImplicitConversion(assignmentImplicitConversion); >+ } >+ // actual assignment > >- // current stack is: >- // field receiver value >- if (valueRequired) { >- if ((lastFieldBinding.type == TypeBinding.LONG) || (lastFieldBinding.type == TypeBinding.DOUBLE)) { >- codeStream.dup2_x2(); >- } else { >- codeStream.dup_x2(); >- } >+ // current stack is: >+ // field receiver value >+ if (valueRequired) { >+ if ((lastFieldBinding.type == TypeBinding.LONG) || (lastFieldBinding.type == TypeBinding.DOUBLE)) { >+ codeStream.dup2_x2(); >+ } else { >+ codeStream.dup_x2(); > } >- // current stack is: >- // value field receiver value >- codeStream.generateEmulatedWriteAccessForField(lastFieldBinding); > } >+ // current stack is: >+ // value field receiver value >+ codeStream.generateEmulatedWriteAccessForField(lastFieldBinding); > } > public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) { >- > FieldBinding lastFieldBinding = generateReadSequence(currentScope, codeStream); > if (lastFieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) { >- SyntheticMethodBinding accessor = >- this.syntheticReadAccessors == null >- ? null >- : this.syntheticReadAccessors[this.syntheticReadAccessors.length - 1]; >- if (lastFieldBinding.isStatic()) { >- if (accessor == null) { >- codeStream.getstatic(lastFieldBinding); >- } else { >- codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */); >- } >+ super.generatePostIncrement(currentScope, codeStream, postIncrement, valueRequired); >+ return; >+ } >+ codeStream.generateEmulatedReadAccessForField(lastFieldBinding); >+ if (valueRequired) { >+ if ((lastFieldBinding.type == TypeBinding.LONG) || (lastFieldBinding.type == TypeBinding.DOUBLE)) { >+ codeStream.dup2(); > } else { > codeStream.dup(); >- if (accessor == null) { >- codeStream.getfield(lastFieldBinding); >- } else { >- codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */); >- } > } >- >- TypeBinding requiredGenericCast = getGenericCast(this.otherCodegenBindings == null ? 0 : this.otherCodegenBindings.length); >- if (requiredGenericCast != null) codeStream.checkcast(requiredGenericCast); >- codeStream.generateImplicitConversion(this.implicitConversion); >- >- // duplicate the old field value >- int operandType = this.implicitConversion & TypeIds.COMPILE_TYPE_MASK; >- if (valueRequired) { >- if (lastFieldBinding.isStatic()) { >- if (operandType == T_long || operandType == T_double) { >- codeStream.dup2(); >- } else { >- codeStream.dup(); >- } >- } else { // Stack: [owner][old field value] ---> [old field value][owner][old field value] >- if (operandType == T_long || operandType == T_double) { >- codeStream.dup2_x1(); >- } else { >- codeStream.dup_x1(); >- } >- } >+ } >+ codeStream.generateEmulationForField(lastFieldBinding); >+ if ((lastFieldBinding.type == TypeBinding.LONG) || (lastFieldBinding.type == TypeBinding.DOUBLE)) { >+ codeStream.dup_x2(); >+ codeStream.pop(); >+ if (lastFieldBinding.isStatic()) { >+ codeStream.aconst_null(); >+ } else { >+ generateReadSequence(currentScope, codeStream); > } >- codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion); >- codeStream.sendOperator(postIncrement.operator, operandType); >- codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion); >- fieldStore(codeStream, lastFieldBinding, this.syntheticWriteAccessor, false); >+ codeStream.dup_x2(); >+ codeStream.pop(); > } else { >- codeStream.generateEmulatedReadAccessForField(lastFieldBinding); >- if (valueRequired) { >- if ((lastFieldBinding.type == TypeBinding.LONG) || (lastFieldBinding.type == TypeBinding.DOUBLE)) { >- codeStream.dup2(); >- } else { >- codeStream.dup(); >- } >- } >- codeStream.generateEmulationForField(lastFieldBinding); >- if ((lastFieldBinding.type == TypeBinding.LONG) || (lastFieldBinding.type == TypeBinding.DOUBLE)) { >- codeStream.dup_x2(); >- codeStream.pop(); >- if (lastFieldBinding.isStatic()) { >- codeStream.aconst_null(); >- } else { >- generateReadSequence(currentScope, codeStream); >- } >- codeStream.dup_x2(); >- codeStream.pop(); >+ codeStream.dup_x1(); >+ codeStream.pop(); >+ if (lastFieldBinding.isStatic()) { >+ codeStream.aconst_null(); > } else { >- codeStream.dup_x1(); >- codeStream.pop(); >- if (lastFieldBinding.isStatic()) { >- codeStream.aconst_null(); >- } else { >- generateReadSequence(currentScope, codeStream); >- } >- codeStream.dup_x1(); >- codeStream.pop(); >- } >- codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion); >- codeStream.sendOperator(postIncrement.operator, lastFieldBinding.type.id); >- codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion); >- codeStream.generateEmulatedWriteAccessForField(lastFieldBinding); >- } >-} >-/* >- * Generate code for all bindings (local and fields) excluding the last one, which may then be generated code >- * for a read or write access. >- */ >-public FieldBinding generateReadSequence(BlockScope currentScope, CodeStream codeStream) { >- >- // determine the rank until which we now we do not need any actual value for the field access >- int otherBindingsCount = this.otherCodegenBindings == null ? 0 : this.otherCodegenBindings.length; >- boolean needValue = otherBindingsCount == 0 || !this.otherBindings[0].isStatic(); >- FieldBinding lastFieldBinding = null; >- TypeBinding lastGenericCast = null; >- >- switch (this.bits & RestrictiveFlagMASK) { >- case Binding.FIELD : >- lastFieldBinding = (FieldBinding) this.codegenBinding; >- lastGenericCast = this.genericCast; >- // if first field is actually constant, we can inline it >- if (lastFieldBinding.constant() != Constant.NotAConstant) { >- break; >- } >- if (needValue) { >- if (lastFieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) { >- if (!lastFieldBinding.isStatic()) { >- if ((this.bits & DepthMASK) != 0) { >- ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((this.bits & DepthMASK) >> DepthSHIFT); >- Object[] emulationPath = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/); >- codeStream.generateOuterAccess(emulationPath, this, targetType, currentScope); >- } else { >- generateReceiver(codeStream); >- } >- } >- } else { >- if (!lastFieldBinding.isStatic()) { >- if ((this.bits & DepthMASK) != 0) { >- // internal error, per construction we should have found it >- // not yet supported >- currentScope.problemReporter().needImplementation(this); >- } else { >- generateReceiver(codeStream); >- } >- } else { >- codeStream.aconst_null(); >- } >- } >- } >- break; >- case Binding.LOCAL : // reading the first local variable >- if (!needValue) break; // no value needed >- LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding; >- // regular local variable read >- Constant localConstant = localBinding.constant(); >- if (localConstant != Constant.NotAConstant) { >- codeStream.generateConstant(localConstant, 0); >- // no implicit conversion >- } else { >- // outer local? >- if ((this.bits & DepthMASK) != 0) { >- // outer local can be reached either through a synthetic arg or a synthetic field >- VariableBinding[] path = currentScope.getEmulationPath(localBinding); >- codeStream.generateOuterAccess(path, this, localBinding, currentScope); >- } else { >- codeStream.load(localBinding); >- } >- } >- } >- >- // all intermediate field accesses are read accesses >- // only the last field binding is a write access >- if (this.otherCodegenBindings != null) { >- for (int i = 0; i < otherBindingsCount; i++) { >- FieldBinding nextField = this.otherCodegenBindings[i]; >- TypeBinding nextGenericCast = this.otherGenericCasts == null ? null : this.otherGenericCasts[i]; >- if (lastFieldBinding != null) { >- needValue = !nextField.isStatic(); >- if (needValue) { >- if (lastFieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) { >- Constant fieldConstant = lastFieldBinding.constant(); >- if (fieldConstant != Constant.NotAConstant) { >- if (lastFieldBinding != this.codegenBinding && !lastFieldBinding.isStatic()) { >- codeStream.invokeObjectGetClass(); // perform null check >- codeStream.pop(); >- } >- codeStream.generateConstant(fieldConstant, 0); >- } else if (lastFieldBinding.isStatic()) { >- codeStream.getstatic(lastFieldBinding); >- } else { >- codeStream.getfield(lastFieldBinding); >- } >- } else { >- codeStream.generateEmulatedReadAccessForField(lastFieldBinding); >- } >- if (lastGenericCast != null) codeStream.checkcast(lastGenericCast); >- } else { >- if (this.codegenBinding != lastFieldBinding && !lastFieldBinding.isStatic()){ >- codeStream.invokeObjectGetClass(); // perform null check >- codeStream.pop(); >- } >- } >- } >- lastFieldBinding = nextField; >- lastGenericCast = nextGenericCast; >- if (lastFieldBinding != null && !lastFieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) { >- if (lastFieldBinding.isStatic()) { >- codeStream.aconst_null(); >- } >- } >+ generateReadSequence(currentScope, codeStream); > } >+ codeStream.dup_x1(); >+ codeStream.pop(); > } >- return lastFieldBinding; >+ codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion); >+ codeStream.sendOperator(postIncrement.operator, lastFieldBinding.type.id); >+ codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion); >+ codeStream.generateEmulatedWriteAccessForField(lastFieldBinding); > } > > public void generateReceiver(CodeStream codeStream) { > codeStream.aload_0(); > if (this.delegateThis != null) { >- codeStream.getfield(this.delegateThis); // delegated field access >+ codeStream.fieldAccess0(Opcodes.OPC_getfield, this.delegateThis, null /* default declaringClass */); // delegated field access > } > } > public TypeBinding getOtherFieldBindings(BlockScope scope) { >@@ -445,7 +207,7 @@ > > // allocation of the fieldBindings array and its respective constants > int otherBindingsLength = length - index; >- this.otherCodegenBindings = this.otherBindings = new FieldBinding[otherBindingsLength]; >+ this.otherBindings = new FieldBinding[otherBindingsLength]; > > // fill the first constant (the one of the binding) > this.constant =((VariableBinding) this.binding).constant(); >@@ -466,6 +228,7 @@ > if (this.delegateThis == null){ // if not found then internal error, field should have been found > return super.reportError(scope); > } >+ this.actualReceiverType = this.delegateThis.type; > } else { > this.constant = Constant.NotAConstant; //don't fill other constants slots... > scope.problemReporter().invalidField(this, field, index, type); >@@ -494,83 +257,22 @@ > } > return (this.otherBindings[otherBindingsLength - 1]).type; > } >- /** >- * Check and/or redirect the field access to the delegate receiver if any >- */ >- public TypeBinding getReceiverType(BlockScope currentScope) { >- Scope scope = currentScope.parent; >- while (true) { >- switch (scope.kind) { >- case Scope.CLASS_SCOPE : >- return ((ClassScope) scope).referenceContext.binding; >- default: >- scope = scope.parent; >- } >- } >- } >- /** >- * index is <0 to denote write access emulation >- */ >- public void manageSyntheticAccessIfNecessary( >- BlockScope currentScope, >- FieldBinding fieldBinding, >- TypeBinding lastReceiverType, >- int index, >- FlowInfo flowInfo) { >- >- if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return; >- >- // if the binding declaring class is not visible, need special action >- // for runtime compatibility on 1.2 VMs : change the declaring class of the binding >- // NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type >- boolean useDelegate; >- if (index < 0) { // write-access? >- useDelegate = fieldBinding == this.binding && this.delegateThis != null; >- } else { >- useDelegate = index == 0 && this.delegateThis != null; >- } > >- if (useDelegate) { >- lastReceiverType = this.delegateThis.type; >- } >- // if the binding declaring class is not visible, need special action >- // for runtime compatibility on 1.2 VMs : change the declaring class of the binding >- // NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type >- // and not from Object or implicit static field access. >- if (fieldBinding.declaringClass != lastReceiverType >- && !lastReceiverType.isArrayType() >- && fieldBinding.declaringClass != null // array.length >- && fieldBinding.constant() == Constant.NotAConstant) { >- CompilerOptions options = currentScope.compilerOptions(); >- if ((options.targetJDK >= ClassFileConstants.JDK1_2 >- && (options.complianceLevel >= ClassFileConstants.JDK1_4 || (index < 0 ? fieldBinding != this.binding : index > 0) || this.indexOfFirstFieldBinding > 1 || !fieldBinding.isStatic()) >- && fieldBinding.declaringClass.id != T_JavaLangObject) // no change for Object fields >- || !(useDelegate >- ? new CodeSnippetScope(currentScope).canBeSeenByForCodeSnippet(fieldBinding.declaringClass, (ReferenceBinding) this.delegateThis.type) >- : fieldBinding.declaringClass.canBeSeenBy(currentScope))) { >- >- if (index < 0) { // write-access? >- if (fieldBinding == this.binding){ >- this.codegenBinding = currentScope.enclosingSourceType().getUpdatedFieldBinding(fieldBinding, (ReferenceBinding)lastReceiverType.erasure()); >- } else { >- if (this.otherCodegenBindings == this.otherBindings){ >- int l = this.otherBindings.length; >- System.arraycopy(this.otherBindings, 0, this.otherCodegenBindings = new FieldBinding[l], 0, l); >- } >- this.otherCodegenBindings[this.otherCodegenBindings.length-1] = currentScope.enclosingSourceType().getUpdatedFieldBinding(fieldBinding, (ReferenceBinding)lastReceiverType.erasure()); >- } >- } if (index == 0){ >- this.codegenBinding = currentScope.enclosingSourceType().getUpdatedFieldBinding(fieldBinding, (ReferenceBinding)lastReceiverType.erasure()); >- } else { >- if (this.otherCodegenBindings == this.otherBindings){ >- int l = this.otherBindings.length; >- System.arraycopy(this.otherBindings, 0, this.otherCodegenBindings = new FieldBinding[l], 0, l); >- } >- this.otherCodegenBindings[index-1] = currentScope.enclosingSourceType().getUpdatedFieldBinding(fieldBinding, (ReferenceBinding)lastReceiverType.erasure()); >- } >+/** >+ * Check and/or redirect the field access to the delegate receiver if any >+ */ >+public TypeBinding getReceiverType(BlockScope currentScope) { >+ Scope scope = currentScope.parent; >+ while (true) { >+ switch (scope.kind) { >+ case Scope.CLASS_SCOPE : >+ return ((ClassScope) scope).referenceContext.binding; >+ default: >+ scope = scope.parent; > } >- } > } >+} >+ > /** > * Normal field binding did not work, try to bind to a field of the delegate receiver. > */ >@@ -593,7 +295,7 @@ > if (((ProblemFieldBinding) fieldBinding).problemId() == NotVisible) { > // manage the access to a private field of the enclosing type > CodeSnippetScope localScope = new CodeSnippetScope(scope); >- this.codegenBinding = this.binding = localScope.getFieldForCodeSnippet(this.delegateThis.type, this.tokens[0], this); >+ this.binding = localScope.getFieldForCodeSnippet(this.delegateThis.type, this.tokens[0], this); > if (this.binding.isValidBinding()) { > return checkFieldAccess(scope); > } else { >@@ -603,7 +305,7 @@ > return super.reportError(scope); > } > } >- this.codegenBinding = this.binding = fieldBinding; >+ this.binding = fieldBinding; > return checkFieldAccess(scope); > } > >@@ -628,7 +330,7 @@ > // the TC is Flag_Type Flag_LocalField and Flag_TypeLocalField > > CodeSnippetScope localScope = new CodeSnippetScope(scope); >- if ((this.codegenBinding = this.binding = localScope.getBinding(this.tokens, this.bits & RestrictiveFlagMASK, this, (ReferenceBinding) this.delegateThis.type)).isValidBinding()) { >+ if ((this.binding = localScope.getBinding(this.tokens, this.bits & RestrictiveFlagMASK, this, (ReferenceBinding) this.delegateThis.type)).isValidBinding()) { > this.bits &= ~RestrictiveFlagMASK; // clear bits > this.bits |= Binding.FIELD; > return getOtherFieldBindings(scope); >Index: codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberAccess.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberAccess.java,v >retrieving revision 1.26 >diff -u -r1.26 CompletionOnMemberAccess.java >--- codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberAccess.java 27 Jun 2008 16:03:59 -0000 1.26 >+++ codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberAccess.java 24 Sep 2008 12:36:50 -0000 >@@ -53,9 +53,9 @@ > > public TypeBinding resolveType(BlockScope scope) { > >- this.receiverType = this.receiver.resolveType(scope); >+ this.actualReceiverType = this.receiver.resolveType(scope); > >- if ((this.receiverType == null || !this.receiverType.isValidBinding()) && this.receiver instanceof MessageSend) { >+ if ((this.actualReceiverType == null || !this.actualReceiverType.isValidBinding()) && this.receiver instanceof MessageSend) { > MessageSend messageSend = (MessageSend) this.receiver; > if(messageSend.receiver instanceof ThisReference) { > Expression[] arguments = messageSend.arguments; >@@ -73,10 +73,10 @@ > } > } > >- if (this.receiverType == null || this.receiverType.isBaseType() || !this.receiverType.isValidBinding()) >+ if (this.actualReceiverType == null || this.actualReceiverType.isBaseType() || !this.actualReceiverType.isValidBinding()) > throw new CompletionNodeFound(); > else >- throw new CompletionNodeFound(this, this.receiverType, scope); >+ throw new CompletionNodeFound(this, this.actualReceiverType, scope); > // array types are passed along to find the length field > } > } >Index: codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocFieldReference.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocFieldReference.java,v >retrieving revision 1.5 >diff -u -r1.5 CompletionOnJavadocFieldReference.java >--- codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocFieldReference.java 27 Jun 2008 16:03:59 -0000 1.5 >+++ codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocFieldReference.java 24 Sep 2008 12:36:50 -0000 >@@ -93,11 +93,11 @@ > > // Resolve only receiver > if (this.receiver == null) { >- this.receiverType = scope.enclosingSourceType(); >+ this.actualReceiverType = scope.enclosingSourceType(); > } else if (scope.kind == Scope.CLASS_SCOPE) { >- this.receiverType = this.receiver.resolveType((ClassScope) scope); >+ this.actualReceiverType = this.receiver.resolveType((ClassScope) scope); > } else { >- this.receiverType = this.receiver.resolveType((BlockScope)scope); >+ this.actualReceiverType = this.receiver.resolveType((BlockScope)scope); > } > return null; > } >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.376 >diff -u -r1.376 CompletionEngine.java >--- codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java 18 Sep 2008 14:06:39 -0000 1.376 >+++ codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java 24 Sep 2008 12:36:50 -0000 >@@ -1927,8 +1927,8 @@ > long completionPosition = fieldRef.nameSourcePosition; > this.javadocTagPosition = fieldRef.tagSourceStart; > >- if (fieldRef.receiverType != null && fieldRef.receiverType.isValidBinding()) { >- ReferenceBinding receiverType = (ReferenceBinding) fieldRef.receiverType; >+ if (fieldRef.actualReceiverType != null && fieldRef.actualReceiverType.isValidBinding()) { >+ ReferenceBinding receiverType = (ReferenceBinding) fieldRef.actualReceiverType; > int rangeStart = (int) (completionPosition >>> 32); > if (fieldRef.receiver.isThis()) { > if (fieldRef.completeInText()) { >@@ -1984,8 +1984,8 @@ > null, > -1, > -1); >- if (fieldRef.receiverType instanceof ReferenceBinding) { >- ReferenceBinding refBinding = (ReferenceBinding)fieldRef.receiverType; >+ if (fieldRef.actualReceiverType instanceof ReferenceBinding) { >+ ReferenceBinding refBinding = (ReferenceBinding)fieldRef.actualReceiverType; > if (this.completionToken == null > || CharOperation.prefixEquals(this.completionToken, refBinding.sourceName) > || (this.options.camelCaseMatch && CharOperation.camelCaseMatch(this.completionToken, refBinding.sourceName))) {
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 247612
:
113015
|
113351
|
113390
|
113439
|
113465
|
113490
|
113530