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);
437 * Anna's code from here
440 ASTNode exprstatement = fragment.getAssociatedNode();
441 while( !(exprstatement instanceof ExpressionStatement)){
442 exprstatement = exprstatement.getParent();
446 ASTNode block = exprstatement.getParent();
448 while(! (block instanceof Block)){
449 block = block.getParent();
450 exprstatement = exprstatement.getParent();
454 ListRewrite lr = rewrite.getListRewrite(block, Block.STATEMENTS_PROPERTY);
456 lr.insertBefore(getAssertStatement(block.getAST()), exprstatement, null);
462 fragment.replace(rewrite, tempName, description);
464 if (fLinkedProposalModel != null)
465 fLinkedProposalModel.getPositionGroup(KEY_NAME, true).addPosition(rewrite.track(tempName), false);
471 * @param ast the AST the Statement will belong to
472 * @return the assert statement, belonging to the input AST, used to check if the code is broken
474 private Statement getAssertStatement(AST ast){
475 AssertStatement assertStatement = ast.newAssertStatement();
476 InfixExpression infixExpression = ast.newInfixExpression();
478 infixExpression.setLeftOperand(ast.newSimpleName(fTempName));
479 infixExpression.setOperator(InfixExpression.Operator.EQUALS);
481 infixExpression.setRightOperand(ast.newName(fSelectedText));
482 assertStatement.setExpression(infixExpression);
483 StringLiteral stringLiteral = ast.newStringLiteral();
484 stringLiteral.setLiteralValue("The Move Method refactoring has broken the program due to aliasing issues!");
485 assertStatement.setMessage(stringLiteral);
486 return assertStatement;
489 private RefactoringStatus checkExpression() throws JavaModelException {
490 Expression selectedExpression= getSelectedExpression().getAssociatedExpression();
491 if (selectedExpression != null) {
492 final ASTNode parent= selectedExpression.getParent();
493 if (selectedExpression instanceof NullLiteral) {
494 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_null_literals);
495 } else if (selectedExpression instanceof ArrayInitializer) {
496 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_array_initializer);
497 } else if (selectedExpression instanceof Assignment) {
498 if (parent instanceof Expression && !(parent instanceof ParenthesizedExpression))
499 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_assignment);
502 } else if (selectedExpression instanceof SimpleName) {
503 if ((((SimpleName) selectedExpression)).isDeclaration())
504 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_names_in_declarations);
505 if (parent instanceof QualifiedName && selectedExpression.getLocationInParent() == QualifiedName.NAME_PROPERTY || parent instanceof FieldAccess && selectedExpression.getLocationInParent() == FieldAccess.NAME_PROPERTY)
506 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_select_expression);
507 } else if (selectedExpression instanceof VariableDeclarationExpression && parent instanceof TryStatement) {
508 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_resource_in_try_with_resources);
515 // !! Same as in ExtractConstantRefactoring
516 private RefactoringStatus checkExpressionFragmentIsRValue() throws JavaModelException {
517 switch (Checks.checkExpressionIsRValue(getSelectedExpression().getAssociatedExpression())) {
518 case Checks.NOT_RVALUE_MISC:
519 return RefactoringStatus.createStatus(RefactoringStatus.FATAL, RefactoringCoreMessages.ExtractTempRefactoring_select_expression, null, Corext.getPluginId(), RefactoringStatusCodes.EXPRESSION_NOT_RVALUE, null);
520 case Checks.NOT_RVALUE_VOID:
521 return RefactoringStatus.createStatus(RefactoringStatus.FATAL, RefactoringCoreMessages.ExtractTempRefactoring_no_void, null, Corext.getPluginId(), RefactoringStatusCodes.EXPRESSION_NOT_RVALUE_VOID, null);
522 case Checks.IS_RVALUE_GUESSED:
523 case Checks.IS_RVALUE:
524 return new RefactoringStatus();
526 Assert.isTrue(false);
531 private ITypeBinding guessBindingForReference(Expression expression) {
532 ITypeBinding binding= expression.resolveTypeBinding();
533 if (binding == null) {
534 binding= ASTResolving.guessBindingForReference(expression);
540 public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException {
542 pm.beginTask(RefactoringCoreMessages.ExtractTempRefactoring_checking_preconditions, 4);
544 fCURewrite= new CompilationUnitRewrite(fCu, fCompilationUnitNode);
545 fCURewrite.getASTRewrite().setTargetSourceRangeComputer(new NoCommentSourceRangeComputer());
547 doCreateChange(new SubProgressMonitor(pm, 2));
549 fChange= fCURewrite.createChange(RefactoringCoreMessages.ExtractTempRefactoring_change_name, true, new SubProgressMonitor(pm, 1));
551 RefactoringStatus result= new RefactoringStatus();
552 if (Arrays.asList(getExcludedVariableNames()).contains(fTempName))
553 result.addWarning(Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_another_variable, BasicElementLabels.getJavaElementName(fTempName)));
555 result.merge(checkMatchingFragments());
557 fChange.setKeepPreviewEdits(true);
559 if (fCheckResultForCompileProblems) {
560 checkNewSource(new SubProgressMonitor(pm, 1), result);
569 private final ExtractLocalDescriptor createRefactoringDescriptor() {
570 final Map<String, String> arguments= new HashMap<String, String>();
571 String project= null;
572 IJavaProject javaProject= fCu.getJavaProject();
573 if (javaProject != null)
574 project= javaProject.getElementName();
575 final String description= Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_descriptor_description_short, BasicElementLabels.getJavaElementName(fTempName));
576 final String expression= ASTNodes.asString(fSelectedExpression.getAssociatedExpression());
577 final String header= Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_descriptor_description, new String[] { BasicElementLabels.getJavaElementName(fTempName), BasicElementLabels.getJavaCodeString(expression)});
578 final JDTRefactoringDescriptorComment comment= new JDTRefactoringDescriptorComment(project, this, header);
579 comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_name_pattern, BasicElementLabels.getJavaElementName(fTempName)));
580 final BodyDeclaration decl= (BodyDeclaration) ASTNodes.getParent(fSelectedExpression.getAssociatedExpression(), BodyDeclaration.class);
581 if (decl instanceof MethodDeclaration) {
582 final IMethodBinding method= ((MethodDeclaration) decl).resolveBinding();
583 final String label= method != null ? BindingLabelProvider.getBindingLabel(method, JavaElementLabels.ALL_FULLY_QUALIFIED) : BasicElementLabels.getJavaElementName('{' + JavaElementLabels.ELLIPSIS_STRING + '}');
584 comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_destination_pattern, label));
586 comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_expression_pattern, BasicElementLabels.getJavaCodeString(expression)));
587 if (fReplaceAllOccurrences)
588 comment.addSetting(RefactoringCoreMessages.ExtractTempRefactoring_replace_occurrences);
590 comment.addSetting(RefactoringCoreMessages.ExtractTempRefactoring_declare_final);
591 final ExtractLocalDescriptor descriptor= RefactoringSignatureDescriptorFactory.createExtractLocalDescriptor(project, description, comment.asString(), arguments, RefactoringDescriptor.NONE);
592 arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT, JavaRefactoringDescriptorUtil.elementToHandle(project, fCu));
593 arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME, fTempName);
594 arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION, new Integer(fSelectionStart).toString() + " " + new Integer(fSelectionLength).toString()); //$NON-NLS-1$
595 arguments.put(ATTRIBUTE_REPLACE, Boolean.valueOf(fReplaceAllOccurrences).toString());
596 arguments.put(ATTRIBUTE_FINAL, Boolean.valueOf(fDeclareFinal).toString());
600 private void doCreateChange(IProgressMonitor pm) throws CoreException {
602 pm.beginTask(RefactoringCoreMessages.ExtractTempRefactoring_checking_preconditions, 1);
604 createTempDeclaration();
605 } catch (CoreException exception) {
606 JavaPlugin.log(exception);
608 addReplaceExpressionWithTemp();
614 private void checkNewSource(SubProgressMonitor monitor, RefactoringStatus result) throws CoreException {
615 String newCuSource= fChange.getPreviewContent(new NullProgressMonitor());
616 CompilationUnit newCUNode= new RefactoringASTParser(ASTProvider.SHARED_AST_LEVEL).parse(newCuSource, fCu, true, true, monitor);
617 IProblem[] newProblems= RefactoringAnalyzeUtil.getIntroducedCompileProblems(newCUNode, fCompilationUnitNode);
618 for (int i= 0; i < newProblems.length; i++) {
619 IProblem problem= newProblems[i];
620 if (problem.isError())
621 result.addEntry(new RefactoringStatusEntry((problem.isError() ? RefactoringStatus.ERROR : RefactoringStatus.WARNING), problem.getMessage(), new JavaStringStatusContext(newCuSource, SourceRangeFactory.create(problem))));
626 public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException {
628 pm.beginTask("", 6); //$NON-NLS-1$
630 RefactoringStatus result= Checks.validateModifiesFiles(ResourceUtil.getFiles(new ICompilationUnit[] { fCu}), getValidationContext());
631 if (result.hasFatalError())
634 if (fCompilationUnitNode == null) {
635 fCompilationUnitNode= RefactoringASTParser.parseWithASTProvider(fCu, true, new SubProgressMonitor(pm, 3));
640 result.merge(checkSelection(new SubProgressMonitor(pm, 3)));
641 if (!result.hasFatalError() && isLiteralNodeSelected())
642 fReplaceAllOccurrences= false;
650 private RefactoringStatus checkMatchingFragments() throws JavaModelException {
651 RefactoringStatus result= new RefactoringStatus();
652 IASTFragment[] matchingFragments= getMatchingFragments();
653 for (int i= 0; i < matchingFragments.length; i++) {
654 ASTNode node= matchingFragments[i].getAssociatedNode();
655 if (isLeftValue(node) && !isReferringToLocalVariableFromFor((Expression) node)) {
656 String msg= RefactoringCoreMessages.ExtractTempRefactoring_assigned_to;
657 result.addWarning(msg, JavaStatusContext.create(fCu, node));
663 private RefactoringStatus checkSelection(IProgressMonitor pm) throws JavaModelException {
665 pm.beginTask("", 8); //$NON-NLS-1$
667 IExpressionFragment selectedExpression= getSelectedExpression();
669 if (selectedExpression == null) {
670 String message= RefactoringCoreMessages.ExtractTempRefactoring_select_expression;
671 return CodeRefactoringUtil.checkMethodSyntaxErrors(fSelectionStart, fSelectionLength, fCompilationUnitNode, message);
675 if (isUsedInExplicitConstructorCall())
676 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_explicit_constructor);
679 ASTNode associatedNode= selectedExpression.getAssociatedNode();
680 if (getEnclosingBodyNode() == null || ASTNodes.getParent(associatedNode, Annotation.class) != null)
681 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_expr_in_method_or_initializer);
684 if (associatedNode instanceof Name && associatedNode.getParent() instanceof ClassInstanceCreation && associatedNode.getLocationInParent() == ClassInstanceCreation.TYPE_PROPERTY)
685 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_name_in_new);
688 RefactoringStatus result= new RefactoringStatus();
689 result.merge(checkExpression());
690 if (result.hasFatalError())
694 result.merge(checkExpressionFragmentIsRValue());
695 if (result.hasFatalError())
699 if (isUsedInForInitializerOrUpdater(getSelectedExpression().getAssociatedExpression()))
700 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_for_initializer_updater);
703 if (isReferringToLocalVariableFromFor(getSelectedExpression().getAssociatedExpression()))
704 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_refers_to_for_variable);
713 public RefactoringStatus checkTempName(String newName) {
714 RefactoringStatus status= Checks.checkTempName(newName, fCu);
715 if (Arrays.asList(getExcludedVariableNames()).contains(newName))
716 status.addWarning(Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_another_variable, BasicElementLabels.getJavaElementName(newName)));
720 private void createAndInsertTempDeclaration() throws CoreException {
721 Expression initializer= getSelectedExpression().createCopyTarget(fCURewrite.getASTRewrite(), true);
722 VariableDeclarationStatement vds= createTempDeclaration(initializer);
724 IASTFragment[] replacableMatches= retainOnlyReplacableMatches(getMatchingFragments());
725 if (!fReplaceAllOccurrences
726 || replacableMatches.length == 0
727 || replacableMatches.length == 1 && replacableMatches[0].equals(getSelectedExpression().getAssociatedExpression())) {
728 insertAt(getSelectedExpression().getAssociatedNode(), vds);
732 ASTNode[] firstReplaceNodeParents= getParents(getFirstReplacedExpression().getAssociatedNode());
733 ASTNode[] commonPath= findDeepestCommonSuperNodePathForReplacedNodes();
734 Assert.isTrue(commonPath.length <= firstReplaceNodeParents.length);
736 ASTNode deepestCommonParent= firstReplaceNodeParents[commonPath.length - 1];
737 if (deepestCommonParent instanceof Block)
738 insertAt(firstReplaceNodeParents[commonPath.length], vds);
740 insertAt(deepestCommonParent, vds);
743 private VariableDeclarationStatement createTempDeclaration(Expression initializer) throws CoreException {
744 AST ast= fCURewrite.getAST();
746 VariableDeclarationFragment vdf= ast.newVariableDeclarationFragment();
747 vdf.setName(ast.newSimpleName(fTempName));
748 vdf.setInitializer(initializer);
750 VariableDeclarationStatement vds= ast.newVariableDeclarationStatement(vdf);
752 vds.modifiers().add(ast.newModifier(ModifierKeyword.FINAL_KEYWORD));
754 vds.setType(createTempType());
756 if (fLinkedProposalModel != null) {
757 ASTRewrite rewrite= fCURewrite.getASTRewrite();
758 LinkedProposalPositionGroup nameGroup= fLinkedProposalModel.getPositionGroup(KEY_NAME, true);
759 nameGroup.addPosition(rewrite.track(vdf.getName()), true);
761 String[] nameSuggestions= guessTempNames();
762 if (nameSuggestions.length > 0 && !nameSuggestions[0].equals(fTempName)) {
763 nameGroup.addProposal(fTempName, null, nameSuggestions.length + 1);
765 for (int i= 0; i < nameSuggestions.length; i++) {
766 nameGroup.addProposal(nameSuggestions[i], null, nameSuggestions.length - i);
772 private void insertAt(ASTNode target, Statement declaration) {
773 ASTRewrite rewrite= fCURewrite.getASTRewrite();
774 TextEditGroup groupDescription= fCURewrite.createGroupDescription(RefactoringCoreMessages.ExtractTempRefactoring_declare_local_variable);
776 ASTNode parent= target.getParent();
777 StructuralPropertyDescriptor locationInParent= target.getLocationInParent();
778 while (locationInParent != Block.STATEMENTS_PROPERTY && locationInParent != SwitchStatement.STATEMENTS_PROPERTY) {
779 if (locationInParent == IfStatement.THEN_STATEMENT_PROPERTY
780 || locationInParent == IfStatement.ELSE_STATEMENT_PROPERTY
781 || locationInParent == ForStatement.BODY_PROPERTY
782 || locationInParent == EnhancedForStatement.BODY_PROPERTY
783 || locationInParent == DoStatement.BODY_PROPERTY
784 || locationInParent == WhileStatement.BODY_PROPERTY) {
785 // create intermediate block if target was the body property of a control statement:
786 Block replacement= rewrite.getAST().newBlock();
787 ListRewrite replacementRewrite= rewrite.getListRewrite(replacement, Block.STATEMENTS_PROPERTY);
788 replacementRewrite.insertFirst(declaration, null);
789 replacementRewrite.insertLast(rewrite.createMoveTarget(target), null);
790 rewrite.replace(target, replacement, groupDescription);
792 } else if (locationInParent == LambdaExpression.BODY_PROPERTY && ((LambdaExpression) parent).getBody() instanceof Expression) {
793 Block replacement= rewrite.getAST().newBlock();
794 ListRewrite replacementRewrite= rewrite.getListRewrite(replacement, Block.STATEMENTS_PROPERTY);
795 replacementRewrite.insertFirst(declaration, null);
796 ASTNode moveTarget= rewrite.createMoveTarget(target);
797 AST ast= rewrite.getAST();
798 if (Bindings.isVoidType(((LambdaExpression) parent).resolveMethodBinding().getReturnType())) {
799 ExpressionStatement expressionStatement= ast.newExpressionStatement((Expression) moveTarget);
800 moveTarget= expressionStatement;
802 ReturnStatement returnStatement= ast.newReturnStatement();
803 returnStatement.setExpression((Expression) moveTarget);
804 moveTarget= returnStatement;
806 replacementRewrite.insertLast(moveTarget, null);
807 rewrite.replace(target, replacement, groupDescription);
811 parent= parent.getParent();
812 locationInParent= target.getLocationInParent();
814 ListRewrite listRewrite= rewrite.getListRewrite(parent, (ChildListPropertyDescriptor)locationInParent);
815 listRewrite.insertBefore(declaration, target, groupDescription);
819 public Change createChange(IProgressMonitor pm) throws CoreException {
821 pm.beginTask(RefactoringCoreMessages.ExtractTempRefactoring_checking_preconditions, 1);
823 ExtractLocalDescriptor descriptor= createRefactoringDescriptor();
824 fChange.setDescriptor(new RefactoringChangeDescriptor(descriptor));
831 private void createTempDeclaration() throws CoreException {
832 if (shouldReplaceSelectedExpressionWithTempDeclaration())
833 replaceSelectedExpressionWithTempDeclaration();
835 createAndInsertTempDeclaration();
838 public boolean declareFinal() {
839 return fDeclareFinal;
842 private ASTNode[] findDeepestCommonSuperNodePathForReplacedNodes() throws JavaModelException {
843 ASTNode[] matchNodes= getMatchNodes();
845 ASTNode[][] matchingNodesParents= new ASTNode[matchNodes.length][];
846 for (int i= 0; i < matchNodes.length; i++) {
847 matchingNodesParents[i]= getParents(matchNodes[i]);
849 List<Object> l= Arrays.asList(getLongestArrayPrefix(matchingNodesParents));
850 return l.toArray(new ASTNode[l.size()]);
853 private ASTNode getEnclosingBodyNode() throws JavaModelException {
854 ASTNode node= getSelectedExpression().getAssociatedNode();
856 // expression must be in a method, lambda or initializer body
857 // make sure it is not in method or parameter annotation
858 StructuralPropertyDescriptor location= null;
859 while (node != null && !(node instanceof BodyDeclaration)) {
860 location= node.getLocationInParent();
861 node= node.getParent();
862 if (node instanceof LambdaExpression) {
866 if (location == MethodDeclaration.BODY_PROPERTY || location == Initializer.BODY_PROPERTY
867 || (location == LambdaExpression.BODY_PROPERTY && ((LambdaExpression) node).resolveMethodBinding() != null)) {
868 return (ASTNode) node.getStructuralProperty(location);
873 private String[] getExcludedVariableNames() {
874 if (fExcludedVariableNames == null) {
876 IBinding[] bindings= new ScopeAnalyzer(fCompilationUnitNode).getDeclarationsInScope(getSelectedExpression().getStartPosition(), ScopeAnalyzer.VARIABLES
877 | ScopeAnalyzer.CHECK_VISIBILITY);
878 fExcludedVariableNames= new String[bindings.length];
879 for (int i= 0; i < bindings.length; i++) {
880 fExcludedVariableNames[i]= bindings[i].getName();
882 } catch (JavaModelException e) {
883 fExcludedVariableNames= new String[0];
886 return fExcludedVariableNames;
889 private IExpressionFragment getFirstReplacedExpression() throws JavaModelException {
890 if (!fReplaceAllOccurrences)
891 return getSelectedExpression();
892 IASTFragment[] nodesToReplace= retainOnlyReplacableMatches(getMatchingFragments());
893 if (nodesToReplace.length == 0)
894 return getSelectedExpression();
895 Comparator<IASTFragment> comparator= new Comparator<IASTFragment>() {
897 public int compare(IASTFragment o1, IASTFragment o2) {
898 return o1.getStartPosition() - o2.getStartPosition();
901 Arrays.sort(nodesToReplace, comparator);
902 return (IExpressionFragment) nodesToReplace[0];
905 private IASTFragment[] getMatchingFragments() throws JavaModelException {
906 if (fReplaceAllOccurrences) {
907 IASTFragment[] allMatches= ASTFragmentFactory.createFragmentForFullSubtree(getEnclosingBodyNode()).getSubFragmentsMatching(getSelectedExpression());
910 return new IASTFragment[] { getSelectedExpression()};
913 private ASTNode[] getMatchNodes() throws JavaModelException {
914 IASTFragment[] matches= retainOnlyReplacableMatches(getMatchingFragments());
915 ASTNode[] result= new ASTNode[matches.length];
916 for (int i= 0; i < matches.length; i++)
917 result[i]= matches[i].getAssociatedNode();
922 public String getName() {
923 return RefactoringCoreMessages.ExtractTempRefactoring_name;
927 private IExpressionFragment getSelectedExpression() throws JavaModelException {
928 if (fSelectedExpression != null)
929 return fSelectedExpression;
930 IASTFragment selectedFragment= ASTFragmentFactory.createFragmentForSourceRange(new SourceRange(fSelectionStart, fSelectionLength), fCompilationUnitNode, fCu);
932 if (selectedFragment instanceof IExpressionFragment && !Checks.isInsideJavadoc(selectedFragment.getAssociatedNode())) {
933 fSelectedExpression= (IExpressionFragment) selectedFragment;
934 } else if (selectedFragment != null) {
935 if (selectedFragment.getAssociatedNode() instanceof ExpressionStatement) {
936 ExpressionStatement exprStatement= (ExpressionStatement) selectedFragment.getAssociatedNode();
937 Expression expression= exprStatement.getExpression();
938 fSelectedExpression= (IExpressionFragment) ASTFragmentFactory.createFragmentForFullSubtree(expression);
939 } else if (selectedFragment.getAssociatedNode() instanceof Assignment) {
940 Assignment assignment= (Assignment) selectedFragment.getAssociatedNode();
941 fSelectedExpression= (IExpressionFragment) ASTFragmentFactory.createFragmentForFullSubtree(assignment);
945 if (fSelectedExpression != null && Checks.isEnumCase(fSelectedExpression.getAssociatedExpression().getParent())) {
946 fSelectedExpression= null;
949 return fSelectedExpression;
952 private Type createTempType() throws CoreException {
953 Expression expression= getSelectedExpression().getAssociatedExpression();
955 Type resultingType= null;
956 ITypeBinding typeBinding= expression.resolveTypeBinding();
958 ASTRewrite rewrite= fCURewrite.getASTRewrite();
959 AST ast= rewrite.getAST();
961 if (expression instanceof ClassInstanceCreation && (typeBinding == null || typeBinding.getTypeArguments().length == 0)) {
962 resultingType= (Type) rewrite.createCopyTarget(((ClassInstanceCreation) expression).getType());
963 } else if (expression instanceof CastExpression) {
964 resultingType= (Type) rewrite.createCopyTarget(((CastExpression) expression).getType());
966 if (typeBinding == null) {
967 typeBinding= ASTResolving.guessBindingForReference(expression);
969 if (typeBinding != null) {
970 typeBinding= Bindings.normalizeForDeclarationUse(typeBinding, ast);
971 ImportRewrite importRewrite= fCURewrite.getImportRewrite();
972 ImportRewriteContext context= new ContextSensitiveImportRewriteContext(expression, importRewrite);
973 resultingType= importRewrite.addImport(typeBinding, ast, context);
975 resultingType= ast.newSimpleType(ast.newSimpleName("Object")); //$NON-NLS-1$
978 if (fLinkedProposalModel != null) {
979 LinkedProposalPositionGroup typeGroup= fLinkedProposalModel.getPositionGroup(KEY_TYPE, true);
980 typeGroup.addPosition(rewrite.track(resultingType), false);
981 if (typeBinding != null) {
982 ITypeBinding[] relaxingTypes= ASTResolving.getNarrowingTypes(ast, typeBinding);
983 for (int i= 0; i < relaxingTypes.length; i++) {
984 typeGroup.addProposal(relaxingTypes[i], fCURewrite.getCu(), relaxingTypes.length - i);
988 return resultingType;
991 public String guessTempName() {
992 String[] proposals= guessTempNames();
993 if (proposals.length == 0)
1000 * @return proposed variable names (may be empty, but not null). The first proposal should be used as "best guess" (if it exists).
1002 public String[] guessTempNames() {
1003 if (fGuessedTempNames == null) {
1005 Expression expression= getSelectedExpression().getAssociatedExpression();
1006 if (expression != null) {
1007 ITypeBinding binding= guessBindingForReference(expression);
1008 fGuessedTempNames= StubUtility.getVariableNameSuggestions(NamingConventions.VK_LOCAL, fCu.getJavaProject(), binding, expression, Arrays.asList(getExcludedVariableNames()));
1010 } catch (JavaModelException e) {
1012 if (fGuessedTempNames == null)
1013 fGuessedTempNames= new String[0];
1015 return fGuessedTempNames;
1018 private boolean isLiteralNodeSelected() throws JavaModelException {
1019 IExpressionFragment fragment= getSelectedExpression();
1020 if (fragment == null)
1022 Expression expression= fragment.getAssociatedExpression();
1023 if (expression == null)
1025 switch (expression.getNodeType()) {
1026 case ASTNode.BOOLEAN_LITERAL:
1027 case ASTNode.CHARACTER_LITERAL:
1028 case ASTNode.NULL_LITERAL:
1029 case ASTNode.NUMBER_LITERAL:
1037 private boolean isUsedInExplicitConstructorCall() throws JavaModelException {
1038 Expression selectedExpression= getSelectedExpression().getAssociatedExpression();
1039 if (ASTNodes.getParent(selectedExpression, ConstructorInvocation.class) != null)
1041 if (ASTNodes.getParent(selectedExpression, SuperConstructorInvocation.class) != null)
1046 public boolean replaceAllOccurrences() {
1047 return fReplaceAllOccurrences;
1050 private void replaceSelectedExpressionWithTempDeclaration() throws CoreException {
1051 ASTRewrite rewrite= fCURewrite.getASTRewrite();
1052 Expression selectedExpression= getSelectedExpression().getAssociatedExpression(); // whole expression selected
1054 Expression initializer= (Expression) rewrite.createMoveTarget(selectedExpression);
1055 VariableDeclarationStatement tempDeclaration= createTempDeclaration(initializer);
1056 ASTNode replacement;
1058 ASTNode parent= selectedExpression.getParent();
1059 boolean isParentLambda= parent instanceof LambdaExpression;
1060 AST ast= rewrite.getAST();
1061 if (isParentLambda) {
1062 Block blockBody= ast.newBlock();
1063 blockBody.statements().add(tempDeclaration);
1064 if (!Bindings.isVoidType(((LambdaExpression) parent).resolveMethodBinding().getReturnType())) {
1065 List<VariableDeclarationFragment> fragments= tempDeclaration.fragments();
1066 SimpleName varName= fragments.get(0).getName();
1067 ReturnStatement returnStatement= ast.newReturnStatement();
1068 returnStatement.setExpression(ast.newSimpleName(varName.getIdentifier()));
1069 blockBody.statements().add(returnStatement);
1071 replacement= blockBody;
1072 } else if (ASTNodes.isControlStatementBody(parent.getLocationInParent())) {
1073 Block block= ast.newBlock();
1074 block.statements().add(tempDeclaration);
1077 replacement= tempDeclaration;
1079 ASTNode replacee= isParentLambda || !ASTNodes.hasSemicolon((ExpressionStatement) parent, fCu) ? selectedExpression : parent;
1080 rewrite.replace(replacee, replacement, fCURewrite.createGroupDescription(RefactoringCoreMessages.ExtractTempRefactoring_declare_local_variable));
1083 public void setDeclareFinal(boolean declareFinal) {
1084 fDeclareFinal= declareFinal;
1087 public void setReplaceAllOccurrences(boolean replaceAllOccurrences) {
1088 fReplaceAllOccurrences= replaceAllOccurrences;
1091 public void setTempName(String newName) {
1095 private boolean shouldReplaceSelectedExpressionWithTempDeclaration() throws JavaModelException {
1096 IExpressionFragment selectedFragment= getSelectedExpression();
1097 IExpressionFragment firstExpression= getFirstReplacedExpression();
1098 if (firstExpression.getStartPosition() < selectedFragment.getStartPosition())
1100 ASTNode associatedNode= selectedFragment.getAssociatedNode();
1101 return (associatedNode.getParent() instanceof ExpressionStatement || associatedNode.getParent() instanceof LambdaExpression)
1102 && selectedFragment.matches(ASTFragmentFactory.createFragmentForFullSubtree(associatedNode));
1105 private RefactoringStatus initialize(JavaRefactoringArguments arguments) {
1106 final String selection= arguments.getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION);
1107 if (selection != null) {
1110 final StringTokenizer tokenizer= new StringTokenizer(selection);
1111 if (tokenizer.hasMoreTokens())
1112 offset= Integer.valueOf(tokenizer.nextToken()).intValue();
1113 if (tokenizer.hasMoreTokens())
1114 length= Integer.valueOf(tokenizer.nextToken()).intValue();
1115 if (offset >= 0 && length >= 0) {
1116 fSelectionStart= offset;
1117 fSelectionLength= length;
1119 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_illegal_argument, new Object[] { selection, JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION}));
1121 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION));
1122 final String handle= arguments.getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT);
1123 if (handle != null) {
1124 final IJavaElement element= JavaRefactoringDescriptorUtil.handleToElement(arguments.getProject(), handle, false);
1125 if (element == null || !element.exists() || element.getElementType() != IJavaElement.COMPILATION_UNIT)
1126 return JavaRefactoringDescriptorUtil.createInputFatalStatus(element, getName(), IJavaRefactorings.EXTRACT_LOCAL_VARIABLE);
1128 fCu= (ICompilationUnit) element;
1130 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT));
1131 final String name= arguments.getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME);
1132 if (name != null && !"".equals(name)) //$NON-NLS-1$
1135 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME));
1136 final String replace= arguments.getAttribute(ATTRIBUTE_REPLACE);
1137 if (replace != null) {
1138 fReplaceAllOccurrences= Boolean.valueOf(replace).booleanValue();
1140 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_REPLACE));
1141 final String declareFinal= arguments.getAttribute(ATTRIBUTE_FINAL);
1142 if (declareFinal != null) {
1143 fDeclareFinal= Boolean.valueOf(declareFinal).booleanValue();
1145 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_FINAL));
1146 return new RefactoringStatus();
1149 public MethodDeclaration getMethodDeclaration(){
1150 return methodDeclaration;