From cc2e7e1da596ad93e337007876bec2f75e22b535 Mon Sep 17 00:00:00 2001 From: Emanuel Graf Date: Thu, 18 Dec 2008 09:23:57 +0000 Subject: [PATCH] FIXED - bug 245089: Enhancement: "Refactor" -> "Implement Method ..." should work for multiple methods https://bugs.eclipse.org/bugs/show_bug.cgi?id=245089 --- .../resources/refactoring/ImplementMethod.rts | 24 ---- .../implementmethod/ImplementMethodData.java | 115 +++++++++++++++ .../ImplementMethodInputPage.java | 106 ++++++++++++++ .../ImplementMethodRefactoring.java | 132 +++++++++++------- .../ImplementMethodRefactoringWizard.java | 26 +++- .../refactoring/implementmethod/Messages.java | 1 + .../MethodToImplementConfig.java | 54 +++++++ .../implementmethod/ParameterHandler.java | 49 +------ .../ParameterNamesInputPage.java | 74 ++++++++-- .../implementmethod/messages.properties | 1 + 10 files changed, 449 insertions(+), 133 deletions(-) create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ImplementMethodData.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ImplementMethodInputPage.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/MethodToImplementConfig.java diff --git a/core/org.eclipse.cdt.ui.tests/resources/refactoring/ImplementMethod.rts b/core/org.eclipse.cdt.ui.tests/resources/refactoring/ImplementMethod.rts index ecf78865dcd..b8c5bcf4d67 100644 --- a/core/org.eclipse.cdt.ui.tests/resources/refactoring/ImplementMethod.rts +++ b/core/org.eclipse.cdt.ui.tests/resources/refactoring/ImplementMethod.rts @@ -72,30 +72,6 @@ template inline void A::test() //= #include "A.h" -//!Test Warning when Method definition in Class selected -//#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest -//@.config -filename=A.h -initialWarnings=1 -//@A.h - -struct Test -{ - void /*$*/bla/*$$*/() {} -}; - -//!Test Warning when ClassName selected -//#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest -//@.config -filename=A.h -initialWarnings=1 -//@A.h - -struct /*$*/Test/*$$*/ -{ - void bla2(); -}; - //!class template member functions //#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest //@.config diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ImplementMethodData.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ImplementMethodData.java new file mode 100644 index 00000000000..ed6d27f45be --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ImplementMethodData.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software (IFS)- initial API and implementation + ******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.implementmethod; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; + +/** + * @author Emanuel Graf IFS + * + */ +public class ImplementMethodData implements ITreeContentProvider{ + + public ImplementMethodData() { + } + + + private List methodDeclarations; + + public void setMethodDeclarations(List methodDeclarations) { + this.methodDeclarations = new ArrayList(); + + for (IASTSimpleDeclaration declaration : methodDeclarations) { + this.methodDeclarations.add(new MethodToImplementConfig(declaration, new ParameterHandler(declaration))); + } + } + + public List getMethodDeclarations() { + return methodDeclarations; + } + + public Object[] getChildren(Object parentElement) { + return null; + } + + public Object getParent(Object element) { + return null; + } + + public boolean hasChildren(Object element) { + return false; + } + + public Object[] getElements(Object inputElement) { + return methodDeclarations.toArray(); + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + + } + + public List getMethodsToImplement() { + List ret = new ArrayList(); + for (MethodToImplementConfig config : methodDeclarations) { + if(config.isChecked()) { + ret.add(config); + } + } + return ret; + } + + public boolean needParameterInput() { + for (MethodToImplementConfig config : getMethodsToImplement()) { + if(config.getParaHandler().needsAdditionalArgumentNames())return true; + } + return false; + } + + public MethodToImplementConfig getNextConfigNeedingParameterNames(MethodToImplementConfig currentConfig) { + int i = 0; + List methodsToImplement = getMethodsToImplement(); + for(;i < methodsToImplement.size();++i) { + if(currentConfig == methodsToImplement.get(i)) { + ++i; + break; + } + } + + for(;i < methodsToImplement.size();++i) { + if(methodsToImplement.get(i).getParaHandler().needsAdditionalArgumentNames()) { + return methodsToImplement.get(i); + } + } + return null; + } + + + public MethodToImplementConfig getFirstConfigNeedingParameterNames() { + List methodsToImplement = getMethodsToImplement(); + for (MethodToImplementConfig config : methodsToImplement) { + if(config.getParaHandler().needsAdditionalArgumentNames()) { + return config; + } + } + return null; + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ImplementMethodInputPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ImplementMethodInputPage.java new file mode 100644 index 00000000000..447e1a4efcf --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ImplementMethodInputPage.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software (IFS)- initial API and implementation + ******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.implementmethod; + +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.jface.wizard.IWizardPage; +import org.eclipse.ltk.ui.refactoring.UserInputWizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.dialogs.ContainerCheckedTreeViewer; + +/** + * @author Emanuel Graf IFS + * + */ +public class ImplementMethodInputPage extends UserInputWizardPage{ + + private ImplementMethodData data; + private ImplementMethodRefactoringWizard wizard; + private ContainerCheckedTreeViewer tree; + + public ImplementMethodInputPage(ImplementMethodData data, ImplementMethodRefactoringWizard implementMethodRefactoringWizard) { + super(Messages.ImplementMethodInputPage_PageTitle); + this.setData(data); + wizard = implementMethodRefactoringWizard; + } + + + + @Override + public boolean canFlipToNextPage() { + if(data.needParameterInput()) { + return super.canFlipToNextPage(); + }else {//getNextPage call is too expensive in this case. + return isPageComplete(); + } + } + + + + public void createControl(Composite parent) { + Composite comp = new Composite(parent, SWT.NONE ); + comp.setLayout(new FillLayout()); + createTree(comp); + + setControl(comp); + checkPage(); + } + + private void createTree(Composite comp) { + tree = new ContainerCheckedTreeViewer(comp); + tree.setContentProvider(data); + tree.setAutoExpandLevel(2); + tree.setInput(""); //$NON-NLS-1$ + + tree.addCheckStateListener(new ICheckStateListener() { + + public void checkStateChanged(CheckStateChangedEvent event) { + MethodToImplementConfig config = ((MethodToImplementConfig)event.getElement()); + config.setChecked(event.getChecked()); + checkPage(); + }}); + + for (MethodToImplementConfig config : data.getMethodsToImplement()) { + tree.setChecked(config, config.isChecked()); + } + + } + + @Override + public IWizardPage getNextPage() { + if(data.needParameterInput()) { + return wizard.getPageForConfig(data.getFirstConfigNeedingParameterNames()); + }else { + return computeSuccessorPage(); + } + } + + public void setData(ImplementMethodData data) { + this.data = data; + } + + public ImplementMethodData getData() { + return data; + } + + private void checkPage() { + if(data.getMethodsToImplement().size() > 0) { + setPageComplete(true); + }else { + setPageComplete(false); + } + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ImplementMethodRefactoring.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ImplementMethodRefactoring.java index 62fb761aff0..5646d6c298b 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ImplementMethodRefactoring.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ImplementMethodRefactoring.java @@ -11,6 +11,9 @@ *******************************************************************************/ package org.eclipse.cdt.internal.ui.refactoring.implementmethod; +import java.util.ArrayList; +import java.util.List; + import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; @@ -20,6 +23,7 @@ import org.eclipse.core.runtime.SubMonitor; import org.eclipse.jface.viewers.ISelection; import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; @@ -53,20 +57,18 @@ import org.eclipse.cdt.internal.ui.refactoring.utils.SelectionHelper; * Main class of the ImplementMethodRefactoring (Source generator). * Checks conditions, finds insert location and generates the ImplementationNode. * - * @author Mirko Stocker, Lukas Felber + * @author Mirko Stocker, Lukas Felber, Emanuel Graf * */ public class ImplementMethodRefactoring extends CRefactoring { - private IASTSimpleDeclaration methodDeclaration; private InsertLocation insertLocation; - private ParameterHandler parameterHandler; - private IASTDeclaration createdMethodDefinition; private CPPASTFunctionDeclarator createdMethodDeclarator; + private ImplementMethodData data; public ImplementMethodRefactoring(IFile file, ISelection selection, ICElement element) { super(file, selection, element); - parameterHandler = new ParameterHandler(this); + data = new ImplementMethodData(); } @Override @@ -74,47 +76,81 @@ public class ImplementMethodRefactoring extends CRefactoring { SubMonitor sm = SubMonitor.convert(pm, 10); super.checkInitialConditions(sm.newChild(6)); - methodDeclaration = SelectionHelper.findFirstSelectedDeclaration(region, unit); + data.setMethodDeclarations(findUnimplementedMethodDeclarations(unit)); - if (!NodeHelper.isMethodDeclaration(methodDeclaration)) { - initStatus.addFatalError(Messages.ImplementMethodRefactoring_NoMethodSelected); - return initStatus; + if(region.getLength()>0) { + IASTSimpleDeclaration methodDeclaration = SelectionHelper.findFirstSelectedDeclaration(region, unit); + if (NodeHelper.isMethodDeclaration(methodDeclaration)) { + for (MethodToImplementConfig config : data.getMethodDeclarations()) { + if(config.getDeclaration() == methodDeclaration) { + config.setChecked(true); + } + } + } } - if(isProgressMonitorCanceld(sm, initStatus))return initStatus; - sm.worked(1); - - if (DefinitionFinder.getDefinition(methodDeclaration, file) != null) { - initStatus.addFatalError(Messages.ImplementMethodRefactoring_MethodHasImpl); - return initStatus; - } - if(isProgressMonitorCanceld(sm, initStatus))return initStatus; - sm.worked(1); - sm.done(); - parameterHandler.initArgumentNames(); - sm.worked(1); - sm.done(); - insertLocation = findInsertLocation(); - sm.worked(1); sm.done(); return initStatus; } + private List findUnimplementedMethodDeclarations( + IASTTranslationUnit unit) { + final List list = new ArrayList(); + unit.accept(new ASTVisitor() { + { + shouldVisitDeclarations = true; + } + + @Override + public int visit(IASTDeclaration declaration) { + if (declaration instanceof IASTSimpleDeclaration) { + IASTSimpleDeclaration simpleDeclaration = (IASTSimpleDeclaration) declaration; + try { + if(NodeHelper.isMethodDeclaration(simpleDeclaration) && DefinitionFinder.getDefinition(simpleDeclaration, file) == null) { + list.add(simpleDeclaration); + } + } catch (CoreException e) {} + } + return ASTVisitor.PROCESS_CONTINUE; + } + + + + }); + return list; + } + @Override protected void collectModifications(IProgressMonitor pm, ModificationCollector collector) throws CoreException, OperationCanceledException { - IASTTranslationUnit targetUnit = insertLocation.getTargetTranslationUnit(); - IASTNode parent = insertLocation.getPartenOfNodeToInsertBefore(); - createFunctionDefinition(targetUnit); - IASTNode nodeToInsertBefore = insertLocation.getNodeToInsertBefore(); - ASTRewrite translationUnitRewrite = collector.rewriterForTranslationUnit(targetUnit); - ASTRewrite methodRewrite = translationUnitRewrite.insertBefore(parent, nodeToInsertBefore, createdMethodDefinition, null); - createParameterModifications(methodRewrite); + List methodsToImplement = data.getMethodsToImplement(); + SubMonitor sm = SubMonitor.convert(pm, 4*methodsToImplement.size()); + for(MethodToImplementConfig config : methodsToImplement) { + createDefinition(collector, config, sm.newChild(4)); + } + } + + protected void createDefinition(ModificationCollector collector, + MethodToImplementConfig config, IProgressMonitor subMonitor) throws CoreException { + IASTSimpleDeclaration decl = config.getDeclaration(); + insertLocation = findInsertLocation(decl); + subMonitor.worked(1); + IASTTranslationUnit targetUnit = insertLocation.getTargetTranslationUnit(); + IASTNode parent = insertLocation.getPartenOfNodeToInsertBefore(); + ASTRewrite translationUnitRewrite = collector.rewriterForTranslationUnit(targetUnit); + subMonitor.worked(1); + + IASTNode nodeToInsertBefore = insertLocation.getNodeToInsertBefore(); + IASTNode createdMethodDefinition = createFunctionDefinition(targetUnit, decl); + subMonitor.worked(1); + ASTRewrite methodRewrite = translationUnitRewrite.insertBefore(parent, nodeToInsertBefore, createdMethodDefinition , null); + createParameterModifications(methodRewrite, config.getParaHandler()); + subMonitor.done(); } - private void createParameterModifications(ASTRewrite methodRewrite) { - for(ParameterInfo actParameterInfo : parameterHandler.getParameterInfos()) { + private void createParameterModifications(ASTRewrite methodRewrite, ParameterHandler handler) { + for(ParameterInfo actParameterInfo : handler.getParameterInfos()) { ASTRewrite parameterRewrite = methodRewrite.insertBefore(createdMethodDeclarator, null, actParameterInfo.getParameter(), null); createNewNameInsertModification(actParameterInfo, parameterRewrite); createRemoveDefaultValueModification(actParameterInfo, parameterRewrite); @@ -136,7 +172,7 @@ public class ImplementMethodRefactoring extends CRefactoring { } } - private InsertLocation findInsertLocation() throws CoreException { + private InsertLocation findInsertLocation(IASTSimpleDeclaration methodDeclaration) throws CoreException { InsertLocation insertLocation = MethodDefinitionInsertLocationFinder.find(methodDeclaration.getFileLocation(), methodDeclaration.getParent(), file); if (!insertLocation.hasFile() || NodeHelper.isContainedInTemplateDeclaration(methodDeclaration)) { @@ -147,19 +183,14 @@ public class ImplementMethodRefactoring extends CRefactoring { return insertLocation; } - private void createFunctionDefinition(IASTTranslationUnit unit) throws CoreException { - createFunctionDefinition( + private IASTDeclaration createFunctionDefinition(IASTTranslationUnit unit, IASTSimpleDeclaration methodDeclaration) throws CoreException { + return createFunctionDefinition( methodDeclaration.getDeclSpecifier().copy(), (ICPPASTFunctionDeclarator) methodDeclaration.getDeclarators()[0], methodDeclaration.getParent(), unit); } - - public IASTDeclaration createFunctionDefinition() throws CoreException { - createFunctionDefinition(unit); - return createdMethodDefinition; - } - private void createFunctionDefinition(IASTDeclSpecifier declSpecifier, ICPPASTFunctionDeclarator functionDeclarator, + private IASTDeclaration createFunctionDefinition(IASTDeclSpecifier declSpecifier, ICPPASTFunctionDeclarator functionDeclarator, IASTNode declarationParent, IASTTranslationUnit unit) throws CoreException { IASTFunctionDefinition func = new CPPASTFunctionDefinition(); @@ -169,7 +200,7 @@ public class ImplementMethodRefactoring extends CRefactoring { ((ICPPASTDeclSpecifier) declSpecifier).setVirtual(false); } - String currentFileName = methodDeclaration.getNodeLocations()[0].asFileLocation().getFileName(); + String currentFileName = declarationParent.getNodeLocations()[0].asFileLocation().getFileName(); if(Path.fromOSString(currentFileName).equals(insertLocation.getInsertFile().getLocation())) { declSpecifier.setInline(true); } @@ -201,10 +232,9 @@ public class ImplementMethodRefactoring extends CRefactoring { } templateDeclaration.setDeclaration(func); - createdMethodDefinition = templateDeclaration; - return; + return templateDeclaration; } - createdMethodDefinition = func; + return func; } private ICPPASTQualifiedName createQualifiedNameFor(IASTFunctionDeclarator functionDeclarator, IASTNode declarationParent) @@ -212,12 +242,8 @@ public class ImplementMethodRefactoring extends CRefactoring { int insertOffset = insertLocation.getInsertPosition(); return NameHelper.createQualifiedNameFor(functionDeclarator.getName(), file, region.getOffset(), insertLocation.getInsertFile(), insertOffset); } - - public IASTSimpleDeclaration getMethodDeclaration() { - return methodDeclaration; - } - - public ParameterHandler getParameterHandler() { - return parameterHandler; + + public ImplementMethodData getRefactoringData() { + return data; } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ImplementMethodRefactoringWizard.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ImplementMethodRefactoringWizard.java index 44ec71d2c39..c052390e0fa 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ImplementMethodRefactoringWizard.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ImplementMethodRefactoringWizard.java @@ -11,6 +11,9 @@ *******************************************************************************/ package org.eclipse.cdt.internal.ui.refactoring.implementmethod; +import java.util.HashMap; +import java.util.Map; + import org.eclipse.ltk.ui.refactoring.RefactoringWizard; /** @@ -20,16 +23,27 @@ import org.eclipse.ltk.ui.refactoring.RefactoringWizard; public class ImplementMethodRefactoringWizard extends RefactoringWizard { private final ImplementMethodRefactoring refactoring; + private MappagesMap = new HashMap(); public ImplementMethodRefactoringWizard(ImplementMethodRefactoring refactoring) { super(refactoring, WIZARD_BASED_USER_INTERFACE); this.refactoring = refactoring; } - @Override - protected void addUserInputPages() { - if(refactoring.getParameterHandler().needsAdditionalArgumentNames()) { - addPage(new ParameterNamesInputPage(refactoring.getParameterHandler())); - } - } + @Override + protected void addUserInputPages() { + addPage(new ImplementMethodInputPage(refactoring.getRefactoringData(), this)); + ImplementMethodData data = refactoring.getRefactoringData(); + for (MethodToImplementConfig config : data.getMethodDeclarations()) { + if(config.getParaHandler().needsAdditionalArgumentNames()) { + ParameterNamesInputPage page = new ParameterNamesInputPage(config, this); + pagesMap.put(config, page); + addPage(page); + } + } + } + + public ParameterNamesInputPage getPageForConfig(MethodToImplementConfig config) { + return pagesMap.get(config); + } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/Messages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/Messages.java index 3e807c9dc5d..5d89f152f0f 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/Messages.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/Messages.java @@ -24,6 +24,7 @@ public final class Messages extends NLS { public static String ParameterNamesInputPage_Title; public static String ParameterNamesInputPage_CompleteMissingMails; public static String PreviewGenerationNotPossible; + public static String ImplementMethodInputPage_PageTitle; public static String ImplementMethodRefactoringPage_GeneratingPreview; public static String ImplementMethodRefactoring_NoMethodSelected; public static String ImplementMethodRefactoring_MethodHasImpl; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/MethodToImplementConfig.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/MethodToImplementConfig.java new file mode 100644 index 00000000000..9f04cca5883 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/MethodToImplementConfig.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software (IFS)- initial API and implementation + ******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.implementmethod; + +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; + +/** + * @author Emanuel Graf IFS + * + */ +public class MethodToImplementConfig { + + private IASTSimpleDeclaration declaration; + private ParameterHandler paraHandler; + private boolean checked; + + public MethodToImplementConfig(IASTSimpleDeclaration declaration, + ParameterHandler paraHandler) { + super(); + this.declaration = declaration; + this.paraHandler = paraHandler; + } + + public IASTSimpleDeclaration getDeclaration() { + return declaration; + } + + public ParameterHandler getParaHandler() { + return paraHandler; + } + + @Override + public String toString() { + return declaration.getRawSignature(); + } + + public boolean isChecked() { + return checked; + } + + public void setChecked(boolean checked) { + this.checked = checked; + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ParameterHandler.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ParameterHandler.java index 1a4d3317ca3..2868e826d23 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ParameterHandler.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ParameterHandler.java @@ -14,18 +14,10 @@ package org.eclipse.cdt.internal.ui.refactoring.implementmethod; import java.util.ArrayList; import java.util.Collection; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.ltk.core.refactoring.Change; -import org.eclipse.ltk.core.refactoring.CompositeChange; -import org.eclipse.text.edits.InsertEdit; -import org.eclipse.text.edits.MultiTextEdit; - import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; -import org.eclipse.cdt.ui.refactoring.CTextFileChange; import org.eclipse.cdt.internal.ui.refactoring.utils.NameHelper; import org.eclipse.cdt.internal.ui.refactoring.utils.PseudoNameGenerator; @@ -40,10 +32,11 @@ public class ParameterHandler { private boolean needsAditionalArgumentNames; private PseudoNameGenerator pseudoNameGenerator; private ArrayList parameterInfos; - private ImplementMethodRefactoring refactoring; + private IASTSimpleDeclaration method; - public ParameterHandler(ImplementMethodRefactoring refactoring) { - this.refactoring = refactoring; + public ParameterHandler(IASTSimpleDeclaration method) { + this.method = method; + initArgumentNames(); } public boolean needsAdditionalArgumentNames() { @@ -85,38 +78,10 @@ public class ParameterHandler { } private IASTParameterDeclaration[] getParametersFromMethodNode() { - if(refactoring.getMethodDeclaration().getDeclarators().length < 1) { + if(method.getDeclarators().length < 1) { return null; } - return ((ICPPASTFunctionDeclarator) refactoring.getMethodDeclaration().getDeclarators()[0]).getParameters(); - } - - public String createFunctionDefinitionSignature() { - try { - CompositeChange compositeChange = (CompositeChange) refactoring.createChange(new NullProgressMonitor()); - InsertEdit insertEdit = getInsertEdit(compositeChange); - return insertEdit.getText().trim(); - } catch (OperationCanceledException e) { - return Messages.PreviewGenerationNotPossible; - } catch (CoreException e) { - return Messages.PreviewGenerationNotPossible; - } - } - - private InsertEdit getInsertEdit(CompositeChange compositeChange) { - for(Change actChange : compositeChange.getChildren()) { - if(actChange instanceof CompositeChange) { - return getInsertEdit((CompositeChange) actChange); - } else if (actChange instanceof CTextFileChange) { - CTextFileChange textFileChange = (CTextFileChange) actChange; - MultiTextEdit multiEdit = (MultiTextEdit) textFileChange.getEdit(); - if(multiEdit.getChildrenSize() == 0) { - continue; - } - return (InsertEdit) multiEdit.getChildren()[0]; - } - } - return null; + return ((ICPPASTFunctionDeclarator) method.getDeclarators()[0]).getParameters(); } public Collection getParameterInfos() { diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ParameterNamesInputPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ParameterNamesInputPage.java index b242039b80d..277fdfcc2f0 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ParameterNamesInputPage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ParameterNamesInputPage.java @@ -13,6 +13,12 @@ package org.eclipse.cdt.internal.ui.refactoring.implementmethod; import java.util.HashMap; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.jface.wizard.IWizardPage; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.CompositeChange; import org.eclipse.ltk.ui.refactoring.UserInputWizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; @@ -21,8 +27,13 @@ import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; +import org.eclipse.text.edits.InsertEdit; +import org.eclipse.text.edits.MultiTextEdit; + +import org.eclipse.cdt.ui.refactoring.CTextFileChange; import org.eclipse.cdt.internal.ui.preferences.formatter.TranslationUnitPreview; +import org.eclipse.cdt.internal.ui.refactoring.ModificationCollector; import org.eclipse.cdt.internal.ui.refactoring.dialogs.ValidatingLabeledTextField; import org.eclipse.cdt.internal.ui.refactoring.utils.DelayedJobRunner; @@ -34,13 +45,15 @@ import org.eclipse.cdt.internal.ui.refactoring.utils.DelayedJobRunner; */ public class ParameterNamesInputPage extends UserInputWizardPage { - private final ParameterHandler parameterHandler; + private MethodToImplementConfig config; private TranslationUnitPreview translationUnitPreview; private DelayedJobRunner delayedPreviewUpdater; - - public ParameterNamesInputPage(ParameterHandler parameterHandler) { - super(Messages.ParameterNamesInputPage_Title); - this.parameterHandler = parameterHandler; + private ImplementMethodRefactoringWizard wizard; + + public ParameterNamesInputPage(MethodToImplementConfig config, ImplementMethodRefactoringWizard wizard) { + super(Messages.ParameterNamesInputPage_Title); + this.config = config; + this.wizard = wizard; } public void createControl(Composite parent) { @@ -56,7 +69,7 @@ public class ParameterNamesInputPage extends UserInputWizardPage { ValidatingLabeledTextField validatingLabeledTextField = new ValidatingLabeledTextField(superComposite); validatingLabeledTextField.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL)); - for (final ParameterInfo actParameterInfo : parameterHandler.getParameterInfos()) { + for (final ParameterInfo actParameterInfo : config.getParaHandler().getParameterInfos()) { String type = actParameterInfo.getTypeName(); String content = actParameterInfo.getParameterName(); @@ -86,6 +99,35 @@ public class ParameterNamesInputPage extends UserInputWizardPage { setControl(superComposite); } + + private InsertEdit getInsertEdit(CompositeChange compositeChange) { + for(Change actChange : compositeChange.getChildren()) { + if(actChange instanceof CompositeChange) { + return getInsertEdit((CompositeChange) actChange); + } else if (actChange instanceof CTextFileChange) { + CTextFileChange textFileChange = (CTextFileChange) actChange; + MultiTextEdit multiEdit = (MultiTextEdit) textFileChange.getEdit(); + if(multiEdit.getChildrenSize() == 0) { + continue; + } + return (InsertEdit) multiEdit.getChildren()[0]; + } + } + return null; + } + + public String createFunctionDefinitionSignature() { + try { + ModificationCollector collector = new ModificationCollector(); + ((ImplementMethodRefactoring)wizard.getRefactoring()).createDefinition(collector, config, new NullProgressMonitor()); + InsertEdit insertEdit = getInsertEdit(collector.createFinalChange()); + return insertEdit.getText().trim(); + } catch (OperationCanceledException e) { + return Messages.PreviewGenerationNotPossible; + } catch (CoreException e) { + return Messages.PreviewGenerationNotPossible; + } + } private void createPreview(Composite superComposite) { translationUnitPreview = new TranslationUnitPreview(new HashMap(), superComposite); @@ -93,7 +135,7 @@ public class ParameterNamesInputPage extends UserInputWizardPage { Runnable runnable = new Runnable() { public void run() { setPreviewText(Messages.ImplementMethodRefactoringPage_GeneratingPreview); - setPreviewText(parameterHandler.createFunctionDefinitionSignature()); + setPreviewText(createFunctionDefinitionSignature()); } private void setPreviewText(final String text) { getShell().getDisplay().asyncExec(new Runnable() { @@ -111,10 +153,26 @@ public class ParameterNamesInputPage extends UserInputWizardPage { }}); } + @Override + public boolean canFlipToNextPage() { + return isPageComplete(); + } + + @Override + public IWizardPage getNextPage() { + MethodToImplementConfig nextConfig = ((ImplementMethodRefactoring)wizard.getRefactoring()).getRefactoringData().getNextConfigNeedingParameterNames(config); + if(nextConfig != null) { + return wizard.getPageForConfig(nextConfig); + }else { + return computeSuccessorPage(); + } + } + private void updatePreview() { if (translationUnitPreview == null) { return; } delayedPreviewUpdater.runJob(); - } + } + } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/messages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/messages.properties index c67e42581d8..d8b7020f425 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/messages.properties +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/messages.properties @@ -12,6 +12,7 @@ ############################################################################### ParameterNamesInputPage_Title=Implement Method ParameterNamesInputPage_CompleteMissingMails=Please complete the missing variable names: +ImplementMethodInputPage_PageTitle=Implement Method ImplementMethodRefactoring_MethodDefinition=Method Definition ImplementMethodRefactoringPage_GeneratingPreview=Generating preview... ImplementMethodRefactoring_NoMethodSelected=No method declaration selected