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:
parent
d353a33638
commit
6df6c40158
32 changed files with 2180 additions and 3 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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$
|
||||
}
|
||||
}
|
|
@ -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$
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>).
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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>).
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue