1 package no.uio.ifi.refaktor.refactorings;
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.Collection;
6 import java.util.Collections;
7 import java.util.Comparator;
8 import java.util.HashMap;
9 import java.util.HashSet;
10 import java.util.Iterator;
11 import java.util.List;
13 import java.util.StringTokenizer;
15 import org.eclipse.core.runtime.Assert;
16 import org.eclipse.core.runtime.CoreException;
17 import org.eclipse.core.runtime.IProgressMonitor;
18 import org.eclipse.core.runtime.NullProgressMonitor;
19 import org.eclipse.core.runtime.SubProgressMonitor;
21 import org.eclipse.text.edits.TextEditGroup;
23 import org.eclipse.ltk.core.refactoring.Change;
24 import org.eclipse.ltk.core.refactoring.Refactoring;
25 import org.eclipse.ltk.core.refactoring.RefactoringChangeDescriptor;
26 import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
27 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
28 import org.eclipse.ltk.core.refactoring.RefactoringStatusEntry;
30 import org.eclipse.jdt.core.ICompilationUnit;
31 import org.eclipse.jdt.core.IJavaElement;
32 import org.eclipse.jdt.core.IJavaProject;
33 import org.eclipse.jdt.core.JavaModelException;
34 import org.eclipse.jdt.core.NamingConventions;
35 import org.eclipse.jdt.core.SourceRange;
36 import org.eclipse.jdt.core.compiler.IProblem;
37 import org.eclipse.jdt.core.dom.AST;
38 import org.eclipse.jdt.core.dom.ASTNode;
39 import org.eclipse.jdt.core.dom.ASTVisitor;
40 import org.eclipse.jdt.core.dom.Annotation;
41 import org.eclipse.jdt.core.dom.ArrayInitializer;
42 import org.eclipse.jdt.core.dom.AssertStatement;
43 import org.eclipse.jdt.core.dom.Assignment;
44 import org.eclipse.jdt.core.dom.Block;
45 import org.eclipse.jdt.core.dom.BodyDeclaration;
46 import org.eclipse.jdt.core.dom.CastExpression;
47 import org.eclipse.jdt.core.dom.CatchClause;
48 import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor;
49 import org.eclipse.jdt.core.dom.ClassInstanceCreation;
50 import org.eclipse.jdt.core.dom.CompilationUnit;
51 import org.eclipse.jdt.core.dom.ConstructorInvocation;
52 import org.eclipse.jdt.core.dom.DoStatement;
53 import org.eclipse.jdt.core.dom.EnhancedForStatement;
54 import org.eclipse.jdt.core.dom.Expression;
55 import org.eclipse.jdt.core.dom.ExpressionStatement;
56 import org.eclipse.jdt.core.dom.FieldAccess;
57 import org.eclipse.jdt.core.dom.ForStatement;
58 import org.eclipse.jdt.core.dom.IBinding;
59 import org.eclipse.jdt.core.dom.IMethodBinding;
60 import org.eclipse.jdt.core.dom.ITypeBinding;
61 import org.eclipse.jdt.core.dom.IVariableBinding;
62 import org.eclipse.jdt.core.dom.IfStatement;
63 import org.eclipse.jdt.core.dom.InfixExpression;
64 import org.eclipse.jdt.core.dom.Initializer;
65 import org.eclipse.jdt.core.dom.LambdaExpression;
66 import org.eclipse.jdt.core.dom.MethodDeclaration;
67 import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;
68 import org.eclipse.jdt.core.dom.Name;
69 import org.eclipse.jdt.core.dom.NullLiteral;
70 import org.eclipse.jdt.core.dom.ParenthesizedExpression;
71 import org.eclipse.jdt.core.dom.PostfixExpression;
72 import org.eclipse.jdt.core.dom.PrefixExpression;
73 import org.eclipse.jdt.core.dom.QualifiedName;
74 import org.eclipse.jdt.core.dom.ReturnStatement;
75 import org.eclipse.jdt.core.dom.SimpleName;
76 import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
77 import org.eclipse.jdt.core.dom.Statement;
78 import org.eclipse.jdt.core.dom.StringLiteral;
79 import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
80 import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
81 import org.eclipse.jdt.core.dom.SwitchCase;
82 import org.eclipse.jdt.core.dom.SwitchStatement;
83 import org.eclipse.jdt.core.dom.TryStatement;
84 import org.eclipse.jdt.core.dom.Type;
85 import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
86 import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
87 import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
88 import org.eclipse.jdt.core.dom.WhileStatement;
89 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
90 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
91 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext;
92 import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
93 import org.eclipse.jdt.core.refactoring.CompilationUnitChange;
94 import org.eclipse.jdt.core.refactoring.IJavaRefactorings;
95 import org.eclipse.jdt.core.refactoring.descriptors.ExtractLocalDescriptor;
97 import org.eclipse.jdt.internal.core.refactoring.descriptors.RefactoringSignatureDescriptorFactory;
98 import org.eclipse.jdt.internal.corext.Corext;
99 import org.eclipse.jdt.internal.corext.SourceRangeFactory;
100 import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext;
101 import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
102 import org.eclipse.jdt.internal.corext.dom.ASTNodes;
103 import org.eclipse.jdt.internal.corext.dom.Bindings;
104 import org.eclipse.jdt.internal.corext.dom.ScopeAnalyzer;
105 import org.eclipse.jdt.internal.corext.dom.fragments.ASTFragmentFactory;
106 import org.eclipse.jdt.internal.corext.dom.fragments.IASTFragment;
107 import org.eclipse.jdt.internal.corext.dom.fragments.IExpressionFragment;
108 import org.eclipse.jdt.internal.corext.fix.LinkedProposalModel;
109 import org.eclipse.jdt.internal.corext.fix.LinkedProposalPositionGroup;
110 import org.eclipse.jdt.internal.corext.refactoring.Checks;
111 import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment;
112 import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringArguments;
113 import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringDescriptorUtil;
114 import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
115 import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext;
116 import org.eclipse.jdt.internal.corext.refactoring.base.JavaStringStatusContext;
117 import org.eclipse.jdt.internal.corext.refactoring.base.RefactoringStatusCodes;
118 import org.eclipse.jdt.internal.corext.refactoring.code.CodeRefactoringUtil;
119 import org.eclipse.jdt.internal.corext.refactoring.code.ExtractTempRefactoring;
120 import org.eclipse.jdt.internal.corext.refactoring.rename.RefactoringAnalyzeUtil;
121 import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite;
122 import org.eclipse.jdt.internal.corext.refactoring.util.NoCommentSourceRangeComputer;
123 import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;
124 import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil;
125 import org.eclipse.jdt.internal.corext.util.Messages;
127 import org.eclipse.jdt.ui.JavaElementLabels;
129 import org.eclipse.jdt.internal.ui.JavaPlugin;
130 import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider;
131 import org.eclipse.jdt.internal.ui.text.correction.ASTResolving;
132 import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels;
133 import org.eclipse.jdt.internal.ui.viewsupport.BindingLabelProvider;
136 * Extract Local Variable (from selected expression inside method or initializer).
138 * @author Anna Eilertsen
140 * TODO: Copied from ExtractTemp, will replace unused code with super-calls
142 public class ExtractTempWithAssertsRefactoring extends ExtractTempRefactoring {
144 private static final String ATTRIBUTE_REPLACE= "replace"; //$NON-NLS-1$
145 private static final String ATTRIBUTE_FINAL= "final"; //$NON-NLS-1$
147 private static final class ForStatementChecker extends ASTVisitor {
149 private final Collection<IVariableBinding> fForInitializerVariables;
151 private boolean fReferringToForVariable= false;
153 public ForStatementChecker(Collection<IVariableBinding> forInitializerVariables) {
154 Assert.isNotNull(forInitializerVariables);
155 fForInitializerVariables= forInitializerVariables;
158 public boolean isReferringToForVariable() {
159 return fReferringToForVariable;
163 public boolean visit(SimpleName node) {
164 IBinding binding= node.resolveBinding();
165 if (binding != null && fForInitializerVariables.contains(binding)) {
166 fReferringToForVariable= true;
174 private static boolean allArraysEqual(Object[][] arrays, int position) {
175 Object element= arrays[0][position];
176 for (int i= 0; i < arrays.length; i++) {
177 Object[] array= arrays[i];
178 if (!element.equals(array[position]))
184 private static boolean canReplace(IASTFragment fragment) {
185 ASTNode node= fragment.getAssociatedNode();
186 ASTNode parent= node.getParent();
187 if (parent instanceof VariableDeclarationFragment) {
188 VariableDeclarationFragment vdf= (VariableDeclarationFragment) parent;
189 if (node.equals(vdf.getName()))
192 if (isMethodParameter(node))
194 if (isThrowableInCatchBlock(node))
196 if (parent instanceof ExpressionStatement)
198 if (parent instanceof LambdaExpression)
200 if (isLeftValue(node))
202 if (isReferringToLocalVariableFromFor((Expression) node))
204 if (isUsedInForInitializerOrUpdater((Expression) node))
206 if (parent instanceof SwitchCase)
211 private static Object[] getArrayPrefix(Object[] array, int prefixLength) {
212 Assert.isTrue(prefixLength <= array.length);
213 Assert.isTrue(prefixLength >= 0);
214 Object[] prefix= new Object[prefixLength];
215 for (int i= 0; i < prefix.length; i++) {
221 // return List<IVariableBinding>
222 private static List<IVariableBinding> getForInitializedVariables(VariableDeclarationExpression variableDeclarations) {
223 List<IVariableBinding> forInitializerVariables= new ArrayList<IVariableBinding>(1);
224 for (Iterator<VariableDeclarationFragment> iter= variableDeclarations.fragments().iterator(); iter.hasNext();) {
225 VariableDeclarationFragment fragment= iter.next();
226 IVariableBinding binding= fragment.resolveBinding();
228 forInitializerVariables.add(binding);
230 return forInitializerVariables;
233 private static Object[] getLongestArrayPrefix(Object[][] arrays) {
235 if (arrays.length == 0)
236 return new Object[0];
237 int minArrayLength= arrays[0].length;
238 for (int i= 1; i < arrays.length; i++)
239 minArrayLength= Math.min(minArrayLength, arrays[i].length);
241 for (int i= 0; i < minArrayLength; i++) {
242 if (!allArraysEqual(arrays, i))
247 return new Object[0];
248 return getArrayPrefix(arrays[0], length + 1);
251 private static ASTNode[] getParents(ASTNode node) {
252 ASTNode current= node;
253 List<ASTNode> parents= new ArrayList<ASTNode>();
255 parents.add(current.getParent());
256 current= current.getParent();
257 } while (current.getParent() != null);
258 Collections.reverse(parents);
259 return parents.toArray(new ASTNode[parents.size()]);
262 private static boolean isLeftValue(ASTNode node) {
263 ASTNode parent= node.getParent();
264 if (parent instanceof Assignment) {
265 Assignment assignment= (Assignment) parent;
266 if (assignment.getLeftHandSide() == node)
269 if (parent instanceof PostfixExpression)
271 if (parent instanceof PrefixExpression) {
272 PrefixExpression.Operator op= ((PrefixExpression) parent).getOperator();
273 if (op.equals(PrefixExpression.Operator.DECREMENT))
275 if (op.equals(PrefixExpression.Operator.INCREMENT))
282 private static boolean isMethodParameter(ASTNode node) {
283 return (node instanceof SimpleName) && (node.getParent() instanceof SingleVariableDeclaration) && (node.getParent().getParent() instanceof MethodDeclaration);
286 private static boolean isReferringToLocalVariableFromFor(Expression expression) {
287 ASTNode current= expression;
288 ASTNode parent= current.getParent();
289 while (parent != null && !(parent instanceof BodyDeclaration)) {
290 if (parent instanceof ForStatement) {
291 ForStatement forStmt= (ForStatement) parent;
292 if (forStmt.initializers().contains(current) || forStmt.updaters().contains(current) || forStmt.getExpression() == current) {
293 List<Expression> initializers= forStmt.initializers();
294 if (initializers.size() == 1 && initializers.get(0) instanceof VariableDeclarationExpression) {
295 List<IVariableBinding> forInitializerVariables= getForInitializedVariables((VariableDeclarationExpression) initializers.get(0));
296 ForStatementChecker checker= new ForStatementChecker(forInitializerVariables);
297 expression.accept(checker);
298 if (checker.isReferringToForVariable())
304 parent= current.getParent();
309 private static boolean isThrowableInCatchBlock(ASTNode node) {
310 return (node instanceof SimpleName) && (node.getParent() instanceof SingleVariableDeclaration) && (node.getParent().getParent() instanceof CatchClause);
313 private static boolean isUsedInForInitializerOrUpdater(Expression expression) {
314 ASTNode parent= expression.getParent();
315 if (parent instanceof ForStatement) {
316 ForStatement forStmt= (ForStatement) parent;
317 return forStmt.initializers().contains(expression) || forStmt.updaters().contains(expression);
322 private static IASTFragment[] retainOnlyReplacableMatches(IASTFragment[] allMatches) {
323 List<IASTFragment> result= new ArrayList<IASTFragment>(allMatches.length);
324 for (int i= 0; i < allMatches.length; i++) {
325 if (canReplace(allMatches[i]))
326 result.add(allMatches[i]);
328 return result.toArray(new IASTFragment[result.size()]);
331 private CompilationUnit fCompilationUnitNode;
333 private CompilationUnitRewrite fCURewrite;
335 private ICompilationUnit fCu;
337 private boolean fDeclareFinal;
339 private String[] fExcludedVariableNames;
341 private boolean fReplaceAllOccurrences;
344 private IExpressionFragment fSelectedExpression;
346 private int fSelectionLength;
348 private int fSelectionStart;
350 private String fTempName;
351 private String[] fGuessedTempNames;
353 private boolean fCheckResultForCompileProblems;
355 private CompilationUnitChange fChange;
357 private LinkedProposalModel fLinkedProposalModel;
358 private MethodDeclaration methodDeclaration;
359 private String fSelectedText;
361 private static final String KEY_NAME= "name"; //$NON-NLS-1$
362 private static final String KEY_TYPE= "type"; //$NON-NLS-1$
366 * Creates a new extract temp refactoring
367 * @param unit the compilation unit, or <code>null</code> if invoked by scripting
368 * @param selectionStart start of selection
369 * @param selectionLength length of selection
372 public ExtractTempWithAssertsRefactoring(ICompilationUnit unit, int selectionStart, int selectionLength, String selectedText) {
373 super(unit, selectionStart, selectionLength);
374 Assert.isTrue(selectionStart >= 0);
375 Assert.isTrue(selectionLength >= 0);
376 fSelectionStart= selectionStart;
377 fSelectionLength= selectionLength;
378 fSelectedText = selectedText;
380 fCompilationUnitNode= null;
382 fReplaceAllOccurrences= true; // default
383 fDeclareFinal= false; // default
384 fTempName= ""; //$NON-NLS-1$
386 fLinkedProposalModel= null;
387 fCheckResultForCompileProblems= true;
390 public ExtractTempWithAssertsRefactoring(CompilationUnit astRoot, int selectionStart, int selectionLength) {
391 super(astRoot, selectionStart, selectionLength);
392 Assert.isTrue(selectionStart >= 0);
393 Assert.isTrue(selectionLength >= 0);
394 Assert.isTrue(astRoot.getTypeRoot() instanceof ICompilationUnit);
396 fSelectionStart= selectionStart;
397 fSelectionLength= selectionLength;
398 fCu= (ICompilationUnit) astRoot.getTypeRoot();
399 fCompilationUnitNode= astRoot;
401 fReplaceAllOccurrences= true; // default
402 fDeclareFinal= false; // default
403 fTempName= ""; //$NON-NLS-1$
405 fLinkedProposalModel= null;
406 fCheckResultForCompileProblems= true;
409 // public ExtractTempWithAssertsRefactoring(JavaRefactoringArguments arguments, RefactoringStatus status) {
410 // this((ICompilationUnit) null, 0, 0);
411 // RefactoringStatus initializeStatus= initialize(arguments);
412 // status.merge(initializeStatus);
415 public void setCheckResultForCompileProblems(boolean checkResultForCompileProblems) {
416 fCheckResultForCompileProblems= checkResultForCompileProblems;
420 public void setLinkedProposalModel(LinkedProposalModel linkedProposalModel) {
421 fLinkedProposalModel= linkedProposalModel;
424 private void addReplaceExpressionWithTemp() throws JavaModelException {
425 IASTFragment[] fragmentsToReplace= retainOnlyReplacableMatches(getMatchingFragments());
426 //TODO: should not have to prune duplicates here...
427 ASTRewrite rewrite= fCURewrite.getASTRewrite();
428 HashSet<IASTFragment> seen= new HashSet<IASTFragment>();
429 for (int i= 0; i < fragmentsToReplace.length; i++) {
430 IASTFragment fragment= fragmentsToReplace[i];
431 if (! seen.add(fragment))
433 SimpleName tempName= fCURewrite.getAST().newSimpleName(fTempName);
434 TextEditGroup description= fCURewrite.createGroupDescription(RefactoringCoreMessages.ExtractTempRefactoring_replace);
440 * Anna's hacky code from here
443 //TODO: some clever way of iterating over parents?
444 ASTNode associatedNode = fragment.getAssociatedNode().getParent().getParent();
446 //For debugging (do this with a while loop later)
447 Object a1 = fragment.getAssociatedNode();
448 Object a = fragment.getAssociatedNode().getClass();
449 Object b1 = fragment.getAssociatedNode().getParent();
450 Object b = fragment.getAssociatedNode().getParent().getClass();
451 Object c1 = fragment.getAssociatedNode().getParent().getParent();
452 Object c = fragment.getAssociatedNode().getParent().getParent().getClass();
453 ASTNode d1 = fragment.getAssociatedNode().getParent().getParent();
454 Object d = fragment.getAssociatedNode().getParent().getParent().getClass();
455 ASTNode block1 = fragment.getAssociatedNode().getParent().getParent().getParent();
456 Object blockClass = fragment.getAssociatedNode().getParent().getParent().getParent().getClass();
459 AST ast = block1.getAST();
461 ASTRewrite ASTRewriteStmt = ASTRewrite.create(ast);
462 //ListRewrite lr = ASTRewriteStmt.getListRewrite(block1, Block.STATEMENTS_PROPERTY);
463 ListRewrite lr = rewrite.getListRewrite(block1, Block.STATEMENTS_PROPERTY);
464 List<ASTNode> ls = lr.getOriginalList();
465 ASTNode first = ls.get(0);
467 boolean check = first == d1;
469 lr.insertBefore(getAssertStatement(ast), d1, null);
471 //ASTRewriteStmt.rewriteAST(fCompilationUnitNode, null).apply(fCompilationUnitNode);
474 * Eclipse code from here
476 fragment.replace(rewrite, tempName, description);
478 if (fLinkedProposalModel != null)
479 fLinkedProposalModel.getPositionGroup(KEY_NAME, true).addPosition(rewrite.track(tempName), false);
483 private Statement getAssertStatement(AST ast){
485 AssertStatement assertStatement = ast.newAssertStatement();
486 InfixExpression infixExpression = ast.newInfixExpression();
488 infixExpression.setLeftOperand(ast.newSimpleName(fTempName));
489 infixExpression.setOperator(InfixExpression.Operator.EQUALS);
491 infixExpression.setRightOperand(ast.newName(fSelectedText));
492 assertStatement.setExpression(infixExpression);
493 StringLiteral stringLiteral = ast.newStringLiteral();
494 stringLiteral.setLiteralValue("The Move Method refactoring has broken the program due to aliasing issues!");
495 assertStatement.setMessage(stringLiteral);
496 return assertStatement;
499 private RefactoringStatus checkExpression() throws JavaModelException {
500 Expression selectedExpression= getSelectedExpression().getAssociatedExpression();
501 if (selectedExpression != null) {
502 final ASTNode parent= selectedExpression.getParent();
503 if (selectedExpression instanceof NullLiteral) {
504 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_null_literals);
505 } else if (selectedExpression instanceof ArrayInitializer) {
506 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_array_initializer);
507 } else if (selectedExpression instanceof Assignment) {
508 if (parent instanceof Expression && !(parent instanceof ParenthesizedExpression))
509 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_assignment);
512 } else if (selectedExpression instanceof SimpleName) {
513 if ((((SimpleName) selectedExpression)).isDeclaration())
514 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_names_in_declarations);
515 if (parent instanceof QualifiedName && selectedExpression.getLocationInParent() == QualifiedName.NAME_PROPERTY || parent instanceof FieldAccess && selectedExpression.getLocationInParent() == FieldAccess.NAME_PROPERTY)
516 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_select_expression);
517 } else if (selectedExpression instanceof VariableDeclarationExpression && parent instanceof TryStatement) {
518 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_resource_in_try_with_resources);
525 // !! Same as in ExtractConstantRefactoring
526 private RefactoringStatus checkExpressionFragmentIsRValue() throws JavaModelException {
527 switch (Checks.checkExpressionIsRValue(getSelectedExpression().getAssociatedExpression())) {
528 case Checks.NOT_RVALUE_MISC:
529 return RefactoringStatus.createStatus(RefactoringStatus.FATAL, RefactoringCoreMessages.ExtractTempRefactoring_select_expression, null, Corext.getPluginId(), RefactoringStatusCodes.EXPRESSION_NOT_RVALUE, null);
530 case Checks.NOT_RVALUE_VOID:
531 return RefactoringStatus.createStatus(RefactoringStatus.FATAL, RefactoringCoreMessages.ExtractTempRefactoring_no_void, null, Corext.getPluginId(), RefactoringStatusCodes.EXPRESSION_NOT_RVALUE_VOID, null);
532 case Checks.IS_RVALUE_GUESSED:
533 case Checks.IS_RVALUE:
534 return new RefactoringStatus();
536 Assert.isTrue(false);
541 private ITypeBinding guessBindingForReference(Expression expression) {
542 ITypeBinding binding= expression.resolveTypeBinding();
543 if (binding == null) {
544 binding= ASTResolving.guessBindingForReference(expression);
550 public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException {
552 pm.beginTask(RefactoringCoreMessages.ExtractTempRefactoring_checking_preconditions, 4);
554 fCURewrite= new CompilationUnitRewrite(fCu, fCompilationUnitNode);
555 fCURewrite.getASTRewrite().setTargetSourceRangeComputer(new NoCommentSourceRangeComputer());
557 doCreateChange(new SubProgressMonitor(pm, 2));
559 fChange= fCURewrite.createChange(RefactoringCoreMessages.ExtractTempRefactoring_change_name, true, new SubProgressMonitor(pm, 1));
561 RefactoringStatus result= new RefactoringStatus();
562 if (Arrays.asList(getExcludedVariableNames()).contains(fTempName))
563 result.addWarning(Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_another_variable, BasicElementLabels.getJavaElementName(fTempName)));
565 result.merge(checkMatchingFragments());
567 fChange.setKeepPreviewEdits(true);
569 if (fCheckResultForCompileProblems) {
570 checkNewSource(new SubProgressMonitor(pm, 1), result);
579 private final ExtractLocalDescriptor createRefactoringDescriptor() {
580 final Map<String, String> arguments= new HashMap<String, String>();
581 String project= null;
582 IJavaProject javaProject= fCu.getJavaProject();
583 if (javaProject != null)
584 project= javaProject.getElementName();
585 final String description= Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_descriptor_description_short, BasicElementLabels.getJavaElementName(fTempName));
586 final String expression= ASTNodes.asString(fSelectedExpression.getAssociatedExpression());
587 final String header= Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_descriptor_description, new String[] { BasicElementLabels.getJavaElementName(fTempName), BasicElementLabels.getJavaCodeString(expression)});
588 final JDTRefactoringDescriptorComment comment= new JDTRefactoringDescriptorComment(project, this, header);
589 comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_name_pattern, BasicElementLabels.getJavaElementName(fTempName)));
590 final BodyDeclaration decl= (BodyDeclaration) ASTNodes.getParent(fSelectedExpression.getAssociatedExpression(), BodyDeclaration.class);
591 if (decl instanceof MethodDeclaration) {
592 final IMethodBinding method= ((MethodDeclaration) decl).resolveBinding();
593 final String label= method != null ? BindingLabelProvider.getBindingLabel(method, JavaElementLabels.ALL_FULLY_QUALIFIED) : BasicElementLabels.getJavaElementName('{' + JavaElementLabels.ELLIPSIS_STRING + '}');
594 comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_destination_pattern, label));
596 comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_expression_pattern, BasicElementLabels.getJavaCodeString(expression)));
597 if (fReplaceAllOccurrences)
598 comment.addSetting(RefactoringCoreMessages.ExtractTempRefactoring_replace_occurrences);
600 comment.addSetting(RefactoringCoreMessages.ExtractTempRefactoring_declare_final);
601 final ExtractLocalDescriptor descriptor= RefactoringSignatureDescriptorFactory.createExtractLocalDescriptor(project, description, comment.asString(), arguments, RefactoringDescriptor.NONE);
602 arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT, JavaRefactoringDescriptorUtil.elementToHandle(project, fCu));
603 arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME, fTempName);
604 arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION, new Integer(fSelectionStart).toString() + " " + new Integer(fSelectionLength).toString()); //$NON-NLS-1$
605 arguments.put(ATTRIBUTE_REPLACE, Boolean.valueOf(fReplaceAllOccurrences).toString());
606 arguments.put(ATTRIBUTE_FINAL, Boolean.valueOf(fDeclareFinal).toString());
610 private void doCreateChange(IProgressMonitor pm) throws CoreException {
612 pm.beginTask(RefactoringCoreMessages.ExtractTempRefactoring_checking_preconditions, 1);
614 createTempDeclaration();
615 } catch (CoreException exception) {
616 JavaPlugin.log(exception);
618 addReplaceExpressionWithTemp();
624 private void checkNewSource(SubProgressMonitor monitor, RefactoringStatus result) throws CoreException {
625 String newCuSource= fChange.getPreviewContent(new NullProgressMonitor());
626 CompilationUnit newCUNode= new RefactoringASTParser(ASTProvider.SHARED_AST_LEVEL).parse(newCuSource, fCu, true, true, monitor);
627 IProblem[] newProblems= RefactoringAnalyzeUtil.getIntroducedCompileProblems(newCUNode, fCompilationUnitNode);
628 for (int i= 0; i < newProblems.length; i++) {
629 IProblem problem= newProblems[i];
630 if (problem.isError())
631 result.addEntry(new RefactoringStatusEntry((problem.isError() ? RefactoringStatus.ERROR : RefactoringStatus.WARNING), problem.getMessage(), new JavaStringStatusContext(newCuSource, SourceRangeFactory.create(problem))));
636 public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException {
638 pm.beginTask("", 6); //$NON-NLS-1$
640 RefactoringStatus result= Checks.validateModifiesFiles(ResourceUtil.getFiles(new ICompilationUnit[] { fCu}), getValidationContext());
641 if (result.hasFatalError())
644 if (fCompilationUnitNode == null) {
645 fCompilationUnitNode= RefactoringASTParser.parseWithASTProvider(fCu, true, new SubProgressMonitor(pm, 3));
650 result.merge(checkSelection(new SubProgressMonitor(pm, 3)));
651 if (!result.hasFatalError() && isLiteralNodeSelected())
652 fReplaceAllOccurrences= false;
660 private RefactoringStatus checkMatchingFragments() throws JavaModelException {
661 RefactoringStatus result= new RefactoringStatus();
662 IASTFragment[] matchingFragments= getMatchingFragments();
663 for (int i= 0; i < matchingFragments.length; i++) {
664 ASTNode node= matchingFragments[i].getAssociatedNode();
665 if (isLeftValue(node) && !isReferringToLocalVariableFromFor((Expression) node)) {
666 String msg= RefactoringCoreMessages.ExtractTempRefactoring_assigned_to;
667 result.addWarning(msg, JavaStatusContext.create(fCu, node));
673 private RefactoringStatus checkSelection(IProgressMonitor pm) throws JavaModelException {
675 pm.beginTask("", 8); //$NON-NLS-1$
677 IExpressionFragment selectedExpression= getSelectedExpression();
679 if (selectedExpression == null) {
680 String message= RefactoringCoreMessages.ExtractTempRefactoring_select_expression;
681 return CodeRefactoringUtil.checkMethodSyntaxErrors(fSelectionStart, fSelectionLength, fCompilationUnitNode, message);
685 if (isUsedInExplicitConstructorCall())
686 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_explicit_constructor);
689 ASTNode associatedNode= selectedExpression.getAssociatedNode();
690 if (getEnclosingBodyNode() == null || ASTNodes.getParent(associatedNode, Annotation.class) != null)
691 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_expr_in_method_or_initializer);
694 if (associatedNode instanceof Name && associatedNode.getParent() instanceof ClassInstanceCreation && associatedNode.getLocationInParent() == ClassInstanceCreation.TYPE_PROPERTY)
695 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_name_in_new);
698 RefactoringStatus result= new RefactoringStatus();
699 result.merge(checkExpression());
700 if (result.hasFatalError())
704 result.merge(checkExpressionFragmentIsRValue());
705 if (result.hasFatalError())
709 if (isUsedInForInitializerOrUpdater(getSelectedExpression().getAssociatedExpression()))
710 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_for_initializer_updater);
713 if (isReferringToLocalVariableFromFor(getSelectedExpression().getAssociatedExpression()))
714 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_refers_to_for_variable);
723 public RefactoringStatus checkTempName(String newName) {
724 RefactoringStatus status= Checks.checkTempName(newName, fCu);
725 if (Arrays.asList(getExcludedVariableNames()).contains(newName))
726 status.addWarning(Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_another_variable, BasicElementLabels.getJavaElementName(newName)));
730 private void createAndInsertTempDeclaration() throws CoreException {
731 Expression initializer= getSelectedExpression().createCopyTarget(fCURewrite.getASTRewrite(), true);
732 VariableDeclarationStatement vds= createTempDeclaration(initializer);
734 IASTFragment[] replacableMatches= retainOnlyReplacableMatches(getMatchingFragments());
735 if (!fReplaceAllOccurrences
736 || replacableMatches.length == 0
737 || replacableMatches.length == 1 && replacableMatches[0].equals(getSelectedExpression().getAssociatedExpression())) {
738 insertAt(getSelectedExpression().getAssociatedNode(), vds);
742 ASTNode[] firstReplaceNodeParents= getParents(getFirstReplacedExpression().getAssociatedNode());
743 ASTNode[] commonPath= findDeepestCommonSuperNodePathForReplacedNodes();
744 Assert.isTrue(commonPath.length <= firstReplaceNodeParents.length);
746 ASTNode deepestCommonParent= firstReplaceNodeParents[commonPath.length - 1];
747 if (deepestCommonParent instanceof Block)
748 insertAt(firstReplaceNodeParents[commonPath.length], vds);
750 insertAt(deepestCommonParent, vds);
753 private VariableDeclarationStatement createTempDeclaration(Expression initializer) throws CoreException {
754 AST ast= fCURewrite.getAST();
756 VariableDeclarationFragment vdf= ast.newVariableDeclarationFragment();
757 vdf.setName(ast.newSimpleName(fTempName));
758 vdf.setInitializer(initializer);
760 VariableDeclarationStatement vds= ast.newVariableDeclarationStatement(vdf);
762 vds.modifiers().add(ast.newModifier(ModifierKeyword.FINAL_KEYWORD));
764 vds.setType(createTempType());
766 if (fLinkedProposalModel != null) {
767 ASTRewrite rewrite= fCURewrite.getASTRewrite();
768 LinkedProposalPositionGroup nameGroup= fLinkedProposalModel.getPositionGroup(KEY_NAME, true);
769 nameGroup.addPosition(rewrite.track(vdf.getName()), true);
771 String[] nameSuggestions= guessTempNames();
772 if (nameSuggestions.length > 0 && !nameSuggestions[0].equals(fTempName)) {
773 nameGroup.addProposal(fTempName, null, nameSuggestions.length + 1);
775 for (int i= 0; i < nameSuggestions.length; i++) {
776 nameGroup.addProposal(nameSuggestions[i], null, nameSuggestions.length - i);
782 private void insertAt(ASTNode target, Statement declaration) {
783 ASTRewrite rewrite= fCURewrite.getASTRewrite();
784 TextEditGroup groupDescription= fCURewrite.createGroupDescription(RefactoringCoreMessages.ExtractTempRefactoring_declare_local_variable);
786 ASTNode parent= target.getParent();
787 StructuralPropertyDescriptor locationInParent= target.getLocationInParent();
788 while (locationInParent != Block.STATEMENTS_PROPERTY && locationInParent != SwitchStatement.STATEMENTS_PROPERTY) {
789 if (locationInParent == IfStatement.THEN_STATEMENT_PROPERTY
790 || locationInParent == IfStatement.ELSE_STATEMENT_PROPERTY
791 || locationInParent == ForStatement.BODY_PROPERTY
792 || locationInParent == EnhancedForStatement.BODY_PROPERTY
793 || locationInParent == DoStatement.BODY_PROPERTY
794 || locationInParent == WhileStatement.BODY_PROPERTY) {
795 // create intermediate block if target was the body property of a control statement:
796 Block replacement= rewrite.getAST().newBlock();
797 ListRewrite replacementRewrite= rewrite.getListRewrite(replacement, Block.STATEMENTS_PROPERTY);
798 replacementRewrite.insertFirst(declaration, null);
799 replacementRewrite.insertLast(rewrite.createMoveTarget(target), null);
800 rewrite.replace(target, replacement, groupDescription);
802 } else if (locationInParent == LambdaExpression.BODY_PROPERTY && ((LambdaExpression) parent).getBody() instanceof Expression) {
803 Block replacement= rewrite.getAST().newBlock();
804 ListRewrite replacementRewrite= rewrite.getListRewrite(replacement, Block.STATEMENTS_PROPERTY);
805 replacementRewrite.insertFirst(declaration, null);
806 ASTNode moveTarget= rewrite.createMoveTarget(target);
807 AST ast= rewrite.getAST();
808 if (Bindings.isVoidType(((LambdaExpression) parent).resolveMethodBinding().getReturnType())) {
809 ExpressionStatement expressionStatement= ast.newExpressionStatement((Expression) moveTarget);
810 moveTarget= expressionStatement;
812 ReturnStatement returnStatement= ast.newReturnStatement();
813 returnStatement.setExpression((Expression) moveTarget);
814 moveTarget= returnStatement;
816 replacementRewrite.insertLast(moveTarget, null);
817 rewrite.replace(target, replacement, groupDescription);
821 parent= parent.getParent();
822 locationInParent= target.getLocationInParent();
824 ListRewrite listRewrite= rewrite.getListRewrite(parent, (ChildListPropertyDescriptor)locationInParent);
825 listRewrite.insertBefore(declaration, target, groupDescription);
829 public Change createChange(IProgressMonitor pm) throws CoreException {
831 pm.beginTask(RefactoringCoreMessages.ExtractTempRefactoring_checking_preconditions, 1);
833 ExtractLocalDescriptor descriptor= createRefactoringDescriptor();
834 fChange.setDescriptor(new RefactoringChangeDescriptor(descriptor));
841 private void createTempDeclaration() throws CoreException {
842 if (shouldReplaceSelectedExpressionWithTempDeclaration())
843 replaceSelectedExpressionWithTempDeclaration();
845 createAndInsertTempDeclaration();
848 public boolean declareFinal() {
849 return fDeclareFinal;
852 private ASTNode[] findDeepestCommonSuperNodePathForReplacedNodes() throws JavaModelException {
853 ASTNode[] matchNodes= getMatchNodes();
855 ASTNode[][] matchingNodesParents= new ASTNode[matchNodes.length][];
856 for (int i= 0; i < matchNodes.length; i++) {
857 matchingNodesParents[i]= getParents(matchNodes[i]);
859 List<Object> l= Arrays.asList(getLongestArrayPrefix(matchingNodesParents));
860 return l.toArray(new ASTNode[l.size()]);
863 private ASTNode getEnclosingBodyNode() throws JavaModelException {
864 ASTNode node= getSelectedExpression().getAssociatedNode();
866 // expression must be in a method, lambda or initializer body
867 // make sure it is not in method or parameter annotation
868 StructuralPropertyDescriptor location= null;
869 while (node != null && !(node instanceof BodyDeclaration)) {
870 location= node.getLocationInParent();
871 node= node.getParent();
872 if (node instanceof LambdaExpression) {
876 if (location == MethodDeclaration.BODY_PROPERTY || location == Initializer.BODY_PROPERTY
877 || (location == LambdaExpression.BODY_PROPERTY && ((LambdaExpression) node).resolveMethodBinding() != null)) {
878 return (ASTNode) node.getStructuralProperty(location);
883 private String[] getExcludedVariableNames() {
884 if (fExcludedVariableNames == null) {
886 IBinding[] bindings= new ScopeAnalyzer(fCompilationUnitNode).getDeclarationsInScope(getSelectedExpression().getStartPosition(), ScopeAnalyzer.VARIABLES
887 | ScopeAnalyzer.CHECK_VISIBILITY);
888 fExcludedVariableNames= new String[bindings.length];
889 for (int i= 0; i < bindings.length; i++) {
890 fExcludedVariableNames[i]= bindings[i].getName();
892 } catch (JavaModelException e) {
893 fExcludedVariableNames= new String[0];
896 return fExcludedVariableNames;
899 private IExpressionFragment getFirstReplacedExpression() throws JavaModelException {
900 if (!fReplaceAllOccurrences)
901 return getSelectedExpression();
902 IASTFragment[] nodesToReplace= retainOnlyReplacableMatches(getMatchingFragments());
903 if (nodesToReplace.length == 0)
904 return getSelectedExpression();
905 Comparator<IASTFragment> comparator= new Comparator<IASTFragment>() {
907 public int compare(IASTFragment o1, IASTFragment o2) {
908 return o1.getStartPosition() - o2.getStartPosition();
911 Arrays.sort(nodesToReplace, comparator);
912 return (IExpressionFragment) nodesToReplace[0];
915 private IASTFragment[] getMatchingFragments() throws JavaModelException {
916 if (fReplaceAllOccurrences) {
917 IASTFragment[] allMatches= ASTFragmentFactory.createFragmentForFullSubtree(getEnclosingBodyNode()).getSubFragmentsMatching(getSelectedExpression());
920 return new IASTFragment[] { getSelectedExpression()};
923 private ASTNode[] getMatchNodes() throws JavaModelException {
924 IASTFragment[] matches= retainOnlyReplacableMatches(getMatchingFragments());
925 ASTNode[] result= new ASTNode[matches.length];
926 for (int i= 0; i < matches.length; i++)
927 result[i]= matches[i].getAssociatedNode();
932 public String getName() {
933 return RefactoringCoreMessages.ExtractTempRefactoring_name;
937 private IExpressionFragment getSelectedExpression() throws JavaModelException {
938 if (fSelectedExpression != null)
939 return fSelectedExpression;
940 IASTFragment selectedFragment= ASTFragmentFactory.createFragmentForSourceRange(new SourceRange(fSelectionStart, fSelectionLength), fCompilationUnitNode, fCu);
942 if (selectedFragment instanceof IExpressionFragment && !Checks.isInsideJavadoc(selectedFragment.getAssociatedNode())) {
943 fSelectedExpression= (IExpressionFragment) selectedFragment;
944 } else if (selectedFragment != null) {
945 if (selectedFragment.getAssociatedNode() instanceof ExpressionStatement) {
946 ExpressionStatement exprStatement= (ExpressionStatement) selectedFragment.getAssociatedNode();
947 Expression expression= exprStatement.getExpression();
948 fSelectedExpression= (IExpressionFragment) ASTFragmentFactory.createFragmentForFullSubtree(expression);
949 } else if (selectedFragment.getAssociatedNode() instanceof Assignment) {
950 Assignment assignment= (Assignment) selectedFragment.getAssociatedNode();
951 fSelectedExpression= (IExpressionFragment) ASTFragmentFactory.createFragmentForFullSubtree(assignment);
955 if (fSelectedExpression != null && Checks.isEnumCase(fSelectedExpression.getAssociatedExpression().getParent())) {
956 fSelectedExpression= null;
959 return fSelectedExpression;
962 private Type createTempType() throws CoreException {
963 Expression expression= getSelectedExpression().getAssociatedExpression();
965 Type resultingType= null;
966 ITypeBinding typeBinding= expression.resolveTypeBinding();
968 ASTRewrite rewrite= fCURewrite.getASTRewrite();
969 AST ast= rewrite.getAST();
971 if (expression instanceof ClassInstanceCreation && (typeBinding == null || typeBinding.getTypeArguments().length == 0)) {
972 resultingType= (Type) rewrite.createCopyTarget(((ClassInstanceCreation) expression).getType());
973 } else if (expression instanceof CastExpression) {
974 resultingType= (Type) rewrite.createCopyTarget(((CastExpression) expression).getType());
976 if (typeBinding == null) {
977 typeBinding= ASTResolving.guessBindingForReference(expression);
979 if (typeBinding != null) {
980 typeBinding= Bindings.normalizeForDeclarationUse(typeBinding, ast);
981 ImportRewrite importRewrite= fCURewrite.getImportRewrite();
982 ImportRewriteContext context= new ContextSensitiveImportRewriteContext(expression, importRewrite);
983 resultingType= importRewrite.addImport(typeBinding, ast, context);
985 resultingType= ast.newSimpleType(ast.newSimpleName("Object")); //$NON-NLS-1$
988 if (fLinkedProposalModel != null) {
989 LinkedProposalPositionGroup typeGroup= fLinkedProposalModel.getPositionGroup(KEY_TYPE, true);
990 typeGroup.addPosition(rewrite.track(resultingType), false);
991 if (typeBinding != null) {
992 ITypeBinding[] relaxingTypes= ASTResolving.getNarrowingTypes(ast, typeBinding);
993 for (int i= 0; i < relaxingTypes.length; i++) {
994 typeGroup.addProposal(relaxingTypes[i], fCURewrite.getCu(), relaxingTypes.length - i);
998 return resultingType;
1001 public String guessTempName() {
1002 String[] proposals= guessTempNames();
1003 if (proposals.length == 0)
1006 return proposals[0];
1010 * @return proposed variable names (may be empty, but not null). The first proposal should be used as "best guess" (if it exists).
1012 public String[] guessTempNames() {
1013 if (fGuessedTempNames == null) {
1015 Expression expression= getSelectedExpression().getAssociatedExpression();
1016 if (expression != null) {
1017 ITypeBinding binding= guessBindingForReference(expression);
1018 fGuessedTempNames= StubUtility.getVariableNameSuggestions(NamingConventions.VK_LOCAL, fCu.getJavaProject(), binding, expression, Arrays.asList(getExcludedVariableNames()));
1020 } catch (JavaModelException e) {
1022 if (fGuessedTempNames == null)
1023 fGuessedTempNames= new String[0];
1025 return fGuessedTempNames;
1028 private boolean isLiteralNodeSelected() throws JavaModelException {
1029 IExpressionFragment fragment= getSelectedExpression();
1030 if (fragment == null)
1032 Expression expression= fragment.getAssociatedExpression();
1033 if (expression == null)
1035 switch (expression.getNodeType()) {
1036 case ASTNode.BOOLEAN_LITERAL:
1037 case ASTNode.CHARACTER_LITERAL:
1038 case ASTNode.NULL_LITERAL:
1039 case ASTNode.NUMBER_LITERAL:
1047 private boolean isUsedInExplicitConstructorCall() throws JavaModelException {
1048 Expression selectedExpression= getSelectedExpression().getAssociatedExpression();
1049 if (ASTNodes.getParent(selectedExpression, ConstructorInvocation.class) != null)
1051 if (ASTNodes.getParent(selectedExpression, SuperConstructorInvocation.class) != null)
1056 public boolean replaceAllOccurrences() {
1057 return fReplaceAllOccurrences;
1060 private void replaceSelectedExpressionWithTempDeclaration() throws CoreException {
1061 ASTRewrite rewrite= fCURewrite.getASTRewrite();
1062 Expression selectedExpression= getSelectedExpression().getAssociatedExpression(); // whole expression selected
1064 Expression initializer= (Expression) rewrite.createMoveTarget(selectedExpression);
1065 VariableDeclarationStatement tempDeclaration= createTempDeclaration(initializer);
1066 ASTNode replacement;
1068 ASTNode parent= selectedExpression.getParent();
1069 boolean isParentLambda= parent instanceof LambdaExpression;
1070 AST ast= rewrite.getAST();
1071 if (isParentLambda) {
1072 Block blockBody= ast.newBlock();
1073 blockBody.statements().add(tempDeclaration);
1074 if (!Bindings.isVoidType(((LambdaExpression) parent).resolveMethodBinding().getReturnType())) {
1075 List<VariableDeclarationFragment> fragments= tempDeclaration.fragments();
1076 SimpleName varName= fragments.get(0).getName();
1077 ReturnStatement returnStatement= ast.newReturnStatement();
1078 returnStatement.setExpression(ast.newSimpleName(varName.getIdentifier()));
1079 blockBody.statements().add(returnStatement);
1081 replacement= blockBody;
1082 } else if (ASTNodes.isControlStatementBody(parent.getLocationInParent())) {
1083 Block block= ast.newBlock();
1084 block.statements().add(tempDeclaration);
1087 replacement= tempDeclaration;
1089 ASTNode replacee= isParentLambda || !ASTNodes.hasSemicolon((ExpressionStatement) parent, fCu) ? selectedExpression : parent;
1090 rewrite.replace(replacee, replacement, fCURewrite.createGroupDescription(RefactoringCoreMessages.ExtractTempRefactoring_declare_local_variable));
1093 public void setDeclareFinal(boolean declareFinal) {
1094 fDeclareFinal= declareFinal;
1097 public void setReplaceAllOccurrences(boolean replaceAllOccurrences) {
1098 fReplaceAllOccurrences= replaceAllOccurrences;
1101 public void setTempName(String newName) {
1105 private boolean shouldReplaceSelectedExpressionWithTempDeclaration() throws JavaModelException {
1106 IExpressionFragment selectedFragment= getSelectedExpression();
1107 IExpressionFragment firstExpression= getFirstReplacedExpression();
1108 if (firstExpression.getStartPosition() < selectedFragment.getStartPosition())
1110 ASTNode associatedNode= selectedFragment.getAssociatedNode();
1111 return (associatedNode.getParent() instanceof ExpressionStatement || associatedNode.getParent() instanceof LambdaExpression)
1112 && selectedFragment.matches(ASTFragmentFactory.createFragmentForFullSubtree(associatedNode));
1115 private RefactoringStatus initialize(JavaRefactoringArguments arguments) {
1116 final String selection= arguments.getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION);
1117 if (selection != null) {
1120 final StringTokenizer tokenizer= new StringTokenizer(selection);
1121 if (tokenizer.hasMoreTokens())
1122 offset= Integer.valueOf(tokenizer.nextToken()).intValue();
1123 if (tokenizer.hasMoreTokens())
1124 length= Integer.valueOf(tokenizer.nextToken()).intValue();
1125 if (offset >= 0 && length >= 0) {
1126 fSelectionStart= offset;
1127 fSelectionLength= length;
1129 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_illegal_argument, new Object[] { selection, JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION}));
1131 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION));
1132 final String handle= arguments.getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT);
1133 if (handle != null) {
1134 final IJavaElement element= JavaRefactoringDescriptorUtil.handleToElement(arguments.getProject(), handle, false);
1135 if (element == null || !element.exists() || element.getElementType() != IJavaElement.COMPILATION_UNIT)
1136 return JavaRefactoringDescriptorUtil.createInputFatalStatus(element, getName(), IJavaRefactorings.EXTRACT_LOCAL_VARIABLE);
1138 fCu= (ICompilationUnit) element;
1140 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT));
1141 final String name= arguments.getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME);
1142 if (name != null && !"".equals(name)) //$NON-NLS-1$
1145 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME));
1146 final String replace= arguments.getAttribute(ATTRIBUTE_REPLACE);
1147 if (replace != null) {
1148 fReplaceAllOccurrences= Boolean.valueOf(replace).booleanValue();
1150 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_REPLACE));
1151 final String declareFinal= arguments.getAttribute(ATTRIBUTE_FINAL);
1152 if (declareFinal != null) {
1153 fDeclareFinal= Boolean.valueOf(declareFinal).booleanValue();
1155 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_FINAL));
1156 return new RefactoringStatus();
1159 public MethodDeclaration getMethodDeclaration(){
1160 return methodDeclaration;