blob: c1815ed33481f30fb07c70591e556848367ba475 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2020 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
* Nikolay Metchev <nikolaymetchev@gmail.com> - [extract local] Extract to local variable not replacing multiple occurrences in same statement - https://bugs.eclipse.org/406347
* Nicolaj Hoess <nicohoess@gmail.com> - [extract local] puts declaration at wrong position - https://bugs.eclipse.org/65875
* Pierre-Yves B. <pyvesdev@gmail.com> - [inline] Allow inlining of local variable initialized to null. - https://bugs.eclipse.org/93850
*******************************************************************************/
package org.eclipse.jdt.internal.corext.refactoring.code;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.text.edits.TextEditGroup;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.Refactoring;
import org.eclipse.ltk.core.refactoring.RefactoringChangeDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.NamingConventions;
import org.eclipse.jdt.core.SourceRange;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.ArrayInitializer;
import org.eclipse.jdt.core.dom.Assignment;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.CastExpression;
import org.eclipse.jdt.core.dom.CatchClause;
import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.ConstructorInvocation;
import org.eclipse.jdt.core.dom.DoStatement;
import org.eclipse.jdt.core.dom.EnhancedForStatement;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.ExpressionStatement;
import org.eclipse.jdt.core.dom.FieldAccess;
import org.eclipse.jdt.core.dom.ForStatement;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.IfStatement;
import org.eclipse.jdt.core.dom.Initializer;
import org.eclipse.jdt.core.dom.LambdaExpression;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.NullLiteral;
import org.eclipse.jdt.core.dom.ParenthesizedExpression;
import org.eclipse.jdt.core.dom.PostfixExpression;
import org.eclipse.jdt.core.dom.PrefixExpression;
import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.ReturnStatement;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.Statement;
import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
import org.eclipse.jdt.core.dom.SwitchCase;
import org.eclipse.jdt.core.dom.SwitchStatement;
import org.eclipse.jdt.core.dom.TryStatement;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
import org.eclipse.jdt.core.dom.WhileStatement;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.TypeLocation;
import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
import org.eclipse.jdt.core.refactoring.CompilationUnitChange;
import org.eclipse.jdt.core.refactoring.IJavaRefactorings;
import org.eclipse.jdt.core.refactoring.descriptors.ExtractLocalDescriptor;
import org.eclipse.jdt.internal.core.manipulation.StubUtility;
import org.eclipse.jdt.internal.core.manipulation.dom.ASTResolving;
import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels;
import org.eclipse.jdt.internal.core.refactoring.descriptors.RefactoringSignatureDescriptorFactory;
import org.eclipse.jdt.internal.corext.Corext;
import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext;
import org.eclipse.jdt.internal.corext.dom.ASTNodes;
import org.eclipse.jdt.internal.corext.dom.Bindings;
import org.eclipse.jdt.internal.corext.dom.ScopeAnalyzer;
import org.eclipse.jdt.internal.corext.dom.fragments.ASTFragmentFactory;
import org.eclipse.jdt.internal.corext.dom.fragments.IASTFragment;
import org.eclipse.jdt.internal.corext.dom.fragments.IExpressionFragment;
import org.eclipse.jdt.internal.corext.fix.LinkedProposalModel;
import org.eclipse.jdt.internal.corext.fix.LinkedProposalPositionGroup;
import org.eclipse.jdt.internal.corext.refactoring.Checks;
import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment;
import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringArguments;
import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringDescriptorUtil;
import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
import org.eclipse.jdt.internal.corext.refactoring.base.RefactoringStatusCodes;
import org.eclipse.jdt.internal.corext.refactoring.rename.RefactoringAnalyzeUtil;
import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite;
import org.eclipse.jdt.internal.corext.refactoring.util.JavaStatusContext;
import org.eclipse.jdt.internal.corext.refactoring.util.NoCommentSourceRangeComputer;
import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;
import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.eclipse.jdt.internal.corext.util.Messages;
import org.eclipse.jdt.ui.JavaElementLabels;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.viewsupport.BindingLabelProvider;
/**
* Extract Local Variable (from selected expression inside method or initializer).
*/
public class ExtractTempRefactoring extends Refactoring {
private static final String ATTRIBUTE_REPLACE= "replace"; //$NON-NLS-1$
private static final String ATTRIBUTE_FINAL= "final"; //$NON-NLS-1$
private static final String ATTRIBUTE_TYPE_VAR= "varType"; //$NON-NLS-1$
private static final class ForStatementChecker extends ASTVisitor {
private final Collection<IVariableBinding> fForInitializerVariables;
private boolean fReferringToForVariable= false;
public ForStatementChecker(Collection<IVariableBinding> forInitializerVariables) {
Assert.isNotNull(forInitializerVariables);
fForInitializerVariables= forInitializerVariables;
}
public boolean isReferringToForVariable() {
return fReferringToForVariable;
}
@Override
public boolean visit(SimpleName node) {
IBinding binding= node.resolveBinding();
if (binding != null && fForInitializerVariables.contains(binding)) {
fReferringToForVariable= true;
}
return false;
}
}
private static boolean allArraysEqual(ASTNode[][] arrays, int position) {
Object element= arrays[0][position];
for (ASTNode[] a : arrays) {
Object[] array= a;
if (!element.equals(array[position]))
return false;
}
return true;
}
private static boolean canReplace(IASTFragment fragment) {
ASTNode node= fragment.getAssociatedNode();
ASTNode parent= node.getParent();
if (parent instanceof VariableDeclarationFragment) {
VariableDeclarationFragment vdf= (VariableDeclarationFragment) parent;
if (node.equals(vdf.getName()))
return false;
}
if (isMethodParameter(node))
return false;
if (isThrowableInCatchBlock(node))
return false;
if (parent instanceof ExpressionStatement)
return false;
if (parent instanceof LambdaExpression)
return false;
if (isLeftValue(node))
return false;
if (isReferringToLocalVariableFromFor((Expression) node))
return false;
if (isUsedInForInitializerOrUpdater((Expression) node))
return false;
if (parent instanceof SwitchCase)
return false;
if (node instanceof SimpleName && node.getLocationInParent() != null) {
return !node.getLocationInParent().getId().equals("name"); //$NON-NLS-1$
}
return true;
}
private static ASTNode[] getArrayPrefix(ASTNode[] array, int prefixLength) {
Assert.isTrue(prefixLength <= array.length);
Assert.isTrue(prefixLength >= 0);
ASTNode[] prefix= new ASTNode[prefixLength];
System.arraycopy(array, 0, prefix, 0, prefix.length);
return prefix;
}
// return List<IVariableBinding>
private static List<IVariableBinding> getForInitializedVariables(VariableDeclarationExpression variableDeclarations) {
List<IVariableBinding> forInitializerVariables= new ArrayList<>(1);
for (Iterator<VariableDeclarationFragment> iter= variableDeclarations.fragments().iterator(); iter.hasNext();) {
VariableDeclarationFragment fragment= iter.next();
IVariableBinding binding= fragment.resolveBinding();
if (binding != null)
forInitializerVariables.add(binding);
}
return forInitializerVariables;
}
private static ASTNode[] getLongestArrayPrefix(ASTNode[][] arrays) {
int length= -1;
if (arrays.length == 0)
return new ASTNode[0];
int minArrayLength= arrays[0].length;
for (int i= 1; i < arrays.length; i++)
minArrayLength= Math.min(minArrayLength, arrays[i].length);
for (int i= 0; i < minArrayLength; i++) {
if (!allArraysEqual(arrays, i))
break;
length++;
}
if (length == -1)
return new ASTNode[0];
return getArrayPrefix(arrays[0], length + 1);
}
private static ASTNode[] getParents(ASTNode node) {
ASTNode current= node;
List<ASTNode> parents= new ArrayList<>();
do {
parents.add(current.getParent());
current= current.getParent();
} while (current.getParent() != null);
Collections.reverse(parents);
return parents.toArray(new ASTNode[parents.size()]);
}
private static boolean isLeftValue(ASTNode node) {
ASTNode parent= node.getParent();
if (parent instanceof Assignment) {
Assignment assignment= (Assignment) parent;
if (assignment.getLeftHandSide() == node)
return true;
}
if (parent instanceof PostfixExpression)
return true;
if (parent instanceof PrefixExpression) {
PrefixExpression.Operator op= ((PrefixExpression) parent).getOperator();
if (op.equals(PrefixExpression.Operator.DECREMENT))
return true;
if (op.equals(PrefixExpression.Operator.INCREMENT))
return true;
return false;
}
return false;
}
private static boolean isMethodParameter(ASTNode node) {
return (node instanceof SimpleName) && (node.getParent() instanceof SingleVariableDeclaration) && (node.getParent().getParent() instanceof MethodDeclaration);
}
private static boolean isReferringToLocalVariableFromFor(Expression expression) {
ASTNode current= expression;
ASTNode parent= current.getParent();
while (parent != null && !(parent instanceof BodyDeclaration)) {
if (parent instanceof ForStatement) {
ForStatement forStmt= (ForStatement) parent;
if (forStmt.initializers().contains(current) || forStmt.updaters().contains(current) || forStmt.getExpression() == current) {
List<Expression> initializers= forStmt.initializers();
if (initializers.size() == 1 && initializers.get(0) instanceof VariableDeclarationExpression) {
List<IVariableBinding> forInitializerVariables= getForInitializedVariables((VariableDeclarationExpression) initializers.get(0));
ForStatementChecker checker= new ForStatementChecker(forInitializerVariables);
expression.accept(checker);
if (checker.isReferringToForVariable())
return true;
}
}
}
current= parent;
parent= current.getParent();
}
return false;
}
private static boolean isThrowableInCatchBlock(ASTNode node) {
return (node instanceof SimpleName) && (node.getParent() instanceof SingleVariableDeclaration) && (node.getParent().getParent() instanceof CatchClause);
}
private static boolean isUsedInForInitializerOrUpdater(Expression expression) {
ASTNode parent= expression.getParent();
if (parent instanceof ForStatement) {
ForStatement forStmt= (ForStatement) parent;
return forStmt.initializers().contains(expression) || forStmt.updaters().contains(expression);
}
return false;
}
private static IASTFragment[] retainOnlyReplacableMatches(IASTFragment[] allMatches) {
List<IASTFragment> result= new ArrayList<>(allMatches.length);
for (IASTFragment match : allMatches) {
if (canReplace(match)) {
result.add(match);
}
}
return result.toArray(new IASTFragment[result.size()]);
}
private CompilationUnit fCompilationUnitNode;
private CompilationUnitRewrite fCURewrite;
private ICompilationUnit fCu;
private boolean fDeclareFinal;
private boolean fDeclareVarType;
private String[] fExcludedVariableNames;
private boolean fReplaceAllOccurrences;
// caches:
private IExpressionFragment fSelectedExpression;
private int fSelectionLength;
private int fSelectionStart;
private String fTempName;
private String[] fGuessedTempNames;
private boolean fCheckResultForCompileProblems;
private CompilationUnitChange fChange;
private LinkedProposalModel fLinkedProposalModel;
private static final String KEY_NAME= "name"; //$NON-NLS-1$
private static final String KEY_TYPE= "type"; //$NON-NLS-1$
/**
* Creates a new extract temp refactoring
* @param unit the compilation unit, or <code>null</code> if invoked by scripting
* @param selectionStart start of selection
* @param selectionLength length of selection
*/
public ExtractTempRefactoring(ICompilationUnit unit, int selectionStart, int selectionLength) {
Assert.isTrue(selectionStart >= 0);
Assert.isTrue(selectionLength >= 0);
fSelectionStart= selectionStart;
fSelectionLength= selectionLength;
fCu= unit;
fCompilationUnitNode= null;
fReplaceAllOccurrences= true; // default
fDeclareFinal= false; // default
fDeclareVarType= false; // default
fTempName= ""; //$NON-NLS-1$
fLinkedProposalModel= null;
fCheckResultForCompileProblems= true;
}
public ExtractTempRefactoring(CompilationUnit astRoot, int selectionStart, int selectionLength) {
Assert.isTrue(selectionStart >= 0);
Assert.isTrue(selectionLength >= 0);
Assert.isTrue(astRoot.getTypeRoot() instanceof ICompilationUnit);
fSelectionStart= selectionStart;
fSelectionLength= selectionLength;
fCu= (ICompilationUnit) astRoot.getTypeRoot();
fCompilationUnitNode= astRoot;
fReplaceAllOccurrences= true; // default
fDeclareFinal= false; // default
fDeclareVarType= false; // default
fTempName= ""; //$NON-NLS-1$
fLinkedProposalModel= null;
fCheckResultForCompileProblems= true;
}
public ExtractTempRefactoring(JavaRefactoringArguments arguments, RefactoringStatus status) {
this((ICompilationUnit) null, 0, 0);
RefactoringStatus initializeStatus= initialize(arguments);
status.merge(initializeStatus);
}
public void setCheckResultForCompileProblems(boolean checkResultForCompileProblems) {
fCheckResultForCompileProblems= checkResultForCompileProblems;
}
public void setLinkedProposalModel(LinkedProposalModel linkedProposalModel) {
fLinkedProposalModel= linkedProposalModel;
}
private void addReplaceExpressionWithTemp() throws JavaModelException {
IASTFragment[] fragmentsToReplace= retainOnlyReplacableMatches(getMatchingFragments());
//TODO: should not have to prune duplicates here...
ASTRewrite rewrite= fCURewrite.getASTRewrite();
HashSet<IASTFragment> seen= new HashSet<>();
for (IASTFragment fragment : fragmentsToReplace) {
if (! seen.add(fragment))
continue;
SimpleName tempName= fCURewrite.getAST().newSimpleName(fTempName);
TextEditGroup description= fCURewrite.createGroupDescription(RefactoringCoreMessages.ExtractTempRefactoring_replace);
fragment.replace(rewrite, tempName, description);
if (fLinkedProposalModel != null)
fLinkedProposalModel.getPositionGroup(KEY_NAME, true).addPosition(rewrite.track(tempName), false);
}
}
private RefactoringStatus checkExpression() throws JavaModelException {
Expression selectedExpression= getSelectedExpression().getAssociatedExpression();
if (selectedExpression != null) {
final ASTNode parent= selectedExpression.getParent();
if (selectedExpression instanceof NullLiteral) {
return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_null_literals);
} else if (selectedExpression instanceof ArrayInitializer) {
return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_array_initializer);
} else if (selectedExpression instanceof Assignment) {
if (parent instanceof Expression && !(parent instanceof ParenthesizedExpression))
return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_assignment);
else
return null;
} else if (selectedExpression instanceof SimpleName) {
if ((((SimpleName) selectedExpression)).isDeclaration())
return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_names_in_declarations);
if (parent instanceof QualifiedName && selectedExpression.getLocationInParent() == QualifiedName.NAME_PROPERTY || parent instanceof FieldAccess && selectedExpression.getLocationInParent() == FieldAccess.NAME_PROPERTY)
return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_select_expression);
} else if (selectedExpression instanceof VariableDeclarationExpression && parent instanceof TryStatement) {
return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_resource_in_try_with_resources);
}
}
return null;
}
// !! Same as in ExtractConstantRefactoring
private RefactoringStatus checkExpressionFragmentIsRValue() throws JavaModelException {
switch (Checks.checkExpressionIsRValue(getSelectedExpression().getAssociatedExpression())) {
case Checks.NOT_RVALUE_MISC:
return RefactoringStatus.createStatus(RefactoringStatus.FATAL, RefactoringCoreMessages.ExtractTempRefactoring_select_expression, null, Corext.getPluginId(), RefactoringStatusCodes.EXPRESSION_NOT_RVALUE, null);
case Checks.NOT_RVALUE_VOID:
return RefactoringStatus.createStatus(RefactoringStatus.FATAL, RefactoringCoreMessages.ExtractTempRefactoring_no_void, null, Corext.getPluginId(), RefactoringStatusCodes.EXPRESSION_NOT_RVALUE_VOID, null);
case Checks.IS_RVALUE_GUESSED:
case Checks.IS_RVALUE:
return new RefactoringStatus();
default:
Assert.isTrue(false);
return null;
}
}
private ITypeBinding guessBindingForReference(Expression expression) {
ITypeBinding binding= expression.resolveTypeBinding();
if (binding == null) {
binding= ASTResolving.guessBindingForReference(expression);
}
return binding;
}
@Override
public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException {
try {
pm.beginTask(RefactoringCoreMessages.ExtractTempRefactoring_checking_preconditions, 4);
fCURewrite= new CompilationUnitRewrite(fCu, fCompilationUnitNode);
fCURewrite.getASTRewrite().setTargetSourceRangeComputer(new NoCommentSourceRangeComputer());
doCreateChange(new SubProgressMonitor(pm, 2));
fChange= fCURewrite.createChange(RefactoringCoreMessages.ExtractTempRefactoring_change_name, true, new SubProgressMonitor(pm, 1));
RefactoringStatus result= new RefactoringStatus();
if (Arrays.asList(getExcludedVariableNames()).contains(fTempName))
result.addWarning(Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_another_variable, BasicElementLabels.getJavaElementName(fTempName)));
result.merge(checkMatchingFragments());
fChange.setKeepPreviewEdits(true);
if (fCheckResultForCompileProblems) {
result.merge(RefactoringAnalyzeUtil.checkNewSource(fChange, fCu, fCompilationUnitNode, pm));
}
return result;
} finally {
pm.done();
}
}
private final ExtractLocalDescriptor createRefactoringDescriptor() {
final Map<String, String> arguments= new HashMap<>();
String project= null;
IJavaProject javaProject= fCu.getJavaProject();
if (javaProject != null)
project= javaProject.getElementName();
final String description= Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_descriptor_description_short, BasicElementLabels.getJavaElementName(fTempName));
final String expression= ASTNodes.asString(fSelectedExpression.getAssociatedExpression());
final String header= Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_descriptor_description, new String[] { BasicElementLabels.getJavaElementName(fTempName), BasicElementLabels.getJavaCodeString(expression)});
final JDTRefactoringDescriptorComment comment= new JDTRefactoringDescriptorComment(project, this, header);
comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_name_pattern, BasicElementLabels.getJavaElementName(fTempName)));
final BodyDeclaration decl= ASTNodes.getParent(fSelectedExpression.getAssociatedExpression(), BodyDeclaration.class);
if (decl instanceof MethodDeclaration) {
final IMethodBinding method= ((MethodDeclaration) decl).resolveBinding();
final String label= method != null ? BindingLabelProvider.getBindingLabel(method, JavaElementLabels.ALL_FULLY_QUALIFIED) : BasicElementLabels.getJavaElementName('{' + JavaElementLabels.ELLIPSIS_STRING + '}');
comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_destination_pattern, label));
}
comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_expression_pattern, BasicElementLabels.getJavaCodeString(expression)));
if (fReplaceAllOccurrences)
comment.addSetting(RefactoringCoreMessages.ExtractTempRefactoring_replace_occurrences);
if (fDeclareFinal)
comment.addSetting(RefactoringCoreMessages.ExtractTempRefactoring_declare_final);
if (fDeclareVarType)
comment.addSetting(RefactoringCoreMessages.ExtractTempRefactoring_declare_var_type);
final ExtractLocalDescriptor descriptor= RefactoringSignatureDescriptorFactory.createExtractLocalDescriptor(project, description, comment.asString(), arguments, RefactoringDescriptor.NONE);
arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT, JavaRefactoringDescriptorUtil.elementToHandle(project, fCu));
arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME, fTempName);
arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION, Integer.valueOf(fSelectionStart).toString() + " " + Integer.valueOf(fSelectionLength).toString()); //$NON-NLS-1$
arguments.put(ATTRIBUTE_REPLACE, Boolean.valueOf(fReplaceAllOccurrences).toString());
arguments.put(ATTRIBUTE_FINAL, Boolean.valueOf(fDeclareFinal).toString());
arguments.put(ATTRIBUTE_TYPE_VAR, Boolean.valueOf(fDeclareVarType).toString());
return descriptor;
}
private void doCreateChange(IProgressMonitor pm) throws CoreException {
try {
pm.beginTask(RefactoringCoreMessages.ExtractTempRefactoring_checking_preconditions, 1);
try {
createTempDeclaration();
} catch (CoreException exception) {
JavaPlugin.log(exception);
}
addReplaceExpressionWithTemp();
} finally {
pm.done();
}
}
@Override
public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException {
try {
pm.beginTask("", 6); //$NON-NLS-1$
RefactoringStatus result= Checks.validateModifiesFiles(ResourceUtil.getFiles(new ICompilationUnit[] { fCu}), getValidationContext());
if (result.hasFatalError())
return result;
if (fCompilationUnitNode == null) {
fCompilationUnitNode= RefactoringASTParser.parseWithASTProvider(fCu, true, new SubProgressMonitor(pm, 3));
} else {
pm.worked(3);
}
result.merge(checkSelection(new SubProgressMonitor(pm, 3)));
if (!result.hasFatalError() && isLiteralNodeSelected())
fReplaceAllOccurrences= false;
return result;
} finally {
pm.done();
}
}
private RefactoringStatus checkMatchingFragments() throws JavaModelException {
RefactoringStatus result= new RefactoringStatus();
for (IASTFragment matchingFragment : getMatchingFragments()) {
ASTNode node= matchingFragment.getAssociatedNode();
if (isLeftValue(node) && !isReferringToLocalVariableFromFor((Expression) node)) {
String msg= RefactoringCoreMessages.ExtractTempRefactoring_assigned_to;
result.addWarning(msg, JavaStatusContext.create(fCu, node));
}
}
return result;
}
private RefactoringStatus checkSelection(IProgressMonitor pm) throws JavaModelException {
try {
pm.beginTask("", 8); //$NON-NLS-1$
IExpressionFragment selectedExpression= getSelectedExpression();
if (selectedExpression == null) {
String message= RefactoringCoreMessages.ExtractTempRefactoring_select_expression;
return CodeRefactoringUtil.checkMethodSyntaxErrors(fSelectionStart, fSelectionLength, fCompilationUnitNode, message);
}
pm.worked(1);
if (isUsedInExplicitConstructorCall())
return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_explicit_constructor);
pm.worked(1);
ASTNode associatedNode= selectedExpression.getAssociatedNode();
if (getEnclosingBodyNode() == null || ASTNodes.getParent(associatedNode, Annotation.class) != null)
return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_expr_in_method_or_initializer);
pm.worked(1);
if (associatedNode instanceof Name && associatedNode.getParent() instanceof ClassInstanceCreation && associatedNode.getLocationInParent() == ClassInstanceCreation.TYPE_PROPERTY)
return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_name_in_new);
pm.worked(1);
RefactoringStatus result= new RefactoringStatus();
result.merge(checkExpression());
if (result.hasFatalError())
return result;
pm.worked(1);
result.merge(checkExpressionFragmentIsRValue());
if (result.hasFatalError())
return result;
pm.worked(1);
if (isUsedInForInitializerOrUpdater(getSelectedExpression().getAssociatedExpression()))
return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_for_initializer_updater);
pm.worked(1);
if (isReferringToLocalVariableFromFor(getSelectedExpression().getAssociatedExpression()))
return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_refers_to_for_variable);
pm.worked(1);
return result;
} finally {
pm.done();
}
}
public RefactoringStatus checkTempName(String newName) {
RefactoringStatus status= Checks.checkTempName(newName, fCu);
if (Arrays.asList(getExcludedVariableNames()).contains(newName))
status.addWarning(Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_another_variable, BasicElementLabels.getJavaElementName(newName)));
return status;
}
private void createAndInsertTempDeclaration() throws CoreException {
Expression initializer= getSelectedExpression().createCopyTarget(fCURewrite.getASTRewrite(), true);
VariableDeclarationStatement vds= createTempDeclaration(initializer);
boolean insertAtSelection;
if (!fReplaceAllOccurrences) {
insertAtSelection= true;
} else {
IASTFragment[] replacableMatches= retainOnlyReplacableMatches(getMatchingFragments());
insertAtSelection= replacableMatches.length == 0
|| replacableMatches.length == 1 && replacableMatches[0].getAssociatedNode().equals(getSelectedExpression().getAssociatedExpression());
}
if (insertAtSelection) {
insertAt(getSelectedExpression().getAssociatedNode(), vds);
return;
}
ASTNode[] firstReplaceNodeParents= getParents(getFirstReplacedExpression().getAssociatedNode());
ASTNode[] commonPath= findDeepestCommonSuperNodePathForReplacedNodes();
Assert.isTrue(commonPath.length <= firstReplaceNodeParents.length);
ASTNode deepestCommonParent= firstReplaceNodeParents[commonPath.length - 1];
if (deepestCommonParent instanceof Block)
insertAt(firstReplaceNodeParents[commonPath.length], vds);
else
insertAt(deepestCommonParent, vds);
}
private VariableDeclarationStatement createTempDeclaration(Expression initializer) throws CoreException {
AST ast= fCURewrite.getAST();
VariableDeclarationFragment vdf= ast.newVariableDeclarationFragment();
vdf.setName(ast.newSimpleName(fTempName));
vdf.setInitializer(initializer);
VariableDeclarationStatement vds= ast.newVariableDeclarationStatement(vdf);
if (fDeclareFinal) {
vds.modifiers().add(ast.newModifier(ModifierKeyword.FINAL_KEYWORD));
}
vds.setType(createTempType());
if (fLinkedProposalModel != null) {
ASTRewrite rewrite= fCURewrite.getASTRewrite();
LinkedProposalPositionGroup nameGroup= fLinkedProposalModel.getPositionGroup(KEY_NAME, true);
nameGroup.addPosition(rewrite.track(vdf.getName()), true);
String[] nameSuggestions= guessTempNames();
if (nameSuggestions.length > 0 && !nameSuggestions[0].equals(fTempName)) {
nameGroup.addProposal(fTempName, null, nameSuggestions.length + 1);
}
for (int i= 0; i < nameSuggestions.length; i++) {
nameGroup.addProposal(nameSuggestions[i], null, nameSuggestions.length - i);
}
}
return vds;
}
private void insertAt(ASTNode target, Statement declaration) {
ASTRewrite rewrite= fCURewrite.getASTRewrite();
TextEditGroup groupDescription= fCURewrite.createGroupDescription(RefactoringCoreMessages.ExtractTempRefactoring_declare_local_variable);
ASTNode parent= target.getParent();
StructuralPropertyDescriptor locationInParent= target.getLocationInParent();
while (locationInParent != Block.STATEMENTS_PROPERTY && locationInParent != SwitchStatement.STATEMENTS_PROPERTY) {
if (locationInParent == IfStatement.THEN_STATEMENT_PROPERTY
|| locationInParent == IfStatement.ELSE_STATEMENT_PROPERTY
|| locationInParent == ForStatement.BODY_PROPERTY
|| locationInParent == EnhancedForStatement.BODY_PROPERTY
|| locationInParent == DoStatement.BODY_PROPERTY
|| locationInParent == WhileStatement.BODY_PROPERTY) {
// create intermediate block if target was the body property of a control statement:
Block replacement= rewrite.getAST().newBlock();
ListRewrite replacementRewrite= rewrite.getListRewrite(replacement, Block.STATEMENTS_PROPERTY);
replacementRewrite.insertFirst(declaration, null);
replacementRewrite.insertLast(rewrite.createMoveTarget(target), null);
rewrite.replace(target, replacement, groupDescription);
return;
} else if (locationInParent == LambdaExpression.BODY_PROPERTY && ((LambdaExpression) parent).getBody() instanceof Expression) {
Block replacement= rewrite.getAST().newBlock();
ListRewrite replacementRewrite= rewrite.getListRewrite(replacement, Block.STATEMENTS_PROPERTY);
replacementRewrite.insertFirst(declaration, null);
ASTNode moveTarget= rewrite.createMoveTarget(target);
AST ast= rewrite.getAST();
if (Bindings.isVoidType(((LambdaExpression) parent).resolveMethodBinding().getReturnType())) {
ExpressionStatement expressionStatement= ast.newExpressionStatement((Expression) moveTarget);
moveTarget= expressionStatement;
} else {
ReturnStatement returnStatement= ast.newReturnStatement();
returnStatement.setExpression((Expression) moveTarget);
moveTarget= returnStatement;
}
replacementRewrite.insertLast(moveTarget, null);
rewrite.replace(target, replacement, groupDescription);
return;
}
target= parent;
parent= parent.getParent();
locationInParent= target.getLocationInParent();
}
ListRewrite listRewrite= rewrite.getListRewrite(parent, (ChildListPropertyDescriptor)locationInParent);
listRewrite.insertBefore(declaration, target, groupDescription);
}
@Override
public Change createChange(IProgressMonitor pm) throws CoreException {
try {
pm.beginTask(RefactoringCoreMessages.ExtractTempRefactoring_checking_preconditions, 1);
ExtractLocalDescriptor descriptor= createRefactoringDescriptor();
fChange.setDescriptor(new RefactoringChangeDescriptor(descriptor));
return fChange;
} finally {
pm.done();
}
}
private void createTempDeclaration() throws CoreException {
if (shouldReplaceSelectedExpressionWithTempDeclaration())
replaceSelectedExpressionWithTempDeclaration();
else
createAndInsertTempDeclaration();
}
public boolean declareFinal() {
return fDeclareFinal;
}
public boolean declareVarType() {
return fDeclareVarType;
}
private ASTNode[] findDeepestCommonSuperNodePathForReplacedNodes() throws JavaModelException {
ASTNode[] matchNodes= getMatchNodes();
ASTNode[][] matchingNodesParents= new ASTNode[matchNodes.length][];
for (int i= 0; i < matchNodes.length; i++) {
matchingNodesParents[i]= getParents(matchNodes[i]);
}
List<ASTNode> l= Arrays.asList(getLongestArrayPrefix(matchingNodesParents));
return l.toArray(new ASTNode[l.size()]);
}
private ASTNode getEnclosingBodyNode() throws JavaModelException {
ASTNode node= getSelectedExpression().getAssociatedNode();
// expression must be in a method, lambda or initializer body
// make sure it is not in method or parameter annotation
StructuralPropertyDescriptor location= null;
while (node != null && !(node instanceof BodyDeclaration)) {
location= node.getLocationInParent();
node= node.getParent();
if (node instanceof LambdaExpression) {
break;
}
}
if (location == MethodDeclaration.BODY_PROPERTY || location == Initializer.BODY_PROPERTY
|| (location == LambdaExpression.BODY_PROPERTY && ((LambdaExpression) node).resolveMethodBinding() != null)) {
return (ASTNode) node.getStructuralProperty(location);
}
return null;
}
private String[] getExcludedVariableNames() {
if (fExcludedVariableNames == null) {
try {
IBinding[] bindings= new ScopeAnalyzer(fCompilationUnitNode).getDeclarationsInScope(getSelectedExpression().getStartPosition(), ScopeAnalyzer.VARIABLES
| ScopeAnalyzer.CHECK_VISIBILITY);
fExcludedVariableNames= new String[bindings.length];
for (int i= 0; i < bindings.length; i++) {
fExcludedVariableNames[i]= bindings[i].getName();
}
} catch (JavaModelException e) {
fExcludedVariableNames= new String[0];
}
}
return fExcludedVariableNames;
}
private IExpressionFragment getFirstReplacedExpression() throws JavaModelException {
if (!fReplaceAllOccurrences)
return getSelectedExpression();
IASTFragment[] nodesToReplace= retainOnlyReplacableMatches(getMatchingFragments());
if (nodesToReplace.length == 0)
return getSelectedExpression();
Comparator<IASTFragment> comparator= new Comparator<IASTFragment>() {
@Override
public int compare(IASTFragment o1, IASTFragment o2) {
return o1.getStartPosition() - o2.getStartPosition();
}
};
Arrays.sort(nodesToReplace, comparator);
return (IExpressionFragment) nodesToReplace[0];
}
private IASTFragment[] getMatchingFragments() throws JavaModelException {
if (fReplaceAllOccurrences) {
IASTFragment[] allMatches= ASTFragmentFactory.createFragmentForFullSubtree(getEnclosingBodyNode()).getSubFragmentsMatching(getSelectedExpression());
return allMatches;
} else
return new IASTFragment[] { getSelectedExpression()};
}
private ASTNode[] getMatchNodes() throws JavaModelException {
IASTFragment[] matches= retainOnlyReplacableMatches(getMatchingFragments());
ASTNode[] result= new ASTNode[matches.length];
for (int i= 0; i < matches.length; i++)
result[i]= matches[i].getAssociatedNode();
return result;
}
@Override
public String getName() {
return RefactoringCoreMessages.ExtractTempRefactoring_name;
}
private IExpressionFragment getSelectedExpression() throws JavaModelException {
if (fSelectedExpression != null)
return fSelectedExpression;
IASTFragment selectedFragment= ASTFragmentFactory.createFragmentForSourceRange(new SourceRange(fSelectionStart, fSelectionLength), fCompilationUnitNode, fCu);
if (selectedFragment instanceof IExpressionFragment && !Checks.isInsideJavadoc(selectedFragment.getAssociatedNode())) {
fSelectedExpression= (IExpressionFragment) selectedFragment;
} else if (selectedFragment != null) {
if (selectedFragment.getAssociatedNode() instanceof ExpressionStatement) {
ExpressionStatement exprStatement= (ExpressionStatement) selectedFragment.getAssociatedNode();
Expression expression= exprStatement.getExpression();
fSelectedExpression= (IExpressionFragment) ASTFragmentFactory.createFragmentForFullSubtree(expression);
} else if (selectedFragment.getAssociatedNode() instanceof Assignment) {
Assignment assignment= (Assignment) selectedFragment.getAssociatedNode();
fSelectedExpression= (IExpressionFragment) ASTFragmentFactory.createFragmentForFullSubtree(assignment);
}
}
if (fSelectedExpression != null && Checks.isEnumCase(fSelectedExpression.getAssociatedExpression().getParent())) {
fSelectedExpression= null;
}
return fSelectedExpression;
}
private Type createTempType() throws CoreException {
Expression expression= getSelectedExpression().getAssociatedExpression();
Type resultingType= null;
ITypeBinding typeBinding= expression.resolveTypeBinding();
ASTRewrite rewrite= fCURewrite.getASTRewrite();
AST ast= rewrite.getAST();
if (isVarTypeAllowed() && fDeclareVarType) {
resultingType= ast.newSimpleType(ast.newSimpleName("var")); //$NON-NLS-1$
} else if (expression instanceof ClassInstanceCreation && (typeBinding == null || typeBinding.getTypeArguments().length == 0)) {
resultingType= (Type) rewrite.createCopyTarget(((ClassInstanceCreation) expression).getType());
} else if (expression instanceof CastExpression) {
resultingType= (Type) rewrite.createCopyTarget(((CastExpression) expression).getType());
} else {
if (typeBinding == null) {
typeBinding= ASTResolving.guessBindingForReference(expression);
}
if (typeBinding != null) {
typeBinding= Bindings.normalizeForDeclarationUse(typeBinding, ast);
ImportRewrite importRewrite= fCURewrite.getImportRewrite();
ImportRewriteContext context= new ContextSensitiveImportRewriteContext(expression, importRewrite);
resultingType= importRewrite.addImport(typeBinding, ast, context, TypeLocation.LOCAL_VARIABLE);
} else {
resultingType= ast.newSimpleType(ast.newSimpleName("Object")); //$NON-NLS-1$
}
}
if (fLinkedProposalModel != null) {
LinkedProposalPositionGroup typeGroup= fLinkedProposalModel.getPositionGroup(KEY_TYPE, true);
typeGroup.addPosition(rewrite.track(resultingType), false);
if (typeBinding != null) {
ITypeBinding[] relaxingTypes= ASTResolving.getNarrowingTypes(ast, typeBinding);
for (int i= 0; i < relaxingTypes.length; i++) {
typeGroup.addProposal(relaxingTypes[i], fCURewrite.getCu(), relaxingTypes.length - i);
}
}
}
return resultingType;
}
public String guessTempName() {
String[] proposals= guessTempNames();
if (proposals.length == 0)
return fTempName;
else
return proposals[0];
}
/**
* @return proposed variable names (may be empty, but not null). The first proposal should be used as "best guess" (if it exists).
*/
public String[] guessTempNames() {
if (fGuessedTempNames == null) {
try {
Expression expression= getSelectedExpression().getAssociatedExpression();
if (expression != null) {
ITypeBinding binding= guessBindingForReference(expression);
fGuessedTempNames= StubUtility.getVariableNameSuggestions(NamingConventions.VK_LOCAL, fCu.getJavaProject(), binding, expression, Arrays.asList(getExcludedVariableNames()));
}
} catch (JavaModelException e) {
}
if (fGuessedTempNames == null)
fGuessedTempNames= new String[0];
}
return fGuessedTempNames;
}
private boolean isLiteralNodeSelected() throws JavaModelException {
IExpressionFragment fragment= getSelectedExpression();
if (fragment == null)
return false;
Expression expression= fragment.getAssociatedExpression();
if (expression == null)
return false;
switch (expression.getNodeType()) {
case ASTNode.BOOLEAN_LITERAL:
case ASTNode.CHARACTER_LITERAL:
case ASTNode.NULL_LITERAL:
case ASTNode.NUMBER_LITERAL:
return true;
default:
return false;
}
}
private boolean isUsedInExplicitConstructorCall() throws JavaModelException {
Expression selectedExpression= getSelectedExpression().getAssociatedExpression();
if (ASTNodes.getParent(selectedExpression, ConstructorInvocation.class) != null)
return true;
if (ASTNodes.getParent(selectedExpression, SuperConstructorInvocation.class) != null)
return true;
return false;
}
public boolean replaceAllOccurrences() {
return fReplaceAllOccurrences;
}
private void replaceSelectedExpressionWithTempDeclaration() throws CoreException {
ASTRewrite rewrite= fCURewrite.getASTRewrite();
Expression selectedExpression= getSelectedExpression().getAssociatedExpression(); // whole expression selected
Expression initializer= (Expression) rewrite.createMoveTarget(selectedExpression);
VariableDeclarationStatement tempDeclaration= createTempDeclaration(initializer);
ASTNode replacement;
ASTNode parent= selectedExpression.getParent();
boolean isParentLambda= parent instanceof LambdaExpression;
AST ast= rewrite.getAST();
if (isParentLambda) {
Block blockBody= ast.newBlock();
blockBody.statements().add(tempDeclaration);
if (!Bindings.isVoidType(((LambdaExpression) parent).resolveMethodBinding().getReturnType())) {
List<VariableDeclarationFragment> fragments= tempDeclaration.fragments();
SimpleName varName= fragments.get(0).getName();
ReturnStatement returnStatement= ast.newReturnStatement();
returnStatement.setExpression(ast.newSimpleName(varName.getIdentifier()));
blockBody.statements().add(returnStatement);
}
replacement= blockBody;
} else if (ASTNodes.isControlStatementBody(parent.getLocationInParent())) {
Block block= ast.newBlock();
block.statements().add(tempDeclaration);
replacement= block;
} else {
replacement= tempDeclaration;
}
ASTNode replacee= isParentLambda || !ASTNodes.hasSemicolon((ExpressionStatement) parent, fCu) ? selectedExpression : parent;
rewrite.replace(replacee, replacement, fCURewrite.createGroupDescription(RefactoringCoreMessages.ExtractTempRefactoring_declare_local_variable));
}
public void setDeclareFinal(boolean declareFinal) {
fDeclareFinal= declareFinal;
}
public void setDeclareVarType(boolean declareVarType) {
fDeclareVarType= declareVarType;
}
public void setReplaceAllOccurrences(boolean replaceAllOccurrences) {
fReplaceAllOccurrences= replaceAllOccurrences;
}
public void setTempName(String newName) {
fTempName= newName;
}
private boolean shouldReplaceSelectedExpressionWithTempDeclaration() throws JavaModelException {
IExpressionFragment selectedFragment= getSelectedExpression();
IExpressionFragment firstExpression= getFirstReplacedExpression();
if (firstExpression.getStartPosition() < selectedFragment.getStartPosition())
return false;
ASTNode associatedNode= selectedFragment.getAssociatedNode();
return (associatedNode.getParent() instanceof ExpressionStatement || associatedNode.getParent() instanceof LambdaExpression)
&& selectedFragment.matches(ASTFragmentFactory.createFragmentForFullSubtree(associatedNode));
}
private RefactoringStatus initialize(JavaRefactoringArguments arguments) {
final String selection= arguments.getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION);
if (selection != null) {
int offset= -1;
int length= -1;
final StringTokenizer tokenizer= new StringTokenizer(selection);
if (tokenizer.hasMoreTokens())
offset= Integer.valueOf(tokenizer.nextToken()).intValue();
if (tokenizer.hasMoreTokens())
length= Integer.valueOf(tokenizer.nextToken()).intValue();
if (offset >= 0 && length >= 0) {
fSelectionStart= offset;
fSelectionLength= length;
} else
return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_illegal_argument, new Object[] { selection, JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION}));
} else
return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION));
final String handle= arguments.getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT);
if (handle != null) {
final IJavaElement element= JavaRefactoringDescriptorUtil.handleToElement(arguments.getProject(), handle, false);
if (element == null || !element.exists() || element.getElementType() != IJavaElement.COMPILATION_UNIT)
return JavaRefactoringDescriptorUtil.createInputFatalStatus(element, getName(), IJavaRefactorings.EXTRACT_LOCAL_VARIABLE);
else
fCu= (ICompilationUnit) element;
} else
return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT));
final String name= arguments.getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME);
if (name != null && !"".equals(name)) //$NON-NLS-1$
fTempName= name;
else
return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME));
final String replace= arguments.getAttribute(ATTRIBUTE_REPLACE);
if (replace != null) {
fReplaceAllOccurrences= Boolean.valueOf(replace).booleanValue();
} else
return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_REPLACE));
final String declareFinal= arguments.getAttribute(ATTRIBUTE_FINAL);
if (declareFinal != null) {
fDeclareFinal= Boolean.valueOf(declareFinal).booleanValue();
} else
return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_FINAL));
final String declareVarType= arguments.getAttribute(ATTRIBUTE_TYPE_VAR);
if (declareVarType != null) {
fDeclareVarType= Boolean.valueOf(declareVarType).booleanValue();
} else
return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_TYPE_VAR));
return new RefactoringStatus();
}
public boolean isVarTypeAllowed() {
boolean isAllowed= false;
if (fCompilationUnitNode != null) {
IJavaElement root= fCompilationUnitNode.getJavaElement();
if (root != null) {
IJavaProject javaProject= root.getJavaProject();
if (javaProject != null && JavaModelUtil.is10OrHigher(javaProject)) {
isAllowed= true;
}
}
}
return isAllowed;
}
}