001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 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.jdt.core.compiler.CharOperation;
013: import org.eclipse.jdt.internal.compiler.ast.ASTNode;
014: import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
015: import org.eclipse.jdt.internal.compiler.lookup.*;
016:
017: public class TypeDeclarationLocator extends PatternLocator {
018:
019: protected TypeDeclarationPattern pattern; // can be a QualifiedTypeDeclarationPattern
020:
021: public TypeDeclarationLocator(TypeDeclarationPattern pattern) {
022: super (pattern);
023:
024: this .pattern = pattern;
025: }
026:
027: //public int match(ASTNode node, MatchingNodeSet nodeSet) - SKIP IT
028: //public int match(ConstructorDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
029: //public int match(Expression node, MatchingNodeSet nodeSet) - SKIP IT
030: //public int match(FieldDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
031: //public int match(MethodDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
032: //public int match(MessageSend node, MatchingNodeSet nodeSet) - SKIP IT
033: //public int match(Reference node, MatchingNodeSet nodeSet) - SKIP IT
034: public int match(TypeDeclaration node, MatchingNodeSet nodeSet) {
035: if (this .pattern.simpleName == null
036: || matchesName(this .pattern.simpleName, node.name))
037: return nodeSet
038: .addMatch(
039: node,
040: ((InternalSearchPattern) this .pattern).mustResolve ? POSSIBLE_MATCH
041: : ACCURATE_MATCH);
042:
043: return IMPOSSIBLE_MATCH;
044: }
045:
046: //public int match(TypeReference node, MatchingNodeSet nodeSet) - SKIP IT
047:
048: public int resolveLevel(ASTNode node) {
049: if (!(node instanceof TypeDeclaration))
050: return IMPOSSIBLE_MATCH;
051:
052: return resolveLevel(((TypeDeclaration) node).binding);
053: }
054:
055: public int resolveLevel(Binding binding) {
056: if (binding == null)
057: return INACCURATE_MATCH;
058: if (!(binding instanceof TypeBinding))
059: return IMPOSSIBLE_MATCH;
060:
061: TypeBinding type = (TypeBinding) binding;
062:
063: switch (this .pattern.typeSuffix) {
064: case CLASS_SUFFIX:
065: if (!type.isClass())
066: return IMPOSSIBLE_MATCH;
067: break;
068: case CLASS_AND_INTERFACE_SUFFIX:
069: if (!(type.isClass() || (type.isInterface() && !type
070: .isAnnotationType())))
071: return IMPOSSIBLE_MATCH;
072: break;
073: case CLASS_AND_ENUM_SUFFIX:
074: if (!(type.isClass() || type.isEnum()))
075: return IMPOSSIBLE_MATCH;
076: break;
077: case INTERFACE_SUFFIX:
078: if (!type.isInterface() || type.isAnnotationType())
079: return IMPOSSIBLE_MATCH;
080: break;
081: case INTERFACE_AND_ANNOTATION_SUFFIX:
082: if (!(type.isInterface() || type.isAnnotationType()))
083: return IMPOSSIBLE_MATCH;
084: break;
085: case ENUM_SUFFIX:
086: if (!type.isEnum())
087: return IMPOSSIBLE_MATCH;
088: break;
089: case ANNOTATION_TYPE_SUFFIX:
090: if (!type.isAnnotationType())
091: return IMPOSSIBLE_MATCH;
092: break;
093: case TYPE_SUFFIX: // nothing
094: }
095:
096: // fully qualified name
097: if (this .pattern instanceof QualifiedTypeDeclarationPattern) {
098: QualifiedTypeDeclarationPattern qualifiedPattern = (QualifiedTypeDeclarationPattern) this .pattern;
099: return resolveLevelForType(qualifiedPattern.simpleName,
100: qualifiedPattern.qualification, type);
101: } else {
102: char[] enclosingTypeName = this .pattern.enclosingTypeNames == null ? null
103: : CharOperation.concatWith(
104: this .pattern.enclosingTypeNames, '.');
105: return resolveLevelForType(this .pattern.simpleName,
106: this .pattern.pkg, enclosingTypeName, type);
107: }
108: }
109:
110: /**
111: * Returns whether the given type binding matches the given simple name pattern
112: * qualification pattern and enclosing type name pattern.
113: */
114: protected int resolveLevelForType(char[] simpleNamePattern,
115: char[] qualificationPattern, char[] enclosingNamePattern,
116: TypeBinding type) {
117: if (enclosingNamePattern == null)
118: return resolveLevelForType(simpleNamePattern,
119: qualificationPattern, type);
120: if (qualificationPattern == null)
121: return resolveLevelForType(simpleNamePattern,
122: enclosingNamePattern, type);
123:
124: // case of an import reference while searching for ALL_OCCURENCES of a type (see bug 37166)
125: if (type instanceof ProblemReferenceBinding)
126: return IMPOSSIBLE_MATCH;
127:
128: // pattern was created from a Java element: qualification is the package name.
129: char[] fullQualificationPattern = CharOperation.concat(
130: qualificationPattern, enclosingNamePattern, '.');
131: if (CharOperation.equals(this .pattern.pkg, CharOperation
132: .concatWith(type.getPackage().compoundName, '.')))
133: return resolveLevelForType(simpleNamePattern,
134: fullQualificationPattern, type);
135: return IMPOSSIBLE_MATCH;
136: }
137:
138: public String toString() {
139: return "Locator for " + this .pattern.toString(); //$NON-NLS-1$
140: }
141: }
|