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.core.runtime.CoreException;
013: import org.eclipse.jdt.core.IJavaElement;
014: import org.eclipse.jdt.internal.compiler.ast.*;
015: import org.eclipse.jdt.internal.compiler.lookup.*;
016: import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
017:
018: public class SuperTypeReferenceLocator extends PatternLocator {
019:
020: protected SuperTypeReferencePattern pattern;
021:
022: public SuperTypeReferenceLocator(SuperTypeReferencePattern pattern) {
023: super (pattern);
024:
025: this .pattern = pattern;
026: }
027:
028: //public int match(ASTNode node, MatchingNodeSet nodeSet) - SKIP IT
029: //public int match(ConstructorDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
030: //public int match(Expression node, MatchingNodeSet nodeSet) - SKIP IT
031: //public int match(FieldDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
032: //public int match(MethodDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
033: //public int match(MessageSend node, MatchingNodeSet nodeSet) - SKIP IT
034: //public int match(Reference node, MatchingNodeSet nodeSet) - SKIP IT
035: //public int match(TypeDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
036: public int match(TypeReference node, MatchingNodeSet nodeSet) {
037: if (this .pattern.super SimpleName == null)
038: return nodeSet
039: .addMatch(
040: node,
041: ((InternalSearchPattern) this .pattern).mustResolve ? POSSIBLE_MATCH
042: : ACCURATE_MATCH);
043:
044: char[] typeRefSimpleName = null;
045: if (node instanceof SingleTypeReference) {
046: typeRefSimpleName = ((SingleTypeReference) node).token;
047: } else { // QualifiedTypeReference
048: char[][] tokens = ((QualifiedTypeReference) node).tokens;
049: typeRefSimpleName = tokens[tokens.length - 1];
050: }
051: if (matchesName(this .pattern.super SimpleName, typeRefSimpleName))
052: return nodeSet
053: .addMatch(
054: node,
055: ((InternalSearchPattern) this .pattern).mustResolve ? POSSIBLE_MATCH
056: : ACCURATE_MATCH);
057:
058: return IMPOSSIBLE_MATCH;
059: }
060:
061: protected int matchContainer() {
062: return CLASS_CONTAINER;
063: }
064:
065: /* (non-Javadoc)
066: * @see org.eclipse.jdt.internal.core.search.matching.PatternLocator#matchReportReference(org.eclipse.jdt.internal.compiler.ast.ASTNode, org.eclipse.jdt.core.IJavaElement, org.eclipse.jdt.internal.compiler.lookup.Binding, int, org.eclipse.jdt.internal.core.search.matching.MatchLocator)
067: */
068: protected void matchReportReference(ASTNode reference,
069: IJavaElement element, Binding elementBinding, int accuracy,
070: MatchLocator locator) throws CoreException {
071: if (elementBinding instanceof ReferenceBinding) {
072: ReferenceBinding referenceBinding = (ReferenceBinding) elementBinding;
073: if (referenceBinding.isClass()
074: && this .pattern.typeSuffix == IIndexConstants.INTERFACE_SUFFIX) {
075: // do not report class if expected types are only interfaces
076: return;
077: }
078: if (referenceBinding.isInterface()
079: && this .pattern.typeSuffix == IIndexConstants.CLASS_SUFFIX) {
080: // do not report interface if expected types are only classes
081: return;
082: }
083: }
084: super .matchReportReference(reference, element, elementBinding,
085: accuracy, locator);
086: }
087:
088: protected int referenceType() {
089: return IJavaElement.TYPE;
090: }
091:
092: public int resolveLevel(ASTNode node) {
093: if (!(node instanceof TypeReference))
094: return IMPOSSIBLE_MATCH;
095:
096: TypeReference typeRef = (TypeReference) node;
097: TypeBinding typeBinding = typeRef.resolvedType;
098: if (typeBinding instanceof ArrayBinding)
099: typeBinding = ((ArrayBinding) typeBinding).leafComponentType;
100: if (typeBinding instanceof ProblemReferenceBinding)
101: typeBinding = ((ProblemReferenceBinding) typeBinding)
102: .closestMatch();
103:
104: if (typeBinding == null)
105: return INACCURATE_MATCH;
106: return resolveLevelForType(this .pattern.super SimpleName,
107: this .pattern.super Qualification, typeBinding);
108: }
109:
110: public int resolveLevel(Binding binding) {
111: if (binding == null)
112: return INACCURATE_MATCH;
113: if (!(binding instanceof ReferenceBinding))
114: return IMPOSSIBLE_MATCH;
115:
116: ReferenceBinding type = (ReferenceBinding) binding;
117: int level = IMPOSSIBLE_MATCH;
118: if (this .pattern.super RefKind != SuperTypeReferencePattern.ONLY_SUPER_INTERFACES) {
119: level = resolveLevelForType(this .pattern.super SimpleName,
120: this .pattern.super Qualification, type.super class());
121: if (level == ACCURATE_MATCH)
122: return ACCURATE_MATCH;
123: }
124:
125: if (this .pattern.super RefKind != SuperTypeReferencePattern.ONLY_SUPER_CLASSES) {
126: ReferenceBinding[] super Interfaces = type.super Interfaces();
127: for (int i = 0, max = super Interfaces.length; i < max; i++) {
128: int newLevel = resolveLevelForType(
129: this .pattern.super SimpleName,
130: this .pattern.super Qualification,
131: super Interfaces[i]);
132: if (newLevel > level) {
133: if (newLevel == ACCURATE_MATCH)
134: return ACCURATE_MATCH;
135: level = newLevel;
136: }
137: }
138: }
139: return level;
140: }
141:
142: public String toString() {
143: return "Locator for " + this .pattern.toString(); //$NON-NLS-1$
144: }
145: }
|