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, SubMonitor monitor) throws Exception {
// creation of DOM/AST from a ICompilationUnit
final ASTParser parser = ASTParser.newParser(AST.JLS8);
resetParser(compilationUnit, parser, options);
CompilationUnit astRoot = (CompilationUnit) parser.createAST(null);
final int maxIterations = 100;
int iterationCount = 0;
Set<ASTVisitor> lastLoopVisitors = Collections.emptySet();
int nbLoopsWithSameVisitors = 0;
monitor.setWorkRemaining(maxIterations);
while (true) {
if (iterationCount > maxIterations) {
// 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);
++iterationCount;
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 che by eclipse.
the class ConvertIterableLoopOperation method satisfiesPreconditions.
/**
* Is this proposal applicable?
*
* @return A status with severity <code>IStatus.Error</code> if not
* applicable
*/
@Override
public final IStatus satisfiesPreconditions() {
IStatus resultStatus = StatusInfo.OK_STATUS;
if (JavaModelUtil.is50OrHigher(getJavaProject())) {
resultStatus = checkExpressionCondition();
if (resultStatus.getSeverity() == IStatus.ERROR)
return resultStatus;
List<Expression> updateExpressions = getForStatement().updaters();
if (updateExpressions.size() == 1) {
resultStatus = new StatusInfo(IStatus.WARNING, Messages.format(FixMessages.ConvertIterableLoopOperation_RemoveUpdateExpression_Warning, BasicElementLabels.getJavaCodeString(updateExpressions.get(0).toString())));
} else if (updateExpressions.size() > 1) {
resultStatus = new StatusInfo(IStatus.WARNING, FixMessages.ConvertIterableLoopOperation_RemoveUpdateExpressions_Warning);
}
for (final Iterator<Expression> outer = getForStatement().initializers().iterator(); outer.hasNext(); ) {
final Expression initializer = outer.next();
if (initializer instanceof VariableDeclarationExpression) {
final VariableDeclarationExpression declaration = (VariableDeclarationExpression) initializer;
List<VariableDeclarationFragment> fragments = declaration.fragments();
if (fragments.size() != 1) {
//$NON-NLS-1$
return new StatusInfo(IStatus.ERROR, "");
} else {
final VariableDeclarationFragment fragment = fragments.get(0);
fragment.accept(new ASTVisitor() {
@Override
public final boolean visit(final MethodInvocation node) {
final IMethodBinding binding = node.resolveMethodBinding();
if (binding != null) {
final ITypeBinding type = binding.getReturnType();
if (type != null) {
final String qualified = type.getQualifiedName();
if (qualified.startsWith("java.util.Enumeration<") || qualified.startsWith("java.util.Iterator<")) {
//$NON-NLS-1$ //$NON-NLS-2$
final Expression qualifier = node.getExpression();
if (qualifier != null) {
final ITypeBinding resolved = qualifier.resolveTypeBinding();
if (resolved != null) {
//$NON-NLS-1$
final ITypeBinding iterable = getSuperType(resolved, "java.lang.Iterable");
if (iterable != null) {
fExpression = qualifier;
fIterable = resolved;
}
}
} else {
final ITypeBinding declaring = binding.getDeclaringClass();
if (declaring != null) {
//$NON-NLS-1$
final ITypeBinding superBinding = getSuperType(declaring, "java.lang.Iterable");
if (superBinding != null) {
fIterable = superBinding;
fThis = true;
}
}
}
}
}
}
return true;
}
@Override
public final boolean visit(final VariableDeclarationFragment node) {
final IVariableBinding binding = node.resolveBinding();
if (binding != null) {
final ITypeBinding type = binding.getType();
if (type != null) {
//$NON-NLS-1$
ITypeBinding iterator = getSuperType(type, "java.util.Iterator");
if (iterator != null)
fIteratorVariable = binding;
else {
//$NON-NLS-1$
iterator = getSuperType(type, "java.util.Enumeration");
if (iterator != null)
fIteratorVariable = binding;
}
}
}
return true;
}
});
}
}
}
final Statement statement = getForStatement().getBody();
final boolean[] otherInvocationThenNext = new boolean[] { false };
final int[] nextInvocationCount = new int[] { 0 };
if (statement != null && fIteratorVariable != null) {
final ITypeBinding elementType = getElementType(fIteratorVariable.getType());
statement.accept(new ASTVisitor() {
@Override
public boolean visit(SimpleName node) {
IBinding nodeBinding = node.resolveBinding();
if (fElementVariable != null && fElementVariable.equals(nodeBinding)) {
fMakeFinal = false;
}
if (nodeBinding == fIteratorVariable) {
if (node.getLocationInParent() == MethodInvocation.EXPRESSION_PROPERTY) {
MethodInvocation invocation = (MethodInvocation) node.getParent();
String name = invocation.getName().getIdentifier();
if (name.equals("next") || name.equals("nextElement")) {
//$NON-NLS-1$ //$NON-NLS-2$
nextInvocationCount[0]++;
Expression left = null;
if (invocation.getLocationInParent() == Assignment.RIGHT_HAND_SIDE_PROPERTY) {
left = ((Assignment) invocation.getParent()).getLeftHandSide();
} else if (invocation.getLocationInParent() == VariableDeclarationFragment.INITIALIZER_PROPERTY) {
left = ((VariableDeclarationFragment) invocation.getParent()).getName();
}
return visitElementVariable(left);
}
}
otherInvocationThenNext[0] = true;
}
return true;
}
private boolean visitElementVariable(final Expression node) {
if (node != null) {
final ITypeBinding binding = node.resolveTypeBinding();
if (binding != null && elementType.equals(binding)) {
if (node instanceof Name) {
final Name name = (Name) node;
final IBinding result = name.resolveBinding();
if (result != null) {
fOccurrences.add(node);
fElementVariable = result;
return false;
}
} else if (node instanceof FieldAccess) {
final FieldAccess access = (FieldAccess) node;
final IBinding result = access.resolveFieldBinding();
if (result != null) {
fOccurrences.add(node);
fElementVariable = result;
return false;
}
}
}
}
return true;
}
});
if (otherInvocationThenNext[0])
return ERROR_STATUS;
if (nextInvocationCount[0] > 1)
return ERROR_STATUS;
if (fElementVariable != null) {
statement.accept(new ASTVisitor() {
@Override
public final boolean visit(final VariableDeclarationFragment node) {
if (node.getInitializer() instanceof NullLiteral) {
SimpleName name = node.getName();
if (elementType.equals(name.resolveTypeBinding()) && fElementVariable.equals(name.resolveBinding())) {
fOccurrences.add(name);
}
}
return true;
}
});
}
}
final ASTNode root = getForStatement().getRoot();
if (root != null) {
root.accept(new ASTVisitor() {
@Override
public final boolean visit(final ForStatement node) {
return false;
}
@Override
public final boolean visit(final SimpleName node) {
final IBinding binding = node.resolveBinding();
if (binding != null && binding.equals(fElementVariable))
fAssigned = true;
return false;
}
});
}
}
if ((fExpression != null || fThis) && fIterable != null && fIteratorVariable != null && !fAssigned) {
return resultStatus;
} else {
return ERROR_STATUS;
}
}
use of org.eclipse.jdt.core.dom.ASTVisitor in project flux by eclipse.
the class ASTNodes method getQualifiedTypeName.
/**
* Returns the (potentially qualified) name of a type, followed by array dimensions.
* Skips type arguments and type annotations.
*
* @param type a type that has a name
* @return the name, followed by array dimensions
* @since 3.10
*/
public static String getQualifiedTypeName(Type type) {
final StringBuffer buffer = new StringBuffer();
ASTVisitor visitor = new ASTVisitor() {
@Override
public boolean visit(SimpleType node) {
buffer.append(node.getName().getFullyQualifiedName());
return false;
}
@Override
public boolean visit(QualifiedType node) {
node.getQualifier().accept(this);
buffer.append('.');
buffer.append(node.getName().getIdentifier());
return false;
}
@Override
public boolean visit(NameQualifiedType node) {
buffer.append(node.getQualifier().getFullyQualifiedName());
buffer.append('.');
buffer.append(node.getName().getIdentifier());
return false;
}
@Override
public boolean visit(ParameterizedType node) {
node.getType().accept(this);
return false;
}
@Override
public void endVisit(ArrayType node) {
for (int i = 0; i < node.dimensions().size(); i++) {
//$NON-NLS-1$
buffer.append("[]");
}
}
};
type.accept(visitor);
return buffer.toString();
}
use of org.eclipse.jdt.core.dom.ASTVisitor in project che by eclipse.
the class ImportRemover method divideTypeRefs.
private void divideTypeRefs(List<SimpleName> importNames, List<SimpleName> staticNames, List<SimpleName> removedRefs, List<SimpleName> unremovedRefs) {
final List<int[]> removedStartsEnds = new ArrayList<int[]>();
fRoot.accept(new ASTVisitor(true) {
int fRemovingStart = -1;
@Override
public void preVisit(ASTNode node) {
Object property = node.getProperty(PROPERTY_KEY);
if (property == REMOVED) {
if (fRemovingStart == -1) {
fRemovingStart = node.getStartPosition();
} else {
/*
* Bug in client code: REMOVED node should not be nested inside another REMOVED node without
* an intermediate RETAINED node.
* Drop REMOVED property to prevent problems later (premature end of REMOVED section).
*/
node.setProperty(PROPERTY_KEY, null);
}
} else if (property == RETAINED) {
if (fRemovingStart != -1) {
removedStartsEnds.add(new int[] { fRemovingStart, node.getStartPosition() });
fRemovingStart = -1;
} else {
/*
* Bug in client code: RETAINED node should not be nested inside another RETAINED node without
* an intermediate REMOVED node and must have an enclosing REMOVED node.
* Drop RETAINED property to prevent problems later (premature restart of REMOVED section).
*/
node.setProperty(PROPERTY_KEY, null);
}
}
super.preVisit(node);
}
@Override
public void postVisit(ASTNode node) {
Object property = node.getProperty(PROPERTY_KEY);
if (property == RETAINED) {
int end = node.getStartPosition() + node.getLength();
fRemovingStart = end;
} else if (property == REMOVED) {
if (fRemovingStart != -1) {
int end = node.getStartPosition() + node.getLength();
removedStartsEnds.add(new int[] { fRemovingStart, end });
fRemovingStart = -1;
}
}
super.postVisit(node);
}
});
for (Iterator<SimpleName> iterator = importNames.iterator(); iterator.hasNext(); ) {
SimpleName name = iterator.next();
if (isInRemoved(name, removedStartsEnds))
removedRefs.add(name);
else
unremovedRefs.add(name);
}
for (Iterator<SimpleName> iterator = staticNames.iterator(); iterator.hasNext(); ) {
SimpleName name = iterator.next();
if (isInRemoved(name, removedStartsEnds))
removedRefs.add(name);
else
unremovedRefs.add(name);
}
for (Iterator<ImportDeclaration> iterator = fInlinedStaticImports.iterator(); iterator.hasNext(); ) {
ImportDeclaration importDecl = iterator.next();
Name name = importDecl.getName();
if (name instanceof QualifiedName)
name = ((QualifiedName) name).getName();
removedRefs.add((SimpleName) name);
}
}
use of org.eclipse.jdt.core.dom.ASTVisitor in project processing by processing.
the class ASTUtils method findAllOccurrences.
protected static List<SimpleName> findAllOccurrences(ASTNode root, String bindingKey) {
List<SimpleName> occurences = new ArrayList<>();
root.getRoot().accept(new ASTVisitor() {
@Override
public boolean visit(SimpleName name) {
IBinding binding = resolveBinding(name);
if (binding != null && bindingKey.equals(binding.getKey())) {
occurences.add(name);
}
return super.visit(name);
}
});
return occurences;
}
Aggregations