001: /*******************************************************************************
002: * Copyright (c) 2000, 2005 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.IJavaElement;
013: import org.eclipse.jdt.internal.compiler.ast.*;
014: import org.eclipse.jdt.internal.compiler.lookup.Binding;
015: import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
016: import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
017: import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
018:
019: /**
020: * Search engine locator for type parameters matches.
021: */
022: public class TypeParameterLocator extends PatternLocator {
023:
024: protected TypeParameterPattern pattern;
025:
026: public TypeParameterLocator(TypeParameterPattern pattern) {
027: super (pattern);
028: this .pattern = pattern;
029: }
030:
031: /*
032: * Verify whether a type reference matches name pattern.
033: * Type parameter references (ie. type arguments) are compiler type reference nodes
034: */
035: public int match(TypeReference node, MatchingNodeSet nodeSet) {
036: if (pattern.findReferences) {
037: if (node instanceof SingleTypeReference) { // Type parameter cannot be qualified
038: if (matchesName(this .pattern.name,
039: ((SingleTypeReference) node).token)) {
040: int level = ((InternalSearchPattern) this .pattern).mustResolve ? POSSIBLE_MATCH
041: : ACCURATE_MATCH;
042: return nodeSet.addMatch(node, level);
043: }
044: }
045: }
046: return IMPOSSIBLE_MATCH;
047: }
048:
049: /*
050: * Verify whether a type parameter matches name pattern.
051: */
052: public int match(TypeParameter node, MatchingNodeSet nodeSet) {
053: if (pattern.findDeclarations) {
054: if (matchesName(this .pattern.name, node.name)) {
055: int level = ((InternalSearchPattern) this .pattern).mustResolve ? POSSIBLE_MATCH
056: : ACCURATE_MATCH;
057: return nodeSet.addMatch(node, level);
058: }
059: }
060: return IMPOSSIBLE_MATCH;
061: }
062:
063: /*
064: * While searching for references, need to match all containers as we can have references in javadoc comments.
065: * Otherwise, only class or method container can declare type parameters.
066: */
067: protected int matchContainer() {
068: if (pattern.findReferences) {
069: return ALL_CONTAINER;
070: }
071: return CLASS_CONTAINER | METHOD_CONTAINER;
072: }
073:
074: /*
075: * Verify that a type variable binding match pattern infos.
076: * For types, only look at declaring member name.
077: * For methods, also look at declaring class and parameters type names
078: */
079: protected int matchTypeParameter(TypeVariableBinding variable,
080: boolean matchName) {
081: if (variable == null || variable.declaringElement == null)
082: return INACCURATE_MATCH;
083: if (variable.declaringElement instanceof ReferenceBinding) {
084: ReferenceBinding refBinding = (ReferenceBinding) variable.declaringElement;
085: if (matchesName(refBinding.sourceName,
086: pattern.declaringMemberName)) {
087: return ACCURATE_MATCH;
088: }
089: } else if (variable.declaringElement instanceof MethodBinding) {
090: MethodBinding methBinding = (MethodBinding) variable.declaringElement;
091: if (matchesName(methBinding.declaringClass.sourceName,
092: pattern.methodDeclaringClassName)
093: && (methBinding.isConstructor() || matchesName(
094: methBinding.selector,
095: pattern.declaringMemberName))) {
096: int length = pattern.methodArgumentTypes == null ? 0
097: : pattern.methodArgumentTypes.length;
098: if (methBinding.parameters == null) {
099: if (length == 0)
100: return ACCURATE_MATCH;
101: } else if (methBinding.parameters.length == length) {
102: for (int i = 0; i < length; i++) {
103: if (!matchesName(methBinding.parameters[i]
104: .shortReadableName(),
105: pattern.methodArgumentTypes[i])) {
106: return IMPOSSIBLE_MATCH;
107: }
108: }
109: return ACCURATE_MATCH;
110: }
111: }
112: }
113: return IMPOSSIBLE_MATCH;
114: }
115:
116: protected int referenceType() {
117: return IJavaElement.TYPE_PARAMETER;
118: }
119:
120: /*
121: * Resolve level for a possible matching node.
122: * Only type references while searching references and type parameters
123: * while searching declarations are valid.
124: */
125: public int resolveLevel(ASTNode possibleMatchingNode) {
126: if (this .pattern.findReferences) {
127: if (possibleMatchingNode instanceof SingleTypeReference) {
128: return resolveLevel(((SingleTypeReference) possibleMatchingNode).resolvedType);
129: }
130: }
131: if (this .pattern.findDeclarations) {
132: if (possibleMatchingNode instanceof TypeParameter) {
133: return matchTypeParameter(
134: ((TypeParameter) possibleMatchingNode).binding,
135: true);
136: }
137: }
138: return IMPOSSIBLE_MATCH;
139: }
140:
141: /*
142: * Resolve level for a binding.
143: * Only type variable bindings are valid.
144: */
145: public int resolveLevel(Binding binding) {
146: if (binding == null)
147: return INACCURATE_MATCH;
148: if (!(binding instanceof TypeVariableBinding))
149: return IMPOSSIBLE_MATCH;
150:
151: return matchTypeParameter((TypeVariableBinding) binding, true);
152: }
153:
154: public String toString() {
155: return "Locator for " + this .pattern.toString(); //$NON-NLS-1$
156: }
157: }
|