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.util;
011:
012: import org.eclipse.jdt.core.*;
013: import org.eclipse.jdt.core.IJavaElement;
014: import org.eclipse.jdt.core.IMethod;
015: import org.eclipse.jdt.core.IType;
016: import org.eclipse.jdt.core.compiler.CharOperation;
017: import org.eclipse.jdt.internal.compiler.ASTVisitor;
018: import org.eclipse.jdt.internal.compiler.ast.*;
019: import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
020: import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
021: import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
022: import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
023: import org.eclipse.jdt.internal.core.SourceRefElement;
024: import org.eclipse.jdt.internal.core.SourceType;
025:
026: /**
027: * Finds an ASTNode given an IJavaElement in a CompilationUnitDeclaration
028: */
029: public class ASTNodeFinder {
030: private CompilationUnitDeclaration unit;
031:
032: public ASTNodeFinder(CompilationUnitDeclaration unit) {
033: this .unit = unit;
034: }
035:
036: /*
037: * Finds the FieldDeclaration in the given ast corresponding to the given field handle.
038: * Returns null if not found.
039: */
040: public FieldDeclaration findField(IField fieldHandle) {
041: TypeDeclaration typeDecl = findType((IType) fieldHandle
042: .getParent());
043: if (typeDecl == null)
044: return null;
045: FieldDeclaration[] fields = typeDecl.fields;
046: if (fields != null) {
047: char[] fieldName = fieldHandle.getElementName()
048: .toCharArray();
049: for (int i = 0, length = fields.length; i < length; i++) {
050: FieldDeclaration field = fields[i];
051: if (CharOperation.equals(fieldName, field.name)) {
052: return field;
053: }
054: }
055: }
056: return null;
057: }
058:
059: /*
060: * Finds the Initializer in the given ast corresponding to the given initializer handle.
061: * Returns null if not found.
062: */
063: public Initializer findInitializer(IInitializer initializerHandle) {
064: TypeDeclaration typeDecl = findType((IType) initializerHandle
065: .getParent());
066: if (typeDecl == null)
067: return null;
068: FieldDeclaration[] fields = typeDecl.fields;
069: if (fields != null) {
070: int occurenceCount = ((SourceRefElement) initializerHandle).occurrenceCount;
071: for (int i = 0, length = fields.length; i < length; i++) {
072: FieldDeclaration field = fields[i];
073: if (field instanceof Initializer
074: && --occurenceCount == 0) {
075: return (Initializer) field;
076: }
077: }
078: }
079: return null;
080: }
081:
082: /*
083: * Finds the AbstractMethodDeclaration in the given ast corresponding to the given method handle.
084: * Returns null if not found.
085: */
086: public AbstractMethodDeclaration findMethod(IMethod methodHandle) {
087: TypeDeclaration typeDecl = findType((IType) methodHandle
088: .getParent());
089: if (typeDecl == null)
090: return null;
091: AbstractMethodDeclaration[] methods = typeDecl.methods;
092: if (methods != null) {
093: char[] selector = methodHandle.getElementName()
094: .toCharArray();
095: String[] parameterTypeSignatures = methodHandle
096: .getParameterTypes();
097: int parameterCount = parameterTypeSignatures.length;
098: nextMethod: for (int i = 0, length = methods.length; i < length; i++) {
099: AbstractMethodDeclaration method = methods[i];
100: if (CharOperation.equals(selector, method.selector)) {
101: Argument[] args = method.arguments;
102: int argsLength = args == null ? 0 : args.length;
103: if (argsLength == parameterCount) {
104: for (int j = 0; j < parameterCount; j++) {
105: TypeReference type = args[j].type;
106: String signature = Util.typeSignature(type);
107: if (!signature
108: .equals(parameterTypeSignatures[j])) {
109: continue nextMethod;
110: }
111: }
112: return method;
113: }
114: }
115: }
116: }
117: return null;
118: }
119:
120: /*
121: * Finds the TypeDeclaration in the given ast corresponding to the given type handle.
122: * Returns null if not found.
123: */
124: public TypeDeclaration findType(IType typeHandle) {
125: IJavaElement parent = typeHandle.getParent();
126: final char[] typeName = typeHandle.getElementName()
127: .toCharArray();
128: final int occurenceCount = ((SourceType) typeHandle).occurrenceCount;
129: final boolean findAnonymous = typeName.length == 0;
130: class Visitor extends ASTVisitor {
131: TypeDeclaration result;
132: int count = 0;
133:
134: public boolean visit(TypeDeclaration typeDeclaration,
135: BlockScope scope) {
136: if (result != null)
137: return false;
138: if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) {
139: if (findAnonymous && ++count == occurenceCount) {
140: result = typeDeclaration;
141: }
142: } else {
143: if (!findAnonymous
144: && CharOperation.equals(typeName,
145: typeDeclaration.name)) {
146: result = typeDeclaration;
147: }
148: }
149: return false; // visit only one level
150: }
151: }
152: switch (parent.getElementType()) {
153: case IJavaElement.COMPILATION_UNIT:
154: TypeDeclaration[] types = this .unit.types;
155: if (types != null) {
156: for (int i = 0, length = types.length; i < length; i++) {
157: TypeDeclaration type = types[i];
158: if (CharOperation.equals(typeName, type.name)) {
159: return type;
160: }
161: }
162: }
163: break;
164: case IJavaElement.TYPE:
165: TypeDeclaration parentDecl = findType((IType) parent);
166: if (parentDecl == null)
167: return null;
168: types = parentDecl.memberTypes;
169: if (types != null) {
170: for (int i = 0, length = types.length; i < length; i++) {
171: TypeDeclaration type = types[i];
172: if (CharOperation.equals(typeName, type.name)) {
173: return type;
174: }
175: }
176: }
177: break;
178: case IJavaElement.FIELD:
179: FieldDeclaration fieldDecl = findField((IField) parent);
180: if (fieldDecl == null)
181: return null;
182: Visitor visitor = new Visitor();
183: fieldDecl.traverse(visitor, null);
184: return visitor.result;
185: case IJavaElement.INITIALIZER:
186: Initializer initializer = findInitializer((IInitializer) parent);
187: if (initializer == null)
188: return null;
189: visitor = new Visitor();
190: initializer.traverse(visitor, null);
191: return visitor.result;
192: case IJavaElement.METHOD:
193: AbstractMethodDeclaration methodDecl = findMethod((IMethod) parent);
194: if (methodDecl == null)
195: return null;
196: visitor = new Visitor();
197: methodDecl.traverse(visitor, (ClassScope) null);
198: return visitor.result;
199: }
200: return null;
201: }
202: }
|