Source Code Cross Referenced for SourceTypeBinding.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.Hashtable;
0014:        import java.util.Iterator;
0015:
0016:        import org.eclipse.jdt.core.compiler.CharOperation;
0017:        import org.eclipse.jdt.internal.compiler.ast.ASTNode;
0018:        import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
0019:        import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
0020:        import org.eclipse.jdt.internal.compiler.ast.Argument;
0021:        import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
0022:        import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
0023:        import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
0024:        import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
0025:        import org.eclipse.jdt.internal.compiler.ast.TypeReference;
0026:        import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
0027:        import org.eclipse.jdt.internal.compiler.impl.Constant;
0028:        import org.eclipse.jdt.internal.compiler.util.Util;
0029:        import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
0030:
0031:        public class SourceTypeBinding extends ReferenceBinding {
0032:            public ReferenceBinding super class;
0033:            public ReferenceBinding[] super Interfaces;
0034:            private FieldBinding[] fields;
0035:            private MethodBinding[] methods;
0036:            public ReferenceBinding[] memberTypes;
0037:            public TypeVariableBinding[] typeVariables;
0038:
0039:            public ClassScope scope;
0040:
0041:            // Synthetics are separated into 5 categories: methods, super methods, fields, class literals, changed declaring type bindings and bridge methods
0042:            public final static int METHOD_EMUL = 0;
0043:            public final static int FIELD_EMUL = 1;
0044:            public final static int CLASS_LITERAL_EMUL = 2;
0045:            public final static int RECEIVER_TYPE_EMUL = 3;
0046:            HashMap[] synthetics;
0047:            char[] genericReferenceTypeSignature;
0048:
0049:            private SimpleLookupTable storedAnnotations = null; // keys are this ReferenceBinding & its fields and methods, value is an AnnotationHolder
0050:
0051:            public SourceTypeBinding(char[][] compoundName,
0052:                    PackageBinding fPackage, ClassScope scope) {
0053:                this .compoundName = compoundName;
0054:                this .fPackage = fPackage;
0055:                this .fileName = scope.referenceCompilationUnit().getFileName();
0056:                this .modifiers = scope.referenceContext.modifiers;
0057:                this .sourceName = scope.referenceContext.name;
0058:                this .scope = scope;
0059:
0060:                // expect the fields & methods to be initialized correctly later
0061:                this .fields = Binding.NO_FIELDS;
0062:                this .methods = Binding.NO_METHODS;
0063:
0064:                computeId();
0065:            }
0066:
0067:            private void addDefaultAbstractMethods() {
0068:                if ((this .tagBits & TagBits.KnowsDefaultAbstractMethods) != 0)
0069:                    return;
0070:
0071:                this .tagBits |= TagBits.KnowsDefaultAbstractMethods;
0072:                if (isClass() && isAbstract()) {
0073:                    if (this .scope.compilerOptions().targetJDK >= ClassFileConstants.JDK1_2)
0074:                        return; // no longer added for post 1.2 targets
0075:
0076:                    ReferenceBinding[] itsInterfaces = super Interfaces();
0077:                    if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
0078:                        MethodBinding[] defaultAbstracts = null;
0079:                        int defaultAbstractsCount = 0;
0080:                        ReferenceBinding[] interfacesToVisit = itsInterfaces;
0081:                        int nextPosition = interfacesToVisit.length;
0082:                        for (int i = 0; i < nextPosition; i++) {
0083:                            ReferenceBinding super Type = interfacesToVisit[i];
0084:                            if (super Type.isValidBinding()) {
0085:                                MethodBinding[] super Methods = super Type
0086:                                        .methods();
0087:                                nextAbstractMethod: for (int m = super Methods.length; --m >= 0;) {
0088:                                    MethodBinding method = super Methods[m];
0089:                                    // explicitly implemented ?
0090:                                    if (implements Method(method))
0091:                                        continue nextAbstractMethod;
0092:                                    if (defaultAbstractsCount == 0) {
0093:                                        defaultAbstracts = new MethodBinding[5];
0094:                                    } else {
0095:                                        // already added as default abstract ?
0096:                                        for (int k = 0; k < defaultAbstractsCount; k++) {
0097:                                            MethodBinding alreadyAdded = defaultAbstracts[k];
0098:                                            if (CharOperation.equals(
0099:                                                    alreadyAdded.selector,
0100:                                                    method.selector)
0101:                                                    && alreadyAdded
0102:                                                            .areParametersEqual(method))
0103:                                                continue nextAbstractMethod;
0104:                                        }
0105:                                    }
0106:                                    MethodBinding defaultAbstract = new MethodBinding(
0107:                                            method.modifiers
0108:                                                    | ExtraCompilerModifiers.AccDefaultAbstract,
0109:                                            method.selector, method.returnType,
0110:                                            method.parameters,
0111:                                            method.thrownExceptions, this );
0112:                                    if (defaultAbstractsCount == defaultAbstracts.length)
0113:                                        System
0114:                                                .arraycopy(
0115:                                                        defaultAbstracts,
0116:                                                        0,
0117:                                                        defaultAbstracts = new MethodBinding[2 * defaultAbstractsCount],
0118:                                                        0,
0119:                                                        defaultAbstractsCount);
0120:                                    defaultAbstracts[defaultAbstractsCount++] = defaultAbstract;
0121:                                }
0122:
0123:                                if ((itsInterfaces = super Type
0124:                                        .super Interfaces()) != Binding.NO_SUPERINTERFACES) {
0125:                                    int itsLength = itsInterfaces.length;
0126:                                    if (nextPosition + itsLength >= interfacesToVisit.length)
0127:                                        System
0128:                                                .arraycopy(
0129:                                                        interfacesToVisit,
0130:                                                        0,
0131:                                                        interfacesToVisit = new ReferenceBinding[nextPosition
0132:                                                                + itsLength + 5],
0133:                                                        0, nextPosition);
0134:                                    nextInterface: for (int a = 0; a < itsLength; a++) {
0135:                                        ReferenceBinding next = itsInterfaces[a];
0136:                                        for (int b = 0; b < nextPosition; b++)
0137:                                            if (next == interfacesToVisit[b])
0138:                                                continue nextInterface;
0139:                                        interfacesToVisit[nextPosition++] = next;
0140:                                    }
0141:                                }
0142:                            }
0143:                        }
0144:                        if (defaultAbstractsCount > 0) {
0145:                            int length = this .methods.length;
0146:                            System
0147:                                    .arraycopy(
0148:                                            this .methods,
0149:                                            0,
0150:                                            this .methods = new MethodBinding[length
0151:                                                    + defaultAbstractsCount],
0152:                                            0, length);
0153:                            System.arraycopy(defaultAbstracts, 0, this .methods,
0154:                                    length, defaultAbstractsCount);
0155:                            // re-sort methods
0156:                            length = length + defaultAbstractsCount;
0157:                            if (length > 1)
0158:                                ReferenceBinding.sortMethods(this .methods, 0,
0159:                                        length);
0160:                            // this.tagBits |= TagBits.AreMethodsSorted; -- already set in #methods()
0161:                        }
0162:                    }
0163:                }
0164:            }
0165:
0166:            /* Add a new synthetic field for <actualOuterLocalVariable>.
0167:             *	Answer the new field or the existing field if one already existed.
0168:             */
0169:            public FieldBinding addSyntheticFieldForInnerclass(
0170:                    LocalVariableBinding actualOuterLocalVariable) {
0171:                if (this .synthetics == null)
0172:                    this .synthetics = new HashMap[4];
0173:                if (this .synthetics[SourceTypeBinding.FIELD_EMUL] == null)
0174:                    this .synthetics[SourceTypeBinding.FIELD_EMUL] = new HashMap(
0175:                            5);
0176:
0177:                FieldBinding synthField = (FieldBinding) this .synthetics[SourceTypeBinding.FIELD_EMUL]
0178:                        .get(actualOuterLocalVariable);
0179:                if (synthField == null) {
0180:                    synthField = new SyntheticFieldBinding(CharOperation
0181:                            .concat(TypeConstants.SYNTHETIC_OUTER_LOCAL_PREFIX,
0182:                                    actualOuterLocalVariable.name),
0183:                            actualOuterLocalVariable.type,
0184:                            ClassFileConstants.AccPrivate
0185:                                    | ClassFileConstants.AccFinal
0186:                                    | ClassFileConstants.AccSynthetic, this ,
0187:                            Constant.NotAConstant,
0188:                            this .synthetics[SourceTypeBinding.FIELD_EMUL]
0189:                                    .size());
0190:                    this .synthetics[SourceTypeBinding.FIELD_EMUL].put(
0191:                            actualOuterLocalVariable, synthField);
0192:                }
0193:
0194:                // ensure there is not already such a field defined by the user
0195:                boolean needRecheck;
0196:                int index = 1;
0197:                do {
0198:                    needRecheck = false;
0199:                    FieldBinding existingField;
0200:                    if ((existingField = this 
0201:                            .getField(synthField.name, true /*resolve*/)) != null) {
0202:                        TypeDeclaration typeDecl = this .scope.referenceContext;
0203:                        for (int i = 0, max = typeDecl.fields.length; i < max; i++) {
0204:                            FieldDeclaration fieldDecl = typeDecl.fields[i];
0205:                            if (fieldDecl.binding == existingField) {
0206:                                synthField.name = CharOperation
0207:                                        .concat(
0208:                                                TypeConstants.SYNTHETIC_OUTER_LOCAL_PREFIX,
0209:                                                actualOuterLocalVariable.name,
0210:                                                ("$" + String.valueOf(index++)).toCharArray()); //$NON-NLS-1$
0211:                                needRecheck = true;
0212:                                break;
0213:                            }
0214:                        }
0215:                    }
0216:                } while (needRecheck);
0217:                return synthField;
0218:            }
0219:
0220:            /* Add a new synthetic field for <enclosingType>.
0221:             *	Answer the new field or the existing field if one already existed.
0222:             */
0223:            public FieldBinding addSyntheticFieldForInnerclass(
0224:                    ReferenceBinding enclosingType) {
0225:                if (this .synthetics == null)
0226:                    this .synthetics = new HashMap[4];
0227:                if (this .synthetics[SourceTypeBinding.FIELD_EMUL] == null)
0228:                    this .synthetics[SourceTypeBinding.FIELD_EMUL] = new HashMap(
0229:                            5);
0230:
0231:                FieldBinding synthField = (FieldBinding) this .synthetics[SourceTypeBinding.FIELD_EMUL]
0232:                        .get(enclosingType);
0233:                if (synthField == null) {
0234:                    synthField = new SyntheticFieldBinding(
0235:                            CharOperation
0236:                                    .concat(
0237:                                            TypeConstants.SYNTHETIC_ENCLOSING_INSTANCE_PREFIX,
0238:                                            String.valueOf(
0239:                                                    enclosingType.depth())
0240:                                                    .toCharArray()),
0241:                            enclosingType, ClassFileConstants.AccDefault
0242:                                    | ClassFileConstants.AccFinal
0243:                                    | ClassFileConstants.AccSynthetic, this ,
0244:                            Constant.NotAConstant,
0245:                            this .synthetics[SourceTypeBinding.FIELD_EMUL]
0246:                                    .size());
0247:                    this .synthetics[SourceTypeBinding.FIELD_EMUL].put(
0248:                            enclosingType, synthField);
0249:                }
0250:                // ensure there is not already such a field defined by the user
0251:                boolean needRecheck;
0252:                do {
0253:                    needRecheck = false;
0254:                    FieldBinding existingField;
0255:                    if ((existingField = this 
0256:                            .getField(synthField.name, true /*resolve*/)) != null) {
0257:                        TypeDeclaration typeDecl = this .scope.referenceContext;
0258:                        for (int i = 0, max = typeDecl.fields.length; i < max; i++) {
0259:                            FieldDeclaration fieldDecl = typeDecl.fields[i];
0260:                            if (fieldDecl.binding == existingField) {
0261:                                if (this .scope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_5) {
0262:                                    synthField.name = CharOperation.concat(
0263:                                            synthField.name, "$".toCharArray()); //$NON-NLS-1$
0264:                                    needRecheck = true;
0265:                                } else {
0266:                                    this .scope.problemReporter()
0267:                                            .duplicateFieldInType(this ,
0268:                                                    fieldDecl);
0269:                                }
0270:                                break;
0271:                            }
0272:                        }
0273:                    }
0274:                } while (needRecheck);
0275:                return synthField;
0276:            }
0277:
0278:            /* Add a new synthetic field for a class literal access.
0279:             *	Answer the new field or the existing field if one already existed.
0280:             */
0281:            public FieldBinding addSyntheticFieldForClassLiteral(
0282:                    TypeBinding targetType, BlockScope blockScope) {
0283:                if (this .synthetics == null)
0284:                    this .synthetics = new HashMap[4];
0285:                if (this .synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL] == null)
0286:                    this .synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL] = new HashMap(
0287:                            5);
0288:
0289:                // use a different table than FIELDS, given there might be a collision between emulation of X.this$0 and X.class.
0290:                FieldBinding synthField = (FieldBinding) this .synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL]
0291:                        .get(targetType);
0292:                if (synthField == null) {
0293:                    synthField = new SyntheticFieldBinding(
0294:                            CharOperation
0295:                                    .concat(
0296:                                            TypeConstants.SYNTHETIC_CLASS,
0297:                                            String
0298:                                                    .valueOf(
0299:                                                            this .synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL]
0300:                                                                    .size())
0301:                                                    .toCharArray()),
0302:                            blockScope.getJavaLangClass(),
0303:                            ClassFileConstants.AccDefault
0304:                                    | ClassFileConstants.AccStatic
0305:                                    | ClassFileConstants.AccSynthetic,
0306:                            this ,
0307:                            Constant.NotAConstant,
0308:                            this .synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL]
0309:                                    .size());
0310:                    this .synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL].put(
0311:                            targetType, synthField);
0312:                }
0313:                // ensure there is not already such a field defined by the user
0314:                FieldBinding existingField;
0315:                if ((existingField = this 
0316:                        .getField(synthField.name, true /*resolve*/)) != null) {
0317:                    TypeDeclaration typeDecl = blockScope.referenceType();
0318:                    for (int i = 0, max = typeDecl.fields.length; i < max; i++) {
0319:                        FieldDeclaration fieldDecl = typeDecl.fields[i];
0320:                        if (fieldDecl.binding == existingField) {
0321:                            blockScope.problemReporter().duplicateFieldInType(
0322:                                    this , fieldDecl);
0323:                            break;
0324:                        }
0325:                    }
0326:                }
0327:                return synthField;
0328:            }
0329:
0330:            /* Add a new synthetic field for the emulation of the assert statement.
0331:             *	Answer the new field or the existing field if one already existed.
0332:             */
0333:            public FieldBinding addSyntheticFieldForAssert(BlockScope blockScope) {
0334:                if (this .synthetics == null)
0335:                    this .synthetics = new HashMap[4];
0336:                if (this .synthetics[SourceTypeBinding.FIELD_EMUL] == null)
0337:                    this .synthetics[SourceTypeBinding.FIELD_EMUL] = new HashMap(
0338:                            5);
0339:
0340:                FieldBinding synthField = (FieldBinding) this .synthetics[SourceTypeBinding.FIELD_EMUL]
0341:                        .get("assertionEmulation"); //$NON-NLS-1$
0342:                if (synthField == null) {
0343:                    synthField = new SyntheticFieldBinding(
0344:                            TypeConstants.SYNTHETIC_ASSERT_DISABLED,
0345:                            TypeBinding.BOOLEAN, ClassFileConstants.AccDefault
0346:                                    | ClassFileConstants.AccStatic
0347:                                    | ClassFileConstants.AccSynthetic
0348:                                    | ClassFileConstants.AccFinal, this ,
0349:                            Constant.NotAConstant,
0350:                            this .synthetics[SourceTypeBinding.FIELD_EMUL]
0351:                                    .size());
0352:                    this .synthetics[SourceTypeBinding.FIELD_EMUL].put(
0353:                            "assertionEmulation", synthField); //$NON-NLS-1$
0354:                }
0355:                // ensure there is not already such a field defined by the user
0356:                // ensure there is not already such a field defined by the user
0357:                boolean needRecheck;
0358:                int index = 0;
0359:                do {
0360:                    needRecheck = false;
0361:                    FieldBinding existingField;
0362:                    if ((existingField = this 
0363:                            .getField(synthField.name, true /*resolve*/)) != null) {
0364:                        TypeDeclaration typeDecl = this .scope.referenceContext;
0365:                        for (int i = 0, max = typeDecl.fields.length; i < max; i++) {
0366:                            FieldDeclaration fieldDecl = typeDecl.fields[i];
0367:                            if (fieldDecl.binding == existingField) {
0368:                                synthField.name = CharOperation
0369:                                        .concat(
0370:                                                TypeConstants.SYNTHETIC_ASSERT_DISABLED,
0371:                                                ("_" + String.valueOf(index++)).toCharArray()); //$NON-NLS-1$
0372:                                needRecheck = true;
0373:                                break;
0374:                            }
0375:                        }
0376:                    }
0377:                } while (needRecheck);
0378:                return synthField;
0379:            }
0380:
0381:            /* Add a new synthetic field for recording all enum constant values
0382:             *	Answer the new field or the existing field if one already existed.
0383:             */
0384:            public FieldBinding addSyntheticFieldForEnumValues() {
0385:                if (this .synthetics == null)
0386:                    this .synthetics = new HashMap[4];
0387:                if (this .synthetics[SourceTypeBinding.FIELD_EMUL] == null)
0388:                    this .synthetics[SourceTypeBinding.FIELD_EMUL] = new HashMap(
0389:                            5);
0390:
0391:                FieldBinding synthField = (FieldBinding) this .synthetics[SourceTypeBinding.FIELD_EMUL]
0392:                        .get("enumConstantValues"); //$NON-NLS-1$
0393:                if (synthField == null) {
0394:                    synthField = new SyntheticFieldBinding(
0395:                            TypeConstants.SYNTHETIC_ENUM_VALUES, this .scope
0396:                                    .createArrayType(this , 1),
0397:                            ClassFileConstants.AccPrivate
0398:                                    | ClassFileConstants.AccStatic
0399:                                    | ClassFileConstants.AccSynthetic
0400:                                    | ClassFileConstants.AccFinal, this ,
0401:                            Constant.NotAConstant,
0402:                            this .synthetics[SourceTypeBinding.FIELD_EMUL]
0403:                                    .size());
0404:                    this .synthetics[SourceTypeBinding.FIELD_EMUL].put(
0405:                            "enumConstantValues", synthField); //$NON-NLS-1$
0406:                }
0407:                // ensure there is not already such a field defined by the user
0408:                // ensure there is not already such a field defined by the user
0409:                boolean needRecheck;
0410:                int index = 0;
0411:                do {
0412:                    needRecheck = false;
0413:                    FieldBinding existingField;
0414:                    if ((existingField = this 
0415:                            .getField(synthField.name, true /*resolve*/)) != null) {
0416:                        TypeDeclaration typeDecl = this .scope.referenceContext;
0417:                        for (int i = 0, max = typeDecl.fields.length; i < max; i++) {
0418:                            FieldDeclaration fieldDecl = typeDecl.fields[i];
0419:                            if (fieldDecl.binding == existingField) {
0420:                                synthField.name = CharOperation
0421:                                        .concat(
0422:                                                TypeConstants.SYNTHETIC_ENUM_VALUES,
0423:                                                ("_" + String.valueOf(index++)).toCharArray()); //$NON-NLS-1$
0424:                                needRecheck = true;
0425:                                break;
0426:                            }
0427:                        }
0428:                    }
0429:                } while (needRecheck);
0430:                return synthField;
0431:            }
0432:
0433:            /* Add a new synthetic access method for read/write access to <targetField>.
0434:             Answer the new method or the existing method if one already existed.
0435:             */
0436:            public SyntheticMethodBinding addSyntheticMethod(
0437:                    FieldBinding targetField, boolean isReadAccess) {
0438:                if (this .synthetics == null)
0439:                    this .synthetics = new HashMap[4];
0440:                if (this .synthetics[SourceTypeBinding.METHOD_EMUL] == null)
0441:                    this .synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap(
0442:                            5);
0443:
0444:                SyntheticMethodBinding accessMethod = null;
0445:                SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) this .synthetics[SourceTypeBinding.METHOD_EMUL]
0446:                        .get(targetField);
0447:                if (accessors == null) {
0448:                    accessMethod = new SyntheticMethodBinding(targetField,
0449:                            isReadAccess, this );
0450:                    this .synthetics[SourceTypeBinding.METHOD_EMUL].put(
0451:                            targetField,
0452:                            accessors = new SyntheticMethodBinding[2]);
0453:                    accessors[isReadAccess ? 0 : 1] = accessMethod;
0454:                } else {
0455:                    if ((accessMethod = accessors[isReadAccess ? 0 : 1]) == null) {
0456:                        accessMethod = new SyntheticMethodBinding(targetField,
0457:                                isReadAccess, this );
0458:                        accessors[isReadAccess ? 0 : 1] = accessMethod;
0459:                    }
0460:                }
0461:                return accessMethod;
0462:            }
0463:
0464:            /* Add a new synthetic method the enum type. Selector can either be 'values' or 'valueOf'.
0465:             * char[] constants from TypeConstants must be used: TypeConstants.VALUES/VALUEOF
0466:             */
0467:            public SyntheticMethodBinding addSyntheticEnumMethod(char[] selector) {
0468:                if (this .synthetics == null)
0469:                    this .synthetics = new HashMap[4];
0470:                if (this .synthetics[SourceTypeBinding.METHOD_EMUL] == null)
0471:                    this .synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap(
0472:                            5);
0473:
0474:                SyntheticMethodBinding accessMethod = null;
0475:                SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) this .synthetics[SourceTypeBinding.METHOD_EMUL]
0476:                        .get(selector);
0477:                if (accessors == null) {
0478:                    accessMethod = new SyntheticMethodBinding(this , selector);
0479:                    this .synthetics[SourceTypeBinding.METHOD_EMUL]
0480:                            .put(selector,
0481:                                    accessors = new SyntheticMethodBinding[2]);
0482:                    accessors[0] = accessMethod;
0483:                } else {
0484:                    if ((accessMethod = accessors[0]) == null) {
0485:                        accessMethod = new SyntheticMethodBinding(this ,
0486:                                selector);
0487:                        accessors[0] = accessMethod;
0488:                    }
0489:                }
0490:                return accessMethod;
0491:            }
0492:
0493:            /*
0494:             * Add a synthetic field to handle the cache of the switch translation table for the corresponding enum type 
0495:             */
0496:            public SyntheticFieldBinding addSyntheticFieldForSwitchEnum(
0497:                    char[] fieldName, String key) {
0498:                if (this .synthetics == null)
0499:                    this .synthetics = new HashMap[4];
0500:                if (this .synthetics[SourceTypeBinding.FIELD_EMUL] == null)
0501:                    this .synthetics[SourceTypeBinding.FIELD_EMUL] = new HashMap(
0502:                            5);
0503:
0504:                SyntheticFieldBinding synthField = (SyntheticFieldBinding) this .synthetics[SourceTypeBinding.FIELD_EMUL]
0505:                        .get(key);
0506:                if (synthField == null) {
0507:                    synthField = new SyntheticFieldBinding(fieldName,
0508:                            this .scope.createArrayType(TypeBinding.INT, 1),
0509:                            ClassFileConstants.AccPrivate
0510:                                    | ClassFileConstants.AccStatic
0511:                                    | ClassFileConstants.AccSynthetic, this ,
0512:                            Constant.NotAConstant,
0513:                            this .synthetics[SourceTypeBinding.FIELD_EMUL]
0514:                                    .size());
0515:                    this .synthetics[SourceTypeBinding.FIELD_EMUL].put(key,
0516:                            synthField);
0517:                }
0518:                // ensure there is not already such a field defined by the user
0519:                boolean needRecheck;
0520:                int index = 0;
0521:                do {
0522:                    needRecheck = false;
0523:                    FieldBinding existingField;
0524:                    if ((existingField = this 
0525:                            .getField(synthField.name, true /*resolve*/)) != null) {
0526:                        TypeDeclaration typeDecl = this .scope.referenceContext;
0527:                        for (int i = 0, max = typeDecl.fields.length; i < max; i++) {
0528:                            FieldDeclaration fieldDecl = typeDecl.fields[i];
0529:                            if (fieldDecl.binding == existingField) {
0530:                                synthField.name = CharOperation
0531:                                        .concat(
0532:                                                fieldName,
0533:                                                ("_" + String.valueOf(index++)).toCharArray()); //$NON-NLS-1$
0534:                                needRecheck = true;
0535:                                break;
0536:                            }
0537:                        }
0538:                    }
0539:                } while (needRecheck);
0540:                return synthField;
0541:            }
0542:
0543:            /* Add a new synthetic method the enum type. Selector can either be 'values' or 'valueOf'.
0544:             * char[] constants from TypeConstants must be used: TypeConstants.VALUES/VALUEOF
0545:             */
0546:            public SyntheticMethodBinding addSyntheticMethodForSwitchEnum(
0547:                    TypeBinding enumBinding) {
0548:                if (this .synthetics == null)
0549:                    this .synthetics = new HashMap[4];
0550:                if (this .synthetics[SourceTypeBinding.METHOD_EMUL] == null)
0551:                    this .synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap(
0552:                            5);
0553:
0554:                SyntheticMethodBinding accessMethod = null;
0555:                char[] selector = CharOperation.concat(
0556:                        TypeConstants.SYNTHETIC_SWITCH_ENUM_TABLE, enumBinding
0557:                                .constantPoolName());
0558:                CharOperation.replace(selector, '/', '$');
0559:                final String key = new String(selector);
0560:                SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) this .synthetics[SourceTypeBinding.METHOD_EMUL]
0561:                        .get(key);
0562:                // first add the corresponding synthetic field
0563:                if (accessors == null) {
0564:                    // then create the synthetic method
0565:                    final SyntheticFieldBinding fieldBinding = this 
0566:                            .addSyntheticFieldForSwitchEnum(selector, key);
0567:                    accessMethod = new SyntheticMethodBinding(fieldBinding,
0568:                            this , enumBinding, selector);
0569:                    this .synthetics[SourceTypeBinding.METHOD_EMUL].put(key,
0570:                            accessors = new SyntheticMethodBinding[2]);
0571:                    accessors[0] = accessMethod;
0572:                } else {
0573:                    if ((accessMethod = accessors[0]) == null) {
0574:                        final SyntheticFieldBinding fieldBinding = this 
0575:                                .addSyntheticFieldForSwitchEnum(selector, key);
0576:                        accessMethod = new SyntheticMethodBinding(fieldBinding,
0577:                                this , enumBinding, selector);
0578:                        accessors[0] = accessMethod;
0579:                    }
0580:                }
0581:                return accessMethod;
0582:            }
0583:
0584:            /* Add a new synthetic access method for access to <targetMethod>.
0585:             * Must distinguish access method used for super access from others (need to use invokespecial bytecode)
0586:             Answer the new method or the existing method if one already existed.
0587:             */
0588:            public SyntheticMethodBinding addSyntheticMethod(
0589:                    MethodBinding targetMethod, boolean isSuperAccess) {
0590:                if (this .synthetics == null)
0591:                    this .synthetics = new HashMap[4];
0592:                if (this .synthetics[SourceTypeBinding.METHOD_EMUL] == null)
0593:                    this .synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap(
0594:                            5);
0595:
0596:                SyntheticMethodBinding accessMethod = null;
0597:                SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) this .synthetics[SourceTypeBinding.METHOD_EMUL]
0598:                        .get(targetMethod);
0599:                if (accessors == null) {
0600:                    accessMethod = new SyntheticMethodBinding(targetMethod,
0601:                            isSuperAccess, this );
0602:                    this .synthetics[SourceTypeBinding.METHOD_EMUL].put(
0603:                            targetMethod,
0604:                            accessors = new SyntheticMethodBinding[2]);
0605:                    accessors[isSuperAccess ? 0 : 1] = accessMethod;
0606:                } else {
0607:                    if ((accessMethod = accessors[isSuperAccess ? 0 : 1]) == null) {
0608:                        accessMethod = new SyntheticMethodBinding(targetMethod,
0609:                                isSuperAccess, this );
0610:                        accessors[isSuperAccess ? 0 : 1] = accessMethod;
0611:                    }
0612:                }
0613:                return accessMethod;
0614:            }
0615:
0616:            /* 
0617:             * Record the fact that bridge methods need to be generated to override certain inherited methods
0618:             */
0619:            public SyntheticMethodBinding addSyntheticBridgeMethod(
0620:                    MethodBinding inheritedMethodToBridge,
0621:                    MethodBinding targetMethod) {
0622:                if (isInterface())
0623:                    return null; // only classes & enums get bridge methods
0624:                // targetMethod may be inherited
0625:                if (inheritedMethodToBridge.returnType.erasure() == targetMethod.returnType
0626:                        .erasure()
0627:                        && inheritedMethodToBridge
0628:                                .areParameterErasuresEqual(targetMethod)) {
0629:                    return null; // do not need bridge method
0630:                }
0631:                if (this .synthetics == null)
0632:                    this .synthetics = new HashMap[4];
0633:                if (this .synthetics[SourceTypeBinding.METHOD_EMUL] == null) {
0634:                    this .synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap(
0635:                            5);
0636:                } else {
0637:                    // check to see if there is another equivalent inheritedMethod already added
0638:                    Iterator synthMethods = this .synthetics[SourceTypeBinding.METHOD_EMUL]
0639:                            .keySet().iterator();
0640:                    while (synthMethods.hasNext()) {
0641:                        Object synthetic = synthMethods.next();
0642:                        if (synthetic instanceof  MethodBinding) {
0643:                            MethodBinding method = (MethodBinding) synthetic;
0644:                            if (CharOperation.equals(
0645:                                    inheritedMethodToBridge.selector,
0646:                                    method.selector)
0647:                                    && inheritedMethodToBridge.returnType
0648:                                            .erasure() == method.returnType
0649:                                            .erasure()
0650:                                    && inheritedMethodToBridge
0651:                                            .areParameterErasuresEqual(method)) {
0652:                                return null;
0653:                            }
0654:                        }
0655:                    }
0656:                }
0657:
0658:                SyntheticMethodBinding accessMethod = null;
0659:                SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) this .synthetics[SourceTypeBinding.METHOD_EMUL]
0660:                        .get(inheritedMethodToBridge);
0661:                if (accessors == null) {
0662:                    accessMethod = new SyntheticMethodBinding(
0663:                            inheritedMethodToBridge, targetMethod, this );
0664:                    this .synthetics[SourceTypeBinding.METHOD_EMUL].put(
0665:                            inheritedMethodToBridge,
0666:                            accessors = new SyntheticMethodBinding[2]);
0667:                    accessors[1] = accessMethod;
0668:                } else {
0669:                    if ((accessMethod = accessors[1]) == null) {
0670:                        accessMethod = new SyntheticMethodBinding(
0671:                                inheritedMethodToBridge, targetMethod, this );
0672:                        accessors[1] = accessMethod;
0673:                    }
0674:                }
0675:                return accessMethod;
0676:            }
0677:
0678:            public int kind() {
0679:                if (this .typeVariables != Binding.NO_TYPE_VARIABLES)
0680:                    return Binding.GENERIC_TYPE;
0681:                return Binding.TYPE;
0682:            }
0683:
0684:            public char[] computeUniqueKey(boolean isLeaf) {
0685:                char[] uniqueKey = super .computeUniqueKey(isLeaf);
0686:                if (uniqueKey.length == 2)
0687:                    return uniqueKey; // problem type's unique key is "L;"
0688:                if (Util.isClassFileName(this .fileName))
0689:                    return uniqueKey; // no need to insert compilation unit name for a .class file
0690:
0691:                // insert compilation unit name if the type name is not the main type name
0692:                int end = CharOperation.lastIndexOf('.', this .fileName);
0693:                if (end != -1) {
0694:                    int start = CharOperation.lastIndexOf('/', this .fileName) + 1;
0695:                    char[] mainTypeName = CharOperation.subarray(this .fileName,
0696:                            start, end);
0697:                    start = CharOperation.lastIndexOf('/', uniqueKey) + 1;
0698:                    if (start == 0)
0699:                        start = 1; // start after L
0700:                    end = CharOperation.indexOf('$', uniqueKey, start);
0701:                    if (end == -1)
0702:                        end = CharOperation.indexOf('<', uniqueKey, start);
0703:                    if (end == -1)
0704:                        end = CharOperation.indexOf(';', uniqueKey, start);
0705:                    char[] topLevelType = CharOperation.subarray(uniqueKey,
0706:                            start, end);
0707:                    if (!CharOperation.equals(topLevelType, mainTypeName)) {
0708:                        StringBuffer buffer = new StringBuffer();
0709:                        buffer.append(uniqueKey, 0, start);
0710:                        buffer.append(mainTypeName);
0711:                        buffer.append('~');
0712:                        buffer.append(topLevelType);
0713:                        buffer.append(uniqueKey, end, uniqueKey.length - end);
0714:                        int length = buffer.length();
0715:                        uniqueKey = new char[length];
0716:                        buffer.getChars(0, length, uniqueKey, 0);
0717:                        return uniqueKey;
0718:                    }
0719:                }
0720:                return uniqueKey;
0721:            }
0722:
0723:            void faultInTypesForFieldsAndMethods() {
0724:                // check @Deprecated annotation
0725:                getAnnotationTagBits(); // marks as deprecated by side effect
0726:                ReferenceBinding enclosingType = this .enclosingType();
0727:                if (enclosingType != null
0728:                        && enclosingType.isViewedAsDeprecated()
0729:                        && !this .isDeprecated())
0730:                    this .modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
0731:                fields();
0732:                methods();
0733:
0734:                for (int i = 0, length = this .memberTypes.length; i < length; i++)
0735:                    ((SourceTypeBinding) this .memberTypes[i])
0736:                            .faultInTypesForFieldsAndMethods();
0737:            }
0738:
0739:            // NOTE: the type of each field of a source type is resolved when needed
0740:            public FieldBinding[] fields() {
0741:                if ((this .tagBits & TagBits.AreFieldsComplete) != 0)
0742:                    return this .fields;
0743:
0744:                int failed = 0;
0745:                FieldBinding[] resolvedFields = this .fields;
0746:                try {
0747:                    // lazily sort fields
0748:                    if ((this .tagBits & TagBits.AreFieldsSorted) == 0) {
0749:                        int length = this .fields.length;
0750:                        if (length > 1)
0751:                            ReferenceBinding.sortFields(this .fields, 0, length);
0752:                        this .tagBits |= TagBits.AreFieldsSorted;
0753:                    }
0754:                    for (int i = 0, length = this .fields.length; i < length; i++) {
0755:                        if (resolveTypeFor(this .fields[i]) == null) {
0756:                            // do not alter original field array until resolution is over, due to reentrance (143259)
0757:                            if (resolvedFields == this .fields) {
0758:                                System
0759:                                        .arraycopy(
0760:                                                this .fields,
0761:                                                0,
0762:                                                resolvedFields = new FieldBinding[length],
0763:                                                0, length);
0764:                            }
0765:                            resolvedFields[i] = null;
0766:                            failed++;
0767:                        }
0768:                    }
0769:                } finally {
0770:                    if (failed > 0) {
0771:                        // ensure fields are consistent reqardless of the error
0772:                        int newSize = resolvedFields.length - failed;
0773:                        if (newSize == 0)
0774:                            return this .fields = Binding.NO_FIELDS;
0775:
0776:                        FieldBinding[] newFields = new FieldBinding[newSize];
0777:                        for (int i = 0, j = 0, length = resolvedFields.length; i < length; i++) {
0778:                            if (resolvedFields[i] != null)
0779:                                newFields[j++] = resolvedFields[i];
0780:                        }
0781:                        this .fields = newFields;
0782:                    }
0783:                }
0784:                this .tagBits |= TagBits.AreFieldsComplete;
0785:                return this .fields;
0786:            }
0787:
0788:            /**
0789:             * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#genericTypeSignature()
0790:             */
0791:            public char[] genericTypeSignature() {
0792:                if (this .genericReferenceTypeSignature == null)
0793:                    this .genericReferenceTypeSignature = computeGenericTypeSignature(this .typeVariables);
0794:                return this .genericReferenceTypeSignature;
0795:            }
0796:
0797:            /**
0798:             * <param1 ... paramN>superclass superinterface1 ... superinterfaceN
0799:             * <T:LY<TT;>;U:Ljava/lang/Object;V::Ljava/lang/Runnable;:Ljava/lang/Cloneable;:Ljava/util/Map;>Ljava/lang/Exception;Ljava/lang/Runnable;
0800:             */
0801:            public char[] genericSignature() {
0802:                StringBuffer sig = null;
0803:                if (this .typeVariables != Binding.NO_TYPE_VARIABLES) {
0804:                    sig = new StringBuffer(10);
0805:                    sig.append('<');
0806:                    for (int i = 0, length = this .typeVariables.length; i < length; i++)
0807:                        sig.append(this .typeVariables[i].genericSignature());
0808:                    sig.append('>');
0809:                } else {
0810:                    // could still need a signature if any of supertypes is parameterized
0811:                    noSignature: if (this .super class == null
0812:                            || !this .super class.isParameterizedType()) {
0813:                        for (int i = 0, length = this .super Interfaces.length; i < length; i++)
0814:                            if (this .super Interfaces[i].isParameterizedType())
0815:                                break noSignature;
0816:                        return null;
0817:                    }
0818:                    sig = new StringBuffer(10);
0819:                }
0820:                if (this .super class != null)
0821:                    sig.append(this .super class.genericTypeSignature());
0822:                else
0823:                    // interface scenario only (as Object cannot be generic) - 65953
0824:                    sig.append(this .scope.getJavaLangObject()
0825:                            .genericTypeSignature());
0826:                for (int i = 0, length = this .super Interfaces.length; i < length; i++)
0827:                    sig.append(this .super Interfaces[i].genericTypeSignature());
0828:                return sig.toString().toCharArray();
0829:            }
0830:
0831:            /**
0832:             * Compute the tagbits for standard annotations. For source types, these could require
0833:             * lazily resolving corresponding annotation nodes, in case of forward references.
0834:             * @see org.eclipse.jdt.internal.compiler.lookup.Binding#getAnnotationTagBits()
0835:             */
0836:            public long getAnnotationTagBits() {
0837:                if ((this .tagBits & TagBits.AnnotationResolved) == 0
0838:                        && this .scope != null) {
0839:                    TypeDeclaration typeDecl = this .scope.referenceContext;
0840:                    boolean old = typeDecl.staticInitializerScope.insideTypeAnnotation;
0841:                    try {
0842:                        typeDecl.staticInitializerScope.insideTypeAnnotation = true;
0843:                        ASTNode.resolveAnnotations(
0844:                                typeDecl.staticInitializerScope,
0845:                                typeDecl.annotations, this );
0846:                    } finally {
0847:                        typeDecl.staticInitializerScope.insideTypeAnnotation = old;
0848:                    }
0849:                    if ((this .tagBits & TagBits.AnnotationDeprecated) != 0)
0850:                        this .modifiers |= ClassFileConstants.AccDeprecated;
0851:                }
0852:                return this .tagBits;
0853:            }
0854:
0855:            public MethodBinding[] getDefaultAbstractMethods() {
0856:                int count = 0;
0857:                for (int i = this .methods.length; --i >= 0;)
0858:                    if (this .methods[i].isDefaultAbstract())
0859:                        count++;
0860:                if (count == 0)
0861:                    return Binding.NO_METHODS;
0862:
0863:                MethodBinding[] result = new MethodBinding[count];
0864:                count = 0;
0865:                for (int i = this .methods.length; --i >= 0;)
0866:                    if (this .methods[i].isDefaultAbstract())
0867:                        result[count++] = this .methods[i];
0868:                return result;
0869:            }
0870:
0871:            // NOTE: the return type, arg & exception types of each method of a source type are resolved when needed
0872:            public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) {
0873:                int argCount = argumentTypes.length;
0874:                if ((this .tagBits & TagBits.AreMethodsComplete) != 0) { // have resolved all arg types & return type of the methods
0875:                    long range;
0876:                    if ((range = ReferenceBinding.binarySearch(
0877:                            TypeConstants.INIT, this .methods)) >= 0) {
0878:                        nextMethod: for (int imethod = (int) range, end = (int) (range >> 32); imethod <= end; imethod++) {
0879:                            MethodBinding method = this .methods[imethod];
0880:                            if (method.parameters.length == argCount) {
0881:                                TypeBinding[] toMatch = method.parameters;
0882:                                for (int iarg = 0; iarg < argCount; iarg++)
0883:                                    if (toMatch[iarg] != argumentTypes[iarg])
0884:                                        continue nextMethod;
0885:                                return method;
0886:                            }
0887:                        }
0888:                    }
0889:                } else {
0890:                    // lazily sort methods
0891:                    if ((this .tagBits & TagBits.AreMethodsSorted) == 0) {
0892:                        int length = this .methods.length;
0893:                        if (length > 1)
0894:                            ReferenceBinding.sortMethods(this .methods, 0,
0895:                                    length);
0896:                        this .tagBits |= TagBits.AreMethodsSorted;
0897:                    }
0898:                    long range;
0899:                    if ((range = ReferenceBinding.binarySearch(
0900:                            TypeConstants.INIT, this .methods)) >= 0) {
0901:                        nextMethod: for (int imethod = (int) range, end = (int) (range >> 32); imethod <= end; imethod++) {
0902:                            MethodBinding method = this .methods[imethod];
0903:                            if (resolveTypesFor(method) == null
0904:                                    || method.returnType == null) {
0905:                                methods();
0906:                                return getExactConstructor(argumentTypes); // try again since the problem methods have been removed
0907:                            }
0908:                            if (method.parameters.length == argCount) {
0909:                                TypeBinding[] toMatch = method.parameters;
0910:                                for (int iarg = 0; iarg < argCount; iarg++)
0911:                                    if (toMatch[iarg] != argumentTypes[iarg])
0912:                                        continue nextMethod;
0913:                                return method;
0914:                            }
0915:                        }
0916:                    }
0917:                }
0918:                return null;
0919:            }
0920:
0921:            //NOTE: the return type, arg & exception types of each method of a source type are resolved when needed
0922:            //searches up the hierarchy as long as no potential (but not exact) match was found.
0923:            public MethodBinding getExactMethod(char[] selector,
0924:                    TypeBinding[] argumentTypes, CompilationUnitScope refScope) {
0925:                // sender from refScope calls recordTypeReference(this)
0926:                int argCount = argumentTypes.length;
0927:                boolean foundNothing = true;
0928:
0929:                if ((this .tagBits & TagBits.AreMethodsComplete) != 0) { // have resolved all arg types & return type of the methods
0930:                    long range;
0931:                    if ((range = ReferenceBinding.binarySearch(selector,
0932:                            this .methods)) >= 0) {
0933:                        nextMethod: for (int imethod = (int) range, end = (int) (range >> 32); imethod <= end; imethod++) {
0934:                            MethodBinding method = this .methods[imethod];
0935:                            foundNothing = false; // inner type lookups must know that a method with this name exists
0936:                            if (method.parameters.length == argCount) {
0937:                                TypeBinding[] toMatch = method.parameters;
0938:                                for (int iarg = 0; iarg < argCount; iarg++)
0939:                                    if (toMatch[iarg] != argumentTypes[iarg])
0940:                                        continue nextMethod;
0941:                                return method;
0942:                            }
0943:                        }
0944:                    }
0945:                } else {
0946:                    // lazily sort methods
0947:                    if ((this .tagBits & TagBits.AreMethodsSorted) == 0) {
0948:                        int length = this .methods.length;
0949:                        if (length > 1)
0950:                            ReferenceBinding.sortMethods(this .methods, 0,
0951:                                    length);
0952:                        this .tagBits |= TagBits.AreMethodsSorted;
0953:                    }
0954:
0955:                    long range;
0956:                    if ((range = ReferenceBinding.binarySearch(selector,
0957:                            this .methods)) >= 0) {
0958:                        // check unresolved method
0959:                        int start = (int) range, end = (int) (range >> 32);
0960:                        for (int imethod = start; imethod <= end; imethod++) {
0961:                            MethodBinding method = this .methods[imethod];
0962:                            if (resolveTypesFor(method) == null
0963:                                    || method.returnType == null) {
0964:                                methods();
0965:                                return getExactMethod(selector, argumentTypes,
0966:                                        refScope); // try again since the problem methods have been removed
0967:                            }
0968:                        }
0969:                        // check dup collisions
0970:                        boolean isSource15 = this .scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
0971:                        for (int i = start; i <= end; i++) {
0972:                            MethodBinding method1 = this .methods[i];
0973:                            for (int j = end; j > i; j--) {
0974:                                MethodBinding method2 = this .methods[j];
0975:                                boolean paramsMatch = isSource15 ? method1
0976:                                        .areParameterErasuresEqual(method2)
0977:                                        : method1.areParametersEqual(method2);
0978:                                if (paramsMatch) {
0979:                                    methods();
0980:                                    return getExactMethod(selector,
0981:                                            argumentTypes, refScope); // try again since the problem methods have been removed
0982:                                }
0983:                            }
0984:                        }
0985:                        nextMethod: for (int imethod = start; imethod <= end; imethod++) {
0986:                            MethodBinding method = this .methods[imethod];
0987:                            TypeBinding[] toMatch = method.parameters;
0988:                            if (toMatch.length == argCount) {
0989:                                for (int iarg = 0; iarg < argCount; iarg++)
0990:                                    if (toMatch[iarg] != argumentTypes[iarg])
0991:                                        continue nextMethod;
0992:                                return method;
0993:                            }
0994:                        }
0995:                    }
0996:                }
0997:
0998:                if (foundNothing) {
0999:                    if (isInterface()) {
1000:                        if (this .super Interfaces.length == 1) {
1001:                            if (refScope != null)
1002:                                refScope
1003:                                        .recordTypeReference(this .super Interfaces[0]);
1004:                            return this .super Interfaces[0].getExactMethod(
1005:                                    selector, argumentTypes, refScope);
1006:                        }
1007:                    } else if (this .super class != null) {
1008:                        if (refScope != null)
1009:                            refScope.recordTypeReference(this .super class);
1010:                        return this .super class.getExactMethod(selector,
1011:                                argumentTypes, refScope);
1012:                    }
1013:                }
1014:                return null;
1015:            }
1016:
1017:            //NOTE: the type of a field of a source type is resolved when needed
1018:            public FieldBinding getField(char[] fieldName, boolean needResolve) {
1019:
1020:                if ((this .tagBits & TagBits.AreFieldsComplete) != 0)
1021:                    return ReferenceBinding
1022:                            .binarySearch(fieldName, this .fields);
1023:
1024:                // lazily sort fields
1025:                if ((this .tagBits & TagBits.AreFieldsSorted) == 0) {
1026:                    int length = this .fields.length;
1027:                    if (length > 1)
1028:                        ReferenceBinding.sortFields(this .fields, 0, length);
1029:                    this .tagBits |= TagBits.AreFieldsSorted;
1030:                }
1031:                // always resolve anyway on source types
1032:                FieldBinding field = ReferenceBinding.binarySearch(fieldName,
1033:                        this .fields);
1034:                if (field != null) {
1035:                    FieldBinding result = null;
1036:                    try {
1037:                        result = resolveTypeFor(field);
1038:                        return result;
1039:                    } finally {
1040:                        if (result == null) {
1041:                            // ensure fields are consistent reqardless of the error
1042:                            int newSize = this .fields.length - 1;
1043:                            if (newSize == 0) {
1044:                                this .fields = Binding.NO_FIELDS;
1045:                            } else {
1046:                                FieldBinding[] newFields = new FieldBinding[newSize];
1047:                                int index = 0;
1048:                                for (int i = 0, length = this .fields.length; i < length; i++) {
1049:                                    FieldBinding f = this .fields[i];
1050:                                    if (f == field)
1051:                                        continue;
1052:                                    newFields[index++] = f;
1053:                                }
1054:                                this .fields = newFields;
1055:                            }
1056:                        }
1057:                    }
1058:                }
1059:                return null;
1060:            }
1061:
1062:            // NOTE: the return type, arg & exception types of each method of a source type are resolved when needed
1063:            public MethodBinding[] getMethods(char[] selector) {
1064:                if ((this .tagBits & TagBits.AreMethodsComplete) != 0) {
1065:                    long range;
1066:                    if ((range = ReferenceBinding.binarySearch(selector,
1067:                            this .methods)) >= 0) {
1068:                        int start = (int) range, end = (int) (range >> 32);
1069:                        int length = end - start + 1;
1070:                        MethodBinding[] result;
1071:                        System.arraycopy(this .methods, start,
1072:                                result = new MethodBinding[length], 0, length);
1073:                        return result;
1074:                    } else {
1075:                        return Binding.NO_METHODS;
1076:                    }
1077:                }
1078:                // lazily sort methods
1079:                if ((this .tagBits & TagBits.AreMethodsSorted) == 0) {
1080:                    int length = this .methods.length;
1081:                    if (length > 1)
1082:                        ReferenceBinding.sortMethods(this .methods, 0, length);
1083:                    this .tagBits |= TagBits.AreMethodsSorted;
1084:                }
1085:                MethodBinding[] result;
1086:                long range;
1087:                if ((range = ReferenceBinding.binarySearch(selector,
1088:                        this .methods)) >= 0) {
1089:                    int start = (int) range, end = (int) (range >> 32);
1090:                    for (int i = start; i <= end; i++) {
1091:                        MethodBinding method = this .methods[i];
1092:                        if (resolveTypesFor(method) == null
1093:                                || method.returnType == null) {
1094:                            methods();
1095:                            return getMethods(selector); // try again since the problem methods have been removed
1096:                        }
1097:                    }
1098:                    int length = end - start + 1;
1099:                    System.arraycopy(this .methods, start,
1100:                            result = new MethodBinding[length], 0, length);
1101:                } else {
1102:                    return Binding.NO_METHODS;
1103:                }
1104:                boolean isSource15 = this .scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
1105:                for (int i = 0, length = result.length - 1; i < length; i++) {
1106:                    MethodBinding method = result[i];
1107:                    for (int j = length; j > i; j--) {
1108:                        boolean paramsMatch = isSource15 ? method
1109:                                .areParameterErasuresEqual(result[j]) : method
1110:                                .areParametersEqual(result[j]);
1111:                        if (paramsMatch) {
1112:                            methods();
1113:                            return getMethods(selector); // try again since the duplicate methods have been removed
1114:                        }
1115:                    }
1116:                }
1117:                return result;
1118:            }
1119:
1120:            /* Answer the synthetic field for <actualOuterLocalVariable>
1121:             *	or null if one does not exist.
1122:             */
1123:            public FieldBinding getSyntheticField(
1124:                    LocalVariableBinding actualOuterLocalVariable) {
1125:                if (this .synthetics == null
1126:                        || this .synthetics[SourceTypeBinding.FIELD_EMUL] == null)
1127:                    return null;
1128:                return (FieldBinding) this .synthetics[SourceTypeBinding.FIELD_EMUL]
1129:                        .get(actualOuterLocalVariable);
1130:            }
1131:
1132:            /* Answer the synthetic field for <targetEnclosingType>
1133:             *	or null if one does not exist.
1134:             */
1135:            public FieldBinding getSyntheticField(
1136:                    ReferenceBinding targetEnclosingType, boolean onlyExactMatch) {
1137:
1138:                if (this .synthetics == null
1139:                        || this .synthetics[SourceTypeBinding.FIELD_EMUL] == null)
1140:                    return null;
1141:                FieldBinding field = (FieldBinding) this .synthetics[SourceTypeBinding.FIELD_EMUL]
1142:                        .get(targetEnclosingType);
1143:                if (field != null)
1144:                    return field;
1145:
1146:                // type compatibility : to handle cases such as
1147:                // class T { class M{}}
1148:                // class S extends T { class N extends M {}} --> need to use S as a default enclosing instance for the super constructor call in N().
1149:                if (!onlyExactMatch) {
1150:                    Iterator accessFields = this .synthetics[SourceTypeBinding.FIELD_EMUL]
1151:                            .values().iterator();
1152:                    while (accessFields.hasNext()) {
1153:                        field = (FieldBinding) accessFields.next();
1154:                        if (CharOperation
1155:                                .prefixEquals(
1156:                                        TypeConstants.SYNTHETIC_ENCLOSING_INSTANCE_PREFIX,
1157:                                        field.name)
1158:                                && field.type
1159:                                        .findSuperTypeWithSameErasure(targetEnclosingType) != null)
1160:                            return field;
1161:                    }
1162:                }
1163:                return null;
1164:            }
1165:
1166:            /* 
1167:             * Answer the bridge method associated for an  inherited methods or null if one does not exist
1168:             */
1169:            public SyntheticMethodBinding getSyntheticBridgeMethod(
1170:                    MethodBinding inheritedMethodToBridge) {
1171:                if (this .synthetics == null)
1172:                    return null;
1173:                if (this .synthetics[SourceTypeBinding.METHOD_EMUL] == null)
1174:                    return null;
1175:                SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) this .synthetics[SourceTypeBinding.METHOD_EMUL]
1176:                        .get(inheritedMethodToBridge);
1177:                if (accessors == null)
1178:                    return null;
1179:                return accessors[1];
1180:            }
1181:
1182:            /**
1183:             * @see org.eclipse.jdt.internal.compiler.lookup.Binding#initializeDeprecatedAnnotationTagBits()
1184:             */
1185:            public void initializeDeprecatedAnnotationTagBits() {
1186:                if ((this .tagBits & TagBits.DeprecatedAnnotationResolved) == 0) {
1187:                    TypeDeclaration typeDecl = this .scope.referenceContext;
1188:                    boolean old = typeDecl.staticInitializerScope.insideTypeAnnotation;
1189:                    try {
1190:                        typeDecl.staticInitializerScope.insideTypeAnnotation = true;
1191:                        ASTNode.resolveDeprecatedAnnotations(
1192:                                typeDecl.staticInitializerScope,
1193:                                typeDecl.annotations, this );
1194:                        this .tagBits |= TagBits.DeprecatedAnnotationResolved;
1195:                    } finally {
1196:                        typeDecl.staticInitializerScope.insideTypeAnnotation = old;
1197:                    }
1198:                    if ((this .tagBits & TagBits.AnnotationDeprecated) != 0) {
1199:                        this .modifiers |= ClassFileConstants.AccDeprecated;
1200:                    }
1201:                }
1202:            }
1203:
1204:            /**
1205:             * Returns true if a type is identical to another one,
1206:             * or for generic types, true if compared to its raw type.
1207:             */
1208:            public boolean isEquivalentTo(TypeBinding otherType) {
1209:
1210:                if (this  == otherType)
1211:                    return true;
1212:                if (otherType == null)
1213:                    return false;
1214:                switch (otherType.kind()) {
1215:
1216:                case Binding.WILDCARD_TYPE:
1217:                    return ((WildcardBinding) otherType).boundCheck(this );
1218:
1219:                case Binding.PARAMETERIZED_TYPE:
1220:                    if ((otherType.tagBits & TagBits.HasDirectWildcard) == 0
1221:                            && (!this .isMemberType() || !otherType
1222:                                    .isMemberType()))
1223:                        return false; // should have been identical
1224:                    ParameterizedTypeBinding otherParamType = (ParameterizedTypeBinding) otherType;
1225:                    if (this  != otherParamType.genericType())
1226:                        return false;
1227:                    if (!isStatic()) { // static member types do not compare their enclosing
1228:                        ReferenceBinding enclosing = enclosingType();
1229:                        if (enclosing != null) {
1230:                            ReferenceBinding otherEnclosing = otherParamType
1231:                                    .enclosingType();
1232:                            if (otherEnclosing == null)
1233:                                return false;
1234:                            if ((otherEnclosing.tagBits & TagBits.HasDirectWildcard) == 0) {
1235:                                if (enclosing != otherEnclosing)
1236:                                    return false;
1237:                            } else {
1238:                                if (!enclosing.isEquivalentTo(otherParamType
1239:                                        .enclosingType()))
1240:                                    return false;
1241:                            }
1242:                        }
1243:                    }
1244:                    int length = this .typeVariables == null ? 0
1245:                            : this .typeVariables.length;
1246:                    TypeBinding[] otherArguments = otherParamType.arguments;
1247:                    int otherLength = otherArguments == null ? 0
1248:                            : otherArguments.length;
1249:                    if (otherLength != length)
1250:                        return false;
1251:                    for (int i = 0; i < length; i++)
1252:                        if (!this .typeVariables[i]
1253:                                .isTypeArgumentContainedBy(otherArguments[i]))
1254:                            return false;
1255:                    return true;
1256:
1257:                case Binding.RAW_TYPE:
1258:                    return otherType.erasure() == this ;
1259:                }
1260:                return false;
1261:            }
1262:
1263:            public boolean isGenericType() {
1264:                return this .typeVariables != Binding.NO_TYPE_VARIABLES;
1265:            }
1266:
1267:            public ReferenceBinding[] memberTypes() {
1268:                return this .memberTypes;
1269:            }
1270:
1271:            public FieldBinding getUpdatedFieldBinding(
1272:                    FieldBinding targetField, ReferenceBinding newDeclaringClass) {
1273:                if (this .synthetics == null)
1274:                    this .synthetics = new HashMap[4];
1275:                if (this .synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL] == null)
1276:                    this .synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL] = new HashMap(
1277:                            5);
1278:
1279:                Hashtable fieldMap = (Hashtable) this .synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL]
1280:                        .get(targetField);
1281:                if (fieldMap == null) {
1282:                    fieldMap = new Hashtable(5);
1283:                    this .synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL].put(
1284:                            targetField, fieldMap);
1285:                }
1286:                FieldBinding updatedField = (FieldBinding) fieldMap
1287:                        .get(newDeclaringClass);
1288:                if (updatedField == null) {
1289:                    updatedField = new FieldBinding(targetField,
1290:                            newDeclaringClass);
1291:                    fieldMap.put(newDeclaringClass, updatedField);
1292:                }
1293:                return updatedField;
1294:            }
1295:
1296:            public MethodBinding getUpdatedMethodBinding(
1297:                    MethodBinding targetMethod,
1298:                    ReferenceBinding newDeclaringClass) {
1299:                if (this .synthetics == null)
1300:                    this .synthetics = new HashMap[4];
1301:                if (this .synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL] == null)
1302:                    this .synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL] = new HashMap(
1303:                            5);
1304:
1305:                Hashtable methodMap = (Hashtable) this .synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL]
1306:                        .get(targetMethod);
1307:                if (methodMap == null) {
1308:                    methodMap = new Hashtable(5);
1309:                    this .synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL].put(
1310:                            targetMethod, methodMap);
1311:                }
1312:                MethodBinding updatedMethod = (MethodBinding) methodMap
1313:                        .get(newDeclaringClass);
1314:                if (updatedMethod == null) {
1315:                    updatedMethod = new MethodBinding(targetMethod,
1316:                            newDeclaringClass);
1317:                    methodMap.put(newDeclaringClass, updatedMethod);
1318:                }
1319:                return updatedMethod;
1320:            }
1321:
1322:            public boolean hasMemberTypes() {
1323:                return this .memberTypes.length > 0;
1324:            }
1325:
1326:            // NOTE: the return type, arg & exception types of each method of a source type are resolved when needed
1327:            public MethodBinding[] methods() {
1328:                if ((this .tagBits & TagBits.AreMethodsComplete) != 0)
1329:                    return this .methods;
1330:
1331:                // lazily sort methods
1332:                if ((this .tagBits & TagBits.AreMethodsSorted) == 0) {
1333:                    int length = this .methods.length;
1334:                    if (length > 1)
1335:                        ReferenceBinding.sortMethods(this .methods, 0, length);
1336:                    this .tagBits |= TagBits.AreMethodsSorted;
1337:                }
1338:
1339:                int failed = 0;
1340:                MethodBinding[] resolvedMethods = this .methods;
1341:                try {
1342:                    for (int i = 0, length = this .methods.length; i < length; i++) {
1343:                        if (resolveTypesFor(this .methods[i]) == null) {
1344:                            // do not alter original method array until resolution is over, due to reentrance (143259)
1345:                            if (resolvedMethods == this .methods) {
1346:                                System
1347:                                        .arraycopy(
1348:                                                this .methods,
1349:                                                0,
1350:                                                resolvedMethods = new MethodBinding[length],
1351:                                                0, length);
1352:                            }
1353:                            resolvedMethods[i] = null; // unable to resolve parameters
1354:                            failed++;
1355:                        }
1356:                    }
1357:
1358:                    // find & report collision cases
1359:                    boolean complyTo15 = this .scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
1360:                    for (int i = 0, length = this .methods.length; i < length; i++) {
1361:                        MethodBinding method = resolvedMethods[i];
1362:                        if (method == null)
1363:                            continue;
1364:                        char[] selector = method.selector;
1365:                        AbstractMethodDeclaration methodDecl = null;
1366:                        nextSibling: for (int j = i + 1; j < length; j++) {
1367:                            MethodBinding method2 = resolvedMethods[j];
1368:                            if (method2 == null)
1369:                                continue nextSibling;
1370:                            if (!CharOperation.equals(selector,
1371:                                    method2.selector))
1372:                                break nextSibling; // methods with same selector are contiguous
1373:
1374:                            if (complyTo15 && method.returnType != null
1375:                                    && method2.returnType != null) {
1376:                                // 8.4.2, for collision to be detected between m1 and m2:
1377:                                // signature(m1) == signature(m2) i.e. same arity, same type parameter count, can be substituted
1378:                                // signature(m1) == erasure(signature(m2)) or erasure(signature(m1)) == signature(m2)
1379:                                TypeBinding[] params1 = method.parameters;
1380:                                TypeBinding[] params2 = method2.parameters;
1381:                                int pLength = params1.length;
1382:                                if (pLength != params2.length)
1383:                                    continue nextSibling;
1384:
1385:                                TypeVariableBinding[] vars = method.typeVariables;
1386:                                TypeVariableBinding[] vars2 = method2.typeVariables;
1387:                                boolean equalTypeVars = vars == vars2;
1388:                                MethodBinding subMethod = method2;
1389:                                if (!equalTypeVars) {
1390:                                    MethodBinding temp = method
1391:                                            .computeSubstitutedMethod(method2,
1392:                                                    this .scope.environment());
1393:                                    if (temp != null) {
1394:                                        equalTypeVars = true;
1395:                                        subMethod = temp;
1396:                                    }
1397:                                }
1398:                                boolean equalParams = method
1399:                                        .areParametersEqual(subMethod);
1400:                                if (equalParams && equalTypeVars) {
1401:                                    // duplicates regardless of return types
1402:                                } else if (method.returnType.erasure() == subMethod.returnType
1403:                                        .erasure()
1404:                                        && (equalParams || method
1405:                                                .areParameterErasuresEqual(method2))) {
1406:                                    // name clash for sure if not duplicates, report as duplicates
1407:                                } else if (!equalTypeVars
1408:                                        && vars != Binding.NO_TYPE_VARIABLES
1409:                                        && vars2 != Binding.NO_TYPE_VARIABLES) {
1410:                                    // type variables are different so we can distinguish between methods
1411:                                    continue nextSibling;
1412:                                } else if (pLength > 0) {
1413:                                    // check to see if the erasure of either method is equal to the other
1414:                                    int index = pLength;
1415:                                    for (; --index >= 0;) {
1416:                                        if (params1[index] != params2[index]
1417:                                                .erasure())
1418:                                            break;
1419:                                        if (params1[index] == params2[index]) {
1420:                                            TypeBinding type = params1[index]
1421:                                                    .leafComponentType();
1422:                                            if (type instanceof  SourceTypeBinding
1423:                                                    && type.typeVariables() != Binding.NO_TYPE_VARIABLES) {
1424:                                                index = pLength; // handle comparing identical source types like X<T>... its erasure is itself BUT we need to answer false
1425:                                                break;
1426:                                            }
1427:                                        }
1428:                                    }
1429:                                    if (index >= 0 && index < pLength) {
1430:                                        for (index = pLength; --index >= 0;)
1431:                                            if (params1[index].erasure() != params2[index])
1432:                                                break;
1433:                                    }
1434:                                    if (index >= 0)
1435:                                        continue nextSibling;
1436:                                }
1437:                            } else if (!method.areParametersEqual(method2)) { // prior to 1.5, parameter identity meant a collision case
1438:                                continue nextSibling;
1439:                            }
1440:                            boolean isEnumSpecialMethod = isEnum()
1441:                                    && (CharOperation.equals(selector,
1442:                                            TypeConstants.VALUEOF) || CharOperation
1443:                                            .equals(selector,
1444:                                                    TypeConstants.VALUES));
1445:                            // report duplicate
1446:                            if (methodDecl == null) {
1447:                                methodDecl = method.sourceMethod(); // cannot be retrieved after binding is lost & may still be null if method is special
1448:                                if (methodDecl != null
1449:                                        && methodDecl.binding != null) { // ensure its a valid user defined method
1450:                                    if (isEnumSpecialMethod) {
1451:                                        this .scope.problemReporter()
1452:                                                .duplicateEnumSpecialMethod(
1453:                                                        this , methodDecl);
1454:                                    } else {
1455:                                        this .scope.problemReporter()
1456:                                                .duplicateMethodInType(this ,
1457:                                                        methodDecl);
1458:                                    }
1459:                                    methodDecl.binding = null;
1460:                                    // do not alter original method array until resolution is over, due to reentrance (143259)
1461:                                    if (resolvedMethods == this .methods) {
1462:                                        System
1463:                                                .arraycopy(
1464:                                                        this .methods,
1465:                                                        0,
1466:                                                        resolvedMethods = new MethodBinding[length],
1467:                                                        0, length);
1468:                                    }
1469:                                    resolvedMethods[i] = null;
1470:                                    failed++;
1471:                                }
1472:                            }
1473:                            AbstractMethodDeclaration method2Decl = method2
1474:                                    .sourceMethod();
1475:                            if (method2Decl != null
1476:                                    && method2Decl.binding != null) { // ensure its a valid user defined method
1477:                                if (isEnumSpecialMethod) {
1478:                                    this .scope.problemReporter()
1479:                                            .duplicateEnumSpecialMethod(this ,
1480:                                                    method2Decl);
1481:                                } else {
1482:                                    this .scope.problemReporter()
1483:                                            .duplicateMethodInType(this ,
1484:                                                    method2Decl);
1485:                                }
1486:                                method2Decl.binding = null;
1487:                                // do not alter original method array until resolution is over, due to reentrance (143259)
1488:                                if (resolvedMethods == this .methods) {
1489:                                    System
1490:                                            .arraycopy(
1491:                                                    this .methods,
1492:                                                    0,
1493:                                                    resolvedMethods = new MethodBinding[length],
1494:                                                    0, length);
1495:                                }
1496:                                resolvedMethods[j] = null;
1497:                                failed++;
1498:                            }
1499:                        }
1500:                        if (method.returnType == null && methodDecl == null) { // forget method with invalid return type... was kept to detect possible collisions
1501:                            methodDecl = method.sourceMethod();
1502:                            if (methodDecl != null) {
1503:                                methodDecl.binding = null;
1504:                            }
1505:                            // do not alter original method array until resolution is over, due to reentrance (143259)
1506:                            if (resolvedMethods == this .methods) {
1507:                                System
1508:                                        .arraycopy(
1509:                                                this .methods,
1510:                                                0,
1511:                                                resolvedMethods = new MethodBinding[length],
1512:                                                0, length);
1513:                            }
1514:                            resolvedMethods[i] = null;
1515:                            failed++;
1516:                        }
1517:                    }
1518:                } finally {
1519:                    if (failed > 0) {
1520:                        int newSize = resolvedMethods.length - failed;
1521:                        if (newSize == 0) {
1522:                            this .methods = Binding.NO_METHODS;
1523:                        } else {
1524:                            MethodBinding[] newMethods = new MethodBinding[newSize];
1525:                            for (int i = 0, j = 0, length = resolvedMethods.length; i < length; i++)
1526:                                if (resolvedMethods[i] != null)
1527:                                    newMethods[j++] = resolvedMethods[i];
1528:                            this .methods = newMethods;
1529:                        }
1530:                    }
1531:
1532:                    // handle forward references to potential default abstract methods
1533:                    addDefaultAbstractMethods();
1534:                    this .tagBits |= TagBits.AreMethodsComplete;
1535:                }
1536:                return this .methods;
1537:            }
1538:
1539:            private FieldBinding resolveTypeFor(FieldBinding field) {
1540:                if ((field.modifiers & ExtraCompilerModifiers.AccUnresolved) == 0)
1541:                    return field;
1542:
1543:                if (this .scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
1544:                    if ((field.getAnnotationTagBits() & TagBits.AnnotationDeprecated) != 0)
1545:                        field.modifiers |= ClassFileConstants.AccDeprecated;
1546:                }
1547:                if (isViewedAsDeprecated() && !field.isDeprecated())
1548:                    field.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
1549:                if (hasRestrictedAccess())
1550:                    field.modifiers |= ExtraCompilerModifiers.AccRestrictedAccess;
1551:                FieldDeclaration[] fieldDecls = this .scope.referenceContext.fields;
1552:                for (int f = 0, length = fieldDecls.length; f < length; f++) {
1553:                    if (fieldDecls[f].binding != field)
1554:                        continue;
1555:
1556:                    MethodScope initializationScope = field.isStatic() ? this .scope.referenceContext.staticInitializerScope
1557:                            : this .scope.referenceContext.initializerScope;
1558:                    FieldBinding previousField = initializationScope.initializedField;
1559:                    try {
1560:                        initializationScope.initializedField = field;
1561:                        FieldDeclaration fieldDecl = fieldDecls[f];
1562:                        TypeBinding fieldType = fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT ? initializationScope
1563:                                .environment().convertToRawType(this ) // enum constant is implicitly of declaring enum type
1564:                                : fieldDecl.type
1565:                                        .resolveType(initializationScope, true /* check bounds*/);
1566:                        field.type = fieldType;
1567:                        field.modifiers &= ~ExtraCompilerModifiers.AccUnresolved;
1568:                        if (fieldType == null) {
1569:                            fieldDecl.binding = null;
1570:                            return null;
1571:                        }
1572:                        if (fieldType == TypeBinding.VOID) {
1573:                            this .scope.problemReporter()
1574:                                    .variableTypeCannotBeVoid(fieldDecl);
1575:                            fieldDecl.binding = null;
1576:                            return null;
1577:                        }
1578:                        if (fieldType.isArrayType()
1579:                                && ((ArrayBinding) fieldType).leafComponentType == TypeBinding.VOID) {
1580:                            this .scope.problemReporter()
1581:                                    .variableTypeCannotBeVoidArray(fieldDecl);
1582:                            fieldDecl.binding = null;
1583:                            return null;
1584:                        }
1585:                        TypeBinding leafType = fieldType.leafComponentType();
1586:                        if (leafType instanceof  ReferenceBinding
1587:                                && (((ReferenceBinding) leafType).modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0) {
1588:                            field.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
1589:                        }
1590:                    } finally {
1591:                        initializationScope.initializedField = previousField;
1592:                    }
1593:                    return field;
1594:                }
1595:                return null; // should never reach this point
1596:            }
1597:
1598:            public MethodBinding resolveTypesFor(MethodBinding method) {
1599:                if ((method.modifiers & ExtraCompilerModifiers.AccUnresolved) == 0)
1600:                    return method;
1601:
1602:                if (this .scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
1603:                    if ((method.getAnnotationTagBits() & TagBits.AnnotationDeprecated) != 0)
1604:                        method.modifiers |= ClassFileConstants.AccDeprecated;
1605:                }
1606:                if (isViewedAsDeprecated() && !method.isDeprecated())
1607:                    method.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
1608:                if (hasRestrictedAccess())
1609:                    method.modifiers |= ExtraCompilerModifiers.AccRestrictedAccess;
1610:
1611:                AbstractMethodDeclaration methodDecl = method.sourceMethod();
1612:                if (methodDecl == null)
1613:                    return null; // method could not be resolved in previous iteration
1614:
1615:                TypeParameter[] typeParameters = methodDecl.typeParameters();
1616:                if (typeParameters != null) {
1617:                    methodDecl.scope.connectTypeVariables(typeParameters, true);
1618:                    // Perform deferred bound checks for type variables (only done after type variable hierarchy is connected)
1619:                    for (int i = 0, paramLength = typeParameters.length; i < paramLength; i++)
1620:                        typeParameters[i].checkBounds(methodDecl.scope);
1621:                }
1622:                TypeReference[] exceptionTypes = methodDecl.thrownExceptions;
1623:                if (exceptionTypes != null) {
1624:                    int size = exceptionTypes.length;
1625:                    method.thrownExceptions = new ReferenceBinding[size];
1626:                    int count = 0;
1627:                    ReferenceBinding resolvedExceptionType;
1628:                    for (int i = 0; i < size; i++) {
1629:                        resolvedExceptionType = (ReferenceBinding) exceptionTypes[i]
1630:                                .resolveType(methodDecl.scope, true /* check bounds*/);
1631:                        if (resolvedExceptionType == null)
1632:                            continue;
1633:                        if (resolvedExceptionType.isBoundParameterizedType()) {
1634:                            methodDecl.scope.problemReporter()
1635:                                    .invalidParameterizedExceptionType(
1636:                                            resolvedExceptionType,
1637:                                            exceptionTypes[i]);
1638:                            continue;
1639:                        }
1640:                        if (resolvedExceptionType.findSuperTypeErasingTo(
1641:                                TypeIds.T_JavaLangThrowable, true) == null) {
1642:                            methodDecl.scope.problemReporter().cannotThrowType(
1643:                                    exceptionTypes[i], resolvedExceptionType);
1644:                            continue;
1645:                        }
1646:                        if ((resolvedExceptionType.modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0)
1647:                            method.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
1648:                        method.thrownExceptions[count++] = resolvedExceptionType;
1649:                    }
1650:                    if (count < size)
1651:                        System
1652:                                .arraycopy(
1653:                                        method.thrownExceptions,
1654:                                        0,
1655:                                        method.thrownExceptions = new ReferenceBinding[count],
1656:                                        0, count);
1657:                }
1658:
1659:                boolean foundArgProblem = false;
1660:                Argument[] arguments = methodDecl.arguments;
1661:                if (arguments != null) {
1662:                    int size = arguments.length;
1663:                    method.parameters = Binding.NO_PARAMETERS;
1664:                    TypeBinding[] newParameters = new TypeBinding[size];
1665:                    for (int i = 0; i < size; i++) {
1666:                        Argument arg = arguments[i];
1667:                        TypeBinding parameterType = arg.type.resolveType(
1668:                                methodDecl.scope, true /* check bounds*/);
1669:                        if (parameterType == null) {
1670:                            foundArgProblem = true;
1671:                        } else if (parameterType == TypeBinding.VOID) {
1672:                            methodDecl.scope.problemReporter()
1673:                                    .argumentTypeCannotBeVoid(this , methodDecl,
1674:                                            arg);
1675:                            foundArgProblem = true;
1676:                        } else {
1677:                            TypeBinding leafType = parameterType
1678:                                    .leafComponentType();
1679:                            if (leafType instanceof  ReferenceBinding
1680:                                    && (((ReferenceBinding) leafType).modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0)
1681:                                method.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
1682:                            newParameters[i] = parameterType;
1683:                            arg.binding = new LocalVariableBinding(arg,
1684:                                    parameterType, arg.modifiers, true);
1685:                        }
1686:                    }
1687:                    // only assign parameters if no problems are found
1688:                    if (!foundArgProblem) {
1689:                        method.parameters = newParameters;
1690:                    }
1691:                }
1692:
1693:                boolean foundReturnTypeProblem = false;
1694:                if (!method.isConstructor()) {
1695:                    TypeReference returnType = methodDecl instanceof  MethodDeclaration ? ((MethodDeclaration) methodDecl).returnType
1696:                            : null;
1697:                    if (returnType == null) {
1698:                        methodDecl.scope.problemReporter().missingReturnType(
1699:                                methodDecl);
1700:                        method.returnType = null;
1701:                        foundReturnTypeProblem = true;
1702:                    } else {
1703:                        TypeBinding methodType = returnType.resolveType(
1704:                                methodDecl.scope, true /* check bounds*/);
1705:                        if (methodType == null) {
1706:                            foundReturnTypeProblem = true;
1707:                        } else if (methodType.isArrayType()
1708:                                && ((ArrayBinding) methodType).leafComponentType == TypeBinding.VOID) {
1709:                            methodDecl.scope.problemReporter()
1710:                                    .returnTypeCannotBeVoidArray(
1711:                                            (MethodDeclaration) methodDecl);
1712:                            foundReturnTypeProblem = true;
1713:                        } else {
1714:                            method.returnType = methodType;
1715:                            TypeBinding leafType = methodType
1716:                                    .leafComponentType();
1717:                            if (leafType instanceof  ReferenceBinding
1718:                                    && (((ReferenceBinding) leafType).modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0)
1719:                                method.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
1720:                        }
1721:                    }
1722:                }
1723:                if (foundArgProblem) {
1724:                    methodDecl.binding = null;
1725:                    method.parameters = Binding.NO_PARAMETERS; // see 107004
1726:                    // nullify type parameter bindings as well as they have a backpointer to the method binding
1727:                    // (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=81134)
1728:                    if (typeParameters != null)
1729:                        for (int i = 0, length = typeParameters.length; i < length; i++)
1730:                            typeParameters[i].binding = null;
1731:                    return null;
1732:                }
1733:                if (foundReturnTypeProblem)
1734:                    return method; // but its still unresolved with a null return type & is still connected to its method declaration
1735:
1736:                method.modifiers &= ~ExtraCompilerModifiers.AccUnresolved;
1737:                return method;
1738:            }
1739:
1740:            public AnnotationHolder retrieveAnnotationHolder(Binding binding,
1741:                    boolean forceInitialization) {
1742:                if (forceInitialization)
1743:                    binding.getAnnotationTagBits(); // ensure annotations are up to date
1744:                return super .retrieveAnnotationHolder(binding, false);
1745:            }
1746:
1747:            public void setFields(FieldBinding[] fields) {
1748:                this .fields = fields;
1749:            }
1750:
1751:            public void setMethods(MethodBinding[] methods) {
1752:                this .methods = methods;
1753:            }
1754:
1755:            public final int sourceEnd() {
1756:                return this .scope.referenceContext.sourceEnd;
1757:            }
1758:
1759:            public final int sourceStart() {
1760:                return this .scope.referenceContext.sourceStart;
1761:            }
1762:
1763:            SimpleLookupTable storedAnnotations(boolean forceInitialize) {
1764:                if (forceInitialize && this .storedAnnotations == null
1765:                        && this .scope != null) { // scope null when no annotation cached, and type got processed fully (159631)
1766:                    this .scope.referenceCompilationUnit().compilationResult.hasAnnotations = true;
1767:                    if (!this .scope.environment().globalOptions.storeAnnotations)
1768:                        return null; // not supported during this compile
1769:                    this .storedAnnotations = new SimpleLookupTable(3);
1770:                }
1771:                return this .storedAnnotations;
1772:            }
1773:
1774:            public ReferenceBinding super class() {
1775:                return this .super class;
1776:            }
1777:
1778:            public ReferenceBinding[] super Interfaces() {
1779:                return this .super Interfaces;
1780:            }
1781:
1782:            // TODO (philippe) could be a performance issue since some senders are building the list just to count them
1783:            public SyntheticMethodBinding[] syntheticMethods() {
1784:
1785:                if (this .synthetics == null
1786:                        || this .synthetics[SourceTypeBinding.METHOD_EMUL] == null
1787:                        || this .synthetics[SourceTypeBinding.METHOD_EMUL]
1788:                                .size() == 0)
1789:                    return null;
1790:
1791:                // difficult to compute size up front because of the embedded arrays so assume there is only 1
1792:                int index = 0;
1793:                SyntheticMethodBinding[] bindings = new SyntheticMethodBinding[1];
1794:                Iterator fieldsOrMethods = this .synthetics[SourceTypeBinding.METHOD_EMUL]
1795:                        .keySet().iterator();
1796:                while (fieldsOrMethods.hasNext()) {
1797:
1798:                    Object fieldOrMethod = fieldsOrMethods.next();
1799:
1800:                    if (fieldOrMethod instanceof  MethodBinding) {
1801:
1802:                        SyntheticMethodBinding[] methodAccessors = (SyntheticMethodBinding[]) this .synthetics[SourceTypeBinding.METHOD_EMUL]
1803:                                .get(fieldOrMethod);
1804:                        int numberOfAccessors = 0;
1805:                        if (methodAccessors[0] != null)
1806:                            numberOfAccessors++;
1807:                        if (methodAccessors[1] != null)
1808:                            numberOfAccessors++;
1809:                        if (index + numberOfAccessors > bindings.length)
1810:                            System
1811:                                    .arraycopy(
1812:                                            bindings,
1813:                                            0,
1814:                                            (bindings = new SyntheticMethodBinding[index
1815:                                                    + numberOfAccessors]), 0,
1816:                                            index);
1817:                        if (methodAccessors[0] != null)
1818:                            bindings[index++] = methodAccessors[0]; // super access 
1819:                        if (methodAccessors[1] != null)
1820:                            bindings[index++] = methodAccessors[1]; // normal access or bridge
1821:
1822:                    } else {
1823:
1824:                        SyntheticMethodBinding[] fieldAccessors = (SyntheticMethodBinding[]) this .synthetics[SourceTypeBinding.METHOD_EMUL]
1825:                                .get(fieldOrMethod);
1826:                        int numberOfAccessors = 0;
1827:                        if (fieldAccessors[0] != null)
1828:                            numberOfAccessors++;
1829:                        if (fieldAccessors[1] != null)
1830:                            numberOfAccessors++;
1831:                        if (index + numberOfAccessors > bindings.length)
1832:                            System
1833:                                    .arraycopy(
1834:                                            bindings,
1835:                                            0,
1836:                                            (bindings = new SyntheticMethodBinding[index
1837:                                                    + numberOfAccessors]), 0,
1838:                                            index);
1839:                        if (fieldAccessors[0] != null)
1840:                            bindings[index++] = fieldAccessors[0]; // read access
1841:                        if (fieldAccessors[1] != null)
1842:                            bindings[index++] = fieldAccessors[1]; // write access
1843:                    }
1844:                }
1845:
1846:                // sort them in according to their own indexes
1847:                int length;
1848:                SyntheticMethodBinding[] sortedBindings = new SyntheticMethodBinding[length = bindings.length];
1849:                for (int i = 0; i < length; i++) {
1850:                    SyntheticMethodBinding binding = bindings[i];
1851:                    sortedBindings[binding.index] = binding;
1852:                }
1853:                return sortedBindings;
1854:            }
1855:
1856:            /**
1857:             * Answer the collection of synthetic fields to append into the classfile
1858:             */
1859:            public FieldBinding[] syntheticFields() {
1860:
1861:                if (this .synthetics == null)
1862:                    return null;
1863:
1864:                int fieldSize = this .synthetics[SourceTypeBinding.FIELD_EMUL] == null ? 0
1865:                        : this .synthetics[SourceTypeBinding.FIELD_EMUL].size();
1866:                int literalSize = this .synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL] == null ? 0
1867:                        : this .synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL]
1868:                                .size();
1869:                int totalSize = fieldSize + literalSize;
1870:                if (totalSize == 0)
1871:                    return null;
1872:                FieldBinding[] bindings = new FieldBinding[totalSize];
1873:
1874:                // add innerclass synthetics
1875:                if (this .synthetics[SourceTypeBinding.FIELD_EMUL] != null) {
1876:                    Iterator elements = this .synthetics[SourceTypeBinding.FIELD_EMUL]
1877:                            .values().iterator();
1878:                    for (int i = 0; i < fieldSize; i++) {
1879:                        SyntheticFieldBinding synthBinding = (SyntheticFieldBinding) elements
1880:                                .next();
1881:                        bindings[synthBinding.index] = synthBinding;
1882:                    }
1883:                }
1884:                // add class literal synthetics
1885:                if (this .synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL] != null) {
1886:                    Iterator elements = this .synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL]
1887:                            .values().iterator();
1888:                    for (int i = 0; i < literalSize; i++) {
1889:                        SyntheticFieldBinding synthBinding = (SyntheticFieldBinding) elements
1890:                                .next();
1891:                        bindings[fieldSize + synthBinding.index] = synthBinding;
1892:                    }
1893:                }
1894:                return bindings;
1895:            }
1896:
1897:            public String toString() {
1898:                StringBuffer buffer = new StringBuffer(30);
1899:                buffer.append("(id="); //$NON-NLS-1$
1900:                if (this .id == TypeIds.NoId)
1901:                    buffer.append("NoId"); //$NON-NLS-1$
1902:                else
1903:                    buffer.append(this .id);
1904:                buffer.append(")\n"); //$NON-NLS-1$
1905:                if (isDeprecated())
1906:                    buffer.append("deprecated "); //$NON-NLS-1$
1907:                if (isPublic())
1908:                    buffer.append("public "); //$NON-NLS-1$
1909:                if (isProtected())
1910:                    buffer.append("protected "); //$NON-NLS-1$
1911:                if (isPrivate())
1912:                    buffer.append("private "); //$NON-NLS-1$
1913:                if (isAbstract() && isClass())
1914:                    buffer.append("abstract "); //$NON-NLS-1$
1915:                if (isStatic() && isNestedType())
1916:                    buffer.append("static "); //$NON-NLS-1$
1917:                if (isFinal())
1918:                    buffer.append("final "); //$NON-NLS-1$
1919:
1920:                if (isEnum())
1921:                    buffer.append("enum "); //$NON-NLS-1$
1922:                else if (isAnnotationType())
1923:                    buffer.append("@interface "); //$NON-NLS-1$
1924:                else if (isClass())
1925:                    buffer.append("class "); //$NON-NLS-1$
1926:                else
1927:                    buffer.append("interface "); //$NON-NLS-1$
1928:                buffer.append((this .compoundName != null) ? CharOperation
1929:                        .toString(this .compoundName) : "UNNAMED TYPE"); //$NON-NLS-1$
1930:
1931:                if (this .typeVariables == null) {
1932:                    buffer.append("<NULL TYPE VARIABLES>"); //$NON-NLS-1$
1933:                } else if (this .typeVariables != Binding.NO_TYPE_VARIABLES) {
1934:                    buffer.append("\n\t<"); //$NON-NLS-1$
1935:                    for (int i = 0, length = this .typeVariables.length; i < length; i++) {
1936:                        if (i > 0)
1937:                            buffer.append(", "); //$NON-NLS-1$
1938:                        buffer
1939:                                .append((this .typeVariables[i] != null) ? this .typeVariables[i]
1940:                                        .toString()
1941:                                        : "NULL TYPE VARIABLE"); //$NON-NLS-1$
1942:                    }
1943:                    buffer.append(">"); //$NON-NLS-1$
1944:                }
1945:                buffer.append("\n\textends "); //$NON-NLS-1$
1946:                buffer.append((this .super class != null) ? this .super class
1947:                        .debugName() : "NULL TYPE"); //$NON-NLS-1$
1948:
1949:                if (this .super Interfaces != null) {
1950:                    if (this .super Interfaces != Binding.NO_SUPERINTERFACES) {
1951:                        buffer.append("\n\timplements : "); //$NON-NLS-1$
1952:                        for (int i = 0, length = this .super Interfaces.length; i < length; i++) {
1953:                            if (i > 0)
1954:                                buffer.append(", "); //$NON-NLS-1$
1955:                            buffer
1956:                                    .append((this .super Interfaces[i] != null) ? this .super Interfaces[i]
1957:                                            .debugName()
1958:                                            : "NULL TYPE"); //$NON-NLS-1$
1959:                        }
1960:                    }
1961:                } else {
1962:                    buffer.append("NULL SUPERINTERFACES"); //$NON-NLS-1$
1963:                }
1964:
1965:                if (enclosingType() != null) {
1966:                    buffer.append("\n\tenclosing type : "); //$NON-NLS-1$
1967:                    buffer.append(enclosingType().debugName());
1968:                }
1969:
1970:                if (this .fields != null) {
1971:                    if (this .fields != Binding.NO_FIELDS) {
1972:                        buffer.append("\n/*   fields   */"); //$NON-NLS-1$
1973:                        for (int i = 0, length = this .fields.length; i < length; i++)
1974:                            buffer.append('\n').append(
1975:                                    (this .fields[i] != null) ? this .fields[i]
1976:                                            .toString() : "NULL FIELD"); //$NON-NLS-1$ 
1977:                    }
1978:                } else {
1979:                    buffer.append("NULL FIELDS"); //$NON-NLS-1$
1980:                }
1981:
1982:                if (this .methods != null) {
1983:                    if (this .methods != Binding.NO_METHODS) {
1984:                        buffer.append("\n/*   methods   */"); //$NON-NLS-1$
1985:                        for (int i = 0, length = this .methods.length; i < length; i++)
1986:                            buffer.append('\n').append(
1987:                                    (this .methods[i] != null) ? this .methods[i]
1988:                                            .toString() : "NULL METHOD"); //$NON-NLS-1$
1989:                    }
1990:                } else {
1991:                    buffer.append("NULL METHODS"); //$NON-NLS-1$
1992:                }
1993:
1994:                if (this .memberTypes != null) {
1995:                    if (this .memberTypes != Binding.NO_MEMBER_TYPES) {
1996:                        buffer.append("\n/*   members   */"); //$NON-NLS-1$
1997:                        for (int i = 0, length = this .memberTypes.length; i < length; i++)
1998:                            buffer
1999:                                    .append('\n')
2000:                                    .append(
2001:                                            (this .memberTypes[i] != null) ? this .memberTypes[i]
2002:                                                    .toString()
2003:                                                    : "NULL TYPE"); //$NON-NLS-1$
2004:                    }
2005:                } else {
2006:                    buffer.append("NULL MEMBER TYPES"); //$NON-NLS-1$
2007:                }
2008:
2009:                buffer.append("\n\n"); //$NON-NLS-1$
2010:                return buffer.toString();
2011:            }
2012:
2013:            public TypeVariableBinding[] typeVariables() {
2014:                return this .typeVariables;
2015:            }
2016:
2017:            void verifyMethods(MethodVerifier verifier) {
2018:                verifier.verify(this );
2019:
2020:                for (int i = this .memberTypes.length; --i >= 0;)
2021:                    ((SourceTypeBinding) this.memberTypes[i])
2022:                            .verifyMethods(verifier);
2023:            }
2024:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.