blob: 203c17a9e8e8c662e1445d7c8c264f018e5bfd37 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2007 Oracle. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0, which accompanies this distribution
* and is available at http://www.eclipse.org/legal/epl-v10.html.
*
* Contributors:
* Oracle - initial API and implementation
******************************************************************************/
package org.eclipse.jpt.core.internal.jdtutility;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IImportDeclaration;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.compiler.CategorizedProblem;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.internal.codeassist.ISelectionRequestor;
import org.eclipse.jdt.internal.codeassist.SelectionEngine;
import org.eclipse.jdt.internal.core.DefaultWorkingCopyOwner;
import org.eclipse.jdt.internal.core.JavaProject;
import org.eclipse.jdt.internal.core.SearchableEnvironment;
import org.eclipse.jpt.core.internal.JptCorePlugin;
public class JDTTools {
/**
* add a "normal" import, as opposed to a "static" import
*/
public static IImportDeclaration addImport(ICompilationUnit compilationUnit, String importElement) {
return addImport(compilationUnit, importElement, Flags.AccDefault);
}
/**
* this doesn't work yet... see eclipse bugzilla 143684
*/
public static IImportDeclaration addStaticImport(ICompilationUnit compilationUnit, String importElement) {
return addImport(compilationUnit, importElement, Flags.AccStatic);
}
public static IImportDeclaration addImport(ICompilationUnit compilationUnit, String importElement, int flags) {
try {
return compilationUnit.createImport(importElement, null, flags, null); // null = place at end of import list; null = no progress monitor
} catch (JavaModelException ex) {
throw new RuntimeException(ex);
}
}
/**
* Build an AST for the specified member's compilation unit or class file.
*/
public static CompilationUnit createASTRoot(IMember member) {
return (member.isBinary()) ?
createASTRoot(member.getClassFile()) // the class file must have a source attachment
:
createASTRoot(member.getCompilationUnit());
}
public static CompilationUnit createASTRoot(IClassFile classFile) {
ASTParser parser = ASTParser.newParser(AST.JLS3);
parser.setSource(classFile);
return (CompilationUnit) parser.createAST(null);
}
public static CompilationUnit createASTRoot(ICompilationUnit compilationUnit) {
ASTParser parser = ASTParser.newParser(AST.JLS3);
parser.setSource(compilationUnit);
return (CompilationUnit) parser.createAST(null);
}
public static IType findType(String packageName, String qualifiedTypeName, IJavaProject javaProject) {
try {
if (javaProject != null) {
return javaProject.findType(packageName, qualifiedTypeName.replace('$', '.'));
}
}
catch (JavaModelException jme) {
JptCorePlugin.log(jme);
}
return null;
}
/**
* Resolve the specified signature in the scope of the specified jdt type.
* Return the fully-qualified type name or return null if it cannot be
* resolved unambiguously.
*/
public static String resolveSignature(String signature, IType type) {
String elementSignature = Signature.getElementType(signature);
if (signatureIsPrimitive(elementSignature)) {
return Signature.toString(signature); // no need to resolve primitives
}
String elementTypeName = Signature.toString(elementSignature);
elementTypeName = resolve(elementTypeName, type);
if (elementTypeName == null) {
return null; // unable to resolve type
}
int arrayCount = Signature.getArrayCount(signature);
if (arrayCount == 0) {
return elementTypeName;
}
StringBuffer sb = new StringBuffer(elementTypeName.length() + 2*arrayCount);
sb.append(elementTypeName);
for (int i = arrayCount; i-- > 0; ) {
sb.append('[').append(']');
}
return sb.toString();
}
/**
* Resolve the specified type name in the scope of the specified jdt type.
* Return the fully-qualified type name or return null if it cannot be
* resolved unambiguously.
*/
public static String resolve(String typeName, IType type) {
try {
return resolve_(typeName, type);
} catch (JavaModelException ex) {
throw new RuntimeException(ex);
}
}
private static String resolve_(String typeName, IType type) throws JavaModelException {
String[][] resolvedTypes = type.resolveType(typeName);
// if more than one resolved type is returned, the type name is ambiguous
if (resolvedTypes == null) {
return null;
}
if (resolvedTypes.length > 1) {
return null;
}
return resolvedTypes[0][0] + "." + resolvedTypes[0][1];
}
public static boolean signatureIsPrimitive(String signature) {
return Signature.getTypeSignatureKind(signature) == Signature.BASE_TYPE_SIGNATURE;
}
public static String resolveEnum(ICompilationUnit sourceUnit, Expression enumExpression) {
return resolveEnum(sourceUnit, enumExpression.getStartPosition(), enumExpression.getStartPosition() + enumExpression.getLength() - 1);
}
public static String resolveEnum(ICompilationUnit sourceUnit, int enumSourceStart, int enumSourceEnd) {
try {
return resolveEnum_(sourceUnit, enumSourceStart, enumSourceEnd);
} catch (JavaModelException ex) {
throw new RuntimeException(ex);
}
}
private static String resolveEnum_(ICompilationUnit sourceUnit, int enumSourceStart, int enumSourceEnd) throws JavaModelException {
String[][] resolvedEnums = resolveField_((org.eclipse.jdt.internal.core.CompilationUnit) sourceUnit, enumSourceStart, enumSourceEnd);
// if more than one resolved enum is returned, the enum name is ambiguous
if (resolvedEnums == null) {
return null;
}
if (resolvedEnums.length > 1) {
return null;
}
return resolvedEnums[0][0] + "." + resolvedEnums[0][1] + "." + resolvedEnums[0][2];
}
// code lifted from SourceType.resolveType(String, WorkingCopyOwner)
private static String[][] resolveField_(org.eclipse.jdt.internal.core.CompilationUnit sourceUnit, int selectionSourceStart, int selectionSourceEnd) throws JavaModelException {
class TypeResolveRequestor implements ISelectionRequestor {
String[][] answers = null;
public void acceptType(char[] packageName, char[] tName, int modifiers, boolean isDeclaration, char[] uniqueKey, int start, int end) {
// ignore
}
public void acceptError(CategorizedProblem error) {
// ignore
}
public void acceptField(char[] declaringTypePackageName, char[] declaringTypeName, char[] fieldName, boolean isDeclaration, char[] uniqueKey, int start, int end) {
String[] answer = new String[] {new String(declaringTypePackageName), new String(declaringTypeName), new String(fieldName) };
if (this.answers == null) {
this.answers = new String[][]{ answer };
} else {
int len = this.answers.length;
System.arraycopy(this.answers, 0, this.answers = new String[len+1][], 0, len);
this.answers[len] = answer;
}
}
public void acceptMethod(char[] declaringTypePackageName, char[] declaringTypeName, String enclosingDeclaringTypeSignature, char[] selector, char[][] parameterPackageNames, char[][] parameterTypeNames, String[] parameterSignatures, char[][] typeParameterNames, char[][][] typeParameterBoundNames, boolean isConstructor, boolean isDeclaration, char[] uniqueKey, int start, int end) {
// ignore
}
public void acceptPackage(char[] packageName){
// ignore
}
public void acceptTypeParameter(char[] declaringTypePackageName, char[] declaringTypeName, char[] typeParameterName, boolean isDeclaration, int start, int end) {
// ignore
}
public void acceptMethodTypeParameter(char[] declaringTypePackageName, char[] declaringTypeName, char[] selector, int selectorStart, int selcetorEnd, char[] typeParameterName, boolean isDeclaration, int start, int end) {
// ignore
}
}
TypeResolveRequestor requestor = new TypeResolveRequestor();
JavaProject project = (JavaProject) sourceUnit.getJavaProject();
SearchableEnvironment environment = project.newSearchableNameEnvironment(DefaultWorkingCopyOwner.PRIMARY);
SelectionEngine engine = new SelectionEngine(environment, requestor, project.getOptions(true));
engine.select(sourceUnit, selectionSourceStart, selectionSourceEnd);
return requestor.answers;
}
}