1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 14:42:11 +02:00

FIXED - bug 245089: Enhancement: "Refactor" -> "Implement Method ..." should work for multiple methods

https://bugs.eclipse.org/bugs/show_bug.cgi?id=245089
This commit is contained in:
Emanuel Graf 2008-12-18 09:23:57 +00:00
parent 728a1a2866
commit cc2e7e1da5
10 changed files with 449 additions and 133 deletions

View file

@ -72,30 +72,6 @@ template<class T> inline void A<T>::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

View file

@ -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<MethodToImplementConfig> methodDeclarations;
public void setMethodDeclarations(List<IASTSimpleDeclaration> methodDeclarations) {
this.methodDeclarations = new ArrayList<MethodToImplementConfig>();
for (IASTSimpleDeclaration declaration : methodDeclarations) {
this.methodDeclarations.add(new MethodToImplementConfig(declaration, new ParameterHandler(declaration)));
}
}
public List<MethodToImplementConfig> 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<MethodToImplementConfig> getMethodsToImplement() {
List<MethodToImplementConfig> ret = new ArrayList<MethodToImplementConfig>();
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<MethodToImplementConfig> 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<MethodToImplementConfig> methodsToImplement = getMethodsToImplement();
for (MethodToImplementConfig config : methodsToImplement) {
if(config.getParaHandler().needsAdditionalArgumentNames()) {
return config;
}
}
return null;
}
}

View file

@ -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);
}
}
}

View file

@ -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<IASTSimpleDeclaration> findUnimplementedMethodDeclarations(
IASTTranslationUnit unit) {
final List<IASTSimpleDeclaration> list = new ArrayList<IASTSimpleDeclaration>();
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<MethodToImplementConfig> 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;
}
}

View file

@ -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 Map<MethodToImplementConfig, ParameterNamesInputPage>pagesMap = new HashMap<MethodToImplementConfig, ParameterNamesInputPage>();
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);
}
}

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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<ParameterInfo> 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<ParameterInfo> getParameterInfos() {

View file

@ -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<String, String>(), 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();
}
}
}

View file

@ -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