Source Code Cross Referenced for QualifiedNameReference.java in  » IDE-Eclipse » jdt » org » eclipse » jdt » internal » compiler » ast » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Eclipse » jdt » org.eclipse.jdt.internal.compiler.ast 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*******************************************************************************
0002:         * Copyright (c) 2000, 2007 IBM Corporation and others.
0003:         * All rights reserved. This program and the accompanying materials
0004:         * are made available under the terms of the Eclipse Public License v1.0
0005:         * which accompanies this distribution, and is available at
0006:         * http://www.eclipse.org/legal/epl-v10.html
0007:         *
0008:         * Contributors:
0009:         *     IBM Corporation - initial API and implementation
0010:         *******************************************************************************/package org.eclipse.jdt.internal.compiler.ast;
0011:
0012:        import org.eclipse.jdt.internal.compiler.ASTVisitor;
0013:        import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
0014:        import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
0015:        import org.eclipse.jdt.internal.compiler.flow.FlowContext;
0016:        import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
0017:        import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
0018:        import org.eclipse.jdt.internal.compiler.impl.Constant;
0019:        import org.eclipse.jdt.internal.compiler.lookup.Binding;
0020:        import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
0021:        import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
0022:        import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
0023:        import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
0024:        import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
0025:        import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
0026:        import org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding;
0027:        import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
0028:        import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
0029:        import org.eclipse.jdt.internal.compiler.lookup.Scope;
0030:        import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
0031:        import org.eclipse.jdt.internal.compiler.lookup.SyntheticMethodBinding;
0032:        import org.eclipse.jdt.internal.compiler.lookup.TagBits;
0033:        import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
0034:        import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
0035:        import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
0036:        import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
0037:
0038:        public class QualifiedNameReference extends NameReference {
0039:
0040:            public char[][] tokens;
0041:            public long[] sourcePositions;
0042:            public FieldBinding[] otherBindings, otherCodegenBindings;
0043:            int[] otherDepths;
0044:            public int indexOfFirstFieldBinding;//points (into tokens) for the first token that corresponds to first FieldBinding
0045:            SyntheticMethodBinding syntheticWriteAccessor;
0046:            SyntheticMethodBinding[] syntheticReadAccessors;
0047:            public TypeBinding genericCast;
0048:            public TypeBinding[] otherGenericCasts;
0049:
0050:            public QualifiedNameReference(char[][] tokens, long[] positions,
0051:                    int sourceStart, int sourceEnd) {
0052:                this .tokens = tokens;
0053:                this .sourcePositions = positions;
0054:                this .sourceStart = sourceStart;
0055:                this .sourceEnd = sourceEnd;
0056:            }
0057:
0058:            public FlowInfo analyseAssignment(BlockScope currentScope,
0059:                    FlowContext flowContext, FlowInfo flowInfo,
0060:                    Assignment assignment, boolean isCompound) {
0061:                // determine the rank until which we now we do not need any actual value for the field access
0062:                int otherBindingsCount = this .otherBindings == null ? 0
0063:                        : this .otherBindings.length;
0064:                boolean needValue = otherBindingsCount == 0
0065:                        || !this .otherBindings[0].isStatic();
0066:                boolean complyTo14 = currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4;
0067:                FieldBinding lastFieldBinding = null;
0068:                switch (this .bits & ASTNode.RestrictiveFlagMASK) {
0069:                case Binding.FIELD: // reading a field
0070:                    lastFieldBinding = (FieldBinding) this .binding;
0071:                    if (needValue || complyTo14) {
0072:                        manageSyntheticAccessIfNecessary(currentScope,
0073:                                lastFieldBinding, this .actualReceiverType, 0,
0074:                                flowInfo);
0075:                    }
0076:                    if (this .indexOfFirstFieldBinding == 1) { // was an implicit reference to the first field binding
0077:                        ReferenceBinding declaringClass = lastFieldBinding.declaringClass;
0078:                        // check if accessing enum static field in initializer					
0079:                        if (declaringClass.isEnum()) {
0080:                            MethodScope methodScope = currentScope
0081:                                    .methodScope();
0082:                            SourceTypeBinding sourceType = methodScope
0083:                                    .enclosingSourceType();
0084:                            if (lastFieldBinding.isStatic()
0085:                                    && (sourceType == declaringClass || sourceType.super class == declaringClass) // enum constant body
0086:                                    && lastFieldBinding.constant() == Constant.NotAConstant
0087:                                    && !methodScope.isStatic
0088:                                    && methodScope
0089:                                            .isInsideInitializerOrConstructor()) {
0090:                                currentScope
0091:                                        .problemReporter()
0092:                                        .enumStaticFieldUsedDuringInitialization(
0093:                                                lastFieldBinding, this );
0094:                            }
0095:                        }
0096:                    }
0097:                    // check if final blank field
0098:                    if (lastFieldBinding.isBlankFinal()
0099:                            && this .otherBindings != null // the last field binding is only assigned
0100:                            && currentScope
0101:                                    .needBlankFinalFieldInitializationCheck(lastFieldBinding)) {
0102:                        if (!flowInfo.isDefinitelyAssigned(lastFieldBinding)) {
0103:                            currentScope.problemReporter()
0104:                                    .uninitializedBlankFinalField(
0105:                                            lastFieldBinding, this );
0106:                        }
0107:                    }
0108:                    break;
0109:                case Binding.LOCAL:
0110:                    // first binding is a local variable
0111:                    LocalVariableBinding localBinding;
0112:                    if (!flowInfo
0113:                            .isDefinitelyAssigned(localBinding = (LocalVariableBinding) this .binding)) {
0114:                        currentScope.problemReporter()
0115:                                .uninitializedLocalVariable(localBinding, this );
0116:                    }
0117:                    if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
0118:                        localBinding.useFlag = LocalVariableBinding.USED;
0119:                    } else if (localBinding.useFlag == LocalVariableBinding.UNUSED) {
0120:                        localBinding.useFlag = LocalVariableBinding.FAKE_USED;
0121:                    }
0122:                    checkNPE(currentScope, flowContext, flowInfo, true);
0123:                }
0124:
0125:                if (needValue) {
0126:                    manageEnclosingInstanceAccessIfNecessary(currentScope,
0127:                            flowInfo);
0128:                    // only for first binding
0129:                }
0130:                // all intermediate field accesses are read accesses
0131:                if (this .otherBindings != null) {
0132:                    for (int i = 0; i < otherBindingsCount - 1; i++) {
0133:                        lastFieldBinding = this .otherBindings[i];
0134:                        needValue = !this .otherBindings[i + 1].isStatic();
0135:                        if (needValue || complyTo14) {
0136:                            manageSyntheticAccessIfNecessary(
0137:                                    currentScope,
0138:                                    lastFieldBinding,
0139:                                    i == 0 ? ((VariableBinding) this .binding).type
0140:                                            : this .otherBindings[i - 1].type,
0141:                                    i + 1, flowInfo);
0142:                        }
0143:                    }
0144:                    lastFieldBinding = this .otherBindings[otherBindingsCount - 1];
0145:                }
0146:
0147:                if (isCompound) {
0148:                    if (otherBindingsCount == 0
0149:                            && lastFieldBinding.isBlankFinal()
0150:                            && currentScope
0151:                                    .needBlankFinalFieldInitializationCheck(lastFieldBinding)
0152:                            && (!flowInfo
0153:                                    .isDefinitelyAssigned(lastFieldBinding))) {
0154:                        currentScope.problemReporter()
0155:                                .uninitializedBlankFinalField(lastFieldBinding,
0156:                                        this );
0157:                    }
0158:                    TypeBinding lastReceiverType;
0159:                    switch (otherBindingsCount) {
0160:                    case 0:
0161:                        lastReceiverType = this .actualReceiverType;
0162:                        break;
0163:                    case 1:
0164:                        lastReceiverType = ((VariableBinding) this .binding).type;
0165:                        break;
0166:                    default:
0167:                        lastReceiverType = this .otherBindings[otherBindingsCount - 2].type;
0168:                        break;
0169:                    }
0170:                    manageSyntheticAccessIfNecessary(currentScope,
0171:                            lastFieldBinding, lastReceiverType,
0172:                            otherBindingsCount, flowInfo);
0173:                }
0174:
0175:                if (assignment.expression != null) {
0176:                    flowInfo = assignment.expression.analyseCode(currentScope,
0177:                            flowContext, flowInfo).unconditionalInits();
0178:                }
0179:
0180:                // the last field access is a write access
0181:                if (lastFieldBinding.isFinal()) {
0182:                    // in a context where it can be assigned?
0183:                    if (otherBindingsCount == 0
0184:                            && this .indexOfFirstFieldBinding == 1
0185:                            && lastFieldBinding.isBlankFinal()
0186:                            && !isCompound
0187:                            && currentScope
0188:                                    .allowBlankFinalFieldAssignment(lastFieldBinding)) {
0189:                        if (flowInfo.isPotentiallyAssigned(lastFieldBinding)) {
0190:                            currentScope.problemReporter()
0191:                                    .duplicateInitializationOfBlankFinalField(
0192:                                            lastFieldBinding, this );
0193:                        } else {
0194:                            flowContext.recordSettingFinal(lastFieldBinding,
0195:                                    this , flowInfo);
0196:                        }
0197:                        flowInfo.markAsDefinitelyAssigned(lastFieldBinding);
0198:                    } else {
0199:                        currentScope.problemReporter()
0200:                                .cannotAssignToFinalField(lastFieldBinding,
0201:                                        this );
0202:                        if (otherBindingsCount == 0
0203:                                && currentScope
0204:                                        .allowBlankFinalFieldAssignment(lastFieldBinding)) { // pretend it got assigned
0205:                            flowInfo.markAsDefinitelyAssigned(lastFieldBinding);
0206:                        }
0207:                    }
0208:                }
0209:                // equivalent to valuesRequired[maxOtherBindings]
0210:                TypeBinding lastReceiverType;
0211:                switch (otherBindingsCount) {
0212:                case 0:
0213:                    lastReceiverType = this .actualReceiverType;
0214:                    break;
0215:                case 1:
0216:                    lastReceiverType = ((VariableBinding) this .binding).type;
0217:                    break;
0218:                default:
0219:                    lastReceiverType = this .otherBindings[otherBindingsCount - 2].type;
0220:                    break;
0221:                }
0222:                manageSyntheticAccessIfNecessary(currentScope,
0223:                        lastFieldBinding, lastReceiverType,
0224:                        -1 /*write-access*/, flowInfo);
0225:
0226:                return flowInfo;
0227:            }
0228:
0229:            public FlowInfo analyseCode(BlockScope currentScope,
0230:                    FlowContext flowContext, FlowInfo flowInfo) {
0231:                return analyseCode(currentScope, flowContext, flowInfo, true);
0232:            }
0233:
0234:            public FlowInfo analyseCode(BlockScope currentScope,
0235:                    FlowContext flowContext, FlowInfo flowInfo,
0236:                    boolean valueRequired) {
0237:                // determine the rank until which we now we do not need any actual value for the field access
0238:                int otherBindingsCount = this .otherBindings == null ? 0
0239:                        : this .otherBindings.length;
0240:
0241:                boolean needValue = otherBindingsCount == 0 ? valueRequired
0242:                        : !this .otherBindings[0].isStatic();
0243:                boolean complyTo14 = currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4;
0244:                switch (this .bits & ASTNode.RestrictiveFlagMASK) {
0245:                case Binding.FIELD: // reading a field
0246:                    if (needValue || complyTo14) {
0247:                        manageSyntheticAccessIfNecessary(currentScope,
0248:                                (FieldBinding) this .binding,
0249:                                this .actualReceiverType, 0, flowInfo);
0250:                    }
0251:                    if (this .indexOfFirstFieldBinding == 1) { // was an implicit reference to the first field binding
0252:                        FieldBinding fieldBinding = (FieldBinding) this .binding;
0253:                        ReferenceBinding declaringClass = fieldBinding.declaringClass;
0254:                        // check if accessing enum static field in initializer					
0255:                        if (declaringClass.isEnum()) {
0256:                            MethodScope methodScope = currentScope
0257:                                    .methodScope();
0258:                            SourceTypeBinding sourceType = methodScope
0259:                                    .enclosingSourceType();
0260:                            if (fieldBinding.isStatic()
0261:                                    && (sourceType == declaringClass || sourceType.super class == declaringClass) // enum constant body
0262:                                    && fieldBinding.constant() == Constant.NotAConstant
0263:                                    && !methodScope.isStatic
0264:                                    && methodScope
0265:                                            .isInsideInitializerOrConstructor()) {
0266:                                currentScope
0267:                                        .problemReporter()
0268:                                        .enumStaticFieldUsedDuringInitialization(
0269:                                                fieldBinding, this );
0270:                            }
0271:                        }
0272:                        // check if reading a final blank field
0273:                        if (fieldBinding.isBlankFinal()
0274:                                && currentScope
0275:                                        .needBlankFinalFieldInitializationCheck(fieldBinding)
0276:                                && !flowInfo.isDefinitelyAssigned(fieldBinding)) {
0277:                            currentScope.problemReporter()
0278:                                    .uninitializedBlankFinalField(fieldBinding,
0279:                                            this );
0280:                        }
0281:                    }
0282:                    break;
0283:                case Binding.LOCAL: // reading a local variable
0284:                    LocalVariableBinding localBinding;
0285:                    if (!flowInfo
0286:                            .isDefinitelyAssigned(localBinding = (LocalVariableBinding) this .binding)) {
0287:                        currentScope.problemReporter()
0288:                                .uninitializedLocalVariable(localBinding, this );
0289:                    }
0290:                    if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
0291:                        localBinding.useFlag = LocalVariableBinding.USED;
0292:                    } else if (localBinding.useFlag == LocalVariableBinding.UNUSED) {
0293:                        localBinding.useFlag = LocalVariableBinding.FAKE_USED;
0294:                    }
0295:                    checkNPE(currentScope, flowContext, flowInfo, true);
0296:                }
0297:                if (needValue) {
0298:                    manageEnclosingInstanceAccessIfNecessary(currentScope,
0299:                            flowInfo);
0300:                    // only for first binding (if value needed only)
0301:                }
0302:                if (this .otherBindings != null) {
0303:                    for (int i = 0; i < otherBindingsCount; i++) {
0304:                        needValue = i < otherBindingsCount - 1 ? !this .otherBindings[i + 1]
0305:                                .isStatic()
0306:                                : valueRequired;
0307:                        if (needValue || complyTo14) {
0308:                            TypeBinding lastReceiverType = getGenericCast(i);
0309:                            if (lastReceiverType == null) {
0310:                                if (i == 0) {
0311:                                    lastReceiverType = ((VariableBinding) this .binding).type;
0312:                                } else {
0313:                                    lastReceiverType = this .otherBindings[i - 1].type;
0314:                                }
0315:                            }
0316:                            manageSyntheticAccessIfNecessary(currentScope,
0317:                                    this .otherBindings[i], lastReceiverType,
0318:                                    i + 1, flowInfo);
0319:                        }
0320:                    }
0321:                }
0322:                return flowInfo;
0323:            }
0324:
0325:            /**
0326:             * Check and/or redirect the field access to the delegate receiver if any
0327:             */
0328:            public TypeBinding checkFieldAccess(BlockScope scope) {
0329:                FieldBinding fieldBinding = (FieldBinding) this .binding;
0330:                MethodScope methodScope = scope.methodScope();
0331:                // check for forward references
0332:                if (this .indexOfFirstFieldBinding == 1
0333:                        && methodScope.enclosingSourceType() == fieldBinding
0334:                                .original().declaringClass
0335:                        && methodScope.lastVisibleFieldID >= 0
0336:                        && fieldBinding.id >= methodScope.lastVisibleFieldID
0337:                        && (!fieldBinding.isStatic() || methodScope.isStatic)) {
0338:                    scope.problemReporter().forwardReference(this , 0,
0339:                            methodScope.enclosingSourceType());
0340:                }
0341:                this .bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits
0342:                this .bits |= Binding.FIELD;
0343:                return getOtherFieldBindings(scope);
0344:            }
0345:
0346:            public void checkNPE(BlockScope scope, FlowContext flowContext,
0347:                    FlowInfo flowInfo, boolean checkString) {
0348:                // cannot override localVariableBinding because this would project o.m onto o when
0349:                // analysing assignments
0350:                if ((this .bits & ASTNode.RestrictiveFlagMASK) == Binding.LOCAL) {
0351:                    LocalVariableBinding local = (LocalVariableBinding) this .binding;
0352:                    if (local != null
0353:                            && (local.type.tagBits & TagBits.IsBaseType) == 0
0354:                            && (checkString || local.type.id != TypeIds.T_JavaLangString)) {
0355:                        if ((this .bits & ASTNode.IsNonNull) == 0) {
0356:                            flowContext.recordUsingNullReference(scope, local,
0357:                                    this , FlowContext.MAY_NULL, flowInfo);
0358:                        }
0359:                        flowInfo.markAsComparedEqualToNonNull(local);
0360:                        // from thereon it is set
0361:                        if (flowContext.initsOnFinally != null) {
0362:                            flowContext.initsOnFinally
0363:                                    .markAsComparedEqualToNonNull(local);
0364:                        }
0365:                    }
0366:                }
0367:            }
0368:
0369:            /**
0370:             * @see org.eclipse.jdt.internal.compiler.ast.Expression#computeConversion(org.eclipse.jdt.internal.compiler.lookup.Scope, org.eclipse.jdt.internal.compiler.lookup.TypeBinding, org.eclipse.jdt.internal.compiler.lookup.TypeBinding)
0371:             */
0372:            public void computeConversion(Scope scope,
0373:                    TypeBinding runtimeTimeType, TypeBinding compileTimeType) {
0374:                if (runtimeTimeType == null || compileTimeType == null)
0375:                    return;
0376:                // set the generic cast after the fact, once the type expectation is fully known (no need for strict cast)
0377:                FieldBinding field = null;
0378:                int length = this .otherBindings == null ? 0
0379:                        : this .otherBindings.length;
0380:                if (length == 0) {
0381:                    if ((this .bits & Binding.FIELD) != 0
0382:                            && this .binding != null
0383:                            && this .binding.isValidBinding()) {
0384:                        field = (FieldBinding) this .binding;
0385:                    }
0386:                } else {
0387:                    field = this .otherBindings[length - 1];
0388:                }
0389:                if (field != null) {
0390:                    FieldBinding originalBinding = field.original();
0391:                    TypeBinding originalType = originalBinding.type;
0392:                    // extra cast needed if method return type has type variable
0393:                    if (originalBinding != field
0394:                            && originalType != field.type
0395:                            && runtimeTimeType.id != TypeIds.T_JavaLangObject
0396:                            && (originalType.tagBits & TagBits.HasTypeVariable) != 0) {
0397:                        TypeBinding targetType = (!compileTimeType.isBaseType() && runtimeTimeType
0398:                                .isBaseType()) ? compileTimeType // unboxing: checkcast before conversion
0399:                                : runtimeTimeType;
0400:                        setGenericCast(length, originalType
0401:                                .genericCast(targetType));
0402:                    }
0403:                }
0404:                super 
0405:                        .computeConversion(scope, runtimeTimeType,
0406:                                compileTimeType);
0407:            }
0408:
0409:            public void generateAssignment(BlockScope currentScope,
0410:                    CodeStream codeStream, Assignment assignment,
0411:                    boolean valueRequired) {
0412:                int pc = codeStream.position;
0413:                FieldBinding lastFieldBinding = generateReadSequence(
0414:                        currentScope, codeStream);
0415:                codeStream.recordPositionsFrom(pc, this .sourceStart);
0416:                assignment.expression.generateCode(currentScope, codeStream,
0417:                        true);
0418:                fieldStore(codeStream, lastFieldBinding,
0419:                        this .syntheticWriteAccessor, valueRequired);
0420:                // equivalent to valuesRequired[maxOtherBindings]
0421:                if (valueRequired) {
0422:                    codeStream
0423:                            .generateImplicitConversion(assignment.implicitConversion);
0424:                }
0425:            }
0426:
0427:            public void generateCode(BlockScope currentScope,
0428:                    CodeStream codeStream, boolean valueRequired) {
0429:                int pc = codeStream.position;
0430:                if (this .constant != Constant.NotAConstant) {
0431:                    if (valueRequired) {
0432:                        codeStream.generateConstant(this .constant,
0433:                                this .implicitConversion);
0434:                    }
0435:                } else {
0436:                    FieldBinding lastFieldBinding = generateReadSequence(
0437:                            currentScope, codeStream);
0438:                    if (lastFieldBinding != null) {
0439:                        boolean isStatic = lastFieldBinding.isStatic();
0440:                        Constant fieldConstant = lastFieldBinding.constant();
0441:                        if (fieldConstant != Constant.NotAConstant) {
0442:                            if (!isStatic) {
0443:                                codeStream.invokeObjectGetClass();
0444:                                codeStream.pop();
0445:                            }
0446:                            if (valueRequired) { // inline the last field constant
0447:                                codeStream.generateConstant(fieldConstant,
0448:                                        this .implicitConversion);
0449:                            }
0450:                        } else {
0451:                            boolean isFirst = lastFieldBinding == this .binding
0452:                                    && (this .indexOfFirstFieldBinding == 1 || lastFieldBinding.declaringClass == currentScope
0453:                                            .enclosingReceiverType())
0454:                                    && this .otherBindings == null; // could be dup: next.next.next
0455:                            TypeBinding requiredGenericCast = getGenericCast(this .otherCodegenBindings == null ? 0
0456:                                    : this .otherCodegenBindings.length);
0457:                            if (valueRequired
0458:                                    || (!isFirst && currentScope
0459:                                            .compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4)
0460:                                    || ((this .implicitConversion & TypeIds.UNBOXING) != 0)
0461:                                    || requiredGenericCast != null) {
0462:                                int lastFieldPc = codeStream.position;
0463:                                if (lastFieldBinding.declaringClass == null) { // array length
0464:                                    codeStream.arraylength();
0465:                                    if (valueRequired) {
0466:                                        codeStream
0467:                                                .generateImplicitConversion(this .implicitConversion);
0468:                                    } else {
0469:                                        // could occur if !valueRequired but compliance >= 1.4
0470:                                        codeStream.pop();
0471:                                    }
0472:                                } else {
0473:                                    SyntheticMethodBinding accessor = this .syntheticReadAccessors == null ? null
0474:                                            : this .syntheticReadAccessors[this .syntheticReadAccessors.length - 1];
0475:                                    if (accessor == null) {
0476:                                        if (isStatic) {
0477:                                            codeStream
0478:                                                    .getstatic(lastFieldBinding);
0479:                                        } else {
0480:                                            codeStream
0481:                                                    .getfield(lastFieldBinding);
0482:                                        }
0483:                                    } else {
0484:                                        codeStream.invokestatic(accessor);
0485:                                    }
0486:                                    if (requiredGenericCast != null)
0487:                                        codeStream
0488:                                                .checkcast(requiredGenericCast);
0489:                                    if (valueRequired) {
0490:                                        codeStream
0491:                                                .generateImplicitConversion(this .implicitConversion);
0492:                                    } else {
0493:                                        boolean isUnboxing = (this .implicitConversion & TypeIds.UNBOXING) != 0;
0494:                                        // conversion only generated if unboxing
0495:                                        if (isUnboxing)
0496:                                            codeStream
0497:                                                    .generateImplicitConversion(this .implicitConversion);
0498:                                        switch (isUnboxing ? postConversionType(currentScope).id
0499:                                                : lastFieldBinding.type.id) {
0500:                                        case T_long:
0501:                                        case T_double:
0502:                                            codeStream.pop2();
0503:                                            break;
0504:                                        default:
0505:                                            codeStream.pop();
0506:                                        }
0507:                                    }
0508:                                }
0509:
0510:                                int fieldPosition = (int) (this .sourcePositions[this .sourcePositions.length - 1] >>> 32);
0511:                                codeStream.recordPositionsFrom(lastFieldPc,
0512:                                        fieldPosition);
0513:                            } else {
0514:                                if (!isStatic) {
0515:                                    codeStream.invokeObjectGetClass(); // perform null check
0516:                                    codeStream.pop();
0517:                                }
0518:                            }
0519:                        }
0520:                    }
0521:                }
0522:                codeStream.recordPositionsFrom(pc, this .sourceStart);
0523:            }
0524:
0525:            public void generateCompoundAssignment(BlockScope currentScope,
0526:                    CodeStream codeStream, Expression expression, int operator,
0527:                    int assignmentImplicitConversion, boolean valueRequired) {
0528:
0529:                FieldBinding lastFieldBinding = generateReadSequence(
0530:                        currentScope, codeStream);
0531:                SyntheticMethodBinding accessor = this .syntheticReadAccessors == null ? null
0532:                        : this .syntheticReadAccessors[this .syntheticReadAccessors.length - 1];
0533:                if (lastFieldBinding.isStatic()) {
0534:                    if (accessor == null) {
0535:                        codeStream.getstatic(lastFieldBinding);
0536:                    } else {
0537:                        codeStream.invokestatic(accessor);
0538:                    }
0539:                } else {
0540:                    codeStream.dup();
0541:                    if (accessor == null) {
0542:                        codeStream.getfield(lastFieldBinding);
0543:                    } else {
0544:                        codeStream.invokestatic(accessor);
0545:                    }
0546:                }
0547:                // the last field access is a write access
0548:                // perform the actual compound operation
0549:                int operationTypeID;
0550:                switch (operationTypeID = (this .implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4) {
0551:                case T_JavaLangString:
0552:                case T_JavaLangObject:
0553:                case T_undefined:
0554:                    codeStream.generateStringConcatenationAppend(currentScope,
0555:                            null, expression);
0556:                    break;
0557:                default:
0558:                    TypeBinding requiredGenericCast = getGenericCast(this .otherCodegenBindings == null ? 0
0559:                            : this .otherCodegenBindings.length);
0560:                    if (requiredGenericCast != null)
0561:                        codeStream.checkcast(requiredGenericCast);
0562:                    // promote the array reference to the suitable operation type
0563:                    codeStream
0564:                            .generateImplicitConversion(this .implicitConversion);
0565:                    // generate the increment value (will by itself  be promoted to the operation value)
0566:                    if (expression == IntLiteral.One) { // prefix operation
0567:                        codeStream.generateConstant(expression.constant,
0568:                                this .implicitConversion);
0569:                    } else {
0570:                        expression.generateCode(currentScope, codeStream, true);
0571:                    }
0572:                    // perform the operation
0573:                    codeStream.sendOperator(operator, operationTypeID);
0574:                    // cast the value back to the array reference type
0575:                    codeStream
0576:                            .generateImplicitConversion(assignmentImplicitConversion);
0577:                }
0578:                // actual assignment
0579:                fieldStore(codeStream, lastFieldBinding,
0580:                        this .syntheticWriteAccessor, valueRequired);
0581:                // equivalent to valuesRequired[maxOtherBindings]
0582:            }
0583:
0584:            public void generatePostIncrement(BlockScope currentScope,
0585:                    CodeStream codeStream, CompoundAssignment postIncrement,
0586:                    boolean valueRequired) {
0587:
0588:                FieldBinding lastFieldBinding = generateReadSequence(
0589:                        currentScope, codeStream);
0590:                SyntheticMethodBinding accessor = this .syntheticReadAccessors == null ? null
0591:                        : this .syntheticReadAccessors[this .syntheticReadAccessors.length - 1];
0592:                if (lastFieldBinding.isStatic()) {
0593:                    if (accessor == null) {
0594:                        codeStream.getstatic(lastFieldBinding);
0595:                    } else {
0596:                        codeStream.invokestatic(accessor);
0597:                    }
0598:                } else {
0599:                    codeStream.dup();
0600:                    if (accessor == null) {
0601:                        codeStream.getfield(lastFieldBinding);
0602:                    } else {
0603:                        codeStream.invokestatic(accessor);
0604:                    }
0605:                }
0606:                // duplicate the old field value
0607:                if (valueRequired) {
0608:                    if (lastFieldBinding.isStatic()) {
0609:                        if ((lastFieldBinding.type == TypeBinding.LONG)
0610:                                || (lastFieldBinding.type == TypeBinding.DOUBLE)) {
0611:                            codeStream.dup2();
0612:                        } else {
0613:                            codeStream.dup();
0614:                        }
0615:                    } else { // Stack:  [owner][old field value]  ---> [old field value][owner][old field value]
0616:                        if ((lastFieldBinding.type == TypeBinding.LONG)
0617:                                || (lastFieldBinding.type == TypeBinding.DOUBLE)) {
0618:                            codeStream.dup2_x1();
0619:                        } else {
0620:                            codeStream.dup_x1();
0621:                        }
0622:                    }
0623:                }
0624:                TypeBinding requiredGenericCast = getGenericCast(this .otherCodegenBindings == null ? 0
0625:                        : this .otherCodegenBindings.length);
0626:                if (requiredGenericCast != null)
0627:                    codeStream.checkcast(requiredGenericCast);
0628:
0629:                codeStream.generateImplicitConversion(this .implicitConversion);
0630:                codeStream.generateConstant(postIncrement.expression.constant,
0631:                        this .implicitConversion);
0632:                codeStream.sendOperator(postIncrement.operator,
0633:                        this .implicitConversion & TypeIds.COMPILE_TYPE_MASK);
0634:                codeStream
0635:                        .generateImplicitConversion(postIncrement.preAssignImplicitConversion);
0636:                fieldStore(codeStream, lastFieldBinding,
0637:                        this .syntheticWriteAccessor, false);
0638:            }
0639:
0640:            /*
0641:             * Generate code for all bindings (local and fields) excluding the last one, which may then be generated code
0642:             * for a read or write access.
0643:             */
0644:            public FieldBinding generateReadSequence(BlockScope currentScope,
0645:                    CodeStream codeStream) {
0646:                // determine the rank until which we now we do not need any actual value for the field access
0647:                int otherBindingsCount = this .otherCodegenBindings == null ? 0
0648:                        : this .otherCodegenBindings.length;
0649:                boolean needValue = otherBindingsCount == 0
0650:                        || !this .otherBindings[0].isStatic();
0651:                FieldBinding lastFieldBinding = null;
0652:                TypeBinding lastGenericCast = null;
0653:                boolean complyTo14 = currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4;
0654:
0655:                switch (this .bits & ASTNode.RestrictiveFlagMASK) {
0656:                case Binding.FIELD:
0657:                    lastFieldBinding = (FieldBinding) this .codegenBinding;
0658:                    lastGenericCast = this .genericCast;
0659:                    // if first field is actually constant, we can inline it
0660:                    if (lastFieldBinding.constant() != Constant.NotAConstant) {
0661:                        break;
0662:                    }
0663:                    if ((needValue && !lastFieldBinding.isStatic())
0664:                            || lastGenericCast != null) {
0665:                        int pc = codeStream.position;
0666:                        if ((this .bits & ASTNode.DepthMASK) != 0) {
0667:                            ReferenceBinding targetType = currentScope
0668:                                    .enclosingSourceType()
0669:                                    .enclosingTypeAt(
0670:                                            (this .bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT);
0671:                            Object[] emulationPath = currentScope
0672:                                    .getEmulationPath(targetType,
0673:                                            true /*only exact match*/, false/*consider enclosing arg*/);
0674:                            codeStream.generateOuterAccess(emulationPath, this ,
0675:                                    targetType, currentScope);
0676:                        } else {
0677:                            generateReceiver(codeStream);
0678:                        }
0679:                        codeStream.recordPositionsFrom(pc, this .sourceStart);
0680:                    }
0681:                    break;
0682:                case Binding.LOCAL: // reading the first local variable
0683:                    if (!needValue)
0684:                        break; // no value needed
0685:                    LocalVariableBinding localBinding = (LocalVariableBinding) this .codegenBinding;
0686:                    // regular local variable read
0687:                    Constant localConstant = localBinding.constant();
0688:                    if (localConstant != Constant.NotAConstant) {
0689:                        codeStream.generateConstant(localConstant, 0);
0690:                        // no implicit conversion
0691:                    } else {
0692:                        // outer local?
0693:                        if ((this .bits & ASTNode.DepthMASK) != 0) {
0694:                            // outer local can be reached either through a synthetic arg or a synthetic field
0695:                            VariableBinding[] path = currentScope
0696:                                    .getEmulationPath(localBinding);
0697:                            codeStream.generateOuterAccess(path, this ,
0698:                                    localBinding, currentScope);
0699:                        } else {
0700:                            codeStream.load(localBinding);
0701:                        }
0702:                    }
0703:                }
0704:
0705:                // all intermediate field accesses are read accesses
0706:                // only the last field binding is a write access
0707:                int positionsLength = this .sourcePositions.length;
0708:                if (this .otherCodegenBindings != null) {
0709:                    for (int i = 0; i < otherBindingsCount; i++) {
0710:                        int pc = codeStream.position;
0711:                        FieldBinding nextField = this .otherCodegenBindings[i];
0712:                        TypeBinding nextGenericCast = this .otherGenericCasts == null ? null
0713:                                : this .otherGenericCasts[i];
0714:                        if (lastFieldBinding != null) {
0715:                            needValue = !nextField.isStatic();
0716:                            Constant fieldConstant = lastFieldBinding
0717:                                    .constant();
0718:                            if (fieldConstant != Constant.NotAConstant) {
0719:                                if (i > 0 && !lastFieldBinding.isStatic()) {
0720:                                    codeStream.invokeObjectGetClass(); // perform null check
0721:                                    codeStream.pop();
0722:                                }
0723:                                if (needValue) {
0724:                                    codeStream.generateConstant(fieldConstant,
0725:                                            0);
0726:                                }
0727:                            } else {
0728:                                if (needValue || (i > 0 && complyTo14)
0729:                                        || lastGenericCast != null) {
0730:                                    MethodBinding accessor = this .syntheticReadAccessors == null ? null
0731:                                            : this .syntheticReadAccessors[i];
0732:                                    if (accessor == null) {
0733:                                        if (lastFieldBinding.isStatic()) {
0734:                                            codeStream
0735:                                                    .getstatic(lastFieldBinding);
0736:                                        } else {
0737:                                            codeStream
0738:                                                    .getfield(lastFieldBinding);
0739:                                        }
0740:                                    } else {
0741:                                        codeStream.invokestatic(accessor);
0742:                                    }
0743:                                    if (lastGenericCast != null)
0744:                                        codeStream.checkcast(lastGenericCast);
0745:                                    if (!needValue)
0746:                                        codeStream.pop();
0747:                                } else {
0748:                                    if (this .codegenBinding == lastFieldBinding) {
0749:                                        if (lastFieldBinding.isStatic()) {
0750:                                            // if no valueRequired, still need possible side-effects of <clinit> invocation, if field belongs to different class
0751:                                            if (((FieldBinding) this .binding)
0752:                                                    .original().declaringClass != this .actualReceiverType
0753:                                                    .erasure()) {
0754:                                                MethodBinding accessor = this .syntheticReadAccessors == null ? null
0755:                                                        : this .syntheticReadAccessors[i];
0756:                                                if (accessor == null) {
0757:                                                    codeStream
0758:                                                            .getstatic(lastFieldBinding);
0759:                                                } else {
0760:                                                    codeStream
0761:                                                            .invokestatic(accessor);
0762:                                                }
0763:                                                codeStream.pop();
0764:                                            }
0765:                                        }
0766:                                    } else if (!lastFieldBinding.isStatic()) {
0767:                                        codeStream.invokeObjectGetClass(); // perform null check
0768:                                        codeStream.pop();
0769:                                    }
0770:                                }
0771:                                if ((positionsLength - otherBindingsCount + i - 1) >= 0) {
0772:                                    int fieldPosition = (int) (this .sourcePositions[positionsLength
0773:                                            - otherBindingsCount + i - 1] >>> 32);
0774:                                    codeStream.recordPositionsFrom(pc,
0775:                                            fieldPosition);
0776:                                }
0777:                            }
0778:                        }
0779:                        lastFieldBinding = nextField;
0780:                        lastGenericCast = nextGenericCast;
0781:                    }
0782:                }
0783:                return lastFieldBinding;
0784:            }
0785:
0786:            public void generateReceiver(CodeStream codeStream) {
0787:                codeStream.aload_0();
0788:            }
0789:
0790:            /**
0791:             * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#genericTypeArguments()
0792:             */
0793:            public TypeBinding[] genericTypeArguments() {
0794:                return null;
0795:            }
0796:
0797:            // get the matching codegenBinding
0798:            protected FieldBinding getCodegenBinding(int index) {
0799:                if (index == 0) {
0800:                    return (FieldBinding) this .codegenBinding;
0801:                } else {
0802:                    return this .otherCodegenBindings[index - 1];
0803:                }
0804:            }
0805:
0806:            // get the matching generic cast
0807:            protected TypeBinding getGenericCast(int index) {
0808:                if (index == 0) {
0809:                    return this .genericCast;
0810:                } else {
0811:                    if (this .otherGenericCasts == null)
0812:                        return null;
0813:                    return this .otherGenericCasts[index - 1];
0814:                }
0815:            }
0816:
0817:            public TypeBinding getOtherFieldBindings(BlockScope scope) {
0818:                // At this point restrictiveFlag may ONLY have two potential value : FIELD LOCAL (i.e cast <<(VariableBinding) binding>> is valid)
0819:                int length = this .tokens.length;
0820:                FieldBinding field;
0821:                if ((this .bits & Binding.FIELD) != 0) {
0822:                    field = (FieldBinding) this .binding;
0823:                    if (!field.isStatic()) {
0824:                        //must check for the static status....
0825:                        if (this .indexOfFirstFieldBinding > 1 //accessing to a field using a type as "receiver" is allowed only with static field
0826:                                || scope.methodScope().isStatic) { // the field is the first token of the qualified reference....
0827:                            scope.problemReporter()
0828:                                    .staticFieldAccessToNonStaticVariable(this ,
0829:                                            field);
0830:                            return null;
0831:                        }
0832:                    } else {
0833:                        // indirect static reference ?
0834:                        if (this .indexOfFirstFieldBinding > 1
0835:                                && field.declaringClass != this .actualReceiverType
0836:                                && field.declaringClass.canBeSeenBy(scope)) {
0837:                            scope.problemReporter()
0838:                                    .indirectAccessToStaticField(this , field);
0839:                        }
0840:                    }
0841:                    // only last field is actually a write access if any
0842:                    if (isFieldUseDeprecated(field, scope,
0843:                            (this .bits & ASTNode.IsStrictlyAssigned) != 0
0844:                                    && this .indexOfFirstFieldBinding == length))
0845:                        scope.problemReporter().deprecatedField(field, this );
0846:                } else {
0847:                    field = null;
0848:                }
0849:                TypeBinding type = ((VariableBinding) this .binding).type;
0850:                int index = this .indexOfFirstFieldBinding;
0851:                if (index == length) { //	restrictiveFlag == FIELD
0852:                    this .constant = ((FieldBinding) this .binding).constant();
0853:                    // perform capture conversion if read access
0854:                    return (type != null && (this .bits & ASTNode.IsStrictlyAssigned) == 0) ? type
0855:                            .capture(scope, this .sourceEnd)
0856:                            : type;
0857:                }
0858:                // allocation of the fieldBindings array	and its respective constants
0859:                int otherBindingsLength = length - index;
0860:                this .otherCodegenBindings = this .otherBindings = new FieldBinding[otherBindingsLength];
0861:                this .otherDepths = new int[otherBindingsLength];
0862:
0863:                // fill the first constant (the one of the binding)
0864:                this .constant = ((VariableBinding) this .binding).constant();
0865:                // save first depth, since will be updated by visibility checks of other bindings
0866:                int firstDepth = (this .bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT;
0867:                // iteration on each field	
0868:                while (index < length) {
0869:                    char[] token = this .tokens[index];
0870:                    if (type == null)
0871:                        return null; // could not resolve type prior to this point
0872:
0873:                    this .bits &= ~ASTNode.DepthMASK; // flush previous depth if any		
0874:                    FieldBinding previousField = field;
0875:                    field = scope.getField(type.capture(scope,
0876:                            (int) this .sourcePositions[index]), token, this );
0877:                    int place = index - this .indexOfFirstFieldBinding;
0878:                    this .otherBindings[place] = field;
0879:                    this .otherDepths[place] = (this .bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT;
0880:                    if (field.isValidBinding()) {
0881:                        // set generic cast of for previous field (if any)
0882:                        if (previousField != null) {
0883:                            TypeBinding fieldReceiverType = type;
0884:                            TypeBinding receiverErasure = type.erasure();
0885:                            if (receiverErasure instanceof  ReferenceBinding) {
0886:                                if (receiverErasure
0887:                                        .findSuperTypeWithSameErasure(field.declaringClass) == null) {
0888:                                    fieldReceiverType = field.declaringClass; // handle indirect inheritance thru variable secondary bound
0889:                                }
0890:                            }
0891:                            FieldBinding originalBinding = previousField
0892:                                    .original();
0893:                            if ((originalBinding.type.tagBits & TagBits.HasTypeVariable) != 0
0894:                                    && fieldReceiverType.id != TypeIds.T_JavaLangObject) {
0895:                                setGenericCast(index - 1, originalBinding.type
0896:                                        .genericCast(fieldReceiverType)); // type cannot be base-type even in boxing case
0897:                            }
0898:                        }
0899:                        // only last field is actually a write access if any
0900:                        if (isFieldUseDeprecated(field, scope,
0901:                                (this .bits & ASTNode.IsStrictlyAssigned) != 0
0902:                                        && index + 1 == length)) {
0903:                            scope.problemReporter()
0904:                                    .deprecatedField(field, this );
0905:                        }
0906:                        // constant propagation can only be performed as long as the previous one is a constant too.
0907:                        if (this .constant != Constant.NotAConstant) {
0908:                            this .constant = field.constant();
0909:                        }
0910:
0911:                        if (field.isStatic()) {
0912:                            // static field accessed through receiver? legal but unoptimal (optional warning)
0913:                            scope.problemReporter()
0914:                                    .nonStaticAccessToStaticField(this , field,
0915:                                            index);
0916:                            // indirect static reference ?
0917:                            if (field.declaringClass != type) {
0918:                                scope.problemReporter()
0919:                                        .indirectAccessToStaticField(this ,
0920:                                                field);
0921:                            }
0922:                        }
0923:                        type = field.type;
0924:                        index++;
0925:                    } else {
0926:                        this .constant = Constant.NotAConstant; //don't fill other constants slots...
0927:                        scope.problemReporter().invalidField(this , field,
0928:                                index, type);
0929:                        setDepth(firstDepth);
0930:                        return null;
0931:                    }
0932:                }
0933:                setDepth(firstDepth);
0934:                type = (this .otherBindings[otherBindingsLength - 1]).type;
0935:                // perform capture conversion if read access
0936:                return (type != null && (this .bits & ASTNode.IsStrictlyAssigned) == 0) ? type
0937:                        .capture(scope, this .sourceEnd)
0938:                        : type;
0939:            }
0940:
0941:            public void manageEnclosingInstanceAccessIfNecessary(
0942:                    BlockScope currentScope, FlowInfo flowInfo) {
0943:                if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
0944:                    //If inlinable field, forget the access emulation, the code gen will directly target it
0945:                    if (((this .bits & ASTNode.DepthMASK) == 0)
0946:                            || (this .constant != Constant.NotAConstant)) {
0947:                        return;
0948:                    }
0949:                    if ((this .bits & ASTNode.RestrictiveFlagMASK) == Binding.LOCAL) {
0950:                        currentScope
0951:                                .emulateOuterAccess((LocalVariableBinding) this .binding);
0952:                    }
0953:                }
0954:            }
0955:
0956:            /**
0957:             * index is <0 to denote write access emulation
0958:             */
0959:            public void manageSyntheticAccessIfNecessary(
0960:                    BlockScope currentScope, FieldBinding fieldBinding,
0961:                    TypeBinding lastReceiverType, int index, FlowInfo flowInfo) {
0962:                if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0)
0963:                    return;
0964:                // index == 0 denotes the first fieldBinding, index > 0 denotes one of the 'otherBindings', index < 0 denotes a write access (to last binding)
0965:                if (fieldBinding.constant() != Constant.NotAConstant)
0966:                    return;
0967:
0968:                // if field from parameterized type got found, use the original field at codegen time
0969:                FieldBinding originalField = fieldBinding.original();
0970:                if (originalField != fieldBinding) {
0971:                    setCodegenBinding(
0972:                            index < 0 ? (this .otherBindings == null ? 0
0973:                                    : this .otherBindings.length) : index,
0974:                            originalField);
0975:                }
0976:
0977:                if (fieldBinding.isPrivate()) { // private access
0978:                    FieldBinding someCodegenBinding = getCodegenBinding(index < 0 ? (this .otherBindings == null ? 0
0979:                            : this .otherBindings.length)
0980:                            : index);
0981:                    if (someCodegenBinding.declaringClass != currentScope
0982:                            .enclosingSourceType()) {
0983:                        setSyntheticAccessor(
0984:                                fieldBinding,
0985:                                index,
0986:                                ((SourceTypeBinding) someCodegenBinding.declaringClass)
0987:                                        .addSyntheticMethod(someCodegenBinding,
0988:                                                index >= 0 /*read-access?*/));
0989:                        currentScope.problemReporter()
0990:                                .needToEmulateFieldAccess(someCodegenBinding,
0991:                                        this , index >= 0 /*read-access?*/);
0992:                        return;
0993:                    }
0994:                } else if (fieldBinding.isProtected()) {
0995:                    int depth = (index == 0 || (index < 0 && this .otherDepths == null)) ? (this .bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT
0996:                            : this .otherDepths[index < 0 ? this .otherDepths.length - 1
0997:                                    : index - 1];
0998:
0999:                    // implicit protected access 
1000:                    if (depth > 0
1001:                            && (fieldBinding.declaringClass.getPackage() != currentScope
1002:                                    .enclosingSourceType().getPackage())) {
1003:                        FieldBinding someCodegenBinding = getCodegenBinding(index < 0 ? (this .otherBindings == null ? 0
1004:                                : this .otherBindings.length)
1005:                                : index);
1006:                        setSyntheticAccessor(fieldBinding, index,
1007:                                ((SourceTypeBinding) currentScope
1008:                                        .enclosingSourceType().enclosingTypeAt(
1009:                                                depth))
1010:                                        .addSyntheticMethod(someCodegenBinding,
1011:                                                index >= 0 /*read-access?*/));
1012:                        currentScope.problemReporter()
1013:                                .needToEmulateFieldAccess(someCodegenBinding,
1014:                                        this , index >= 0 /*read-access?*/);
1015:                        return;
1016:                    }
1017:                }
1018:                // if the binding declaring class is not visible, need special action
1019:                // for runtime compatibility on 1.2 VMs : change the declaring class of the binding
1020:                // NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type
1021:                // and not from Object or implicit static field access.	
1022:                if (fieldBinding.declaringClass != lastReceiverType
1023:                        && !lastReceiverType.isArrayType()
1024:                        && fieldBinding.declaringClass != null // array.length
1025:                        && fieldBinding.constant() == Constant.NotAConstant) {
1026:                    CompilerOptions options = currentScope.compilerOptions();
1027:                    if ((options.targetJDK >= ClassFileConstants.JDK1_2
1028:                            && (options.complianceLevel >= ClassFileConstants.JDK1_4 || !(index <= 1
1029:                                    && this .indexOfFirstFieldBinding == 1 && fieldBinding
1030:                                    .isStatic())) && fieldBinding.declaringClass.id != TypeIds.T_JavaLangObject) // no change for Object fields
1031:                            || !fieldBinding.declaringClass
1032:                                    .canBeSeenBy(currentScope)) {
1033:
1034:                        setCodegenBinding(
1035:                                index < 0 ? (this .otherBindings == null ? 0
1036:                                        : this .otherBindings.length) : index,
1037:                                currentScope
1038:                                        .enclosingSourceType()
1039:                                        .getUpdatedFieldBinding(
1040:                                                getCodegenBinding(index < 0 ? (this .otherBindings == null ? 0
1041:                                                        : this .otherBindings.length)
1042:                                                        : index),
1043:                                                (ReferenceBinding) lastReceiverType
1044:                                                        .erasure()));
1045:                    }
1046:                }
1047:            }
1048:
1049:            public int nullStatus(FlowInfo flowInfo) {
1050:                return FlowInfo.UNKNOWN;
1051:            }
1052:
1053:            public Constant optimizedBooleanConstant() {
1054:                switch (this .resolvedType.id) {
1055:                case T_boolean:
1056:                case T_JavaLangBoolean:
1057:                    if (this .constant != Constant.NotAConstant)
1058:                        return this .constant;
1059:                    switch (this .bits & ASTNode.RestrictiveFlagMASK) {
1060:                    case Binding.FIELD: // reading a field
1061:                        if (this .otherBindings == null)
1062:                            return ((FieldBinding) this .binding).constant();
1063:                        // fall thru
1064:                    case Binding.LOCAL: // reading a local variable
1065:                        return this .otherBindings[this .otherBindings.length - 1]
1066:                                .constant();
1067:                    }
1068:                }
1069:                return Constant.NotAConstant;
1070:            }
1071:
1072:            /**
1073:             * @see org.eclipse.jdt.internal.compiler.ast.Expression#postConversionType(Scope)
1074:             */
1075:            public TypeBinding postConversionType(Scope scope) {
1076:                TypeBinding convertedType = this .resolvedType;
1077:                TypeBinding requiredGenericCast = getGenericCast(this .otherCodegenBindings == null ? 0
1078:                        : this .otherCodegenBindings.length);
1079:                if (requiredGenericCast != null)
1080:                    convertedType = requiredGenericCast;
1081:                int runtimeType = (this .implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4;
1082:                switch (runtimeType) {
1083:                case T_boolean:
1084:                    convertedType = TypeBinding.BOOLEAN;
1085:                    break;
1086:                case T_byte:
1087:                    convertedType = TypeBinding.BYTE;
1088:                    break;
1089:                case T_short:
1090:                    convertedType = TypeBinding.SHORT;
1091:                    break;
1092:                case T_char:
1093:                    convertedType = TypeBinding.CHAR;
1094:                    break;
1095:                case T_int:
1096:                    convertedType = TypeBinding.INT;
1097:                    break;
1098:                case T_float:
1099:                    convertedType = TypeBinding.FLOAT;
1100:                    break;
1101:                case T_long:
1102:                    convertedType = TypeBinding.LONG;
1103:                    break;
1104:                case T_double:
1105:                    convertedType = TypeBinding.DOUBLE;
1106:                    break;
1107:                default:
1108:                }
1109:                if ((this .implicitConversion & TypeIds.BOXING) != 0) {
1110:                    convertedType = scope.environment().computeBoxingType(
1111:                            convertedType);
1112:                }
1113:                return convertedType;
1114:            }
1115:
1116:            public StringBuffer printExpression(int indent, StringBuffer output) {
1117:                for (int i = 0; i < this .tokens.length; i++) {
1118:                    if (i > 0)
1119:                        output.append('.');
1120:                    output.append(this .tokens[i]);
1121:                }
1122:                return output;
1123:            }
1124:
1125:            /**
1126:             * Normal field binding did not work, try to bind to a field of the delegate receiver.
1127:             */
1128:            public TypeBinding reportError(BlockScope scope) {
1129:                if (this .binding instanceof  ProblemFieldBinding) {
1130:                    scope.problemReporter().invalidField(this ,
1131:                            (FieldBinding) this .binding);
1132:                } else if (this .binding instanceof  ProblemReferenceBinding) {
1133:                    scope.problemReporter().invalidType(this ,
1134:                            (TypeBinding) this .binding);
1135:                } else {
1136:                    scope.problemReporter().unresolvableReference(this ,
1137:                            this .binding);
1138:                }
1139:                return null;
1140:            }
1141:
1142:            public TypeBinding resolveType(BlockScope scope) {
1143:                // field and/or local are done before type lookups
1144:                // the only available value for the restrictiveFlag BEFORE
1145:                // the TC is Flag_Type Flag_LocalField and Flag_TypeLocalField 
1146:                this .actualReceiverType = scope.enclosingReceiverType();
1147:                this .constant = Constant.NotAConstant;
1148:                if ((this .codegenBinding = this .binding = scope.getBinding(
1149:                        this .tokens, this .bits & ASTNode.RestrictiveFlagMASK,
1150:                        this , true /*resolve*/)).isValidBinding()) {
1151:                    switch (this .bits & ASTNode.RestrictiveFlagMASK) {
1152:                    case Binding.VARIABLE: //============only variable===========
1153:                    case Binding.TYPE | Binding.VARIABLE:
1154:                        if (this .binding instanceof  LocalVariableBinding) {
1155:                            if (!((LocalVariableBinding) this .binding)
1156:                                    .isFinal()
1157:                                    && ((this .bits & ASTNode.DepthMASK) != 0))
1158:                                scope
1159:                                        .problemReporter()
1160:                                        .cannotReferToNonFinalOuterLocal(
1161:                                                (LocalVariableBinding) this .binding,
1162:                                                this );
1163:                            this .bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits
1164:                            this .bits |= Binding.LOCAL;
1165:                            return this .resolvedType = getOtherFieldBindings(scope);
1166:                        }
1167:                        if (this .binding instanceof  FieldBinding) {
1168:                            FieldBinding fieldBinding = (FieldBinding) this .binding;
1169:                            MethodScope methodScope = scope.methodScope();
1170:                            // check for forward references
1171:                            if (this .indexOfFirstFieldBinding == 1
1172:                                    && methodScope.enclosingSourceType() == fieldBinding
1173:                                            .original().declaringClass
1174:                                    && methodScope.lastVisibleFieldID >= 0
1175:                                    && fieldBinding.id >= methodScope.lastVisibleFieldID
1176:                                    && (!fieldBinding.isStatic() || methodScope.isStatic)) {
1177:                                scope.problemReporter().forwardReference(this ,
1178:                                        0, methodScope.enclosingSourceType());
1179:                            }
1180:                            if (!fieldBinding.isStatic()
1181:                                    && this .indexOfFirstFieldBinding == 1
1182:                                    && scope
1183:                                            .compilerOptions()
1184:                                            .getSeverity(
1185:                                                    CompilerOptions.UnqualifiedFieldAccess) != ProblemSeverities.Ignore) {
1186:                                scope.problemReporter().unqualifiedFieldAccess(
1187:                                        this , fieldBinding);
1188:                            }
1189:                            this .bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits
1190:                            this .bits |= Binding.FIELD;
1191:
1192:                            //						// check for deprecated receiver type
1193:                            //						// deprecation check for receiver type if not first token
1194:                            //						if (indexOfFirstFieldBinding > 1) {
1195:                            //							if (isTypeUseDeprecated(this.actualReceiverType, scope))
1196:                            //								scope.problemReporter().deprecatedType(this.actualReceiverType, this);
1197:                            //						}
1198:
1199:                            return this .resolvedType = getOtherFieldBindings(scope);
1200:                        }
1201:                        // thus it was a type
1202:                        this .bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits
1203:                        this .bits |= Binding.TYPE;
1204:                    case Binding.TYPE: //=============only type ==============
1205:                        TypeBinding type = (TypeBinding) this .binding;
1206:                        //					if (isTypeUseDeprecated(type, scope))
1207:                        //						scope.problemReporter().deprecatedType(type, this);
1208:                        type = scope.environment().convertToRawType(type);
1209:                        return this .resolvedType = type;
1210:                    }
1211:                }
1212:                //========error cases===============
1213:                return this .resolvedType = this .reportError(scope);
1214:            }
1215:
1216:            // set the matching codegenBinding and generic cast
1217:            protected void setCodegenBinding(int index,
1218:                    FieldBinding someCodegenBinding) {
1219:                if (index == 0) {
1220:                    this .codegenBinding = someCodegenBinding;
1221:                } else {
1222:                    int length = this .otherBindings.length;
1223:                    if (this .otherCodegenBindings == this .otherBindings) {
1224:                        System
1225:                                .arraycopy(
1226:                                        this .otherBindings,
1227:                                        0,
1228:                                        this .otherCodegenBindings = new FieldBinding[length],
1229:                                        0, length);
1230:                    }
1231:                    this .otherCodegenBindings[index - 1] = someCodegenBinding;
1232:                }
1233:            }
1234:
1235:            public void setFieldIndex(int index) {
1236:                this .indexOfFirstFieldBinding = index;
1237:            }
1238:
1239:            // set the matching codegenBinding and generic cast
1240:            protected void setGenericCast(int index, TypeBinding someGenericCast) {
1241:                if (index == 0) {
1242:                    this .genericCast = someGenericCast;
1243:                } else {
1244:                    if (this .otherGenericCasts == null) {
1245:                        this .otherGenericCasts = new TypeBinding[this .otherBindings.length];
1246:                    }
1247:                    this .otherGenericCasts[index - 1] = someGenericCast;
1248:                }
1249:            }
1250:
1251:            // set the matching synthetic accessor
1252:            protected void setSyntheticAccessor(FieldBinding fieldBinding,
1253:                    int index, SyntheticMethodBinding syntheticAccessor) {
1254:                if (index < 0) { // write-access ?
1255:                    this .syntheticWriteAccessor = syntheticAccessor;
1256:                } else {
1257:                    if (this .syntheticReadAccessors == null) {
1258:                        this .syntheticReadAccessors = new SyntheticMethodBinding[this .otherBindings == null ? 1
1259:                                : this .otherBindings.length + 1];
1260:                    }
1261:                    this .syntheticReadAccessors[index] = syntheticAccessor;
1262:                }
1263:            }
1264:
1265:            public void traverse(ASTVisitor visitor, BlockScope scope) {
1266:                visitor.visit(this , scope);
1267:                visitor.endVisit(this , scope);
1268:            }
1269:
1270:            public void traverse(ASTVisitor visitor, ClassScope scope) {
1271:                visitor.visit(this , scope);
1272:                visitor.endVisit(this , scope);
1273:            }
1274:
1275:            public String unboundReferenceErrorName() {
1276:                return new String(this .tokens[0]);
1277:            }
1278:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.