Source Code Cross Referenced for TypeReferenceLocator.java in  » IDE-Eclipse » jdt » org » eclipse » jdt » internal » core » search » matching » 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.core.search.matching 
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:         *******************************************************************************/package org.eclipse.jdt.internal.core.search.matching;
011:
012:        import org.eclipse.core.resources.IResource;
013:        import org.eclipse.core.runtime.*;
014:        import org.eclipse.jdt.core.*;
015:        import org.eclipse.jdt.core.compiler.CharOperation;
016:        import org.eclipse.jdt.core.search.*;
017:        import org.eclipse.jdt.internal.compiler.ast.*;
018:        import org.eclipse.jdt.internal.compiler.env.IBinaryType;
019:        import org.eclipse.jdt.internal.compiler.lookup.*;
020:        import org.eclipse.jdt.internal.compiler.util.SimpleSet;
021:        import org.eclipse.jdt.internal.core.JavaElement;
022:
023:        public class TypeReferenceLocator extends PatternLocator {
024:
025:            protected TypeReferencePattern pattern;
026:            protected boolean isDeclarationOfReferencedTypesPattern;
027:
028:            public TypeReferenceLocator(TypeReferencePattern pattern) {
029:
030:                super (pattern);
031:
032:                this .pattern = pattern;
033:                this .isDeclarationOfReferencedTypesPattern = this .pattern instanceof  DeclarationOfReferencedTypesPattern;
034:            }
035:
036:            protected IJavaElement findElement(IJavaElement element,
037:                    int accuracy) {
038:                // need exact match to be able to open on type ref
039:                if (accuracy != SearchMatch.A_ACCURATE)
040:                    return null;
041:
042:                // element that references the type must be included in the enclosing element
043:                DeclarationOfReferencedTypesPattern declPattern = (DeclarationOfReferencedTypesPattern) this .pattern;
044:                while (element != null
045:                        && !declPattern.enclosingElement.equals(element))
046:                    element = element.getParent();
047:                return element;
048:            }
049:
050:            public int match(Annotation node, MatchingNodeSet nodeSet) {
051:                return match(node.type, nodeSet);
052:            }
053:
054:            public int match(ASTNode node, MatchingNodeSet nodeSet) { // interested in ImportReference
055:                if (!(node instanceof  ImportReference))
056:                    return IMPOSSIBLE_MATCH;
057:
058:                return nodeSet.addMatch(node,
059:                        matchLevel((ImportReference) node));
060:            }
061:
062:            //public int match(ConstructorDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
063:            //public int match(Expression node, MatchingNodeSet nodeSet) - SKIP IT
064:            //public int match(FieldDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
065:            //public int match(MethodDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
066:            //public int match(MessageSend node, MatchingNodeSet nodeSet) - SKIP IT
067:            public int match(Reference node, MatchingNodeSet nodeSet) { // interested in NameReference & its subtypes
068:                if (!(node instanceof  NameReference))
069:                    return IMPOSSIBLE_MATCH;
070:
071:                if (this .pattern.simpleName == null)
072:                    return nodeSet
073:                            .addMatch(
074:                                    node,
075:                                    ((InternalSearchPattern) this .pattern).mustResolve ? POSSIBLE_MATCH
076:                                            : ACCURATE_MATCH);
077:
078:                if (node instanceof  SingleNameReference) {
079:                    if (matchesName(this .pattern.simpleName,
080:                            ((SingleNameReference) node).token))
081:                        return nodeSet.addMatch(node, POSSIBLE_MATCH); // resolution is needed to find out if it is a type ref 
082:                } else {
083:                    char[][] tokens = ((QualifiedNameReference) node).tokens;
084:                    for (int i = 0, max = tokens.length; i < max; i++)
085:                        if (matchesName(this .pattern.simpleName, tokens[i]))
086:                            return nodeSet.addMatch(node, POSSIBLE_MATCH); // resolution is needed to find out if it is a type ref
087:                }
088:
089:                return IMPOSSIBLE_MATCH;
090:            }
091:
092:            //public int match(TypeDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
093:            public int match(TypeReference node, MatchingNodeSet nodeSet) {
094:                if (this .pattern.simpleName == null)
095:                    return nodeSet
096:                            .addMatch(
097:                                    node,
098:                                    ((InternalSearchPattern) this .pattern).mustResolve ? POSSIBLE_MATCH
099:                                            : ACCURATE_MATCH);
100:
101:                if (node instanceof  SingleTypeReference) {
102:                    if (matchesName(this .pattern.simpleName,
103:                            ((SingleTypeReference) node).token))
104:                        return nodeSet
105:                                .addMatch(
106:                                        node,
107:                                        ((InternalSearchPattern) this .pattern).mustResolve ? POSSIBLE_MATCH
108:                                                : ACCURATE_MATCH);
109:                } else {
110:                    char[][] tokens = ((QualifiedTypeReference) node).tokens;
111:                    for (int i = 0, max = tokens.length; i < max; i++)
112:                        if (matchesName(this .pattern.simpleName, tokens[i]))
113:                            return nodeSet.addMatch(node, POSSIBLE_MATCH); // resolution is needed to find out if it is a type ref
114:                }
115:
116:                return IMPOSSIBLE_MATCH;
117:            }
118:
119:            protected int matchLevel(ImportReference importRef) {
120:                if (this .pattern.qualification == null) {
121:                    if (this .pattern.simpleName == null)
122:                        return ACCURATE_MATCH;
123:                    char[][] tokens = importRef.tokens;
124:                    if (matchesName(this .pattern.simpleName,
125:                            tokens[tokens.length - 1]))
126:                        return ACCURATE_MATCH;
127:                } else {
128:                    char[][] tokens = importRef.tokens;
129:                    char[] qualifiedPattern = this .pattern.simpleName == null ? this .pattern.qualification
130:                            : CharOperation.concat(this .pattern.qualification,
131:                                    this .pattern.simpleName, '.');
132:                    char[] qualifiedTypeName = CharOperation.concatWith(tokens,
133:                            '.');
134:                    if (qualifiedPattern == null)
135:                        return ACCURATE_MATCH; // null is as if it was "*"
136:                    if (qualifiedTypeName == null)
137:                        return IMPOSSIBLE_MATCH; // cannot match null name
138:                    if (qualifiedTypeName.length == 0) { // empty name
139:                        if (qualifiedPattern.length == 0) { // can only matches empty pattern
140:                            return ACCURATE_MATCH;
141:                        }
142:                        return IMPOSSIBLE_MATCH;
143:                    }
144:                    boolean matchFirstChar = !this .isCaseSensitive
145:                            || (qualifiedPattern[0] == qualifiedTypeName[0]);
146:                    if (this .isCamelCase) {
147:                        if (matchFirstChar
148:                                && CharOperation
149:                                        .camelCaseMatch(
150:                                                qualifiedPattern,
151:                                                qualifiedTypeName,
152:                                                (this .matchMode & SearchPattern.R_PREFIX_MATCH) != 0)) {
153:                            return POSSIBLE_MATCH;
154:                        }
155:                        if (this .isCaseSensitive)
156:                            return IMPOSSIBLE_MATCH;
157:                    }
158:                    switch (this .matchMode) {
159:                    case SearchPattern.R_EXACT_MATCH:
160:                    case SearchPattern.R_PREFIX_MATCH:
161:                        if (CharOperation.prefixEquals(qualifiedPattern,
162:                                qualifiedTypeName, this .isCaseSensitive)) {
163:                            return POSSIBLE_MATCH;
164:                        }
165:                        break;
166:
167:                    case SearchPattern.R_PATTERN_MATCH:
168:                        if (CharOperation.match(qualifiedPattern,
169:                                qualifiedTypeName, this .isCaseSensitive)) {
170:                            return POSSIBLE_MATCH;
171:                        }
172:                        break;
173:
174:                    case SearchPattern.R_REGEXP_MATCH:
175:                        // TODO (frederic) implement regular expression match
176:                        break;
177:                    }
178:                }
179:                return IMPOSSIBLE_MATCH;
180:            }
181:
182:            /* (non-Javadoc)
183:             * @see org.eclipse.jdt.internal.core.search.matching.PatternLocator#matchLevelAndReportImportRef(org.eclipse.jdt.internal.compiler.ast.ImportReference, org.eclipse.jdt.internal.compiler.lookup.Binding, org.eclipse.jdt.internal.core.search.matching.MatchLocator)
184:             */
185:            protected void matchLevelAndReportImportRef(
186:                    ImportReference importRef, Binding binding,
187:                    MatchLocator locator) throws CoreException {
188:                Binding refBinding = binding;
189:                if (importRef.isStatic()) {
190:                    // for static import, binding can be a field binding or a member type binding
191:                    // verify that in this case binding is static and use declaring class for fields
192:                    if (binding instanceof  FieldBinding) {
193:                        FieldBinding fieldBinding = (FieldBinding) binding;
194:                        if (!fieldBinding.isStatic())
195:                            return;
196:                        refBinding = fieldBinding.declaringClass;
197:                    } else if (binding instanceof  MethodBinding) {
198:                        MethodBinding methodBinding = (MethodBinding) binding;
199:                        if (!methodBinding.isStatic())
200:                            return;
201:                        refBinding = methodBinding.declaringClass;
202:                    } else if (binding instanceof  MemberTypeBinding) {
203:                        MemberTypeBinding memberBinding = (MemberTypeBinding) binding;
204:                        if (!memberBinding.isStatic())
205:                            return;
206:                    }
207:                    // resolve and report
208:                    int level = resolveLevel(refBinding);
209:                    if (level >= INACCURATE_MATCH) {
210:                        matchReportImportRef(
211:                                importRef,
212:                                binding,
213:                                locator.createImportHandle(importRef),
214:                                level == ACCURATE_MATCH ? SearchMatch.A_ACCURATE
215:                                        : SearchMatch.A_INACCURATE, locator);
216:                    }
217:                    return;
218:                }
219:                super .matchLevelAndReportImportRef(importRef, refBinding,
220:                        locator);
221:            }
222:
223:            protected void matchReportImportRef(ImportReference importRef,
224:                    Binding binding, IJavaElement element, int accuracy,
225:                    MatchLocator locator) throws CoreException {
226:                if (this .isDeclarationOfReferencedTypesPattern) {
227:                    if ((element = findElement(element, accuracy)) != null) {
228:                        SimpleSet knownTypes = ((DeclarationOfReferencedTypesPattern) this .pattern).knownTypes;
229:                        while (binding instanceof  ReferenceBinding) {
230:                            ReferenceBinding typeBinding = (ReferenceBinding) binding;
231:                            reportDeclaration(typeBinding, 1, locator,
232:                                    knownTypes);
233:                            binding = typeBinding.enclosingType();
234:                        }
235:                    }
236:                    return;
237:                }
238:
239:                // return if this is not necessary to report
240:                if (this .pattern.hasTypeArguments() && !this .isEquivalentMatch
241:                        && !this .isErasureMatch) {
242:                    return;
243:                }
244:
245:                // Create search match
246:                match = locator.newTypeReferenceMatch(element, binding,
247:                        accuracy, importRef);
248:
249:                // set match raw flag and rule
250:                match.setRaw(true);
251:                if (this .pattern.hasTypeArguments()) {
252:                    // binding is raw => only compatible erasure if pattern has type arguments
253:                    match.setRule(match.getRule()
254:                            & (~SearchPattern.R_FULL_MATCH));
255:                }
256:
257:                // Try to find best selection for match
258:                ReferenceBinding typeBinding = null;
259:                boolean lastButOne = false;
260:                if (binding instanceof  ReferenceBinding) {
261:                    typeBinding = (ReferenceBinding) binding;
262:                } else if (binding instanceof  FieldBinding) { // may happen for static import
263:                    typeBinding = ((FieldBinding) binding).declaringClass;
264:                    lastButOne = importRef.isStatic()
265:                            && ((importRef.bits & ASTNode.OnDemand) == 0);
266:                } else if (binding instanceof  MethodBinding) { // may happen for static import
267:                    typeBinding = ((MethodBinding) binding).declaringClass;
268:                    lastButOne = importRef.isStatic()
269:                            && ((importRef.bits & ASTNode.OnDemand) == 0);
270:                }
271:                if (typeBinding != null) {
272:                    int lastIndex = importRef.tokens.length - 1;
273:                    if (lastButOne) {
274:                        // for field or method static import, use last but one token
275:                        lastIndex--;
276:                    }
277:                    if (typeBinding instanceof  ProblemReferenceBinding) {
278:                        ProblemReferenceBinding pbBinding = (ProblemReferenceBinding) typeBinding;
279:                        typeBinding = pbBinding.closestMatch();
280:                        lastIndex = pbBinding.compoundName.length - 1;
281:                    }
282:                    // try to match all enclosing types for which the token matches as well.
283:                    while (typeBinding != null && lastIndex >= 0) {
284:                        if (resolveLevelForType(typeBinding) != IMPOSSIBLE_MATCH) {
285:                            if (locator.encloses(element)) {
286:                                long[] positions = importRef.sourcePositions;
287:                                // index now depends on pattern type signature
288:                                int index = lastIndex;
289:                                if (this .pattern.qualification != null) {
290:                                    index = lastIndex
291:                                            - this .pattern.segmentsSize;
292:                                }
293:                                if (index < 0)
294:                                    index = 0;
295:                                int start = (int) ((positions[index]) >>> 32);
296:                                int end = (int) positions[lastIndex];
297:                                // report match
298:                                match.setOffset(start);
299:                                match.setLength(end - start + 1);
300:                                locator.report(match);
301:                            }
302:                            return;
303:                        }
304:                        lastIndex--;
305:                        typeBinding = typeBinding.enclosingType();
306:                    }
307:                }
308:                locator.reportAccurateTypeReference(match, importRef,
309:                        this .pattern.simpleName);
310:            }
311:
312:            protected void matchReportReference(ArrayTypeReference arrayRef,
313:                    IJavaElement element, Binding elementBinding, int accuracy,
314:                    MatchLocator locator) throws CoreException {
315:                if (this .pattern.simpleName == null) {
316:                    // TODO (frederic) need to add a test for this case while searching generic types...
317:                    if (locator.encloses(element)) {
318:                        int offset = arrayRef.sourceStart;
319:                        int length = arrayRef.sourceEnd - offset + 1;
320:                        if (this .match == null) {
321:                            this .match = locator.newTypeReferenceMatch(element,
322:                                    elementBinding, accuracy, offset, length,
323:                                    arrayRef);
324:                        } else {
325:                            this .match.setOffset(offset);
326:                            this .match.setLength(length);
327:                        }
328:                        locator.report(match);
329:                        return;
330:                    }
331:                }
332:                match = locator.newTypeReferenceMatch(element, elementBinding,
333:                        accuracy, arrayRef);
334:                if (arrayRef.resolvedType != null) {
335:                    matchReportReference(arrayRef, -1, arrayRef.resolvedType
336:                            .leafComponentType(), locator);
337:                    return;
338:                }
339:                locator.reportAccurateTypeReference(match, arrayRef,
340:                        this .pattern.simpleName);
341:            }
342:
343:            /**
344:             * Reports the match of the given reference.
345:             */
346:            protected void matchReportReference(ASTNode reference,
347:                    IJavaElement element, Binding elementBinding, int accuracy,
348:                    MatchLocator locator) throws CoreException {
349:                matchReportReference(reference, element, null, null,
350:                        elementBinding, accuracy, locator);
351:            }
352:
353:            /**
354:             * Reports the match of the given reference. Also provide a local and other elements to eventually report in match.
355:             */
356:            protected void matchReportReference(ASTNode reference,
357:                    IJavaElement element, IJavaElement localElement,
358:                    IJavaElement[] otherElements, Binding elementBinding,
359:                    int accuracy, MatchLocator locator) throws CoreException {
360:                if (this .isDeclarationOfReferencedTypesPattern) {
361:                    if ((element = findElement(element, accuracy)) != null)
362:                        reportDeclaration(
363:                                reference,
364:                                element,
365:                                locator,
366:                                ((DeclarationOfReferencedTypesPattern) this .pattern).knownTypes);
367:                    return;
368:                }
369:
370:                // Create search match
371:                TypeReferenceMatch refMatch = locator.newTypeReferenceMatch(
372:                        element, elementBinding, accuracy, reference);
373:                refMatch.setLocalElement(localElement);
374:                refMatch.setOtherElements(otherElements);
375:                this .match = refMatch;
376:
377:                // Report match depending on reference type
378:                if (reference instanceof  QualifiedNameReference)
379:                    matchReportReference((QualifiedNameReference) reference,
380:                            element, elementBinding, accuracy, locator);
381:                else if (reference instanceof  QualifiedTypeReference)
382:                    matchReportReference((QualifiedTypeReference) reference,
383:                            element, elementBinding, accuracy, locator);
384:                else if (reference instanceof  ArrayTypeReference)
385:                    matchReportReference((ArrayTypeReference) reference,
386:                            element, elementBinding, accuracy, locator);
387:                else {
388:                    TypeBinding typeBinding = reference instanceof  Expression ? ((Expression) reference).resolvedType
389:                            : null;
390:                    if (typeBinding != null) {
391:                        matchReportReference((Expression) reference, -1,
392:                                typeBinding, locator);
393:                        return;
394:                    }
395:                    locator.report(match);
396:                }
397:            }
398:
399:            /**
400:             * Reports the match of the given reference. Also provide a scope to look for possible local and other elements.
401:             */
402:            protected void matchReportReference(ASTNode reference,
403:                    IJavaElement element, Binding elementBinding, Scope scope,
404:                    int accuracy, MatchLocator locator) throws CoreException {
405:                if (scope == null
406:                        || (scope.kind != Scope.BLOCK_SCOPE && scope.kind != Scope.METHOD_SCOPE)) {
407:                    matchReportReference(reference, element, elementBinding,
408:                            accuracy, locator);
409:                    return;
410:                }
411:
412:                // Look if some block scope local variable declarations include reference start position
413:                BlockScope blockScope = (BlockScope) scope;
414:                LocalDeclaration[] localDeclarations = blockScope
415:                        .findLocalVariableDeclarations(reference.sourceStart);
416:                IJavaElement localElement = null;
417:                IJavaElement[] otherElements = null;
418:
419:                // Some local variable declaration are matching
420:                if (localDeclarations != null) {
421:                    int length = localDeclarations.length;
422:
423:                    // Set local element to first matching local declaration
424:                    int idx = 0;
425:                    for (; idx < length; idx++) {
426:                        if (localDeclarations[idx] == null)
427:                            break;
428:                        if (reference.sourceStart == localDeclarations[idx].declarationSourceStart) {
429:                            localElement = locator.createHandle(
430:                                    localDeclarations[idx], element);
431:                            break;
432:                        }
433:                        if (idx > 0
434:                                && localDeclarations[idx].sourceStart > reference.sourceStart) {
435:                            localElement = locator.createHandle(
436:                                    localDeclarations[idx - 1], element);
437:                            break;
438:                        }
439:                    }
440:                    if (localElement == null && idx > 0) {
441:                        if (reference.sourceEnd < localDeclarations[idx - 1].declarationEnd) {
442:                            localElement = locator.createHandle(
443:                                    localDeclarations[idx - 1], element);
444:                        }
445:                    }
446:
447:                    // Store other local variable declarations in other elements
448:                    int size = 0;
449:                    for (int j = 1; j < length; j++) {
450:                        if (localDeclarations[j] == null)
451:                            break;
452:                        if (reference.sourceStart == localDeclarations[j].declarationSourceStart) {
453:                            if (otherElements == null) {
454:                                otherElements = new IJavaElement[length - j];
455:                            }
456:                            otherElements[size++] = locator.createHandle(
457:                                    localDeclarations[j], element);
458:                        }
459:                    }
460:                    if (size > 0 && size != (length - 1)) {
461:                        System
462:                                .arraycopy(otherElements, 0,
463:                                        otherElements = new IJavaElement[size],
464:                                        0, size);
465:                    }
466:                }
467:
468:                // Report match with local and other elements if any
469:                matchReportReference(reference, element, localElement,
470:                        otherElements, elementBinding, accuracy, locator);
471:            }
472:
473:            protected void matchReportReference(
474:                    QualifiedNameReference qNameRef, IJavaElement element,
475:                    Binding elementBinding, int accuracy, MatchLocator locator)
476:                    throws CoreException {
477:                Binding binding = qNameRef.binding;
478:                TypeBinding typeBinding = null;
479:                int lastIndex = qNameRef.tokens.length - 1;
480:                switch (qNameRef.bits & ASTNode.RestrictiveFlagMASK) {
481:                case Binding.FIELD: // reading a field
482:                    typeBinding = qNameRef.actualReceiverType;
483:                    lastIndex -= qNameRef.otherBindings == null ? 1
484:                            : qNameRef.otherBindings.length + 1;
485:                    break;
486:                case Binding.TYPE: //=============only type ==============
487:                    if (binding instanceof  TypeBinding)
488:                        typeBinding = (TypeBinding) binding;
489:                    break;
490:                case Binding.VARIABLE: //============unbound cases===========
491:                case Binding.TYPE | Binding.VARIABLE:
492:                    if (binding instanceof  ProblemReferenceBinding) {
493:                        typeBinding = (TypeBinding) binding;
494:                    } else if (binding instanceof  ProblemFieldBinding) {
495:                        typeBinding = qNameRef.actualReceiverType;
496:                        lastIndex -= qNameRef.otherBindings == null ? 1
497:                                : qNameRef.otherBindings.length + 1;
498:                    } else if (binding instanceof  ProblemBinding) {
499:                        typeBinding = ((ProblemBinding) binding).searchType;
500:                    }
501:                    break;
502:                }
503:                if (typeBinding instanceof  ProblemReferenceBinding) {
504:                    ProblemReferenceBinding pbBinding = (ProblemReferenceBinding) typeBinding;
505:                    typeBinding = pbBinding.closestMatch();
506:                    lastIndex = pbBinding.compoundName.length - 1;
507:                }
508:
509:                // Create search match to report
510:                if (this .match == null) {
511:                    this .match = locator.newTypeReferenceMatch(element,
512:                            elementBinding, accuracy, qNameRef);
513:                }
514:
515:                // try to match all enclosing types for which the token matches as well.
516:                if (typeBinding instanceof  ReferenceBinding) {
517:                    ReferenceBinding refBinding = (ReferenceBinding) typeBinding;
518:                    while (refBinding != null && lastIndex >= 0) {
519:                        if (resolveLevelForType(refBinding) == ACCURATE_MATCH) {
520:                            if (locator.encloses(element)) {
521:                                long[] positions = qNameRef.sourcePositions;
522:                                // index now depends on pattern type signature
523:                                int index = lastIndex;
524:                                if (this .pattern.qualification != null) {
525:                                    index = lastIndex
526:                                            - this .pattern.segmentsSize;
527:                                }
528:                                if (index < 0)
529:                                    index = 0;
530:                                int start = (int) ((positions[index]) >>> 32);
531:                                int end = (int) positions[lastIndex];
532:                                match.setOffset(start);
533:                                match.setLength(end - start + 1);
534:
535:                                //  Look if there's a need to special report for parameterized type
536:                                matchReportReference(qNameRef, lastIndex,
537:                                        refBinding, locator);
538:                            }
539:                            return;
540:                        }
541:                        lastIndex--;
542:                        refBinding = refBinding.enclosingType();
543:                    }
544:                }
545:                locator.reportAccurateTypeReference(match, qNameRef,
546:                        this .pattern.simpleName);
547:            }
548:
549:            protected void matchReportReference(
550:                    QualifiedTypeReference qTypeRef, IJavaElement element,
551:                    Binding elementBinding, int accuracy, MatchLocator locator)
552:                    throws CoreException {
553:                TypeBinding typeBinding = qTypeRef.resolvedType;
554:                int lastIndex = qTypeRef.tokens.length - 1;
555:                if (typeBinding instanceof  ArrayBinding)
556:                    typeBinding = ((ArrayBinding) typeBinding).leafComponentType;
557:                if (typeBinding instanceof  ProblemReferenceBinding) {
558:                    ProblemReferenceBinding pbBinding = (ProblemReferenceBinding) typeBinding;
559:                    typeBinding = pbBinding.closestMatch();
560:                    lastIndex = pbBinding.compoundName.length - 1;
561:                }
562:
563:                // Create search match to report
564:                if (this .match == null) {
565:                    this .match = locator.newTypeReferenceMatch(element,
566:                            elementBinding, accuracy, qTypeRef);
567:                }
568:
569:                // try to match all enclosing types for which the token matches as well
570:                if (typeBinding instanceof  ReferenceBinding) {
571:                    ReferenceBinding refBinding = (ReferenceBinding) typeBinding;
572:                    while (refBinding != null && lastIndex >= 0) {
573:                        if (resolveLevelForType(refBinding) != IMPOSSIBLE_MATCH) {
574:                            if (locator.encloses(element)) {
575:                                long[] positions = qTypeRef.sourcePositions;
576:                                // index now depends on pattern type signature
577:                                int index = lastIndex;
578:                                if (this .pattern.qualification != null) {
579:                                    index = lastIndex
580:                                            - this .pattern.segmentsSize;
581:                                }
582:                                if (index < 0)
583:                                    index = 0;
584:                                int start = (int) ((positions[index]) >>> 32);
585:                                int end = (int) positions[lastIndex];
586:                                match.setOffset(start);
587:                                match.setLength(end - start + 1);
588:
589:                                //  Look if there's a need to special report for parameterized type
590:                                matchReportReference(qTypeRef, lastIndex,
591:                                        refBinding, locator);
592:                            }
593:                            return;
594:                        }
595:                        lastIndex--;
596:                        refBinding = refBinding.enclosingType();
597:                    }
598:                }
599:                locator.reportAccurateTypeReference(match, qTypeRef,
600:                        this .pattern.simpleName);
601:            }
602:
603:            void matchReportReference(Expression expr, int lastIndex,
604:                    TypeBinding refBinding, MatchLocator locator)
605:                    throws CoreException {
606:
607:                // Look if there's a need to special report for parameterized type
608:                if (refBinding.isParameterizedType() || refBinding.isRawType()) {
609:
610:                    // Try to refine accuracy
611:                    ParameterizedTypeBinding parameterizedBinding = (ParameterizedTypeBinding) refBinding;
612:                    updateMatch(parameterizedBinding, this .pattern
613:                            .getTypeArguments(), this .pattern
614:                            .hasTypeParameters(), 0, locator);
615:
616:                    // See whether it is necessary to report or not
617:                    if (match.getRule() == 0)
618:                        return; // impossible match
619:                    boolean report = (this .isErasureMatch && match.isErasure())
620:                            || (this .isEquivalentMatch && match.isEquivalent())
621:                            || match.isExact();
622:                    if (!report)
623:                        return;
624:
625:                    // Make a special report for parameterized types if necessary
626:                    if (refBinding.isParameterizedType()
627:                            && this .pattern.hasTypeArguments()) {
628:                        TypeReference typeRef = null;
629:                        TypeReference[] typeArguments = null;
630:                        if (expr instanceof  ParameterizedQualifiedTypeReference) {
631:                            typeRef = (ParameterizedQualifiedTypeReference) expr;
632:                            typeArguments = ((ParameterizedQualifiedTypeReference) expr).typeArguments[lastIndex];
633:                        } else if (expr instanceof  ParameterizedSingleTypeReference) {
634:                            typeRef = (ParameterizedSingleTypeReference) expr;
635:                            typeArguments = ((ParameterizedSingleTypeReference) expr).typeArguments;
636:                        }
637:                        if (typeRef != null) {
638:                            locator.reportAccurateParameterizedTypeReference(
639:                                    match, typeRef, lastIndex, typeArguments);
640:                            return;
641:                        }
642:                    }
643:                } else if (this .pattern.hasTypeArguments()) { // binding has no type params, compatible erasure if pattern does
644:                    match.setRule(SearchPattern.R_ERASURE_MATCH);
645:                }
646:
647:                // Report match
648:                if (expr instanceof  ArrayTypeReference) {
649:                    locator.reportAccurateTypeReference(match, expr,
650:                            this .pattern.simpleName);
651:                    return;
652:                }
653:                if (refBinding.isLocalType()) {
654:                    // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=82673
655:                    LocalTypeBinding local = (LocalTypeBinding) refBinding;
656:                    IJavaElement focus = ((InternalSearchPattern) pattern).focus;
657:                    if (focus != null
658:                            && local.enclosingMethod != null
659:                            && focus.getParent().getElementType() == IJavaElement.METHOD) {
660:                        IMethod method = (IMethod) focus.getParent();
661:                        if (!CharOperation.equals(
662:                                local.enclosingMethod.selector, method
663:                                        .getElementName().toCharArray())) {
664:                            return;
665:                        }
666:                    }
667:                }
668:                locator.report(match);
669:            }
670:
671:            protected int referenceType() {
672:                return IJavaElement.TYPE;
673:            }
674:
675:            protected void reportDeclaration(ASTNode reference,
676:                    IJavaElement element, MatchLocator locator,
677:                    SimpleSet knownTypes) throws CoreException {
678:                int maxType = -1;
679:                TypeBinding typeBinding = null;
680:                if (reference instanceof  TypeReference) {
681:                    typeBinding = ((TypeReference) reference).resolvedType;
682:                    maxType = Integer.MAX_VALUE;
683:                } else if (reference instanceof  QualifiedNameReference) {
684:                    QualifiedNameReference qNameRef = (QualifiedNameReference) reference;
685:                    Binding binding = qNameRef.binding;
686:                    maxType = qNameRef.tokens.length - 1;
687:                    switch (qNameRef.bits & ASTNode.RestrictiveFlagMASK) {
688:                    case Binding.FIELD: // reading a field
689:                        typeBinding = qNameRef.actualReceiverType;
690:                        maxType -= qNameRef.otherBindings == null ? 1
691:                                : qNameRef.otherBindings.length + 1;
692:                        break;
693:                    case Binding.TYPE: //=============only type ==============
694:                        if (binding instanceof  TypeBinding)
695:                            typeBinding = (TypeBinding) binding;
696:                        break;
697:                    case Binding.VARIABLE: //============unbound cases===========
698:                    case Binding.TYPE | Binding.VARIABLE:
699:                        if (binding instanceof  ProblemFieldBinding) {
700:                            typeBinding = qNameRef.actualReceiverType;
701:                            maxType -= qNameRef.otherBindings == null ? 1
702:                                    : qNameRef.otherBindings.length + 1;
703:                        } else if (binding instanceof  ProblemBinding) {
704:                            ProblemBinding pbBinding = (ProblemBinding) binding;
705:                            typeBinding = pbBinding.searchType; // second chance with recorded type so far
706:                            char[] partialQualifiedName = pbBinding.name;
707:                            maxType = CharOperation.occurencesOf('.',
708:                                    partialQualifiedName) - 1; // index of last bound token is one before the pb token
709:                            if (typeBinding == null || maxType < 0)
710:                                return;
711:                        }
712:                        break;
713:                    }
714:                } else if (reference instanceof  SingleNameReference) {
715:                    typeBinding = (TypeBinding) ((SingleNameReference) reference).binding;
716:                    maxType = 1;
717:                }
718:
719:                if (typeBinding instanceof  ArrayBinding)
720:                    typeBinding = ((ArrayBinding) typeBinding).leafComponentType;
721:                if (typeBinding == null
722:                        || typeBinding instanceof  BaseTypeBinding)
723:                    return;
724:                if (typeBinding instanceof  ProblemReferenceBinding) {
725:                    ReferenceBinding original = ((ProblemReferenceBinding) typeBinding)
726:                            .closestMatch();
727:                    if (original == null)
728:                        return; // original may not be set (bug 71279)
729:                    typeBinding = original;
730:                }
731:                typeBinding = typeBinding.erasure();
732:                reportDeclaration((ReferenceBinding) typeBinding, maxType,
733:                        locator, knownTypes);
734:            }
735:
736:            protected void reportDeclaration(ReferenceBinding typeBinding,
737:                    int maxType, MatchLocator locator, SimpleSet knownTypes)
738:                    throws CoreException {
739:                IType type = locator.lookupType(typeBinding);
740:                if (type == null)
741:                    return; // case of a secondary type
742:
743:                IResource resource = type.getResource();
744:                boolean isBinary = type.isBinary();
745:                IBinaryType info = null;
746:                if (isBinary) {
747:                    if (resource == null)
748:                        resource = type.getJavaProject().getProject();
749:                    info = locator.getBinaryInfo(
750:                            (org.eclipse.jdt.internal.core.ClassFile) type
751:                                    .getClassFile(), resource);
752:                }
753:                while (maxType >= 0 && type != null) {
754:                    if (!knownTypes.includes(type)) {
755:                        if (isBinary) {
756:                            locator.reportBinaryMemberDeclaration(resource,
757:                                    type, typeBinding, info,
758:                                    SearchMatch.A_ACCURATE);
759:                        } else {
760:                            if (typeBinding instanceof  ParameterizedTypeBinding)
761:                                typeBinding = ((ParameterizedTypeBinding) typeBinding)
762:                                        .genericType();
763:                            ClassScope scope = ((SourceTypeBinding) typeBinding).scope;
764:                            if (scope != null) {
765:                                TypeDeclaration typeDecl = scope.referenceContext;
766:                                int offset = typeDecl.sourceStart;
767:                                match = new TypeDeclarationMatch(
768:                                        ((JavaElement) type)
769:                                                .resolved(typeBinding),
770:                                        SearchMatch.A_ACCURATE, offset,
771:                                        typeDecl.sourceEnd - offset + 1,
772:                                        locator.getParticipant(), resource);
773:                                locator.report(match);
774:                            }
775:                        }
776:                        knownTypes.add(type);
777:                    }
778:                    typeBinding = typeBinding.enclosingType();
779:                    IJavaElement parent = type.getParent();
780:                    if (parent instanceof  IType) {
781:                        type = (IType) parent;
782:                    } else {
783:                        type = null;
784:                    }
785:                    maxType--;
786:                }
787:            }
788:
789:            public int resolveLevel(ASTNode node) {
790:                if (node instanceof  TypeReference)
791:                    return resolveLevel((TypeReference) node);
792:                if (node instanceof  NameReference)
793:                    return resolveLevel((NameReference) node);
794:                //	if (node instanceof ImportReference) - Not called when resolve is true, see MatchingNodeSet.reportMatching(unit)
795:                return IMPOSSIBLE_MATCH;
796:            }
797:
798:            public int resolveLevel(Binding binding) {
799:                if (binding == null)
800:                    return INACCURATE_MATCH;
801:                if (!(binding instanceof  TypeBinding))
802:                    return IMPOSSIBLE_MATCH;
803:
804:                TypeBinding typeBinding = (TypeBinding) binding;
805:                if (typeBinding instanceof  ArrayBinding)
806:                    typeBinding = ((ArrayBinding) typeBinding).leafComponentType;
807:                if (typeBinding instanceof  ProblemReferenceBinding)
808:                    typeBinding = ((ProblemReferenceBinding) typeBinding)
809:                            .closestMatch();
810:
811:                if (((InternalSearchPattern) this .pattern).focus instanceof  IType
812:                        && typeBinding instanceof  ReferenceBinding) {
813:                    IPackageFragment pkg = ((IType) ((InternalSearchPattern) this .pattern).focus)
814:                            .getPackageFragment();
815:                    // check that type is located inside this instance of a package fragment
816:                    if (!PackageReferenceLocator.isDeclaringPackageFragment(
817:                            pkg, (ReferenceBinding) typeBinding))
818:                        return IMPOSSIBLE_MATCH;
819:                }
820:
821:                return resolveLevelForTypeOrEnclosingTypes(
822:                        this .pattern.simpleName, this .pattern.qualification,
823:                        typeBinding);
824:            }
825:
826:            protected int resolveLevel(NameReference nameRef) {
827:                Binding binding = nameRef.binding;
828:
829:                if (nameRef instanceof  SingleNameReference) {
830:                    if (binding instanceof  ProblemReferenceBinding)
831:                        binding = ((ProblemReferenceBinding) binding)
832:                                .closestMatch();
833:                    if (binding instanceof  ReferenceBinding)
834:                        return resolveLevelForType((ReferenceBinding) binding);
835:                    return binding == null || binding instanceof  ProblemBinding ? INACCURATE_MATCH
836:                            : IMPOSSIBLE_MATCH;
837:                }
838:
839:                TypeBinding typeBinding = null;
840:                QualifiedNameReference qNameRef = (QualifiedNameReference) nameRef;
841:                switch (qNameRef.bits & ASTNode.RestrictiveFlagMASK) {
842:                case Binding.FIELD: // reading a field
843:                    if (qNameRef.tokens.length < (qNameRef.otherBindings == null ? 2
844:                            : qNameRef.otherBindings.length + 2))
845:                        return IMPOSSIBLE_MATCH; // must be at least A.x
846:                    typeBinding = nameRef.actualReceiverType;
847:                    break;
848:                case Binding.LOCAL: // reading a local variable
849:                    return IMPOSSIBLE_MATCH; // no type match in it
850:                case Binding.TYPE: //=============only type ==============
851:                    if (binding instanceof  TypeBinding)
852:                        typeBinding = (TypeBinding) binding;
853:                    break;
854:                /*
855:                 * Handling of unbound qualified name references. The match may reside in the resolved fragment,
856:                 * which is recorded inside the problem binding, along with the portion of the name until it became a problem.
857:                 */
858:                case Binding.VARIABLE: //============unbound cases===========
859:                case Binding.TYPE | Binding.VARIABLE:
860:                    if (binding instanceof  ProblemReferenceBinding) {
861:                        typeBinding = (TypeBinding) binding;
862:                    } else if (binding instanceof  ProblemFieldBinding) {
863:                        if (qNameRef.tokens.length < (qNameRef.otherBindings == null ? 2
864:                                : qNameRef.otherBindings.length + 2))
865:                            return IMPOSSIBLE_MATCH; // must be at least A.x
866:                        typeBinding = nameRef.actualReceiverType;
867:                    } else if (binding instanceof  ProblemBinding) {
868:                        ProblemBinding pbBinding = (ProblemBinding) binding;
869:                        if (CharOperation.occurencesOf('.', pbBinding.name) <= 0) // index of last bound token is one before the pb token
870:                            return INACCURATE_MATCH;
871:                        typeBinding = pbBinding.searchType;
872:                    }
873:                    break;
874:                }
875:                return resolveLevel(typeBinding);
876:            }
877:
878:            protected int resolveLevel(TypeReference typeRef) {
879:                TypeBinding typeBinding = typeRef.resolvedType;
880:                if (typeBinding instanceof  ArrayBinding)
881:                    typeBinding = ((ArrayBinding) typeBinding).leafComponentType;
882:                if (typeBinding instanceof  ProblemReferenceBinding)
883:                    typeBinding = ((ProblemReferenceBinding) typeBinding)
884:                            .closestMatch();
885:
886:                if (typeRef instanceof  SingleTypeReference) {
887:                    return resolveLevelForType(typeBinding);
888:                } else
889:                    return resolveLevelForTypeOrEnclosingTypes(
890:                            this .pattern.simpleName,
891:                            this .pattern.qualification, typeBinding);
892:            }
893:
894:            /* (non-Javadoc)
895:             * Resolve level for type with a given binding.
896:             * This is just an helper to avoid call of method with all parameters...
897:             */
898:            protected int resolveLevelForType(TypeBinding typeBinding) {
899:                return resolveLevelForType(this .pattern.simpleName,
900:                        this .pattern.qualification, this .pattern
901:                                .getTypeArguments(), 0, typeBinding);
902:            }
903:
904:            /**
905:             * Returns whether the given type binding or one of its enclosing types
906:             * matches the given simple name pattern and qualification pattern.
907:             * Returns ACCURATE_MATCH if it does.
908:             * Returns INACCURATE_MATCH if resolve failed.
909:             * Returns IMPOSSIBLE_MATCH if it doesn't.
910:             */
911:            protected int resolveLevelForTypeOrEnclosingTypes(
912:                    char[] simpleNamePattern, char[] qualificationPattern,
913:                    TypeBinding binding) {
914:                if (binding == null)
915:                    return INACCURATE_MATCH;
916:
917:                if (binding instanceof  ReferenceBinding) {
918:                    ReferenceBinding type = (ReferenceBinding) binding;
919:                    while (type != null) {
920:                        int level = resolveLevelForType(type);
921:                        if (level != IMPOSSIBLE_MATCH)
922:                            return level;
923:
924:                        type = type.enclosingType();
925:                    }
926:                }
927:                return IMPOSSIBLE_MATCH;
928:            }
929:
930:            public String toString() {
931:                return "Locator for " + this .pattern.toString(); //$NON-NLS-1$
932:            }
933:        }
w_w__w_.j__a_v___a__2__s.___c__o__m__ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.