package org.eclipse.jdt.internal.core; | |
/* | |
* (c) Copyright IBM Corp. 2000, 2001. | |
* All Rights Reserved. | |
*/ | |
import org.eclipse.core.resources.*; | |
import org.eclipse.jdt.internal.compiler.IProblem; | |
import org.eclipse.jdt.internal.codeassist.ISelectionRequestor; | |
import org.eclipse.jdt.internal.codeassist.SelectionEngine; | |
import org.eclipse.jdt.core.*; | |
/** | |
* Implementation of <code>ISelectionRequestor</code> to assist with | |
* code resolve in a compilation unit. Translates names to elements. | |
*/ | |
public class SelectionRequestor implements ISelectionRequestor { | |
/** | |
* The name lookup facility used to resolve packages | |
*/ | |
protected INameLookup fNameLookup= null; | |
/** | |
* Fix for 1FVXGDK | |
* | |
* The compilation unit we are resolving in | |
*/ | |
protected IJavaElement fCodeResolve; | |
/** | |
* The collection of resolved elements. | |
*/ | |
protected IJavaElement[] fElements= fgEmptyElements; | |
/** | |
* Empty collection used for efficiency. | |
*/ | |
protected static IJavaElement[] fgEmptyElements = new IJavaElement[]{}; | |
/** | |
* Creates a selection requestor that uses that given | |
* name lookup facility to resolve names. | |
* | |
* Fix for 1FVXGDK | |
*/ | |
public SelectionRequestor(INameLookup nameLookup, IJavaElement codeResolve) { | |
super(); | |
fNameLookup = nameLookup; | |
fCodeResolve = codeResolve; | |
} | |
/** | |
* Resolve the binary method | |
* | |
* fix for 1FWFT6Q | |
*/ | |
protected void acceptBinaryMethod(IType type, char[] selector, char[][] parameterPackageNames, char[][] parameterTypeNames) { | |
String[] parameterTypes= null; | |
if (parameterTypeNames != null) { | |
parameterTypes= new String[parameterTypeNames.length]; | |
for (int i= 0, max = parameterTypeNames.length; i < max; i++) { | |
String pkg = IPackageFragment.DEFAULT_PACKAGE_NAME; | |
if (parameterPackageNames[i] != null && parameterPackageNames[i].length > 0) { | |
pkg = new String(parameterPackageNames[i]) + "."; //$NON-NLS-1$ | |
} | |
parameterTypes[i]= Signature.createTypeSignature( | |
pkg + new String(parameterTypeNames[i]), true); | |
} | |
} | |
IMethod method= type.getMethod(new String(selector), parameterTypes); | |
if (method.exists()) { | |
fElements = growAndAddToArray(fElements, method); | |
} | |
} | |
/** | |
* Resolve the class. | |
*/ | |
public void acceptClass(char[] packageName, char[] className, boolean needQualification) { | |
acceptType(packageName, className, INameLookup.ACCEPT_CLASSES, needQualification); | |
} | |
/** | |
* Do nothing. | |
*/ | |
public void acceptError(IProblem error) {} | |
/** | |
* Resolve the field. | |
*/ | |
public void acceptField(char[] declaringTypePackageName, char[] declaringTypeName, char[] name) { | |
IType type= resolveType(declaringTypePackageName, declaringTypeName, | |
INameLookup.ACCEPT_CLASSES | INameLookup.ACCEPT_INTERFACES); | |
if (type != null) { | |
IField field= type.getField(new String(name)); | |
if (field.exists()) { | |
fElements= growAndAddToArray(fElements, field); | |
} | |
} | |
} | |
/** | |
* Resolve the interface | |
*/ | |
public void acceptInterface(char[] packageName, char[] interfaceName, boolean needQualification) { | |
acceptType(packageName, interfaceName, INameLookup.ACCEPT_INTERFACES, needQualification); | |
} | |
/** | |
* Resolve the method | |
*/ | |
public void acceptMethod(char[] declaringTypePackageName, char[] declaringTypeName, char[] selector, char[][] parameterPackageNames, char[][] parameterTypeNames) { | |
IType type= resolveType(declaringTypePackageName, declaringTypeName, | |
INameLookup.ACCEPT_CLASSES | INameLookup.ACCEPT_INTERFACES); | |
// fix for 1FWFT6Q | |
if (type != null) { | |
if (type.isBinary()) { | |
acceptBinaryMethod(type, selector, parameterPackageNames, parameterTypeNames); | |
} else { | |
acceptSourceMethod(type, selector, parameterPackageNames, parameterTypeNames); | |
} | |
} | |
} | |
/** | |
* Resolve the package | |
*/ | |
public void acceptPackage(char[] packageName) { | |
IPackageFragment[] pkgs = fNameLookup.findPackageFragments(new String(packageName), false); | |
if (pkgs != null) { | |
for (int i = 0, length = pkgs.length; i < length; i++) { | |
fElements = growAndAddToArray(fElements, pkgs[i]); | |
} | |
} | |
} | |
/** | |
* Resolve the source method | |
* | |
* fix for 1FWFT6Q | |
*/ | |
protected void acceptSourceMethod(IType type, char[] selector, char[][] parameterPackageNames, char[][] parameterTypeNames) { | |
String name = new String(selector); | |
IMethod[] methods = null; | |
try { | |
methods = type.getMethods(); | |
} catch (JavaModelException e) { | |
return; | |
} | |
IJavaElement[] matches = new IJavaElement[] {}; | |
for (int i = 0; i < methods.length; i++) { | |
if (methods[i].getElementName().equals(name) && methods[i].getParameterTypes().length == parameterTypeNames.length) { | |
matches = growAndAddToArray(matches, methods[i]); | |
} | |
} | |
// if no matches, nothing to report | |
if (matches.length == 0) { | |
return; | |
} | |
// if there is only one match, we've got it | |
if (matches.length == 1) { | |
fElements = growAndAddToArray(fElements, matches[0]); | |
return; | |
} | |
// more than one match - must match simple parameter types | |
for (int i = 0; i < matches.length; i++) { | |
IMethod method= (IMethod)matches[i]; | |
String[] signatures = method.getParameterTypes(); | |
boolean match= true; | |
for (int p = 0; p < signatures.length; p++) { | |
String simpleName= Signature.getSimpleName(Signature.toString(signatures[p])); | |
if (!simpleName.equals(new String(parameterTypeNames[p]))) { | |
match = false; | |
break; | |
} | |
} | |
if (match) { | |
fElements = growAndAddToArray(fElements, method); | |
} | |
} | |
} | |
/** | |
* Resolve the type, adding to the resolved elements. | |
*/ | |
protected void acceptType(char[] packageName, char[] typeName, int acceptFlags, boolean needQualification) { | |
IType type= resolveType(packageName, typeName, acceptFlags); | |
if (type != null) { | |
fElements= growAndAddToArray(fElements, type); | |
} | |
} | |
/** | |
* Returns the resolved elements. | |
*/ | |
public IJavaElement[] getElements() { | |
return fElements; | |
} | |
/** | |
* Adds the new element to a new array that contains all of the elements of the old array. | |
* Returns the new array. | |
*/ | |
protected IJavaElement[] growAndAddToArray(IJavaElement[] array, IJavaElement addition) { | |
IJavaElement[] old = array; | |
array = new IJavaElement[old.length + 1]; | |
System.arraycopy(old, 0, array, 0, old.length); | |
array[old.length] = addition; | |
return array; | |
} | |
/** | |
* Resolve the type | |
*/ | |
protected IType resolveType(char[] packageName, char[] typeName, int acceptFlags) { | |
//fix for 1FVXGDK | |
IType type= null; | |
if (packageName == null || packageName.length == 0) { | |
// default package | |
type= fNameLookup.findType(new String(typeName), false, acceptFlags); | |
} else { | |
IPackageFragment[] pkgs = fNameLookup.findPackageFragments(new String(packageName), false); | |
if (pkgs != null) { | |
for (int i = 0, length = pkgs.length; i < length; i++) { | |
type= fNameLookup.findType(new String(typeName), pkgs[i], false, acceptFlags); | |
if (type != null) break; | |
} | |
} | |
} | |
if (type == null) { | |
String pName= IPackageFragment.DEFAULT_PACKAGE_NAME; | |
if (packageName != null) { | |
pName = new String(packageName); | |
} | |
if (fCodeResolve != null && fCodeResolve.getParent().getElementName().equals(pName)) { | |
// look inside the type in which we are resolving in | |
String tName= new String(typeName); | |
tName = tName.replace('.','$'); | |
IType[] allTypes= null; | |
try { | |
java.util.Vector v = ((JavaElement)fCodeResolve).getChildrenOfType(IJavaElement.TYPE); | |
allTypes = new IType[v.size()]; | |
v.copyInto(allTypes); | |
} catch (JavaModelException e) { | |
return null; | |
} | |
for (int i= 0; i < allTypes.length; i++) { | |
if (allTypes[i].getTypeQualifiedName().equals(tName)) { | |
return allTypes[i]; | |
} | |
} | |
} | |
} | |
return type; | |
} | |
} |