Source Code Cross Referenced for SourceTypeConverter.java in  » IDE-Eclipse » jdt » org » eclipse » jdt » internal » compiler » parser » 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.parser 
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.parser;
0011:
0012:        /**
0013:         * Converter from source element type to parsed compilation unit.
0014:         *
0015:         * Limitation:
0016:         * | The source element field does not carry any information for its constant part, thus
0017:         * | the converted parse tree will not include any field initializations.
0018:         * | Therefore, any binary produced by compiling against converted source elements will
0019:         * | not take advantage of remote field constant inlining.
0020:         * | Given the intended purpose of the conversion is to resolve references, this is not
0021:         * | a problem.
0022:         *
0023:         */
0024:
0025:        import java.util.ArrayList;
0026:        import java.util.HashMap;
0027:
0028:        import org.eclipse.jdt.core.IImportDeclaration;
0029:        import org.eclipse.jdt.core.IJavaElement;
0030:        import org.eclipse.jdt.core.JavaModelException;
0031:        import org.eclipse.jdt.core.Signature;
0032:        import org.eclipse.jdt.core.compiler.CharOperation;
0033:        import org.eclipse.jdt.internal.compiler.CompilationResult;
0034:        import org.eclipse.jdt.internal.compiler.ast.*;
0035:        import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
0036:        import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
0037:        import org.eclipse.jdt.internal.compiler.env.*;
0038:
0039:        import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
0040:        import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
0041:        import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
0042:        import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
0043:        import org.eclipse.jdt.internal.core.*;
0044:        import org.eclipse.jdt.internal.core.util.Util;
0045:
0046:        public class SourceTypeConverter {
0047:
0048:            /* 
0049:             * Exception thrown while converting an anonymous type of a member type
0050:             * in this case, we must parse the source as the enclosing instance cannot be recreated
0051:             * from the model
0052:             */
0053:            static class AnonymousMemberFound extends RuntimeException {
0054:                private static final long serialVersionUID = 1L;
0055:            }
0056:
0057:            public static final int FIELD = 0x01;
0058:            public static final int CONSTRUCTOR = 0x02;
0059:            public static final int METHOD = 0x04;
0060:            public static final int MEMBER_TYPE = 0x08;
0061:            public static final int FIELD_INITIALIZATION = 0x10;
0062:            public static final int FIELD_AND_METHOD = FIELD | CONSTRUCTOR
0063:                    | METHOD;
0064:            public static final int LOCAL_TYPE = 0x20;
0065:            public static final int NONE = 0;
0066:
0067:            private int flags;
0068:            private CompilationUnitDeclaration unit;
0069:            private Parser parser;
0070:            private ProblemReporter problemReporter;
0071:            private ICompilationUnit cu;
0072:            private char[] source;
0073:            private HashMap annotationPositions;
0074:            private boolean has1_5Compliance;
0075:
0076:            int namePos;
0077:
0078:            private SourceTypeConverter(int flags,
0079:                    ProblemReporter problemReporter) {
0080:                this .flags = flags;
0081:                this .problemReporter = problemReporter;
0082:                this .has1_5Compliance = problemReporter.options.complianceLevel >= ClassFileConstants.JDK1_5;
0083:            }
0084:
0085:            /*
0086:             * Convert a set of source element types into a parsed compilation unit declaration
0087:             * The argument types are then all grouped in the same unit. The argument types must 
0088:             * at least contain one type.
0089:             * Can optionally ignore fields & methods or member types or field initialization
0090:             */
0091:            public static CompilationUnitDeclaration buildCompilationUnit(
0092:                    ISourceType[] sourceTypes, int flags,
0093:                    ProblemReporter problemReporter,
0094:                    CompilationResult compilationResult) {
0095:
0096:                //		long start = System.currentTimeMillis();
0097:                SourceTypeConverter converter = new SourceTypeConverter(flags,
0098:                        problemReporter);
0099:                try {
0100:                    return converter.convert(sourceTypes, compilationResult);
0101:                } catch (JavaModelException e) {
0102:                    return null;
0103:                    /*		} finally {
0104:                     System.out.println("Spent " + (System.currentTimeMillis() - start) + "ms to convert " + ((JavaElement) converter.cu).toStringWithAncestors());
0105:                     */}
0106:            }
0107:
0108:            /*
0109:             * Convert a set of source element types into a parsed compilation unit declaration
0110:             * The argument types are then all grouped in the same unit. The argument types must 
0111:             * at least contain one type.
0112:             */
0113:            private CompilationUnitDeclaration convert(
0114:                    ISourceType[] sourceTypes,
0115:                    CompilationResult compilationResult)
0116:                    throws JavaModelException {
0117:                this .unit = new CompilationUnitDeclaration(
0118:                        this .problemReporter, compilationResult, 0);
0119:                // not filled at this point
0120:
0121:                if (sourceTypes.length == 0)
0122:                    return this .unit;
0123:                SourceTypeElementInfo topLevelTypeInfo = (SourceTypeElementInfo) sourceTypes[0];
0124:                org.eclipse.jdt.core.ICompilationUnit cuHandle = topLevelTypeInfo
0125:                        .getHandle().getCompilationUnit();
0126:                this .cu = (ICompilationUnit) cuHandle;
0127:                this .annotationPositions = ((CompilationUnitElementInfo) ((JavaElement) this .cu)
0128:                        .getElementInfo()).annotationPositions;
0129:
0130:                if (this .has1_5Compliance && this .annotationPositions != null
0131:                        && this .annotationPositions.size() > 10) { // experimental value
0132:                    // if more than 10 annotations, diet parse as this is faster
0133:                    return new Parser(this .problemReporter, true).dietParse(
0134:                            this .cu, compilationResult);
0135:                }
0136:
0137:                /* only positions available */
0138:                int start = topLevelTypeInfo.getNameSourceStart();
0139:                int end = topLevelTypeInfo.getNameSourceEnd();
0140:
0141:                /* convert package and imports */
0142:                String[] packageName = ((PackageFragment) cuHandle.getParent()).names;
0143:                if (packageName.length > 0)
0144:                    // if its null then it is defined in the default package
0145:                    this .unit.currentPackage = createImportReference(
0146:                            packageName, start, end, false,
0147:                            ClassFileConstants.AccDefault);
0148:                IImportDeclaration[] importDeclarations = topLevelTypeInfo
0149:                        .getHandle().getCompilationUnit().getImports();
0150:                int importCount = importDeclarations.length;
0151:                this .unit.imports = new ImportReference[importCount];
0152:                for (int i = 0; i < importCount; i++) {
0153:                    ImportDeclaration importDeclaration = (ImportDeclaration) importDeclarations[i];
0154:                    ISourceImport sourceImport = (ISourceImport) importDeclaration
0155:                            .getElementInfo();
0156:                    String nameWithoutStar = importDeclaration
0157:                            .getNameWithoutStar();
0158:                    this .unit.imports[i] = createImportReference(Util.splitOn(
0159:                            '.', nameWithoutStar, 0, nameWithoutStar.length()),
0160:                            sourceImport.getDeclarationSourceStart(),
0161:                            sourceImport.getDeclarationSourceEnd(),
0162:                            importDeclaration.isOnDemand(), sourceImport
0163:                                    .getModifiers());
0164:                }
0165:                /* convert type(s) */
0166:                try {
0167:                    int typeCount = sourceTypes.length;
0168:                    final TypeDeclaration[] types = new TypeDeclaration[typeCount];
0169:                    /*
0170:                     * We used a temporary types collection to prevent this.unit.types from being null during a call to
0171:                     * convert(...) when the source is syntactically incorrect and the parser is flushing the unit's types.
0172:                     * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=97466
0173:                     */
0174:                    for (int i = 0; i < typeCount; i++) {
0175:                        SourceTypeElementInfo typeInfo = (SourceTypeElementInfo) sourceTypes[i];
0176:                        types[i] = convert((SourceType) typeInfo.getHandle(),
0177:                                compilationResult);
0178:                    }
0179:                    this .unit.types = types;
0180:                    return this .unit;
0181:                } catch (AnonymousMemberFound e) {
0182:                    return new Parser(this .problemReporter, true).parse(
0183:                            this .cu, compilationResult);
0184:                }
0185:            }
0186:
0187:            private void addIdentifiers(String typeSignature, int start,
0188:                    int endExclusive, int identCount, ArrayList fragments) {
0189:                if (identCount == 1) {
0190:                    char[] identifier;
0191:                    typeSignature.getChars(start, endExclusive,
0192:                            identifier = new char[endExclusive - start], 0);
0193:                    fragments.add(identifier);
0194:                } else
0195:                    fragments.add(extractIdentifiers(typeSignature, start,
0196:                            endExclusive - 1, identCount));
0197:            }
0198:
0199:            /*
0200:             * Convert an initializerinfo into a parsed initializer declaration
0201:             */
0202:            private Initializer convert(InitializerElementInfo initializerInfo,
0203:                    CompilationResult compilationResult)
0204:                    throws JavaModelException {
0205:
0206:                Block block = new Block(0);
0207:                Initializer initializer = new Initializer(block,
0208:                        ClassFileConstants.AccDefault);
0209:
0210:                int start = initializerInfo.getDeclarationSourceStart();
0211:                int end = initializerInfo.getDeclarationSourceEnd();
0212:
0213:                initializer.sourceStart = initializer.declarationSourceStart = start;
0214:                initializer.sourceEnd = initializer.declarationSourceEnd = end;
0215:                initializer.modifiers = initializerInfo.getModifiers();
0216:
0217:                /* convert local and anonymous types */
0218:                IJavaElement[] children = initializerInfo.getChildren();
0219:                int typesLength = children.length;
0220:                if (typesLength > 0) {
0221:                    Statement[] statements = new Statement[typesLength];
0222:                    for (int i = 0; i < typesLength; i++) {
0223:                        SourceType type = (SourceType) children[i];
0224:                        TypeDeclaration localType = convert(type,
0225:                                compilationResult);
0226:                        if ((localType.bits & ASTNode.IsAnonymousType) != 0) {
0227:                            QualifiedAllocationExpression expression = new QualifiedAllocationExpression(
0228:                                    localType);
0229:                            expression.type = localType.super class;
0230:                            localType.super class = null;
0231:                            localType.super Interfaces = null;
0232:                            localType.allocation = expression;
0233:                            statements[i] = expression;
0234:                        } else {
0235:                            statements[i] = localType;
0236:                        }
0237:                    }
0238:                    block.statements = statements;
0239:                }
0240:
0241:                return initializer;
0242:            }
0243:
0244:            /*
0245:             * Convert a field source element into a parsed field declaration
0246:             */
0247:            private FieldDeclaration convert(SourceField fieldHandle,
0248:                    TypeDeclaration type, CompilationResult compilationResult)
0249:                    throws JavaModelException {
0250:
0251:                SourceFieldElementInfo fieldInfo = (SourceFieldElementInfo) fieldHandle
0252:                        .getElementInfo();
0253:                FieldDeclaration field = new FieldDeclaration();
0254:
0255:                int start = fieldInfo.getNameSourceStart();
0256:                int end = fieldInfo.getNameSourceEnd();
0257:
0258:                field.name = fieldHandle.getElementName().toCharArray();
0259:                field.sourceStart = start;
0260:                field.sourceEnd = end;
0261:                field.declarationSourceStart = fieldInfo
0262:                        .getDeclarationSourceStart();
0263:                field.declarationSourceEnd = fieldInfo
0264:                        .getDeclarationSourceEnd();
0265:                int modifiers = fieldInfo.getModifiers();
0266:                boolean isEnumConstant = (modifiers & ClassFileConstants.AccEnum) != 0;
0267:                if (isEnumConstant) {
0268:                    field.modifiers = modifiers & ~ClassFileConstants.AccEnum; // clear AccEnum bit onto AST (binding will add it)
0269:                } else {
0270:                    field.modifiers = modifiers;
0271:                    field.type = createTypeReference(fieldInfo.getTypeName(),
0272:                            start, end);
0273:                }
0274:
0275:                // convert 1.5 specific constructs only if compliance is 1.5 or above
0276:                if (this .has1_5Compliance) {
0277:                    /* convert annotations */
0278:                    field.annotations = convertAnnotations(fieldHandle);
0279:                }
0280:
0281:                /* conversion of field constant */
0282:                if ((this .flags & FIELD_INITIALIZATION) != 0) {
0283:                    char[] initializationSource = fieldInfo
0284:                            .getInitializationSource();
0285:                    if (initializationSource != null) {
0286:                        if (this .parser == null) {
0287:                            this .parser = new Parser(this .problemReporter, true);
0288:                        }
0289:                        this .parser.parse(field, type, this .unit,
0290:                                initializationSource);
0291:                    }
0292:                }
0293:
0294:                /* conversion of local and anonymous types */
0295:                if ((this .flags & LOCAL_TYPE) != 0) {
0296:                    IJavaElement[] children = fieldInfo.getChildren();
0297:                    int childrenLength = children.length;
0298:                    if (childrenLength == 1) {
0299:                        field.initialization = convert(children[0],
0300:                                isEnumConstant ? field : null,
0301:                                compilationResult);
0302:                    } else if (childrenLength > 1) {
0303:                        ArrayInitializer initializer = new ArrayInitializer();
0304:                        field.initialization = initializer;
0305:                        Expression[] expressions = new Expression[childrenLength];
0306:                        initializer.expressions = expressions;
0307:                        for (int i = 0; i < childrenLength; i++) {
0308:                            expressions[i] = convert(children[i],
0309:                                    isEnumConstant ? field : null,
0310:                                    compilationResult);
0311:                        }
0312:                    }
0313:                }
0314:                return field;
0315:            }
0316:
0317:            private QualifiedAllocationExpression convert(
0318:                    IJavaElement localType, FieldDeclaration enumConstant,
0319:                    CompilationResult compilationResult)
0320:                    throws JavaModelException {
0321:                TypeDeclaration anonymousLocalTypeDeclaration = convert(
0322:                        (SourceType) localType, compilationResult);
0323:                QualifiedAllocationExpression expression = new QualifiedAllocationExpression(
0324:                        anonymousLocalTypeDeclaration);
0325:                expression.type = anonymousLocalTypeDeclaration.super class;
0326:                anonymousLocalTypeDeclaration.super class = null;
0327:                anonymousLocalTypeDeclaration.super Interfaces = null;
0328:                anonymousLocalTypeDeclaration.allocation = expression;
0329:                if (enumConstant != null) {
0330:                    anonymousLocalTypeDeclaration.modifiers &= ~ClassFileConstants.AccEnum;
0331:                    expression.enumConstant = enumConstant;
0332:                    expression.type = null;
0333:                }
0334:                return expression;
0335:            }
0336:
0337:            /*
0338:             * Convert a method source element into a parsed method/constructor declaration 
0339:             */
0340:            private AbstractMethodDeclaration convert(
0341:                    SourceMethod methodHandle,
0342:                    SourceMethodElementInfo methodInfo,
0343:                    CompilationResult compilationResult)
0344:                    throws JavaModelException {
0345:                AbstractMethodDeclaration method;
0346:
0347:                /* only source positions available */
0348:                int start = methodInfo.getNameSourceStart();
0349:                int end = methodInfo.getNameSourceEnd();
0350:
0351:                // convert 1.5 specific constructs only if compliance is 1.5 or above
0352:                TypeParameter[] typeParams = null;
0353:                if (this .has1_5Compliance) {
0354:                    /* convert type parameters */
0355:                    char[][] typeParameterNames = methodInfo
0356:                            .getTypeParameterNames();
0357:                    if (typeParameterNames != null) {
0358:                        int parameterCount = typeParameterNames.length;
0359:                        if (parameterCount > 0) { // method's type parameters must be null if no type parameter
0360:                            char[][][] typeParameterBounds = methodInfo
0361:                                    .getTypeParameterBounds();
0362:                            typeParams = new TypeParameter[parameterCount];
0363:                            for (int i = 0; i < parameterCount; i++) {
0364:                                typeParams[i] = createTypeParameter(
0365:                                        typeParameterNames[i],
0366:                                        typeParameterBounds[i], start, end);
0367:                            }
0368:                        }
0369:                    }
0370:                }
0371:
0372:                int modifiers = methodInfo.getModifiers();
0373:                if (methodInfo.isConstructor()) {
0374:                    ConstructorDeclaration decl = new ConstructorDeclaration(
0375:                            compilationResult);
0376:                    decl.bits &= ~ASTNode.IsDefaultConstructor;
0377:                    method = decl;
0378:                    decl.typeParameters = typeParams;
0379:                } else {
0380:                    MethodDeclaration decl;
0381:                    if (methodInfo.isAnnotationMethod()) {
0382:                        AnnotationMethodDeclaration annotationMethodDeclaration = new AnnotationMethodDeclaration(
0383:                                compilationResult);
0384:
0385:                        /* conversion of default value */
0386:                        SourceAnnotationMethodInfo annotationMethodInfo = (SourceAnnotationMethodInfo) methodInfo;
0387:                        boolean hasDefaultValue = annotationMethodInfo.defaultValueStart != -1
0388:                                || annotationMethodInfo.defaultValueEnd != -1;
0389:                        if ((this .flags & FIELD_INITIALIZATION) != 0) {
0390:                            if (hasDefaultValue) {
0391:                                char[] defaultValueSource = CharOperation
0392:                                        .subarray(
0393:                                                getSource(),
0394:                                                annotationMethodInfo.defaultValueStart,
0395:                                                annotationMethodInfo.defaultValueEnd + 1);
0396:                                if (defaultValueSource != null) {
0397:                                    Expression expression = parseMemberValue(defaultValueSource);
0398:                                    if (expression != null) {
0399:                                        annotationMethodDeclaration.defaultValue = expression;
0400:                                    }
0401:                                } else {
0402:                                    // could not retrieve the default value
0403:                                    hasDefaultValue = false;
0404:                                }
0405:                            }
0406:                        }
0407:                        if (hasDefaultValue)
0408:                            modifiers |= ClassFileConstants.AccAnnotationDefault;
0409:                        decl = annotationMethodDeclaration;
0410:                    } else {
0411:                        decl = new MethodDeclaration(compilationResult);
0412:                    }
0413:
0414:                    // convert return type
0415:                    decl.returnType = createTypeReference(methodInfo
0416:                            .getReturnTypeName(), start, end);
0417:
0418:                    // type parameters
0419:                    decl.typeParameters = typeParams;
0420:
0421:                    method = decl;
0422:                }
0423:                method.selector = methodHandle.getElementName().toCharArray();
0424:                boolean isVarargs = (modifiers & ClassFileConstants.AccVarargs) != 0;
0425:                method.modifiers = modifiers & ~ClassFileConstants.AccVarargs;
0426:                method.sourceStart = start;
0427:                method.sourceEnd = end;
0428:                method.declarationSourceStart = methodInfo
0429:                        .getDeclarationSourceStart();
0430:                method.declarationSourceEnd = methodInfo
0431:                        .getDeclarationSourceEnd();
0432:
0433:                // convert 1.5 specific constructs only if compliance is 1.5 or above
0434:                if (this .has1_5Compliance) {
0435:                    /* convert annotations */
0436:                    method.annotations = convertAnnotations(methodHandle);
0437:                }
0438:
0439:                /* convert arguments */
0440:                String[] argumentTypeSignatures = methodHandle
0441:                        .getParameterTypes();
0442:                char[][] argumentNames = methodInfo.getArgumentNames();
0443:                int argumentCount = argumentTypeSignatures == null ? 0
0444:                        : argumentTypeSignatures.length;
0445:                if (argumentCount > 0) {
0446:                    long position = ((long) start << 32) + end;
0447:                    method.arguments = new Argument[argumentCount];
0448:                    for (int i = 0; i < argumentCount; i++) {
0449:                        TypeReference typeReference = createTypeReference(
0450:                                argumentTypeSignatures[i], start, end);
0451:                        if (isVarargs && i == argumentCount - 1) {
0452:                            typeReference.bits |= ASTNode.IsVarArgs;
0453:                        }
0454:                        method.arguments[i] = new Argument(argumentNames[i],
0455:                                position, typeReference,
0456:                                ClassFileConstants.AccDefault);
0457:                        // do not care whether was final or not
0458:                    }
0459:                }
0460:
0461:                /* convert thrown exceptions */
0462:                char[][] exceptionTypeNames = methodInfo
0463:                        .getExceptionTypeNames();
0464:                int exceptionCount = exceptionTypeNames == null ? 0
0465:                        : exceptionTypeNames.length;
0466:                if (exceptionCount > 0) {
0467:                    method.thrownExceptions = new TypeReference[exceptionCount];
0468:                    for (int i = 0; i < exceptionCount; i++) {
0469:                        method.thrownExceptions[i] = createTypeReference(
0470:                                exceptionTypeNames[i], start, end);
0471:                    }
0472:                }
0473:
0474:                /* convert local and anonymous types */
0475:                if ((this .flags & LOCAL_TYPE) != 0) {
0476:                    IJavaElement[] children = methodInfo.getChildren();
0477:                    int typesLength = children.length;
0478:                    if (typesLength != 0) {
0479:                        Statement[] statements = new Statement[typesLength];
0480:                        for (int i = 0; i < typesLength; i++) {
0481:                            SourceType type = (SourceType) children[i];
0482:                            TypeDeclaration localType = convert(type,
0483:                                    compilationResult);
0484:                            if ((localType.bits & ASTNode.IsAnonymousType) != 0) {
0485:                                QualifiedAllocationExpression expression = new QualifiedAllocationExpression(
0486:                                        localType);
0487:                                expression.type = localType.super class;
0488:                                localType.super class = null;
0489:                                localType.super Interfaces = null;
0490:                                localType.allocation = expression;
0491:                                statements[i] = expression;
0492:                            } else {
0493:                                statements[i] = localType;
0494:                            }
0495:                        }
0496:                        method.statements = statements;
0497:                    }
0498:                }
0499:
0500:                return method;
0501:            }
0502:
0503:            /*
0504:             * Convert a source element type into a parsed type declaration
0505:             */
0506:            private TypeDeclaration convert(SourceType typeHandle,
0507:                    CompilationResult compilationResult)
0508:                    throws JavaModelException {
0509:                SourceTypeElementInfo typeInfo = (SourceTypeElementInfo) typeHandle
0510:                        .getElementInfo();
0511:                if (typeInfo.isAnonymousMember())
0512:                    throw new AnonymousMemberFound();
0513:                /* create type declaration - can be member type */
0514:                TypeDeclaration type = new TypeDeclaration(compilationResult);
0515:                if (typeInfo.getEnclosingType() == null) {
0516:                    if (typeHandle.isAnonymous()) {
0517:                        type.name = CharOperation.NO_CHAR;
0518:                        type.bits |= (ASTNode.IsAnonymousType | ASTNode.IsLocalType);
0519:                    } else {
0520:                        if (typeHandle.isLocal()) {
0521:                            type.bits |= ASTNode.IsLocalType;
0522:                        }
0523:                    }
0524:                } else {
0525:                    type.bits |= ASTNode.IsMemberType;
0526:                }
0527:                if ((type.bits & ASTNode.IsAnonymousType) == 0) {
0528:                    type.name = typeInfo.getName();
0529:                }
0530:                type.name = typeInfo.getName();
0531:                int start, end; // only positions available
0532:                type.sourceStart = start = typeInfo.getNameSourceStart();
0533:                type.sourceEnd = end = typeInfo.getNameSourceEnd();
0534:                type.modifiers = typeInfo.getModifiers();
0535:                type.declarationSourceStart = typeInfo
0536:                        .getDeclarationSourceStart();
0537:                type.declarationSourceEnd = typeInfo.getDeclarationSourceEnd();
0538:                type.bodyEnd = type.declarationSourceEnd;
0539:
0540:                // convert 1.5 specific constructs only if compliance is 1.5 or above
0541:                if (this .has1_5Compliance) {
0542:                    /* convert annotations */
0543:                    type.annotations = convertAnnotations(typeHandle);
0544:
0545:                    /* convert type parameters */
0546:                    char[][] typeParameterNames = typeInfo
0547:                            .getTypeParameterNames();
0548:                    if (typeParameterNames.length > 0) {
0549:                        int parameterCount = typeParameterNames.length;
0550:                        char[][][] typeParameterBounds = typeInfo
0551:                                .getTypeParameterBounds();
0552:                        type.typeParameters = new TypeParameter[parameterCount];
0553:                        for (int i = 0; i < parameterCount; i++) {
0554:                            type.typeParameters[i] = createTypeParameter(
0555:                                    typeParameterNames[i],
0556:                                    typeParameterBounds[i], start, end);
0557:                        }
0558:                    }
0559:                }
0560:
0561:                /* set superclass and superinterfaces */
0562:                if (typeInfo.getSuperclassName() != null) {
0563:                    type.super class = createTypeReference(typeInfo
0564:                            .getSuperclassName(), start, end);
0565:                    type.super class.bits |= ASTNode.IsSuperType;
0566:                }
0567:                char[][] interfaceNames = typeInfo.getInterfaceNames();
0568:                int interfaceCount = interfaceNames == null ? 0
0569:                        : interfaceNames.length;
0570:                if (interfaceCount > 0) {
0571:                    type.super Interfaces = new TypeReference[interfaceCount];
0572:                    for (int i = 0; i < interfaceCount; i++) {
0573:                        type.super Interfaces[i] = createTypeReference(
0574:                                interfaceNames[i], start, end);
0575:                        type.super Interfaces[i].bits |= ASTNode.IsSuperType;
0576:                    }
0577:                }
0578:                /* convert member types */
0579:                if ((this .flags & MEMBER_TYPE) != 0) {
0580:                    SourceType[] sourceMemberTypes = typeInfo
0581:                            .getMemberTypeHandles();
0582:                    int sourceMemberTypeCount = sourceMemberTypes.length;
0583:                    type.memberTypes = new TypeDeclaration[sourceMemberTypeCount];
0584:                    for (int i = 0; i < sourceMemberTypeCount; i++) {
0585:                        type.memberTypes[i] = convert(sourceMemberTypes[i],
0586:                                compilationResult);
0587:                    }
0588:                }
0589:
0590:                /* convert intializers and fields*/
0591:                InitializerElementInfo[] initializers = null;
0592:                int initializerCount = 0;
0593:                if ((this .flags & LOCAL_TYPE) != 0) {
0594:                    initializers = typeInfo.getInitializers();
0595:                    initializerCount = initializers.length;
0596:                }
0597:                SourceField[] sourceFields = null;
0598:                int sourceFieldCount = 0;
0599:                if ((this .flags & FIELD) != 0) {
0600:                    sourceFields = typeInfo.getFieldHandles();
0601:                    sourceFieldCount = sourceFields.length;
0602:                }
0603:                int length = initializerCount + sourceFieldCount;
0604:                if (length > 0) {
0605:                    type.fields = new FieldDeclaration[length];
0606:                    for (int i = 0; i < initializerCount; i++) {
0607:                        type.fields[i] = convert(initializers[i],
0608:                                compilationResult);
0609:                    }
0610:                    int index = 0;
0611:                    for (int i = initializerCount; i < length; i++) {
0612:                        type.fields[i] = convert(sourceFields[index++], type,
0613:                                compilationResult);
0614:                    }
0615:                }
0616:
0617:                /* convert methods - need to add default constructor if necessary */
0618:                boolean needConstructor = (this .flags & CONSTRUCTOR) != 0;
0619:                boolean needMethod = (this .flags & METHOD) != 0;
0620:                if (needConstructor || needMethod) {
0621:
0622:                    SourceMethod[] sourceMethods = typeInfo.getMethodHandles();
0623:                    int sourceMethodCount = sourceMethods.length;
0624:
0625:                    /* source type has a constructor ?           */
0626:                    /* by default, we assume that one is needed. */
0627:                    int extraConstructor = 0;
0628:                    int methodCount = 0;
0629:                    int kind = TypeDeclaration.kind(type.modifiers);
0630:                    boolean isAbstract = kind == TypeDeclaration.INTERFACE_DECL
0631:                            || kind == TypeDeclaration.ANNOTATION_TYPE_DECL;
0632:                    if (!isAbstract) {
0633:                        extraConstructor = needConstructor ? 1 : 0;
0634:                        for (int i = 0; i < sourceMethodCount; i++) {
0635:                            if (sourceMethods[i].isConstructor()) {
0636:                                if (needConstructor) {
0637:                                    extraConstructor = 0; // Does not need the extra constructor since one constructor already exists.
0638:                                    methodCount++;
0639:                                }
0640:                            } else if (needMethod) {
0641:                                methodCount++;
0642:                            }
0643:                        }
0644:                    } else {
0645:                        methodCount = needMethod ? sourceMethodCount : 0;
0646:                    }
0647:                    type.methods = new AbstractMethodDeclaration[methodCount
0648:                            + extraConstructor];
0649:                    if (extraConstructor != 0) { // add default constructor in first position
0650:                        type.methods[0] = type.createDefaultConstructor(false,
0651:                                false);
0652:                    }
0653:                    int index = 0;
0654:                    boolean hasAbstractMethods = false;
0655:                    for (int i = 0; i < sourceMethodCount; i++) {
0656:                        SourceMethod sourceMethod = sourceMethods[i];
0657:                        SourceMethodElementInfo methodInfo = (SourceMethodElementInfo) sourceMethod
0658:                                .getElementInfo();
0659:                        boolean isConstructor = methodInfo.isConstructor();
0660:                        if ((methodInfo.getModifiers() & ClassFileConstants.AccAbstract) != 0) {
0661:                            hasAbstractMethods = true;
0662:                        }
0663:                        if ((isConstructor && needConstructor)
0664:                                || (!isConstructor && needMethod)) {
0665:                            AbstractMethodDeclaration method = convert(
0666:                                    sourceMethod, methodInfo, compilationResult);
0667:                            if (isAbstract || method.isAbstract()) { // fix-up flag 
0668:                                method.modifiers |= ExtraCompilerModifiers.AccSemicolonBody;
0669:                            }
0670:                            type.methods[extraConstructor + index++] = method;
0671:                        }
0672:                    }
0673:                    if (hasAbstractMethods)
0674:                        type.bits |= ASTNode.HasAbstractMethods;
0675:                }
0676:
0677:                return type;
0678:            }
0679:
0680:            private Annotation[] convertAnnotations(JavaElement element) {
0681:                if (this .annotationPositions == null)
0682:                    return null;
0683:                char[] cuSource = getSource();
0684:                long[] positions = (long[]) this .annotationPositions
0685:                        .get(element);
0686:                if (positions == null)
0687:                    return null;
0688:                int length = positions.length;
0689:                Annotation[] annotations = new Annotation[length];
0690:                int recordedAnnotations = 0;
0691:                for (int i = 0; i < length; i++) {
0692:                    long position = positions[i];
0693:                    int start = (int) (position >>> 32);
0694:                    int end = (int) position;
0695:                    char[] annotationSource = CharOperation.subarray(cuSource,
0696:                            start, end + 1);
0697:                    if (annotationSource != null) {
0698:                        Expression expression = parseMemberValue(annotationSource);
0699:                        /*
0700:                         * expression can be null or not an annotation if the source has changed between
0701:                         * the moment where the annotation source positions have been retrieved and the moment were
0702:                         * this parsing occured.
0703:                         * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=90916
0704:                         */
0705:                        if (expression instanceof  Annotation) {
0706:                            annotations[recordedAnnotations++] = (Annotation) expression;
0707:                        }
0708:                    }
0709:                }
0710:                if (length != recordedAnnotations) {
0711:                    // resize to remove null annotations
0712:                    System
0713:                            .arraycopy(
0714:                                    annotations,
0715:                                    0,
0716:                                    (annotations = new Annotation[recordedAnnotations]),
0717:                                    0, recordedAnnotations);
0718:                }
0719:                return annotations;
0720:            }
0721:
0722:            /*
0723:             * Build an import reference from an import name, e.g. java.lang.*
0724:             */
0725:            private ImportReference createImportReference(String[] importName,
0726:                    int start, int end, boolean onDemand, int modifiers) {
0727:
0728:                int length = importName.length;
0729:                long[] positions = new long[length];
0730:                long position = ((long) start << 32) + end;
0731:                char[][] qImportName = new char[length][];
0732:                for (int i = 0; i < length; i++) {
0733:                    qImportName[i] = importName[i].toCharArray();
0734:                    positions[i] = position; // dummy positions
0735:                }
0736:                return new ImportReference(qImportName, positions, onDemand,
0737:                        modifiers);
0738:            }
0739:
0740:            private TypeParameter createTypeParameter(char[] typeParameterName,
0741:                    char[][] typeParameterBounds, int start, int end) {
0742:
0743:                TypeParameter parameter = new TypeParameter();
0744:                parameter.name = typeParameterName;
0745:                parameter.sourceStart = start;
0746:                parameter.sourceEnd = end;
0747:                if (typeParameterBounds != null) {
0748:                    int length = typeParameterBounds.length;
0749:                    if (length > 0) {
0750:                        parameter.type = createTypeReference(
0751:                                typeParameterBounds[0], start, end);
0752:                        if (length > 1) {
0753:                            parameter.bounds = new TypeReference[length - 1];
0754:                            for (int i = 1; i < length; i++) {
0755:                                TypeReference bound = createTypeReference(
0756:                                        typeParameterBounds[i], start, end);
0757:                                bound.bits |= ASTNode.IsSuperType;
0758:                                parameter.bounds[i - 1] = bound;
0759:                            }
0760:                        }
0761:                    }
0762:                }
0763:                return parameter;
0764:            }
0765:
0766:            /*
0767:             * Build a type reference from a readable name, e.g. java.lang.Object[][]
0768:             */
0769:            private TypeReference createTypeReference(char[] typeName,
0770:                    int start, int end) {
0771:
0772:                int length = typeName.length;
0773:                this .namePos = 0;
0774:                return decodeType(typeName, length, start, end);
0775:            }
0776:
0777:            /*
0778:             * Build a type reference from a type signature, e.g. Ljava.lang.Object;
0779:             */
0780:            private TypeReference createTypeReference(String typeSignature,
0781:                    int start, int end) {
0782:
0783:                int length = typeSignature.length();
0784:                this .namePos = 0;
0785:                return decodeType(typeSignature, length, start, end);
0786:            }
0787:
0788:            private TypeReference decodeType(String typeSignature, int length,
0789:                    int start, int end) {
0790:                int identCount = 1;
0791:                int dim = 0;
0792:                int nameFragmentStart = this .namePos, nameFragmentEnd = -1;
0793:                boolean nameStarted = false;
0794:                ArrayList fragments = null;
0795:                typeLoop: while (this .namePos < length) {
0796:                    char currentChar = typeSignature.charAt(this .namePos);
0797:                    switch (currentChar) {
0798:                    case Signature.C_BOOLEAN:
0799:                        if (!nameStarted) {
0800:                            this .namePos++;
0801:                            if (dim == 0)
0802:                                return new SingleTypeReference(
0803:                                        TypeBinding.BOOLEAN.simpleName,
0804:                                        ((long) start << 32) + end);
0805:                            else
0806:                                return new ArrayTypeReference(
0807:                                        TypeBinding.BOOLEAN.simpleName, dim,
0808:                                        ((long) start << 32) + end);
0809:                        }
0810:                        break;
0811:                    case Signature.C_BYTE:
0812:                        if (!nameStarted) {
0813:                            this .namePos++;
0814:                            if (dim == 0)
0815:                                return new SingleTypeReference(
0816:                                        TypeBinding.BYTE.simpleName,
0817:                                        ((long) start << 32) + end);
0818:                            else
0819:                                return new ArrayTypeReference(
0820:                                        TypeBinding.BYTE.simpleName, dim,
0821:                                        ((long) start << 32) + end);
0822:                        }
0823:                        break;
0824:                    case Signature.C_CHAR:
0825:                        if (!nameStarted) {
0826:                            this .namePos++;
0827:                            if (dim == 0)
0828:                                return new SingleTypeReference(
0829:                                        TypeBinding.CHAR.simpleName,
0830:                                        ((long) start << 32) + end);
0831:                            else
0832:                                return new ArrayTypeReference(
0833:                                        TypeBinding.CHAR.simpleName, dim,
0834:                                        ((long) start << 32) + end);
0835:                        }
0836:                        break;
0837:                    case Signature.C_DOUBLE:
0838:                        if (!nameStarted) {
0839:                            this .namePos++;
0840:                            if (dim == 0)
0841:                                return new SingleTypeReference(
0842:                                        TypeBinding.DOUBLE.simpleName,
0843:                                        ((long) start << 32) + end);
0844:                            else
0845:                                return new ArrayTypeReference(
0846:                                        TypeBinding.DOUBLE.simpleName, dim,
0847:                                        ((long) start << 32) + end);
0848:                        }
0849:                        break;
0850:                    case Signature.C_FLOAT:
0851:                        if (!nameStarted) {
0852:                            this .namePos++;
0853:                            if (dim == 0)
0854:                                return new SingleTypeReference(
0855:                                        TypeBinding.FLOAT.simpleName,
0856:                                        ((long) start << 32) + end);
0857:                            else
0858:                                return new ArrayTypeReference(
0859:                                        TypeBinding.FLOAT.simpleName, dim,
0860:                                        ((long) start << 32) + end);
0861:                        }
0862:                        break;
0863:                    case Signature.C_INT:
0864:                        if (!nameStarted) {
0865:                            this .namePos++;
0866:                            if (dim == 0)
0867:                                return new SingleTypeReference(
0868:                                        TypeBinding.INT.simpleName,
0869:                                        ((long) start << 32) + end);
0870:                            else
0871:                                return new ArrayTypeReference(
0872:                                        TypeBinding.INT.simpleName, dim,
0873:                                        ((long) start << 32) + end);
0874:                        }
0875:                        break;
0876:                    case Signature.C_LONG:
0877:                        if (!nameStarted) {
0878:                            this .namePos++;
0879:                            if (dim == 0)
0880:                                return new SingleTypeReference(
0881:                                        TypeBinding.LONG.simpleName,
0882:                                        ((long) start << 32) + end);
0883:                            else
0884:                                return new ArrayTypeReference(
0885:                                        TypeBinding.LONG.simpleName, dim,
0886:                                        ((long) start << 32) + end);
0887:                        }
0888:                        break;
0889:                    case Signature.C_SHORT:
0890:                        if (!nameStarted) {
0891:                            this .namePos++;
0892:                            if (dim == 0)
0893:                                return new SingleTypeReference(
0894:                                        TypeBinding.SHORT.simpleName,
0895:                                        ((long) start << 32) + end);
0896:                            else
0897:                                return new ArrayTypeReference(
0898:                                        TypeBinding.SHORT.simpleName, dim,
0899:                                        ((long) start << 32) + end);
0900:                        }
0901:                        break;
0902:                    case Signature.C_VOID:
0903:                        if (!nameStarted) {
0904:                            this .namePos++;
0905:                            new SingleTypeReference(
0906:                                    TypeBinding.VOID.simpleName,
0907:                                    ((long) start << 32) + end);
0908:                        }
0909:                        break;
0910:                    case Signature.C_RESOLVED:
0911:                    case Signature.C_UNRESOLVED:
0912:                        if (!nameStarted) {
0913:                            nameFragmentStart = this .namePos + 1;
0914:                            nameStarted = true;
0915:                        }
0916:                        break;
0917:                    case Signature.C_STAR:
0918:                        this .namePos++;
0919:                        Wildcard result = new Wildcard(Wildcard.UNBOUND);
0920:                        result.sourceStart = start;
0921:                        result.sourceEnd = end;
0922:                        return result;
0923:                    case Signature.C_EXTENDS:
0924:                        this .namePos++;
0925:                        result = new Wildcard(Wildcard.EXTENDS);
0926:                        result.bound = decodeType(typeSignature, length, start,
0927:                                end);
0928:                        result.sourceStart = start;
0929:                        result.sourceEnd = end;
0930:                        return result;
0931:                    case Signature.C_SUPER:
0932:                        this .namePos++;
0933:                        result = new Wildcard(Wildcard.SUPER);
0934:                        result.bound = decodeType(typeSignature, length, start,
0935:                                end);
0936:                        result.sourceStart = start;
0937:                        result.sourceEnd = end;
0938:                        return result;
0939:                    case Signature.C_ARRAY:
0940:                        dim++;
0941:                        break;
0942:                    case Signature.C_GENERIC_END:
0943:                    case Signature.C_SEMICOLON:
0944:                        nameFragmentEnd = this .namePos - 1;
0945:                        this .namePos++;
0946:                        break typeLoop;
0947:                    case Signature.C_DOT:
0948:                    case Signature.C_DOLLAR:
0949:                        if (!nameStarted) {
0950:                            nameFragmentStart = this .namePos + 1;
0951:                            nameStarted = true;
0952:                        } else if (this .namePos > nameFragmentStart) // handle name starting with a $ (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=91709)
0953:                            identCount++;
0954:                        break;
0955:                    case Signature.C_GENERIC_START:
0956:                        nameFragmentEnd = this .namePos - 1;
0957:                        // convert 1.5 specific constructs only if compliance is 1.5 or above
0958:                        if (!this .has1_5Compliance)
0959:                            break typeLoop;
0960:                        if (fragments == null)
0961:                            fragments = new ArrayList(2);
0962:                        addIdentifiers(typeSignature, nameFragmentStart,
0963:                                nameFragmentEnd + 1, identCount, fragments);
0964:                        this .namePos++; // skip '<'
0965:                        TypeReference[] arguments = decodeTypeArguments(
0966:                                typeSignature, length, start, end); // positionned on '>' at end
0967:                        fragments.add(arguments);
0968:                        identCount = 1;
0969:                        nameStarted = false;
0970:                        // next increment will skip '>'
0971:                        break;
0972:                    }
0973:                    this .namePos++;
0974:                }
0975:                if (fragments == null) { // non parameterized 
0976:                    /* rebuild identifiers and dimensions */
0977:                    if (identCount == 1) { // simple type reference
0978:                        if (dim == 0) {
0979:                            char[] nameFragment = new char[nameFragmentEnd
0980:                                    - nameFragmentStart + 1];
0981:                            typeSignature.getChars(nameFragmentStart,
0982:                                    nameFragmentEnd + 1, nameFragment, 0);
0983:                            return new SingleTypeReference(nameFragment,
0984:                                    ((long) start << 32) + end);
0985:                        } else {
0986:                            char[] nameFragment = new char[nameFragmentEnd
0987:                                    - nameFragmentStart + 1];
0988:                            typeSignature.getChars(nameFragmentStart,
0989:                                    nameFragmentEnd + 1, nameFragment, 0);
0990:                            return new ArrayTypeReference(nameFragment, dim,
0991:                                    ((long) start << 32) + end);
0992:                        }
0993:                    } else { // qualified type reference
0994:                        long[] positions = new long[identCount];
0995:                        long pos = ((long) start << 32) + end;
0996:                        for (int i = 0; i < identCount; i++) {
0997:                            positions[i] = pos;
0998:                        }
0999:                        char[][] identifiers = extractIdentifiers(
1000:                                typeSignature, nameFragmentStart,
1001:                                nameFragmentEnd, identCount);
1002:                        if (dim == 0) {
1003:                            return new QualifiedTypeReference(identifiers,
1004:                                    positions);
1005:                        } else {
1006:                            return new ArrayQualifiedTypeReference(identifiers,
1007:                                    dim, positions);
1008:                        }
1009:                    }
1010:                } else { // parameterized
1011:                    // rebuild type reference from available fragments: char[][], arguments, char[][], arguments...
1012:                    // check trailing qualified name
1013:                    if (nameStarted) {
1014:                        addIdentifiers(typeSignature, nameFragmentStart,
1015:                                nameFragmentEnd + 1, identCount, fragments);
1016:                    }
1017:                    int fragmentLength = fragments.size();
1018:                    if (fragmentLength == 2) {
1019:                        Object firstFragment = fragments.get(0);
1020:                        if (firstFragment instanceof  char[]) {
1021:                            // parameterized single type
1022:                            return new ParameterizedSingleTypeReference(
1023:                                    (char[]) firstFragment,
1024:                                    (TypeReference[]) fragments.get(1), dim,
1025:                                    ((long) start << 32) + end);
1026:                        }
1027:                    }
1028:                    // parameterized qualified type
1029:                    identCount = 0;
1030:                    for (int i = 0; i < fragmentLength; i++) {
1031:                        Object element = fragments.get(i);
1032:                        if (element instanceof  char[][]) {
1033:                            identCount += ((char[][]) element).length;
1034:                        } else if (element instanceof  char[])
1035:                            identCount++;
1036:                    }
1037:                    char[][] tokens = new char[identCount][];
1038:                    TypeReference[][] arguments = new TypeReference[identCount][];
1039:                    int index = 0;
1040:                    for (int i = 0; i < fragmentLength; i++) {
1041:                        Object element = fragments.get(i);
1042:                        if (element instanceof  char[][]) {
1043:                            char[][] fragmentTokens = (char[][]) element;
1044:                            int fragmentTokenLength = fragmentTokens.length;
1045:                            System.arraycopy(fragmentTokens, 0, tokens, index,
1046:                                    fragmentTokenLength);
1047:                            index += fragmentTokenLength;
1048:                        } else if (element instanceof  char[]) {
1049:                            tokens[index++] = (char[]) element;
1050:                        } else {
1051:                            arguments[index - 1] = (TypeReference[]) element;
1052:                        }
1053:                    }
1054:                    long[] positions = new long[identCount];
1055:                    long pos = ((long) start << 32) + end;
1056:                    for (int i = 0; i < identCount; i++) {
1057:                        positions[i] = pos;
1058:                    }
1059:                    return new ParameterizedQualifiedTypeReference(tokens,
1060:                            arguments, dim, positions);
1061:                }
1062:            }
1063:
1064:            private TypeReference decodeType(char[] typeName, int length,
1065:                    int start, int end) {
1066:                int identCount = 1;
1067:                int dim = 0;
1068:                int nameFragmentStart = this .namePos, nameFragmentEnd = -1;
1069:                ArrayList fragments = null;
1070:                typeLoop: while (this .namePos < length) {
1071:                    char currentChar = typeName[this .namePos];
1072:                    switch (currentChar) {
1073:                    case '?':
1074:                        this .namePos++; // skip '?'
1075:                        while (typeName[this .namePos] == ' ')
1076:                            this .namePos++;
1077:                        switch (typeName[this .namePos]) {
1078:                        case 's':
1079:                            checkSuper: {
1080:                                int max = TypeConstants.WILDCARD_SUPER.length - 1;
1081:                                for (int ahead = 1; ahead < max; ahead++) {
1082:                                    if (typeName[this .namePos + ahead] != TypeConstants.WILDCARD_SUPER[ahead + 1]) {
1083:                                        break checkSuper;
1084:                                    }
1085:                                }
1086:                                this .namePos += max;
1087:                                Wildcard result = new Wildcard(Wildcard.SUPER);
1088:                                result.bound = decodeType(typeName, length,
1089:                                        start, end);
1090:                                result.sourceStart = start;
1091:                                result.sourceEnd = end;
1092:                                return result;
1093:                            }
1094:                            break;
1095:                        case 'e':
1096:                            checkExtends: {
1097:                                int max = TypeConstants.WILDCARD_EXTENDS.length - 1;
1098:                                for (int ahead = 1; ahead < max; ahead++) {
1099:                                    if (typeName[this .namePos + ahead] != TypeConstants.WILDCARD_EXTENDS[ahead + 1]) {
1100:                                        break checkExtends;
1101:                                    }
1102:                                }
1103:                                this .namePos += max;
1104:                                Wildcard result = new Wildcard(Wildcard.EXTENDS);
1105:                                result.bound = decodeType(typeName, length,
1106:                                        start, end);
1107:                                result.sourceStart = start;
1108:                                result.sourceEnd = end;
1109:                                return result;
1110:                            }
1111:                            break;
1112:                        }
1113:                        Wildcard result = new Wildcard(Wildcard.UNBOUND);
1114:                        result.sourceStart = start;
1115:                        result.sourceEnd = end;
1116:                        return result;
1117:                    case '[':
1118:                        if (dim == 0)
1119:                            nameFragmentEnd = this .namePos - 1;
1120:                        dim++;
1121:                        break;
1122:                    case ']':
1123:                        break;
1124:                    case '>':
1125:                    case ',':
1126:                        break typeLoop;
1127:                    case '.':
1128:                        if (nameFragmentStart < 0)
1129:                            nameFragmentStart = this .namePos + 1; // member type name
1130:                        identCount++;
1131:                        break;
1132:                    case '<':
1133:                        // convert 1.5 specific constructs only if compliance is 1.5 or above
1134:                        if (!this .has1_5Compliance)
1135:                            break typeLoop;
1136:                        if (fragments == null)
1137:                            fragments = new ArrayList(2);
1138:                        nameFragmentEnd = this .namePos - 1;
1139:                        char[][] identifiers = CharOperation.splitOn('.',
1140:                                typeName, nameFragmentStart, this .namePos);
1141:                        fragments.add(identifiers);
1142:                        this .namePos++; // skip '<'
1143:                        TypeReference[] arguments = decodeTypeArguments(
1144:                                typeName, length, start, end); // positionned on '>' at end
1145:                        fragments.add(arguments);
1146:                        identCount = 0;
1147:                        nameFragmentStart = -1;
1148:                        nameFragmentEnd = -1;
1149:                        // next increment will skip '>'
1150:                        break;
1151:                    }
1152:                    this .namePos++;
1153:                }
1154:                if (nameFragmentEnd < 0)
1155:                    nameFragmentEnd = this .namePos - 1;
1156:                if (fragments == null) { // non parameterized 
1157:                    /* rebuild identifiers and dimensions */
1158:                    if (identCount == 1) { // simple type reference
1159:                        if (dim == 0) {
1160:                            char[] nameFragment;
1161:                            if (nameFragmentStart != 0 || nameFragmentEnd >= 0) {
1162:                                int nameFragmentLength = nameFragmentEnd
1163:                                        - nameFragmentStart + 1;
1164:                                System
1165:                                        .arraycopy(
1166:                                                typeName,
1167:                                                nameFragmentStart,
1168:                                                nameFragment = new char[nameFragmentLength],
1169:                                                0, nameFragmentLength);
1170:                            } else {
1171:                                nameFragment = typeName;
1172:                            }
1173:                            return new SingleTypeReference(nameFragment,
1174:                                    ((long) start << 32) + end);
1175:                        } else {
1176:                            int nameFragmentLength = nameFragmentEnd
1177:                                    - nameFragmentStart + 1;
1178:                            char[] nameFragment = new char[nameFragmentLength];
1179:                            System.arraycopy(typeName, nameFragmentStart,
1180:                                    nameFragment, 0, nameFragmentLength);
1181:                            return new ArrayTypeReference(nameFragment, dim,
1182:                                    ((long) start << 32) + end);
1183:                        }
1184:                    } else { // qualified type reference
1185:                        long[] positions = new long[identCount];
1186:                        long pos = ((long) start << 32) + end;
1187:                        for (int i = 0; i < identCount; i++) {
1188:                            positions[i] = pos;
1189:                        }
1190:                        char[][] identifiers = CharOperation.splitOn('.',
1191:                                typeName, nameFragmentStart,
1192:                                nameFragmentEnd + 1);
1193:                        if (dim == 0) {
1194:                            return new QualifiedTypeReference(identifiers,
1195:                                    positions);
1196:                        } else {
1197:                            return new ArrayQualifiedTypeReference(identifiers,
1198:                                    dim, positions);
1199:                        }
1200:                    }
1201:                } else { // parameterized
1202:                    // rebuild type reference from available fragments: char[][], arguments, char[][], arguments...
1203:                    // check trailing qualified name
1204:                    if (nameFragmentStart > 0 && nameFragmentStart < length) {
1205:                        char[][] identifiers = CharOperation.splitOn('.',
1206:                                typeName, nameFragmentStart,
1207:                                nameFragmentEnd + 1);
1208:                        fragments.add(identifiers);
1209:                    }
1210:                    int fragmentLength = fragments.size();
1211:                    if (fragmentLength == 2) {
1212:                        char[][] firstFragment = (char[][]) fragments.get(0);
1213:                        if (firstFragment.length == 1) {
1214:                            // parameterized single type
1215:                            return new ParameterizedSingleTypeReference(
1216:                                    firstFragment[0],
1217:                                    (TypeReference[]) fragments.get(1), dim,
1218:                                    ((long) start << 32) + end);
1219:                        }
1220:                    }
1221:                    // parameterized qualified type
1222:                    identCount = 0;
1223:                    for (int i = 0; i < fragmentLength; i++) {
1224:                        Object element = fragments.get(i);
1225:                        if (element instanceof  char[][]) {
1226:                            identCount += ((char[][]) element).length;
1227:                        }
1228:                    }
1229:                    char[][] tokens = new char[identCount][];
1230:                    TypeReference[][] arguments = new TypeReference[identCount][];
1231:                    int index = 0;
1232:                    for (int i = 0; i < fragmentLength; i++) {
1233:                        Object element = fragments.get(i);
1234:                        if (element instanceof  char[][]) {
1235:                            char[][] fragmentTokens = (char[][]) element;
1236:                            int fragmentTokenLength = fragmentTokens.length;
1237:                            System.arraycopy(fragmentTokens, 0, tokens, index,
1238:                                    fragmentTokenLength);
1239:                            index += fragmentTokenLength;
1240:                        } else {
1241:                            arguments[index - 1] = (TypeReference[]) element;
1242:                        }
1243:                    }
1244:                    long[] positions = new long[identCount];
1245:                    long pos = ((long) start << 32) + end;
1246:                    for (int i = 0; i < identCount; i++) {
1247:                        positions[i] = pos;
1248:                    }
1249:                    return new ParameterizedQualifiedTypeReference(tokens,
1250:                            arguments, dim, positions);
1251:                }
1252:            }
1253:
1254:            private TypeReference[] decodeTypeArguments(char[] typeName,
1255:                    int length, int start, int end) {
1256:                ArrayList argumentList = new ArrayList(1);
1257:                int count = 0;
1258:                argumentsLoop: while (this .namePos < length) {
1259:                    TypeReference argument = decodeType(typeName, length,
1260:                            start, end);
1261:                    count++;
1262:                    argumentList.add(argument);
1263:                    if (this .namePos >= length)
1264:                        break argumentsLoop;
1265:                    if (typeName[this .namePos] == '>') {
1266:                        break argumentsLoop;
1267:                    }
1268:                    this .namePos++; // skip ','
1269:                }
1270:                TypeReference[] typeArguments = new TypeReference[count];
1271:                argumentList.toArray(typeArguments);
1272:                return typeArguments;
1273:            }
1274:
1275:            private TypeReference[] decodeTypeArguments(String typeSignature,
1276:                    int length, int start, int end) {
1277:                ArrayList argumentList = new ArrayList(1);
1278:                int count = 0;
1279:                argumentsLoop: while (this .namePos < length) {
1280:                    TypeReference argument = decodeType(typeSignature, length,
1281:                            start, end);
1282:                    count++;
1283:                    argumentList.add(argument);
1284:                    if (this .namePos >= length)
1285:                        break argumentsLoop;
1286:                    if (typeSignature.charAt(this .namePos) == '>') {
1287:                        break argumentsLoop;
1288:                    }
1289:                }
1290:                TypeReference[] typeArguments = new TypeReference[count];
1291:                argumentList.toArray(typeArguments);
1292:                return typeArguments;
1293:            }
1294:
1295:            private char[][] extractIdentifiers(String typeSignature,
1296:                    int start, int endInclusive, int identCount) {
1297:                char[][] result = new char[identCount][];
1298:                int charIndex = start;
1299:                int i = 0;
1300:                while (charIndex < endInclusive) {
1301:                    if (typeSignature.charAt(charIndex) == '.') {
1302:                        typeSignature.getChars(start, charIndex,
1303:                                result[i++] = new char[charIndex - start], 0);
1304:                        start = ++charIndex;
1305:                    } else
1306:                        charIndex++;
1307:                }
1308:                typeSignature.getChars(start, charIndex + 1,
1309:                        result[i++] = new char[charIndex - start + 1], 0);
1310:                return result;
1311:            }
1312:
1313:            private char[] getSource() {
1314:                if (this .source == null)
1315:                    this .source = this .cu.getContents();
1316:                return this .source;
1317:            }
1318:
1319:            private Expression parseMemberValue(char[] memberValue) {
1320:                // memberValue must not be null
1321:                if (this .parser == null) {
1322:                    this .parser = new Parser(this .problemReporter, true);
1323:                }
1324:                return this .parser.parseMemberValue(memberValue, 0,
1325:                        memberValue.length, this.unit);
1326:            }
1327:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.