1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 17:05:26 +02:00

Implement Method (work in progress) by Emanuel Graf, bug 226646.

This commit is contained in:
Markus Schorn 2008-04-16 13:09:08 +00:00
parent d353a33638
commit 6df6c40158
32 changed files with 2180 additions and 3 deletions

View file

@ -129,8 +129,11 @@ public class ChangeGenerator extends CPPASTVisitor {
synthTreatment(translationUnit);
}
sourceOffsets.put(translationUnit.getFileLocation().getFileName(),
Integer.valueOf(translationUnit.getFileLocation().getNodeOffset()));
final IASTFileLocation fileLocation = translationUnit.getFileLocation();
if (fileLocation != null) {
sourceOffsets.put(fileLocation.getFileName(),
Integer.valueOf(fileLocation.getNodeOffset()));
}
return super.visit(translationUnit);
}

View file

@ -0,0 +1,582 @@
//!implement in existing namespace
//#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest
//@.config
filename=A.h
//@A.h
namespace NameSpace
{
class ClassInNamespace
{
public:
int test();
//$void test2();$//
};
}
//@A.cpp
#include "A.h"
namespace NameSpace
{
int ClassInNamespace::test()
{
return 5;
}
}
//=
#include "A.h"
namespace NameSpace
{
int ClassInNamespace::test()
{
return 5;
}
void ClassInNamespace::test2()
{
}
}
//!method declared in otherwise empty class
//#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest
//@.config
filename=A.h
//@A.h
class A
{
public:
//$void test();$//
};
//=
class A
{
public:
void test();
};
//@A.cpp
//=
void A::test()
{
}
//!virtual method in the middle of con/destructor, without parameters and void return value
//#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest
//@.config
filename=A.h
//@A.h
#ifndef A_H_
#define A_H_
class A
{
public:
A();
//$virtual void foo();$//
~A();
};
#endif /*A_H_*/
//@A.cpp
#include "A.h"
A::A()
{
}
A::~A()
{
}
//=
#include "A.h"
A::A()
{
}
void A::foo()
{
}
A::~A()
{
}
//!implement a function at start of source file
//#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest
//@.config
filename=A.h
//@A.h
//$void function();$//
void function_with_impl();
//@A.cpp
void function_with_impl()
{
}
//=
void function()
{
}
void function_with_impl()
{
}
//!method declared in otherwise empty class without cpp file
//#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest
//@.config
filename=A.h
//@A.h
class A
{
public:
//$void test();$//
};
//=
class A
{
public:
void test();
};
inline void A::test()
{
}
//!method at end, without parameters and void return value
//#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest
//@.config
filename=A.h
//@A.h
#ifndef A_H_
#define A_H_
class A
{
public:
A();
//$void foo();$//
};
#endif /*A_H_*/
//@A.cpp
#include "A.h"
A::A()
{
}
//=
#include "A.h"
A::A()
{
}
void A::foo()
{
}
//!method at beginning, without parameters, void return value and const
//#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest
//@.config
filename=A.h
//@A.h
#ifndef A_H_
#define A_H_
class A
{
public:
//$void foo() const;$//
A();
};
#endif /*A_H_*/
//@A.cpp
#include "A.h"
A::A()
{
}
//=
#include "A.h"
void A::foo() const
{
}
A::A()
{
}
//!method with int return value
//#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest
//@.config
filename=A.h
//@A.h
#ifndef A_H_
#define A_H_
class A
{
public:
A();
//$int foo();$//
};
#endif /*A_H_*/
//@A.cpp
#include "A.h"
A::A()
{
}
//=
#include "A.h"
A::A()
{
}
int A::foo()
{
}
//!method with two int parameters
//#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest
//@.config
filename=A.h
//@A.h
#ifndef A_H_
#define A_H_
class A
{
public:
A();
//$int foo(int param1, int param2);$//
};
#endif /*A_H_*/
//@A.cpp
#include "A.h"
A::A()
{
}
//=
#include "A.h"
A::A()
{
}
int A::foo(int param1, int param2)
{
}
//!method defined in header
//#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest
//@.config
filename=A.h
//@A.h
class A
{
public:
A();
//$void test();$//
};
A::A()
{
}
//=
class A
{
public:
A();
void test();
};
A::A()
{
}
inline void A::test()
{
}
//!implement a function at end of source file
//#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest
//@.config
filename=A.h
//@A.h
void function_with_impl();
//$void function();$//
//@A.cpp
void function_with_impl()
{
}
//=
void function_with_impl()
{
}
void function()
{
}
//!implement with namespace
//#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest
//@.config
filename=A.h
//@A.h
namespace NameSpace
{
class ClassInNamespace
{
public:
int other_test();
//$void test();$//
};
}
//@A.cpp
#include "A.h"
void NameSpace::ClassInNamespace::other_test()
{
}
//=
#include "A.h"
void NameSpace::ClassInNamespace::other_test()
{
}
void NameSpace::ClassInNamespace::test()
{
}
//!implement function within namespace
//#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest
//@.config
filename=A.h
//@A.h
namespace OuterSpace {
namespace NameSpace
{
int test();
//$int test2();$//
}
}
//@A.cpp
#include "A.h"
namespace OuterSpace {
int NameSpace::test()
{
}
}
//=
#include "A.h"
namespace OuterSpace {
int NameSpace::test()
{
}
int NameSpace::test2()
{
}
}
//!implement function within namespaces
//#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest
//@.config
filename=A.h
//@A.h
namespace OuterSpace {
namespace NameSpace
{
int test();
//$int test2();$//
}
}
//@A.cpp
#include "A.h"
namespace OuterSpace {
namespace NameSpace {
int test()
{
}
}
}
//=
#include "A.h"
namespace OuterSpace {
namespace NameSpace {
int test()
{
}
int test2()
{
}
}
}
//!class template member functions
//#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest
//@.config
filename=A.h
//@A.h
template<class T> class A
{
public:
A();
//$void test();$//
};
template<class T> A<T>::A()
{
}
//=
template<class T> class A
{
public:
A();
void test();
};
template<class T> A<T>::A()
{
}
template<class T> inline void A<T>::test()
{
}
//!class template member functions with multiple templates
//#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest
//@.config
filename=A.h
//@A.h
template<class T, class U> class A
{
public:
A();
//$void test();$//
};
template<class T, class U> A<T,U>::A()
{
}
//=
template<class T, class U> class A
{
public:
A();
void test();
};
template<class T, class U> A<T,U>::A()
{
}
template<class T, class U> inline void A<T,U>::test()
{
}
//!with default parameters
//#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest
//@.config
filename=A.h
//@A.h
class Class
{
public:
//$void test(int param1, int param2 = 5, int param3 = 10);$//
};
//@A.cpp
#include "A.h"
//=
#include "A.h"
void Class::test(int param1, int param2, int param3)
{
}
//!static method
//#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest
//@.config
filename=A.h
//@A.h
class Class
{
public:
//$static void test();$//
};
//@A.cpp
#include "A.h"
//=
#include "A.h"
void Class::test()
{
}
//!member class
//#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest
//@.config
filename=A.h
//@A.h
class Demo
{
class SubClass
{
//$void test();$//
};
};
//@A.cpp
#include "A.h"
//=
#include "A.h"
void Demo::SubClass::test()
{
}

View file

@ -31,7 +31,7 @@ public class RefactoringTestSuite extends TestSuite {
suite.addTest(RefactoringTester.suite("ExtractConstantRefactoringTests", "resources/refactoring/ExtractConstant.rts"));
suite.addTest(RefactoringTester.suite("HideMethodRefactoringTests", "resources/refactoring/HideMethod.rts"));
suite.addTest(UtilTestSuite.suite());
suite.addTest(RefactoringTester.suite("ImplementMethodRefactoringTests", "resources/refactoring/ImplementMethod.rts"));
return suite;
}
}

View file

@ -0,0 +1,71 @@
/*******************************************************************************
* 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 - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.ui.tests.refactoring.implementmethod;
import java.util.Properties;
import java.util.Vector;
import org.eclipse.core.resources.IFile;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.cdt.ui.tests.refactoring.RefactoringTest;
import org.eclipse.cdt.ui.tests.refactoring.TestSourceFile;
import org.eclipse.cdt.internal.ui.refactoring.CRefactoring;
import org.eclipse.cdt.internal.ui.refactoring.implementmethod.ImplementMethodRefactoring;
/**
* @author Mirko Stocker
*
*/
public class ImplementMethodRefactoringTest extends RefactoringTest {
protected int warnings;
public ImplementMethodRefactoringTest(String name,Vector<TestSourceFile> files) {
super(name, files);
}
@Override
protected void runTest() throws Throwable {
IFile refFile = project.getFile(fileName);
CRefactoring refactoring = new ImplementMethodRefactoring(refFile, selection, null);
refactoring.lockIndex();
try {
RefactoringStatus checkInitialConditions = refactoring.checkInitialConditions(NULL_PROGRESS_MONITOR);
assertConditionsOk(checkInitialConditions);
refactoring.checkFinalConditions(NULL_PROGRESS_MONITOR);
RefactoringStatus finalConditions = refactoring.checkFinalConditions(NULL_PROGRESS_MONITOR);
if (warnings == 0) {
Change createChange = refactoring.createChange(NULL_PROGRESS_MONITOR);
assertConditionsOk(finalConditions);
createChange.perform(NULL_PROGRESS_MONITOR);
} else {
assertConditionsWarning(finalConditions, warnings);
}
compareFiles(fileMap);
}
finally {
refactoring.unlockIndex();
}
}
@Override
protected void configureRefactoring(Properties refactoringProperties) {
warnings = new Integer(refactoringProperties.getProperty("warnings", "0")).intValue(); //$NON-NLS-1$//$NON-NLS-2$
}
}

View file

@ -0,0 +1,63 @@
/*******************************************************************************
* 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 - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.ui.tests.refactoring.utils;
import junit.framework.TestCase;
import org.eclipse.cdt.internal.ui.refactoring.utils.PseudoNameGenerator;
/**
* @author Mirko Stocker
*
*/
public class PseudoNameGeneratorTest extends TestCase {
private static final String CHAR2 = "char2"; //$NON-NLS-1$
private static final String INT3 = "int3"; //$NON-NLS-1$
private static final String INT2 = "int2"; //$NON-NLS-1$
private static final String CHAR = "char"; //$NON-NLS-1$
private static final String CHAR1 = "char1"; //$NON-NLS-1$
private static final String INT = "int"; //$NON-NLS-1$
private static final String INT1 = "int1"; //$NON-NLS-1$
private PseudoNameGenerator pseudoNameGenerator;
@Override
protected void setUp() throws Exception {
pseudoNameGenerator = new PseudoNameGenerator();
}
public void testNonConflictingCase() {
assertEquals(INT1, pseudoNameGenerator.generateNewName(INT));
}
public void testMultipleNonConflictingCase() {
assertEquals(INT1, pseudoNameGenerator.generateNewName(INT));
assertEquals(CHAR1, pseudoNameGenerator.generateNewName(CHAR));
}
public void testConflictingCase() {
pseudoNameGenerator.addExistingName(INT1);
assertEquals(INT2, pseudoNameGenerator.generateNewName(INT));
}
public void testMultipleConflictsCase() {
pseudoNameGenerator.addExistingName(INT1);
pseudoNameGenerator.addExistingName(CHAR1);
assertEquals(INT2, pseudoNameGenerator.generateNewName(INT));
assertEquals(INT3, pseudoNameGenerator.generateNewName(INT));
assertEquals(CHAR2, pseudoNameGenerator.generateNewName(CHAR));
}
public void testWithNamespace() {
assertEquals("string1", pseudoNameGenerator.generateNewName("std::string")); //$NON-NLS-1$//$NON-NLS-2$
}
}

View file

@ -26,6 +26,7 @@ public class UtilTestSuite extends TestSuite {
UtilTestSuite suite = new UtilTestSuite();
suite.addTest(IdentifierHelperTest.suite());
suite.addTest(RefactoringTester.suite("TranslationUnitHelperTest", "resources/refactoring/TranslationunitHelper.rts")); //$NON-NLS-1$ //$NON-NLS-2$
suite.addTestSuite(PseudoNameGeneratorTest.class);
return suite;
}
}

View file

@ -33,6 +33,7 @@ Export-Package: org.eclipse.cdt.internal.corext;x-internal:=true,
org.eclipse.cdt.internal.ui.refactoring.extractconstant;x-friends:="org.eclipse.cdt.ui.tests",
org.eclipse.cdt.internal.ui.refactoring.extractfunction;x-friends:="org.eclipse.cdt.ui.tests",
org.eclipse.cdt.internal.ui.refactoring.hidemethod;x-friends:="org.eclipse.cdt.ui.tests",
org.eclipse.cdt.internal.ui.refactoring.implementmethod;x-friends:="org.eclipse.cdt.ui.tests",
org.eclipse.cdt.internal.ui.refactoring.rename;x-friends:="org.eclipse.cdt.ui.tests",
org.eclipse.cdt.internal.ui.refactoring.utils;x-friends:="org.eclipse.cdt.ui.tests",
org.eclipse.cdt.internal.ui.search;x-internal:=true,

View file

@ -146,6 +146,8 @@ ActionDefinition.extractConstant.name= Extract Constant - Refactoring
ActionDefinition.extractConstant.description= Extract a constant for the selected expression
ActionDefinition.extractFunction.name= Extract Function - Refactoring
ActionDefinition.extractFunction.description= Extract a function for the selected list of expressions or statements
ActionDefinition.implementMethod.name= Implement Method - Source Generation
ActionDefinition.implementMethod.description= Implements a method for a selected method declaration
# Action Set
CodingActionSet.label= C/C++ Coding
@ -156,6 +158,7 @@ Refactoring.renameAction.label=Re&name...
Refactoring.extractConstant.label=Extr&act Constant...
Refactoring.extractFunction.label=Extract &Function... (work in progress)
Refactoring.hideMethod.label=Hide Member Function... (work in progress)
Refactoring.implementMethod.label=Impl&ement Method... (work in progress)
CEditor.name=C/C++ Editor

View file

@ -1171,6 +1171,13 @@
id="org.eclipse.cdt.ui.actions.ExtractConstant"
retarget="true">
</action>
<action
definitionId="org.eclipse.cdt.ui.refactor.implement.method"
label="%Refactoring.implementMethod.label"
menubarPath="org.eclipse.jdt.ui.refactoring.menu/codingGroup"
id="org.eclipse.cdt.ui.actions.ImplementMethod"
retarget="true">
</action>
</actionSet>
<actionSet
label="%CSearchActionSet.label"
@ -1996,6 +2003,12 @@
categoryId="org.eclipse.cdt.ui.category.refactoring"
id="org.eclipse.cdt.ui.refactor.extract.function">
</command>
<command
name="%ActionDefinition.implementMethod.name"
description="%ActionDefinition.implementMethod.description"
categoryId="org.eclipse.cdt.ui.category.refactoring"
id="org.eclipse.cdt.ui.refactor.implement.method">
</command>
</extension>
<extension

View file

@ -110,6 +110,12 @@ public interface ICEditorActionDefinitionIds extends ITextEditorActionDefinition
*/
public static final String HIDE_METHOD= "org.eclipse.cdt.ui.refactor.hide.method"; //$NON-NLS-1$
/**
* Action definition ID of the refactor -> implement method action
* (value <code>"org.eclipse.cdt.ui.refactor.implement.method"</code>).
*/
public static final String IMPLEMENT_METHOD= "org.eclipse.cdt.ui.refactor.implement.method"; //$NON-NLS-1$
/**
* Action definition ID of the refactor -> undo action
* (value <code>"org.eclipse.cdt.ui.edit.text.undo.action"</code>).

View file

@ -27,6 +27,9 @@ public final class Messages extends NLS {
public static String ExtractInputPage_EnterName;
public static String ExtractInputPage_CheckName;
public static String VisibilitySelectionPanel_AccessModifier;
public static String ValidatingLabeledTextField_CantBeEmpty;
public static String ValidatingLabeledTextField_InvalidCharacters;
public static String ValidatingLabeledTextField_DuplicatedNames;
static {
NLS.initializeMessages(BUNDLE_NAME, Messages.class);

View file

@ -0,0 +1,198 @@
/*******************************************************************************
* 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 - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.dialogs;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
/**
* @author Mirko Stocker
*
* Text field with a description and error handling using the Validator-Callback. Can also be used for multiple inputs.
*
*/
public class ValidatingLabeledTextField extends Composite {
private static final String EMPTY_STRING = ""; //$NON-NLS-1$
private final Map<Text, Boolean> validationStatus = new HashMap<Text, Boolean>();
private final ArrayList<Listener> inputTextListeners = new ArrayList<Listener>();
private final Color errorColor = new Color(getShell().getDisplay(), new RGB(255, 208, 196));
/**
* The Validator is used for feedback about the validation status of the inputs and to validate the input.
*/
public static abstract class Validator {
/**
* Is called if all input texts contain valid input.
*/
public void hasErrors() {}
/**
* Is called if any input text contains invalid input.
*/
public void hasNoErrors() {}
/**
* @param text the new value of the field
* @return whether the value is valid or not
*/
public abstract boolean isValidInput(String text);
public String errorMessageForEmptyField() {
return Messages.ValidatingLabeledTextField_CantBeEmpty;
}
public String errorMessageForInvalidInput() {
return Messages.ValidatingLabeledTextField_InvalidCharacters;
}
public String errorMessageForDuplicateValues() {
return Messages.ValidatingLabeledTextField_DuplicatedNames;
}
}
public ValidatingLabeledTextField(Composite parent, int style) {
super(parent, style);
GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 4;
setLayout(gridLayout);
}
public ValidatingLabeledTextField(Composite parent) {
this(parent, SWT.NONE);
}
public void addElement(String description, String initialText, boolean readOnly, final Validator validator) {
Label label = new Label(this, SWT.NONE);
label.setText(description);
label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
final Text textField = new Text(this, SWT.BORDER |SWT.SINGLE);
textField.setText(initialText);
textField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
if(readOnly) {
//readOnly inputs are always valid:
validationStatus.put(textField, Boolean.TRUE);
textField.setEnabled(false);
return;
}
validationStatus.put(textField, Boolean.FALSE);
final Label errorImageLabel = new Label(this, SWT.NONE);
errorImageLabel.setImage(JFaceResources.getImage(Dialog.DLG_IMG_MESSAGE_ERROR));
errorImageLabel.setLayoutData(new GridData());
errorImageLabel.setVisible(false);
final Label errorLabel = new Label(this, SWT.NONE);
errorLabel.setLayoutData(new GridData());
final Color defaultColor = textField.getBackground();
Listener listener = new Listener(){
@SuppressWarnings("unchecked")
public void checkField() {
String newName = textField.getText();
boolean isEmpty = (newName.length() == 0);
boolean isNameAlreadyInUse = nameAlreadyInUse(textField, newName);
boolean isValid = validator.isValidInput(newName);
if (isValid && !isNameAlreadyInUse && !isEmpty) {
setErrorStatus(EMPTY_STRING);
} else if (isEmpty) {
setErrorStatus(validator.errorMessageForEmptyField());
} else if (!isValid) {
setErrorStatus(validator.errorMessageForInvalidInput());
} else if (isNameAlreadyInUse) {
setErrorStatus(validator.errorMessageForDuplicateValues());
}
validationStatus.put(textField, Boolean.valueOf(isValid && !isNameAlreadyInUse && !isEmpty));
if(validationStatus.values().contains(Boolean.FALSE) || isEmpty || isNameAlreadyInUse) {
validator.hasErrors();
} else {
validator.hasNoErrors();
}
layout();
// recheck all other listeners in case duplicate names have been resolved,
// but remove this first to avoid an infinite loop
inputTextListeners.remove(this);
for(Listener listener : (ArrayList<Listener>) inputTextListeners.clone()) {
listener.handleEvent(null);
}
inputTextListeners.add(this);
}
private boolean nameAlreadyInUse(final Text textField, String newName) {
for (Text text : validationStatus.keySet()) {
if(text != textField && text.getText().equals(newName)) {
return true;
}
}
return false;
}
private void setErrorStatus(String errorMessage) {
if (EMPTY_STRING.equals(errorMessage)) {
textField.setBackground(defaultColor);
errorLabel.setText(EMPTY_STRING);
errorImageLabel.setVisible(false);
} else {
textField.setBackground(errorColor);
errorLabel.setText(errorMessage);
errorImageLabel.setVisible(true);
}
}
public void handleEvent(Event event) {
checkField();
}};
//we need to keep a list of all listeners so we get access from other textfields to resolve duplicate names
inputTextListeners.add(listener);
listener.handleEvent(null);
textField.addListener(SWT.Modify, listener);
}
}

View file

@ -15,3 +15,6 @@ ExtractInputPage_ReplaceInSubclass=Replace in subclass:
ExtractInputPage_EnterName=Enter a name
ExtractInputPage_CheckName=Check Name: {0}
VisibilitySelectionPanel_AccessModifier=&Access modifier:
ValidatingLabeledTextField_CantBeEmpty=Cannot be empty
ValidatingLabeledTextField_InvalidCharacters=Invalid characters
ValidatingLabeledTextField_DuplicatedNames=Duplicated name

View file

@ -0,0 +1,248 @@
/*******************************************************************************
* 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 - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.implementmethod;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
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.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTCompoundStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionDeclarator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionDefinition;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTemplateDeclaration;
import org.eclipse.cdt.internal.ui.refactoring.CRefactoring;
import org.eclipse.cdt.internal.ui.refactoring.ModificationCollector;
import org.eclipse.cdt.internal.ui.refactoring.utils.DefinitionFinder;
import org.eclipse.cdt.internal.ui.refactoring.utils.NameHelper;
import org.eclipse.cdt.internal.ui.refactoring.utils.NodeHelper;
import org.eclipse.cdt.internal.ui.refactoring.utils.PseudoNameGenerator;
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
*
*/
public class ImplementMethodRefactoring extends CRefactoring {
private IASTSimpleDeclaration methodDeclaration;
private InsertLocation insertLocation;
private final Set<String> generatedNames = new HashSet<String>();
public ImplementMethodRefactoring(IFile file, ISelection selection, ICElement element) {
super(file, selection, element);
}
public boolean needsAdditionalArgumentNames() {
for (IASTParameterDeclaration parameterDeclaration : getParameters()) {
if(parameterDeclaration.getDeclarator().getName().toCharArray().length < 1) {
return true;
}
}
return false;
}
public IASTParameterDeclaration[] getParameters() {
if(methodDeclaration.getDeclarators().length < 1) {
return null;
}
return ((ICPPASTFunctionDeclarator) methodDeclaration.getDeclarators()[0]).getParameters();
}
@Override
public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException {
SubMonitor sm = SubMonitor.convert(pm, 8);
super.checkInitialConditions(sm.newChild(6));
methodDeclaration = SelectionHelper.findFirstSelectedDeclaration(region, unit);
if (methodDeclaration == null) {
initStatus.addFatalError("No method selected"); //$NON-NLS-1$
return initStatus;
}
if(isProgressMonitorCanceld(sm, initStatus))return initStatus;
sm.worked(1);
if (DefinitionFinder.getDefinition(methodDeclaration, file) != null) {
initStatus.addFatalError("This method already has an implementation."); //$NON-NLS-1$
return initStatus;
}
if(isProgressMonitorCanceld(sm, initStatus))return initStatus;
sm.worked(1);
sm.done();
return initStatus;
}
@Override
protected void collectModifications(IProgressMonitor pm, ModificationCollector collector) throws CoreException, OperationCanceledException {
findInsertLocation();
IASTTranslationUnit targetUnit = insertLocation.getTargetTranslationUnit();
IASTNode parent = insertLocation.getPartenOfNodeToInsertBefore();
IASTNode insertNode = createFunctionDefinition(targetUnit);
IASTNode nodeToInsertBefore = insertLocation.getNodeToInsertBefore();
ASTRewrite rewrite = collector.rewriterForTranslationUnit(targetUnit);
rewrite.insertBefore(parent, nodeToInsertBefore, insertNode, null);
}
private void findInsertLocation() throws CoreException {
insertLocation = MethodDefinitionInsertLocationFinder.find(
methodDeclaration.getFileLocation(), methodDeclaration
.getParent(), file);
if (!insertLocation.hasFile()) {
insertLocation.setInsertFile(file);
insertLocation.setNodeToInsertAfter(NodeHelper
.getTopLevelParent(methodDeclaration));
}
}
private IASTNode createFunctionDefinition(IASTTranslationUnit unit) {
return createFunctionDefinition(
methodDeclaration.getDeclSpecifier(),
(ICPPASTFunctionDeclarator) methodDeclaration.getDeclarators()[0],
methodDeclaration.getParent(), unit);
}
public IASTNode createFunctionDefinition() {
return createFunctionDefinition(unit);
}
private IASTNode createFunctionDefinition(IASTDeclSpecifier declSpecifier, ICPPASTFunctionDeclarator functionDeclarator, IASTNode declarationParent, IASTTranslationUnit unit) {
IASTFunctionDefinition func = new CPPASTFunctionDefinition();
func.setParent(unit);
if(declSpecifier instanceof ICPPASTDeclSpecifier) {
((ICPPASTDeclSpecifier) declSpecifier).setVirtual(false);
}
if(Path.fromOSString(methodDeclaration.getNodeLocations()[0].asFileLocation().getFileName()).equals(insertLocation.getInsertFile().getLocation())) {
declSpecifier.setInline(true);
}
if(declSpecifier.getStorageClass() == IASTDeclSpecifier.sc_static) {
declSpecifier.setStorageClass(IASTDeclSpecifier.sc_unspecified);
}
func.setDeclSpecifier(declSpecifier);
ICPPASTQualifiedName qname = createQualifiedNameFor(functionDeclarator, declarationParent);
CPPASTFunctionDeclarator newFunctionDeclarator = new CPPASTFunctionDeclarator();
newFunctionDeclarator.setName(qname);
newFunctionDeclarator.setConst(functionDeclarator.isConst());
PseudoNameGenerator pseudoNameGenerator = new PseudoNameGenerator();
for(IASTParameterDeclaration parameter : getParameters()) {
if(parameter.getDeclarator().getName().toString().length() > 0) {
pseudoNameGenerator.addExistingName(parameter.getDeclarator().getName().toString());
}
}
for(IASTParameterDeclaration parameter : getParameters()) {
if(parameter.getDeclarator().getName().toString().length() < 1) {
IASTDeclSpecifier parameterDeclSpecifier = parameter.getDeclSpecifier();
String typeName;
if(parameterDeclSpecifier instanceof ICPPASTNamedTypeSpecifier) {
typeName = ((ICPPASTNamedTypeSpecifier) parameterDeclSpecifier).getName().getRawSignature();
} else {
typeName = parameterDeclSpecifier.getRawSignature();
}
String generateNewName = pseudoNameGenerator.generateNewName(typeName);
generatedNames.add(generateNewName);
parameter.getDeclarator().setName(new CPPASTName(generateNewName.toCharArray()));
}
newFunctionDeclarator.addParameterDeclaration(parameter);
}
removeAllDefaultParameters(newFunctionDeclarator);
func.setDeclarator(newFunctionDeclarator);
func.setBody(new CPPASTCompoundStatement());
if(classHasTemplates(declarationParent)) {
CPPASTTemplateDeclaration templateDeclaration = new CPPASTTemplateDeclaration();
templateDeclaration.setParent(unit);
for(ICPPASTTemplateParameter templateParameter : ((ICPPASTTemplateDeclaration) declarationParent.getParent().getParent() ).getTemplateParameters()) {
templateDeclaration.addTemplateParamter(templateParameter);
}
templateDeclaration.setDeclaration(func);
return templateDeclaration;
}
return func;
}
private void removeAllDefaultParameters(ICPPASTFunctionDeclarator functionDeclarator) {
for (IASTParameterDeclaration parameterDeclaration : functionDeclarator.getParameters()) {
parameterDeclaration.getDeclarator().setInitializer(null);
}
}
private ICPPASTQualifiedName createQualifiedNameFor(IASTFunctionDeclarator functionDeclarator, IASTNode declarationParent) {
int insertOffset;
if(insertLocation.getNodeToInsertBefore() == null) {
insertOffset = 0;
} else {
insertOffset = insertLocation.getPartenOfNodeToInsertBefore().getFileLocation().getNodeOffset();
}
return NameHelper.createQualifiedNameFor(functionDeclarator.getName(), file, region.getOffset(), insertLocation.getInsertFile(), insertOffset);
}
private boolean classHasTemplates(IASTNode declarationParent) {
return declarationParent.getParent() != null && declarationParent.getParent().getParent() instanceof ICPPASTTemplateDeclaration;
}
public IASTSimpleDeclaration getMethodDeclaration() {
return methodDeclaration;
}
public Set<String> getGeneratedNames() {
return generatedNames;
}
}

View file

@ -0,0 +1,55 @@
/*******************************************************************************
* 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 - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.implementmethod;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.window.IShellProvider;
import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.internal.ui.refactoring.RefactoringRunner;
/**
* @author Lukas Felber
*
*/
public class ImplementMethodRefactoringRunner extends RefactoringRunner {
public ImplementMethodRefactoringRunner(IFile file, ISelection selection, ICElement element, IShellProvider shellProvider) {
super(file, selection, element, shellProvider);
}
@Override
public void run() {
ImplementMethodRefactoring refactoring = new ImplementMethodRefactoring(file, selection, celement);
ImplementMethodRefactoringWizard wizard = new ImplementMethodRefactoringWizard(refactoring);
RefactoringWizardOpenOperation operator = new RefactoringWizardOpenOperation(wizard);
try {
refactoring.lockIndex();
try {
operator.run(shellProvider.getShell(), refactoring.getName());
}
finally {
refactoring.unlockIndex();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (CoreException e) {
CUIPlugin.log(e);
}
}
}

View file

@ -0,0 +1,35 @@
/*******************************************************************************
* 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 - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.implementmethod;
import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
/**
* @author Mirko Stocker
*
*/
public class ImplementMethodRefactoringWizard extends RefactoringWizard {
private final ImplementMethodRefactoring refactoring;
public ImplementMethodRefactoringWizard(ImplementMethodRefactoring refactoring) {
super(refactoring, WIZARD_BASED_USER_INTERFACE);
this.refactoring = refactoring;
}
@Override
protected void addUserInputPages() {
if(refactoring.needsAdditionalArgumentNames()) {
addPage(new ParameterNamesInputPage(refactoring));
}
}
}

View file

@ -0,0 +1,89 @@
/*******************************************************************************
* 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 - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.implementmethod;
import org.eclipse.core.resources.IFile;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.internal.ui.refactoring.utils.TranslationUnitHelper;
/**
* Is returned when using the find-method of the MethodDefinitionInsertLocationFinder.
* Contains all the infos needet to insert at the correct position.
*
* @author Lukas Felber
*
*/
public class InsertLocation {
private IFile insertFile;
private IASTNode nodeToInsertAfter;
private IASTNode nodeToInsertBefore;
private IASTTranslationUnit targetTranslationUnit;
public boolean hasAnyNode() {
return nodeToInsertAfter == null && nodeToInsertBefore == null;
}
public IASTNode getNodeToInsertBefore() {
return nodeToInsertBefore;
}
public IASTNode getPartenOfNodeToInsertBefore() {
IASTNode affectedNode = getAffectedNode();
return (affectedNode != null) ? affectedNode.getParent() : getTargetTranslationUnit();
}
private IASTNode getAffectedNode() {
IASTNode concernedNode = (nodeToInsertBefore != null) ? nodeToInsertBefore : nodeToInsertAfter;
return concernedNode;
}
public IFile getInsertFile() {
return insertFile;
}
public void setInsertFile(IFile insertFile) {
this.insertFile = insertFile;
}
public void setNodeToInsertAfter(IASTNode nodeToInsertAfter) {
this.nodeToInsertAfter = nodeToInsertAfter;
}
public void setNodeToInsertBefore(IASTNode nodeToInsertBefore) {
this.nodeToInsertBefore = nodeToInsertBefore;
}
public boolean hasFile() {
return insertFile != null;
}
public IASTTranslationUnit getTargetTranslationUnit() {
if(targetTranslationUnit == null) {
loadTargetTranslationUnit();
}
return targetTranslationUnit;
}
private void loadTargetTranslationUnit() {
IASTNode affectedNode = getAffectedNode();
if(affectedNode != null) {
targetTranslationUnit = affectedNode.getTranslationUnit();
} else if(hasFile()) {
targetTranslationUnit = TranslationUnitHelper.loadTranslationUnit(insertFile);
}
}
}

View file

@ -0,0 +1,32 @@
/*******************************************************************************
* Copyright (c) 2005 IBM Corporation 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:
* IBM - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.implementmethod;
import org.eclipse.osgi.util.NLS;
public final class Messages extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.cdt.internal.ui.refactoring.implementmethod.messages";//$NON-NLS-1$
private Messages() {
// Do not instantiate
}
public static String ImplementMethodRefactoring_MethodDefinition;
public static String ParameterNamesInputPage_Title;
public static String ParameterNamesInputPage_CompleteMissingMails;
static {
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
}
}

View file

@ -0,0 +1,133 @@
/*******************************************************************************
* 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 - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.implementmethod;
import java.util.Collection;
import java.util.Vector;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.internal.ui.refactoring.utils.DefinitionFinder;
import org.eclipse.cdt.internal.ui.refactoring.utils.FileHelper;
import org.eclipse.cdt.internal.ui.refactoring.utils.NodeHelper;
/**
* Findes the information that are needed to tell where a MethodDefinition of a certain method declaration should be inserted.
*
* @author Mirko Stocker, Lukas Felber
*
*/
public class MethodDefinitionInsertLocationFinder {
private static IASTNode findFunctionDefinitionInParents(IASTNode node) {
if(node == null) {
return null;
} else if(node instanceof IASTFunctionDefinition) {
return node;
}
return findFunctionDefinitionInParents(node.getParent());
}
private static IASTNode findFirstSurroundingParentFunctionNode(IASTNode definition) {
IASTNode functionDefinitionInParents = findFunctionDefinitionInParents(definition);
if(functionDefinitionInParents == null || functionDefinitionInParents.getNodeLocations().length == 0) {
return null;
}
return functionDefinitionInParents;
}
public static InsertLocation find(IASTFileLocation methodDeclarationLocation, IASTNode parent, IFile file) throws CoreException {
IASTName definition = null;
IASTDeclaration[] declarations = NodeHelper.getDeclarations(parent);
InsertLocation result = new InsertLocation();
for (IASTSimpleDeclaration simpleDeclaration : getAllPreviousIASTSimpleDeclarationsFromClassInReverseOrder(declarations, methodDeclarationLocation)) {
definition = DefinitionFinder.getDefinition(simpleDeclaration, file);
if (definition != null) {
result.setNodeToInsertAfter(findFirstSurroundingParentFunctionNode(definition));
result.setInsertFile(FileHelper.getIFilefromIASTNode(definition));
}
}
for (IASTSimpleDeclaration simpleDeclaration : getAllFollowingIASTSimpleDeclarationsFromClass(declarations, methodDeclarationLocation)) {
definition = DefinitionFinder.getDefinition(simpleDeclaration, file);
if (definition != null) {
result.setNodeToInsertBefore(findFirstSurroundingParentFunctionNode(definition));
result.setInsertFile(FileHelper.getIFilefromIASTNode(definition));
}
}
if(!result.hasAnyNode()) {
return result;
}
IPath path = file.getLocation().removeFileExtension().addFileExtension("cpp"); //$NON-NLS-1$
IFile fileForLocation = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path);
if(fileForLocation != null && fileForLocation.exists()) {
result.setInsertFile(fileForLocation);
}
return result;
}
/**
* Search the given class for all IASTSimpleDeclarations occuring before 'method' and return them in reverse order.
*
* @param declarations to be searched
* @param methodPosition on which the search aborts
* @return all declarations, sorted in reverse order
*/
private static Collection<IASTSimpleDeclaration> getAllPreviousIASTSimpleDeclarationsFromClassInReverseOrder(IASTDeclaration[] declarations, IASTFileLocation methodPosition) {
Vector<IASTSimpleDeclaration> allIASTSimpleDeclarations = new Vector<IASTSimpleDeclaration>();
for (IASTDeclaration decl : declarations) {
if (decl.getFileLocation().getStartingLineNumber() >= methodPosition.getStartingLineNumber()) {
return allIASTSimpleDeclarations;
}
if (isMemberFunctionDeclaration(decl)) {
allIASTSimpleDeclarations.insertElementAt((IASTSimpleDeclaration) decl, 0);
}
}
return allIASTSimpleDeclarations;
}
private static Collection<IASTSimpleDeclaration> getAllFollowingIASTSimpleDeclarationsFromClass(IASTDeclaration[] declarations, IASTFileLocation methodPosition) {
Vector<IASTSimpleDeclaration> allIASTSimpleDeclarations = new Vector<IASTSimpleDeclaration>();
for (IASTDeclaration decl : declarations) {
if (isMemberFunctionDeclaration(decl) && decl.getFileLocation().getStartingLineNumber() > methodPosition.getStartingLineNumber() ) {
allIASTSimpleDeclarations.add((IASTSimpleDeclaration) decl);
}
}
return allIASTSimpleDeclarations;
}
private static boolean isMemberFunctionDeclaration(IASTDeclaration decl) {
return decl instanceof IASTSimpleDeclaration && ((IASTSimpleDeclaration) decl).getDeclarators().length > 0 && ((IASTSimpleDeclaration) decl).getDeclarators()[0] instanceof IASTFunctionDeclarator;
}
}

View file

@ -0,0 +1,101 @@
/*******************************************************************************
* 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 - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.implementmethod;
import java.util.HashMap;
import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;
import org.eclipse.swt.SWT;
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.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
import org.eclipse.cdt.internal.ui.preferences.formatter.TranslationUnitPreview;
import org.eclipse.cdt.internal.ui.refactoring.dialogs.ValidatingLabeledTextField;
import org.eclipse.cdt.internal.ui.refactoring.utils.NameHelper;
/**
* InputPage used by the ImplementMethod refactoring if its necessary to enteraditional parameter names.
*
* @author Mirko Stocker
*
*/
public class ParameterNamesInputPage extends UserInputWizardPage {
private final ImplementMethodRefactoring refactoring;
private TranslationUnitPreview translationUnitPreview;
public ParameterNamesInputPage(ImplementMethodRefactoring implementMethodRefactoring) {
super(Messages.ParameterNamesInputPage_Title);
this.refactoring = implementMethodRefactoring;
}
public void createControl(Composite parent) {
Composite superComposite = new Composite(parent, SWT.NONE);
superComposite.setLayout(new GridLayout());
Label label = new Label(superComposite, SWT.NONE);
label.setText(Messages.ParameterNamesInputPage_CompleteMissingMails);
label.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));
ValidatingLabeledTextField validatingLabeledTextField = new ValidatingLabeledTextField(superComposite);
validatingLabeledTextField.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));
for (final IASTParameterDeclaration parameterDeclaration : refactoring.getParameters()) {
String type = parameterDeclaration.getDeclSpecifier().getRawSignature();
String content = String.valueOf(parameterDeclaration.getDeclarator().getName().toCharArray());
boolean enabled = parameterDeclaration.getDeclarator().getName().toCharArray().length > 0;
validatingLabeledTextField.addElement(type, content, enabled, new ValidatingLabeledTextField.Validator(){
@Override
public void hasErrors() {
setPageComplete(false);
}
@Override
public void hasNoErrors() {
setPageComplete(true);
}
@Override
public boolean isValidInput(String newName) {
boolean isValid = NameHelper.isValidLocalVariableName(newName);
if(isValid) {
parameterDeclaration.getDeclarator().setName(new CPPASTName(newName.toCharArray()));
translationUnitPreview.setPreviewText(refactoring.createFunctionDefinition().getRawSignature());
}
return isValid;
}});
}
translationUnitPreview = new TranslationUnitPreview(new HashMap<String, String>(), superComposite);
translationUnitPreview.getControl().setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));
translationUnitPreview.setPreviewText(refactoring.createFunctionDefinition().getRawSignature());
setControl(superComposite);
setPageComplete(false);
}
}

View file

@ -0,0 +1,15 @@
###############################################################################
# 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 - initial API and implementation
# IBM Corporation
###############################################################################
ParameterNamesInputPage_Title=Implement Method
ParameterNamesInputPage_CompleteMissingMails=Please complete the missing variable names:
ImplementMethodRefactoring_MethodDefinition=Method Definition

View file

@ -0,0 +1,109 @@
/*******************************************************************************
* 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 - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.utils;
import java.util.TreeMap;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.internal.ui.refactoring.Container;
/**
* Helper class to find definitions.
*
* @author Lukas Felber
*
*/
public class DefinitionFinder {
public static IASTName getDefinition(IASTSimpleDeclaration simpleDeclaration, IFile file) throws CoreException {
IASTDeclarator declarator = simpleDeclaration.getDeclarators()[0];
IBinding resolveBinding = declarator.getName().resolveBinding();
return DefinitionFinder.getDefinition(declarator.getName(), resolveBinding, file);
}
@SuppressWarnings("null") // Can't be null
public static IASTName getDefinition(IASTName methodName, IBinding bind, IFile file) throws CoreException {
TreeMap<String, IASTTranslationUnit> parsedFiles = new TreeMap<String, IASTTranslationUnit>();
ITranslationUnit tu = (ITranslationUnit) CCorePlugin.getDefault().getCoreModel().create(file);
IIndex index = CCorePlugin.getIndexManager().getIndex(tu.getCProject());
IIndexName[] pdomref = null;
try {
index.acquireReadLock();
pdomref = index.findDefinitions(bind);
} catch (InterruptedException e) {
IStatus status = new Status(IStatus.WARNING, CUIPlugin.PLUGIN_ID, IStatus.OK, e.getMessage(), e);
CUIPlugin.log(status);
} finally {
index.releaseReadLock();
}
if (pdomref == null || (pdomref != null && pdomref.length < 1)) {
return null;
}
IASTTranslationUnit transUnit;
if (!parsedFiles.containsKey(pdomref[0].getFileLocation().getFileName())) {
String filename = pdomref[0].getFileLocation().getFileName();
transUnit = TranslationUnitHelper.loadTranslationUnit(filename);
} else {
transUnit = parsedFiles.get(pdomref[0].getFileLocation().getFileName());
}
return findDefinitionInTranslationUnit(transUnit, methodName, pdomref[0]);
}
private static IASTName findDefinitionInTranslationUnit(IASTTranslationUnit transUnit, final IASTName name2, final IIndexName indexName) {
final Container<IASTName> defName = new Container<IASTName>();
transUnit.accept(new CPPASTVisitor() {
{
shouldVisitNames = true;
}
@Override
public int visit(IASTName name) {
if (name.isDefinition() && name.getNodeLocations().length > 0) {
IASTNodeLocation nodeLocation = name.getNodeLocations()[0];
if (indexName.getNodeOffset() == nodeLocation.getNodeOffset()
&& indexName.getNodeLength() == nodeLocation.getNodeLength()
&& new Path(indexName.getFileLocation().getFileName()).equals(new Path(nodeLocation.asFileLocation().getFileName()))) {
defName.setObject(name);
return ASTVisitor.PROCESS_ABORT;
}
}
return ASTVisitor.PROCESS_CONTINUE;
}
});
return defName.getObject();
}
}

View file

@ -0,0 +1,67 @@
/*******************************************************************************
* 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 - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.utils;
import java.util.regex.Pattern;
import org.eclipse.core.resources.IFile;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTQualifiedName;
/**
* Helps with IASTNames.
*
* @author Mirko Stocker
*
*/
public class NameHelper {
private static final String localVariableRegexp = "[a-z_A-Z]\\w*"; //$NON-NLS-1$
public static boolean isValidLocalVariableName(String name) {
boolean valid = Pattern.compile(localVariableRegexp).matcher(name).matches();
return valid; /* && Keyword.getKeyword(stringToValidate, stringToValidate.length()) == null*/ //TODO Check for keywords?;
}
/**
* Constructs the fully qualified name from the given parameters. The file and offset parameters are used to determine
* the namespace at the declaration position and the target namespace at the target position.
*
* @param declaratorName of the method or function
* @param declarationFile
* @param selectionOffset the offset in the declarationFile, usually the position or selection of the declaration
* @param insertFile the target file in which the definition is inserted
* @param insertLocation
* @return the correct name for the target
*/
public static ICPPASTQualifiedName createQualifiedNameFor(IASTName declaratorName, IFile declarationFile, int selectionOffset, IFile insertFile, int insertLocation) {
ICPPASTQualifiedName qname = new CPPASTQualifiedName();
IASTName[] declarationNames = NamespaceHelper.getSurroundingNamespace(declarationFile, selectionOffset).getNames();
IASTName[] implementationNames = NamespaceHelper.getSurroundingNamespace(insertFile, insertLocation).getNames();
for(int i = 0; i < declarationNames.length; i++) {
if(i >= implementationNames.length) {
qname.addName(declarationNames[i]);
} else if (!String.valueOf(declarationNames[i].toCharArray()).equals(String.valueOf(implementationNames[i].toCharArray()))) {
qname.addName(declarationNames[i]);
}
}
qname.addName(declaratorName);
return qname;
}
}

View file

@ -0,0 +1,108 @@
/*******************************************************************************
* 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 - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.utils;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNamedTypeSpecifier;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTQualifiedName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleTypeTemplateParameter;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTemplateId;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTypeId;
import org.eclipse.core.resources.IFile;
/**
* Helper class to find Namespace informations.
* @author Mirko Stocker
*
*/
public class NamespaceHelper {
/**
* Returns the qualified name of all namespaces that are defined at the specified file and offset.
*
* @param insertFile
* @param offset
* @return ICPPASTQualifiedName with the names of all namespaces
*/
public static ICPPASTQualifiedName getSurroundingNamespace(final IFile insertFile, final int offset) {
final CPPASTQualifiedName qualifiedName = new CPPASTQualifiedName();
TranslationUnitHelper.loadTranslationUnit(insertFile).accept(new CPPASTAllVisitor() {
@Override
public int visit(IASTDeclSpecifier declSpec) {
if (declSpec instanceof ICPPASTCompositeTypeSpecifier && checkFileNameAndLocation(insertFile, offset, declSpec)) {
qualifiedName.addName(createNameWithTemplates(declSpec));
}
return super.visit(declSpec);
}
@Override
public int visit(ICPPASTNamespaceDefinition namespace) {
if (checkFileNameAndLocation(insertFile, offset, namespace)) {
qualifiedName.addName((namespace).getName());
}
return super.visit(namespace);
}
});
return qualifiedName;
}
private static boolean checkFileNameAndLocation(final IFile insertFile, final int offset, IASTNode namespace) {
return namespace.getFileLocation().getFileName().endsWith(insertFile.getFullPath().toOSString())
&& offset >= namespace.getNodeLocations()[0].getNodeOffset()
&& offset <= namespace.getNodeLocations()[0].getNodeOffset() + namespace.getNodeLocations()[0].getNodeLength();
}
private static IASTName createNameWithTemplates(IASTNode declarationParent) {
IASTName parentName;
parentName = ((ICPPASTCompositeTypeSpecifier) declarationParent).getName();
if(classHasTemplates(declarationParent)) {
CPPASTTemplateId templateId = new CPPASTTemplateId();
templateId.setTemplateName(parentName);
for(ICPPASTTemplateParameter templateParameter : ((ICPPASTTemplateDeclaration) declarationParent.getParent().getParent() ).getTemplateParameters()) {
if (templateParameter instanceof CPPASTSimpleTypeTemplateParameter) {
CPPASTSimpleTypeTemplateParameter simpleTypeTemplateParameter = (CPPASTSimpleTypeTemplateParameter) templateParameter;
CPPASTTypeId id = new CPPASTTypeId();
CPPASTNamedTypeSpecifier namedTypeSpecifier = new CPPASTNamedTypeSpecifier();
namedTypeSpecifier.setName(simpleTypeTemplateParameter.getName());
id.setDeclSpecifier(namedTypeSpecifier);
templateId.addTemplateArgument(id);
}
}
parentName = templateId;
}
return parentName;
}
private static boolean classHasTemplates(IASTNode declarationParent) {
return declarationParent.getParent() != null
&& declarationParent.getParent().getParent() instanceof ICPPASTTemplateDeclaration;
}
}

View file

@ -0,0 +1,63 @@
/*******************************************************************************
* 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 - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.utils;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNamespaceDefinition;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTranslationUnit;
/**
* General class for common Node operations.
*
* @author Lukas Felber
*
*/
public class NodeHelper {
public static IASTDeclaration[] getDeclarations(IASTNode parent) {
if (parent instanceof ICPPASTCompositeTypeSpecifier) {
return ((ICPPASTCompositeTypeSpecifier) parent).getMembers();
} else if (parent instanceof CPPASTTranslationUnit) {
return ((CPPASTTranslationUnit) parent).getDeclarations();
} else if (parent instanceof CPPASTNamespaceDefinition) {
return ((CPPASTNamespaceDefinition) parent).getDeclarations();
}
return new IASTDeclaration[0];
}
public static IASTNode findFollowingNode(IASTNode currentNode) {
if(currentNode == null || currentNode.getParent() == null) {
return null;
}
boolean match = false;
for(IASTNode actNode : getDeclarations(currentNode.getParent())) {
if(match) {
return actNode;
}
if(actNode.equals(currentNode)) {
match = true;
}
}
return null;
}
public static IASTNode getTopLevelParent(IASTNode currentNode) {
while(currentNode != null && currentNode.getParent() != null && currentNode.getParent().getParent() != null) {
return getTopLevelParent(currentNode.getParent());
}
return currentNode;
}
}

View file

@ -0,0 +1,48 @@
/*******************************************************************************
* 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 - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.utils;
import java.util.HashSet;
import java.util.Set;
/**
* Helps to generate new unsused names.
*
* @author Mirko Stocker
*
*/
public class PseudoNameGenerator {
private final Set<String> names = new HashSet<String>();
public void addExistingName(String name) {
names.add(name);
}
public String generateNewName(String typeName) {
String[] nameParts = typeName.split("::"); //$NON-NLS-1$
typeName = nameParts[nameParts.length - 1];
String newNameCandidate = null;
int index = 0;
do {
index++;
newNameCandidate = String.format("%s%d", typeName, Integer.valueOf(index)); //$NON-NLS-1$
} while(names.contains(newNameCandidate));
names.add(newNameCandidate);
return newNameCandidate;
}
}

View file

@ -0,0 +1,51 @@
/*******************************************************************************
* 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 - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.utils;
import org.eclipse.jface.text.Region;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
import org.eclipse.cdt.internal.ui.refactoring.CRefactoring;
import org.eclipse.cdt.internal.ui.refactoring.Container;
/**
* Helper class to suport operations conserning a selection.
*
* @author Mirko Stocker
*
*/
public class SelectionHelper {
public static IASTSimpleDeclaration findFirstSelectedDeclaration(final Region textSelection, IASTTranslationUnit translationUnit) {
final Container<IASTSimpleDeclaration> container = new Container<IASTSimpleDeclaration>();
translationUnit.accept(new CPPASTVisitor() {
{
shouldVisitDeclarations = true;
}
@Override
public int visit(IASTDeclaration declaration) {
if (declaration instanceof IASTSimpleDeclaration && CRefactoring.isSelectionOnExpression(textSelection, declaration)) {
container.setObject((IASTSimpleDeclaration) declaration);
}
return super.visit(declaration);
}
});
return container.getObject();
}
}

View file

@ -254,6 +254,12 @@ public class CdtActionConstants {
*/
public static final String HIDE_METHOD= "org.eclipse.cdt.ui.actions.HideMethod"; //$NON-NLS-1$
/**
* Refactor menu: name of standard Extract Constant global action
* (value <code>"org.eclipse.cdt.ui.actions.ImplementMethod"</code>).
*/
public static final String IMPLEMENT_METHOD= "org.eclipse.cdt.ui.actions.ImplementMethod"; //$NON-NLS-1$
/**
* Refactor menu: name of standard Introduce Parameter global action
* (value <code>"org.eclipse.cdt.ui.actions.IntroduceParameter"</code>).

View file

@ -115,6 +115,7 @@ public class CRefactoringActionGroup extends ActionGroup implements ISelectionCh
private RefactoringAction fExtractConstantAction;
private RefactoringAction fExtractFunctionAction;
private RefactoringAction fHideMethodAction;
private RefactoringAction fImplementMethodAction;
private IWorkbenchSite fSite;
private List<RefactoringAction> fAllActions= new ArrayList<RefactoringAction>();
@ -159,6 +160,10 @@ public class CRefactoringActionGroup extends ActionGroup implements ISelectionCh
fHideMethodAction = new HideMethodAction();
fHideMethodAction.setActionDefinitionId(ICEditorActionDefinitionIds.HIDE_METHOD);
fAllActions.add(fHideMethodAction);
fImplementMethodAction = new ImplementMethodAction();
fImplementMethodAction.setActionDefinitionId(ICEditorActionDefinitionIds.IMPLEMENT_METHOD);
fAllActions.add(fImplementMethodAction);
}
public void setWorkbenchSite(IWorkbenchSite site) {
@ -196,6 +201,7 @@ public class CRefactoringActionGroup extends ActionGroup implements ISelectionCh
setActionHandler(actionBar, CdtActionConstants.EXTRACT_CONSTANT, fExtractConstantAction);
setActionHandler(actionBar, CdtActionConstants.EXTRACT_METHOD, fExtractFunctionAction);
setActionHandler(actionBar, CdtActionConstants.HIDE_METHOD, fHideMethodAction);
setActionHandler(actionBar, CdtActionConstants.IMPLEMENT_METHOD, fImplementMethodAction);
}
private void setActionHandler(IActionBars actionBar, String id, RefactoringAction action) {
@ -226,6 +232,7 @@ public class CRefactoringActionGroup extends ActionGroup implements ISelectionCh
addAction(refactorSubmenu, fExtractConstantAction);
addAction(refactorSubmenu, fExtractFunctionAction);
addAction(refactorSubmenu, fHideMethodAction);
addAction(refactorSubmenu, fImplementMethodAction);
refactorSubmenu.add(new Separator(GROUP_REORG2));
refactorSubmenu.add(new Separator(GROUP_TYPE));

View file

@ -0,0 +1,61 @@
/*******************************************************************************
* 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 - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.ui.refactoring.actions;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.window.IShellProvider;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.IMethod;
import org.eclipse.cdt.core.model.IMethodDeclaration;
import org.eclipse.cdt.core.model.ISourceReference;
import org.eclipse.cdt.core.model.IWorkingCopy;
import org.eclipse.cdt.internal.ui.refactoring.implementmethod.ImplementMethodRefactoringRunner;
/**
* Launches the implement method source generator (refactoring).
*
* @author Lukas Felber
*/
public class ImplementMethodAction extends RefactoringAction {
public ImplementMethodAction() {
super(Messages.ImplementMethodAction_label);
}
@Override
public void run(IShellProvider shellProvider, ICElement elem) {
new ImplementMethodRefactoringRunner(null, null, elem, shellProvider).run();
}
@Override
public void run(IShellProvider shellProvider, IWorkingCopy wc, ITextSelection selection) {
IResource res = wc.getResource();
if (res instanceof IFile) {
new ImplementMethodRefactoringRunner((IFile) res, selection, null, shellProvider).run();
}
}
@Override
public void updateSelection(ICElement elem) {
super.updateSelection(elem);
if (elem instanceof IMethod || elem instanceof IMethodDeclaration == false
|| elem instanceof ISourceReference == false
|| ((ISourceReference) elem).getTranslationUnit().getResource() instanceof IFile == false) {
setEnabled(false);
}
}
}

View file

@ -19,6 +19,7 @@ public class Messages extends NLS {
public static String ExtractConstantAction_label;
public static String ExtractFunctionAction_label;
public static String HideMethodAction_label;
public static String ImplementMethodAction_label;
static {
// initialize resource bundle

View file

@ -11,5 +11,6 @@
CRefactoringActionGroup_menu=Refactor
CRenameAction_label=Rename...
ExtractConstantAction_label=Extract Constant...
ImplementMethodAction_label=Implement Method... (work in progress)
HideMethodAction_label=Hide Member Function... (work in progress)
ExtractFunctionAction_label=Extract Function... (work in progress)