use of org.eclipse.jdt.core.dom.ASTVisitor in project AutoRefactor by JnRouvignac.
the class ApplyRefactoringsJob method applyRefactoring.
/**
* Applies the refactorings provided inside the {@link AggregateASTVisitor} to the provided
* {@link ICompilationUnit}.
*
* @param document the document where the compilation unit comes from
* @param compilationUnit the compilation unit to refactor
* @param refactoring the {@link AggregateASTVisitor} to apply to the compilation unit
* @param options the Java project options used to compile the project
* @param monitor the progress monitor of the current job
* @throws Exception if any problem occurs
*
* @see <a
* href="http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.jdt.doc.isv%2Fguide%2Fjdt_api_manip.htm"
* >Eclipse JDT core - Manipulating Java code</a>
* @see <a href="
* http://help.eclipse.org/indigo/index.jsp?topic=/org.eclipse.platform.doc.isv/guide/workbench_cmd_menus.htm"
* > Eclipse Platform Plug-in Developer Guide > Plugging into the workbench
* > Basic workbench extension points using commands > org.eclipse.ui.menus</a>
* @see <a
* href="http://www.eclipse.org/articles/article.php?file=Article-JavaCodeManipulation_AST/index.html"
* >Abstract Syntax Tree > Write it down</a>
*/
public void applyRefactoring(IDocument document, ICompilationUnit compilationUnit, AggregateASTVisitor refactoring, JavaProjectOptions options, IProgressMonitor monitor) throws Exception {
// creation of DOM/AST from a ICompilationUnit
final ASTParser parser = ASTParser.newParser(AST.JLS4);
resetParser(compilationUnit, parser, options);
CompilationUnit astRoot = (CompilationUnit) parser.createAST(null);
int totalNbLoops = 0;
Set<ASTVisitor> lastLoopVisitors = Collections.emptySet();
int nbLoopsWithSameVisitors = 0;
while (true) {
if (totalNbLoops > 100) {
// Oops! Something went wrong.
final String errorMsg = "An infinite loop has been detected for file " + getFileName(astRoot) + "." + " A possible cause is that code is being incorrectly" + " refactored one way then refactored back to what it was." + " Fix the code before pursuing." + getPossibleCulprits(nbLoopsWithSameVisitors, lastLoopVisitors);
environment.getLogger().error(errorMsg, new IllegalStateException(astRoot, errorMsg));
break;
}
final RefactoringContext ctx = new RefactoringContext(compilationUnit, astRoot, options, monitor, environment);
refactoring.setRefactoringContext(ctx);
final Refactorings refactorings = refactoring.getRefactorings(astRoot);
if (!refactorings.hasRefactorings()) {
// we are done with applying the refactorings.
return;
}
// apply the refactorings and save the compilation unit
refactorings.applyTo(document);
final boolean hadUnsavedChanges = compilationUnit.hasUnsavedChanges();
compilationUnit.getBuffer().setContents(document.get());
// , null, null);
if (!hadUnsavedChanges) {
compilationUnit.save(null, true);
}
// I did not find any other way to directly modify the AST
// while still keeping the resolved type bindings working.
// Using astRoot.recordModifications() did not work:
// type bindings were lost. Is there a way to recover them?
// FIXME we should find a way to apply all the changes at
// the AST level and refresh the bindings
resetParser(compilationUnit, parser, options);
astRoot = (CompilationUnit) parser.createAST(null);
++totalNbLoops;
final Set<ASTVisitor> thisLoopVisitors = refactoring.getVisitorsContributingRefactoring();
if (!thisLoopVisitors.equals(lastLoopVisitors)) {
lastLoopVisitors = new HashSet<ASTVisitor>(thisLoopVisitors);
nbLoopsWithSameVisitors = 0;
} else {
++nbLoopsWithSameVisitors;
}
}
}
use of org.eclipse.jdt.core.dom.ASTVisitor in project liferay-ide by liferay.
the class JavaFileJDT method findImport.
@Override
public SearchResult findImport(String importName) {
List<SearchResult> searchResults = new ArrayList<>();
_ast.accept(new ASTVisitor() {
@Override
public boolean visit(ImportDeclaration node) {
String searchContext = node.getName().toString();
if (importName.equals(searchContext)) {
int startLine = _ast.getLineNumber(node.getName().getStartPosition());
int startOffset = node.getName().getStartPosition();
int endLine = _ast.getLineNumber(node.getName().getStartPosition() + node.getName().getLength());
int endOffset = node.getName().getStartPosition() + node.getName().getLength();
searchResults.add(createSearchResult(searchContext, startOffset, endOffset, startLine, endLine, true));
}
return false;
}
});
if (ListUtil.isNotEmpty(searchResults)) {
return searchResults.get(0);
}
return null;
}
use of org.eclipse.jdt.core.dom.ASTVisitor in project liferay-ide by liferay.
the class JavaFileJDT method findMethodDeclaration.
@Override
public List<SearchResult> findMethodDeclaration(String name, String[] params, String returnType) {
List<SearchResult> searchResults = new ArrayList<>();
_ast.accept(new ASTVisitor() {
@Override
public boolean visit(MethodDeclaration node) {
boolean sameParmSize = true;
boolean sameReturnType = true;
if (returnType != null) {
Type type = node.getReturnType2();
if (type != null) {
String returnTypeName = type.resolveBinding().getName();
if (!returnTypeName.equals(returnType)) {
sameReturnType = false;
}
} else {
sameReturnType = false;
}
}
String methodName = node.getName().toString();
List<?> parmsList = node.parameters();
if (name.equals(methodName) && (params.length == parmsList.size())) {
for (int i = 0; i < params.length; i++) {
Object x = parmsList.get(i);
if (!(params[i].trim().equals(x.toString().substring(0, params[i].trim().length())))) {
sameParmSize = false;
break;
}
}
} else {
sameParmSize = false;
}
if (sameParmSize && sameReturnType) {
int startLine = _ast.getLineNumber(node.getName().getStartPosition());
int startOffset = node.getName().getStartPosition();
node.accept(new ASTVisitor() {
@Override
public boolean visit(Block node) {
// SimpleName parent can not be MarkerAnnotation and
// SimpleType
// SingleVariableDeclaration node contains the
// parms's type
int endLine = _ast.getLineNumber(node.getStartPosition());
int endOffset = node.getStartPosition();
searchResults.add(createSearchResult(null, startOffset, endOffset, startLine, endLine, true));
return false;
}
});
}
return false;
}
});
return searchResults;
}
use of org.eclipse.jdt.core.dom.ASTVisitor in project liferay-ide by liferay.
the class JavaFileJDT method findMethodInvocations.
/**
* find the method invocations for a particular method on a given type or
* expression
*
* @param typeHint
* the type hint to use when matching expressions
* @param expressionValue
* the expression only value (no type hint)
* @param methodName
* the method name
* @return search results
*/
@Override
@SuppressWarnings("unchecked")
public List<SearchResult> findMethodInvocations(String typeHint, String expressionValue, String methodName, String[] methodParamTypes) {
List<SearchResult> searchResults = new ArrayList<>();
_ast.accept(new ASTVisitor() {
@Override
public boolean visit(MethodInvocation node) {
String methodNameValue = node.getName().toString();
Expression expression = node.getExpression();
ITypeBinding type = null;
if (expression != null) {
try {
type = _typeCache.get(expression).orElse(null);
} catch (ExecutionException ee) {
}
}
if (((methodName.equals(methodNameValue)) || ("*".equals(methodName))) && ((typeHint != null && type != null && type.getName().endsWith(typeHint)) || (typeHint == null && expression != null && expression.toString().equals(expressionValue)))) {
boolean argumentsMatch = false;
if (methodParamTypes != null) {
Expression[] argExpressions = ((List<Expression>) node.arguments()).toArray(new Expression[0]);
if (argExpressions.length == methodParamTypes.length) {
// args number matched
boolean possibleMatch = true;
// assume all types will match until we find
// otherwise
boolean typeMatched = true;
boolean typeUnresolved = false;
for (int i = 0; i < argExpressions.length; i++) {
Expression arg = argExpressions[i];
ITypeBinding argType = arg.resolveTypeBinding();
if (argType != null) {
if (_typeMatch(methodParamTypes[i], argType.getQualifiedName())) {
continue;
} else {
// type unmatched
possibleMatch = false;
typeMatched = false;
break;
}
} else {
possibleMatch = false;
// there are two cases :
// typeUnresolved : means that all resolved
// type is matched and there is unsolved
// type , need to set fullMatch false
// typeUnmatched : means that some resolved
// type is unmatched , no need to add
// SearchResult
// do not add searchResults now, just record
// the state and continue
// because there maybe unmatched type later
// which will break this case
typeUnresolved = true;
}
}
if (typeMatched && typeUnresolved) {
int startOffset = expression.getStartPosition();
int startLine = _ast.getLineNumber(startOffset);
int endOffset = node.getStartPosition() + node.getLength();
int endLine = _ast.getLineNumber(endOffset);
// can't resolve the type but args number
// matched , note that the last param is false
searchResults.add(createSearchResult(null, startOffset, endOffset, startLine, endLine, false));
}
if (possibleMatch) {
argumentsMatch = true;
}
}
} else // any method args types is OK without setting
// methodParamTypes
{
argumentsMatch = true;
}
if (argumentsMatch) {
int startOffset = expression.getStartPosition();
int startLine = _ast.getLineNumber(startOffset);
int endOffset = node.getStartPosition() + node.getLength();
int endLine = _ast.getLineNumber(endOffset);
boolean fullMatch = true;
if ((typeHint != null) && (type != null) && type.getName().endsWith(typeHint) && !type.getName().equals(typeHint)) {
fullMatch = false;
}
searchResults.add(createSearchResult(null, startOffset, endOffset, startLine, endLine, fullMatch));
}
}
return true;
}
});
return searchResults;
}
use of org.eclipse.jdt.core.dom.ASTVisitor in project liferay-ide by liferay.
the class JavaFileJDT method findSuperClass.
@Override
public List<SearchResult> findSuperClass(String superClassName) {
List<SearchResult> searchResults = new ArrayList<>();
_ast.accept(new ASTVisitor() {
@Override
public boolean visit(TypeDeclaration node) {
ITypeBinding superClass = null;
if (node.resolveBinding() != null) {
superClass = node.resolveBinding().getSuperclass();
if (superClass != null) {
String searchContext = superClass.getName();
if (searchContext.equals(superClassName)) {
int startLine = _ast.getLineNumber(node.getName().getStartPosition());
int startOffset = node.getName().getStartPosition();
int endLine = _ast.getLineNumber(node.getName().getStartPosition() + node.getName().getLength());
int endOffset = node.getName().getStartPosition() + node.getName().getLength();
searchResults.add(createSearchResult(searchContext, startOffset, endOffset, startLine, endLine, true));
}
}
}
return true;
}
});
return searchResults;
}
Aggregations