diff options
Diffstat (limited to 'bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/corext/refactoring/code/ExtractTempRefactoring.java')
-rw-r--r-- | bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/corext/refactoring/code/ExtractTempRefactoring.java | 1007 |
1 files changed, 0 insertions, 1007 deletions
diff --git a/bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/corext/refactoring/code/ExtractTempRefactoring.java b/bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/corext/refactoring/code/ExtractTempRefactoring.java deleted file mode 100644 index 6e636d23..00000000 --- a/bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/corext/refactoring/code/ExtractTempRefactoring.java +++ /dev/null @@ -1,1007 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2008 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.wst.jsdt.internal.corext.refactoring.code; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.StringTokenizer; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.SubProgressMonitor; -import org.eclipse.ltk.core.refactoring.Change; -import org.eclipse.ltk.core.refactoring.RefactoringDescriptor; -import org.eclipse.ltk.core.refactoring.RefactoringStatus; -import org.eclipse.ltk.core.refactoring.RefactoringStatusEntry; -import org.eclipse.ltk.core.refactoring.TextChange; -import org.eclipse.ltk.core.refactoring.participants.RefactoringArguments; -import org.eclipse.text.edits.TextEditGroup; -import org.eclipse.wst.jsdt.core.IJavaScriptUnit; -import org.eclipse.wst.jsdt.core.IJavaScriptElement; -import org.eclipse.wst.jsdt.core.IJavaScriptProject; -import org.eclipse.wst.jsdt.core.JavaScriptModelException; -import org.eclipse.wst.jsdt.core.compiler.IProblem; -import org.eclipse.wst.jsdt.core.dom.AST; -import org.eclipse.wst.jsdt.core.dom.ASTNode; -import org.eclipse.wst.jsdt.core.dom.ASTVisitor; -import org.eclipse.wst.jsdt.core.dom.ArrayInitializer; -import org.eclipse.wst.jsdt.core.dom.Assignment; -import org.eclipse.wst.jsdt.core.dom.Block; -import org.eclipse.wst.jsdt.core.dom.BodyDeclaration; -import org.eclipse.wst.jsdt.core.dom.CatchClause; -import org.eclipse.wst.jsdt.core.dom.ClassInstanceCreation; -import org.eclipse.wst.jsdt.core.dom.JavaScriptUnit; -import org.eclipse.wst.jsdt.core.dom.ConstructorInvocation; -import org.eclipse.wst.jsdt.core.dom.DoStatement; -import org.eclipse.wst.jsdt.core.dom.EnhancedForStatement; -import org.eclipse.wst.jsdt.core.dom.Expression; -import org.eclipse.wst.jsdt.core.dom.ExpressionStatement; -import org.eclipse.wst.jsdt.core.dom.FieldAccess; -import org.eclipse.wst.jsdt.core.dom.ForInStatement; -import org.eclipse.wst.jsdt.core.dom.ForStatement; -import org.eclipse.wst.jsdt.core.dom.IBinding; -import org.eclipse.wst.jsdt.core.dom.IFunctionBinding; -import org.eclipse.wst.jsdt.core.dom.ITypeBinding; -import org.eclipse.wst.jsdt.core.dom.IVariableBinding; -import org.eclipse.wst.jsdt.core.dom.IfStatement; -import org.eclipse.wst.jsdt.core.dom.Initializer; -import org.eclipse.wst.jsdt.core.dom.FunctionDeclaration; -import org.eclipse.wst.jsdt.core.dom.Name; -import org.eclipse.wst.jsdt.core.dom.NullLiteral; -import org.eclipse.wst.jsdt.core.dom.ParenthesizedExpression; -import org.eclipse.wst.jsdt.core.dom.PostfixExpression; -import org.eclipse.wst.jsdt.core.dom.PrefixExpression; -import org.eclipse.wst.jsdt.core.dom.QualifiedName; -import org.eclipse.wst.jsdt.core.dom.SimpleName; -import org.eclipse.wst.jsdt.core.dom.SingleVariableDeclaration; -import org.eclipse.wst.jsdt.core.dom.Statement; -import org.eclipse.wst.jsdt.core.dom.StructuralPropertyDescriptor; -import org.eclipse.wst.jsdt.core.dom.SuperConstructorInvocation; -import org.eclipse.wst.jsdt.core.dom.SwitchCase; -import org.eclipse.wst.jsdt.core.dom.VariableDeclarationExpression; -import org.eclipse.wst.jsdt.core.dom.VariableDeclarationFragment; -import org.eclipse.wst.jsdt.core.dom.VariableDeclarationStatement; -import org.eclipse.wst.jsdt.core.dom.WhileStatement; -import org.eclipse.wst.jsdt.core.dom.WithStatement; -import org.eclipse.wst.jsdt.core.dom.rewrite.ASTRewrite; -import org.eclipse.wst.jsdt.core.dom.rewrite.ListRewrite; -import org.eclipse.wst.jsdt.core.refactoring.IJavaScriptRefactorings; -import org.eclipse.wst.jsdt.internal.corext.Corext; -import org.eclipse.wst.jsdt.internal.corext.SourceRange; -import org.eclipse.wst.jsdt.internal.corext.codemanipulation.StubUtility; -import org.eclipse.wst.jsdt.internal.corext.dom.ASTNodes; -import org.eclipse.wst.jsdt.internal.corext.dom.ScopeAnalyzer; -import org.eclipse.wst.jsdt.internal.corext.dom.fragments.ASTFragmentFactory; -import org.eclipse.wst.jsdt.internal.corext.dom.fragments.IASTFragment; -import org.eclipse.wst.jsdt.internal.corext.dom.fragments.IExpressionFragment; -import org.eclipse.wst.jsdt.internal.corext.fix.LinkedProposalModel; -import org.eclipse.wst.jsdt.internal.corext.fix.LinkedProposalPositionGroup; -import org.eclipse.wst.jsdt.internal.corext.refactoring.Checks; -import org.eclipse.wst.jsdt.internal.corext.refactoring.JDTRefactoringDescriptor; -import org.eclipse.wst.jsdt.internal.corext.refactoring.JDTRefactoringDescriptorComment; -import org.eclipse.wst.jsdt.internal.corext.refactoring.JavaRefactoringArguments; -import org.eclipse.wst.jsdt.internal.corext.refactoring.RefactoringCoreMessages; -import org.eclipse.wst.jsdt.internal.corext.refactoring.base.JavaStatusContext; -import org.eclipse.wst.jsdt.internal.corext.refactoring.base.JavaStringStatusContext; -import org.eclipse.wst.jsdt.internal.corext.refactoring.base.RefactoringStatusCodes; -import org.eclipse.wst.jsdt.internal.corext.refactoring.changes.RefactoringDescriptorChange; -import org.eclipse.wst.jsdt.internal.corext.refactoring.rename.RefactoringAnalyzeUtil; -import org.eclipse.wst.jsdt.internal.corext.refactoring.structure.CompilationUnitRewrite; -import org.eclipse.wst.jsdt.internal.corext.refactoring.util.NoCommentSourceRangeComputer; -import org.eclipse.wst.jsdt.internal.corext.refactoring.util.RefactoringASTParser; -import org.eclipse.wst.jsdt.internal.corext.refactoring.util.ResourceUtil; -import org.eclipse.wst.jsdt.internal.corext.util.Messages; -import org.eclipse.wst.jsdt.internal.ui.JavaScriptPlugin; -import org.eclipse.wst.jsdt.internal.ui.viewsupport.BindingLabelProvider; -import org.eclipse.wst.jsdt.ui.JavaScriptElementLabels; - -/** - * Extract Local Variable (from selected expression inside method or initializer). - */ -public class ExtractTempRefactoring extends ScriptableRefactoring { - - private static final String ATTRIBUTE_REPLACE= "replace"; //$NON-NLS-1$ - private static final String ATTRIBUTE_FINAL= "final"; //$NON-NLS-1$ - - private static final class ForStatementChecker extends ASTVisitor { - - private final Collection fForInitializerVariables; - - private boolean fReferringToForVariable= false; - - public ForStatementChecker(Collection forInitializerVariables) { - Assert.isNotNull(forInitializerVariables); - fForInitializerVariables= forInitializerVariables; - } - - public boolean isReferringToForVariable() { - return fReferringToForVariable; - } - - public boolean visit(SimpleName node) { - IBinding binding= node.resolveBinding(); - if (binding != null && fForInitializerVariables.contains(binding)) { - fReferringToForVariable= true; - } - return false; - } - } - - - - private static boolean allArraysEqual(Object[][] arrays, int position) { - Object element= arrays[0][position]; - for (int i= 0; i < arrays.length; i++) { - Object[] array= arrays[i]; - if (!element.equals(array[position])) - return false; - } - return true; - } - - private static boolean canReplace(IASTFragment fragment) { - ASTNode node= fragment.getAssociatedNode(); - ASTNode parent= node.getParent(); - if (parent instanceof VariableDeclarationFragment) { - VariableDeclarationFragment vdf= (VariableDeclarationFragment) parent; - if (node.equals(vdf.getName())) - return false; - } - if (isMethodParameter(node)) - return false; - if (isThrowableInCatchBlock(node)) - return false; - if (parent instanceof ExpressionStatement) - return false; - if (isLeftValue(node)) - return false; - if (isReferringToLocalVariableFromFor((Expression) node)) - return false; - if (isUsedInForInitializerOrUpdater((Expression) node)) - return false; - if (parent instanceof SwitchCase) - return false; - return true; - } - - private static Object[] getArrayPrefix(Object[] array, int prefixLength) { - Assert.isTrue(prefixLength <= array.length); - Assert.isTrue(prefixLength >= 0); - Object[] prefix= new Object[prefixLength]; - for (int i= 0; i < prefix.length; i++) { - prefix[i]= array[i]; - } - return prefix; - } - - // return List<IVariableBinding> - private static List getForInitializedVariables(VariableDeclarationExpression variableDeclarations) { - List forInitializerVariables= new ArrayList(1); - for (Iterator iter= variableDeclarations.fragments().iterator(); iter.hasNext();) { - VariableDeclarationFragment fragment= (VariableDeclarationFragment) iter.next(); - IVariableBinding binding= fragment.resolveBinding(); - if (binding != null) - forInitializerVariables.add(binding); - } - return forInitializerVariables; - } - - private static Object[] getLongestArrayPrefix(Object[][] arrays) { - int length= -1; - if (arrays.length == 0) - return new Object[0]; - int minArrayLength= arrays[0].length; - for (int i= 1; i < arrays.length; i++) - minArrayLength= Math.min(minArrayLength, arrays[i].length); - - for (int i= 0; i < minArrayLength; i++) { - if (!allArraysEqual(arrays, i)) - break; - length++; - } - if (length == -1) - return new Object[0]; - return getArrayPrefix(arrays[0], length + 1); - } - - private static ASTNode[] getParents(ASTNode node) { - ASTNode current= node; - List parents= new ArrayList(); - do { - parents.add(current.getParent()); - current= current.getParent(); - } while (current.getParent() != null); - Collections.reverse(parents); - return (ASTNode[]) parents.toArray(new ASTNode[parents.size()]); - } - - private static boolean isLeftValue(ASTNode node) { - ASTNode parent= node.getParent(); - if (parent instanceof Assignment) { - Assignment assignment= (Assignment) parent; - if (assignment.getLeftHandSide() == node) - return true; - } - if (parent instanceof PostfixExpression) - return true; - if (parent instanceof PrefixExpression) { - PrefixExpression.Operator op= ((PrefixExpression) parent).getOperator(); - if (op.equals(PrefixExpression.Operator.DECREMENT)) - return true; - if (op.equals(PrefixExpression.Operator.INCREMENT)) - return true; - return false; - } - return false; - } - - private static boolean isMethodParameter(ASTNode node) { - return (node instanceof SimpleName) && (node.getParent() instanceof SingleVariableDeclaration) && (node.getParent().getParent() instanceof FunctionDeclaration); - } - - private static boolean isReferringToLocalVariableFromFor(Expression expression) { - ASTNode current= expression; - ASTNode parent= current.getParent(); - while (parent != null && !(parent instanceof BodyDeclaration)) { - if (parent instanceof ForStatement) { - ForStatement forStmt= (ForStatement) parent; - if (forStmt.initializers().contains(current) || forStmt.updaters().contains(current) || forStmt.getExpression() == current) { - List initializers= forStmt.initializers(); - if (initializers.size() == 1 && initializers.get(0) instanceof VariableDeclarationExpression) { - List forInitializerVariables= getForInitializedVariables((VariableDeclarationExpression) initializers.get(0)); - ForStatementChecker checker= new ForStatementChecker(forInitializerVariables); - expression.accept(checker); - if (checker.isReferringToForVariable()) - return true; - } - } - } - else if (parent instanceof ForInStatement) { - ForInStatement forInStmt= (ForInStatement) parent; - if (forInStmt.getIterationVariable().equals(current) || forInStmt.getCollection() == current) { - if (forInStmt.getIterationVariable() instanceof VariableDeclarationStatement) { - List forInitializerVariables= new ArrayList(1); - forInitializerVariables.add( ((VariableDeclarationStatement) forInStmt.getIterationVariable()).resolveBinding()); - ForStatementChecker checker= new ForStatementChecker(forInitializerVariables); - expression.accept(checker); - if (checker.isReferringToForVariable()) - return true; - } - } - } - current= parent; - parent= current.getParent(); - } - return false; - } - - private static boolean isThrowableInCatchBlock(ASTNode node) { - return (node instanceof SimpleName) && (node.getParent() instanceof SingleVariableDeclaration) && (node.getParent().getParent() instanceof CatchClause); - } - - private static boolean isUsedInForInitializerOrUpdater(Expression expression) { - ASTNode parent= expression.getParent(); - if (parent instanceof ForStatement) { - ForStatement forStmt= (ForStatement) parent; - return forStmt.initializers().contains(expression) || forStmt.updaters().contains(expression); - } - return false; - } - - private static IASTFragment[] retainOnlyReplacableMatches(IASTFragment[] allMatches) { - List result= new ArrayList(allMatches.length); - for (int i= 0; i < allMatches.length; i++) { - if (canReplace(allMatches[i])) - result.add(allMatches[i]); - } - return (IASTFragment[]) result.toArray(new IASTFragment[result.size()]); - } - - private JavaScriptUnit fCompilationUnitNode; - - private CompilationUnitRewrite fCURewrite; - - private IJavaScriptUnit fCu; - - private boolean fDeclareFinal; - - private String[] fExcludedVariableNames; - - private boolean fReplaceAllOccurrences; - - // caches: - private IExpressionFragment fSelectedExpression; - - private int fSelectionLength; - - private int fSelectionStart; - - private String fTempName; - private String[] fGuessedTempNames; - - private TextChange fChange; - - private LinkedProposalModel fLinkedProposalModel; - - private static final String KEY_NAME= "name"; //$NON-NLS-1$ -// private static final String KEY_TYPE= "type"; //$NON-NLS-1$ - - - /** - * Creates a new extract temp refactoring - * @param unit the compilation unit, or <code>null</code> if invoked by scripting - * @param selectionStart - * @param selectionLength - */ - public ExtractTempRefactoring(IJavaScriptUnit unit, int selectionStart, int selectionLength) { - Assert.isTrue(selectionStart >= 0); - Assert.isTrue(selectionLength >= 0); - fSelectionStart= selectionStart; - fSelectionLength= selectionLength; - fCu= unit; - fCompilationUnitNode= null; - - fReplaceAllOccurrences= true; // default - fDeclareFinal= false; // default - fTempName= ""; //$NON-NLS-1$ - - fLinkedProposalModel= null; - } - - public ExtractTempRefactoring(JavaScriptUnit astRoot, int selectionStart, int selectionLength) { - Assert.isTrue(selectionStart >= 0); - Assert.isTrue(selectionLength >= 0); - Assert.isTrue(astRoot.getTypeRoot() instanceof IJavaScriptUnit); - - fSelectionStart= selectionStart; - fSelectionLength= selectionLength; - fCu= (IJavaScriptUnit) astRoot.getTypeRoot(); - fCompilationUnitNode= astRoot; - - fReplaceAllOccurrences= true; // default - fDeclareFinal= false; // default - fTempName= ""; //$NON-NLS-1$ - - fLinkedProposalModel= null; - } - - public void setLinkedProposalModel(LinkedProposalModel linkedProposalModel) { - fLinkedProposalModel= linkedProposalModel; - } - - private void addReplaceExpressionWithTemp() throws JavaScriptModelException { - IASTFragment[] fragmentsToReplace= retainOnlyReplacableMatches(getMatchingFragments()); - //TODO: should not have to prune duplicates here... - ASTRewrite rewrite= fCURewrite.getASTRewrite(); - HashSet seen= new HashSet(); - for (int i= 0; i < fragmentsToReplace.length; i++) { - IASTFragment fragment= fragmentsToReplace[i]; - if (! seen.add(fragment)) - continue; - SimpleName tempName= fCURewrite.getAST().newSimpleName(fTempName); - TextEditGroup description= fCURewrite.createGroupDescription(RefactoringCoreMessages.ExtractTempRefactoring_replace); - - fragment.replace(rewrite, tempName, description); - if (fLinkedProposalModel != null) - fLinkedProposalModel.getPositionGroup(KEY_NAME, true).addPosition(rewrite.track(tempName), false); - } - } - - private RefactoringStatus checkExpression() throws JavaScriptModelException { - Expression selectedExpression= getSelectedExpression().getAssociatedExpression(); - if (selectedExpression != null) { - final ASTNode parent= selectedExpression.getParent(); - if (selectedExpression instanceof NullLiteral) { - return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_null_literals); - } else if (selectedExpression instanceof ArrayInitializer) { - return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_array_initializer); - } else if (selectedExpression instanceof Assignment) { - if (parent instanceof Expression && !(parent instanceof ParenthesizedExpression)) - return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_assignment); - else - return null; - - } else if (selectedExpression instanceof SimpleName) { - if ((((SimpleName) selectedExpression)).isDeclaration()) - return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_names_in_declarations); - if (parent instanceof QualifiedName && selectedExpression.getLocationInParent() == QualifiedName.NAME_PROPERTY || parent instanceof FieldAccess && selectedExpression.getLocationInParent() == FieldAccess.NAME_PROPERTY) - return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_select_expression); - } - } - - return null; - } - - // !! Same as in ExtractConstantRefactoring - private RefactoringStatus checkExpressionFragmentIsRValue() throws JavaScriptModelException { - switch (Checks.checkExpressionIsRValue(getSelectedExpression().getAssociatedExpression())) { - case Checks.NOT_RVALUE_MISC: - return RefactoringStatus.createStatus(RefactoringStatus.FATAL, RefactoringCoreMessages.ExtractTempRefactoring_select_expression, null, Corext.getPluginId(), RefactoringStatusCodes.EXPRESSION_NOT_RVALUE, null); - case Checks.NOT_RVALUE_VOID: - return RefactoringStatus.createStatus(RefactoringStatus.FATAL, RefactoringCoreMessages.ExtractTempRefactoring_no_void, null, Corext.getPluginId(), RefactoringStatusCodes.EXPRESSION_NOT_RVALUE_VOID, null); - case Checks.IS_RVALUE: - return new RefactoringStatus(); - default: - Assert.isTrue(false); - return null; - } - } - - public TextChange createTextChange(IProgressMonitor pm) throws CoreException { - try { - pm.beginTask(RefactoringCoreMessages.ExtractTempRefactoring_checking_preconditions, 3); - - fCURewrite= new CompilationUnitRewrite(fCu, fCompilationUnitNode); - fCURewrite.getASTRewrite().setTargetSourceRangeComputer(new NoCommentSourceRangeComputer()); - - doCreateChange(new SubProgressMonitor(pm, 2)); - - return fCURewrite.createChange(RefactoringCoreMessages.ExtractTempRefactoring_change_name, true, new SubProgressMonitor(pm, 1)); - } finally { - pm.done(); - } - } - - - public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException { - fChange= createTextChange(pm); - - RefactoringStatus result= new RefactoringStatus(); - if (Arrays.asList(getExcludedVariableNames()).contains(fTempName)) - result.addWarning(Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_another_variable, fTempName)); - - result.merge(checkMatchingFragments()); - - fChange.setKeepPreviewEdits(true); - checkNewSource(result); - - return result; - } - - private final JDTRefactoringDescriptor createRefactoringDescriptor() { - final Map arguments= new HashMap(); - String project= null; - IJavaScriptProject javaProject= fCu.getJavaScriptProject(); - if (javaProject != null) - project= javaProject.getElementName(); - final String description= Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_descriptor_description_short, fTempName); - final String expression= ASTNodes.asString(fSelectedExpression.getAssociatedExpression()); - final String header= Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_descriptor_description, new String[] { fTempName, expression}); - final JDTRefactoringDescriptorComment comment= new JDTRefactoringDescriptorComment(project, this, header); - comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_name_pattern, fTempName)); - final BodyDeclaration decl= (BodyDeclaration) ASTNodes.getParent(fSelectedExpression.getAssociatedExpression(), BodyDeclaration.class); - if (decl instanceof FunctionDeclaration) { - final IFunctionBinding method= ((FunctionDeclaration) decl).resolveBinding(); - final String label= method != null ? BindingLabelProvider.getBindingLabel(method, JavaScriptElementLabels.ALL_FULLY_QUALIFIED) : '{' + JavaScriptElementLabels.ELLIPSIS_STRING + '}'; - comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_destination_pattern, label)); - } - comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_expression_pattern, expression)); - if (fReplaceAllOccurrences) - comment.addSetting(RefactoringCoreMessages.ExtractTempRefactoring_replace_occurrences); - if (fDeclareFinal) - comment.addSetting(RefactoringCoreMessages.ExtractTempRefactoring_declare_final); - final JDTRefactoringDescriptor descriptor= new JDTRefactoringDescriptor(IJavaScriptRefactorings.EXTRACT_LOCAL_VARIABLE, project, description, comment.asString(), arguments, RefactoringDescriptor.NONE); - arguments.put(JDTRefactoringDescriptor.ATTRIBUTE_INPUT, descriptor.elementToHandle(fCu)); - arguments.put(JDTRefactoringDescriptor.ATTRIBUTE_NAME, fTempName); - arguments.put(JDTRefactoringDescriptor.ATTRIBUTE_SELECTION, new Integer(fSelectionStart).toString() + " " + new Integer(fSelectionLength).toString()); //$NON-NLS-1$ - arguments.put(ATTRIBUTE_REPLACE, Boolean.valueOf(fReplaceAllOccurrences).toString()); - arguments.put(ATTRIBUTE_FINAL, Boolean.valueOf(fDeclareFinal).toString()); - return descriptor; - } - - private void doCreateChange(IProgressMonitor pm) throws CoreException { - try { - pm.beginTask(RefactoringCoreMessages.ExtractTempRefactoring_checking_preconditions, 1); - try { - createTempDeclaration(); - } catch (CoreException exception) { - JavaScriptPlugin.log(exception); - } - addReplaceExpressionWithTemp(); - } finally { - pm.done(); - } - } - - private void checkNewSource(RefactoringStatus result) throws CoreException { - String newCuSource= fChange.getPreviewContent(new NullProgressMonitor()); - JavaScriptUnit newCUNode= new RefactoringASTParser(AST.JLS3).parse(newCuSource, fCu, true, true, null); - IProblem[] newProblems= RefactoringAnalyzeUtil.getIntroducedCompileProblems(newCUNode, fCompilationUnitNode); - for (int i= 0; i < newProblems.length; i++) { - IProblem problem= newProblems[i]; - if (problem.isError()) - result.addEntry(new RefactoringStatusEntry((problem.isError() ? RefactoringStatus.ERROR : RefactoringStatus.WARNING), problem.getMessage(), new JavaStringStatusContext(newCuSource, new SourceRange(problem)))); - } - } - - public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException { - try { - pm.beginTask("", 6); //$NON-NLS-1$ - - RefactoringStatus result= Checks.validateModifiesFiles(ResourceUtil.getFiles(new IJavaScriptUnit[] { fCu}), getValidationContext()); - if (result.hasFatalError()) - return result; - - if (fCompilationUnitNode == null) { - fCompilationUnitNode= RefactoringASTParser.parseWithASTProvider(fCu, true, new SubProgressMonitor(pm, 3)); - } else { - pm.worked(3); - } - - result.merge(checkSelection(new SubProgressMonitor(pm, 3))); - if (!result.hasFatalError() && isLiteralNodeSelected()) - fReplaceAllOccurrences= false; - return result; - - } finally { - pm.done(); - } - } - - private RefactoringStatus checkMatchingFragments() throws JavaScriptModelException { - RefactoringStatus result= new RefactoringStatus(); - IASTFragment[] matchingFragments= getMatchingFragments(); - for (int i= 0; i < matchingFragments.length; i++) { - ASTNode node= matchingFragments[i].getAssociatedNode(); - if (isLeftValue(node) && !isReferringToLocalVariableFromFor((Expression) node)) { - String msg= RefactoringCoreMessages.ExtractTempRefactoring_assigned_to; - result.addWarning(msg, JavaStatusContext.create(fCu, node)); - } - } - return result; - } - - private RefactoringStatus checkSelection(IProgressMonitor pm) throws JavaScriptModelException { - try { - pm.beginTask("", 8); //$NON-NLS-1$ - - IExpressionFragment selectedExpression= getSelectedExpression(); - - if (selectedExpression == null) { - String message= RefactoringCoreMessages.ExtractTempRefactoring_select_expression; - return CodeRefactoringUtil.checkMethodSyntaxErrors(fSelectionStart, fSelectionLength, fCompilationUnitNode, message); - } - pm.worked(1); - - if (isUsedInExplicitConstructorCall()) - return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_explicit_constructor); - pm.worked(1); - - if (getEnclosingBodyNode() == null) - return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_expr_in_method_or_initializer); - pm.worked(1); - - ASTNode associatedNode= selectedExpression.getAssociatedNode(); - if (associatedNode instanceof Name && associatedNode.getParent() instanceof ClassInstanceCreation && associatedNode.getLocationInParent() == ClassInstanceCreation.TYPE_PROPERTY) - return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_name_in_new); - pm.worked(1); - - RefactoringStatus result= new RefactoringStatus(); - result.merge(checkExpression()); - if (result.hasFatalError()) - return result; - pm.worked(1); - - result.merge(checkExpressionFragmentIsRValue()); - if (result.hasFatalError()) - return result; - pm.worked(1); - - if (isUsedInForInitializerOrUpdater(getSelectedExpression().getAssociatedExpression())) - return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_for_initializer_updater); - pm.worked(1); - - if (isReferringToLocalVariableFromFor(getSelectedExpression().getAssociatedExpression())) - return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_refers_to_for_variable); - pm.worked(1); - - return result; - } finally { - pm.done(); - } - } - - public RefactoringStatus checkTempName(String newName) { - RefactoringStatus status= Checks.checkTempName(newName); - if (Arrays.asList(getExcludedVariableNames()).contains(newName)) - status.addWarning(Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_another_variable, newName)); - return status; - } - - private void createAndInsertTempDeclaration() throws CoreException { - Expression initializer= getSelectedExpression().createCopyTarget(fCURewrite.getASTRewrite()); - VariableDeclarationStatement vds= createTempDeclaration(initializer); - - if ((!fReplaceAllOccurrences) || (retainOnlyReplacableMatches(getMatchingFragments()).length <= 1)) { - insertAt(getSelectedExpression().getAssociatedNode(), vds); - return; - } - - ASTNode[] firstReplaceNodeParents= getParents(getFirstReplacedExpression().getAssociatedNode()); - ASTNode[] commonPath= findDeepestCommonSuperNodePathForReplacedNodes(); - Assert.isTrue(commonPath.length <= firstReplaceNodeParents.length); - - ASTNode deepestCommonParent= firstReplaceNodeParents[commonPath.length - 1]; - if (deepestCommonParent instanceof Block) - insertAt(firstReplaceNodeParents[commonPath.length], vds); - else - insertAt(deepestCommonParent, vds); - } - - private VariableDeclarationStatement createTempDeclaration(Expression initializer) throws CoreException { - AST ast= fCURewrite.getAST(); - - VariableDeclarationFragment vdf= ast.newVariableDeclarationFragment(); - vdf.setName(ast.newSimpleName(fTempName)); - vdf.setInitializer(initializer); - - VariableDeclarationStatement vds= ast.newVariableDeclarationStatement(vdf); -// if (fDeclareFinal) { -// vds.modifiers().add(ast.newModifier(ModifierKeyword.FINAL_KEYWORD)); -// } -// vds.setType(createTempType()); - - if (fLinkedProposalModel != null) { - ASTRewrite rewrite= fCURewrite.getASTRewrite(); - LinkedProposalPositionGroup nameGroup= fLinkedProposalModel.getPositionGroup(KEY_NAME, true); - nameGroup.addPosition(rewrite.track(vdf.getName()), true); - - String[] nameSuggestions= guessTempNames(); - if (nameSuggestions.length > 0 && !nameSuggestions[0].equals(fTempName)) { - nameGroup.addProposal(fTempName, null, nameSuggestions.length + 1); - } - for (int i= 0; i < nameSuggestions.length; i++) { - nameGroup.addProposal(nameSuggestions[i], null, nameSuggestions.length - i); - } - } - return vds; - } - - private void insertAt(ASTNode target, Statement declaration) throws JavaScriptModelException { - ASTRewrite rewrite= fCURewrite.getASTRewrite(); - TextEditGroup groupDescription= fCURewrite.createGroupDescription(RefactoringCoreMessages.ExtractTempRefactoring_declare_local_variable); - - ASTNode parent= target.getParent(); - while (! (parent instanceof Block)) { - StructuralPropertyDescriptor locationInParent= target.getLocationInParent(); - if (locationInParent == IfStatement.THEN_STATEMENT_PROPERTY - || locationInParent == IfStatement.ELSE_STATEMENT_PROPERTY - || locationInParent == ForStatement.BODY_PROPERTY - || locationInParent == ForInStatement.BODY_PROPERTY - || locationInParent == EnhancedForStatement.BODY_PROPERTY - || locationInParent == DoStatement.BODY_PROPERTY - || locationInParent == WhileStatement.BODY_PROPERTY - || locationInParent == WithStatement.BODY_PROPERTY - ) { - Block replacement= rewrite.getAST().newBlock(); - ListRewrite replacementRewrite= rewrite.getListRewrite(replacement, Block.STATEMENTS_PROPERTY); - replacementRewrite.insertFirst(declaration, null); - replacementRewrite.insertLast(rewrite.createMoveTarget(target), null); - rewrite.replace(target, replacement, groupDescription); - return; - } - target= parent; - parent= parent.getParent(); - } - ListRewrite listRewrite= rewrite.getListRewrite(parent, Block.STATEMENTS_PROPERTY); - listRewrite.insertBefore(declaration, target, groupDescription); - } - - public Change createChange(IProgressMonitor pm) throws CoreException { - try { - pm.beginTask(RefactoringCoreMessages.ExtractTempRefactoring_checking_preconditions, 1); - JDTRefactoringDescriptor descriptor= createRefactoringDescriptor(); - return new RefactoringDescriptorChange(descriptor, RefactoringCoreMessages.ExtractTempRefactoring_extract_temp, new Change[] { fChange}); - } finally { - pm.done(); - } - } - - private void createTempDeclaration() throws CoreException { - if (shouldReplaceSelectedExpressionWithTempDeclaration()) - replaceSelectedExpressionWithTempDeclaration(); - else - createAndInsertTempDeclaration(); - } - - public boolean declareFinal() { - return fDeclareFinal; - } - - private ASTNode[] findDeepestCommonSuperNodePathForReplacedNodes() throws JavaScriptModelException { - ASTNode[] matchNodes= getMatchNodes(); - - ASTNode[][] matchingNodesParents= new ASTNode[matchNodes.length][]; - for (int i= 0; i < matchNodes.length; i++) { - matchingNodesParents[i]= getParents(matchNodes[i]); - } - List l= Arrays.asList(getLongestArrayPrefix(matchingNodesParents)); - return (ASTNode[]) l.toArray(new ASTNode[l.size()]); - } - - private Block getEnclosingBodyNode() throws JavaScriptModelException { - ASTNode node= getSelectedExpression().getAssociatedNode(); - do { - switch (node.getNodeType()) { - case ASTNode.FUNCTION_DECLARATION: - return ((FunctionDeclaration) node).getBody(); - case ASTNode.INITIALIZER: - return ((Initializer) node).getBody(); - } - node= node.getParent(); - } while (node != null); - return null; - } - - private String[] getExcludedVariableNames() { - if (fExcludedVariableNames == null) { - try { - IBinding[] bindings= new ScopeAnalyzer(fCompilationUnitNode).getDeclarationsInScope(getSelectedExpression().getStartPosition(), ScopeAnalyzer.VARIABLES); - fExcludedVariableNames= new String[bindings.length]; - for (int i= 0; i < bindings.length; i++) { - fExcludedVariableNames[i]= bindings[i].getName(); - } - } catch (JavaScriptModelException e) { - fExcludedVariableNames= new String[0]; - } - } - return fExcludedVariableNames; - } - - private IExpressionFragment getFirstReplacedExpression() throws JavaScriptModelException { - if (!fReplaceAllOccurrences) - return getSelectedExpression(); - IASTFragment[] nodesToReplace= retainOnlyReplacableMatches(getMatchingFragments()); - if (nodesToReplace.length == 0) - return getSelectedExpression(); - Comparator comparator= new Comparator() { - - public int compare(Object o1, Object o2) { - return ((IASTFragment) o1).getStartPosition() - ((IASTFragment) o2).getStartPosition(); - } - }; - Arrays.sort(nodesToReplace, comparator); - return (IExpressionFragment) nodesToReplace[0]; - } - - private IASTFragment[] getMatchingFragments() throws JavaScriptModelException { - if (fReplaceAllOccurrences) { - IASTFragment[] allMatches= ASTFragmentFactory.createFragmentForFullSubtree(getEnclosingBodyNode()).getSubFragmentsMatching(getSelectedExpression()); - return allMatches; - } else - return new IASTFragment[] { getSelectedExpression()}; - } - - private ASTNode[] getMatchNodes() throws JavaScriptModelException { - IASTFragment[] matches= retainOnlyReplacableMatches(getMatchingFragments()); - ASTNode[] result= new ASTNode[matches.length]; - for (int i= 0; i < matches.length; i++) - result[i]= matches[i].getAssociatedNode(); - return result; - } - - public String getName() { - return RefactoringCoreMessages.ExtractTempRefactoring_name; - } - - - private IExpressionFragment getSelectedExpression() throws JavaScriptModelException { - if (fSelectedExpression != null) - return fSelectedExpression; - IASTFragment selectedFragment= ASTFragmentFactory.createFragmentForSourceRange(new SourceRange(fSelectionStart, fSelectionLength), fCompilationUnitNode, fCu); - - if (selectedFragment instanceof IExpressionFragment && !Checks.isInsideJavadoc(selectedFragment.getAssociatedNode())) { - fSelectedExpression= (IExpressionFragment) selectedFragment; - } else if (selectedFragment != null) { - if (selectedFragment.getAssociatedNode() instanceof ExpressionStatement) { - ExpressionStatement exprStatement= (ExpressionStatement) selectedFragment.getAssociatedNode(); - Expression expression= exprStatement.getExpression(); - fSelectedExpression= (IExpressionFragment) ASTFragmentFactory.createFragmentForFullSubtree(expression); - } else if (selectedFragment.getAssociatedNode() instanceof Assignment) { - Assignment assignment= (Assignment) selectedFragment.getAssociatedNode(); - fSelectedExpression= (IExpressionFragment) ASTFragmentFactory.createFragmentForFullSubtree(assignment); - } - } - - return fSelectedExpression; - } - -// private Type createTempType() throws CoreException { -// Expression expression= getSelectedExpression().getAssociatedExpression(); -// -// Type resultingType= null; -// ITypeBinding typeBinding= expression.resolveTypeBinding(); -// -// ASTRewrite rewrite= fCURewrite.getASTRewrite(); -// AST ast= rewrite.getAST(); -// -// if (expression instanceof ClassInstanceCreation) { -// resultingType= (Type) rewrite.createCopyTarget(((ClassInstanceCreation) expression).getType()); -// } else if (expression instanceof CastExpression) { -// resultingType= (Type) rewrite.createCopyTarget(((CastExpression) expression).getType()); -// } else { -// if (typeBinding == null) { -// typeBinding= ASTResolving.guessBindingForReference(expression); -// } -// if (typeBinding != null) { -// typeBinding= Bindings.normalizeForDeclarationUse(typeBinding, ast); -// resultingType= fCURewrite.getImportRewrite().addImport(typeBinding, ast); -// } else { -// resultingType= ast.newSimpleType(ast.newSimpleName("Object")); //$NON-NLS-1$ -// } -// } -// if (fLinkedProposalModel != null) { -// LinkedProposalPositionGroup typeGroup= fLinkedProposalModel.getPositionGroup(KEY_TYPE, true); -// typeGroup.addPosition(rewrite.track(resultingType), false); -// if (typeBinding != null) { -// ITypeBinding[] relaxingTypes= ASTResolving.getNarrowingTypes(ast, typeBinding); -// for (int i= 0; i < relaxingTypes.length; i++) { -// typeGroup.addProposal(relaxingTypes[i], fCURewrite.getCu(), relaxingTypes.length - i); -// } -// } -// } -// return resultingType; -// } - - public String guessTempName() { - String[] proposals= guessTempNames(); - if (proposals.length == 0) - return fTempName; - else - return proposals[0]; - } - - /** - * @return proposed variable names (may be empty, but not null). The first proposal should be used as "best guess" (if it exists). - */ - public String[] guessTempNames() { - if (fGuessedTempNames == null) { - try { - Expression expression= getSelectedExpression().getAssociatedExpression(); - if (expression != null) { - ITypeBinding binding= expression.resolveTypeBinding(); - fGuessedTempNames= StubUtility.getVariableNameSuggestions(StubUtility.LOCAL, fCu.getJavaScriptProject(), binding, expression, Arrays.asList(getExcludedVariableNames())); - } - } catch (JavaScriptModelException e) { - } - if (fGuessedTempNames == null) - fGuessedTempNames= new String[0]; - } - return fGuessedTempNames; - } - - private boolean isLiteralNodeSelected() throws JavaScriptModelException { - IExpressionFragment fragment= getSelectedExpression(); - if (fragment == null) - return false; - Expression expression= fragment.getAssociatedExpression(); - if (expression == null) - return false; - switch (expression.getNodeType()) { - case ASTNode.BOOLEAN_LITERAL: - case ASTNode.CHARACTER_LITERAL: - case ASTNode.NULL_LITERAL: - case ASTNode.NUMBER_LITERAL: - case ASTNode.REGULAR_EXPRESSION_LITERAL: - case ASTNode.UNDEFINED_LITERAL: - return true; - - default: - return false; - } - } - - private boolean isUsedInExplicitConstructorCall() throws JavaScriptModelException { - Expression selectedExpression= getSelectedExpression().getAssociatedExpression(); - if (ASTNodes.getParent(selectedExpression, ConstructorInvocation.class) != null) - return true; - if (ASTNodes.getParent(selectedExpression, SuperConstructorInvocation.class) != null) - return true; - return false; - } - - public boolean replaceAllOccurrences() { - return fReplaceAllOccurrences; - } - - private void replaceSelectedExpressionWithTempDeclaration() throws CoreException { - ASTRewrite rewrite= fCURewrite.getASTRewrite(); - Expression selectedExpression= getSelectedExpression().getAssociatedExpression(); // whole expression selected - - Expression initializer= (Expression) rewrite.createMoveTarget(selectedExpression); - ASTNode replacement= createTempDeclaration(initializer); // creates a VariableDeclarationStatement - - ExpressionStatement parent= (ExpressionStatement) selectedExpression.getParent(); - if (ASTNodes.isControlStatementBody(parent.getLocationInParent())) { - Block block= rewrite.getAST().newBlock(); - block.statements().add(replacement); - replacement= block; - - } - rewrite.replace(parent, replacement, fCURewrite.createGroupDescription(RefactoringCoreMessages.ExtractTempRefactoring_declare_local_variable)); - } - - public void setDeclareFinal(boolean declareFinal) { - fDeclareFinal= declareFinal; - } - - public void setReplaceAllOccurrences(boolean replaceAllOccurrences) { - fReplaceAllOccurrences= replaceAllOccurrences; - } - - public void setTempName(String newName) { - fTempName= newName; - } - - private boolean shouldReplaceSelectedExpressionWithTempDeclaration() throws JavaScriptModelException { - IExpressionFragment selectedFragment= getSelectedExpression(); - return selectedFragment.getAssociatedNode().getParent() instanceof ExpressionStatement - && selectedFragment.matches(ASTFragmentFactory.createFragmentForFullSubtree(selectedFragment.getAssociatedNode())); - } - - public RefactoringStatus initialize(final RefactoringArguments arguments) { - if (arguments instanceof JavaRefactoringArguments) { - final JavaRefactoringArguments extended= (JavaRefactoringArguments) arguments; - final String selection= extended.getAttribute(JDTRefactoringDescriptor.ATTRIBUTE_SELECTION); - if (selection != null) { - int offset= -1; - int length= -1; - final StringTokenizer tokenizer= new StringTokenizer(selection); - if (tokenizer.hasMoreTokens()) - offset= Integer.valueOf(tokenizer.nextToken()).intValue(); - if (tokenizer.hasMoreTokens()) - length= Integer.valueOf(tokenizer.nextToken()).intValue(); - if (offset >= 0 && length >= 0) { - fSelectionStart= offset; - fSelectionLength= length; - } else - return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_illegal_argument, new Object[] { selection, JDTRefactoringDescriptor.ATTRIBUTE_SELECTION})); - } else - return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JDTRefactoringDescriptor.ATTRIBUTE_SELECTION)); - final String handle= extended.getAttribute(JDTRefactoringDescriptor.ATTRIBUTE_INPUT); - if (handle != null) { - final IJavaScriptElement element= JDTRefactoringDescriptor.handleToElement(extended.getProject(), handle, false); - if (element == null || !element.exists() || element.getElementType() != IJavaScriptElement.JAVASCRIPT_UNIT) - return createInputFatalStatus(element, IJavaScriptRefactorings.EXTRACT_LOCAL_VARIABLE); - else - fCu= (IJavaScriptUnit) element; - } else - return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JDTRefactoringDescriptor.ATTRIBUTE_INPUT)); - final String name= extended.getAttribute(JDTRefactoringDescriptor.ATTRIBUTE_NAME); - if (name != null && !"".equals(name)) //$NON-NLS-1$ - fTempName= name; - else - return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JDTRefactoringDescriptor.ATTRIBUTE_NAME)); - final String replace= extended.getAttribute(ATTRIBUTE_REPLACE); - if (replace != null) { - fReplaceAllOccurrences= Boolean.valueOf(replace).booleanValue(); - } else - return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_REPLACE)); - final String declareFinal= extended.getAttribute(ATTRIBUTE_FINAL); - if (declareFinal != null) { - fDeclareFinal= Boolean.valueOf(declareFinal).booleanValue(); - } else - return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_FINAL)); - } else - return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.InitializableRefactoring_inacceptable_arguments); - return new RefactoringStatus(); - } -} |