| /******************************************************************************* |
| * Copyright (c) 2000, 2019 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 |
| * Microsoft Corporation - copied to jdt.core.manipulation |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.corext.refactoring.code; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.HashMap; |
| 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.text.edits.TextEdit; |
| |
| import org.eclipse.jface.text.Document; |
| |
| 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.ltk.core.refactoring.RefactoringStatusContext; |
| |
| import org.eclipse.jdt.core.ICompilationUnit; |
| import org.eclipse.jdt.core.IJavaElement; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.dom.AST; |
| import org.eclipse.jdt.core.dom.ASTNode; |
| import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; |
| import org.eclipse.jdt.core.dom.AnonymousClassDeclaration; |
| import org.eclipse.jdt.core.dom.ArrayCreation; |
| import org.eclipse.jdt.core.dom.ArrayInitializer; |
| import org.eclipse.jdt.core.dom.ArrayType; |
| 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.CatchClause; |
| import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor; |
| import org.eclipse.jdt.core.dom.CompilationUnit; |
| import org.eclipse.jdt.core.dom.ConstructorInvocation; |
| import org.eclipse.jdt.core.dom.Dimension; |
| import org.eclipse.jdt.core.dom.Expression; |
| import org.eclipse.jdt.core.dom.FieldDeclaration; |
| import org.eclipse.jdt.core.dom.IBinding; |
| import org.eclipse.jdt.core.dom.IExtendedModifier; |
| 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.Javadoc; |
| import org.eclipse.jdt.core.dom.MethodDeclaration; |
| import org.eclipse.jdt.core.dom.Modifier; |
| import org.eclipse.jdt.core.dom.SimpleName; |
| import org.eclipse.jdt.core.dom.Statement; |
| import org.eclipse.jdt.core.dom.SwitchStatement; |
| import org.eclipse.jdt.core.dom.Type; |
| import org.eclipse.jdt.core.dom.TypeDeclaration; |
| import org.eclipse.jdt.core.dom.VariableDeclaration; |
| import org.eclipse.jdt.core.dom.VariableDeclarationFragment; |
| import org.eclipse.jdt.core.dom.VariableDeclarationStatement; |
| 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.manipulation.CodeGeneration; |
| import org.eclipse.jdt.core.refactoring.CompilationUnitChange; |
| import org.eclipse.jdt.core.refactoring.IJavaRefactorings; |
| import org.eclipse.jdt.core.refactoring.descriptors.ConvertLocalVariableDescriptor; |
| |
| import org.eclipse.jdt.internal.core.manipulation.BindingLabelProviderCore; |
| import org.eclipse.jdt.internal.core.manipulation.JavaElementLabelsCore; |
| 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.codemanipulation.ContextSensitiveImportRewriteContext; |
| import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory; |
| import org.eclipse.jdt.internal.corext.dom.ASTNodes; |
| import org.eclipse.jdt.internal.corext.dom.DimensionRewrite; |
| import org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor; |
| import org.eclipse.jdt.internal.corext.dom.ModifierRewrite; |
| import org.eclipse.jdt.internal.corext.fix.LinkedProposalModelCore; |
| import org.eclipse.jdt.internal.corext.fix.LinkedProposalPositionGroupCore; |
| 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.changes.TextChangeCompatibility; |
| import org.eclipse.jdt.internal.corext.refactoring.rename.TempDeclarationFinder; |
| import org.eclipse.jdt.internal.corext.refactoring.rename.TempOccurrenceAnalyzer; |
| import org.eclipse.jdt.internal.corext.refactoring.util.JavaStatusContext; |
| 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.JdtFlags; |
| import org.eclipse.jdt.internal.corext.util.Messages; |
| |
| public class PromoteTempToFieldRefactoring extends Refactoring { |
| |
| private static final String ATTRIBUTE_STATIC= "static"; //$NON-NLS-1$ |
| private static final String ATTRIBUTE_FINAL= "final"; //$NON-NLS-1$ |
| private static final String ATTRIBUTE_VISIBILITY= "visibility"; //$NON-NLS-1$ |
| private static final String ATTRIBUTE_INITIALIZE= "initialize"; //$NON-NLS-1$ |
| |
| private int fSelectionStart; |
| private int fSelectionLength; |
| private ICompilationUnit fCu; |
| |
| public static final int INITIALIZE_IN_FIELD= 0; |
| public static final int INITIALIZE_IN_METHOD= 1; |
| public static final int INITIALIZE_IN_CONSTRUCTOR= 2; |
| |
| private static final String LINKED_NAME= "name"; //$NON-NLS-1$ |
| |
| //------ settings ---------// |
| private String fFieldName; |
| private int fVisibility; /*see Modifier*/ |
| private boolean fDeclareStatic; |
| private boolean fDeclareFinal; |
| private int fInitializeIn; /*see INITIALIZE_IN_* constraints */ |
| |
| //------ fields used for computations ---------// |
| private CompilationUnit fCompilationUnitNode; |
| private VariableDeclaration fTempDeclarationNode; |
| //------ analysis ---------// |
| private boolean fInitializerUsesLocalTypes; |
| private boolean fTempTypeUsesClassTypeVariables; |
| //------ scripting --------// |
| private boolean fSelfInitializing= false; |
| private LinkedProposalModelCore fLinkedProposalModel; |
| |
| private Map<String, String> fFormatterOptions; |
| |
| /** |
| * Creates a new promote temp to field refactoring. |
| * @param unit the compilation unit, or <code>null</code> if invoked by scripting |
| * @param selectionStart start |
| * @param selectionLength length |
| */ |
| public PromoteTempToFieldRefactoring(ICompilationUnit unit, int selectionStart, int selectionLength){ |
| Assert.isTrue(selectionStart >= 0); |
| Assert.isTrue(selectionLength >= 0); |
| fSelectionStart= selectionStart; |
| fSelectionLength= selectionLength; |
| fCu= unit; |
| |
| fFieldName= ""; //$NON-NLS-1$ |
| fVisibility= Modifier.PRIVATE; |
| fDeclareStatic= false; |
| fDeclareFinal= false; |
| fInitializeIn= INITIALIZE_IN_METHOD; |
| fLinkedProposalModel= null; |
| } |
| |
| /** |
| * Creates a new promote temp to field refactoring. |
| * @param declaration the variable declaration node to convert to a field |
| */ |
| public PromoteTempToFieldRefactoring(VariableDeclaration declaration) { |
| Assert.isTrue(declaration != null); |
| fTempDeclarationNode= declaration; |
| IVariableBinding resolveBinding= declaration.resolveBinding(); |
| Assert.isTrue(resolveBinding != null && !resolveBinding.isParameter() && !resolveBinding.isField()); |
| |
| ASTNode root= declaration.getRoot(); |
| Assert.isTrue(root instanceof CompilationUnit); |
| fCompilationUnitNode= (CompilationUnit) root; |
| |
| IJavaElement input= fCompilationUnitNode.getJavaElement(); |
| Assert.isTrue(input instanceof ICompilationUnit); |
| fCu= (ICompilationUnit) input; |
| |
| fSelectionStart= declaration.getStartPosition(); |
| fSelectionLength= declaration.getLength(); |
| |
| fFieldName= ""; //$NON-NLS-1$ |
| fVisibility= Modifier.PRIVATE; |
| fDeclareStatic= false; |
| fDeclareFinal= false; |
| fInitializeIn= INITIALIZE_IN_METHOD; |
| fLinkedProposalModel= null; |
| } |
| |
| public PromoteTempToFieldRefactoring(JavaRefactoringArguments arguments, RefactoringStatus status) { |
| this(null); |
| RefactoringStatus initializeStatus= initialize(arguments); |
| status.merge(initializeStatus); |
| } |
| |
| @Override |
| public String getName() { |
| return RefactoringCoreMessages.PromoteTempToFieldRefactoring_name; |
| } |
| |
| public int[] getAvailableVisibilities(){ |
| return new int[]{Modifier.PUBLIC, Modifier.PROTECTED, Modifier.NONE, Modifier.PRIVATE}; |
| } |
| |
| public int getVisibility() { |
| return fVisibility; |
| } |
| |
| public boolean getDeclareFinal() { |
| return fDeclareFinal; |
| } |
| |
| public boolean getDeclareStatic() { |
| return fDeclareStatic; |
| } |
| |
| public int getInitializeIn() { |
| return fInitializeIn; |
| } |
| |
| public void setVisibility(int accessModifier) { |
| Assert.isTrue(accessModifier == Modifier.PRIVATE || |
| accessModifier == Modifier.NONE || |
| accessModifier == Modifier.PROTECTED || |
| accessModifier == Modifier.PUBLIC); |
| fVisibility= accessModifier; |
| } |
| |
| public void setDeclareFinal(boolean declareFinal) { |
| fDeclareFinal= declareFinal; |
| } |
| |
| public void setDeclareStatic(boolean declareStatic) { |
| fDeclareStatic= declareStatic; |
| } |
| |
| public void setFieldName(String fieldName) { |
| Assert.isNotNull(fieldName); |
| fFieldName= fieldName; |
| } |
| |
| public void setInitializeIn(int initializeIn) { |
| Assert.isTrue( initializeIn == INITIALIZE_IN_CONSTRUCTOR || |
| initializeIn == INITIALIZE_IN_FIELD || |
| initializeIn == INITIALIZE_IN_METHOD); |
| fInitializeIn= initializeIn; |
| } |
| |
| public boolean canEnableSettingStatic(){ |
| return fInitializeIn != INITIALIZE_IN_CONSTRUCTOR && |
| ! isTempDeclaredInStaticMethod() && |
| ! fTempTypeUsesClassTypeVariables; |
| } |
| |
| public boolean canEnableSettingFinal(){ |
| if (fInitializeIn == INITIALIZE_IN_CONSTRUCTOR) |
| return canEnableSettingDeclareInConstructors() && ! tempHasAssignmentsOtherThanInitialization(); |
| else if (fInitializeIn == INITIALIZE_IN_FIELD) |
| return canEnableSettingDeclareInFieldDeclaration() && ! tempHasAssignmentsOtherThanInitialization(); |
| else if (getMethodDeclaration().isConstructor()) |
| return !tempHasAssignmentsOtherThanInitialization(); |
| else |
| return false; |
| } |
| |
| private boolean tempHasAssignmentsOtherThanInitialization() { |
| TempAssignmentFinder assignmentFinder= new TempAssignmentFinder(fTempDeclarationNode); |
| fCompilationUnitNode.accept(assignmentFinder); |
| return assignmentFinder.hasAssignments(); |
| } |
| |
| public boolean canEnableSettingDeclareInConstructors(){ |
| return ! fDeclareStatic && |
| ! fInitializerUsesLocalTypes && |
| ! getMethodDeclaration().isConstructor() && |
| ! isDeclaredInAnonymousClass() && |
| ! isTempDeclaredInStaticMethod() && |
| tempHasInitializer(); |
| } |
| |
| public boolean canEnableSettingDeclareInMethod(){ |
| return ! fDeclareFinal && |
| tempHasInitializer(); |
| } |
| private boolean tempHasInitializer() { |
| return getTempInitializer() != null; |
| } |
| |
| public boolean canEnableSettingDeclareInFieldDeclaration(){ |
| return ! fInitializerUsesLocalTypes && tempHasInitializer(); |
| } |
| |
| private Expression getTempInitializer() { |
| return fTempDeclarationNode.getInitializer(); |
| } |
| |
| private boolean isTempDeclaredInStaticMethod() { |
| return Modifier.isStatic(getMethodDeclaration().getModifiers()); |
| } |
| |
| private MethodDeclaration getMethodDeclaration(){ |
| return ASTNodes.getParent(fTempDeclarationNode, MethodDeclaration.class); |
| } |
| |
| private boolean isDeclaredInAnonymousClass() { |
| return null != ASTNodes.getParent(fTempDeclarationNode, AnonymousClassDeclaration.class); |
| } |
| |
| /* |
| * @see org.eclipse.jdt.internal.corext.refactoring.base.Refactoring#checkActivation(org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| @Override |
| public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException { |
| RefactoringStatus result= Checks.validateModifiesFiles( |
| ResourceUtil.getFiles(new ICompilationUnit[]{fCu}), |
| getValidationContext()); |
| if (result.hasFatalError()) |
| return result; |
| |
| initAST(pm); |
| |
| if (fTempDeclarationNode == null) |
| return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.PromoteTempToFieldRefactoring_select_declaration); |
| |
| if (! Checks.isDeclaredIn(fTempDeclarationNode, MethodDeclaration.class)) |
| return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.PromoteTempToFieldRefactoring_only_declared_in_methods); |
| |
| if (isMethodParameter()) |
| return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.PromoteTempToFieldRefactoring_method_parameters); |
| |
| if (isTempAnExceptionInCatchBlock()) |
| return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.PromoteTempToFieldRefactoring_exceptions); |
| |
| ASTNode declaringType= ASTResolving.findParentType(fTempDeclarationNode); |
| if (declaringType instanceof TypeDeclaration && ((TypeDeclaration) declaringType).isInterface()) |
| return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.PromoteTempToFieldRefactoring_interface_methods); |
| |
| result.merge(checkTempTypeForLocalTypeUsage()); |
| if (result.hasFatalError()) |
| return result; |
| |
| checkTempInitializerForLocalTypeUsage(); |
| |
| if (!fSelfInitializing) |
| initializeDefaults(); |
| return result; |
| } |
| |
| private void initializeDefaults() { |
| fVisibility= Modifier.PRIVATE; |
| fDeclareStatic= Modifier.isStatic(getMethodDeclaration().getModifiers()); |
| fDeclareFinal= false; |
| if (canEnableSettingDeclareInMethod()) |
| fInitializeIn= INITIALIZE_IN_METHOD; |
| else if (canEnableSettingDeclareInFieldDeclaration()) |
| fInitializeIn= INITIALIZE_IN_FIELD; |
| else if (canEnableSettingDeclareInConstructors()) |
| fInitializeIn= INITIALIZE_IN_CONSTRUCTOR; |
| } |
| |
| public String[] guessFieldNames() { |
| String rawTempName= StubUtility.getBaseName(fTempDeclarationNode.resolveBinding(), fCu.getJavaProject()); |
| String[] excludedNames= getNamesOfFieldsInDeclaringType(); |
| int dim= ASTNodes.getDimensions(fTempDeclarationNode); |
| return StubUtility.getFieldNameSuggestions(fCu.getJavaProject(), rawTempName, dim, getModifiers(), excludedNames); |
| } |
| |
| private String getInitialFieldName() { |
| String[] suggestedNames= guessFieldNames(); |
| if (suggestedNames.length > 0) { |
| if (fLinkedProposalModel != null) { |
| LinkedProposalPositionGroupCore nameGroup= fLinkedProposalModel.getPositionGroup(LINKED_NAME, true); |
| for (int i= 0; i < suggestedNames.length; i++) { |
| nameGroup.addProposal(suggestedNames[i], suggestedNames.length - i); |
| } |
| } |
| return suggestedNames[0]; |
| } else { |
| return fTempDeclarationNode.getName().getIdentifier(); |
| } |
| } |
| |
| private String[] getNamesOfFieldsInDeclaringType() { |
| final AbstractTypeDeclaration type= getEnclosingType(); |
| if (type instanceof TypeDeclaration) { |
| FieldDeclaration[] fields= ((TypeDeclaration) type).getFields(); |
| List<String> result= new ArrayList<>(fields.length); |
| for (int i= 0; i < fields.length; i++) { |
| for (Iterator<VariableDeclarationFragment> iter= fields[i].fragments().iterator(); iter.hasNext();) { |
| VariableDeclarationFragment field= iter.next(); |
| result.add(field.getName().getIdentifier()); |
| } |
| } |
| return result.toArray(new String[result.size()]); |
| } |
| return new String[] {}; |
| } |
| |
| private void checkTempInitializerForLocalTypeUsage() { |
| Expression initializer= fTempDeclarationNode.getInitializer(); |
| if (initializer == null) |
| return; |
| |
| IMethodBinding declaringMethodBinding= getMethodDeclaration().resolveBinding(); |
| ITypeBinding[] methodTypeParameters= declaringMethodBinding == null ? new ITypeBinding[0] : declaringMethodBinding.getTypeParameters(); |
| LocalTypeAndVariableUsageAnalyzer localTypeAnalyer= new LocalTypeAndVariableUsageAnalyzer(methodTypeParameters); |
| initializer.accept(localTypeAnalyer); |
| fInitializerUsesLocalTypes= ! localTypeAnalyer.getUsageOfEnclosingNodes().isEmpty(); |
| } |
| |
| private RefactoringStatus checkTempTypeForLocalTypeUsage(){ |
| VariableDeclarationStatement vds= getTempDeclarationStatement(); |
| if (vds == null) |
| return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.PromoteTempToFieldRefactoring_cannot_promote); |
| Type type= vds.getType(); |
| ITypeBinding binding= type.resolveBinding(); |
| if (binding == null) |
| return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.PromoteTempToFieldRefactoring_cannot_promote); |
| |
| IMethodBinding declaringMethodBinding= getMethodDeclaration().resolveBinding(); |
| ITypeBinding[] methodTypeParameters= declaringMethodBinding == null ? new ITypeBinding[0] : declaringMethodBinding.getTypeParameters(); |
| LocalTypeAndVariableUsageAnalyzer analyzer= new LocalTypeAndVariableUsageAnalyzer(methodTypeParameters); |
| type.accept(analyzer); |
| boolean usesLocalTypes= ! analyzer.getUsageOfEnclosingNodes().isEmpty(); |
| fTempTypeUsesClassTypeVariables= analyzer.getClassTypeVariablesUsed(); |
| if (usesLocalTypes) |
| return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.PromoteTempToFieldRefactoring_uses_type_declared_locally); |
| return null; |
| } |
| |
| private VariableDeclarationStatement getTempDeclarationStatement() { |
| return ASTNodes.getParent(fTempDeclarationNode, VariableDeclarationStatement.class); |
| } |
| |
| private boolean isTempAnExceptionInCatchBlock() { |
| return (fTempDeclarationNode.getParent() instanceof CatchClause); |
| } |
| |
| private boolean isMethodParameter() { |
| return (fTempDeclarationNode.getParent() instanceof MethodDeclaration); |
| } |
| |
| private void initAST(IProgressMonitor pm){ |
| if (fCompilationUnitNode == null) { |
| fCompilationUnitNode= RefactoringASTParser.parseWithASTProvider(fCu, true, pm); |
| fTempDeclarationNode= TempDeclarationFinder.findTempDeclaration(fCompilationUnitNode, fSelectionStart, fSelectionLength); |
| } |
| } |
| |
| public RefactoringStatus validateInput(){ |
| return Checks.checkFieldName(fFieldName, fCu); |
| } |
| |
| /* |
| * @see org.eclipse.jdt.internal.corext.refactoring.base.Refactoring#checkInput(org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| @Override |
| public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException { |
| try{ |
| RefactoringStatus result= new RefactoringStatus(); |
| result.merge(checkClashesWithExistingFields()); |
| if (fInitializeIn == INITIALIZE_IN_CONSTRUCTOR) |
| result.merge(checkClashesInConstructors()); |
| return result; |
| } finally { |
| pm.done(); |
| } |
| } |
| |
| private RefactoringStatus checkClashesInConstructors() { |
| Assert.isTrue(fInitializeIn == INITIALIZE_IN_CONSTRUCTOR); |
| Assert.isTrue(!isDeclaredInAnonymousClass()); |
| final AbstractTypeDeclaration declaration= (AbstractTypeDeclaration) getMethodDeclaration().getParent(); |
| if (declaration instanceof TypeDeclaration) { |
| MethodDeclaration[] methods= ((TypeDeclaration) declaration).getMethods(); |
| for (int i= 0; i < methods.length; i++) { |
| MethodDeclaration method= methods[i]; |
| if (!method.isConstructor()) |
| continue; |
| NameCollector nameCollector= new NameCollector(method) { |
| @Override |
| protected boolean visitNode(ASTNode node) { |
| return true; |
| } |
| }; |
| method.accept(nameCollector); |
| List<String> names= nameCollector.getNames(); |
| if (names.contains(fFieldName)) { |
| String[] keys= { BasicElementLabels.getJavaElementName(fFieldName), BindingLabelProviderCore.getBindingLabel(method.resolveBinding(), JavaElementLabelsCore.ALL_FULLY_QUALIFIED)}; |
| String msg= Messages.format(RefactoringCoreMessages.PromoteTempToFieldRefactoring_Name_conflict, keys); |
| return RefactoringStatus.createFatalErrorStatus(msg); |
| } |
| } |
| } |
| return null; |
| } |
| |
| private RefactoringStatus checkClashesWithExistingFields(){ |
| FieldDeclaration[] existingFields= getFieldDeclarations(); |
| for (int i= 0; i < existingFields.length; i++) { |
| FieldDeclaration declaration= existingFields[i]; |
| VariableDeclarationFragment[] fragments= (VariableDeclarationFragment[]) declaration.fragments().toArray(new VariableDeclarationFragment[declaration.fragments().size()]); |
| for (int j= 0; j < fragments.length; j++) { |
| VariableDeclarationFragment fragment= fragments[j]; |
| if (fFieldName.equals(fragment.getName().getIdentifier())){ |
| //cannot conflict with more than 1 name |
| RefactoringStatusContext context= JavaStatusContext.create(fCu, fragment); |
| return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.PromoteTempToFieldRefactoring_Name_conflict_with_field, context); |
| } |
| } |
| } |
| return null; |
| } |
| |
| private FieldDeclaration[] getFieldDeclarations() { |
| List<BodyDeclaration> bodyDeclarations= ASTNodes.getBodyDeclarations(getMethodDeclaration().getParent()); |
| List<FieldDeclaration> fields= new ArrayList<>(1); |
| for (Iterator<BodyDeclaration> iter= bodyDeclarations.iterator(); iter.hasNext();) { |
| Object each= iter.next(); |
| if (each instanceof FieldDeclaration) |
| fields.add((FieldDeclaration) each); |
| } |
| return fields.toArray(new FieldDeclaration[fields.size()]); |
| } |
| |
| /* |
| * @see org.eclipse.jdt.internal.corext.refactoring.base.IRefactoring#createChange(org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| @Override |
| public Change createChange(IProgressMonitor pm) throws CoreException { |
| pm.beginTask("", 1); //$NON-NLS-1$ |
| try { |
| if (fFieldName.length() == 0) { |
| fFieldName= getInitialFieldName(); |
| } |
| |
| ASTRewrite rewrite= ASTRewrite.create(fCompilationUnitNode.getAST()); |
| if (fInitializeIn == INITIALIZE_IN_METHOD && tempHasInitializer()) |
| addLocalDeclarationSplit(rewrite); |
| else |
| addLocalDeclarationRemoval(rewrite); |
| if (fInitializeIn == INITIALIZE_IN_CONSTRUCTOR) |
| addInitializersToConstructors(rewrite); |
| addTempRenames(rewrite); |
| addFieldDeclaration(rewrite); |
| |
| CompilationUnitChange result= new CompilationUnitChange(RefactoringCoreMessages.PromoteTempToFieldRefactoring_name, fCu); |
| result.setDescriptor(new RefactoringChangeDescriptor(getRefactoringDescriptor())); |
| TextEdit resultingEdits; |
| if (fFormatterOptions == null) { |
| resultingEdits= rewrite.rewriteAST(); |
| } else { |
| resultingEdits= rewrite.rewriteAST(new Document(fCu.getSource()), fFormatterOptions); |
| } |
| |
| TextChangeCompatibility.addTextEdit(result, RefactoringCoreMessages.PromoteTempToFieldRefactoring_editName, resultingEdits); |
| return result; |
| |
| } finally { |
| pm.done(); |
| } |
| } |
| |
| private void addTempRenames(ASTRewrite rewrite) { |
| boolean noNameChange= fFieldName.equals(fTempDeclarationNode.getName().getIdentifier()); |
| if (fLinkedProposalModel == null && noNameChange) { |
| return; // no changes needed |
| } |
| TempOccurrenceAnalyzer analyzer= new TempOccurrenceAnalyzer(fTempDeclarationNode, false); |
| analyzer.perform(); |
| SimpleName[] tempRefs= analyzer.getReferenceNodes(); // no javadocs (refactoring not for parameters) |
| |
| |
| for (int j= 0; j < tempRefs.length; j++) { |
| SimpleName occurence= tempRefs[j]; |
| if (noNameChange) { |
| addLinkedName(rewrite, occurence, false); |
| } else { |
| SimpleName newName= getAST().newSimpleName(fFieldName); |
| addLinkedName(rewrite, newName, false); |
| rewrite.replace(occurence, newName, null); |
| } |
| } |
| } |
| |
| private void addInitializersToConstructors(ASTRewrite rewrite) throws CoreException { |
| Assert.isTrue(! isDeclaredInAnonymousClass()); |
| final AbstractTypeDeclaration declaration= (AbstractTypeDeclaration)getMethodDeclaration().getParent(); |
| final MethodDeclaration[] constructors= getAllConstructors(declaration); |
| if (constructors.length == 0) { |
| AST ast= rewrite.getAST(); |
| MethodDeclaration newConstructor= ast.newMethodDeclaration(); |
| newConstructor.setConstructor(true); |
| newConstructor.modifiers().addAll(ast.newModifiers(declaration.getModifiers() & ModifierRewrite.VISIBILITY_MODIFIERS)); |
| newConstructor.setName(ast.newSimpleName(declaration.getName().getIdentifier())); |
| newConstructor.setJavadoc(getNewConstructorComment(rewrite)); |
| newConstructor.setBody(ast.newBlock()); |
| |
| addFieldInitializationToConstructor(rewrite, newConstructor); |
| |
| int insertionIndex= computeInsertIndexForNewConstructor(declaration); |
| rewrite.getListRewrite(declaration, declaration.getBodyDeclarationsProperty()).insertAt(newConstructor, insertionIndex, null); |
| } else { |
| for (int index= 0; index < constructors.length; index++) { |
| if (shouldInsertTempInitialization(constructors[index])) |
| addFieldInitializationToConstructor(rewrite, constructors[index]); |
| } |
| } |
| } |
| |
| private String getEnclosingTypeName() { |
| return getEnclosingType().getName().getIdentifier(); |
| } |
| |
| private AbstractTypeDeclaration getEnclosingType() { |
| return ASTNodes.getParent(getTempDeclarationStatement(), AbstractTypeDeclaration.class); |
| } |
| |
| private Javadoc getNewConstructorComment(ASTRewrite rewrite) throws CoreException { |
| if (StubUtility.doAddComments(fCu.getJavaProject())){ |
| String comment= CodeGeneration.getMethodComment(fCu, getEnclosingTypeName(), getEnclosingTypeName(), new String[0], new String[0], null, null, StubUtility.getLineDelimiterUsed(fCu)); |
| if (comment != null && comment.length() > 0) { |
| return (Javadoc) rewrite.createStringPlaceholder(comment, ASTNode.JAVADOC); |
| } |
| } |
| return null; |
| } |
| |
| private int computeInsertIndexForNewConstructor(AbstractTypeDeclaration declaration) { |
| List<BodyDeclaration> declarations= declaration.bodyDeclarations(); |
| if (declarations.isEmpty()) |
| return 0; |
| int index= findFirstMethodIndex(declaration); |
| if (index == -1) |
| return declarations.size(); |
| else |
| return index; |
| } |
| |
| private int findFirstMethodIndex(AbstractTypeDeclaration typeDeclaration) { |
| for (int i= 0, n= typeDeclaration.bodyDeclarations().size(); i < n; i++) { |
| if (typeDeclaration.bodyDeclarations().get(i) instanceof MethodDeclaration) |
| return i; |
| } |
| return -1; |
| } |
| |
| private void addFieldInitializationToConstructor(ASTRewrite rewrite, MethodDeclaration constructor) { |
| if (constructor.getBody() == null) |
| constructor.setBody(getAST().newBlock()); |
| Statement newStatement= createNewAssignmentStatement(rewrite); |
| rewrite.getListRewrite(constructor.getBody(), Block.STATEMENTS_PROPERTY).insertLast(newStatement, null); |
| } |
| |
| private static boolean shouldInsertTempInitialization(MethodDeclaration constructor){ |
| Assert.isTrue(constructor.isConstructor()); |
| if (constructor.getBody() == null) |
| return false; |
| List<Statement> statements= constructor.getBody().statements(); |
| if (statements == null) |
| return false; |
| if (statements.size() > 0 && statements.get(0) instanceof ConstructorInvocation) |
| return false; |
| return true; |
| } |
| |
| private static MethodDeclaration[] getAllConstructors(AbstractTypeDeclaration typeDeclaration) { |
| if (typeDeclaration instanceof TypeDeclaration) { |
| MethodDeclaration[] allMethods= ((TypeDeclaration) typeDeclaration).getMethods(); |
| List<MethodDeclaration> result= new ArrayList<>(Math.min(allMethods.length, 1)); |
| for (int i= 0; i < allMethods.length; i++) { |
| MethodDeclaration declaration= allMethods[i]; |
| if (declaration.isConstructor()) |
| result.add(declaration); |
| } |
| return result.toArray(new MethodDeclaration[result.size()]); |
| } |
| return new MethodDeclaration[] {}; |
| } |
| |
| |
| private ConvertLocalVariableDescriptor getRefactoringDescriptor() { |
| final Map<String, String> arguments= new HashMap<>(); |
| String project= null; |
| IJavaProject javaProject= fCu.getJavaProject(); |
| if (javaProject != null) |
| project= javaProject.getElementName(); |
| final IVariableBinding binding= fTempDeclarationNode.resolveBinding(); |
| final String description= Messages.format(RefactoringCoreMessages.PromoteTempToFieldRefactoring_descriptor_description_short, BasicElementLabels.getJavaElementName(binding.getName())); |
| final String header= Messages.format(RefactoringCoreMessages.PromoteTempToFieldRefactoring_descriptor_description, new String[] { BindingLabelProviderCore.getBindingLabel(binding, JavaElementLabelsCore.ALL_FULLY_QUALIFIED), BindingLabelProviderCore.getBindingLabel(binding.getDeclaringMethod(), JavaElementLabelsCore.ALL_FULLY_QUALIFIED)}); |
| final JDTRefactoringDescriptorComment comment= new JDTRefactoringDescriptorComment(project, this, header); |
| comment.addSetting(Messages.format(RefactoringCoreMessages.PromoteTempToFieldRefactoring_original_pattern, BindingLabelProviderCore.getBindingLabel(binding, JavaElementLabelsCore.ALL_FULLY_QUALIFIED))); |
| comment.addSetting(Messages.format(RefactoringCoreMessages.PromoteTempToFieldRefactoring_field_pattern, BasicElementLabels.getJavaElementName(fFieldName))); |
| switch (fInitializeIn) { |
| case INITIALIZE_IN_CONSTRUCTOR: |
| comment.addSetting(RefactoringCoreMessages.PromoteTempToFieldRefactoring_initialize_constructor); |
| break; |
| case INITIALIZE_IN_FIELD: |
| comment.addSetting(RefactoringCoreMessages.PromoteTempToFieldRefactoring_initialize_declaration); |
| break; |
| case INITIALIZE_IN_METHOD: |
| comment.addSetting(RefactoringCoreMessages.PromoteTempToFieldRefactoring_initialize_method); |
| break; |
| } |
| String visibility= JdtFlags.getVisibilityString(fVisibility); |
| if ("".equals(visibility)) //$NON-NLS-1$ |
| visibility= RefactoringCoreMessages.PromoteTempToFieldRefactoring_default_visibility; |
| comment.addSetting(Messages.format(RefactoringCoreMessages.PromoteTempToFieldRefactoring_visibility_pattern, visibility)); |
| if (fDeclareFinal && fDeclareStatic) |
| comment.addSetting(RefactoringCoreMessages.PromoteTempToFieldRefactoring_declare_final_static); |
| else if (fDeclareFinal) |
| comment.addSetting(RefactoringCoreMessages.PromoteTempToFieldRefactoring_declare_final); |
| else if (fDeclareStatic) |
| comment.addSetting(RefactoringCoreMessages.PromoteTempToFieldRefactoring_declare_static); |
| final ConvertLocalVariableDescriptor descriptor= RefactoringSignatureDescriptorFactory.createConvertLocalVariableDescriptor(project, description, comment.asString(), arguments, RefactoringDescriptor.STRUCTURAL_CHANGE); |
| arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT, JavaRefactoringDescriptorUtil.elementToHandle(project, fCu)); |
| arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME, fFieldName); |
| arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION, Integer.valueOf(fSelectionStart).toString() + " " + Integer.valueOf(fSelectionLength).toString()); //$NON-NLS-1$ |
| arguments.put(ATTRIBUTE_STATIC, Boolean.valueOf(fDeclareStatic).toString()); |
| arguments.put(ATTRIBUTE_FINAL, Boolean.valueOf(fDeclareFinal).toString()); |
| arguments.put(ATTRIBUTE_VISIBILITY, Integer.valueOf(fVisibility).toString()); |
| arguments.put(ATTRIBUTE_INITIALIZE, Integer.valueOf(fInitializeIn).toString()); |
| return descriptor; |
| } |
| |
| private void addLocalDeclarationSplit(ASTRewrite rewrite) { |
| VariableDeclarationStatement tempDeclarationStatement= getTempDeclarationStatement(); |
| ASTNode parentStatement= tempDeclarationStatement.getParent(); |
| |
| ListRewrite listRewrite; |
| if (parentStatement instanceof SwitchStatement) { |
| listRewrite= rewrite.getListRewrite(parentStatement, SwitchStatement.STATEMENTS_PROPERTY); |
| } else if (parentStatement instanceof Block) { |
| listRewrite= rewrite.getListRewrite(parentStatement, Block.STATEMENTS_PROPERTY); |
| } else { |
| // should not happen. VariableDeclaration's can not be in a control statement body |
| listRewrite= null; |
| Assert.isTrue(false); |
| } |
| int statementIndex= listRewrite.getOriginalList().indexOf(tempDeclarationStatement); |
| Assert.isTrue(statementIndex != -1); |
| |
| Statement newStatement= createNewAssignmentStatement(rewrite); |
| |
| List<VariableDeclarationFragment> fragments= tempDeclarationStatement.fragments(); |
| |
| int fragmentIndex= fragments.indexOf(fTempDeclarationNode); |
| Assert.isTrue(fragmentIndex != -1); |
| |
| if (fragments.size() == 1) { |
| rewrite.replace(tempDeclarationStatement, newStatement, null); |
| return; |
| } |
| |
| for (int i1= fragmentIndex, n = fragments.size(); i1 < n; i1++) { |
| VariableDeclarationFragment fragment= fragments.get(i1); |
| rewrite.remove(fragment, null); |
| } |
| if (fragmentIndex == 0) |
| rewrite.remove(tempDeclarationStatement, null); |
| |
| Assert.isTrue(tempHasInitializer()); |
| |
| listRewrite.insertAt(newStatement, statementIndex + 1, null); |
| |
| if (fragmentIndex + 1 < fragments.size()){ |
| VariableDeclarationFragment firstFragmentAfter= fragments.get(fragmentIndex + 1); |
| VariableDeclarationFragment copyfirstFragmentAfter= (VariableDeclarationFragment)rewrite.createCopyTarget(firstFragmentAfter); |
| VariableDeclarationStatement statement= getAST().newVariableDeclarationStatement(copyfirstFragmentAfter); |
| Type type= (Type)rewrite.createCopyTarget(tempDeclarationStatement.getType()); |
| statement.setType(type); |
| List<IExtendedModifier> modifiers= tempDeclarationStatement.modifiers(); |
| if (modifiers.size() > 0) { |
| ListRewrite modifiersRewrite= rewrite.getListRewrite(tempDeclarationStatement, VariableDeclarationStatement.MODIFIERS2_PROPERTY); |
| ASTNode firstModifier= (ASTNode) modifiers.get(0); |
| ASTNode lastModifier= (ASTNode) modifiers.get(modifiers.size() - 1); |
| ASTNode modifiersCopy= modifiersRewrite.createCopyTarget(firstModifier, lastModifier); |
| statement.modifiers().add(modifiersCopy); |
| } |
| for (int i= fragmentIndex + 2; i < fragments.size(); i++) { |
| VariableDeclarationFragment fragment= fragments.get(i); |
| VariableDeclarationFragment fragmentCopy= (VariableDeclarationFragment)rewrite.createCopyTarget(fragment); |
| statement.fragments().add(fragmentCopy); |
| } |
| listRewrite.insertAt(statement, statementIndex + 2, null); |
| } |
| } |
| |
| private Statement createNewAssignmentStatement(ASTRewrite rewrite) { |
| AST ast= getAST(); |
| Assignment assignment= ast.newAssignment(); |
| SimpleName fieldName= ast.newSimpleName(fFieldName); |
| addLinkedName(rewrite, fieldName, true); |
| assignment.setLeftHandSide(fieldName); |
| assignment.setRightHandSide(getTempInitializerCopy(rewrite)); |
| return ast.newExpressionStatement(assignment); |
| } |
| |
| private void addLinkedName(ASTRewrite rewrite, SimpleName fieldName, boolean isFirst) { |
| if (fLinkedProposalModel != null) { |
| fLinkedProposalModel.getPositionGroup(LINKED_NAME, true).addPosition(rewrite.track(fieldName), isFirst); |
| } |
| } |
| |
| private Expression getTempInitializerCopy(ASTRewrite rewrite) { |
| final Expression initializer= (Expression) rewrite.createCopyTarget(getTempInitializer()); |
| if (initializer instanceof ArrayInitializer && ASTNodes.getDimensions(fTempDeclarationNode) > 0) { |
| ArrayCreation arrayCreation= rewrite.getAST().newArrayCreation(); |
| arrayCreation.setType((ArrayType) ASTNodeFactory.newType(rewrite.getAST(), fTempDeclarationNode)); |
| arrayCreation.setInitializer((ArrayInitializer) initializer); |
| return arrayCreation; |
| } |
| return initializer; |
| } |
| |
| private void addLocalDeclarationRemoval(ASTRewrite rewrite) { |
| VariableDeclarationStatement tempDeclarationStatement= getTempDeclarationStatement(); |
| List<VariableDeclarationFragment> fragments= tempDeclarationStatement.fragments(); |
| |
| int fragmentIndex= fragments.indexOf(fTempDeclarationNode); |
| Assert.isTrue(fragmentIndex != -1); |
| VariableDeclarationFragment fragment= fragments.get(fragmentIndex); |
| rewrite.remove(fragment, null); |
| if (fragments.size() == 1) |
| rewrite.remove(tempDeclarationStatement, null); |
| } |
| |
| private void addFieldDeclaration(ASTRewrite rewrite) { |
| FieldDeclaration[] fields= getFieldDeclarations(); |
| ASTNode parent= getMethodDeclaration().getParent(); |
| ChildListPropertyDescriptor descriptor= ASTNodes.getBodyDeclarationsProperty(parent); |
| int insertIndex; |
| if (fields.length == 0) |
| insertIndex= 0; |
| else |
| insertIndex= ASTNodes.getBodyDeclarations(parent).indexOf(fields[fields.length - 1]) + 1; |
| |
| final FieldDeclaration declaration= createNewFieldDeclaration(rewrite); |
| rewrite.getListRewrite(parent, descriptor).insertAt(declaration, insertIndex, null); |
| } |
| |
| private FieldDeclaration createNewFieldDeclaration(ASTRewrite rewrite) { |
| AST ast= getAST(); |
| VariableDeclarationFragment fragment= ast.newVariableDeclarationFragment(); |
| SimpleName variableName= ast.newSimpleName(fFieldName); |
| fragment.setName(variableName); |
| addLinkedName(rewrite, variableName, false); |
| List<Dimension> extraDimensions= DimensionRewrite.copyDimensions(fTempDeclarationNode.extraDimensions(), rewrite); |
| fragment.extraDimensions().addAll(extraDimensions); |
| if (fInitializeIn == INITIALIZE_IN_FIELD && tempHasInitializer()){ |
| Expression initializer= (Expression)rewrite.createCopyTarget(getTempInitializer()); |
| fragment.setInitializer(initializer); |
| } |
| FieldDeclaration fieldDeclaration= ast.newFieldDeclaration(fragment); |
| |
| VariableDeclarationStatement vds= getTempDeclarationStatement(); |
| ITypeBinding binding= vds.getType().resolveBinding(); |
| Type type; |
| // "var" type cannot be initialized separately, so change to inferred type |
| if (ASTNodes.isVarType(vds, fCompilationUnitNode) && binding != null) { |
| ImportRewrite importRewrite= StubUtility.createImportRewrite(fCompilationUnitNode, true); |
| ImportRewriteContext context= new ContextSensitiveImportRewriteContext(fCompilationUnitNode, importRewrite); |
| type= importRewrite.addImport(binding, getAST(), context, TypeLocation.FIELD); |
| } else { |
| type= (Type)rewrite.createCopyTarget(vds.getType()); |
| } |
| fieldDeclaration.setType(type); |
| fieldDeclaration.modifiers().addAll(ASTNodeFactory.newModifiers(ast, getModifiers())); |
| return fieldDeclaration; |
| } |
| |
| private int getModifiers() { |
| int flags= fVisibility; |
| if (fDeclareFinal) |
| flags |= Modifier.FINAL; |
| if (fDeclareStatic) |
| flags |= Modifier.STATIC; |
| return flags; |
| } |
| |
| private AST getAST(){ |
| return fTempDeclarationNode.getAST(); |
| } |
| |
| private static class LocalTypeAndVariableUsageAnalyzer extends HierarchicalASTVisitor{ |
| private final List<IBinding> fLocalDefinitions= new ArrayList<>(0); // List of IBinding (Variable and Type) |
| private final List<SimpleName> fLocalReferencesToEnclosing= new ArrayList<>(0); // List of ASTNodes |
| private final List<ITypeBinding> fMethodTypeVariables; |
| private boolean fClassTypeVariablesUsed= false; |
| public LocalTypeAndVariableUsageAnalyzer(ITypeBinding[] methodTypeVariables) { |
| fMethodTypeVariables= Arrays.asList(methodTypeVariables); |
| } |
| public List<SimpleName> getUsageOfEnclosingNodes(){ |
| return fLocalReferencesToEnclosing; |
| } |
| public boolean getClassTypeVariablesUsed() { |
| return fClassTypeVariablesUsed; |
| } |
| @Override |
| public boolean visit(SimpleName node) { |
| ITypeBinding typeBinding= node.resolveTypeBinding(); |
| if (typeBinding != null && typeBinding.isLocal()) { |
| if (node.isDeclaration()) { |
| fLocalDefinitions.add(typeBinding); |
| } else if (! fLocalDefinitions.contains(typeBinding)) { |
| fLocalReferencesToEnclosing.add(node); |
| } |
| } |
| if (typeBinding != null && typeBinding.isTypeVariable()) { |
| if (node.isDeclaration()) { |
| fLocalDefinitions.add(typeBinding); |
| } else if (! fLocalDefinitions.contains(typeBinding)) { |
| if (fMethodTypeVariables.contains(typeBinding)) { |
| fLocalReferencesToEnclosing.add(node); |
| } else { |
| fClassTypeVariablesUsed= true; |
| } |
| } |
| } |
| IBinding binding= node.resolveBinding(); |
| if (binding != null && binding.getKind() == IBinding.VARIABLE && ! ((IVariableBinding)binding).isField()) { |
| if (node.isDeclaration()) { |
| fLocalDefinitions.add(binding); |
| } else if (! fLocalDefinitions.contains(binding)) { |
| fLocalReferencesToEnclosing.add(node); |
| } |
| } |
| return super.visit(node); |
| } |
| } |
| |
| private RefactoringStatus initialize(JavaRefactoringArguments arguments) { |
| fSelfInitializing= true; |
| 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.CONVERT_LOCAL_VARIABLE); |
| else |
| fCu= (ICompilationUnit) element; |
| } else |
| return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT)); |
| final String visibility= arguments.getAttribute(ATTRIBUTE_VISIBILITY); |
| if (visibility != null && !"".equals(visibility)) {//$NON-NLS-1$ |
| int flag= 0; |
| try { |
| flag= Integer.parseInt(visibility); |
| } catch (NumberFormatException exception) { |
| return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_VISIBILITY)); |
| } |
| fVisibility= flag; |
| } |
| final String initialize= arguments.getAttribute(ATTRIBUTE_INITIALIZE); |
| if (initialize != null && !"".equals(initialize)) {//$NON-NLS-1$ |
| int value= 0; |
| try { |
| value= Integer.parseInt(initialize); |
| } catch (NumberFormatException exception) { |
| return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_INITIALIZE)); |
| } |
| fInitializeIn= value; |
| } |
| final String name= arguments.getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME); |
| if (name != null && !"".equals(name)) //$NON-NLS-1$ |
| fFieldName= name; |
| else |
| return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME)); |
| final String declareStatic= arguments.getAttribute(ATTRIBUTE_STATIC); |
| if (declareStatic != null) { |
| fDeclareStatic= Boolean.valueOf(declareStatic).booleanValue(); |
| } else |
| return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_STATIC)); |
| 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)); |
| return new RefactoringStatus(); |
| } |
| |
| |
| public void setLinkedProposalModel(LinkedProposalModelCore model) { |
| fLinkedProposalModel= model; |
| } |
| |
| public Map<String, String> getFormatterOptions() { |
| return fFormatterOptions; |
| } |
| |
| /** |
| * Set the formatter options to format the refactored code. |
| * @param formatterOptions the formatter options to format the refactored code |
| */ |
| public void setFormatterOptions(Map<String, String> formatterOptions) { |
| fFormatterOptions= formatterOptions; |
| } |
| } |