Source Code Cross Referenced for TypeDeclaration.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.core.compiler.*;
0013:        import org.eclipse.jdt.internal.compiler.*;
0014:        import org.eclipse.jdt.internal.compiler.impl.*;
0015:        import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
0016:        import org.eclipse.jdt.internal.compiler.codegen.*;
0017:        import org.eclipse.jdt.internal.compiler.flow.*;
0018:        import org.eclipse.jdt.internal.compiler.lookup.*;
0019:        import org.eclipse.jdt.internal.compiler.parser.*;
0020:        import org.eclipse.jdt.internal.compiler.problem.*;
0021:
0022:        public class TypeDeclaration extends Statement implements 
0023:                ProblemSeverities, ReferenceContext {
0024:            // Type decl kinds
0025:            public static final int CLASS_DECL = 1;
0026:            public static final int INTERFACE_DECL = 2;
0027:            public static final int ENUM_DECL = 3;
0028:            public static final int ANNOTATION_TYPE_DECL = 4;
0029:
0030:            public int modifiers = ClassFileConstants.AccDefault;
0031:            public int modifiersSourceStart;
0032:            public Annotation[] annotations;
0033:            public char[] name;
0034:            public TypeReference super class;
0035:            public TypeReference[] super Interfaces;
0036:            public FieldDeclaration[] fields;
0037:            public AbstractMethodDeclaration[] methods;
0038:            public TypeDeclaration[] memberTypes;
0039:            public SourceTypeBinding binding;
0040:            public ClassScope scope;
0041:            public MethodScope initializerScope;
0042:            public MethodScope staticInitializerScope;
0043:            public boolean ignoreFurtherInvestigation = false;
0044:            public int maxFieldCount;
0045:            public int declarationSourceStart;
0046:            public int declarationSourceEnd;
0047:            public int bodyStart;
0048:            public int bodyEnd; // doesn't include the trailing comment if any.
0049:            public CompilationResult compilationResult;
0050:            public MethodDeclaration[] missingAbstractMethods;
0051:            public Javadoc javadoc;
0052:
0053:            public QualifiedAllocationExpression allocation; // for anonymous only
0054:            public TypeDeclaration enclosingType; // for member types only
0055:
0056:            public FieldBinding enumValuesSyntheticfield; // for enum
0057:
0058:            // 1.5 support
0059:            public TypeParameter[] typeParameters;
0060:
0061:            public TypeDeclaration(CompilationResult compilationResult) {
0062:                this .compilationResult = compilationResult;
0063:            }
0064:
0065:            /*
0066:             *	We cause the compilation task to abort to a given extent.
0067:             */
0068:            public void abort(int abortLevel, CategorizedProblem problem) {
0069:                switch (abortLevel) {
0070:                case AbortCompilation:
0071:                    throw new AbortCompilation(this .compilationResult, problem);
0072:                case AbortCompilationUnit:
0073:                    throw new AbortCompilationUnit(this .compilationResult,
0074:                            problem);
0075:                case AbortMethod:
0076:                    throw new AbortMethod(this .compilationResult, problem);
0077:                default:
0078:                    throw new AbortType(this .compilationResult, problem);
0079:                }
0080:            }
0081:
0082:            /**
0083:             * This method is responsible for adding a <clinit> method declaration to the type method collections.
0084:             * Note that this implementation is inserting it in first place (as VAJ or javac), and that this
0085:             * impacts the behavior of the method ConstantPool.resetForClinit(int. int), in so far as 
0086:             * the latter will have to reset the constant pool state accordingly (if it was added first, it does 
0087:             * not need to preserve some of the method specific cached entries since this will be the first method).
0088:             * inserts the clinit method declaration in the first position.
0089:             * 
0090:             * @see org.eclipse.jdt.internal.compiler.codegen.ConstantPool#resetForClinit(int, int)
0091:             */
0092:            public final void addClinit() {
0093:                //see comment on needClassInitMethod
0094:                if (needClassInitMethod()) {
0095:                    int length;
0096:                    AbstractMethodDeclaration[] methodDeclarations;
0097:                    if ((methodDeclarations = this .methods) == null) {
0098:                        length = 0;
0099:                        methodDeclarations = new AbstractMethodDeclaration[1];
0100:                    } else {
0101:                        length = methodDeclarations.length;
0102:                        System
0103:                                .arraycopy(
0104:                                        methodDeclarations,
0105:                                        0,
0106:                                        (methodDeclarations = new AbstractMethodDeclaration[length + 1]),
0107:                                        1, length);
0108:                    }
0109:                    Clinit clinit = new Clinit(this .compilationResult);
0110:                    methodDeclarations[0] = clinit;
0111:                    // clinit is added in first location, so as to minimize the use of ldcw (big consumer of constant inits)
0112:                    clinit.declarationSourceStart = clinit.sourceStart = this .sourceStart;
0113:                    clinit.declarationSourceEnd = clinit.sourceEnd = this .sourceEnd;
0114:                    clinit.bodyEnd = this .sourceEnd;
0115:                    this .methods = methodDeclarations;
0116:                }
0117:            }
0118:
0119:            /*
0120:             * INTERNAL USE ONLY - Creates a fake method declaration for the corresponding binding.
0121:             * It is used to report errors for missing abstract methods.
0122:             */
0123:            public MethodDeclaration addMissingAbstractMethodFor(
0124:                    MethodBinding methodBinding) {
0125:                TypeBinding[] argumentTypes = methodBinding.parameters;
0126:                int argumentsLength = argumentTypes.length;
0127:                //the constructor
0128:                MethodDeclaration methodDeclaration = new MethodDeclaration(
0129:                        this .compilationResult);
0130:                methodDeclaration.selector = methodBinding.selector;
0131:                methodDeclaration.sourceStart = this .sourceStart;
0132:                methodDeclaration.sourceEnd = this .sourceEnd;
0133:                methodDeclaration.modifiers = methodBinding.getAccessFlags()
0134:                        & ~ClassFileConstants.AccAbstract;
0135:
0136:                if (argumentsLength > 0) {
0137:                    String baseName = "arg";//$NON-NLS-1$
0138:                    Argument[] arguments = (methodDeclaration.arguments = new Argument[argumentsLength]);
0139:                    for (int i = argumentsLength; --i >= 0;) {
0140:                        arguments[i] = new Argument((baseName + i)
0141:                                .toCharArray(), 0L, null /*type ref*/,
0142:                                ClassFileConstants.AccDefault);
0143:                    }
0144:                }
0145:
0146:                //adding the constructor in the methods list
0147:                if (this .missingAbstractMethods == null) {
0148:                    this .missingAbstractMethods = new MethodDeclaration[] { methodDeclaration };
0149:                } else {
0150:                    MethodDeclaration[] newMethods;
0151:                    System
0152:                            .arraycopy(
0153:                                    this .missingAbstractMethods,
0154:                                    0,
0155:                                    newMethods = new MethodDeclaration[this .missingAbstractMethods.length + 1],
0156:                                    1, this .missingAbstractMethods.length);
0157:                    newMethods[0] = methodDeclaration;
0158:                    this .missingAbstractMethods = newMethods;
0159:                }
0160:
0161:                //============BINDING UPDATE==========================
0162:                methodDeclaration.binding = new MethodBinding(
0163:                        methodDeclaration.modifiers, //methodDeclaration
0164:                        methodBinding.selector, methodBinding.returnType,
0165:                        argumentsLength == 0 ? Binding.NO_PARAMETERS
0166:                                : argumentTypes, //arguments bindings
0167:                        methodBinding.thrownExceptions, //exceptions
0168:                        this .binding); //declaringClass
0169:
0170:                methodDeclaration.scope = new MethodScope(this .scope,
0171:                        methodDeclaration, true);
0172:                methodDeclaration.bindArguments();
0173:
0174:                /*		if (binding.methods == null) {
0175:                 binding.methods = new MethodBinding[] { methodDeclaration.binding };
0176:                 } else {
0177:                 MethodBinding[] newMethods;
0178:                 System.arraycopy(
0179:                 binding.methods,
0180:                 0,
0181:                 newMethods = new MethodBinding[binding.methods.length + 1],
0182:                 1,
0183:                 binding.methods.length);
0184:                 newMethods[0] = methodDeclaration.binding;
0185:                 binding.methods = newMethods;
0186:                 }*/
0187:                //===================================================
0188:                return methodDeclaration;
0189:            }
0190:
0191:            /**
0192:             *	Flow analysis for a local innertype
0193:             *
0194:             */
0195:            public FlowInfo analyseCode(BlockScope currentScope,
0196:                    FlowContext flowContext, FlowInfo flowInfo) {
0197:                if (this .ignoreFurtherInvestigation)
0198:                    return flowInfo;
0199:                try {
0200:                    if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
0201:                        this .bits |= ASTNode.IsReachable;
0202:                        LocalTypeBinding localType = (LocalTypeBinding) this .binding;
0203:                        localType.setConstantPoolName(currentScope
0204:                                .compilationUnitScope()
0205:                                .computeConstantPoolName(localType));
0206:                    }
0207:                    manageEnclosingInstanceAccessIfNecessary(currentScope,
0208:                            flowInfo);
0209:                    updateMaxFieldCount(); // propagate down the max field count
0210:                    internalAnalyseCode(flowContext, flowInfo);
0211:                } catch (AbortType e) {
0212:                    this .ignoreFurtherInvestigation = true;
0213:                }
0214:                return flowInfo;
0215:            }
0216:
0217:            /**
0218:             *	Flow analysis for a member innertype
0219:             *
0220:             */
0221:            public void analyseCode(ClassScope enclosingClassScope) {
0222:                if (this .ignoreFurtherInvestigation)
0223:                    return;
0224:                try {
0225:                    // propagate down the max field count
0226:                    updateMaxFieldCount();
0227:                    internalAnalyseCode(null, FlowInfo
0228:                            .initial(this .maxFieldCount));
0229:                } catch (AbortType e) {
0230:                    this .ignoreFurtherInvestigation = true;
0231:                }
0232:            }
0233:
0234:            /**
0235:             *	Flow analysis for a local member innertype
0236:             *
0237:             */
0238:            public void analyseCode(ClassScope currentScope,
0239:                    FlowContext flowContext, FlowInfo flowInfo) {
0240:                if (this .ignoreFurtherInvestigation)
0241:                    return;
0242:                try {
0243:                    if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
0244:                        this .bits |= ASTNode.IsReachable;
0245:                        LocalTypeBinding localType = (LocalTypeBinding) this .binding;
0246:                        localType.setConstantPoolName(currentScope
0247:                                .compilationUnitScope()
0248:                                .computeConstantPoolName(localType));
0249:                    }
0250:                    manageEnclosingInstanceAccessIfNecessary(currentScope,
0251:                            flowInfo);
0252:                    updateMaxFieldCount(); // propagate down the max field count
0253:                    internalAnalyseCode(flowContext, flowInfo);
0254:                } catch (AbortType e) {
0255:                    this .ignoreFurtherInvestigation = true;
0256:                }
0257:            }
0258:
0259:            /**
0260:             *	Flow analysis for a package member type
0261:             *
0262:             */
0263:            public void analyseCode(CompilationUnitScope unitScope) {
0264:                if (this .ignoreFurtherInvestigation)
0265:                    return;
0266:                try {
0267:                    internalAnalyseCode(null, FlowInfo
0268:                            .initial(this .maxFieldCount));
0269:                } catch (AbortType e) {
0270:                    this .ignoreFurtherInvestigation = true;
0271:                }
0272:            }
0273:
0274:            /**
0275:             * Check for constructor vs. method with no return type.
0276:             * Answers true if at least one constructor is defined
0277:             */
0278:            public boolean checkConstructors(Parser parser) {
0279:                //if a constructor has not the name of the type,
0280:                //convert it into a method with 'null' as its return type
0281:                boolean hasConstructor = false;
0282:                if (this .methods != null) {
0283:                    for (int i = this .methods.length; --i >= 0;) {
0284:                        AbstractMethodDeclaration am;
0285:                        if ((am = this .methods[i]).isConstructor()) {
0286:                            if (!CharOperation.equals(am.selector, this .name)) {
0287:                                // the constructor was in fact a method with no return type
0288:                                // unless an explicit constructor call was supplied
0289:                                ConstructorDeclaration c = (ConstructorDeclaration) am;
0290:                                if (c.constructorCall == null
0291:                                        || c.constructorCall.isImplicitSuper()) { //changed to a method
0292:                                    MethodDeclaration m = parser
0293:                                            .convertToMethodDeclaration(c,
0294:                                                    this .compilationResult);
0295:                                    this .methods[i] = m;
0296:                                }
0297:                            } else {
0298:                                switch (kind(this .modifiers)) {
0299:                                case TypeDeclaration.INTERFACE_DECL:
0300:                                    // report the problem and continue the parsing
0301:                                    parser
0302:                                            .problemReporter()
0303:                                            .interfaceCannotHaveConstructors(
0304:                                                    (ConstructorDeclaration) am);
0305:                                    break;
0306:                                case TypeDeclaration.ANNOTATION_TYPE_DECL:
0307:                                    // report the problem and continue the parsing
0308:                                    parser
0309:                                            .problemReporter()
0310:                                            .annotationTypeDeclarationCannotHaveConstructor(
0311:                                                    (ConstructorDeclaration) am);
0312:                                    break;
0313:
0314:                                }
0315:                                hasConstructor = true;
0316:                            }
0317:                        }
0318:                    }
0319:                }
0320:                return hasConstructor;
0321:            }
0322:
0323:            public CompilationResult compilationResult() {
0324:                return this .compilationResult;
0325:            }
0326:
0327:            public ConstructorDeclaration createDefaultConstructor(
0328:                    boolean needExplicitConstructorCall, boolean needToInsert) {
0329:                //Add to method'set, the default constuctor that just recall the
0330:                //super constructor with no arguments
0331:                //The arguments' type will be positionned by the TC so just use
0332:                //the default int instead of just null (consistency purpose)
0333:
0334:                //the constructor
0335:                ConstructorDeclaration constructor = new ConstructorDeclaration(
0336:                        this .compilationResult);
0337:                constructor.bits |= ASTNode.IsDefaultConstructor;
0338:                constructor.selector = this .name;
0339:                constructor.modifiers = this .modifiers
0340:                        & ExtraCompilerModifiers.AccVisibilityMASK;
0341:
0342:                //if you change this setting, please update the 
0343:                //SourceIndexer2.buildTypeDeclaration(TypeDeclaration,char[]) method
0344:                constructor.declarationSourceStart = constructor.sourceStart = this .sourceStart;
0345:                constructor.declarationSourceEnd = constructor.sourceEnd = constructor.bodyEnd = this .sourceEnd;
0346:
0347:                //the super call inside the constructor
0348:                if (needExplicitConstructorCall) {
0349:                    constructor.constructorCall = SuperReference
0350:                            .implicitSuperConstructorCall();
0351:                    constructor.constructorCall.sourceStart = this .sourceStart;
0352:                    constructor.constructorCall.sourceEnd = this .sourceEnd;
0353:                }
0354:
0355:                //adding the constructor in the methods list: rank is not critical since bindings will be sorted
0356:                if (needToInsert) {
0357:                    if (this .methods == null) {
0358:                        this .methods = new AbstractMethodDeclaration[] { constructor };
0359:                    } else {
0360:                        AbstractMethodDeclaration[] newMethods;
0361:                        System
0362:                                .arraycopy(
0363:                                        this .methods,
0364:                                        0,
0365:                                        newMethods = new AbstractMethodDeclaration[this .methods.length + 1],
0366:                                        1, this .methods.length);
0367:                        newMethods[0] = constructor;
0368:                        this .methods = newMethods;
0369:                    }
0370:                }
0371:                return constructor;
0372:            }
0373:
0374:            // anonymous type constructor creation: rank is important since bindings already got sorted
0375:            public MethodBinding createDefaultConstructorWithBinding(
0376:                    MethodBinding inheritedConstructorBinding) {
0377:                //Add to method'set, the default constuctor that just recall the
0378:                //super constructor with the same arguments
0379:                String baseName = "$anonymous"; //$NON-NLS-1$
0380:                TypeBinding[] argumentTypes = inheritedConstructorBinding.parameters;
0381:                int argumentsLength = argumentTypes.length;
0382:                //the constructor
0383:                ConstructorDeclaration constructor = new ConstructorDeclaration(
0384:                        this .compilationResult);
0385:                constructor.selector = new char[] { 'x' }; //no maining
0386:                constructor.sourceStart = this .sourceStart;
0387:                constructor.sourceEnd = this .sourceEnd;
0388:                int newModifiers = this .modifiers
0389:                        & ExtraCompilerModifiers.AccVisibilityMASK;
0390:                if (inheritedConstructorBinding.isVarargs()) {
0391:                    newModifiers |= ClassFileConstants.AccVarargs;
0392:                }
0393:                constructor.modifiers = newModifiers;
0394:                constructor.bits |= ASTNode.IsDefaultConstructor;
0395:
0396:                if (argumentsLength > 0) {
0397:                    Argument[] arguments = (constructor.arguments = new Argument[argumentsLength]);
0398:                    for (int i = argumentsLength; --i >= 0;) {
0399:                        arguments[i] = new Argument((baseName + i)
0400:                                .toCharArray(), 0L, null /*type ref*/,
0401:                                ClassFileConstants.AccDefault);
0402:                    }
0403:                }
0404:                //the super call inside the constructor
0405:                constructor.constructorCall = SuperReference
0406:                        .implicitSuperConstructorCall();
0407:                constructor.constructorCall.sourceStart = this .sourceStart;
0408:                constructor.constructorCall.sourceEnd = this .sourceEnd;
0409:
0410:                if (argumentsLength > 0) {
0411:                    Expression[] args;
0412:                    args = constructor.constructorCall.arguments = new Expression[argumentsLength];
0413:                    for (int i = argumentsLength; --i >= 0;) {
0414:                        args[i] = new SingleNameReference((baseName + i)
0415:                                .toCharArray(), 0L);
0416:                    }
0417:                }
0418:
0419:                //adding the constructor in the methods list
0420:                if (this .methods == null) {
0421:                    this .methods = new AbstractMethodDeclaration[] { constructor };
0422:                } else {
0423:                    AbstractMethodDeclaration[] newMethods;
0424:                    System
0425:                            .arraycopy(
0426:                                    this .methods,
0427:                                    0,
0428:                                    newMethods = new AbstractMethodDeclaration[this .methods.length + 1],
0429:                                    1, this .methods.length);
0430:                    newMethods[0] = constructor;
0431:                    this .methods = newMethods;
0432:                }
0433:
0434:                //============BINDING UPDATE==========================
0435:                SourceTypeBinding sourceType = this .binding;
0436:                constructor.binding = new MethodBinding(constructor.modifiers, //methodDeclaration
0437:                        argumentsLength == 0 ? Binding.NO_PARAMETERS
0438:                                : argumentTypes, //arguments bindings
0439:                        inheritedConstructorBinding.thrownExceptions, //exceptions
0440:                        sourceType); //declaringClass
0441:
0442:                constructor.binding.modifiers |= ExtraCompilerModifiers.AccIsDefaultConstructor;
0443:
0444:                constructor.scope = new MethodScope(this .scope, constructor,
0445:                        true);
0446:                constructor.bindArguments();
0447:                constructor.constructorCall.resolve(constructor.scope);
0448:
0449:                MethodBinding[] methodBindings = sourceType.methods(); // trigger sorting
0450:                int length;
0451:                System
0452:                        .arraycopy(
0453:                                methodBindings,
0454:                                0,
0455:                                methodBindings = new MethodBinding[(length = methodBindings.length) + 1],
0456:                                1, length);
0457:                methodBindings[0] = constructor.binding;
0458:                if (++length > 1)
0459:                    ReferenceBinding.sortMethods(methodBindings, 0, length); // need to resort, since could be valid methods ahead (140643) - DOM needs eager sorting
0460:                sourceType.setMethods(methodBindings);
0461:                //===================================================
0462:
0463:                return constructor.binding;
0464:            }
0465:
0466:            /**
0467:             * Find the matching parse node, answers null if nothing found
0468:             */
0469:            public FieldDeclaration declarationOf(FieldBinding fieldBinding) {
0470:                if (fieldBinding != null && this .fields != null) {
0471:                    for (int i = 0, max = this .fields.length; i < max; i++) {
0472:                        FieldDeclaration fieldDecl;
0473:                        if ((fieldDecl = this .fields[i]).binding == fieldBinding)
0474:                            return fieldDecl;
0475:                    }
0476:                }
0477:                return null;
0478:            }
0479:
0480:            /**
0481:             * Find the matching parse node, answers null if nothing found
0482:             */
0483:            public TypeDeclaration declarationOf(
0484:                    MemberTypeBinding memberTypeBinding) {
0485:                if (memberTypeBinding != null && this .memberTypes != null) {
0486:                    for (int i = 0, max = this .memberTypes.length; i < max; i++) {
0487:                        TypeDeclaration memberTypeDecl;
0488:                        if ((memberTypeDecl = this .memberTypes[i]).binding == memberTypeBinding)
0489:                            return memberTypeDecl;
0490:                    }
0491:                }
0492:                return null;
0493:            }
0494:
0495:            /**
0496:             * Find the matching parse node, answers null if nothing found
0497:             */
0498:            public AbstractMethodDeclaration declarationOf(
0499:                    MethodBinding methodBinding) {
0500:                if (methodBinding != null && this .methods != null) {
0501:                    for (int i = 0, max = this .methods.length; i < max; i++) {
0502:                        AbstractMethodDeclaration methodDecl;
0503:
0504:                        if ((methodDecl = this .methods[i]).binding == methodBinding)
0505:                            return methodDecl;
0506:                    }
0507:                }
0508:                return null;
0509:            }
0510:
0511:            /**
0512:             * Finds the matching type amoung this type's member types.
0513:             * Returns null if no type with this name is found.
0514:             * The type name is a compound name relative to this type
0515:             * eg. if this type is X and we're looking for Y.X.A.B
0516:             *     then a type name would be {X, A, B}
0517:             */
0518:            public TypeDeclaration declarationOfType(char[][] typeName) {
0519:                int typeNameLength = typeName.length;
0520:                if (typeNameLength < 1
0521:                        || !CharOperation.equals(typeName[0], this .name)) {
0522:                    return null;
0523:                }
0524:                if (typeNameLength == 1) {
0525:                    return this ;
0526:                }
0527:                char[][] subTypeName = new char[typeNameLength - 1][];
0528:                System.arraycopy(typeName, 1, subTypeName, 0,
0529:                        typeNameLength - 1);
0530:                for (int i = 0; i < this .memberTypes.length; i++) {
0531:                    TypeDeclaration typeDecl = this .memberTypes[i]
0532:                            .declarationOfType(subTypeName);
0533:                    if (typeDecl != null) {
0534:                        return typeDecl;
0535:                    }
0536:                }
0537:                return null;
0538:            }
0539:
0540:            /**
0541:             * Generic bytecode generation for type
0542:             */
0543:            public void generateCode(ClassFile enclosingClassFile) {
0544:                if ((this .bits & ASTNode.HasBeenGenerated) != 0)
0545:                    return;
0546:                this .bits |= ASTNode.HasBeenGenerated;
0547:                if (this .ignoreFurtherInvestigation) {
0548:                    if (this .binding == null)
0549:                        return;
0550:                    ClassFile.createProblemType(this , this .scope
0551:                            .referenceCompilationUnit().compilationResult);
0552:                    return;
0553:                }
0554:                try {
0555:                    // create the result for a compiled type
0556:                    ClassFile classFile = ClassFile
0557:                            .getNewInstance(this .binding);
0558:                    classFile.initialize(this .binding, enclosingClassFile,
0559:                            false);
0560:                    if (this .binding.isMemberType()) {
0561:                        classFile.recordInnerClasses(this .binding);
0562:                    } else if (this .binding.isLocalType()) {
0563:                        enclosingClassFile.recordInnerClasses(this .binding);
0564:                        classFile.recordInnerClasses(this .binding);
0565:                    }
0566:
0567:                    // generate all fiels
0568:                    classFile.addFieldInfos();
0569:
0570:                    if (this .memberTypes != null) {
0571:                        for (int i = 0, max = this .memberTypes.length; i < max; i++) {
0572:                            TypeDeclaration memberType = this .memberTypes[i];
0573:                            classFile.recordInnerClasses(memberType.binding);
0574:                            memberType.generateCode(this .scope, classFile);
0575:                        }
0576:                    }
0577:                    // generate all methods
0578:                    classFile.setForMethodInfos();
0579:                    if (this .methods != null) {
0580:                        for (int i = 0, max = this .methods.length; i < max; i++) {
0581:                            this .methods[i].generateCode(this .scope, classFile);
0582:                        }
0583:                    }
0584:                    // generate all synthetic and abstract methods
0585:                    classFile.addSpecialMethods();
0586:
0587:                    if (this .ignoreFurtherInvestigation) { // trigger problem type generation for code gen errors
0588:                        throw new AbortType(this .scope
0589:                                .referenceCompilationUnit().compilationResult,
0590:                                null);
0591:                    }
0592:
0593:                    // finalize the compiled type result
0594:                    classFile.addAttributes();
0595:                    this .scope.referenceCompilationUnit().compilationResult
0596:                            .record(this .binding.constantPoolName(), classFile);
0597:                } catch (AbortType e) {
0598:                    if (this .binding == null)
0599:                        return;
0600:                    ClassFile.createProblemType(this , this .scope
0601:                            .referenceCompilationUnit().compilationResult);
0602:                }
0603:            }
0604:
0605:            /**
0606:             * Bytecode generation for a local inner type (API as a normal statement code gen)
0607:             */
0608:            public void generateCode(BlockScope blockScope,
0609:                    CodeStream codeStream) {
0610:                if ((this .bits & ASTNode.IsReachable) == 0) {
0611:                    return;
0612:                }
0613:                if ((this .bits & ASTNode.HasBeenGenerated) != 0)
0614:                    return;
0615:                int pc = codeStream.position;
0616:                if (this .binding != null)
0617:                    ((NestedTypeBinding) this .binding)
0618:                            .computeSyntheticArgumentSlotSizes();
0619:                generateCode(codeStream.classFile);
0620:                codeStream.recordPositionsFrom(pc, this .sourceStart);
0621:            }
0622:
0623:            /**
0624:             * Bytecode generation for a member inner type
0625:             */
0626:            public void generateCode(ClassScope classScope,
0627:                    ClassFile enclosingClassFile) {
0628:                if ((this .bits & ASTNode.HasBeenGenerated) != 0)
0629:                    return;
0630:                if (this .binding != null)
0631:                    ((NestedTypeBinding) this .binding)
0632:                            .computeSyntheticArgumentSlotSizes();
0633:                generateCode(enclosingClassFile);
0634:            }
0635:
0636:            /**
0637:             * Bytecode generation for a package member
0638:             */
0639:            public void generateCode(CompilationUnitScope unitScope) {
0640:                generateCode((ClassFile) null);
0641:            }
0642:
0643:            public boolean hasErrors() {
0644:                return this .ignoreFurtherInvestigation;
0645:            }
0646:
0647:            /**
0648:             *	Common flow analysis for all types
0649:             */
0650:            private void internalAnalyseCode(FlowContext flowContext,
0651:                    FlowInfo flowInfo) {
0652:                if ((this .binding.isPrivate() || (this .binding.tagBits & (TagBits.IsAnonymousType | TagBits.IsLocalType)) == TagBits.IsLocalType)
0653:                        && !this .binding.isUsed()) {
0654:                    if (!this .scope.referenceCompilationUnit().compilationResult.hasSyntaxError) {
0655:                        this .scope.problemReporter().unusedPrivateType(this );
0656:                    }
0657:                }
0658:                InitializationFlowContext initializerContext = new InitializationFlowContext(
0659:                        null, this , this .initializerScope);
0660:                InitializationFlowContext staticInitializerContext = new InitializationFlowContext(
0661:                        null, this , this .staticInitializerScope);
0662:                FlowInfo nonStaticFieldInfo = flowInfo
0663:                        .unconditionalFieldLessCopy();
0664:                FlowInfo staticFieldInfo = flowInfo
0665:                        .unconditionalFieldLessCopy();
0666:                if (this .fields != null) {
0667:                    for (int i = 0, count = this .fields.length; i < count; i++) {
0668:                        FieldDeclaration field = this .fields[i];
0669:                        if (field.isStatic()) {
0670:                            if ((staticFieldInfo.tagBits & FlowInfo.UNREACHABLE) != 0)
0671:                                field.bits &= ~ASTNode.IsReachable;
0672:
0673:                            /*if (field.isField()){
0674:                            	staticInitializerContext.handledExceptions = NoExceptions; // no exception is allowed jls8.3.2
0675:                            } else {*/
0676:                            staticInitializerContext.handledExceptions = Binding.ANY_EXCEPTION; // tolerate them all, and record them
0677:                            /*}*/
0678:                            staticFieldInfo = field.analyseCode(
0679:                                    this .staticInitializerScope,
0680:                                    staticInitializerContext, staticFieldInfo);
0681:                            // in case the initializer is not reachable, use a reinitialized flowInfo and enter a fake reachable
0682:                            // branch, since the previous initializer already got the blame.
0683:                            if (staticFieldInfo == FlowInfo.DEAD_END) {
0684:                                this .staticInitializerScope.problemReporter()
0685:                                        .initializerMustCompleteNormally(field);
0686:                                staticFieldInfo = FlowInfo.initial(
0687:                                        this .maxFieldCount).setReachMode(
0688:                                        FlowInfo.UNREACHABLE);
0689:                            }
0690:                        } else {
0691:                            if ((nonStaticFieldInfo.tagBits & FlowInfo.UNREACHABLE) != 0)
0692:                                field.bits &= ~ASTNode.IsReachable;
0693:
0694:                            /*if (field.isField()){
0695:                            	initializerContext.handledExceptions = NoExceptions; // no exception is allowed jls8.3.2
0696:                            } else {*/
0697:                            initializerContext.handledExceptions = Binding.ANY_EXCEPTION; // tolerate them all, and record them
0698:                            /*}*/
0699:                            nonStaticFieldInfo = field.analyseCode(
0700:                                    this .initializerScope, initializerContext,
0701:                                    nonStaticFieldInfo);
0702:                            // in case the initializer is not reachable, use a reinitialized flowInfo and enter a fake reachable
0703:                            // branch, since the previous initializer already got the blame.
0704:                            if (nonStaticFieldInfo == FlowInfo.DEAD_END) {
0705:                                this .initializerScope.problemReporter()
0706:                                        .initializerMustCompleteNormally(field);
0707:                                nonStaticFieldInfo = FlowInfo.initial(
0708:                                        this .maxFieldCount).setReachMode(
0709:                                        FlowInfo.UNREACHABLE);
0710:                            }
0711:                        }
0712:                    }
0713:                }
0714:                if (this .memberTypes != null) {
0715:                    for (int i = 0, count = this .memberTypes.length; i < count; i++) {
0716:                        if (flowContext != null) { // local type
0717:                            this .memberTypes[i]
0718:                                    .analyseCode(
0719:                                            this .scope,
0720:                                            flowContext,
0721:                                            nonStaticFieldInfo
0722:                                                    .copy()
0723:                                                    .setReachMode(
0724:                                                            flowInfo
0725:                                                                    .reachMode())); // reset reach mode in case initializers did abrupt completely
0726:                        } else {
0727:                            this .memberTypes[i].analyseCode(this .scope);
0728:                        }
0729:                    }
0730:                }
0731:                if (this .methods != null) {
0732:                    UnconditionalFlowInfo outerInfo = flowInfo
0733:                            .unconditionalFieldLessCopy();
0734:                    FlowInfo constructorInfo = nonStaticFieldInfo
0735:                            .unconditionalInits()
0736:                            .discardNonFieldInitializations()
0737:                            .addInitializationsFrom(outerInfo);
0738:                    for (int i = 0, count = this .methods.length; i < count; i++) {
0739:                        AbstractMethodDeclaration method = this .methods[i];
0740:                        if (method.ignoreFurtherInvestigation)
0741:                            continue;
0742:                        if (method.isInitializationMethod()) {
0743:                            if (method.isStatic()) { // <clinit>
0744:                                method
0745:                                        .analyseCode(
0746:                                                this .scope,
0747:                                                staticInitializerContext,
0748:                                                staticFieldInfo
0749:                                                        .unconditionalInits()
0750:                                                        .discardNonFieldInitializations()
0751:                                                        .addInitializationsFrom(
0752:                                                                outerInfo));
0753:                            } else { // constructor
0754:                                ((ConstructorDeclaration) method).analyseCode(
0755:                                        this .scope, initializerContext,
0756:                                        constructorInfo.copy(), flowInfo
0757:                                                .reachMode());
0758:                            }
0759:                        } else { // regular method
0760:                            method.analyseCode(this .scope, null, flowInfo
0761:                                    .copy());
0762:                        }
0763:                    }
0764:                }
0765:                // enable enum support ?
0766:                if (this .binding.isEnum() && !this .binding.isAnonymousType()) {
0767:                    this .enumValuesSyntheticfield = this .binding
0768:                            .addSyntheticFieldForEnumValues();
0769:                }
0770:            }
0771:
0772:            public final static int kind(int flags) {
0773:                switch (flags
0774:                        & (ClassFileConstants.AccInterface
0775:                                | ClassFileConstants.AccAnnotation | ClassFileConstants.AccEnum)) {
0776:                case ClassFileConstants.AccInterface:
0777:                    return TypeDeclaration.INTERFACE_DECL;
0778:                case ClassFileConstants.AccInterface
0779:                        | ClassFileConstants.AccAnnotation:
0780:                    return TypeDeclaration.ANNOTATION_TYPE_DECL;
0781:                case ClassFileConstants.AccEnum:
0782:                    return TypeDeclaration.ENUM_DECL;
0783:                default:
0784:                    return TypeDeclaration.CLASS_DECL;
0785:                }
0786:            }
0787:
0788:            /* 
0789:             * Access emulation for a local type
0790:             * force to emulation of access to direct enclosing instance.
0791:             * By using the initializer scope, we actually only request an argument emulation, the
0792:             * field is not added until actually used. However we will force allocations to be qualified
0793:             * with an enclosing instance.
0794:             * 15.9.2
0795:             */
0796:            public void manageEnclosingInstanceAccessIfNecessary(
0797:                    BlockScope currentScope, FlowInfo flowInfo) {
0798:                if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0)
0799:                    return;
0800:                NestedTypeBinding nestedType = (NestedTypeBinding) this .binding;
0801:
0802:                MethodScope methodScope = currentScope.methodScope();
0803:                if (!methodScope.isStatic && !methodScope.isConstructorCall) {
0804:                    nestedType.addSyntheticArgumentAndField(nestedType
0805:                            .enclosingType());
0806:                }
0807:                // add superclass enclosing instance arg for anonymous types (if necessary)
0808:                if (nestedType.isAnonymousType()) {
0809:                    ReferenceBinding super classBinding = (ReferenceBinding) nestedType.super class
0810:                            .erasure();
0811:                    if (super classBinding.enclosingType() != null
0812:                            && !super classBinding.isStatic()) {
0813:                        if (!super classBinding.isLocalType()
0814:                                || ((NestedTypeBinding) super classBinding)
0815:                                        .getSyntheticField(super classBinding
0816:                                                .enclosingType(), true) != null) {
0817:
0818:                            nestedType.addSyntheticArgument(super classBinding
0819:                                    .enclosingType());
0820:                        }
0821:                    }
0822:                    // From 1.5 on, provide access to enclosing instance synthetic constructor argument when declared inside constructor call
0823:                    // only for direct anonymous type
0824:                    //public class X {
0825:                    //	void foo() {}
0826:                    //	class M {
0827:                    //		M(Object o) {}
0828:                    //		M() { this(new Object() { void baz() { foo(); }}); } // access to #foo() indirects through constructor synthetic arg: val$this$0
0829:                    //	}
0830:                    //}
0831:                    if (!methodScope.isStatic
0832:                            && methodScope.isConstructorCall
0833:                            && currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_5) {
0834:                        ReferenceBinding enclosing = nestedType.enclosingType();
0835:                        if (enclosing.isNestedType()) {
0836:                            NestedTypeBinding nestedEnclosing = (NestedTypeBinding) enclosing;
0837:                            //					if (nestedEnclosing.findSuperTypeErasingTo(nestedEnclosing.enclosingType()) == null) { // only if not inheriting
0838:                            SyntheticArgumentBinding syntheticEnclosingInstanceArgument = nestedEnclosing
0839:                                    .getSyntheticArgument(nestedEnclosing
0840:                                            .enclosingType(), true);
0841:                            if (syntheticEnclosingInstanceArgument != null) {
0842:                                nestedType
0843:                                        .addSyntheticArgumentAndField(syntheticEnclosingInstanceArgument);
0844:                            }
0845:                        }
0846:                        //				}
0847:                    }
0848:                }
0849:            }
0850:
0851:            /**
0852:             * Access emulation for a local member type
0853:             * force to emulation of access to direct enclosing instance.
0854:             * By using the initializer scope, we actually only request an argument emulation, the
0855:             * field is not added until actually used. However we will force allocations to be qualified
0856:             * with an enclosing instance.
0857:             * 
0858:             * Local member cannot be static.
0859:             */
0860:            public void manageEnclosingInstanceAccessIfNecessary(
0861:                    ClassScope currentScope, FlowInfo flowInfo) {
0862:                if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
0863:                    NestedTypeBinding nestedType = (NestedTypeBinding) this .binding;
0864:                    nestedType.addSyntheticArgumentAndField(this .binding
0865:                            .enclosingType());
0866:                }
0867:            }
0868:
0869:            /**
0870:             * A <clinit> will be requested as soon as static fields or assertions are present. It will be eliminated during
0871:             * classfile creation if no bytecode was actually produced based on some optimizations/compiler settings.
0872:             */
0873:            public final boolean needClassInitMethod() {
0874:                // always need a <clinit> when assertions are present
0875:                if ((this .bits & ASTNode.ContainsAssertion) != 0)
0876:                    return true;
0877:
0878:                switch (kind(this .modifiers)) {
0879:                case TypeDeclaration.INTERFACE_DECL:
0880:                case TypeDeclaration.ANNOTATION_TYPE_DECL:
0881:                    return this .fields != null; // fields are implicitly statics
0882:                case TypeDeclaration.ENUM_DECL:
0883:                    return true; // even if no enum constants, need to set $VALUES array
0884:                }
0885:                if (this .fields != null) {
0886:                    for (int i = this .fields.length; --i >= 0;) {
0887:                        FieldDeclaration field = this .fields[i];
0888:                        //need to test the modifier directly while there is no binding yet
0889:                        if ((field.modifiers & ClassFileConstants.AccStatic) != 0)
0890:                            return true; // TODO (philippe) shouldn't it check whether field is initializer or has some initial value ?
0891:                    }
0892:                }
0893:                return false;
0894:            }
0895:
0896:            public void parseMethod(Parser parser,
0897:                    CompilationUnitDeclaration unit) {
0898:                //connect method bodies
0899:                if (unit.ignoreMethodBodies)
0900:                    return;
0901:
0902:                //members
0903:                if (this .memberTypes != null) {
0904:                    int length = this .memberTypes.length;
0905:                    for (int i = 0; i < length; i++)
0906:                        this .memberTypes[i].parseMethod(parser, unit);
0907:                }
0908:
0909:                //methods
0910:                if (this .methods != null) {
0911:                    int length = this .methods.length;
0912:                    for (int i = 0; i < length; i++) {
0913:                        this .methods[i].parseStatements(parser, unit);
0914:                    }
0915:                }
0916:
0917:                //initializers
0918:                if (this .fields != null) {
0919:                    int length = this .fields.length;
0920:                    for (int i = 0; i < length; i++) {
0921:                        final FieldDeclaration fieldDeclaration = this .fields[i];
0922:                        switch (fieldDeclaration.getKind()) {
0923:                        case AbstractVariableDeclaration.INITIALIZER:
0924:                            ((Initializer) fieldDeclaration).parseStatements(
0925:                                    parser, this , unit);
0926:                            break;
0927:                        }
0928:                    }
0929:                }
0930:            }
0931:
0932:            public StringBuffer print(int indent, StringBuffer output) {
0933:                if (this .javadoc != null) {
0934:                    this .javadoc.print(indent, output);
0935:                }
0936:                if ((this .bits & ASTNode.IsAnonymousType) == 0) {
0937:                    printIndent(indent, output);
0938:                    printHeader(0, output);
0939:                }
0940:                return printBody(indent, output);
0941:            }
0942:
0943:            public StringBuffer printBody(int indent, StringBuffer output) {
0944:                output.append(" {"); //$NON-NLS-1$
0945:                if (this .memberTypes != null) {
0946:                    for (int i = 0; i < this .memberTypes.length; i++) {
0947:                        if (this .memberTypes[i] != null) {
0948:                            output.append('\n');
0949:                            this .memberTypes[i].print(indent + 1, output);
0950:                        }
0951:                    }
0952:                }
0953:                if (this .fields != null) {
0954:                    for (int fieldI = 0; fieldI < this .fields.length; fieldI++) {
0955:                        if (this .fields[fieldI] != null) {
0956:                            output.append('\n');
0957:                            this .fields[fieldI].print(indent + 1, output);
0958:                        }
0959:                    }
0960:                }
0961:                if (this .methods != null) {
0962:                    for (int i = 0; i < this .methods.length; i++) {
0963:                        if (this .methods[i] != null) {
0964:                            output.append('\n');
0965:                            this .methods[i].print(indent + 1, output);
0966:                        }
0967:                    }
0968:                }
0969:                output.append('\n');
0970:                return printIndent(indent, output).append('}');
0971:            }
0972:
0973:            public StringBuffer printHeader(int indent, StringBuffer output) {
0974:                printModifiers(this .modifiers, output);
0975:                if (this .annotations != null)
0976:                    printAnnotations(this .annotations, output);
0977:
0978:                switch (kind(this .modifiers)) {
0979:                case TypeDeclaration.CLASS_DECL:
0980:                    output.append("class "); //$NON-NLS-1$
0981:                    break;
0982:                case TypeDeclaration.INTERFACE_DECL:
0983:                    output.append("interface "); //$NON-NLS-1$
0984:                    break;
0985:                case TypeDeclaration.ENUM_DECL:
0986:                    output.append("enum "); //$NON-NLS-1$
0987:                    break;
0988:                case TypeDeclaration.ANNOTATION_TYPE_DECL:
0989:                    output.append("@interface "); //$NON-NLS-1$
0990:                    break;
0991:                }
0992:                output.append(this .name);
0993:                if (this .typeParameters != null) {
0994:                    output.append("<");//$NON-NLS-1$
0995:                    for (int i = 0; i < this .typeParameters.length; i++) {
0996:                        if (i > 0)
0997:                            output.append(", "); //$NON-NLS-1$
0998:                        this .typeParameters[i].print(0, output);
0999:                    }
1000:                    output.append(">");//$NON-NLS-1$
1001:                }
1002:                if (this .super class != null) {
1003:                    output.append(" extends "); //$NON-NLS-1$
1004:                    this .super class.print(0, output);
1005:                }
1006:                if (this .super Interfaces != null
1007:                        && this .super Interfaces.length > 0) {
1008:                    switch (kind(this .modifiers)) {
1009:                    case TypeDeclaration.CLASS_DECL:
1010:                    case TypeDeclaration.ENUM_DECL:
1011:                        output.append(" implements "); //$NON-NLS-1$
1012:                        break;
1013:                    case TypeDeclaration.INTERFACE_DECL:
1014:                    case TypeDeclaration.ANNOTATION_TYPE_DECL:
1015:                        output.append(" extends "); //$NON-NLS-1$
1016:                        break;
1017:                    }
1018:                    for (int i = 0; i < this .super Interfaces.length; i++) {
1019:                        if (i > 0)
1020:                            output.append(", "); //$NON-NLS-1$
1021:                        this .super Interfaces[i].print(0, output);
1022:                    }
1023:                }
1024:                return output;
1025:            }
1026:
1027:            public StringBuffer printStatement(int tab, StringBuffer output) {
1028:                return print(tab, output);
1029:            }
1030:
1031:            public void resolve() {
1032:                SourceTypeBinding sourceType = this .binding;
1033:                if (sourceType == null) {
1034:                    this .ignoreFurtherInvestigation = true;
1035:                    return;
1036:                }
1037:                try {
1038:                    boolean old = this .staticInitializerScope.insideTypeAnnotation;
1039:                    try {
1040:                        this .staticInitializerScope.insideTypeAnnotation = true;
1041:                        resolveAnnotations(this .staticInitializerScope,
1042:                                this .annotations, sourceType);
1043:                    } finally {
1044:                        this .staticInitializerScope.insideTypeAnnotation = old;
1045:                    }
1046:                    // check @Deprecated annotation
1047:                    if ((sourceType.getAnnotationTagBits() & TagBits.AnnotationDeprecated) == 0
1048:                            && (sourceType.modifiers & ClassFileConstants.AccDeprecated) != 0
1049:                            && this .scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
1050:                        this .scope.problemReporter()
1051:                                .missingDeprecatedAnnotationForType(this );
1052:                    }
1053:                    if ((this .bits & ASTNode.UndocumentedEmptyBlock) != 0) {
1054:                        this .scope.problemReporter().undocumentedEmptyBlock(
1055:                                this .bodyStart - 1, this .bodyEnd);
1056:                    }
1057:                    boolean needSerialVersion = this .scope.compilerOptions()
1058:                            .getSeverity(CompilerOptions.MissingSerialVersion) != ProblemSeverities.Ignore
1059:                            && sourceType.isClass()
1060:                            && sourceType
1061:                                    .findSuperTypeErasingTo(
1062:                                            TypeIds.T_JavaIoExternalizable,
1063:                                            false /*Serializable is not a class*/) == null
1064:                            && sourceType
1065:                                    .findSuperTypeErasingTo(
1066:                                            TypeIds.T_JavaIoSerializable, false /*Serializable is not a class*/) != null;
1067:
1068:                    if (needSerialVersion) {
1069:                        // if Object writeReplace() throws java.io.ObjectStreamException is present, then no serialVersionUID is needed
1070:                        // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=101476
1071:                        CompilationUnitScope compilationUnitScope = this .scope
1072:                                .compilationUnitScope();
1073:                        MethodBinding methodBinding = sourceType
1074:                                .getExactMethod(TypeConstants.WRITEREPLACE,
1075:                                        new TypeBinding[0],
1076:                                        compilationUnitScope);
1077:                        ReferenceBinding[] throwsExceptions;
1078:                        needSerialVersion = methodBinding == null
1079:                                || !methodBinding.isValidBinding()
1080:                                || methodBinding.returnType.id != TypeIds.T_JavaLangObject
1081:                                || (throwsExceptions = methodBinding.thrownExceptions).length != 1
1082:                                || throwsExceptions[0].id != TypeIds.T_JavaIoObjectStreamException;
1083:                        if (needSerialVersion) {
1084:                            // check the presence of an implementation of the methods
1085:                            // private void writeObject(java.io.ObjectOutputStream out) throws IOException
1086:                            // private void readObject(java.io.ObjectInputStream out) throws IOException
1087:                            boolean hasWriteObjectMethod = false;
1088:                            boolean hasReadObjectMethod = false;
1089:                            TypeBinding argumentTypeBinding = this .scope
1090:                                    .getType(
1091:                                            TypeConstants.JAVA_IO_OBJECTOUTPUTSTREAM,
1092:                                            3);
1093:                            if (argumentTypeBinding.isValidBinding()) {
1094:                                methodBinding = sourceType
1095:                                        .getExactMethod(
1096:                                                TypeConstants.WRITEOBJECT,
1097:                                                new TypeBinding[] { argumentTypeBinding },
1098:                                                compilationUnitScope);
1099:                                hasWriteObjectMethod = methodBinding != null
1100:                                        && methodBinding.isValidBinding()
1101:                                        && methodBinding.modifiers == ClassFileConstants.AccPrivate
1102:                                        && methodBinding.returnType == TypeBinding.VOID
1103:                                        && (throwsExceptions = methodBinding.thrownExceptions).length == 1
1104:                                        && throwsExceptions[0].id == TypeIds.T_JavaIoException;
1105:                            }
1106:                            argumentTypeBinding = this .scope.getType(
1107:                                    TypeConstants.JAVA_IO_OBJECTINPUTSTREAM, 3);
1108:                            if (argumentTypeBinding.isValidBinding()) {
1109:                                methodBinding = sourceType
1110:                                        .getExactMethod(
1111:                                                TypeConstants.READOBJECT,
1112:                                                new TypeBinding[] { argumentTypeBinding },
1113:                                                compilationUnitScope);
1114:                                hasReadObjectMethod = methodBinding != null
1115:                                        && methodBinding.isValidBinding()
1116:                                        && methodBinding.modifiers == ClassFileConstants.AccPrivate
1117:                                        && methodBinding.returnType == TypeBinding.VOID
1118:                                        && (throwsExceptions = methodBinding.thrownExceptions).length == 1
1119:                                        && throwsExceptions[0].id == TypeIds.T_JavaIoException;
1120:                            }
1121:                            needSerialVersion = !hasWriteObjectMethod
1122:                                    || !hasReadObjectMethod;
1123:                        }
1124:                    }
1125:                    // generics (and non static generic members) cannot extend Throwable
1126:                    if (sourceType.findSuperTypeErasingTo(
1127:                            TypeIds.T_JavaLangThrowable, true) != null) {
1128:                        ReferenceBinding current = sourceType;
1129:                        checkEnclosedInGeneric: do {
1130:                            if (current.isGenericType()) {
1131:                                this .scope.problemReporter()
1132:                                        .genericTypeCannotExtendThrowable(this );
1133:                                break checkEnclosedInGeneric;
1134:                            }
1135:                            if (current.isStatic())
1136:                                break checkEnclosedInGeneric;
1137:                            if (current.isLocalType()) {
1138:                                NestedTypeBinding nestedType = (NestedTypeBinding) current
1139:                                        .erasure();
1140:                                if (nestedType.scope.methodScope().isStatic)
1141:                                    break checkEnclosedInGeneric;
1142:                            }
1143:                        } while ((current = current.enclosingType()) != null);
1144:                    }
1145:                    this .maxFieldCount = 0;
1146:                    int lastVisibleFieldID = -1;
1147:                    boolean hasEnumConstants = false;
1148:                    boolean hasEnumConstantsWithoutBody = false;
1149:
1150:                    if (this .typeParameters != null) {
1151:                        for (int i = 0, count = this .typeParameters.length; i < count; i++) {
1152:                            this .typeParameters[i].resolve(this .scope);
1153:                        }
1154:                    }
1155:                    if (this .memberTypes != null) {
1156:                        for (int i = 0, count = this .memberTypes.length; i < count; i++) {
1157:                            this .memberTypes[i].resolve(this .scope);
1158:                        }
1159:                    }
1160:                    if (this .fields != null) {
1161:                        for (int i = 0, count = this .fields.length; i < count; i++) {
1162:                            FieldDeclaration field = this .fields[i];
1163:                            switch (field.getKind()) {
1164:                            case AbstractVariableDeclaration.ENUM_CONSTANT:
1165:                                hasEnumConstants = true;
1166:                                if (!(field.initialization instanceof  QualifiedAllocationExpression))
1167:                                    hasEnumConstantsWithoutBody = true;
1168:                            case AbstractVariableDeclaration.FIELD:
1169:                                FieldBinding fieldBinding = field.binding;
1170:                                if (fieldBinding == null) {
1171:                                    // still discover secondary errors
1172:                                    if (field.initialization != null)
1173:                                        field.initialization
1174:                                                .resolve(field.isStatic() ? this .staticInitializerScope
1175:                                                        : this .initializerScope);
1176:                                    this .ignoreFurtherInvestigation = true;
1177:                                    continue;
1178:                                }
1179:                                if (needSerialVersion
1180:                                        && ((fieldBinding.modifiers & (ClassFileConstants.AccStatic | ClassFileConstants.AccFinal)) == (ClassFileConstants.AccStatic | ClassFileConstants.AccFinal))
1181:                                        && CharOperation.equals(
1182:                                                TypeConstants.SERIALVERSIONUID,
1183:                                                fieldBinding.name)
1184:                                        && TypeBinding.LONG == fieldBinding.type) {
1185:                                    needSerialVersion = false;
1186:                                }
1187:                                this .maxFieldCount++;
1188:                                lastVisibleFieldID = field.binding.id;
1189:                                break;
1190:
1191:                            case AbstractVariableDeclaration.INITIALIZER:
1192:                                ((Initializer) field).lastVisibleFieldID = lastVisibleFieldID + 1;
1193:                                break;
1194:                            }
1195:                            field
1196:                                    .resolve(field.isStatic() ? this .staticInitializerScope
1197:                                            : this .initializerScope);
1198:                        }
1199:                    }
1200:                    if (needSerialVersion) {
1201:                        this .scope.problemReporter().missingSerialVersion(this );
1202:                    }
1203:                    // check extends/implements for annotation type
1204:                    switch (kind(this .modifiers)) {
1205:                    case TypeDeclaration.ANNOTATION_TYPE_DECL:
1206:                        if (this .super class != null) {
1207:                            this .scope
1208:                                    .problemReporter()
1209:                                    .annotationTypeDeclarationCannotHaveSuperclass(
1210:                                            this );
1211:                        }
1212:                        if (this .super Interfaces != null) {
1213:                            this .scope
1214:                                    .problemReporter()
1215:                                    .annotationTypeDeclarationCannotHaveSuperinterfaces(
1216:                                            this );
1217:                        }
1218:                        break;
1219:                    case TypeDeclaration.ENUM_DECL:
1220:                        // check enum abstract methods
1221:                        if (this .binding.isAbstract()) {
1222:                            if (!hasEnumConstants
1223:                                    || hasEnumConstantsWithoutBody) {
1224:                                for (int i = 0, count = this .methods.length; i < count; i++) {
1225:                                    final AbstractMethodDeclaration methodDeclaration = this .methods[i];
1226:                                    if (methodDeclaration.isAbstract()
1227:                                            && methodDeclaration.binding != null) {
1228:                                        this .scope
1229:                                                .problemReporter()
1230:                                                .enumAbstractMethodMustBeImplemented(
1231:                                                        methodDeclaration);
1232:                                    }
1233:                                }
1234:                            }
1235:                        }
1236:                        break;
1237:                    }
1238:
1239:                    int missingAbstractMethodslength = this .missingAbstractMethods == null ? 0
1240:                            : this .missingAbstractMethods.length;
1241:                    int methodsLength = this .methods == null ? 0
1242:                            : this .methods.length;
1243:                    if ((methodsLength + missingAbstractMethodslength) > 0xFFFF) {
1244:                        this .scope.problemReporter().tooManyMethods(this );
1245:                    }
1246:                    if (this .methods != null) {
1247:                        for (int i = 0, count = this .methods.length; i < count; i++) {
1248:                            this .methods[i].resolve(this .scope);
1249:                        }
1250:                    }
1251:                    // Resolve javadoc
1252:                    if (this .javadoc != null) {
1253:                        if (this .scope != null
1254:                                && (this .name != TypeConstants.PACKAGE_INFO_NAME)) {
1255:                            // if the type is package-info, the javadoc was resolved as part of the compilation unit javadoc
1256:                            this .javadoc.resolve(this .scope);
1257:                        }
1258:                    } else if (sourceType != null && !sourceType.isLocalType()) {
1259:                        this .scope.problemReporter().javadocMissing(
1260:                                this .sourceStart, this .sourceEnd,
1261:                                sourceType.modifiers);
1262:                    }
1263:
1264:                } catch (AbortType e) {
1265:                    this .ignoreFurtherInvestigation = true;
1266:                    return;
1267:                }
1268:            }
1269:
1270:            /**
1271:             * Resolve a local type declaration
1272:             */
1273:            public void resolve(BlockScope blockScope) {
1274:
1275:                // need to build its scope first and proceed with binding's creation
1276:                if ((this .bits & ASTNode.IsAnonymousType) == 0) {
1277:                    // check collision scenarii
1278:                    Binding existing = blockScope.getType(this .name);
1279:                    if (existing instanceof  ReferenceBinding
1280:                            && existing != this .binding
1281:                            && existing.isValidBinding()) {
1282:                        ReferenceBinding existingType = (ReferenceBinding) existing;
1283:                        if (existingType instanceof  TypeVariableBinding) {
1284:                            blockScope.problemReporter().typeHiding(this ,
1285:                                    (TypeVariableBinding) existingType);
1286:                        } else if (existingType instanceof  LocalTypeBinding
1287:                                && ((LocalTypeBinding) existingType).scope
1288:                                        .methodScope() == blockScope
1289:                                        .methodScope()) {
1290:                            // dup in same method
1291:                            blockScope.problemReporter().duplicateNestedType(
1292:                                    this );
1293:                        } else if (blockScope.isDefinedInType(existingType)) {
1294:                            //	collision with enclosing type
1295:                            blockScope.problemReporter()
1296:                                    .typeCollidesWithEnclosingType(this );
1297:                        } else if (blockScope.isDefinedInSameUnit(existingType)) { // only consider hiding inside same unit
1298:                            // hiding sibling
1299:                            blockScope.problemReporter().typeHiding(this ,
1300:                                    existingType);
1301:                        }
1302:                    }
1303:                    blockScope.addLocalType(this );
1304:                }
1305:
1306:                if (this .binding != null) {
1307:                    // remember local types binding for innerclass emulation propagation
1308:                    blockScope.referenceCompilationUnit().record(
1309:                            (LocalTypeBinding) this .binding);
1310:
1311:                    // binding is not set if the receiver could not be created
1312:                    resolve();
1313:                    updateMaxFieldCount();
1314:                }
1315:            }
1316:
1317:            /**
1318:             * Resolve a member type declaration (can be a local member)
1319:             */
1320:            public void resolve(ClassScope upperScope) {
1321:                // member scopes are already created
1322:                // request the construction of a binding if local member type
1323:
1324:                if (this .binding != null
1325:                        && this .binding instanceof  LocalTypeBinding) {
1326:                    // remember local types binding for innerclass emulation propagation
1327:                    upperScope.referenceCompilationUnit().record(
1328:                            (LocalTypeBinding) this .binding);
1329:                }
1330:                resolve();
1331:                updateMaxFieldCount();
1332:            }
1333:
1334:            /**
1335:             * Resolve a top level type declaration
1336:             */
1337:            public void resolve(CompilationUnitScope upperScope) {
1338:                // top level : scope are already created
1339:                resolve();
1340:                updateMaxFieldCount();
1341:            }
1342:
1343:            public void tagAsHavingErrors() {
1344:                this .ignoreFurtherInvestigation = true;
1345:            }
1346:
1347:            /**
1348:             *	Iteration for a package member type
1349:             *
1350:             */
1351:            public void traverse(ASTVisitor visitor,
1352:                    CompilationUnitScope unitScope) {
1353:
1354:                if (this .ignoreFurtherInvestigation)
1355:                    return;
1356:                try {
1357:                    if (visitor.visit(this , unitScope)) {
1358:                        if (this .javadoc != null) {
1359:                            this .javadoc.traverse(visitor, this .scope);
1360:                        }
1361:                        if (this .annotations != null) {
1362:                            int annotationsLength = this .annotations.length;
1363:                            for (int i = 0; i < annotationsLength; i++)
1364:                                this .annotations[i].traverse(visitor,
1365:                                        this .staticInitializerScope);
1366:                        }
1367:                        if (this .super class != null)
1368:                            this .super class.traverse(visitor, this .scope);
1369:                        if (this .super Interfaces != null) {
1370:                            int length = this .super Interfaces.length;
1371:                            for (int i = 0; i < length; i++)
1372:                                this .super Interfaces[i].traverse(visitor,
1373:                                        this .scope);
1374:                        }
1375:                        if (this .typeParameters != null) {
1376:                            int length = this .typeParameters.length;
1377:                            for (int i = 0; i < length; i++) {
1378:                                this .typeParameters[i].traverse(visitor,
1379:                                        this .scope);
1380:                            }
1381:                        }
1382:                        if (this .memberTypes != null) {
1383:                            int length = this .memberTypes.length;
1384:                            for (int i = 0; i < length; i++)
1385:                                this .memberTypes[i].traverse(visitor,
1386:                                        this .scope);
1387:                        }
1388:                        if (this .fields != null) {
1389:                            int length = this .fields.length;
1390:                            for (int i = 0; i < length; i++) {
1391:                                FieldDeclaration field;
1392:                                if ((field = this .fields[i]).isStatic()) {
1393:                                    field.traverse(visitor,
1394:                                            this .staticInitializerScope);
1395:                                } else {
1396:                                    field.traverse(visitor,
1397:                                            this .initializerScope);
1398:                                }
1399:                            }
1400:                        }
1401:                        if (this .methods != null) {
1402:                            int length = this .methods.length;
1403:                            for (int i = 0; i < length; i++)
1404:                                this .methods[i].traverse(visitor, this .scope);
1405:                        }
1406:                    }
1407:                    visitor.endVisit(this , unitScope);
1408:                } catch (AbortType e) {
1409:                    // silent abort
1410:                }
1411:            }
1412:
1413:            /**
1414:             *	Iteration for a local innertype
1415:             */
1416:            public void traverse(ASTVisitor visitor, BlockScope blockScope) {
1417:                if (this .ignoreFurtherInvestigation)
1418:                    return;
1419:                try {
1420:                    if (visitor.visit(this , blockScope)) {
1421:                        if (this .javadoc != null) {
1422:                            this .javadoc.traverse(visitor, this .scope);
1423:                        }
1424:                        if (this .annotations != null) {
1425:                            int annotationsLength = this .annotations.length;
1426:                            for (int i = 0; i < annotationsLength; i++)
1427:                                this .annotations[i].traverse(visitor,
1428:                                        this .staticInitializerScope);
1429:                        }
1430:                        if (this .super class != null)
1431:                            this .super class.traverse(visitor, this .scope);
1432:                        if (this .super Interfaces != null) {
1433:                            int length = this .super Interfaces.length;
1434:                            for (int i = 0; i < length; i++)
1435:                                this .super Interfaces[i].traverse(visitor,
1436:                                        this .scope);
1437:                        }
1438:                        if (this .typeParameters != null) {
1439:                            int length = this .typeParameters.length;
1440:                            for (int i = 0; i < length; i++) {
1441:                                this .typeParameters[i].traverse(visitor,
1442:                                        this .scope);
1443:                            }
1444:                        }
1445:                        if (this .memberTypes != null) {
1446:                            int length = this .memberTypes.length;
1447:                            for (int i = 0; i < length; i++)
1448:                                this .memberTypes[i].traverse(visitor,
1449:                                        this .scope);
1450:                        }
1451:                        if (this .fields != null) {
1452:                            int length = this .fields.length;
1453:                            for (int i = 0; i < length; i++) {
1454:                                FieldDeclaration field;
1455:                                if ((field = this .fields[i]).isStatic()) {
1456:                                    // local type cannot have static fields
1457:                                } else {
1458:                                    field.traverse(visitor,
1459:                                            this .initializerScope);
1460:                                }
1461:                            }
1462:                        }
1463:                        if (this .methods != null) {
1464:                            int length = this .methods.length;
1465:                            for (int i = 0; i < length; i++)
1466:                                this .methods[i].traverse(visitor, this .scope);
1467:                        }
1468:                    }
1469:                    visitor.endVisit(this , blockScope);
1470:                } catch (AbortType e) {
1471:                    // silent abort
1472:                }
1473:            }
1474:
1475:            /**
1476:             *	Iteration for a member innertype
1477:             *
1478:             */
1479:            public void traverse(ASTVisitor visitor, ClassScope classScope) {
1480:                if (this .ignoreFurtherInvestigation)
1481:                    return;
1482:                try {
1483:                    if (visitor.visit(this , classScope)) {
1484:                        if (this .javadoc != null) {
1485:                            this .javadoc.traverse(visitor, scope);
1486:                        }
1487:                        if (this .annotations != null) {
1488:                            int annotationsLength = this .annotations.length;
1489:                            for (int i = 0; i < annotationsLength; i++)
1490:                                this .annotations[i].traverse(visitor,
1491:                                        this .staticInitializerScope);
1492:                        }
1493:                        if (this .super class != null)
1494:                            this .super class.traverse(visitor, this .scope);
1495:                        if (this .super Interfaces != null) {
1496:                            int length = this .super Interfaces.length;
1497:                            for (int i = 0; i < length; i++)
1498:                                this .super Interfaces[i].traverse(visitor,
1499:                                        this .scope);
1500:                        }
1501:                        if (this .typeParameters != null) {
1502:                            int length = this .typeParameters.length;
1503:                            for (int i = 0; i < length; i++) {
1504:                                this .typeParameters[i].traverse(visitor,
1505:                                        this .scope);
1506:                            }
1507:                        }
1508:                        if (this .memberTypes != null) {
1509:                            int length = this .memberTypes.length;
1510:                            for (int i = 0; i < length; i++)
1511:                                this .memberTypes[i].traverse(visitor,
1512:                                        this .scope);
1513:                        }
1514:                        if (this .fields != null) {
1515:                            int length = this .fields.length;
1516:                            for (int i = 0; i < length; i++) {
1517:                                FieldDeclaration field;
1518:                                if ((field = this .fields[i]).isStatic()) {
1519:                                    field.traverse(visitor,
1520:                                            this .staticInitializerScope);
1521:                                } else {
1522:                                    field.traverse(visitor,
1523:                                            this .initializerScope);
1524:                                }
1525:                            }
1526:                        }
1527:                        if (this .methods != null) {
1528:                            int length = this .methods.length;
1529:                            for (int i = 0; i < length; i++)
1530:                                this .methods[i].traverse(visitor, this .scope);
1531:                        }
1532:                    }
1533:                    visitor.endVisit(this , classScope);
1534:                } catch (AbortType e) {
1535:                    // silent abort
1536:                }
1537:            }
1538:
1539:            /**
1540:             * MaxFieldCount's computation is necessary so as to reserve space for
1541:             * the flow info field portions. It corresponds to the maximum amount of
1542:             * fields this class or one of its innertypes have.
1543:             *
1544:             * During name resolution, types are traversed, and the max field count is recorded
1545:             * on the outermost type. It is then propagated down during the flow analysis.
1546:             *
1547:             * This method is doing either up/down propagation.
1548:             */
1549:            void updateMaxFieldCount() {
1550:                if (this .binding == null)
1551:                    return; // error scenario
1552:                TypeDeclaration outerMostType = this .scope
1553:                        .outerMostClassScope().referenceType();
1554:                if (this .maxFieldCount > outerMostType.maxFieldCount) {
1555:                    outerMostType.maxFieldCount = this .maxFieldCount; // up
1556:                } else {
1557:                    this .maxFieldCount = outerMostType.maxFieldCount; // down
1558:                }
1559:            }
1560:
1561:            /**
1562:             * Returns whether the type is a secondary one or not.
1563:             */
1564:            public boolean isSecondary() {
1565:                return (this .bits & ASTNode.IsSecondaryType) != 0;
1566:            }
1567:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.