diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/PromoteTempToFieldRefactoring.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/PromoteTempToFieldRefactoring.java index 774f96e..2fbc460 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/PromoteTempToFieldRefactoring.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/PromoteTempToFieldRefactoring.java @@ -6,6 +6,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: + * Timo Kinnunen - Contribution for bug 432147 - [refactoring] Extract Constant displays error message on name of local variable * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.internal.corext.refactoring.code; @@ -56,6 +57,7 @@ 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.Initializer; import org.eclipse.jdt.core.dom.Javadoc; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.Modifier; @@ -257,7 +259,7 @@ return canEnableSettingDeclareInConstructors() && ! tempHasAssignmentsOtherThanInitialization(); else if (fInitializeIn == INITIALIZE_IN_FIELD) return canEnableSettingDeclareInFieldDeclaration() && ! tempHasAssignmentsOtherThanInitialization(); - else if (getMethodDeclaration().isConstructor()) + else if (isDeclaredInConstructor()) return !tempHasAssignmentsOtherThanInitialization(); else return false; @@ -272,10 +274,18 @@ public boolean canEnableSettingDeclareInConstructors(){ return ! fDeclareStatic && ! fInitializerUsesLocalTypes && - ! getMethodDeclaration().isConstructor() && + ! isDeclaredInConstructor() && ! isDeclaredInAnonymousClass() && ! isTempDeclaredInStaticMethod() && tempHasInitializer(); + } + + private boolean isDeclaredInConstructor() { + BodyDeclaration methodDeclaration= getMethodDeclaration(); + if(methodDeclaration instanceof MethodDeclaration) { + return ((MethodDeclaration) methodDeclaration).isConstructor(); + } + return false; } public boolean canEnableSettingDeclareInMethod(){ @@ -298,8 +308,8 @@ return Modifier.isStatic(getMethodDeclaration().getModifiers()); } - private MethodDeclaration getMethodDeclaration(){ - return (MethodDeclaration)ASTNodes.getParent(fTempDeclarationNode, MethodDeclaration.class); + private BodyDeclaration getMethodDeclaration(){ + return (BodyDeclaration)ASTNodes.getParent(fTempDeclarationNode, BodyDeclaration.class); } private boolean isDeclaredInAnonymousClass() { @@ -322,7 +332,7 @@ if (fTempDeclarationNode == null) return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.PromoteTempToFieldRefactoring_select_declaration); - if (! Checks.isDeclaredIn(fTempDeclarationNode, MethodDeclaration.class)) + if (! Checks.isDeclaredIn(fTempDeclarationNode, MethodDeclaration.class) && !Checks.isDeclaredIn(fTempDeclarationNode, Initializer.class) ) return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.PromoteTempToFieldRefactoring_only_declared_in_methods); if (isMethodParameter()) @@ -401,7 +411,7 @@ if (initializer == null) return; - IMethodBinding declaringMethodBinding= getMethodDeclaration().resolveBinding(); + IMethodBinding declaringMethodBinding= getMethodBinding(); ITypeBinding[] methodTypeParameters= declaringMethodBinding == null ? new ITypeBinding[0] : declaringMethodBinding.getTypeParameters(); LocalTypeAndVariableUsageAnalyzer localTypeAnalyer= new LocalTypeAndVariableUsageAnalyzer(methodTypeParameters); initializer.accept(localTypeAnalyer); @@ -417,7 +427,7 @@ if (binding == null) return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.PromoteTempToFieldRefactoring_cannot_promote); - IMethodBinding declaringMethodBinding= getMethodDeclaration().resolveBinding(); + IMethodBinding declaringMethodBinding= getMethodBinding(); ITypeBinding[] methodTypeParameters= declaringMethodBinding == null ? new ITypeBinding[0] : declaringMethodBinding.getTypeParameters(); LocalTypeAndVariableUsageAnalyzer analyzer= new LocalTypeAndVariableUsageAnalyzer(methodTypeParameters); type.accept(analyzer); @@ -427,6 +437,11 @@ return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.PromoteTempToFieldRefactoring_uses_type_declared_locally); return null; } + + private IMethodBinding getMethodBinding() { + BodyDeclaration methodDeclaration= getMethodDeclaration(); + return methodDeclaration != null && methodDeclaration instanceof MethodDeclaration ? ((MethodDeclaration) methodDeclaration).resolveBinding() : null; + } private VariableDeclarationStatement getTempDeclarationStatement() { return (VariableDeclarationStatement) ASTNodes.getParent(fTempDeclarationNode, VariableDeclarationStatement.class); @@ -983,4 +998,8 @@ public void setLinkedProposalModel(LinkedProposalModel model) { fLinkedProposalModel= model; } + + public void setSelfInitializing(boolean value) { + fSelfInitializing = value; + } } diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/actions/ExtractConstantAction.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/actions/ExtractConstantAction.java index ff6a4c8..7f8ac11 100644 --- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/actions/ExtractConstantAction.java +++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/actions/ExtractConstantAction.java @@ -6,25 +6,44 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: + * Timo Kinnunen - Contribution for bug 432147 - [refactoring] Extract Constant displays error message on name of local variable * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.ui.actions; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jface.text.ITextSelection; import org.eclipse.ui.PlatformUI; +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.SourceRange; +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.SimpleName; +import org.eclipse.jdt.core.dom.VariableDeclaration; + +import org.eclipse.jdt.internal.corext.dom.fragments.ASTFragmentFactory; +import org.eclipse.jdt.internal.corext.dom.fragments.IASTFragment; import org.eclipse.jdt.internal.corext.refactoring.RefactoringAvailabilityTester; import org.eclipse.jdt.internal.corext.refactoring.code.ExtractConstantRefactoring; +import org.eclipse.jdt.internal.corext.refactoring.code.PromoteTempToFieldRefactoring; +import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite; +import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser; import org.eclipse.jdt.ui.refactoring.RefactoringSaveHelper; import org.eclipse.jdt.internal.ui.IJavaHelpContextIds; +import org.eclipse.jdt.internal.ui.JavaPlugin; import org.eclipse.jdt.internal.ui.actions.ActionUtil; import org.eclipse.jdt.internal.ui.actions.SelectionConverter; import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor; import org.eclipse.jdt.internal.ui.javaeditor.JavaTextSelection; import org.eclipse.jdt.internal.ui.refactoring.ExtractConstantWizard; +import org.eclipse.jdt.internal.ui.refactoring.PromoteTempWizard; import org.eclipse.jdt.internal.ui.refactoring.RefactoringMessages; import org.eclipse.jdt.internal.ui.refactoring.actions.RefactoringStarter; @@ -84,7 +103,37 @@ public void run(ITextSelection selection) { if (!ActionUtil.isEditable(fEditor)) return; - ExtractConstantRefactoring refactoring= new ExtractConstantRefactoring(SelectionConverter.getInputAsCompilationUnit(fEditor), selection.getOffset(), selection.getLength()); + ICompilationUnit unit= SelectionConverter.getInputAsCompilationUnit(fEditor); + CompilationUnit cuNode= RefactoringASTParser.parseWithASTProvider(unit, true, null); + int selectionStart= selection.getOffset(); + int selectionLength= selection.getLength(); + ExtractConstantRefactoring refactoring= new ExtractConstantRefactoring(cuNode, selectionStart, selectionLength); + try { + CompilationUnitRewrite cuRewrite= new CompilationUnitRewrite(unit, cuNode); + SourceRange range= new SourceRange(selectionStart, selectionLength); + IASTFragment ast= ASTFragmentFactory.createFragmentForSourceRange(range, cuRewrite.getRoot(), unit); + ASTNode node= ast.getAssociatedNode(); + if (node instanceof SimpleName && node.getParent() instanceof VariableDeclaration) { + ICompilationUnit cunit= SelectionConverter.getInputAsCompilationUnit(fEditor); + PromoteTempToFieldRefactoring refactoring2= new PromoteTempToFieldRefactoring(cunit, selection.getOffset(), selection.getLength()); + if (refactoring2.checkInitialConditions(new NullProgressMonitor()).isOK() && refactoring2.canEnableSettingDeclareInFieldDeclaration()) { + refactoring2.setInitializeIn(PromoteTempToFieldRefactoring.INITIALIZE_IN_FIELD); + if (refactoring2.canEnableSettingFinal() && refactoring2.canEnableSettingStatic()) { + refactoring2.setDeclareFinal(true); + refactoring2.setDeclareStatic(true); + refactoring2.setFieldName(refactoring.guessConstantName()); + refactoring2.setSelfInitializing(true); + } + + } + new RefactoringStarter().activate(new PromoteTempWizard(refactoring2), getShell(), RefactoringMessages.ConvertLocalToField_title, RefactoringSaveHelper.SAVE_NOTHING); + return; + } + } catch (JavaModelException e) { + JavaPlugin.log(e); + } catch (CoreException e) { + JavaPlugin.log(e); + } new RefactoringStarter().activate(new ExtractConstantWizard(refactoring), getShell(), RefactoringMessages.ExtractConstantAction_extract_constant, RefactoringSaveHelper.SAVE_NOTHING); } }