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


0001:        /*******************************************************************************
0002:         * Copyright (c) 2000, 2007 IBM Corporation and others.
0003:         * All rights reserved. This program and the accompanying materials
0004:         * are made available under the terms of the Eclipse Public License v1.0
0005:         * which accompanies this distribution, and is available at
0006:         * http://www.eclipse.org/legal/epl-v10.html
0007:         *
0008:         * Contributors:
0009:         *     IBM Corporation - initial API and implementation
0010:         *******************************************************************************/package org.eclipse.jdt.internal.core.search.matching;
0011:
0012:        import org.eclipse.core.runtime.*;
0013:        import org.eclipse.jdt.core.*;
0014:        import org.eclipse.jdt.core.compiler.*;
0015:        import org.eclipse.jdt.core.search.*;
0016:        import org.eclipse.jdt.internal.compiler.ast.*;
0017:        import org.eclipse.jdt.internal.compiler.lookup.*;
0018:        import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
0019:
0020:        public abstract class PatternLocator implements  IIndexConstants {
0021:
0022:            // store pattern info
0023:            protected int matchMode;
0024:            protected boolean isCaseSensitive;
0025:            protected boolean isCamelCase;
0026:            protected boolean isEquivalentMatch;
0027:            protected boolean isErasureMatch;
0028:            protected boolean mustResolve;
0029:            protected boolean mayBeGeneric;
0030:
0031:            // match to report
0032:            SearchMatch match = null;
0033:
0034:            /* match levels */
0035:            public static final int IMPOSSIBLE_MATCH = 0;
0036:            public static final int INACCURATE_MATCH = 1;
0037:            public static final int POSSIBLE_MATCH = 2;
0038:            public static final int ACCURATE_MATCH = 3;
0039:            public static final int ERASURE_MATCH = 4;
0040:
0041:            // Possible rule match flavors
0042:            // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=79866
0043:            public static final int EXACT_FLAVOR = 0x0010;
0044:            public static final int PREFIX_FLAVOR = 0x0020;
0045:            public static final int PATTERN_FLAVOR = 0x0040;
0046:            public static final int REGEXP_FLAVOR = 0x0080;
0047:            public static final int CAMELCASE_FLAVOR = 0x0100;
0048:            public static final int SUPER_INVOCATION_FLAVOR = 0x0200;
0049:            public static final int SUB_INVOCATION_FLAVOR = 0x0400;
0050:            public static final int OVERRIDDEN_METHOD_FLAVOR = 0x0800;
0051:            public static final int MATCH_LEVEL_MASK = 0x0F;
0052:            public static final int FLAVORS_MASK = ~MATCH_LEVEL_MASK;
0053:
0054:            /* match container */
0055:            public static final int COMPILATION_UNIT_CONTAINER = 1;
0056:            public static final int CLASS_CONTAINER = 2;
0057:            public static final int METHOD_CONTAINER = 4;
0058:            public static final int FIELD_CONTAINER = 8;
0059:            public static final int ALL_CONTAINER = COMPILATION_UNIT_CONTAINER
0060:                    | CLASS_CONTAINER | METHOD_CONTAINER | FIELD_CONTAINER;
0061:
0062:            /* match rule */
0063:            public static final int RAW_MASK = SearchPattern.R_EQUIVALENT_MATCH
0064:                    | SearchPattern.R_ERASURE_MATCH;
0065:            public static final int RULE_MASK = RAW_MASK; // no other values for the while...
0066:
0067:            public static PatternLocator patternLocator(SearchPattern pattern) {
0068:                switch (((InternalSearchPattern) pattern).kind) {
0069:                case IIndexConstants.PKG_REF_PATTERN:
0070:                    return new PackageReferenceLocator(
0071:                            (PackageReferencePattern) pattern);
0072:                case IIndexConstants.PKG_DECL_PATTERN:
0073:                    return new PackageDeclarationLocator(
0074:                            (PackageDeclarationPattern) pattern);
0075:                case IIndexConstants.TYPE_REF_PATTERN:
0076:                    return new TypeReferenceLocator(
0077:                            (TypeReferencePattern) pattern);
0078:                case IIndexConstants.TYPE_DECL_PATTERN:
0079:                    return new TypeDeclarationLocator(
0080:                            (TypeDeclarationPattern) pattern);
0081:                case IIndexConstants.SUPER_REF_PATTERN:
0082:                    return new SuperTypeReferenceLocator(
0083:                            (SuperTypeReferencePattern) pattern);
0084:                case IIndexConstants.CONSTRUCTOR_PATTERN:
0085:                    return new ConstructorLocator((ConstructorPattern) pattern);
0086:                case IIndexConstants.FIELD_PATTERN:
0087:                    return new FieldLocator((FieldPattern) pattern);
0088:                case IIndexConstants.METHOD_PATTERN:
0089:                    return new MethodLocator((MethodPattern) pattern);
0090:                case IIndexConstants.OR_PATTERN:
0091:                    return new OrLocator((OrPattern) pattern);
0092:                case IIndexConstants.AND_PATTERN:
0093:                    return new AndLocator((AndPattern) pattern);
0094:                case IIndexConstants.LOCAL_VAR_PATTERN:
0095:                    return new LocalVariableLocator(
0096:                            (LocalVariablePattern) pattern);
0097:                case IIndexConstants.TYPE_PARAM_PATTERN:
0098:                    return new TypeParameterLocator(
0099:                            (TypeParameterPattern) pattern);
0100:                }
0101:                return null;
0102:            }
0103:
0104:            public static char[] qualifiedPattern(char[] simpleNamePattern,
0105:                    char[] qualificationPattern) {
0106:                // NOTE: if case insensitive search then simpleNamePattern & qualificationPattern are assumed to be lowercase
0107:                if (simpleNamePattern == null) {
0108:                    if (qualificationPattern == null)
0109:                        return null;
0110:                    return CharOperation.concat(qualificationPattern, ONE_STAR,
0111:                            '.');
0112:                } else {
0113:                    return qualificationPattern == null ? CharOperation.concat(
0114:                            ONE_STAR, simpleNamePattern) : CharOperation
0115:                            .concat(qualificationPattern, simpleNamePattern,
0116:                                    '.');
0117:                }
0118:            }
0119:
0120:            public static char[] qualifiedSourceName(TypeBinding binding) {
0121:                if (binding instanceof  ReferenceBinding) {
0122:                    ReferenceBinding type = (ReferenceBinding) binding;
0123:                    if (type.isLocalType())
0124:                        return type.isMemberType() ? CharOperation.concat(
0125:                                qualifiedSourceName(type.enclosingType()), type
0126:                                        .sourceName(), '.') : CharOperation
0127:                                .concat(qualifiedSourceName(type
0128:                                        .enclosingType()), new char[] { '.',
0129:                                        '1', '.' }, type.sourceName());
0130:                }
0131:                return binding != null ? binding.qualifiedSourceName() : null;
0132:            }
0133:
0134:            public PatternLocator(SearchPattern pattern) {
0135:                int matchRule = pattern.getMatchRule();
0136:                this .isCaseSensitive = (matchRule & SearchPattern.R_CASE_SENSITIVE) != 0;
0137:                this .isCamelCase = (matchRule & SearchPattern.R_CAMEL_CASE_MATCH) != 0;
0138:                this .isErasureMatch = (matchRule & SearchPattern.R_ERASURE_MATCH) != 0;
0139:                this .isEquivalentMatch = (matchRule & SearchPattern.R_EQUIVALENT_MATCH) != 0;
0140:                this .matchMode = matchRule & JavaSearchPattern.MATCH_MODE_MASK;
0141:                this .mustResolve = ((InternalSearchPattern) pattern).mustResolve;
0142:            }
0143:
0144:            /*
0145:             * Clear caches
0146:             */
0147:            protected void clear() {
0148:                // nothing to clear by default
0149:            }
0150:
0151:            /* (non-Javadoc)
0152:             * Modify PatternLocator.qualifiedPattern behavior:
0153:             * do not add star before simple name pattern when qualification pattern is null.
0154:             * This avoid to match p.X when pattern is only X...
0155:             */
0156:            protected char[] getQualifiedPattern(char[] simpleNamePattern,
0157:                    char[] qualificationPattern) {
0158:                // NOTE: if case insensitive search then simpleNamePattern & qualificationPattern are assumed to be lowercase
0159:                if (simpleNamePattern == null) {
0160:                    if (qualificationPattern == null)
0161:                        return null;
0162:                    return CharOperation.concat(qualificationPattern, ONE_STAR,
0163:                            '.');
0164:                } else if (qualificationPattern == null) {
0165:                    return simpleNamePattern;
0166:                } else {
0167:                    return CharOperation.concat(qualificationPattern,
0168:                            simpleNamePattern, '.');
0169:                }
0170:            }
0171:
0172:            /* (non-Javadoc)
0173:             * Modify PatternLocator.qualifiedSourceName behavior:
0174:             * also concatene enclosing type name when type is a only a member type.
0175:             */
0176:            protected char[] getQualifiedSourceName(TypeBinding binding) {
0177:                TypeBinding type = binding instanceof  ArrayBinding ? ((ArrayBinding) binding).leafComponentType
0178:                        : binding;
0179:                if (type instanceof  ReferenceBinding) {
0180:                    if (type.isLocalType()) {
0181:                        return CharOperation.concat(qualifiedSourceName(type
0182:                                .enclosingType()),
0183:                                new char[] { '.', '1', '.' }, binding
0184:                                        .sourceName());
0185:                    } else if (type.isMemberType()) {
0186:                        return CharOperation.concat(qualifiedSourceName(type
0187:                                .enclosingType()), binding.sourceName(), '.');
0188:                    }
0189:                }
0190:                return binding != null ? binding.qualifiedSourceName() : null;
0191:            }
0192:
0193:            /*
0194:             * Get binding of type argument from a class unit scope and its index position.
0195:             * Cache is lazy initialized and if no binding is found, then store a problem binding
0196:             * to avoid making research twice...
0197:             */
0198:            protected TypeBinding getTypeNameBinding(int index) {
0199:                return null;
0200:            }
0201:
0202:            /**
0203:             * Initializes this search pattern so that polymorphic search can be performed.
0204:             */
0205:            public void initializePolymorphicSearch(MatchLocator locator) {
0206:                // default is to do nothing
0207:            }
0208:
0209:            public int match(Annotation node, MatchingNodeSet nodeSet) {
0210:                // each subtype should override if needed
0211:                return IMPOSSIBLE_MATCH;
0212:            }
0213:
0214:            /**
0215:             * Check if the given ast node syntactically matches this pattern.
0216:             * If it does, add it to the match set.
0217:             * Returns the match level.
0218:             */
0219:            public int match(ASTNode node, MatchingNodeSet nodeSet) { // needed for some generic nodes
0220:                // each subtype should override if needed
0221:                return IMPOSSIBLE_MATCH;
0222:            }
0223:
0224:            public int match(ConstructorDeclaration node,
0225:                    MatchingNodeSet nodeSet) {
0226:                // each subtype should override if needed
0227:                return IMPOSSIBLE_MATCH;
0228:            }
0229:
0230:            public int match(Expression node, MatchingNodeSet nodeSet) {
0231:                // each subtype should override if needed
0232:                return IMPOSSIBLE_MATCH;
0233:            }
0234:
0235:            public int match(FieldDeclaration node, MatchingNodeSet nodeSet) {
0236:                // each subtype should override if needed
0237:                return IMPOSSIBLE_MATCH;
0238:            }
0239:
0240:            public int match(LocalDeclaration node, MatchingNodeSet nodeSet) {
0241:                // each subtype should override if needed
0242:                return IMPOSSIBLE_MATCH;
0243:            }
0244:
0245:            public int match(MethodDeclaration node, MatchingNodeSet nodeSet) {
0246:                // each subtype should override if needed
0247:                return IMPOSSIBLE_MATCH;
0248:            }
0249:
0250:            public int match(MemberValuePair node, MatchingNodeSet nodeSet) {
0251:                // each subtype should override if needed
0252:                return IMPOSSIBLE_MATCH;
0253:            }
0254:
0255:            public int match(MessageSend node, MatchingNodeSet nodeSet) {
0256:                // each subtype should override if needed
0257:                return IMPOSSIBLE_MATCH;
0258:            }
0259:
0260:            public int match(Reference node, MatchingNodeSet nodeSet) {
0261:                // each subtype should override if needed
0262:                return IMPOSSIBLE_MATCH;
0263:            }
0264:
0265:            public int match(TypeDeclaration node, MatchingNodeSet nodeSet) {
0266:                // each subtype should override if needed
0267:                return IMPOSSIBLE_MATCH;
0268:            }
0269:
0270:            public int match(TypeParameter node, MatchingNodeSet nodeSet) {
0271:                // each subtype should override if needed
0272:                return IMPOSSIBLE_MATCH;
0273:            }
0274:
0275:            public int match(TypeReference node, MatchingNodeSet nodeSet) {
0276:                // each subtype should override if needed
0277:                return IMPOSSIBLE_MATCH;
0278:            }
0279:
0280:            /**
0281:             * Returns the type(s) of container for this pattern.
0282:             * It is a bit combination of types, denoting compilation unit, class declarations, field declarations or method declarations.
0283:             */
0284:            protected int matchContainer() {
0285:                // override if the pattern can be more specific
0286:                return ALL_CONTAINER;
0287:            }
0288:
0289:            /**
0290:             * Returns whether the given name matches the given pattern.
0291:             */
0292:            protected boolean matchesName(char[] pattern, char[] name) {
0293:                if (pattern == null)
0294:                    return true; // null is as if it was "*"
0295:                if (name == null)
0296:                    return false; // cannot match null name
0297:                return matchNameValue(pattern, name) != IMPOSSIBLE_MATCH;
0298:            }
0299:
0300:            /**
0301:             * Return how the given name matches the given pattern.
0302:             * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=79866"
0303:             * 
0304:             * @param pattern
0305:             * @param name
0306:             * @return Possible values are:
0307:             * <ul>
0308:             * 	<li> {@link #ACCURATE_MATCH}</li>
0309:             * 	<li> {@link #IMPOSSIBLE_MATCH}</li>
0310:             * 	<li> {@link #POSSIBLE_MATCH} which may be flavored with following values:
0311:             * 		<ul>
0312:             * 		<li>{@link #EXACT_FLAVOR}: Given name is equals to pattern</li>
0313:             * 		<li>{@link #PREFIX_FLAVOR}: Given name prefix equals to pattern</li>
0314:             * 		<li>{@link #CAMELCASE_FLAVOR}: Given name matches pattern as Camel Case</li>
0315:             * 		<li>{@link #PATTERN_FLAVOR}: Given name matches pattern as Pattern (ie. using '*' and '?' characters)</li>
0316:             * 		</ul>
0317:             * 	</li>
0318:             * </ul>
0319:             */
0320:            protected int matchNameValue(char[] pattern, char[] name) {
0321:                if (pattern == null)
0322:                    return ACCURATE_MATCH; // null is as if it was "*"
0323:                if (name == null)
0324:                    return IMPOSSIBLE_MATCH; // cannot match null name
0325:                if (name.length == 0) { // empty name
0326:                    if (pattern.length == 0) { // can only matches empty pattern
0327:                        return ACCURATE_MATCH;
0328:                    }
0329:                    return IMPOSSIBLE_MATCH;
0330:                } else if (pattern.length == 0) {
0331:                    return IMPOSSIBLE_MATCH; // need to have both name and pattern length==0 to be accurate
0332:                }
0333:                boolean matchFirstChar = !this .isCaseSensitive
0334:                        || pattern[0] == name[0];
0335:                boolean sameLength = pattern.length == name.length;
0336:                boolean canBePrefix = name.length >= pattern.length;
0337:                if (this .isCamelCase) {
0338:                    if (matchFirstChar
0339:                            && CharOperation
0340:                                    .camelCaseMatch(
0341:                                            pattern,
0342:                                            name,
0343:                                            (this .matchMode & SearchPattern.R_PREFIX_MATCH) != 0)) {
0344:                        return POSSIBLE_MATCH;
0345:                    }
0346:                    if (this .isCaseSensitive)
0347:                        return IMPOSSIBLE_MATCH;
0348:                }
0349:                switch (this .matchMode) {
0350:                case SearchPattern.R_EXACT_MATCH:
0351:                    if (sameLength
0352:                            && matchFirstChar
0353:                            && CharOperation.equals(pattern, name,
0354:                                    this .isCaseSensitive)) {
0355:                        return POSSIBLE_MATCH | EXACT_FLAVOR;
0356:                    }
0357:                    break;
0358:                case SearchPattern.R_PREFIX_MATCH:
0359:                    if (canBePrefix
0360:                            && matchFirstChar
0361:                            && CharOperation.prefixEquals(pattern, name,
0362:                                    this .isCaseSensitive)) {
0363:                        return POSSIBLE_MATCH;
0364:                    }
0365:                    break;
0366:                case SearchPattern.R_PATTERN_MATCH:
0367:                    // TODO_PERFS (frederic) Not sure this lowercase is necessary
0368:                    if (!this .isCaseSensitive) {
0369:                        pattern = CharOperation.toLowerCase(pattern);
0370:                    }
0371:                    if (CharOperation
0372:                            .match(pattern, name, this .isCaseSensitive)) {
0373:                        return POSSIBLE_MATCH;
0374:                    }
0375:                    break;
0376:                case SearchPattern.R_REGEXP_MATCH:
0377:                    // TODO (frederic) implement regular expression match
0378:                    break;
0379:                }
0380:                return IMPOSSIBLE_MATCH;
0381:            }
0382:
0383:            /**
0384:             * Returns whether the given type reference matches the given pattern.
0385:             */
0386:            protected boolean matchesTypeReference(char[] pattern,
0387:                    TypeReference type) {
0388:                if (pattern == null)
0389:                    return true; // null is as if it was "*"
0390:                if (type == null)
0391:                    return true; // treat as an inexact match
0392:
0393:                char[][] compoundName = type.getTypeName();
0394:                char[] simpleName = compoundName[compoundName.length - 1];
0395:                int dimensions = type.dimensions() * 2;
0396:                if (dimensions > 0) {
0397:                    int length = simpleName.length;
0398:                    char[] result = new char[length + dimensions];
0399:                    System.arraycopy(simpleName, 0, result, 0, length);
0400:                    for (int i = length, l = result.length; i < l;) {
0401:                        result[i++] = '[';
0402:                        result[i++] = ']';
0403:                    }
0404:                    simpleName = result;
0405:                }
0406:
0407:                return matchesName(pattern, simpleName);
0408:            }
0409:
0410:            /**
0411:             * Returns the match level for the given importRef.
0412:             */
0413:            protected int matchLevel(ImportReference importRef) {
0414:                // override if interested in import references which are caught by the generic version of match(ASTNode, MatchingNodeSet)
0415:                return IMPOSSIBLE_MATCH;
0416:            }
0417:
0418:            /**
0419:             * Reports the match of the given import reference if the resolveLevel is high enough.
0420:             */
0421:            protected void matchLevelAndReportImportRef(
0422:                    ImportReference importRef, Binding binding,
0423:                    MatchLocator locator) throws CoreException {
0424:                int level = resolveLevel(binding);
0425:                if (level >= INACCURATE_MATCH) {
0426:                    matchReportImportRef(importRef, binding, locator
0427:                            .createImportHandle(importRef),
0428:                            level == ACCURATE_MATCH ? SearchMatch.A_ACCURATE
0429:                                    : SearchMatch.A_INACCURATE, locator);
0430:                }
0431:            }
0432:
0433:            /**
0434:             * Reports the match of the given import reference.
0435:             */
0436:            protected void matchReportImportRef(ImportReference importRef,
0437:                    Binding binding, IJavaElement element, int accuracy,
0438:                    MatchLocator locator) throws CoreException {
0439:                if (locator.encloses(element)) {
0440:                    // default is to report a match as a regular ref.
0441:                    this .matchReportReference(importRef, element,
0442:                            null/*no binding*/, accuracy, locator);
0443:                }
0444:            }
0445:
0446:            /**
0447:             * Reports the match of the given reference.
0448:             */
0449:            protected void matchReportReference(ASTNode reference,
0450:                    IJavaElement element, Binding elementBinding, int accuracy,
0451:                    MatchLocator locator) throws CoreException {
0452:                match = null;
0453:                int referenceType = referenceType();
0454:                int offset = reference.sourceStart;
0455:                switch (referenceType) {
0456:                case IJavaElement.PACKAGE_FRAGMENT:
0457:                    match = locator
0458:                            .newPackageReferenceMatch(element, accuracy,
0459:                                    offset, reference.sourceEnd - offset + 1,
0460:                                    reference);
0461:                    break;
0462:                case IJavaElement.TYPE:
0463:                    match = locator.newTypeReferenceMatch(element,
0464:                            elementBinding, accuracy, offset,
0465:                            reference.sourceEnd - offset + 1, reference);
0466:                    break;
0467:                case IJavaElement.FIELD:
0468:                    match = locator.newFieldReferenceMatch(element,
0469:                            elementBinding, accuracy, offset,
0470:                            reference.sourceEnd - offset + 1, reference);
0471:                    break;
0472:                case IJavaElement.LOCAL_VARIABLE:
0473:                    match = locator.newLocalVariableReferenceMatch(element,
0474:                            accuracy, offset, reference.sourceEnd - offset + 1,
0475:                            reference);
0476:                    break;
0477:                case IJavaElement.TYPE_PARAMETER:
0478:                    match = locator.newTypeParameterReferenceMatch(element,
0479:                            accuracy, offset, reference.sourceEnd - offset + 1,
0480:                            reference);
0481:                    break;
0482:                }
0483:                if (match != null) {
0484:                    locator.report(match);
0485:                }
0486:            }
0487:
0488:            /**
0489:             * Reports the match of the given reference. Also provide a local element to eventually report in match.
0490:             */
0491:            protected void matchReportReference(ASTNode reference,
0492:                    IJavaElement element, IJavaElement localElement,
0493:                    IJavaElement[] otherElements, Binding elementBinding,
0494:                    int accuracy, MatchLocator locator) throws CoreException {
0495:                matchReportReference(reference, element, elementBinding,
0496:                        accuracy, locator);
0497:            }
0498:
0499:            /**
0500:             * Reports the match of the given reference. Also provide a scope to look for potential other elements.
0501:             */
0502:            protected void matchReportReference(ASTNode reference,
0503:                    IJavaElement element, Binding elementBinding, Scope scope,
0504:                    int accuracy, MatchLocator locator) throws CoreException {
0505:                matchReportReference(reference, element, elementBinding,
0506:                        accuracy, locator);
0507:            }
0508:
0509:            public SearchMatch newDeclarationMatch(ASTNode reference,
0510:                    IJavaElement element, Binding elementBinding, int accuracy,
0511:                    int length, MatchLocator locator) {
0512:                return locator.newDeclarationMatch(element, elementBinding,
0513:                        accuracy, reference.sourceStart, length);
0514:            }
0515:
0516:            protected int referenceType() {
0517:                return 0; // defaults to unknown (a generic JavaSearchMatch will be created)
0518:            }
0519:
0520:            /**
0521:             * Finds out whether the given ast node matches this search pattern.
0522:             * Returns IMPOSSIBLE_MATCH if it doesn't.
0523:             * Returns INACCURATE_MATCH if it potentially matches this search pattern (ie. 
0524:             * it has already been resolved but resolving failed.)
0525:             * Returns ACCURATE_MATCH if it matches exactly this search pattern (ie. 
0526:             * it doesn't need to be resolved or it has already been resolved.)
0527:             */
0528:            public int resolveLevel(ASTNode possibleMatchingNode) {
0529:                // only called with nodes which were possible matches to the call to matchLevel
0530:                // need to do instance of checks to find out exact type of ASTNode
0531:                return IMPOSSIBLE_MATCH;
0532:            }
0533:
0534:            /*
0535:             * Update pattern locator match for parameterized top level types.
0536:             * Set match raw flag and recurse to enclosing types if any...
0537:             */
0538:            protected void updateMatch(
0539:                    ParameterizedTypeBinding parameterizedBinding,
0540:                    char[][][] patternTypeArguments, MatchLocator locator) {
0541:                // Only possible if locator has an unit scope.
0542:                if (locator.unitScope != null) {
0543:                    updateMatch(parameterizedBinding, patternTypeArguments,
0544:                            false, 0, locator);
0545:                }
0546:            }
0547:
0548:            protected void updateMatch(
0549:                    ParameterizedTypeBinding parameterizedBinding,
0550:                    char[][][] patternTypeArguments,
0551:                    boolean patternHasTypeParameters, int depth,
0552:                    MatchLocator locator) {
0553:                // Only possible if locator has an unit scope.
0554:                if (locator.unitScope == null)
0555:                    return;
0556:
0557:                // Set match raw flag
0558:                boolean endPattern = patternTypeArguments == null ? true
0559:                        : depth >= patternTypeArguments.length;
0560:                TypeBinding[] argumentsBindings = parameterizedBinding.arguments;
0561:                boolean isRaw = parameterizedBinding.isRawType()
0562:                        || (argumentsBindings == null && parameterizedBinding
0563:                                .genericType().isGenericType());
0564:                if (isRaw && !match.isRaw()) {
0565:                    match.setRaw(isRaw);
0566:                }
0567:
0568:                // Update match
0569:                if (!endPattern && patternTypeArguments != null) {
0570:                    // verify if this is a reference to the generic type itself
0571:                    if (!isRaw && patternHasTypeParameters
0572:                            && argumentsBindings != null) {
0573:                        boolean needUpdate = false;
0574:                        TypeVariableBinding[] typeVariables = parameterizedBinding
0575:                                .genericType().typeVariables();
0576:                        for (int i = 0, l = argumentsBindings.length; i < l; i++) {
0577:                            if (argumentsBindings[i] != typeVariables[i]) {
0578:                                needUpdate = true;
0579:                                break;
0580:                            }
0581:                        }
0582:                        if (needUpdate) {
0583:                            char[][] patternArguments = patternTypeArguments[depth];
0584:                            updateMatch(argumentsBindings, locator,
0585:                                    patternArguments, patternHasTypeParameters);
0586:                        }
0587:                    } else {
0588:                        char[][] patternArguments = patternTypeArguments[depth];
0589:                        updateMatch(argumentsBindings, locator,
0590:                                patternArguments, patternHasTypeParameters);
0591:                    }
0592:                }
0593:
0594:                // Recurse
0595:                TypeBinding enclosingType = parameterizedBinding
0596:                        .enclosingType();
0597:                if (enclosingType != null
0598:                        && (enclosingType.isParameterizedType() || enclosingType
0599:                                .isRawType())) {
0600:                    updateMatch((ParameterizedTypeBinding) enclosingType,
0601:                            patternTypeArguments, patternHasTypeParameters,
0602:                            depth + 1, locator);
0603:                }
0604:            }
0605:
0606:            /*
0607:             * Update pattern locator match comparing type arguments with pattern ones.
0608:             * Try to resolve pattern and look for compatibility with type arguments
0609:             * to set match rule.
0610:             */
0611:            protected void updateMatch(TypeBinding[] argumentsBinding,
0612:                    MatchLocator locator, char[][] patternArguments,
0613:                    boolean hasTypeParameters) {
0614:                // Only possible if locator has an unit scope.
0615:                if (locator.unitScope == null)
0616:                    return;
0617:
0618:                // First compare lengthes
0619:                int patternTypeArgsLength = patternArguments == null ? 0
0620:                        : patternArguments.length;
0621:                int typeArgumentsLength = argumentsBinding == null ? 0
0622:                        : argumentsBinding.length;
0623:
0624:                // Initialize match rule
0625:                int matchRule = match.getRule();
0626:                if (match.isRaw()) {
0627:                    if (patternTypeArgsLength != 0) {
0628:                        matchRule &= ~SearchPattern.R_FULL_MATCH;
0629:                    }
0630:                }
0631:                if (hasTypeParameters) {
0632:                    matchRule = SearchPattern.R_ERASURE_MATCH;
0633:                }
0634:
0635:                // Compare arguments lengthes
0636:                if (patternTypeArgsLength == typeArgumentsLength) {
0637:                    if (!match.isRaw() && hasTypeParameters) {
0638:                        // generic patterns are always not compatible match
0639:                        match.setRule(SearchPattern.R_ERASURE_MATCH);
0640:                        return;
0641:                    }
0642:                } else {
0643:                    if (patternTypeArgsLength == 0) {
0644:                        if (!match.isRaw() || hasTypeParameters) {
0645:                            match.setRule(matchRule
0646:                                    & ~SearchPattern.R_FULL_MATCH);
0647:                        }
0648:                    } else if (typeArgumentsLength == 0) {
0649:                        // raw binding is always compatible
0650:                        match.setRule(matchRule & ~SearchPattern.R_FULL_MATCH);
0651:                    } else {
0652:                        match.setRule(0); // impossible match
0653:                    }
0654:                    return;
0655:                }
0656:                if (argumentsBinding == null || patternArguments == null) {
0657:                    match.setRule(matchRule);
0658:                    return;
0659:                }
0660:
0661:                // Compare binding for each type argument only if pattern is not erasure only and at first level
0662:                if (!hasTypeParameters && !match.isRaw()
0663:                        && (match.isEquivalent() || match.isExact())) {
0664:                    for (int i = 0; i < typeArgumentsLength; i++) {
0665:                        // Get parameterized type argument binding
0666:                        TypeBinding argumentBinding = argumentsBinding[i];
0667:                        if (argumentBinding instanceof  CaptureBinding) {
0668:                            WildcardBinding capturedWildcard = ((CaptureBinding) argumentBinding).wildcard;
0669:                            if (capturedWildcard != null)
0670:                                argumentBinding = capturedWildcard;
0671:                        }
0672:                        // Get binding for pattern argument
0673:                        char[] patternTypeArgument = patternArguments[i];
0674:                        char patternWildcard = patternTypeArgument[0];
0675:                        char[] patternTypeName = patternTypeArgument;
0676:                        int patternWildcardKind = -1;
0677:                        switch (patternWildcard) {
0678:                        case Signature.C_STAR:
0679:                            if (argumentBinding.isWildcard()) {
0680:                                WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
0681:                                if (wildcardBinding.boundKind == Wildcard.UNBOUND)
0682:                                    continue;
0683:                            }
0684:                            matchRule &= ~SearchPattern.R_FULL_MATCH;
0685:                            continue; // unbound parameter always match
0686:                        case Signature.C_EXTENDS:
0687:                            patternWildcardKind = Wildcard.EXTENDS;
0688:                            patternTypeName = CharOperation.subarray(
0689:                                    patternTypeArgument, 1,
0690:                                    patternTypeArgument.length);
0691:                            break;
0692:                        case Signature.C_SUPER:
0693:                            patternWildcardKind = Wildcard.SUPER;
0694:                            patternTypeName = CharOperation.subarray(
0695:                                    patternTypeArgument, 1,
0696:                                    patternTypeArgument.length);
0697:                        default:
0698:                            break;
0699:                        }
0700:                        patternTypeName = Signature
0701:                                .toCharArray(patternTypeName);
0702:                        TypeBinding patternBinding = locator.getType(
0703:                                patternTypeArgument, patternTypeName);
0704:
0705:                        // If have no binding for pattern arg, then we won't be able to refine accuracy
0706:                        if (patternBinding == null) {
0707:                            if (argumentBinding.isWildcard()) {
0708:                                WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
0709:                                if (wildcardBinding.boundKind == Wildcard.UNBOUND) {
0710:                                    matchRule &= ~SearchPattern.R_FULL_MATCH;
0711:                                } else {
0712:                                    match
0713:                                            .setRule(SearchPattern.R_ERASURE_MATCH);
0714:                                    return;
0715:                                }
0716:                            }
0717:                            continue;
0718:                        }
0719:
0720:                        // Verify tha pattern binding is compatible with match type argument binding
0721:                        switch (patternWildcard) {
0722:                        case Signature.C_STAR: // UNBOUND pattern
0723:                            // unbound always match => skip to next argument
0724:                            matchRule &= ~SearchPattern.R_FULL_MATCH;
0725:                            continue;
0726:                        case Signature.C_EXTENDS: // EXTENDS pattern
0727:                            if (argumentBinding.isWildcard()) { // argument is a wildcard
0728:                                WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
0729:                                // It's ok if wildcards are identical
0730:                                if (wildcardBinding.boundKind == patternWildcardKind
0731:                                        && wildcardBinding.bound == patternBinding) {
0732:                                    continue;
0733:                                }
0734:                                // Look for wildcard compatibility
0735:                                switch (wildcardBinding.boundKind) {
0736:                                case Wildcard.EXTENDS:
0737:                                    if (wildcardBinding.bound == null
0738:                                            || wildcardBinding.bound
0739:                                                    .isCompatibleWith(patternBinding)) {
0740:                                        // valid when arg extends a subclass of pattern
0741:                                        matchRule &= ~SearchPattern.R_FULL_MATCH;
0742:                                        continue;
0743:                                    }
0744:                                    break;
0745:                                case Wildcard.SUPER:
0746:                                    break;
0747:                                case Wildcard.UNBOUND:
0748:                                    matchRule &= ~SearchPattern.R_FULL_MATCH;
0749:                                    continue;
0750:                                }
0751:                            } else if (argumentBinding
0752:                                    .isCompatibleWith(patternBinding)) {
0753:                                // valid when arg is a subclass of pattern 
0754:                                matchRule &= ~SearchPattern.R_FULL_MATCH;
0755:                                continue;
0756:                            }
0757:                            break;
0758:                        case Signature.C_SUPER: // SUPER pattern
0759:                            if (argumentBinding.isWildcard()) { // argument is a wildcard
0760:                                WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
0761:                                // It's ok if wildcards are identical
0762:                                if (wildcardBinding.boundKind == patternWildcardKind
0763:                                        && wildcardBinding.bound == patternBinding) {
0764:                                    continue;
0765:                                }
0766:                                // Look for wildcard compatibility
0767:                                switch (wildcardBinding.boundKind) {
0768:                                case Wildcard.EXTENDS:
0769:                                    break;
0770:                                case Wildcard.SUPER:
0771:                                    if (wildcardBinding.bound == null
0772:                                            || patternBinding
0773:                                                    .isCompatibleWith(wildcardBinding.bound)) {
0774:                                        // valid only when arg super a superclass of pattern
0775:                                        matchRule &= ~SearchPattern.R_FULL_MATCH;
0776:                                        continue;
0777:                                    }
0778:                                    break;
0779:                                case Wildcard.UNBOUND:
0780:                                    matchRule &= ~SearchPattern.R_FULL_MATCH;
0781:                                    continue;
0782:                                }
0783:                            } else if (patternBinding
0784:                                    .isCompatibleWith(argumentBinding)) {
0785:                                // valid only when arg is a superclass of pattern
0786:                                matchRule &= ~SearchPattern.R_FULL_MATCH;
0787:                                continue;
0788:                            }
0789:                            break;
0790:                        default:
0791:                            if (argumentBinding.isWildcard()) {
0792:                                WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
0793:                                switch (wildcardBinding.boundKind) {
0794:                                case Wildcard.EXTENDS:
0795:                                    if (wildcardBinding.bound == null
0796:                                            || patternBinding
0797:                                                    .isCompatibleWith(wildcardBinding.bound)) {
0798:                                        // valid only when arg extends a superclass of pattern
0799:                                        matchRule &= ~SearchPattern.R_FULL_MATCH;
0800:                                        continue;
0801:                                    }
0802:                                    break;
0803:                                case Wildcard.SUPER:
0804:                                    if (wildcardBinding.bound == null
0805:                                            || wildcardBinding.bound
0806:                                                    .isCompatibleWith(patternBinding)) {
0807:                                        // valid only when arg super a subclass of pattern
0808:                                        matchRule &= ~SearchPattern.R_FULL_MATCH;
0809:                                        continue;
0810:                                    }
0811:                                    break;
0812:                                case Wildcard.UNBOUND:
0813:                                    matchRule &= ~SearchPattern.R_FULL_MATCH;
0814:                                    continue;
0815:                                }
0816:                            } else if (argumentBinding == patternBinding)
0817:                                // valid only when arg is equals to pattern
0818:                                continue;
0819:                            break;
0820:                        }
0821:
0822:                        // Argument does not match => erasure match will be the only possible one
0823:                        match.setRule(SearchPattern.R_ERASURE_MATCH);
0824:                        return;
0825:                    }
0826:                }
0827:
0828:                // Set match rule
0829:                match.setRule(matchRule);
0830:            }
0831:
0832:            /**
0833:             * Finds out whether the given binding matches this search pattern.
0834:             * Returns ACCURATE_MATCH if it does.
0835:             * Returns INACCURATE_MATCH if resolve failed but match is still possible.
0836:             * Returns IMPOSSIBLE_MATCH otherwise.
0837:             * Default is to return INACCURATE_MATCH.
0838:             */
0839:            public int resolveLevel(Binding binding) {
0840:                // override if the pattern can match the binding
0841:                return INACCURATE_MATCH;
0842:            }
0843:
0844:            /**
0845:             * Returns whether the given type binding matches the given simple name pattern 
0846:             * and qualification pattern.
0847:             * Note that from since 3.1, this method resolve to accurate member or local types
0848:             * even if they are not fully qualified (ie. X.Member instead of p.X.Member).
0849:             * Returns ACCURATE_MATCH if it does.
0850:             * Returns INACCURATE_MATCH if resolve failed.
0851:             * Returns IMPOSSIBLE_MATCH if it doesn't.
0852:             */
0853:            protected int resolveLevelForType(char[] simpleNamePattern,
0854:                    char[] qualificationPattern, TypeBinding binding) {
0855:                //	return resolveLevelForType(qualifiedPattern(simpleNamePattern, qualificationPattern), type);
0856:                char[] qualifiedPattern = getQualifiedPattern(
0857:                        simpleNamePattern, qualificationPattern);
0858:                int level = resolveLevelForType(qualifiedPattern, binding);
0859:                if (level == ACCURATE_MATCH || binding == null)
0860:                    return level;
0861:                TypeBinding type = binding instanceof  ArrayBinding ? ((ArrayBinding) binding).leafComponentType
0862:                        : binding;
0863:                char[] sourceName = null;
0864:                if (type.isMemberType() || type.isLocalType()) {
0865:                    if (qualificationPattern != null) {
0866:                        sourceName = getQualifiedSourceName(binding);
0867:                    } else {
0868:                        sourceName = binding.sourceName();
0869:                    }
0870:                } else if (qualificationPattern == null) {
0871:                    sourceName = getQualifiedSourceName(binding);
0872:                }
0873:                if (sourceName == null)
0874:                    return IMPOSSIBLE_MATCH;
0875:                if ((this .matchMode & SearchPattern.R_PREFIX_MATCH) != 0) {
0876:                    if (CharOperation.prefixEquals(qualifiedPattern,
0877:                            sourceName, this .isCaseSensitive)) {
0878:                        return ACCURATE_MATCH;
0879:                    }
0880:                }
0881:                if (this .isCamelCase) {
0882:                    if ((qualifiedPattern.length > 0 && sourceName.length > 0 && qualifiedPattern[0] == sourceName[0])) {
0883:                        if (CharOperation
0884:                                .camelCaseMatch(
0885:                                        qualifiedPattern,
0886:                                        sourceName,
0887:                                        (this .matchMode & SearchPattern.R_PREFIX_MATCH) != 0)) {
0888:                            return ACCURATE_MATCH;
0889:                        }
0890:                    }
0891:                    if (!this .isCaseSensitive
0892:                            && this .matchMode == SearchPattern.R_EXACT_MATCH) {
0893:                        boolean matchPattern = CharOperation.equals(
0894:                                qualifiedPattern, sourceName, false);
0895:                        return matchPattern ? ACCURATE_MATCH : IMPOSSIBLE_MATCH;
0896:                    }
0897:                }
0898:                boolean matchPattern = CharOperation.match(qualifiedPattern,
0899:                        sourceName, this .isCaseSensitive);
0900:                return matchPattern ? ACCURATE_MATCH : IMPOSSIBLE_MATCH;
0901:
0902:            }
0903:
0904:            /**
0905:             * Returns whether the given type binding matches the given qualified pattern.
0906:             * Returns ACCURATE_MATCH if it does.
0907:             * Returns INACCURATE_MATCH if resolve failed.
0908:             * Returns IMPOSSIBLE_MATCH if it doesn't.
0909:             */
0910:            protected int resolveLevelForType(char[] qualifiedPattern,
0911:                    TypeBinding type) {
0912:                if (qualifiedPattern == null)
0913:                    return ACCURATE_MATCH;
0914:                if (type == null)
0915:                    return INACCURATE_MATCH;
0916:
0917:                // Type variable cannot be specified through pattern => this kind of binding cannot match it (see bug 79803)
0918:                if (type.isTypeVariable())
0919:                    return IMPOSSIBLE_MATCH;
0920:
0921:                // NOTE: if case insensitive search then qualifiedPattern is assumed to be lowercase
0922:
0923:                char[] qualifiedPackageName = type.qualifiedPackageName();
0924:                char[] qualifiedSourceName = qualifiedSourceName(type);
0925:                char[] fullyQualifiedTypeName = qualifiedPackageName.length == 0 ? qualifiedSourceName
0926:                        : CharOperation.concat(qualifiedPackageName,
0927:                                qualifiedSourceName, '.');
0928:                return CharOperation.match(qualifiedPattern,
0929:                        fullyQualifiedTypeName, this .isCaseSensitive) ? ACCURATE_MATCH
0930:                        : IMPOSSIBLE_MATCH;
0931:            }
0932:
0933:            /* (non-Javadoc)
0934:             * Resolve level for type with a given binding with all pattern information.
0935:             */
0936:            protected int resolveLevelForType(char[] simpleNamePattern,
0937:                    char[] qualificationPattern,
0938:                    char[][][] patternTypeArguments, int depth, TypeBinding type) {
0939:                // standard search with no generic additional information must succeed
0940:                int level = resolveLevelForType(simpleNamePattern,
0941:                        qualificationPattern, type);
0942:                if (level == IMPOSSIBLE_MATCH)
0943:                    return IMPOSSIBLE_MATCH;
0944:                if (type == null || patternTypeArguments == null
0945:                        || patternTypeArguments.length == 0
0946:                        || depth >= patternTypeArguments.length) {
0947:                    return level;
0948:                }
0949:
0950:                // if pattern is erasure match (see bug 79790), commute impossible to erasure
0951:                int impossible = this .isErasureMatch ? ERASURE_MATCH
0952:                        : IMPOSSIBLE_MATCH;
0953:
0954:                // pattern has type parameter(s) or type argument(s)
0955:                if (type.isGenericType()) {
0956:                    // Binding is generic, get its type variable(s)
0957:                    TypeVariableBinding[] typeVariables = null;
0958:                    if (type instanceof  SourceTypeBinding) {
0959:                        SourceTypeBinding sourceTypeBinding = (SourceTypeBinding) type;
0960:                        typeVariables = sourceTypeBinding.typeVariables;
0961:                    } else if (type instanceof  BinaryTypeBinding) {
0962:                        BinaryTypeBinding binaryTypeBinding = (BinaryTypeBinding) type;
0963:                        if (this .mustResolve)
0964:                            typeVariables = binaryTypeBinding.typeVariables(); // TODO (frederic) verify performance
0965:                    }
0966:                    if (patternTypeArguments[depth] != null
0967:                            && patternTypeArguments[depth].length > 0
0968:                            && typeVariables != null
0969:                            && typeVariables.length > 0) {
0970:                        if (typeVariables.length != patternTypeArguments[depth].length)
0971:                            return IMPOSSIBLE_MATCH;
0972:                    }
0973:                    // TODO (frederic) do we need to verify each parameter?
0974:                    return level; // we can't do better
0975:                } else if (type.isRawType()) {
0976:                    return level; // raw type always match
0977:                } else {
0978:                    TypeBinding leafType = type.leafComponentType();
0979:                    if (!leafType.isParameterizedType()) {
0980:                        // Standard types (ie. neither generic nor parameterized nor raw types)
0981:                        // cannot match pattern with type parameters or arguments
0982:                        return (patternTypeArguments[depth] == null || patternTypeArguments[depth].length == 0) ? level
0983:                                : IMPOSSIBLE_MATCH;
0984:                    }
0985:                    ParameterizedTypeBinding paramTypeBinding = (ParameterizedTypeBinding) leafType;
0986:
0987:                    // Compare arguments only if there ones on both sides
0988:                    if (patternTypeArguments[depth] != null
0989:                            && patternTypeArguments[depth].length > 0
0990:                            && paramTypeBinding.arguments != null
0991:                            && paramTypeBinding.arguments.length > 0) {
0992:
0993:                        // type parameters length must match at least specified type names length
0994:                        int length = patternTypeArguments[depth].length;
0995:                        if (paramTypeBinding.arguments.length != length)
0996:                            return IMPOSSIBLE_MATCH;
0997:
0998:                        // verify each pattern type parameter
0999:                        nextTypeArgument: for (int i = 0; i < length; i++) {
1000:                            char[] patternTypeArgument = patternTypeArguments[depth][i];
1001:                            TypeBinding argTypeBinding = paramTypeBinding.arguments[i];
1002:                            // get corresponding pattern wildcard
1003:                            switch (patternTypeArgument[0]) {
1004:                            case Signature.C_STAR: // unbound parameter always match
1005:                            case Signature.C_SUPER: // needs pattern type parameter binding
1006:                                // skip to next type argument as it will be resolved later
1007:                                continue nextTypeArgument;
1008:                            case Signature.C_EXTENDS:
1009:                                // remove wildcard from patter type argument
1010:                                patternTypeArgument = CharOperation.subarray(
1011:                                        patternTypeArgument, 1,
1012:                                        patternTypeArgument.length);
1013:                            default:
1014:                                // no wildcard
1015:                                break;
1016:                            }
1017:                            // get pattern type argument from its signature
1018:                            patternTypeArgument = Signature
1019:                                    .toCharArray(patternTypeArgument);
1020:                            if (!this .isCaseSensitive)
1021:                                patternTypeArgument = CharOperation
1022:                                        .toLowerCase(patternTypeArgument);
1023:                            boolean patternTypeArgHasAnyChars = CharOperation
1024:                                    .contains(new char[] { '*', '?' },
1025:                                            patternTypeArgument);
1026:
1027:                            // Verify that names match...
1028:                            // ...special case for wildcard
1029:                            if (argTypeBinding instanceof  CaptureBinding) {
1030:                                WildcardBinding capturedWildcard = ((CaptureBinding) argTypeBinding).wildcard;
1031:                                if (capturedWildcard != null)
1032:                                    argTypeBinding = capturedWildcard;
1033:                            }
1034:                            if (argTypeBinding.isWildcard()) {
1035:                                WildcardBinding wildcardBinding = (WildcardBinding) argTypeBinding;
1036:                                switch (wildcardBinding.boundKind) {
1037:                                case Wildcard.EXTENDS:
1038:                                    // Invalid if type argument is not exact
1039:                                    if (patternTypeArgHasAnyChars)
1040:                                        return impossible;
1041:                                case Wildcard.UNBOUND:
1042:                                    // there's no bound name to match => valid
1043:                                    continue nextTypeArgument;
1044:                                }
1045:                                // Look if bound name match pattern type argument
1046:                                ReferenceBinding boundBinding = (ReferenceBinding) wildcardBinding.bound;
1047:                                if (CharOperation.match(patternTypeArgument,
1048:                                        boundBinding.shortReadableName(),
1049:                                        this .isCaseSensitive)
1050:                                        || CharOperation.match(
1051:                                                patternTypeArgument,
1052:                                                boundBinding.readableName(),
1053:                                                this .isCaseSensitive)) {
1054:                                    // found name in hierarchy => match
1055:                                    continue nextTypeArgument;
1056:                                }
1057:
1058:                                // If pattern is not exact then match fails
1059:                                if (patternTypeArgHasAnyChars)
1060:                                    return impossible;
1061:
1062:                                // Look for bound name in type argument superclasses
1063:                                boundBinding = boundBinding.super class();
1064:                                while (boundBinding != null) {
1065:                                    if (CharOperation.equals(
1066:                                            patternTypeArgument, boundBinding
1067:                                                    .shortReadableName(),
1068:                                            this .isCaseSensitive)
1069:                                            || CharOperation
1070:                                                    .equals(
1071:                                                            patternTypeArgument,
1072:                                                            boundBinding
1073:                                                                    .readableName(),
1074:                                                            this .isCaseSensitive)) {
1075:                                        // found name in hierarchy => match
1076:                                        continue nextTypeArgument;
1077:                                    } else if (boundBinding.isLocalType()
1078:                                            || boundBinding.isMemberType()) {
1079:                                        // for local or member type, verify also source name (bug 81084)
1080:                                        if (CharOperation.match(
1081:                                                patternTypeArgument,
1082:                                                boundBinding.sourceName(),
1083:                                                this .isCaseSensitive))
1084:                                            continue nextTypeArgument;
1085:                                    }
1086:                                    boundBinding = boundBinding.super class();
1087:                                }
1088:                                return impossible;
1089:                            }
1090:
1091:                            // See if names match
1092:                            if (CharOperation.match(patternTypeArgument,
1093:                                    argTypeBinding.shortReadableName(),
1094:                                    this .isCaseSensitive)
1095:                                    || CharOperation.match(patternTypeArgument,
1096:                                            argTypeBinding.readableName(),
1097:                                            this .isCaseSensitive)) {
1098:                                continue nextTypeArgument;
1099:                            } else if (argTypeBinding.isLocalType()
1100:                                    || argTypeBinding.isMemberType()) {
1101:                                // for local or member type, verify also source name (bug 81084)
1102:                                if (CharOperation.match(patternTypeArgument,
1103:                                        argTypeBinding.sourceName(),
1104:                                        this .isCaseSensitive))
1105:                                    continue nextTypeArgument;
1106:                            }
1107:
1108:                            // If pattern is not exact then match fails
1109:                            if (patternTypeArgHasAnyChars)
1110:                                return impossible;
1111:
1112:                            // Scan hierarchy
1113:                            TypeBinding leafTypeBinding = argTypeBinding
1114:                                    .leafComponentType();
1115:                            if (leafTypeBinding.isBaseType())
1116:                                return impossible;
1117:                            ReferenceBinding refBinding = ((ReferenceBinding) leafTypeBinding)
1118:                                    .super class();
1119:                            while (refBinding != null) {
1120:                                if (CharOperation.equals(patternTypeArgument,
1121:                                        refBinding.shortReadableName(),
1122:                                        this .isCaseSensitive)
1123:                                        || CharOperation.equals(
1124:                                                patternTypeArgument, refBinding
1125:                                                        .readableName(),
1126:                                                this .isCaseSensitive)) {
1127:                                    // found name in hierarchy => match
1128:                                    continue nextTypeArgument;
1129:                                } else if (refBinding.isLocalType()
1130:                                        || refBinding.isMemberType()) {
1131:                                    // for local or member type, verify also source name (bug 81084)
1132:                                    if (CharOperation.match(
1133:                                            patternTypeArgument, refBinding
1134:                                                    .sourceName(),
1135:                                            this .isCaseSensitive))
1136:                                        continue nextTypeArgument;
1137:                                }
1138:                                refBinding = refBinding.super class();
1139:                            }
1140:                            return impossible;
1141:                        }
1142:                    }
1143:
1144:                    // Recurse on enclosing type
1145:                    TypeBinding enclosingType = paramTypeBinding
1146:                            .enclosingType();
1147:                    if (enclosingType != null
1148:                            && enclosingType.isParameterizedType()
1149:                            && depth < patternTypeArguments.length
1150:                            && qualificationPattern != null) {
1151:                        int lastDot = CharOperation.lastIndexOf('.',
1152:                                qualificationPattern);
1153:                        char[] enclosingQualificationPattern = lastDot == -1 ? null
1154:                                : CharOperation.subarray(qualificationPattern,
1155:                                        0, lastDot);
1156:                        char[] enclosingSimpleNamePattern = lastDot == -1 ? qualificationPattern
1157:                                : CharOperation.subarray(qualificationPattern,
1158:                                        lastDot + 1,
1159:                                        qualificationPattern.length);
1160:                        int enclosingLevel = resolveLevelForType(
1161:                                enclosingSimpleNamePattern,
1162:                                enclosingQualificationPattern,
1163:                                patternTypeArguments, depth + 1, enclosingType);
1164:                        if (enclosingLevel == impossible)
1165:                            return impossible;
1166:                        if (enclosingLevel == IMPOSSIBLE_MATCH)
1167:                            return IMPOSSIBLE_MATCH;
1168:                    }
1169:                    return level;
1170:                }
1171:            }
1172:
1173:            public String toString() {
1174:                return "SearchPattern"; //$NON-NLS-1$
1175:            }
1176:        }
w_w_w_.j___av___a__2s___._c__o___m | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.