Source Code Cross Referenced for CompilationUnitScope.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) 


001:        /*******************************************************************************
002:         * Copyright (c) 2000, 2007 IBM Corporation and others.
003:         * All rights reserved. This program and the accompanying materials
004:         * are made available under the terms of the Eclipse Public License v1.0
005:         * which accompanies this distribution, and is available at
006:         * http://www.eclipse.org/legal/epl-v10.html
007:         *
008:         * Contributors:
009:         *     IBM Corporation - initial API and implementation
010:         *     Erling Ellingsen -  patch for bug 125570
011:         *******************************************************************************/package org.eclipse.jdt.internal.compiler.lookup;
012:
013:        import org.eclipse.jdt.core.compiler.CharOperation;
014:        import org.eclipse.jdt.internal.compiler.ast.*;
015:        import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
016:        import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
017:        import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
018:        import org.eclipse.jdt.internal.compiler.util.*;
019:
020:        public class CompilationUnitScope extends Scope {
021:
022:            public LookupEnvironment environment;
023:            public CompilationUnitDeclaration referenceContext;
024:            public char[][] currentPackageName;
025:            public PackageBinding fPackage;
026:            public ImportBinding[] imports;
027:            public HashtableOfObject typeOrPackageCache; // used in Scope.getTypeOrPackage()
028:
029:            public SourceTypeBinding[] topLevelTypes;
030:
031:            private CompoundNameVector qualifiedReferences;
032:            private SimpleNameVector simpleNameReferences;
033:            private ObjectVector referencedTypes;
034:            private ObjectVector referencedSuperTypes;
035:
036:            HashtableOfType constantPoolNameUsage;
037:            private int captureID = 1;
038:
039:            public CompilationUnitScope(CompilationUnitDeclaration unit,
040:                    LookupEnvironment environment) {
041:                super (COMPILATION_UNIT_SCOPE, null);
042:                this .environment = environment;
043:                this .referenceContext = unit;
044:                unit.scope = this ;
045:                this .currentPackageName = unit.currentPackage == null ? CharOperation.NO_CHAR_CHAR
046:                        : unit.currentPackage.tokens;
047:
048:                if (compilerOptions().produceReferenceInfo) {
049:                    this .qualifiedReferences = new CompoundNameVector();
050:                    this .simpleNameReferences = new SimpleNameVector();
051:                    this .referencedTypes = new ObjectVector();
052:                    this .referencedSuperTypes = new ObjectVector();
053:                } else {
054:                    this .qualifiedReferences = null; // used to test if dependencies should be recorded
055:                    this .simpleNameReferences = null;
056:                    this .referencedTypes = null;
057:                    this .referencedSuperTypes = null;
058:                }
059:            }
060:
061:            void buildFieldsAndMethods() {
062:                for (int i = 0, length = topLevelTypes.length; i < length; i++)
063:                    topLevelTypes[i].scope.buildFieldsAndMethods();
064:            }
065:
066:            void buildTypeBindings(AccessRestriction accessRestriction) {
067:                topLevelTypes = new SourceTypeBinding[0]; // want it initialized if the package cannot be resolved
068:                boolean firstIsSynthetic = false;
069:                if (referenceContext.compilationResult.compilationUnit != null) {
070:                    char[][] expectedPackageName = referenceContext.compilationResult.compilationUnit
071:                            .getPackageName();
072:                    if (expectedPackageName != null
073:                            && !CharOperation.equals(currentPackageName,
074:                                    expectedPackageName)) {
075:
076:                        // only report if the unit isn't structurally empty
077:                        if (referenceContext.currentPackage != null
078:                                || referenceContext.types != null
079:                                || referenceContext.imports != null) {
080:                            problemReporter().packageIsNotExpectedPackage(
081:                                    referenceContext);
082:                        }
083:                        currentPackageName = expectedPackageName.length == 0 ? CharOperation.NO_CHAR_CHAR
084:                                : expectedPackageName;
085:                    }
086:                }
087:                if (currentPackageName == CharOperation.NO_CHAR_CHAR) {
088:                    if ((fPackage = environment.defaultPackage) == null) {
089:                        problemReporter().mustSpecifyPackage(referenceContext);
090:                        return;
091:                    }
092:                } else {
093:                    if ((fPackage = environment
094:                            .createPackage(currentPackageName)) == null) {
095:                        problemReporter().packageCollidesWithType(
096:                                referenceContext);
097:                        return;
098:                    } else if (referenceContext.isPackageInfo()) {
099:                        // resolve package annotations now if this is "package-info.java".				
100:                        if (referenceContext.types == null
101:                                || referenceContext.types.length == 0) {
102:                            referenceContext.types = new TypeDeclaration[1];
103:                            TypeDeclaration declaration = new TypeDeclaration(
104:                                    referenceContext.compilationResult);
105:                            referenceContext.types[0] = declaration;
106:                            declaration.name = TypeConstants.PACKAGE_INFO_NAME;
107:                            declaration.modifiers = ClassFileConstants.AccDefault
108:                                    | ClassFileConstants.AccInterface;
109:                            firstIsSynthetic = true;
110:                        }
111:                    }
112:                    recordQualifiedReference(currentPackageName); // always dependent on your own package
113:                }
114:
115:                // Skip typeDeclarations which know of previously reported errors
116:                TypeDeclaration[] types = referenceContext.types;
117:                int typeLength = (types == null) ? 0 : types.length;
118:                topLevelTypes = new SourceTypeBinding[typeLength];
119:                int count = 0;
120:                nextType: for (int i = 0; i < typeLength; i++) {
121:                    TypeDeclaration typeDecl = types[i];
122:                    ReferenceBinding typeBinding = fPackage
123:                            .getType0(typeDecl.name);
124:                    recordSimpleReference(typeDecl.name); // needed to detect collision cases
125:                    if (typeBinding != null
126:                            && typeBinding.isValidBinding()
127:                            && !(typeBinding instanceof  UnresolvedReferenceBinding)) {
128:                        // if a type exists, check that its a valid type
129:                        // it can be a NotFound problem type if its a secondary type referenced before its primary type found in additional units
130:                        // and it can be an unresolved type which is now being defined
131:                        problemReporter().duplicateTypes(referenceContext,
132:                                typeDecl);
133:                        continue nextType;
134:                    }
135:                    if (fPackage != environment.defaultPackage
136:                            && fPackage.getPackage(typeDecl.name) != null) {
137:                        // if a package exists, it must be a valid package - cannot be a NotFound problem package
138:                        // this is now a warning since a package does not really 'exist' until it contains a type, see JLS v2, 7.4.3
139:                        problemReporter().typeCollidesWithPackage(
140:                                referenceContext, typeDecl);
141:                    }
142:
143:                    if ((typeDecl.modifiers & ClassFileConstants.AccPublic) != 0) {
144:                        char[] mainTypeName;
145:                        if ((mainTypeName = referenceContext.getMainTypeName()) != null // mainTypeName == null means that implementor of ICompilationUnit decided to return null
146:                                && !CharOperation.equals(mainTypeName,
147:                                        typeDecl.name)) {
148:                            problemReporter().publicClassMustMatchFileName(
149:                                    referenceContext, typeDecl);
150:                            // tolerate faulty main type name (91091), allow to proceed into type construction
151:                        }
152:                    }
153:
154:                    ClassScope child = new ClassScope(this , typeDecl);
155:                    SourceTypeBinding type = child.buildType(null, fPackage,
156:                            accessRestriction);
157:                    if (firstIsSynthetic && i == 0)
158:                        type.modifiers |= ClassFileConstants.AccSynthetic;
159:                    if (type != null)
160:                        topLevelTypes[count++] = type;
161:                }
162:
163:                // shrink topLevelTypes... only happens if an error was reported
164:                if (count != topLevelTypes.length)
165:                    System.arraycopy(topLevelTypes, 0,
166:                            topLevelTypes = new SourceTypeBinding[count], 0,
167:                            count);
168:            }
169:
170:            void checkAndSetImports() {
171:                if (referenceContext.imports == null) {
172:                    imports = getDefaultImports();
173:                    return;
174:                }
175:
176:                // allocate the import array, add java.lang.* by default
177:                int numberOfStatements = referenceContext.imports.length;
178:                int numberOfImports = numberOfStatements + 1;
179:                for (int i = 0; i < numberOfStatements; i++) {
180:                    ImportReference importReference = referenceContext.imports[i];
181:                    if (((importReference.bits & ASTNode.OnDemand) != 0)
182:                            && CharOperation.equals(JAVA_LANG,
183:                                    importReference.tokens)
184:                            && !importReference.isStatic()) {
185:                        numberOfImports--;
186:                        break;
187:                    }
188:                }
189:                ImportBinding[] resolvedImports = new ImportBinding[numberOfImports];
190:                resolvedImports[0] = getDefaultImports()[0];
191:                int index = 1;
192:
193:                nextImport: for (int i = 0; i < numberOfStatements; i++) {
194:                    ImportReference importReference = referenceContext.imports[i];
195:                    char[][] compoundName = importReference.tokens;
196:
197:                    // skip duplicates or imports of the current package
198:                    for (int j = 0; j < index; j++) {
199:                        ImportBinding resolved = resolvedImports[j];
200:                        if (resolved.onDemand == ((importReference.bits & ASTNode.OnDemand) != 0)
201:                                && resolved.isStatic() == importReference
202:                                        .isStatic())
203:                            if (CharOperation.equals(compoundName,
204:                                    resolvedImports[j].compoundName))
205:                                continue nextImport;
206:                    }
207:
208:                    if ((importReference.bits & ASTNode.OnDemand) != 0) {
209:                        if (CharOperation.equals(compoundName,
210:                                currentPackageName))
211:                            continue nextImport;
212:
213:                        Binding importBinding = findImport(compoundName,
214:                                compoundName.length);
215:                        if (!importBinding.isValidBinding()
216:                                || (importReference.isStatic() && importBinding instanceof  PackageBinding))
217:                            continue nextImport; // we report all problems in faultInImports()
218:                        resolvedImports[index++] = new ImportBinding(
219:                                compoundName, true, importBinding,
220:                                importReference);
221:                    } else {
222:                        // resolve single imports only when the last name matches
223:                        resolvedImports[index++] = new ImportBinding(
224:                                compoundName, false, null, importReference);
225:                    }
226:                }
227:
228:                // shrink resolvedImports... only happens if an error was reported
229:                if (resolvedImports.length > index)
230:                    System.arraycopy(resolvedImports, 0,
231:                            resolvedImports = new ImportBinding[index], 0,
232:                            index);
233:                imports = resolvedImports;
234:            }
235:
236:            /**
237:             * Perform deferred check specific to parameterized types: bound checks, supertype collisions
238:             */
239:            void checkParameterizedTypes() {
240:                if (compilerOptions().sourceLevel < ClassFileConstants.JDK1_5)
241:                    return;
242:
243:                for (int i = 0, length = topLevelTypes.length; i < length; i++) {
244:                    ClassScope scope = topLevelTypes[i].scope;
245:                    scope.checkParameterizedTypeBounds();
246:                    scope.checkParameterizedSuperTypeCollisions();
247:                }
248:            }
249:
250:            /*
251:             * INTERNAL USE-ONLY
252:             * Innerclasses get their name computed as they are generated, since some may not
253:             * be actually outputed if sitting inside unreachable code.
254:             */
255:            public char[] computeConstantPoolName(LocalTypeBinding localType) {
256:                if (localType.constantPoolName() != null) {
257:                    return localType.constantPoolName();
258:                }
259:                // delegates to the outermost enclosing classfile, since it is the only one with a global vision of its innertypes.
260:
261:                if (constantPoolNameUsage == null)
262:                    constantPoolNameUsage = new HashtableOfType();
263:
264:                ReferenceBinding outerMostEnclosingType = localType.scope
265:                        .outerMostClassScope().enclosingSourceType();
266:
267:                // ensure there is not already such a local type name defined by the user
268:                int index = 0;
269:                char[] candidateName;
270:                boolean isCompliant15 = compilerOptions().complianceLevel >= ClassFileConstants.JDK1_5;
271:                while (true) {
272:                    if (localType.isMemberType()) {
273:                        if (index == 0) {
274:                            candidateName = CharOperation.concat(localType
275:                                    .enclosingType().constantPoolName(),
276:                                    localType.sourceName, '$');
277:                        } else {
278:                            // in case of collision, then member name gets extra $1 inserted
279:                            // e.g. class X { { class L{} new X(){ class L{} } } }
280:                            candidateName = CharOperation.concat(localType
281:                                    .enclosingType().constantPoolName(), '$',
282:                                    String.valueOf(index).toCharArray(), '$',
283:                                    localType.sourceName);
284:                        }
285:                    } else if (localType.isAnonymousType()) {
286:                        if (isCompliant15) {
287:                            // from 1.5 on, use immediately enclosing type name
288:                            candidateName = CharOperation.concat(
289:                                    localType.enclosingType.constantPoolName(),
290:                                    String.valueOf(index + 1).toCharArray(),
291:                                    '$');
292:                        } else {
293:                            candidateName = CharOperation.concat(
294:                                    outerMostEnclosingType.constantPoolName(),
295:                                    String.valueOf(index + 1).toCharArray(),
296:                                    '$');
297:                        }
298:                    } else {
299:                        // local type
300:                        if (isCompliant15) {
301:                            candidateName = CharOperation.concat(CharOperation
302:                                    .concat(localType.enclosingType()
303:                                            .constantPoolName(), String
304:                                            .valueOf(index + 1).toCharArray(),
305:                                            '$'), localType.sourceName);
306:                        } else {
307:                            candidateName = CharOperation.concat(
308:                                    outerMostEnclosingType.constantPoolName(),
309:                                    '$', String.valueOf(index + 1)
310:                                            .toCharArray(), '$',
311:                                    localType.sourceName);
312:                        }
313:                    }
314:                    if (constantPoolNameUsage.get(candidateName) != null) {
315:                        index++;
316:                    } else {
317:                        constantPoolNameUsage.put(candidateName, localType);
318:                        break;
319:                    }
320:                }
321:                return candidateName;
322:            }
323:
324:            void connectTypeHierarchy() {
325:                for (int i = 0, length = topLevelTypes.length; i < length; i++)
326:                    topLevelTypes[i].scope.connectTypeHierarchy();
327:            }
328:
329:            void faultInImports() {
330:                if (this .typeOrPackageCache != null)
331:                    return; // can be called when a field constant is resolved before static imports
332:                if (referenceContext.imports == null) {
333:                    this .typeOrPackageCache = new HashtableOfObject(1);
334:                    return;
335:                }
336:
337:                // collect the top level type names if a single type import exists
338:                int numberOfStatements = referenceContext.imports.length;
339:                HashtableOfType typesBySimpleNames = null;
340:                for (int i = 0; i < numberOfStatements; i++) {
341:                    if ((referenceContext.imports[i].bits & ASTNode.OnDemand) == 0) {
342:                        typesBySimpleNames = new HashtableOfType(
343:                                topLevelTypes.length + numberOfStatements);
344:                        for (int j = 0, length = topLevelTypes.length; j < length; j++)
345:                            typesBySimpleNames.put(topLevelTypes[j].sourceName,
346:                                    topLevelTypes[j]);
347:                        break;
348:                    }
349:                }
350:
351:                // allocate the import array, add java.lang.* by default
352:                int numberOfImports = numberOfStatements + 1;
353:                for (int i = 0; i < numberOfStatements; i++) {
354:                    ImportReference importReference = referenceContext.imports[i];
355:                    if (((importReference.bits & ASTNode.OnDemand) != 0)
356:                            && CharOperation.equals(JAVA_LANG,
357:                                    importReference.tokens)
358:                            && !importReference.isStatic()) {
359:                        numberOfImports--;
360:                        break;
361:                    }
362:                }
363:                ImportBinding[] resolvedImports = new ImportBinding[numberOfImports];
364:                resolvedImports[0] = getDefaultImports()[0];
365:                int index = 1;
366:
367:                // keep static imports with normal imports until there is a reason to split them up
368:                // on demand imports continue to be packages & types. need to check on demand type imports for fields/methods
369:                // single imports change from being just types to types or fields
370:                nextImport: for (int i = 0; i < numberOfStatements; i++) {
371:                    ImportReference importReference = referenceContext.imports[i];
372:                    char[][] compoundName = importReference.tokens;
373:
374:                    // skip duplicates or imports of the current package
375:                    for (int j = 0; j < index; j++) {
376:                        ImportBinding resolved = resolvedImports[j];
377:                        if (resolved.onDemand == ((importReference.bits & ASTNode.OnDemand) != 0)
378:                                && resolved.isStatic() == importReference
379:                                        .isStatic()) {
380:                            if (CharOperation.equals(compoundName,
381:                                    resolved.compoundName)) {
382:                                problemReporter().unusedImport(importReference); // since skipped, must be reported now
383:                                continue nextImport;
384:                            }
385:                        }
386:                    }
387:                    if ((importReference.bits & ASTNode.OnDemand) != 0) {
388:                        if (CharOperation.equals(compoundName,
389:                                currentPackageName)) {
390:                            problemReporter().unusedImport(importReference); // since skipped, must be reported now
391:                            continue nextImport;
392:                        }
393:
394:                        Binding importBinding = findImport(compoundName,
395:                                compoundName.length);
396:                        if (!importBinding.isValidBinding()) {
397:                            problemReporter().importProblem(importReference,
398:                                    importBinding);
399:                            continue nextImport;
400:                        }
401:                        if (importReference.isStatic()
402:                                && importBinding instanceof  PackageBinding) {
403:                            problemReporter().cannotImportPackage(
404:                                    importReference);
405:                            continue nextImport;
406:                        }
407:                        resolvedImports[index++] = new ImportBinding(
408:                                compoundName, true, importBinding,
409:                                importReference);
410:                    } else {
411:                        Binding importBinding = findSingleImport(compoundName,
412:                                importReference.isStatic());
413:                        if (!importBinding.isValidBinding()) {
414:                            problemReporter().importProblem(importReference,
415:                                    importBinding);
416:                            continue nextImport;
417:                        }
418:                        if (importBinding instanceof  PackageBinding) {
419:                            problemReporter().cannotImportPackage(
420:                                    importReference);
421:                            continue nextImport;
422:                        }
423:                        ReferenceBinding conflictingType = null;
424:                        if (importBinding instanceof  MethodBinding) {
425:                            conflictingType = (ReferenceBinding) getType(
426:                                    compoundName, compoundName.length);
427:                            if (!conflictingType.isValidBinding())
428:                                conflictingType = null;
429:                        }
430:                        // collisions between an imported static field & a type should be checked according to spec... but currently not by javac
431:                        if (importBinding instanceof  ReferenceBinding
432:                                || conflictingType != null) {
433:                            ReferenceBinding referenceBinding = conflictingType == null ? (ReferenceBinding) importBinding
434:                                    : conflictingType;
435:                            if (importReference.isTypeUseDeprecated(
436:                                    referenceBinding, this ))
437:                                problemReporter().deprecatedType(
438:                                        referenceBinding, importReference);
439:
440:                            ReferenceBinding existingType = typesBySimpleNames
441:                                    .get(compoundName[compoundName.length - 1]);
442:                            if (existingType != null) {
443:                                // duplicate test above should have caught this case, but make sure
444:                                if (existingType == referenceBinding)
445:                                    continue nextImport;
446:                                // either the type collides with a top level type or another imported type
447:                                for (int j = 0, length = topLevelTypes.length; j < length; j++) {
448:                                    if (CharOperation.equals(
449:                                            topLevelTypes[j].sourceName,
450:                                            existingType.sourceName)) {
451:                                        problemReporter().conflictingImport(
452:                                                importReference);
453:                                        continue nextImport;
454:                                    }
455:                                }
456:                                problemReporter().duplicateImport(
457:                                        importReference);
458:                                continue nextImport;
459:                            }
460:                            typesBySimpleNames.put(
461:                                    compoundName[compoundName.length - 1],
462:                                    referenceBinding);
463:                        } else if (importBinding instanceof  FieldBinding) {
464:                            for (int j = 0; j < index; j++) {
465:                                ImportBinding resolved = resolvedImports[j];
466:                                // find other static fields with the same name
467:                                if (resolved.isStatic()
468:                                        && resolved.resolvedImport instanceof  FieldBinding
469:                                        && importBinding != resolved.resolvedImport) {
470:                                    if (CharOperation
471:                                            .equals(
472:                                                    compoundName[compoundName.length - 1],
473:                                                    resolved.compoundName[resolved.compoundName.length - 1])) {
474:                                        problemReporter().duplicateImport(
475:                                                importReference);
476:                                        continue nextImport;
477:                                    }
478:                                }
479:                            }
480:                        }
481:                        resolvedImports[index++] = conflictingType == null ? new ImportBinding(
482:                                compoundName, false, importBinding,
483:                                importReference)
484:                                : new ImportConflictBinding(compoundName,
485:                                        importBinding, conflictingType,
486:                                        importReference);
487:                    }
488:                }
489:
490:                // shrink resolvedImports... only happens if an error was reported
491:                if (resolvedImports.length > index)
492:                    System.arraycopy(resolvedImports, 0,
493:                            resolvedImports = new ImportBinding[index], 0,
494:                            index);
495:                imports = resolvedImports;
496:
497:                int length = imports.length;
498:                this .typeOrPackageCache = new HashtableOfObject(length);
499:                for (int i = 0; i < length; i++) {
500:                    ImportBinding binding = imports[i];
501:                    if (!binding.onDemand
502:                            && binding.resolvedImport instanceof  ReferenceBinding
503:                            || binding instanceof  ImportConflictBinding)
504:                        this .typeOrPackageCache
505:                                .put(
506:                                        binding.compoundName[binding.compoundName.length - 1],
507:                                        binding);
508:                }
509:            }
510:
511:            public void faultInTypes() {
512:                faultInImports();
513:
514:                for (int i = 0, length = topLevelTypes.length; i < length; i++)
515:                    topLevelTypes[i].faultInTypesForFieldsAndMethods();
516:            }
517:
518:            // this API is for code assist purpose
519:            public Binding findImport(char[][] compoundName,
520:                    boolean findStaticImports, boolean onDemand) {
521:                if (onDemand) {
522:                    return findImport(compoundName, compoundName.length);
523:                } else {
524:                    return findSingleImport(compoundName, findStaticImports);
525:                }
526:            }
527:
528:            private Binding findImport(char[][] compoundName, int length) {
529:                recordQualifiedReference(compoundName);
530:
531:                Binding binding = environment
532:                        .getTopLevelPackage(compoundName[0]);
533:                int i = 1;
534:                foundNothingOrType: if (binding != null) {
535:                    PackageBinding packageBinding = (PackageBinding) binding;
536:                    while (i < length) {
537:                        binding = packageBinding
538:                                .getTypeOrPackage(compoundName[i++]);
539:                        if (binding == null || !binding.isValidBinding()) {
540:                            binding = null;
541:                            break foundNothingOrType;
542:                        }
543:                        if (!(binding instanceof  PackageBinding))
544:                            break foundNothingOrType;
545:
546:                        packageBinding = (PackageBinding) binding;
547:                    }
548:                    return packageBinding;
549:                }
550:
551:                ReferenceBinding type;
552:                if (binding == null) {
553:                    if (environment.defaultPackage == null
554:                            || compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4)
555:                        return new ProblemReferenceBinding(CharOperation
556:                                .subarray(compoundName, 0, i), null,
557:                                ProblemReasons.NotFound);
558:                    type = findType(compoundName[0],
559:                            environment.defaultPackage,
560:                            environment.defaultPackage);
561:                    if (type == null || !type.isValidBinding())
562:                        return new ProblemReferenceBinding(CharOperation
563:                                .subarray(compoundName, 0, i), null,
564:                                ProblemReasons.NotFound);
565:                    i = 1; // reset to look for member types inside the default package type
566:                } else {
567:                    type = (ReferenceBinding) binding;
568:                }
569:
570:                while (i < length) {
571:                    type = (ReferenceBinding) environment
572:                            .convertToRawType(type); // type imports are necessarily raw for all except last
573:                    if (!type.canBeSeenBy(fPackage))
574:                        return new ProblemReferenceBinding(CharOperation
575:                                .subarray(compoundName, 0, i), type,
576:                                ProblemReasons.NotVisible);
577:
578:                    char[] name = compoundName[i++];
579:                    // does not look for inherited member types on purpose, only immediate members
580:                    type = type.getMemberType(name);
581:                    if (type == null)
582:                        return new ProblemReferenceBinding(CharOperation
583:                                .subarray(compoundName, 0, i), null,
584:                                ProblemReasons.NotFound);
585:                }
586:                if (!type.canBeSeenBy(fPackage))
587:                    return new ProblemReferenceBinding(compoundName, type,
588:                            ProblemReasons.NotVisible);
589:                return type;
590:            }
591:
592:            private Binding findSingleImport(char[][] compoundName,
593:                    boolean findStaticImports) {
594:                if (compoundName.length == 1) {
595:                    // findType records the reference
596:                    // the name cannot be a package
597:                    if (environment.defaultPackage == null
598:                            || compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4)
599:                        return new ProblemReferenceBinding(compoundName, null,
600:                                ProblemReasons.NotFound);
601:                    ReferenceBinding typeBinding = findType(compoundName[0],
602:                            environment.defaultPackage, fPackage);
603:                    if (typeBinding == null)
604:                        return new ProblemReferenceBinding(compoundName, null,
605:                                ProblemReasons.NotFound);
606:                    return typeBinding;
607:                }
608:
609:                if (findStaticImports)
610:                    return findSingleStaticImport(compoundName);
611:                return findImport(compoundName, compoundName.length);
612:            }
613:
614:            private Binding findSingleStaticImport(char[][] compoundName) {
615:                Binding binding = findImport(compoundName,
616:                        compoundName.length - 1);
617:                if (!binding.isValidBinding())
618:                    return binding;
619:
620:                char[] name = compoundName[compoundName.length - 1];
621:                if (binding instanceof  PackageBinding) {
622:                    Binding temp = ((PackageBinding) binding)
623:                            .getTypeOrPackage(name);
624:                    if (temp != null && temp instanceof  ReferenceBinding) // must resolve to a member type or field, not a top level type
625:                        return new ProblemReferenceBinding(compoundName,
626:                                (ReferenceBinding) temp,
627:                                ProblemReasons.InvalidTypeForStaticImport);
628:                    return binding; // cannot be a package, error is caught in sender
629:                }
630:
631:                // look to see if its a static field first
632:                ReferenceBinding type = (ReferenceBinding) binding;
633:                FieldBinding field = findField(type, name, null, true);
634:                if (field != null && field.isValidBinding() && field.isStatic()
635:                        && field.canBeSeenBy(type, null, this ))
636:                    return field;
637:
638:                // look to see if there is a static method with the same selector
639:                MethodBinding method = findStaticMethod(type, name);
640:                if (method != null)
641:                    return method;
642:
643:                type = findMemberType(name, type);
644:                if (type == null || !type.isStatic()) {
645:                    if (field != null && !field.isValidBinding()
646:                            && field.problemId() != ProblemReasons.NotFound)
647:                        return field;
648:                    return new ProblemReferenceBinding(compoundName, type,
649:                            ProblemReasons.NotFound);
650:                }
651:                if (!type.canBeSeenBy(fPackage))
652:                    return new ProblemReferenceBinding(compoundName, type,
653:                            ProblemReasons.NotVisible);
654:                return type;
655:            }
656:
657:            MethodBinding findStaticMethod(ReferenceBinding currentType,
658:                    char[] selector) {
659:                if (!currentType.canBeSeenBy(this ))
660:                    return null;
661:
662:                do {
663:                    MethodBinding[] methods = currentType.getMethods(selector);
664:                    if (methods != Binding.NO_METHODS) {
665:                        for (int i = methods.length; --i >= 0;) {
666:                            MethodBinding method = methods[i];
667:                            if (method.isStatic()
668:                                    && method.canBeSeenBy(fPackage))
669:                                return method;
670:                        }
671:                    }
672:                    if (currentType.super Interfaces() == null) // needed for statically imported types which don't know their hierarchy yet
673:                        ((SourceTypeBinding) currentType).scope
674:                                .connectTypeHierarchy();
675:                } while ((currentType = currentType.super class()) != null);
676:                return null;
677:            }
678:
679:            ImportBinding[] getDefaultImports() {
680:                // initialize the default imports if necessary... share the default java.lang.* import
681:                if (environment.defaultImports != null)
682:                    return environment.defaultImports;
683:
684:                Binding importBinding = environment.getTopLevelPackage(JAVA);
685:                if (importBinding != null)
686:                    importBinding = ((PackageBinding) importBinding)
687:                            .getTypeOrPackage(JAVA_LANG[1]);
688:
689:                if (importBinding == null || !importBinding.isValidBinding()) {
690:                    // create a proxy for the missing BinaryType
691:                    BinaryTypeBinding missingObject = environment
692:                            .cacheMissingBinaryType(JAVA_LANG_OBJECT,
693:                                    this .referenceContext);
694:                    importBinding = missingObject.fPackage;
695:                }
696:
697:                return environment.defaultImports = new ImportBinding[] { new ImportBinding(
698:                        JAVA_LANG, true, importBinding, null) };
699:            }
700:
701:            // NOT Public API
702:            public final Binding getImport(char[][] compoundName,
703:                    boolean onDemand, boolean isStaticImport) {
704:                if (onDemand)
705:                    return findImport(compoundName, compoundName.length);
706:                return findSingleImport(compoundName, isStaticImport);
707:            }
708:
709:            public int nextCaptureID() {
710:                return this .captureID++;
711:            }
712:
713:            /* Answer the problem reporter to use for raising new problems.
714:             *
715:             * Note that as a side-effect, this updates the current reference context
716:             * (unit, type or method) in case the problem handler decides it is necessary
717:             * to abort.
718:             */
719:            public ProblemReporter problemReporter() {
720:                ProblemReporter problemReporter = referenceContext.problemReporter;
721:                problemReporter.referenceContext = referenceContext;
722:                return problemReporter;
723:            }
724:
725:            /*
726:             What do we hold onto:
727:
728:             1. when we resolve 'a.b.c', say we keep only 'a.b.c'
729:             & when we fail to resolve 'c' in 'a.b', lets keep 'a.b.c'
730:             THEN when we come across a new/changed/removed item named 'a.b.c',
731:             we would find all references to 'a.b.c'
732:             -> This approach fails because every type is resolved in every onDemand import to
733:             detect collision cases... so the references could be 10 times bigger than necessary.
734:
735:             2. when we resolve 'a.b.c', lets keep 'a.b' & 'c'
736:             & when we fail to resolve 'c' in 'a.b', lets keep 'a.b' & 'c'
737:             THEN when we come across a new/changed/removed item named 'a.b.c',
738:             we would find all references to 'a.b' & 'c'
739:             -> This approach does not have a space problem but fails to handle collision cases.
740:             What happens if a type is added named 'a.b'? We would search for 'a' & 'b' but
741:             would not find a match.
742:
743:             3. when we resolve 'a.b.c', lets keep 'a', 'a.b' & 'a', 'b', 'c'
744:             & when we fail to resolve 'c' in 'a.b', lets keep 'a', 'a.b' & 'a', 'b', 'c'
745:             THEN when we come across a new/changed/removed item named 'a.b.c',
746:             we would find all references to 'a.b' & 'c'
747:             OR 'a.b' -> 'a' & 'b'
748:             OR 'a' -> '' & 'a'
749:             -> As long as each single char[] is interned, we should not have a space problem
750:             and can handle collision cases.
751:
752:             4. when we resolve 'a.b.c', lets keep 'a.b' & 'a', 'b', 'c'
753:             & when we fail to resolve 'c' in 'a.b', lets keep 'a.b' & 'a', 'b', 'c'
754:             THEN when we come across a new/changed/removed item named 'a.b.c',
755:             we would find all references to 'a.b' & 'c'
756:             OR 'a.b' -> 'a' & 'b' in the simple name collection
757:             OR 'a' -> 'a' in the simple name collection
758:             -> As long as each single char[] is interned, we should not have a space problem
759:             and can handle collision cases.
760:             */
761:            void recordQualifiedReference(char[][] qualifiedName) {
762:                if (qualifiedReferences == null)
763:                    return; // not recording dependencies
764:
765:                int length = qualifiedName.length;
766:                if (length > 1) {
767:                    while (!qualifiedReferences.contains(qualifiedName)) {
768:                        qualifiedReferences.add(qualifiedName);
769:                        if (length == 2) {
770:                            recordSimpleReference(qualifiedName[0]);
771:                            recordSimpleReference(qualifiedName[1]);
772:                            return;
773:                        }
774:                        length--;
775:                        recordSimpleReference(qualifiedName[length]);
776:                        System.arraycopy(qualifiedName, 0,
777:                                qualifiedName = new char[length][], 0, length);
778:                    }
779:                } else if (length == 1) {
780:                    recordSimpleReference(qualifiedName[0]);
781:                }
782:            }
783:
784:            void recordReference(char[][] qualifiedEnclosingName,
785:                    char[] simpleName) {
786:                recordQualifiedReference(qualifiedEnclosingName);
787:                recordSimpleReference(simpleName);
788:            }
789:
790:            void recordReference(ReferenceBinding type, char[] simpleName) {
791:                ReferenceBinding actualType = typeToRecord(type);
792:                if (actualType != null)
793:                    recordReference(actualType.compoundName, simpleName);
794:            }
795:
796:            void recordSimpleReference(char[] simpleName) {
797:                if (simpleNameReferences == null)
798:                    return; // not recording dependencies
799:
800:                if (!simpleNameReferences.contains(simpleName))
801:                    simpleNameReferences.add(simpleName);
802:            }
803:
804:            void recordSuperTypeReference(TypeBinding type) {
805:                if (referencedSuperTypes == null)
806:                    return; // not recording dependencies
807:
808:                ReferenceBinding actualType = typeToRecord(type);
809:                if (actualType != null
810:                        && !referencedSuperTypes.containsIdentical(actualType))
811:                    referencedSuperTypes.add(actualType);
812:            }
813:
814:            public void recordTypeConversion(TypeBinding super Type,
815:                    TypeBinding subType) {
816:                recordSuperTypeReference(subType); // must record the hierarchy of the subType that is converted to the superType
817:            }
818:
819:            void recordTypeReference(TypeBinding type) {
820:                if (referencedTypes == null)
821:                    return; // not recording dependencies
822:
823:                ReferenceBinding actualType = typeToRecord(type);
824:                if (actualType != null
825:                        && !referencedTypes.containsIdentical(actualType))
826:                    referencedTypes.add(actualType);
827:            }
828:
829:            void recordTypeReferences(TypeBinding[] types) {
830:                if (referencedTypes == null)
831:                    return; // not recording dependencies
832:                if (types == null || types.length == 0)
833:                    return;
834:
835:                for (int i = 0, max = types.length; i < max; i++) {
836:                    // No need to record supertypes of method arguments & thrown exceptions, just the compoundName
837:                    // If a field/method is retrieved from such a type then a separate call does the job
838:                    ReferenceBinding actualType = typeToRecord(types[i]);
839:                    if (actualType != null
840:                            && !referencedTypes.containsIdentical(actualType))
841:                        referencedTypes.add(actualType);
842:                }
843:            }
844:
845:            Binding resolveSingleImport(ImportBinding importBinding) {
846:                if (importBinding.resolvedImport == null) {
847:                    importBinding.resolvedImport = findSingleImport(
848:                            importBinding.compoundName, importBinding
849:                                    .isStatic());
850:                    if (!importBinding.resolvedImport.isValidBinding()
851:                            || importBinding.resolvedImport instanceof  PackageBinding) {
852:                        if (this .imports != null) {
853:                            ImportBinding[] newImports = new ImportBinding[imports.length - 1];
854:                            for (int i = 0, n = 0, max = this .imports.length; i < max; i++)
855:                                if (this .imports[i] != importBinding)
856:                                    newImports[n++] = this .imports[i];
857:                            this .imports = newImports;
858:                        }
859:                        return null;
860:                    }
861:                }
862:                return importBinding.resolvedImport;
863:            }
864:
865:            public void storeDependencyInfo() {
866:                // add the type hierarchy of each referenced supertype
867:                // cannot do early since the hierarchy may not be fully resolved
868:                for (int i = 0; i < referencedSuperTypes.size; i++) { // grows as more types are added
869:                    ReferenceBinding type = (ReferenceBinding) referencedSuperTypes
870:                            .elementAt(i);
871:                    if (!referencedTypes.containsIdentical(type))
872:                        referencedTypes.add(type);
873:
874:                    if (!type.isLocalType()) {
875:                        ReferenceBinding enclosing = type.enclosingType();
876:                        if (enclosing != null)
877:                            recordSuperTypeReference(enclosing);
878:                    }
879:                    ReferenceBinding super class = type.super class();
880:                    if (super class != null)
881:                        recordSuperTypeReference(super class);
882:                    ReferenceBinding[] interfaces = type.super Interfaces();
883:                    if (interfaces != null)
884:                        for (int j = 0, length = interfaces.length; j < length; j++)
885:                            recordSuperTypeReference(interfaces[j]);
886:                }
887:
888:                for (int i = 0, l = referencedTypes.size; i < l; i++) {
889:                    ReferenceBinding type = (ReferenceBinding) referencedTypes
890:                            .elementAt(i);
891:                    if (!type.isLocalType())
892:                        recordQualifiedReference(type.isMemberType() ? CharOperation
893:                                .splitOn('.', type.readableName())
894:                                : type.compoundName);
895:                }
896:
897:                int size = qualifiedReferences.size;
898:                char[][][] qualifiedRefs = new char[size][][];
899:                for (int i = 0; i < size; i++)
900:                    qualifiedRefs[i] = qualifiedReferences.elementAt(i);
901:                referenceContext.compilationResult.qualifiedReferences = qualifiedRefs;
902:
903:                size = simpleNameReferences.size;
904:                char[][] simpleRefs = new char[size][];
905:                for (int i = 0; i < size; i++)
906:                    simpleRefs[i] = simpleNameReferences.elementAt(i);
907:                referenceContext.compilationResult.simpleNameReferences = simpleRefs;
908:            }
909:
910:            public String toString() {
911:                return "--- CompilationUnit Scope : " + new String(referenceContext.getFileName()); //$NON-NLS-1$
912:            }
913:
914:            private ReferenceBinding typeToRecord(TypeBinding type) {
915:                if (type.isArrayType())
916:                    type = ((ArrayBinding) type).leafComponentType;
917:
918:                switch (type.kind()) {
919:                case Binding.BASE_TYPE:
920:                case Binding.TYPE_PARAMETER:
921:                case Binding.WILDCARD_TYPE:
922:                    return null;
923:                case Binding.PARAMETERIZED_TYPE:
924:                case Binding.RAW_TYPE:
925:                    type = type.erasure();
926:                }
927:                ReferenceBinding refType = (ReferenceBinding) type;
928:                if (refType.isLocalType())
929:                    return null;
930:                return refType;
931:            }
932:
933:            public void verifyMethods(MethodVerifier verifier) {
934:                for (int i = 0, length = topLevelTypes.length; i < length; i++)
935:                    topLevelTypes[i].verifyMethods(verifier);
936:            }
937:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.