/******************************************************************************* * Copyright (c) 2005, 2011 IBM Corporation and others. * 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: * IBM Corporation - initial API and implementation *******************************************************************************/ /** * **/ package org.eclipse.che.ide.ext.java.jdt.internal.corext.fix; import org.eclipse.che.ide.ext.java.jdt.core.dom.CompilationUnit; import org.eclipse.che.ide.ext.java.jdt.core.dom.ForStatement; import org.eclipse.che.ide.ext.java.jdt.internal.corext.dom.GenericVisitor; import org.eclipse.che.ide.ext.java.jdt.text.Document; import org.eclipse.che.ide.runtime.IStatus; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; public class ConvertLoopFix extends CompilationUnitRewriteOperationsFix { private final static class ControlStatementFinder extends GenericVisitor { private final List<ConvertLoopOperation> fResult; private final HashMap<ForStatement, String> fUsedNames; private final boolean fFindForLoopsToConvert; private final boolean fConvertIterableForLoops; private final boolean fMakeFinal; public ControlStatementFinder(boolean findForLoopsToConvert, boolean convertIterableForLoops, boolean makeFinal, List<ConvertLoopOperation> resultingCollection) { fFindForLoopsToConvert = findForLoopsToConvert; fConvertIterableForLoops = convertIterableForLoops; fMakeFinal = makeFinal; fResult = resultingCollection; fUsedNames = new HashMap<ForStatement, String>(); } /* (non-Javadoc) * @see org.eclipse.jdt.internal.corext.dom.GenericVisitor#visit(org.eclipse.jdt.core.dom.ForStatement) */ @Override public boolean visit(ForStatement node) { if (fFindForLoopsToConvert || fConvertIterableForLoops) { ForStatement current = node; ConvertLoopOperation operation = getConvertOperation(current); ConvertLoopOperation oldOperation = null; while (operation != null) { if (oldOperation == null) { fResult.add(operation); } else { oldOperation.setBodyConverter(operation); } if (current.getBody() instanceof ForStatement) { current = (ForStatement)current.getBody(); oldOperation = operation; operation = getConvertOperation(current); } else { operation = null; } } current.getBody().accept(this); return false; } return super.visit(node); } private ConvertLoopOperation getConvertOperation(ForStatement node) { Collection<String> usedNamesCollection = fUsedNames.values(); String[] usedNames = usedNamesCollection.toArray(new String[usedNamesCollection.size()]); ConvertLoopOperation convertForLoopOperation = new ConvertForLoopOperation(node, usedNames, fMakeFinal); if (convertForLoopOperation.satisfiesPreconditions().isOK()) { if (fFindForLoopsToConvert) { fUsedNames.put(node, convertForLoopOperation.getIntroducedVariableName()); return convertForLoopOperation; } } else if (fConvertIterableForLoops) { ConvertLoopOperation iterableConverter = new ConvertIterableLoopOperation(node, usedNames, fMakeFinal); if (iterableConverter.satisfiesPreconditions().isOK()) { fUsedNames.put(node, iterableConverter.getIntroducedVariableName()); return iterableConverter; } } return null; } /* (non-Javadoc) * @see org.eclipse.jdt.internal.corext.dom.GenericVisitor#endVisit(org.eclipse.jdt.core.dom.ForStatement) */ @Override public void endVisit(ForStatement node) { if (fFindForLoopsToConvert || fConvertIterableForLoops) { fUsedNames.remove(node); } super.endVisit(node); } } public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit, boolean convertForLoops, boolean convertIterableForLoops, boolean makeFinal, Document document) { // if (!JavaModelUtil.is50OrHigher(compilationUnit.getJavaElement().getJavaProject())) // return null; if (!convertForLoops && !convertIterableForLoops) return null; List<ConvertLoopOperation> operations = new ArrayList<ConvertLoopOperation>(); ControlStatementFinder finder = new ControlStatementFinder(convertForLoops, convertIterableForLoops, makeFinal, operations); compilationUnit.accept(finder); if (operations.isEmpty()) return null; CompilationUnitRewriteOperation[] ops = operations.toArray(new CompilationUnitRewriteOperation[operations.size()]); return new ConvertLoopFix(FixMessages.INSTANCE.ControlStatementsFix_change_name(), compilationUnit, ops, null, document); } public static ConvertLoopFix createConvertForLoopToEnhancedFix(CompilationUnit compilationUnit, ForStatement loop, Document document) { ConvertLoopOperation convertForLoopOperation = new ConvertForLoopOperation(loop); if (!convertForLoopOperation.satisfiesPreconditions().isOK()) return null; return new ConvertLoopFix(FixMessages.INSTANCE.Java50Fix_ConvertToEnhancedForLoop_description(), compilationUnit, new CompilationUnitRewriteOperation[]{convertForLoopOperation}, null, document); } public static ConvertLoopFix createConvertIterableLoopToEnhancedFix(CompilationUnit compilationUnit, ForStatement loop, Document document) { ConvertIterableLoopOperation loopConverter = new ConvertIterableLoopOperation(loop); IStatus status = loopConverter.satisfiesPreconditions(); if (status.getSeverity() == IStatus.ERROR) return null; return new ConvertLoopFix(FixMessages.INSTANCE.Java50Fix_ConvertToEnhancedForLoop_description(), compilationUnit, new CompilationUnitRewriteOperation[]{loopConverter}, status, document); } private final IStatus fStatus; protected ConvertLoopFix(String name, CompilationUnit compilationUnit, CompilationUnitRewriteOperation[] fixRewriteOperations, IStatus status, Document document) { super(name, compilationUnit, fixRewriteOperations, document); fStatus = status; } /** {@inheritDoc} */ @Override public IStatus getStatus() { return fStatus; } }