Source Code Cross Referenced for LookupEnvironment.java in  » IDE-Eclipse » jdt » org » eclipse » jdt » internal » compiler » lookup » 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.lookup 
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.lookup;
0011:
0012:        import java.util.HashMap;
0013:        import java.util.Map;
0014:
0015:        import org.eclipse.jdt.core.compiler.CharOperation;
0016:        import org.eclipse.jdt.internal.compiler.ClassFilePool;
0017:        import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
0018:        import org.eclipse.jdt.internal.compiler.ast.Wildcard;
0019:        import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
0020:        import org.eclipse.jdt.internal.compiler.env.*;
0021:        import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
0022:        import org.eclipse.jdt.internal.compiler.impl.ITypeRequestor;
0023:        import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
0024:        import org.eclipse.jdt.internal.compiler.util.HashtableOfPackage;
0025:        import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
0026:
0027:        public class LookupEnvironment implements  ProblemReasons, TypeConstants {
0028:
0029:            final static int BUILD_FIELDS_AND_METHODS = 4;
0030:            final static int BUILD_TYPE_HIERARCHY = 1;
0031:            final static int CHECK_AND_SET_IMPORTS = 2;
0032:            final static int CONNECT_TYPE_HIERARCHY = 3;
0033:            static final ProblemPackageBinding TheNotFoundPackage = new ProblemPackageBinding(
0034:                    CharOperation.NO_CHAR, NotFound);
0035:            static final ProblemReferenceBinding TheNotFoundType = new ProblemReferenceBinding(
0036:                    CharOperation.NO_CHAR, null, NotFound);
0037:
0038:            /**
0039:             * Map from typeBinding -> accessRestriction rule
0040:             */
0041:            private Map accessRestrictions;
0042:            ImportBinding[] defaultImports;
0043:
0044:            public PackageBinding defaultPackage;
0045:            HashtableOfPackage knownPackages;
0046:            private int lastCompletedUnitIndex = -1;
0047:            private int lastUnitIndex = -1;
0048:
0049:            public INameEnvironment nameEnvironment;
0050:            public CompilerOptions globalOptions;
0051:            public ProblemReporter problemReporter;
0052:
0053:            public ClassFilePool classFilePool;
0054:
0055:            // indicate in which step on the compilation we are.
0056:            // step 1 : build the reference binding
0057:            // step 2 : conect the hierarchy (connect bindings)
0058:            // step 3 : build fields and method bindings.
0059:            private int stepCompleted;
0060:            public ITypeRequestor typeRequestor;
0061:            private ArrayBinding[][] uniqueArrayBindings;
0062:            private SimpleLookupTable uniqueParameterizedTypeBindings;
0063:            private SimpleLookupTable uniqueRawTypeBindings;
0064:            private SimpleLookupTable uniqueWildcardBindings;
0065:            private SimpleLookupTable uniqueParameterizedGenericMethodBindings;
0066:
0067:            public CompilationUnitDeclaration unitBeingCompleted = null; // only set while completing units
0068:            public Object missingClassFileLocation = null; // only set when resolving certain references, to help locating problems
0069:
0070:            private CompilationUnitDeclaration[] units = new CompilationUnitDeclaration[4];
0071:            private MethodVerifier verifier;
0072:
0073:            public LookupEnvironment(ITypeRequestor typeRequestor,
0074:                    CompilerOptions globalOptions,
0075:                    ProblemReporter problemReporter,
0076:                    INameEnvironment nameEnvironment) {
0077:                this .typeRequestor = typeRequestor;
0078:                this .globalOptions = globalOptions;
0079:                this .problemReporter = problemReporter;
0080:                this .defaultPackage = new PackageBinding(this ); // assume the default package always exists
0081:                this .defaultImports = null;
0082:                this .nameEnvironment = nameEnvironment;
0083:                this .knownPackages = new HashtableOfPackage();
0084:                this .uniqueArrayBindings = new ArrayBinding[5][];
0085:                this .uniqueArrayBindings[0] = new ArrayBinding[50]; // start off the most common 1 dimension array @ 50
0086:                this .uniqueParameterizedTypeBindings = new SimpleLookupTable(3);
0087:                this .uniqueRawTypeBindings = new SimpleLookupTable(3);
0088:                this .uniqueWildcardBindings = new SimpleLookupTable(3);
0089:                this .uniqueParameterizedGenericMethodBindings = new SimpleLookupTable(
0090:                        3);
0091:                this .accessRestrictions = new HashMap(3);
0092:                this .classFilePool = ClassFilePool.newInstance();
0093:            }
0094:
0095:            /**
0096:             * Ask the name environment for a type which corresponds to the compoundName.
0097:             * Answer null if the name cannot be found.
0098:             */
0099:
0100:            public ReferenceBinding askForType(char[][] compoundName) {
0101:                NameEnvironmentAnswer answer = nameEnvironment
0102:                        .findType(compoundName);
0103:                if (answer == null)
0104:                    return null;
0105:
0106:                if (answer.isBinaryType())
0107:                    // the type was found as a .class file
0108:                    typeRequestor.accept(answer.getBinaryType(),
0109:                            computePackageFrom(compoundName), answer
0110:                                    .getAccessRestriction());
0111:                else if (answer.isCompilationUnit())
0112:                    // the type was found as a .java file, try to build it then search the cache
0113:                    typeRequestor.accept(answer.getCompilationUnit(), answer
0114:                            .getAccessRestriction());
0115:                else if (answer.isSourceType())
0116:                    // the type was found as a source model
0117:                    typeRequestor.accept(answer.getSourceTypes(),
0118:                            computePackageFrom(compoundName), answer
0119:                                    .getAccessRestriction());
0120:
0121:                return getCachedType(compoundName);
0122:            }
0123:
0124:            /* Ask the oracle for a type named name in the packageBinding.
0125:             * Answer null if the name cannot be found.
0126:             */
0127:
0128:            ReferenceBinding askForType(PackageBinding packageBinding,
0129:                    char[] name) {
0130:                if (packageBinding == null) {
0131:                    if (defaultPackage == null)
0132:                        return null;
0133:                    packageBinding = defaultPackage;
0134:                }
0135:                NameEnvironmentAnswer answer = nameEnvironment.findType(name,
0136:                        packageBinding.compoundName);
0137:                if (answer == null)
0138:                    return null;
0139:
0140:                if (answer.isBinaryType())
0141:                    // the type was found as a .class file
0142:                    typeRequestor.accept(answer.getBinaryType(),
0143:                            packageBinding, answer.getAccessRestriction());
0144:                else if (answer.isCompilationUnit())
0145:                    // the type was found as a .java file, try to build it then search the cache
0146:                    typeRequestor.accept(answer.getCompilationUnit(), answer
0147:                            .getAccessRestriction());
0148:                else if (answer.isSourceType())
0149:                    // the type was found as a source model
0150:                    typeRequestor.accept(answer.getSourceTypes(),
0151:                            packageBinding, answer.getAccessRestriction());
0152:
0153:                return packageBinding.getType0(name);
0154:            }
0155:
0156:            /* Create the initial type bindings for the compilation unit.
0157:             *
0158:             * See completeTypeBindings() for a description of the remaining steps
0159:             *
0160:             * NOTE: This method can be called multiple times as additional source files are needed
0161:             */
0162:
0163:            public void buildTypeBindings(CompilationUnitDeclaration unit,
0164:                    AccessRestriction accessRestriction) {
0165:                CompilationUnitScope scope = new CompilationUnitScope(unit,
0166:                        this );
0167:                scope.buildTypeBindings(accessRestriction);
0168:
0169:                int unitsLength = units.length;
0170:                if (++lastUnitIndex >= unitsLength)
0171:                    System
0172:                            .arraycopy(
0173:                                    units,
0174:                                    0,
0175:                                    units = new CompilationUnitDeclaration[2 * unitsLength],
0176:                                    0, unitsLength);
0177:                units[lastUnitIndex] = unit;
0178:            }
0179:
0180:            /* Cache the binary type since we know it is needed during this compile.
0181:             *
0182:             * Answer the created BinaryTypeBinding or null if the type is already in the cache.
0183:             */
0184:
0185:            public BinaryTypeBinding cacheBinaryType(IBinaryType binaryType,
0186:                    AccessRestriction accessRestriction) {
0187:                return cacheBinaryType(binaryType, true, accessRestriction);
0188:            }
0189:
0190:            /* Cache the binary type since we know it is needed during this compile.
0191:             *
0192:             * Answer the created BinaryTypeBinding or null if the type is already in the cache.
0193:             */
0194:
0195:            public BinaryTypeBinding cacheBinaryType(IBinaryType binaryType,
0196:                    boolean needFieldsAndMethods,
0197:                    AccessRestriction accessRestriction) {
0198:                char[][] compoundName = CharOperation.splitOn('/', binaryType
0199:                        .getName());
0200:                ReferenceBinding existingType = getCachedType(compoundName);
0201:
0202:                if (existingType == null
0203:                        || existingType instanceof  UnresolvedReferenceBinding)
0204:                    // only add the binary type if its not already in the cache
0205:                    return createBinaryTypeFrom(binaryType,
0206:                            computePackageFrom(compoundName),
0207:                            needFieldsAndMethods, accessRestriction);
0208:                return null; // the type already exists & can be retrieved from the cache
0209:            }
0210:
0211:            public BinaryTypeBinding cacheMissingBinaryType(
0212:                    char[][] compoundName, CompilationUnitDeclaration unit) {
0213:                // report the missing class file first
0214:                problemReporter.isClassPathCorrect(compoundName,
0215:                        unit == null ? this .unitBeingCompleted : unit,
0216:                        this .missingClassFileLocation);
0217:
0218:                PackageBinding packageBinding = computePackageFrom(compoundName);
0219:                // create a proxy for the missing BinaryType
0220:                MissingBinaryTypeBinding type = new MissingBinaryTypeBinding(
0221:                        packageBinding, compoundName, this );
0222:                if (type.id != TypeIds.T_JavaLangObject) {
0223:                    // make Object be its superclass - it could in turn be missing as well
0224:                    ReferenceBinding objectType = getType(TypeConstants.JAVA_LANG_OBJECT);
0225:                    if (objectType == null)
0226:                        objectType = cacheMissingBinaryType(
0227:                                TypeConstants.JAVA_LANG_OBJECT, unit); // create a proxy for the missing Object type		
0228:                    type.setMissingSuperclass(objectType);
0229:                }
0230:                packageBinding.addType(type);
0231:                return type;
0232:            }
0233:
0234:            /*
0235:             * 1. Connect the type hierarchy for the type bindings created for parsedUnits.
0236:             * 2. Create the field bindings
0237:             * 3. Create the method bindings
0238:             */
0239:
0240:            /* We know each known compilationUnit is free of errors at this point...
0241:             *
0242:             * Each step will create additional bindings unless a problem is detected, in which
0243:             * case either the faulty import/superinterface/field/method will be skipped or a
0244:             * suitable replacement will be substituted (such as Object for a missing superclass)
0245:             */
0246:
0247:            public void completeTypeBindings() {
0248:                stepCompleted = BUILD_TYPE_HIERARCHY;
0249:
0250:                for (int i = this .lastCompletedUnitIndex + 1; i <= this .lastUnitIndex; i++) {
0251:                    (this .unitBeingCompleted = this .units[i]).scope
0252:                            .checkAndSetImports();
0253:                }
0254:                stepCompleted = CHECK_AND_SET_IMPORTS;
0255:
0256:                for (int i = this .lastCompletedUnitIndex + 1; i <= this .lastUnitIndex; i++) {
0257:                    (this .unitBeingCompleted = this .units[i]).scope
0258:                            .connectTypeHierarchy();
0259:                }
0260:                stepCompleted = CONNECT_TYPE_HIERARCHY;
0261:
0262:                for (int i = this .lastCompletedUnitIndex + 1; i <= this .lastUnitIndex; i++) {
0263:                    CompilationUnitScope unitScope = (this .unitBeingCompleted = this .units[i]).scope;
0264:                    unitScope.checkParameterizedTypes();
0265:                    unitScope.buildFieldsAndMethods();
0266:                    this .units[i] = null; // release unnecessary reference to the parsed unit
0267:                }
0268:                stepCompleted = BUILD_FIELDS_AND_METHODS;
0269:                this .lastCompletedUnitIndex = this .lastUnitIndex;
0270:                this .unitBeingCompleted = null;
0271:            }
0272:
0273:            /*
0274:             * 1. Connect the type hierarchy for the type bindings created for parsedUnits.
0275:             * 2. Create the field bindings
0276:             * 3. Create the method bindings
0277:             */
0278:
0279:            /*
0280:             * Each step will create additional bindings unless a problem is detected, in which
0281:             * case either the faulty import/superinterface/field/method will be skipped or a
0282:             * suitable replacement will be substituted (such as Object for a missing superclass)
0283:             */
0284:
0285:            public void completeTypeBindings(
0286:                    CompilationUnitDeclaration parsedUnit) {
0287:                if (stepCompleted == BUILD_FIELDS_AND_METHODS) {
0288:                    // This can only happen because the original set of units are completely built and
0289:                    // are now being processed, so we want to treat all the additional units as a group
0290:                    // until they too are completely processed.
0291:                    completeTypeBindings();
0292:                } else {
0293:                    if (parsedUnit.scope == null)
0294:                        return; // parsing errors were too severe
0295:
0296:                    if (stepCompleted >= CHECK_AND_SET_IMPORTS)
0297:                        (this .unitBeingCompleted = parsedUnit).scope
0298:                                .checkAndSetImports();
0299:
0300:                    if (stepCompleted >= CONNECT_TYPE_HIERARCHY)
0301:                        (this .unitBeingCompleted = parsedUnit).scope
0302:                                .connectTypeHierarchy();
0303:
0304:                    this .unitBeingCompleted = null;
0305:                }
0306:            }
0307:
0308:            /*
0309:             * Used by other compiler tools which do not start by calling completeTypeBindings().
0310:             *
0311:             * 1. Connect the type hierarchy for the type bindings created for parsedUnits.
0312:             * 2. Create the field bindings
0313:             * 3. Create the method bindings
0314:             */
0315:
0316:            public void completeTypeBindings(
0317:                    CompilationUnitDeclaration parsedUnit,
0318:                    boolean buildFieldsAndMethods) {
0319:                if (parsedUnit.scope == null)
0320:                    return; // parsing errors were too severe
0321:
0322:                (this .unitBeingCompleted = parsedUnit).scope
0323:                        .checkAndSetImports();
0324:                parsedUnit.scope.connectTypeHierarchy();
0325:                parsedUnit.scope.checkParameterizedTypes();
0326:                if (buildFieldsAndMethods)
0327:                    parsedUnit.scope.buildFieldsAndMethods();
0328:                this .unitBeingCompleted = null;
0329:            }
0330:
0331:            public TypeBinding computeBoxingType(TypeBinding type) {
0332:                TypeBinding boxedType;
0333:                switch (type.id) {
0334:                case TypeIds.T_JavaLangBoolean:
0335:                    return TypeBinding.BOOLEAN;
0336:                case TypeIds.T_JavaLangByte:
0337:                    return TypeBinding.BYTE;
0338:                case TypeIds.T_JavaLangCharacter:
0339:                    return TypeBinding.CHAR;
0340:                case TypeIds.T_JavaLangShort:
0341:                    return TypeBinding.SHORT;
0342:                case TypeIds.T_JavaLangDouble:
0343:                    return TypeBinding.DOUBLE;
0344:                case TypeIds.T_JavaLangFloat:
0345:                    return TypeBinding.FLOAT;
0346:                case TypeIds.T_JavaLangInteger:
0347:                    return TypeBinding.INT;
0348:                case TypeIds.T_JavaLangLong:
0349:                    return TypeBinding.LONG;
0350:
0351:                case TypeIds.T_int:
0352:                    boxedType = getType(JAVA_LANG_INTEGER);
0353:                    if (boxedType != null)
0354:                        return boxedType;
0355:                    return new ProblemReferenceBinding(JAVA_LANG_INTEGER, null,
0356:                            NotFound);
0357:                case TypeIds.T_byte:
0358:                    boxedType = getType(JAVA_LANG_BYTE);
0359:                    if (boxedType != null)
0360:                        return boxedType;
0361:                    return new ProblemReferenceBinding(JAVA_LANG_BYTE, null,
0362:                            NotFound);
0363:                case TypeIds.T_short:
0364:                    boxedType = getType(JAVA_LANG_SHORT);
0365:                    if (boxedType != null)
0366:                        return boxedType;
0367:                    return new ProblemReferenceBinding(JAVA_LANG_SHORT, null,
0368:                            NotFound);
0369:                case TypeIds.T_char:
0370:                    boxedType = getType(JAVA_LANG_CHARACTER);
0371:                    if (boxedType != null)
0372:                        return boxedType;
0373:                    return new ProblemReferenceBinding(JAVA_LANG_CHARACTER,
0374:                            null, NotFound);
0375:                case TypeIds.T_long:
0376:                    boxedType = getType(JAVA_LANG_LONG);
0377:                    if (boxedType != null)
0378:                        return boxedType;
0379:                    return new ProblemReferenceBinding(JAVA_LANG_LONG, null,
0380:                            NotFound);
0381:                case TypeIds.T_float:
0382:                    boxedType = getType(JAVA_LANG_FLOAT);
0383:                    if (boxedType != null)
0384:                        return boxedType;
0385:                    return new ProblemReferenceBinding(JAVA_LANG_FLOAT, null,
0386:                            NotFound);
0387:                case TypeIds.T_double:
0388:                    boxedType = getType(JAVA_LANG_DOUBLE);
0389:                    if (boxedType != null)
0390:                        return boxedType;
0391:                    return new ProblemReferenceBinding(JAVA_LANG_DOUBLE, null,
0392:                            NotFound);
0393:                case TypeIds.T_boolean:
0394:                    boxedType = getType(JAVA_LANG_BOOLEAN);
0395:                    if (boxedType != null)
0396:                        return boxedType;
0397:                    return new ProblemReferenceBinding(JAVA_LANG_BOOLEAN, null,
0398:                            NotFound);
0399:                    //		case TypeIds.T_int :
0400:                    //			return getResolvedType(JAVA_LANG_INTEGER, null);
0401:                    //		case TypeIds.T_byte :
0402:                    //			return getResolvedType(JAVA_LANG_BYTE, null);
0403:                    //		case TypeIds.T_short :
0404:                    //			return getResolvedType(JAVA_LANG_SHORT, null);
0405:                    //		case TypeIds.T_char :
0406:                    //			return getResolvedType(JAVA_LANG_CHARACTER, null);
0407:                    //		case TypeIds.T_long :
0408:                    //			return getResolvedType(JAVA_LANG_LONG, null);
0409:                    //		case TypeIds.T_float :
0410:                    //			return getResolvedType(JAVA_LANG_FLOAT, null);
0411:                    //		case TypeIds.T_double :
0412:                    //			return getResolvedType(JAVA_LANG_DOUBLE, null);
0413:                    //		case TypeIds.T_boolean :
0414:                    //			return getResolvedType(JAVA_LANG_BOOLEAN, null);
0415:                }
0416:                // allow indirect unboxing conversion for wildcards and type parameters
0417:                switch (type.kind()) {
0418:                case Binding.WILDCARD_TYPE:
0419:                case Binding.TYPE_PARAMETER:
0420:                    switch (type.erasure().id) {
0421:                    case TypeIds.T_JavaLangBoolean:
0422:                        return TypeBinding.BOOLEAN;
0423:                    case TypeIds.T_JavaLangByte:
0424:                        return TypeBinding.BYTE;
0425:                    case TypeIds.T_JavaLangCharacter:
0426:                        return TypeBinding.CHAR;
0427:                    case TypeIds.T_JavaLangShort:
0428:                        return TypeBinding.SHORT;
0429:                    case TypeIds.T_JavaLangDouble:
0430:                        return TypeBinding.DOUBLE;
0431:                    case TypeIds.T_JavaLangFloat:
0432:                        return TypeBinding.FLOAT;
0433:                    case TypeIds.T_JavaLangInteger:
0434:                        return TypeBinding.INT;
0435:                    case TypeIds.T_JavaLangLong:
0436:                        return TypeBinding.LONG;
0437:                    }
0438:                }
0439:                return type;
0440:            }
0441:
0442:            private PackageBinding computePackageFrom(char[][] constantPoolName) {
0443:                if (constantPoolName.length == 1)
0444:                    return defaultPackage;
0445:
0446:                PackageBinding packageBinding = getPackage0(constantPoolName[0]);
0447:                if (packageBinding == null
0448:                        || packageBinding == TheNotFoundPackage) {
0449:                    packageBinding = new PackageBinding(constantPoolName[0],
0450:                            this );
0451:                    knownPackages.put(constantPoolName[0], packageBinding);
0452:                }
0453:
0454:                for (int i = 1, length = constantPoolName.length - 1; i < length; i++) {
0455:                    PackageBinding parent = packageBinding;
0456:                    if ((packageBinding = parent
0457:                            .getPackage0(constantPoolName[i])) == null
0458:                            || packageBinding == TheNotFoundPackage) {
0459:                        packageBinding = new PackageBinding(CharOperation
0460:                                .subarray(constantPoolName, 0, i + 1), parent,
0461:                                this );
0462:                        parent.addPackage(packageBinding);
0463:                    }
0464:                }
0465:                return packageBinding;
0466:            }
0467:
0468:            /**
0469:             * Convert a given source type into a parameterized form if generic.
0470:             * generic X<E> --> param X<E>
0471:             */
0472:            public ReferenceBinding convertToParameterizedType(
0473:                    ReferenceBinding originalType) {
0474:                if (originalType != null) {
0475:                    boolean isGeneric = originalType.isGenericType();
0476:                    ReferenceBinding originalEnclosingType = originalType
0477:                            .enclosingType();
0478:                    ReferenceBinding convertedEnclosingType = originalEnclosingType;
0479:                    boolean needToConvert = isGeneric;
0480:                    if (originalEnclosingType != null) {
0481:                        convertedEnclosingType = originalType.isStatic() ? (ReferenceBinding) convertToRawType(originalEnclosingType)
0482:                                : convertToParameterizedType(originalEnclosingType);
0483:                        needToConvert |= originalEnclosingType != convertedEnclosingType;
0484:                    }
0485:                    if (needToConvert) {
0486:                        return createParameterizedType(
0487:                                originalType,
0488:                                isGeneric ? originalType.typeVariables() : null,
0489:                                convertedEnclosingType);
0490:                    }
0491:                }
0492:                return originalType;
0493:            }
0494:
0495:            public TypeBinding convertToRawType(TypeBinding type) {
0496:                int dimension;
0497:                TypeBinding originalType;
0498:                switch (type.kind()) {
0499:                case Binding.BASE_TYPE:
0500:                case Binding.TYPE_PARAMETER:
0501:                case Binding.WILDCARD_TYPE:
0502:                case Binding.RAW_TYPE:
0503:                    return type;
0504:                case Binding.ARRAY_TYPE:
0505:                    dimension = type.dimensions();
0506:                    originalType = type.leafComponentType();
0507:                    break;
0508:                default:
0509:                    if (type.id == TypeIds.T_JavaLangObject)
0510:                        return type; // Object is not generic
0511:                    dimension = 0;
0512:                    originalType = type;
0513:                }
0514:                boolean needToConvert;
0515:                switch (originalType.kind()) {
0516:                case Binding.BASE_TYPE:
0517:                    return type;
0518:                case Binding.GENERIC_TYPE:
0519:                    needToConvert = true;
0520:                    break;
0521:                case Binding.PARAMETERIZED_TYPE:
0522:                    ParameterizedTypeBinding paramType = (ParameterizedTypeBinding) originalType;
0523:                    needToConvert = paramType.genericType().isGenericType(); // only recursive call to enclosing type can find parameterizedType with arguments
0524:                    break;
0525:                default:
0526:                    needToConvert = false;
0527:                    break;
0528:                }
0529:                ReferenceBinding originalEnclosing = originalType
0530:                        .enclosingType();
0531:                TypeBinding convertedType;
0532:                if (originalEnclosing == null) {
0533:                    convertedType = needToConvert ? createRawType(
0534:                            (ReferenceBinding) originalType.erasure(), null)
0535:                            : originalType;
0536:                } else {
0537:                    ReferenceBinding convertedEnclosing;
0538:                    if (originalEnclosing.kind() == Binding.RAW_TYPE) {
0539:                        needToConvert |= !((ReferenceBinding) originalType)
0540:                                .isStatic();
0541:                        convertedEnclosing = originalEnclosing;
0542:                    } else if (needToConvert
0543:                            || ((ReferenceBinding) originalType).isStatic()) {
0544:                        convertedEnclosing = (ReferenceBinding) convertToRawType(originalEnclosing);
0545:                    } else {
0546:                        convertedEnclosing = convertToParameterizedType(originalEnclosing);
0547:                    }
0548:                    if (needToConvert) {
0549:                        convertedType = createRawType(
0550:                                (ReferenceBinding) originalType.erasure(),
0551:                                convertedEnclosing);
0552:                    } else if (originalEnclosing != convertedEnclosing) {
0553:                        convertedType = createParameterizedType(
0554:                                (ReferenceBinding) originalType.erasure(),
0555:                                null, convertedEnclosing);
0556:                    } else {
0557:                        convertedType = originalType;
0558:                    }
0559:                }
0560:                if (originalType != convertedType) {
0561:                    return dimension > 0 ? (TypeBinding) createArrayType(
0562:                            convertedType, dimension) : convertedType;
0563:                }
0564:                return type;
0565:            }
0566:
0567:            // variation for unresolved types in binaries (consider generic type as raw)
0568:            public TypeBinding convertUnresolvedBinaryToRawType(TypeBinding type) {
0569:                int dimension;
0570:                TypeBinding originalType;
0571:                switch (type.kind()) {
0572:                case Binding.BASE_TYPE:
0573:                case Binding.TYPE_PARAMETER:
0574:                case Binding.WILDCARD_TYPE:
0575:                case Binding.RAW_TYPE:
0576:                    return type;
0577:                case Binding.ARRAY_TYPE:
0578:                    dimension = type.dimensions();
0579:                    originalType = type.leafComponentType();
0580:                    break;
0581:                default:
0582:                    if (type.id == TypeIds.T_JavaLangObject)
0583:                        return type; // Object is not generic
0584:                    dimension = 0;
0585:                    originalType = type;
0586:                }
0587:                boolean needToConvert;
0588:                switch (originalType.kind()) {
0589:                case Binding.BASE_TYPE:
0590:                    return type;
0591:                case Binding.GENERIC_TYPE:
0592:                    needToConvert = true;
0593:                    break;
0594:                case Binding.PARAMETERIZED_TYPE:
0595:                    ParameterizedTypeBinding paramType = (ParameterizedTypeBinding) originalType;
0596:                    needToConvert = paramType.genericType().isGenericType(); // only recursive call to enclosing type can find parameterizedType with arguments
0597:                    break;
0598:                default:
0599:                    needToConvert = false;
0600:                    break;
0601:                }
0602:                ReferenceBinding originalEnclosing = originalType
0603:                        .enclosingType();
0604:                TypeBinding convertedType;
0605:                if (originalEnclosing == null) {
0606:                    convertedType = needToConvert ? createRawType(
0607:                            (ReferenceBinding) originalType.erasure(), null)
0608:                            : originalType;
0609:                } else {
0610:                    ReferenceBinding convertedEnclosing = (ReferenceBinding) convertUnresolvedBinaryToRawType(originalEnclosing);
0611:                    if (convertedEnclosing != originalEnclosing) {
0612:                        needToConvert |= !((ReferenceBinding) originalType)
0613:                                .isStatic();
0614:                    }
0615:                    if (needToConvert) {
0616:                        convertedType = createRawType(
0617:                                (ReferenceBinding) originalType.erasure(),
0618:                                convertedEnclosing);
0619:                    } else if (originalEnclosing != convertedEnclosing) {
0620:                        convertedType = createParameterizedType(
0621:                                (ReferenceBinding) originalType.erasure(),
0622:                                null, convertedEnclosing);
0623:                    } else {
0624:                        convertedType = originalType;
0625:                    }
0626:                }
0627:                if (originalType != convertedType) {
0628:                    return dimension > 0 ? (TypeBinding) createArrayType(
0629:                            convertedType, dimension) : convertedType;
0630:                }
0631:                return type;
0632:            }
0633:
0634:            /*
0635:             *  Used to guarantee annotation identity.
0636:             */
0637:            public AnnotationBinding createAnnotation(
0638:                    ReferenceBinding annotationType, ElementValuePair[] pairs) {
0639:                if (pairs.length != 0) {
0640:                    AnnotationBinding.setMethodBindings(annotationType, pairs);
0641:                }
0642:                return new AnnotationBinding(annotationType, pairs);
0643:            }
0644:
0645:            /*
0646:             *  Used to guarantee array type identity.
0647:             */
0648:            public ArrayBinding createArrayType(TypeBinding leafComponentType,
0649:                    int dimensionCount) {
0650:                if (leafComponentType instanceof  LocalTypeBinding) // cache local type arrays with the local type itself
0651:                    return ((LocalTypeBinding) leafComponentType)
0652:                            .createArrayType(dimensionCount, this );
0653:
0654:                // find the array binding cache for this dimension
0655:                int dimIndex = dimensionCount - 1;
0656:                int length = uniqueArrayBindings.length;
0657:                ArrayBinding[] arrayBindings;
0658:                if (dimIndex < length) {
0659:                    if ((arrayBindings = uniqueArrayBindings[dimIndex]) == null)
0660:                        uniqueArrayBindings[dimIndex] = arrayBindings = new ArrayBinding[10];
0661:                } else {
0662:                    System
0663:                            .arraycopy(
0664:                                    uniqueArrayBindings,
0665:                                    0,
0666:                                    uniqueArrayBindings = new ArrayBinding[dimensionCount][],
0667:                                    0, length);
0668:                    uniqueArrayBindings[dimIndex] = arrayBindings = new ArrayBinding[10];
0669:                }
0670:
0671:                // find the cached array binding for this leaf component type (if any)
0672:                int index = -1;
0673:                length = arrayBindings.length;
0674:                while (++index < length) {
0675:                    ArrayBinding currentBinding = arrayBindings[index];
0676:                    if (currentBinding == null) // no matching array, but space left
0677:                        return arrayBindings[index] = new ArrayBinding(
0678:                                leafComponentType, dimensionCount, this );
0679:                    if (currentBinding.leafComponentType == leafComponentType)
0680:                        return currentBinding;
0681:                }
0682:
0683:                // no matching array, no space left
0684:                System.arraycopy(arrayBindings, 0,
0685:                        (arrayBindings = new ArrayBinding[length * 2]), 0,
0686:                        length);
0687:                uniqueArrayBindings[dimIndex] = arrayBindings;
0688:                return arrayBindings[length] = new ArrayBinding(
0689:                        leafComponentType, dimensionCount, this );
0690:            }
0691:
0692:            public BinaryTypeBinding createBinaryTypeFrom(
0693:                    IBinaryType binaryType, PackageBinding packageBinding,
0694:                    AccessRestriction accessRestriction) {
0695:                return createBinaryTypeFrom(binaryType, packageBinding, true,
0696:                        accessRestriction);
0697:            }
0698:
0699:            public BinaryTypeBinding createBinaryTypeFrom(
0700:                    IBinaryType binaryType, PackageBinding packageBinding,
0701:                    boolean needFieldsAndMethods,
0702:                    AccessRestriction accessRestriction) {
0703:                BinaryTypeBinding binaryBinding = new BinaryTypeBinding(
0704:                        packageBinding, binaryType, this );
0705:
0706:                // resolve any array bindings which reference the unresolvedType
0707:                ReferenceBinding cachedType = packageBinding
0708:                        .getType0(binaryBinding.compoundName[binaryBinding.compoundName.length - 1]);
0709:                if (cachedType != null) { // update reference to unresolved binding after having read classfile (knows whether generic for raw conversion)
0710:                    if (cachedType instanceof  UnresolvedReferenceBinding) {
0711:                        ((UnresolvedReferenceBinding) cachedType)
0712:                                .setResolvedType(binaryBinding, this );
0713:                    } else {
0714:                        if (cachedType.isBinaryBinding()) // sanity check... at this point the cache should ONLY contain unresolved types
0715:                            return (BinaryTypeBinding) cachedType;
0716:                        // it is possible with a large number of source files (exceeding AbstractImageBuilder.MAX_AT_ONCE) that a member type can be in the cache as an UnresolvedType,
0717:                        // but because its enclosingType is resolved while its created (call to BinaryTypeBinding constructor), its replaced with a source type
0718:                        return null;
0719:                    }
0720:                }
0721:
0722:                packageBinding.addType(binaryBinding);
0723:                setAccessRestriction(binaryBinding, accessRestriction);
0724:                binaryBinding.cachePartsFrom(binaryType, needFieldsAndMethods);
0725:                return binaryBinding;
0726:            }
0727:
0728:            /* Used to create packages from the package statement.
0729:             */
0730:
0731:            public PackageBinding createPackage(char[][] compoundName) {
0732:                PackageBinding packageBinding = getPackage0(compoundName[0]);
0733:                if (packageBinding == null
0734:                        || packageBinding == TheNotFoundPackage) {
0735:                    packageBinding = new PackageBinding(compoundName[0], this );
0736:                    knownPackages.put(compoundName[0], packageBinding);
0737:                }
0738:
0739:                for (int i = 1, length = compoundName.length; i < length; i++) {
0740:                    // check to see if it collides with a known type...
0741:                    // this case can only happen if the package does not exist as a directory in the file system
0742:                    // otherwise when the source type was defined, the correct error would have been reported
0743:                    // unless its an unresolved type which is referenced from an inconsistent class file
0744:                    // NOTE: empty packages are not packages according to changes in JLS v2, 7.4.3
0745:                    // so not all types cause collision errors when they're created even though the package did exist
0746:                    ReferenceBinding type = packageBinding
0747:                            .getType0(compoundName[i]);
0748:                    if (type != null && type != TheNotFoundType
0749:                            && !(type instanceof  UnresolvedReferenceBinding))
0750:                        return null;
0751:
0752:                    PackageBinding parent = packageBinding;
0753:                    if ((packageBinding = parent.getPackage0(compoundName[i])) == null
0754:                            || packageBinding == TheNotFoundPackage) {
0755:                        // if the package is unknown, check to see if a type exists which would collide with the new package
0756:                        // catches the case of a package statement of: package java.lang.Object;
0757:                        // since the package can be added after a set of source files have already been compiled,
0758:                        // we need to check whenever a package is created
0759:                        if (nameEnvironment.findType(compoundName[i],
0760:                                parent.compoundName) != null)
0761:                            return null;
0762:
0763:                        packageBinding = new PackageBinding(CharOperation
0764:                                .subarray(compoundName, 0, i + 1), parent, this );
0765:                        parent.addPackage(packageBinding);
0766:                    }
0767:                }
0768:                return packageBinding;
0769:            }
0770:
0771:            public ParameterizedGenericMethodBinding createParameterizedGenericMethod(
0772:                    MethodBinding genericMethod, RawTypeBinding rawType) {
0773:
0774:                // cached info is array of already created parameterized types for this type
0775:                ParameterizedGenericMethodBinding[] cachedInfo = (ParameterizedGenericMethodBinding[]) this .uniqueParameterizedGenericMethodBindings
0776:                        .get(genericMethod);
0777:                boolean needToGrow = false;
0778:                int index = 0;
0779:                if (cachedInfo != null) {
0780:                    nextCachedMethod:
0781:                    // iterate existing parameterized for reusing one with same type arguments if any
0782:                    for (int max = cachedInfo.length; index < max; index++) {
0783:                        ParameterizedGenericMethodBinding cachedMethod = cachedInfo[index];
0784:                        if (cachedMethod == null)
0785:                            break nextCachedMethod;
0786:                        if (!cachedMethod.isRaw)
0787:                            continue nextCachedMethod;
0788:                        if (cachedMethod.declaringClass != (rawType == null ? genericMethod.declaringClass
0789:                                : rawType))
0790:                            continue nextCachedMethod;
0791:                        return cachedMethod;
0792:                    }
0793:                    needToGrow = true;
0794:                } else {
0795:                    cachedInfo = new ParameterizedGenericMethodBinding[5];
0796:                    this .uniqueParameterizedGenericMethodBindings.put(
0797:                            genericMethod, cachedInfo);
0798:                }
0799:                // grow cache ?
0800:                int length = cachedInfo.length;
0801:                if (needToGrow && index == length) {
0802:                    System
0803:                            .arraycopy(
0804:                                    cachedInfo,
0805:                                    0,
0806:                                    cachedInfo = new ParameterizedGenericMethodBinding[length * 2],
0807:                                    0, length);
0808:                    this .uniqueParameterizedGenericMethodBindings.put(
0809:                            genericMethod, cachedInfo);
0810:                }
0811:                // add new binding
0812:                ParameterizedGenericMethodBinding parameterizedGenericMethod = new ParameterizedGenericMethodBinding(
0813:                        genericMethod, rawType, this );
0814:                cachedInfo[index] = parameterizedGenericMethod;
0815:                return parameterizedGenericMethod;
0816:            }
0817:
0818:            public ParameterizedGenericMethodBinding createParameterizedGenericMethod(
0819:                    MethodBinding genericMethod, TypeBinding[] typeArguments) {
0820:
0821:                // cached info is array of already created parameterized types for this type
0822:                ParameterizedGenericMethodBinding[] cachedInfo = (ParameterizedGenericMethodBinding[]) this .uniqueParameterizedGenericMethodBindings
0823:                        .get(genericMethod);
0824:                int argLength = typeArguments == null ? 0
0825:                        : typeArguments.length;
0826:                boolean needToGrow = false;
0827:                int index = 0;
0828:                if (cachedInfo != null) {
0829:                    nextCachedMethod:
0830:                    // iterate existing parameterized for reusing one with same type arguments if any
0831:                    for (int max = cachedInfo.length; index < max; index++) {
0832:                        ParameterizedGenericMethodBinding cachedMethod = cachedInfo[index];
0833:                        if (cachedMethod == null)
0834:                            break nextCachedMethod;
0835:                        if (cachedMethod.isRaw)
0836:                            continue nextCachedMethod;
0837:                        TypeBinding[] cachedArguments = cachedMethod.typeArguments;
0838:                        int cachedArgLength = cachedArguments == null ? 0
0839:                                : cachedArguments.length;
0840:                        if (argLength != cachedArgLength)
0841:                            continue nextCachedMethod;
0842:                        for (int j = 0; j < cachedArgLength; j++) {
0843:                            if (typeArguments[j] != cachedArguments[j])
0844:                                continue nextCachedMethod;
0845:                        }
0846:                        // all arguments match, reuse current
0847:                        return cachedMethod;
0848:                    }
0849:                    needToGrow = true;
0850:                } else {
0851:                    cachedInfo = new ParameterizedGenericMethodBinding[5];
0852:                    this .uniqueParameterizedGenericMethodBindings.put(
0853:                            genericMethod, cachedInfo);
0854:                }
0855:                // grow cache ?
0856:                int length = cachedInfo.length;
0857:                if (needToGrow && index == length) {
0858:                    System
0859:                            .arraycopy(
0860:                                    cachedInfo,
0861:                                    0,
0862:                                    cachedInfo = new ParameterizedGenericMethodBinding[length * 2],
0863:                                    0, length);
0864:                    this .uniqueParameterizedGenericMethodBindings.put(
0865:                            genericMethod, cachedInfo);
0866:                }
0867:                // add new binding
0868:                ParameterizedGenericMethodBinding parameterizedGenericMethod = new ParameterizedGenericMethodBinding(
0869:                        genericMethod, typeArguments, this );
0870:                cachedInfo[index] = parameterizedGenericMethod;
0871:                return parameterizedGenericMethod;
0872:            }
0873:
0874:            public ParameterizedTypeBinding createParameterizedType(
0875:                    ReferenceBinding genericType, TypeBinding[] typeArguments,
0876:                    ReferenceBinding enclosingType) {
0877:
0878:                // cached info is array of already created parameterized types for this type
0879:                ParameterizedTypeBinding[] cachedInfo = (ParameterizedTypeBinding[]) this .uniqueParameterizedTypeBindings
0880:                        .get(genericType);
0881:                int argLength = typeArguments == null ? 0
0882:                        : typeArguments.length;
0883:                boolean needToGrow = false;
0884:                int index = 0;
0885:                if (cachedInfo != null) {
0886:                    nextCachedType:
0887:                    // iterate existing parameterized for reusing one with same type arguments if any
0888:                    for (int max = cachedInfo.length; index < max; index++) {
0889:                        ParameterizedTypeBinding cachedType = cachedInfo[index];
0890:                        if (cachedType == null)
0891:                            break nextCachedType;
0892:                        if (cachedType.actualType() != genericType)
0893:                            continue nextCachedType; // remain of unresolved type
0894:                        if (cachedType.enclosingType() != enclosingType)
0895:                            continue nextCachedType;
0896:                        TypeBinding[] cachedArguments = cachedType.arguments;
0897:                        int cachedArgLength = cachedArguments == null ? 0
0898:                                : cachedArguments.length;
0899:                        if (argLength != cachedArgLength)
0900:                            continue nextCachedType; // would be an error situation (from unresolved binaries)
0901:                        for (int j = 0; j < cachedArgLength; j++) {
0902:                            if (typeArguments[j] != cachedArguments[j])
0903:                                continue nextCachedType;
0904:                        }
0905:                        // all arguments match, reuse current
0906:                        return cachedType;
0907:                    }
0908:                    needToGrow = true;
0909:                } else {
0910:                    cachedInfo = new ParameterizedTypeBinding[5];
0911:                    this .uniqueParameterizedTypeBindings.put(genericType,
0912:                            cachedInfo);
0913:                }
0914:                // grow cache ?
0915:                int length = cachedInfo.length;
0916:                if (needToGrow && index == length) {
0917:                    System
0918:                            .arraycopy(
0919:                                    cachedInfo,
0920:                                    0,
0921:                                    cachedInfo = new ParameterizedTypeBinding[length * 2],
0922:                                    0, length);
0923:                    this .uniqueParameterizedTypeBindings.put(genericType,
0924:                            cachedInfo);
0925:                }
0926:                // add new binding
0927:                ParameterizedTypeBinding parameterizedType = new ParameterizedTypeBinding(
0928:                        genericType, typeArguments, enclosingType, this );
0929:                cachedInfo[index] = parameterizedType;
0930:                return parameterizedType;
0931:            }
0932:
0933:            public RawTypeBinding createRawType(ReferenceBinding genericType,
0934:                    ReferenceBinding enclosingType) {
0935:                // cached info is array of already created raw types for this type
0936:                RawTypeBinding[] cachedInfo = (RawTypeBinding[]) this .uniqueRawTypeBindings
0937:                        .get(genericType);
0938:                boolean needToGrow = false;
0939:                int index = 0;
0940:                if (cachedInfo != null) {
0941:                    nextCachedType:
0942:                    // iterate existing parameterized for reusing one with same type arguments if any
0943:                    for (int max = cachedInfo.length; index < max; index++) {
0944:                        RawTypeBinding cachedType = cachedInfo[index];
0945:                        if (cachedType == null)
0946:                            break nextCachedType;
0947:                        if (cachedType.actualType() != genericType)
0948:                            continue nextCachedType; // remain of unresolved type
0949:                        if (cachedType.enclosingType() != enclosingType)
0950:                            continue nextCachedType;
0951:                        // all enclosing type match, reuse current
0952:                        return cachedType;
0953:                    }
0954:                    needToGrow = true;
0955:                } else {
0956:                    cachedInfo = new RawTypeBinding[1];
0957:                    this .uniqueRawTypeBindings.put(genericType, cachedInfo);
0958:                }
0959:                // grow cache ?
0960:                int length = cachedInfo.length;
0961:                if (needToGrow && index == length) {
0962:                    System.arraycopy(cachedInfo, 0,
0963:                            cachedInfo = new RawTypeBinding[length * 2], 0,
0964:                            length);
0965:                    this .uniqueRawTypeBindings.put(genericType, cachedInfo);
0966:                }
0967:                // add new binding
0968:                RawTypeBinding rawType = new RawTypeBinding(genericType,
0969:                        enclosingType, this );
0970:                cachedInfo[index] = rawType;
0971:                return rawType;
0972:
0973:            }
0974:
0975:            public WildcardBinding createWildcard(ReferenceBinding genericType,
0976:                    int rank, TypeBinding bound, TypeBinding[] otherBounds,
0977:                    int boundKind) {
0978:
0979:                // cached info is array of already created wildcard  types for this type
0980:                if (genericType == null) // pseudo wildcard denoting composite bounds for lub computation
0981:                    genericType = ReferenceBinding.LUB_GENERIC;
0982:                WildcardBinding[] cachedInfo = (WildcardBinding[]) this .uniqueWildcardBindings
0983:                        .get(genericType);
0984:                boolean needToGrow = false;
0985:                int index = 0;
0986:                if (cachedInfo != null) {
0987:                    nextCachedType:
0988:                    // iterate existing wildcards for reusing one with same information if any
0989:                    for (int max = cachedInfo.length; index < max; index++) {
0990:                        WildcardBinding cachedType = cachedInfo[index];
0991:                        if (cachedType == null)
0992:                            break nextCachedType;
0993:                        if (cachedType.genericType != genericType)
0994:                            continue nextCachedType; // remain of unresolved type
0995:                        if (cachedType.rank != rank)
0996:                            continue nextCachedType;
0997:                        if (cachedType.boundKind != boundKind)
0998:                            continue nextCachedType;
0999:                        if (cachedType.bound != bound)
1000:                            continue nextCachedType;
1001:                        if (cachedType.otherBounds != otherBounds) {
1002:                            int cachedLength = cachedType.otherBounds == null ? 0
1003:                                    : cachedType.otherBounds.length;
1004:                            int length = otherBounds == null ? 0
1005:                                    : otherBounds.length;
1006:                            if (cachedLength != length)
1007:                                continue nextCachedType;
1008:                            for (int j = 0; j < length; j++) {
1009:                                if (cachedType.otherBounds[j] != otherBounds[j])
1010:                                    continue nextCachedType;
1011:                            }
1012:                        }
1013:                        // all match, reuse current
1014:                        return cachedType;
1015:                    }
1016:                    needToGrow = true;
1017:                } else {
1018:                    cachedInfo = new WildcardBinding[10];
1019:                    this .uniqueWildcardBindings.put(genericType, cachedInfo);
1020:                }
1021:                // grow cache ?
1022:                int length = cachedInfo.length;
1023:                if (needToGrow && index == length) {
1024:                    System.arraycopy(cachedInfo, 0,
1025:                            cachedInfo = new WildcardBinding[length * 2], 0,
1026:                            length);
1027:                    this .uniqueWildcardBindings.put(genericType, cachedInfo);
1028:                }
1029:                // add new binding
1030:                WildcardBinding wildcard = new WildcardBinding(genericType,
1031:                        rank, bound, otherBounds, boundKind, this );
1032:                cachedInfo[index] = wildcard;
1033:                return wildcard;
1034:            }
1035:
1036:            /**
1037:             * Returns the access restriction associated to a given type, or null if none
1038:             */
1039:            public AccessRestriction getAccessRestriction(TypeBinding type) {
1040:                return (AccessRestriction) this .accessRestrictions.get(type);
1041:            }
1042:
1043:            /**
1044:             *  Answer the type for the compoundName if it exists in the cache.
1045:             * Answer theNotFoundType if it could not be resolved the first time
1046:             * it was looked up, otherwise answer null.
1047:             *
1048:             * NOTE: Do not use for nested types... the answer is NOT the same for a.b.C or a.b.C.D.E
1049:             * assuming C is a type in both cases. In the a.b.C.D.E case, null is the answer.
1050:             */
1051:
1052:            public ReferenceBinding getCachedType(char[][] compoundName) {
1053:                if (compoundName.length == 1) {
1054:                    if (defaultPackage == null)
1055:                        return null;
1056:                    return defaultPackage.getType0(compoundName[0]);
1057:                }
1058:
1059:                PackageBinding packageBinding = getPackage0(compoundName[0]);
1060:                if (packageBinding == null
1061:                        || packageBinding == TheNotFoundPackage)
1062:                    return null;
1063:
1064:                for (int i = 1, packageLength = compoundName.length - 1; i < packageLength; i++)
1065:                    if ((packageBinding = packageBinding
1066:                            .getPackage0(compoundName[i])) == null
1067:                            || packageBinding == TheNotFoundPackage)
1068:                        return null;
1069:                return packageBinding
1070:                        .getType0(compoundName[compoundName.length - 1]);
1071:            }
1072:
1073:            /* Answer the top level package named name if it exists in the cache.
1074:             * Answer theNotFoundPackage if it could not be resolved the first time
1075:             * it was looked up, otherwise answer null.
1076:             *
1077:             * NOTE: Senders must convert theNotFoundPackage into a real problem
1078:             * package if its to returned.
1079:             */
1080:
1081:            PackageBinding getPackage0(char[] name) {
1082:                return knownPackages.get(name);
1083:            }
1084:
1085:            /* Answer the type corresponding to the compoundName.
1086:             * Ask the name environment for the type if its not in the cache.
1087:             * Fail with a classpath error if the type cannot be found.
1088:             */
1089:            public ReferenceBinding getResolvedType(char[][] compoundName,
1090:                    Scope scope) {
1091:                ReferenceBinding type = getType(compoundName);
1092:                if (type != null)
1093:                    return type;
1094:
1095:                // create a proxy for the missing BinaryType
1096:                return cacheMissingBinaryType(compoundName,
1097:                        scope == null ? this .unitBeingCompleted : scope
1098:                                .referenceCompilationUnit());
1099:            }
1100:
1101:            /* Answer the top level package named name.
1102:             * Ask the oracle for the package if its not in the cache.
1103:             * Answer null if the package cannot be found.
1104:             */
1105:
1106:            PackageBinding getTopLevelPackage(char[] name) {
1107:                PackageBinding packageBinding = getPackage0(name);
1108:                if (packageBinding != null) {
1109:                    if (packageBinding == TheNotFoundPackage)
1110:                        return null;
1111:                    return packageBinding;
1112:                }
1113:
1114:                if (nameEnvironment.isPackage(null, name)) {
1115:                    knownPackages.put(name,
1116:                            packageBinding = new PackageBinding(name, this ));
1117:                    return packageBinding;
1118:                }
1119:
1120:                knownPackages.put(name, TheNotFoundPackage); // saves asking the oracle next time
1121:                return null;
1122:            }
1123:
1124:            /* Answer the type corresponding to the compoundName.
1125:             * Ask the name environment for the type if its not in the cache.
1126:             * Answer null if the type cannot be found.
1127:             */
1128:
1129:            public ReferenceBinding getType(char[][] compoundName) {
1130:                ReferenceBinding referenceBinding;
1131:
1132:                if (compoundName.length == 1) {
1133:                    if (defaultPackage == null)
1134:                        return null;
1135:
1136:                    if ((referenceBinding = defaultPackage
1137:                            .getType0(compoundName[0])) == null) {
1138:                        PackageBinding packageBinding = getPackage0(compoundName[0]);
1139:                        if (packageBinding != null
1140:                                && packageBinding != TheNotFoundPackage)
1141:                            return null; // collides with a known package... should not call this method in such a case
1142:                        referenceBinding = askForType(defaultPackage,
1143:                                compoundName[0]);
1144:                    }
1145:                } else {
1146:                    PackageBinding packageBinding = getPackage0(compoundName[0]);
1147:                    if (packageBinding == TheNotFoundPackage)
1148:                        return null;
1149:
1150:                    if (packageBinding != null) {
1151:                        for (int i = 1, packageLength = compoundName.length - 1; i < packageLength; i++) {
1152:                            if ((packageBinding = packageBinding
1153:                                    .getPackage0(compoundName[i])) == null)
1154:                                break;
1155:                            if (packageBinding == TheNotFoundPackage)
1156:                                return null;
1157:                        }
1158:                    }
1159:
1160:                    if (packageBinding == null)
1161:                        referenceBinding = askForType(compoundName);
1162:                    else if ((referenceBinding = packageBinding
1163:                            .getType0(compoundName[compoundName.length - 1])) == null)
1164:                        referenceBinding = askForType(packageBinding,
1165:                                compoundName[compoundName.length - 1]);
1166:                }
1167:
1168:                if (referenceBinding == null
1169:                        || referenceBinding == TheNotFoundType)
1170:                    return null;
1171:                referenceBinding = BinaryTypeBinding.resolveType(
1172:                        referenceBinding, this , false); // no raw conversion for now
1173:
1174:                // compoundName refers to a nested type incorrectly (for example, package1.A$B)
1175:                if (referenceBinding.isNestedType())
1176:                    return new ProblemReferenceBinding(compoundName,
1177:                            referenceBinding, InternalNameProvided);
1178:                return referenceBinding;
1179:            }
1180:
1181:            private TypeBinding[] getTypeArgumentsFromSignature(
1182:                    SignatureWrapper wrapper,
1183:                    TypeVariableBinding[] staticVariables,
1184:                    ReferenceBinding enclosingType, ReferenceBinding genericType) {
1185:                java.util.ArrayList args = new java.util.ArrayList(2);
1186:                int rank = 0;
1187:                do {
1188:                    args
1189:                            .add(getTypeFromVariantTypeSignature(wrapper,
1190:                                    staticVariables, enclosingType,
1191:                                    genericType, rank++));
1192:                } while (wrapper.signature[wrapper.start] != '>');
1193:                wrapper.start++; // skip '>'
1194:                TypeBinding[] typeArguments = new TypeBinding[args.size()];
1195:                args.toArray(typeArguments);
1196:                return typeArguments;
1197:            }
1198:
1199:            /* Answer the type corresponding to the compound name.
1200:             * Does not ask the oracle for the type if its not found in the cache... instead an
1201:             * unresolved type is returned which must be resolved before used.
1202:             *
1203:             * NOTE: Does NOT answer base types nor array types!
1204:             */
1205:
1206:            ReferenceBinding getTypeFromCompoundName(char[][] compoundName,
1207:                    boolean isParameterized) {
1208:                ReferenceBinding binding = getCachedType(compoundName);
1209:                if (binding == null) {
1210:                    PackageBinding packageBinding = computePackageFrom(compoundName);
1211:                    binding = new UnresolvedReferenceBinding(compoundName,
1212:                            packageBinding);
1213:                    packageBinding.addType(binding);
1214:                } else if (binding == TheNotFoundType) {
1215:                    // create a proxy for the missing BinaryType
1216:                    binding = cacheMissingBinaryType(compoundName,
1217:                            this .unitBeingCompleted);
1218:                } else if (!isParameterized) {
1219:                    // check raw type, only for resolved types
1220:                    binding = (ReferenceBinding) convertUnresolvedBinaryToRawType(binding);
1221:                }
1222:                return binding;
1223:            }
1224:
1225:            /* Answer the type corresponding to the name from the binary file.
1226:             * Does not ask the oracle for the type if its not found in the cache... instead an
1227:             * unresolved type is returned which must be resolved before used.
1228:             *
1229:             * NOTE: Does NOT answer base types nor array types!
1230:             */
1231:
1232:            ReferenceBinding getTypeFromConstantPoolName(char[] signature,
1233:                    int start, int end, boolean isParameterized) {
1234:                if (end == -1)
1235:                    end = signature.length;
1236:
1237:                char[][] compoundName = CharOperation.splitOn('/', signature,
1238:                        start, end);
1239:                return getTypeFromCompoundName(compoundName, isParameterized);
1240:            }
1241:
1242:            /* Answer the type corresponding to the signature from the binary file.
1243:             * Does not ask the oracle for the type if its not found in the cache... instead an
1244:             * unresolved type is returned which must be resolved before used.
1245:             *
1246:             * NOTE: Does answer base types & array types.
1247:             */
1248:
1249:            TypeBinding getTypeFromSignature(char[] signature, int start,
1250:                    int end, boolean isParameterized, TypeBinding enclosingType) {
1251:                int dimension = 0;
1252:                while (signature[start] == '[') {
1253:                    start++;
1254:                    dimension++;
1255:                }
1256:                if (end == -1)
1257:                    end = signature.length - 1;
1258:
1259:                // Just switch on signature[start] - the L case is the else
1260:                TypeBinding binding = null;
1261:                if (start == end) {
1262:                    switch (signature[start]) {
1263:                    case 'I':
1264:                        binding = TypeBinding.INT;
1265:                        break;
1266:                    case 'Z':
1267:                        binding = TypeBinding.BOOLEAN;
1268:                        break;
1269:                    case 'V':
1270:                        binding = TypeBinding.VOID;
1271:                        break;
1272:                    case 'C':
1273:                        binding = TypeBinding.CHAR;
1274:                        break;
1275:                    case 'D':
1276:                        binding = TypeBinding.DOUBLE;
1277:                        break;
1278:                    case 'B':
1279:                        binding = TypeBinding.BYTE;
1280:                        break;
1281:                    case 'F':
1282:                        binding = TypeBinding.FLOAT;
1283:                        break;
1284:                    case 'J':
1285:                        binding = TypeBinding.LONG;
1286:                        break;
1287:                    case 'S':
1288:                        binding = TypeBinding.SHORT;
1289:                        break;
1290:                    default:
1291:                        problemReporter.corruptedSignature(enclosingType,
1292:                                signature, start);
1293:                        // will never reach here, since error will cause abort
1294:                    }
1295:                } else {
1296:                    binding = getTypeFromConstantPoolName(signature, start + 1,
1297:                            end, isParameterized); // skip leading 'L' or 'T'
1298:                }
1299:
1300:                if (dimension == 0)
1301:                    return binding;
1302:                return createArrayType(binding, dimension);
1303:            }
1304:
1305:            TypeBinding getTypeFromTypeSignature(SignatureWrapper wrapper,
1306:                    TypeVariableBinding[] staticVariables,
1307:                    ReferenceBinding enclosingType) {
1308:                // TypeVariableSignature = 'T' Identifier ';'
1309:                // ArrayTypeSignature = '[' TypeSignature
1310:                // ClassTypeSignature = 'L' Identifier TypeArgs(optional) ';'
1311:                //   or ClassTypeSignature '.' 'L' Identifier TypeArgs(optional) ';'
1312:                // TypeArgs = '<' VariantTypeSignature VariantTypeSignatures '>'
1313:                int dimension = 0;
1314:                while (wrapper.signature[wrapper.start] == '[') {
1315:                    wrapper.start++;
1316:                    dimension++;
1317:                }
1318:
1319:                if (wrapper.signature[wrapper.start] == 'T') {
1320:                    int varStart = wrapper.start + 1;
1321:                    int varEnd = wrapper.computeEnd();
1322:                    for (int i = staticVariables.length; --i >= 0;)
1323:                        if (CharOperation.equals(staticVariables[i].sourceName,
1324:                                wrapper.signature, varStart, varEnd))
1325:                            return dimension == 0 ? (TypeBinding) staticVariables[i]
1326:                                    : createArrayType(staticVariables[i],
1327:                                            dimension);
1328:                    ReferenceBinding initialType = enclosingType;
1329:                    do {
1330:                        if (enclosingType instanceof  BinaryTypeBinding) { // per construction can only be binary type binding
1331:                            TypeVariableBinding[] enclosingVariables = ((BinaryTypeBinding) enclosingType).typeVariables; // do not trigger resolution of variables
1332:                            for (int i = enclosingVariables.length; --i >= 0;)
1333:                                if (CharOperation.equals(
1334:                                        enclosingVariables[i].sourceName,
1335:                                        wrapper.signature, varStart, varEnd))
1336:                                    return dimension == 0 ? (TypeBinding) enclosingVariables[i]
1337:                                            : createArrayType(
1338:                                                    enclosingVariables[i],
1339:                                                    dimension);
1340:                        }
1341:                    } while ((enclosingType = enclosingType.enclosingType()) != null);
1342:                    problemReporter.undefinedTypeVariableSignature(
1343:                            CharOperation.subarray(wrapper.signature, varStart,
1344:                                    varEnd), initialType);
1345:                    return null; // cannot reach this, since previous problem will abort compilation
1346:                }
1347:                boolean isParameterized;
1348:                TypeBinding type = getTypeFromSignature(wrapper.signature,
1349:                        wrapper.start, wrapper.computeEnd(),
1350:                        isParameterized = (wrapper.end == wrapper.bracket),
1351:                        enclosingType);
1352:                if (!isParameterized)
1353:                    return dimension == 0 ? type : createArrayType(type,
1354:                            dimension);
1355:
1356:                // type must be a ReferenceBinding at this point, cannot be a BaseTypeBinding or ArrayTypeBinding
1357:                ReferenceBinding actualType = (ReferenceBinding) type;
1358:                if (actualType instanceof  UnresolvedReferenceBinding)
1359:                    if (CharOperation
1360:                            .indexOf(
1361:                                    '$',
1362:                                    actualType.compoundName[actualType.compoundName.length - 1]) > 0)
1363:                        actualType = BinaryTypeBinding.resolveType(actualType,
1364:                                this , false); // must resolve member types before asking for enclosingType
1365:                ReferenceBinding genericType = actualType;
1366:                ReferenceBinding actualEnclosing = actualType.enclosingType();
1367:                if (actualEnclosing != null) { // convert needed if read some static member type
1368:                    actualEnclosing = (ReferenceBinding) convertToRawType(actualEnclosing);
1369:                    // The actualType needs to be a ParameterizedTypeBinding when its a member type, whose enclosing type is a generic
1370:                    genericType = createParameterizedType(actualType, null,
1371:                            actualEnclosing);
1372:                }
1373:                TypeBinding[] typeArguments = getTypeArgumentsFromSignature(
1374:                        wrapper, staticVariables, enclosingType, genericType);
1375:                ParameterizedTypeBinding parameterizedType = createParameterizedType(
1376:                        actualType, typeArguments, actualEnclosing);
1377:
1378:                while (wrapper.signature[wrapper.start] == '.') {
1379:                    wrapper.start++; // skip '.'
1380:                    char[] memberName = wrapper.nextWord();
1381:                    BinaryTypeBinding.resolveType(parameterizedType, this ,
1382:                            false);
1383:                    ReferenceBinding memberType = parameterizedType
1384:                            .genericType().getMemberType(memberName);
1385:                    if (wrapper.signature[wrapper.start] == '<') {
1386:                        wrapper.start++; // skip '<'
1387:                        typeArguments = getTypeArgumentsFromSignature(wrapper,
1388:                                staticVariables, enclosingType, memberType);
1389:                    } else {
1390:                        typeArguments = null;
1391:                    }
1392:                    parameterizedType = createParameterizedType(memberType,
1393:                            typeArguments, parameterizedType);
1394:                }
1395:                wrapper.start++; // skip ';'
1396:                return dimension == 0 ? (TypeBinding) parameterizedType
1397:                        : createArrayType(parameterizedType, dimension);
1398:            }
1399:
1400:            TypeBinding getTypeFromVariantTypeSignature(
1401:                    SignatureWrapper wrapper,
1402:                    TypeVariableBinding[] staticVariables,
1403:                    ReferenceBinding enclosingType,
1404:                    ReferenceBinding genericType, int rank) {
1405:                // VariantTypeSignature = '-' TypeSignature
1406:                //   or '+' TypeSignature
1407:                //   or TypeSignature
1408:                //   or '*'
1409:                switch (wrapper.signature[wrapper.start]) {
1410:                case '-':
1411:                    // ? super aType
1412:                    wrapper.start++;
1413:                    TypeBinding bound = getTypeFromTypeSignature(wrapper,
1414:                            staticVariables, enclosingType);
1415:                    return createWildcard(genericType, rank, bound,
1416:                            null /*no extra bound*/, Wildcard.SUPER);
1417:                case '+':
1418:                    // ? extends aType
1419:                    wrapper.start++;
1420:                    bound = getTypeFromTypeSignature(wrapper, staticVariables,
1421:                            enclosingType);
1422:                    return createWildcard(genericType, rank, bound,
1423:                            null /*no extra bound*/, Wildcard.EXTENDS);
1424:                case '*':
1425:                    // ?
1426:                    wrapper.start++;
1427:                    return createWildcard(genericType, rank, null,
1428:                            null /*no extra bound*/, Wildcard.UNBOUND);
1429:                default:
1430:                    return getTypeFromTypeSignature(wrapper, staticVariables,
1431:                            enclosingType);
1432:                }
1433:            }
1434:
1435:            /* Ask the oracle if a package exists named name in the package named compoundName.
1436:             */
1437:            boolean isPackage(char[][] compoundName, char[] name) {
1438:                if (compoundName == null || compoundName.length == 0)
1439:                    return nameEnvironment.isPackage(null, name);
1440:                return nameEnvironment.isPackage(compoundName, name);
1441:            }
1442:
1443:            // The method verifier is lazily initialized to guarantee the receiver, the compiler & the oracle are ready.
1444:
1445:            public MethodVerifier methodVerifier() {
1446:                if (verifier == null)
1447:                    verifier = this .globalOptions.sourceLevel < ClassFileConstants.JDK1_5 ? new MethodVerifier(
1448:                            this )
1449:                            : new MethodVerifier15(this ); // covariance only if sourceLevel is >= 1.5
1450:                return verifier;
1451:            }
1452:
1453:            public void reset() {
1454:                this .defaultPackage = new PackageBinding(this ); // assume the default package always exists
1455:                this .defaultImports = null;
1456:                this .knownPackages = new HashtableOfPackage();
1457:                this .accessRestrictions = new HashMap(3);
1458:
1459:                this .verifier = null;
1460:                for (int i = this .uniqueArrayBindings.length; --i >= 0;) {
1461:                    ArrayBinding[] arrayBindings = this .uniqueArrayBindings[i];
1462:                    if (arrayBindings != null)
1463:                        for (int j = arrayBindings.length; --j >= 0;)
1464:                            arrayBindings[j] = null;
1465:                }
1466:                this .uniqueParameterizedTypeBindings = new SimpleLookupTable(3);
1467:                this .uniqueRawTypeBindings = new SimpleLookupTable(3);
1468:                this .uniqueWildcardBindings = new SimpleLookupTable(3);
1469:                this .uniqueParameterizedGenericMethodBindings = new SimpleLookupTable(
1470:                        3);
1471:
1472:                for (int i = this .units.length; --i >= 0;)
1473:                    this .units[i] = null;
1474:                this .lastUnitIndex = -1;
1475:                this .lastCompletedUnitIndex = -1;
1476:                this .unitBeingCompleted = null; // in case AbortException occurred
1477:
1478:                this .classFilePool.reset();
1479:                // name environment has a longer life cycle, and must be reset in
1480:                // the code which created it.
1481:            }
1482:
1483:            /**
1484:             * Associate a given type with some access restriction
1485:             * (did not store the restriction directly into binding, since sparse information)
1486:             */
1487:            public void setAccessRestriction(ReferenceBinding type,
1488:                    AccessRestriction accessRestriction) {
1489:                if (accessRestriction == null)
1490:                    return;
1491:                type.modifiers |= ExtraCompilerModifiers.AccRestrictedAccess;
1492:                this .accessRestrictions.put(type, accessRestriction);
1493:            }
1494:
1495:            void updateCaches(UnresolvedReferenceBinding unresolvedType,
1496:                    ReferenceBinding resolvedType) {
1497:                // walk all the unique collections & replace the unresolvedType with the resolvedType
1498:                // must prevent 2 entries so == still works (1 containing the unresolvedType and the other containing the resolvedType)
1499:                if (this .uniqueParameterizedTypeBindings.get(unresolvedType) != null) { // update the key
1500:                    Object[] keys = this .uniqueParameterizedTypeBindings.keyTable;
1501:                    for (int i = 0, l = keys.length; i < l; i++) {
1502:                        if (keys[i] == unresolvedType) {
1503:                            keys[i] = resolvedType; // hashCode is based on compoundName so this works - cannot be raw since type of parameterized type
1504:                            break;
1505:                        }
1506:                    }
1507:                }
1508:
1509:                if (this .uniqueWildcardBindings.get(unresolvedType) != null) { // update the key
1510:                    Object[] keys = this .uniqueWildcardBindings.keyTable;
1511:                    for (int i = 0, l = keys.length; i < l; i++) {
1512:                        if (keys[i] == unresolvedType) {
1513:                            keys[i] = resolvedType; // hashCode is based on compoundName so this works
1514:                            break;
1515:                        }
1516:                    }
1517:                }
1518:            }
1519:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.