mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-31 04:45:38 +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);
|
synthTreatment(translationUnit);
|
||||||
}
|
}
|
||||||
sourceOffsets.put(translationUnit.getFileLocation().getFileName(),
|
final IASTFileLocation fileLocation = translationUnit.getFileLocation();
|
||||||
Integer.valueOf(translationUnit.getFileLocation().getNodeOffset()));
|
if (fileLocation != null) {
|
||||||
|
sourceOffsets.put(fileLocation.getFileName(),
|
||||||
|
Integer.valueOf(fileLocation.getNodeOffset()));
|
||||||
|
}
|
||||||
return super.visit(translationUnit);
|
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("ExtractConstantRefactoringTests", "resources/refactoring/ExtractConstant.rts"));
|
||||||
suite.addTest(RefactoringTester.suite("HideMethodRefactoringTests", "resources/refactoring/HideMethod.rts"));
|
suite.addTest(RefactoringTester.suite("HideMethodRefactoringTests", "resources/refactoring/HideMethod.rts"));
|
||||||
suite.addTest(UtilTestSuite.suite());
|
suite.addTest(UtilTestSuite.suite());
|
||||||
|
suite.addTest(RefactoringTester.suite("ImplementMethodRefactoringTests", "resources/refactoring/ImplementMethod.rts"));
|
||||||
return suite;
|
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();
|
UtilTestSuite suite = new UtilTestSuite();
|
||||||
suite.addTest(IdentifierHelperTest.suite());
|
suite.addTest(IdentifierHelperTest.suite());
|
||||||
suite.addTest(RefactoringTester.suite("TranslationUnitHelperTest", "resources/refactoring/TranslationunitHelper.rts")); //$NON-NLS-1$ //$NON-NLS-2$
|
suite.addTest(RefactoringTester.suite("TranslationUnitHelperTest", "resources/refactoring/TranslationunitHelper.rts")); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
suite.addTestSuite(PseudoNameGeneratorTest.class);
|
||||||
return suite;
|
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.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.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.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.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.refactoring.utils;x-friends:="org.eclipse.cdt.ui.tests",
|
||||||
org.eclipse.cdt.internal.ui.search;x-internal:=true,
|
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.extractConstant.description= Extract a constant for the selected expression
|
||||||
ActionDefinition.extractFunction.name= Extract Function - Refactoring
|
ActionDefinition.extractFunction.name= Extract Function - Refactoring
|
||||||
ActionDefinition.extractFunction.description= Extract a function for the selected list of expressions or statements
|
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
|
# Action Set
|
||||||
CodingActionSet.label= C/C++ Coding
|
CodingActionSet.label= C/C++ Coding
|
||||||
|
@ -156,6 +158,7 @@ Refactoring.renameAction.label=Re&name...
|
||||||
Refactoring.extractConstant.label=Extr&act Constant...
|
Refactoring.extractConstant.label=Extr&act Constant...
|
||||||
Refactoring.extractFunction.label=Extract &Function... (work in progress)
|
Refactoring.extractFunction.label=Extract &Function... (work in progress)
|
||||||
Refactoring.hideMethod.label=Hide Member 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
|
CEditor.name=C/C++ Editor
|
||||||
|
|
||||||
|
|
|
@ -1171,6 +1171,13 @@
|
||||||
id="org.eclipse.cdt.ui.actions.ExtractConstant"
|
id="org.eclipse.cdt.ui.actions.ExtractConstant"
|
||||||
retarget="true">
|
retarget="true">
|
||||||
</action>
|
</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>
|
||||||
<actionSet
|
<actionSet
|
||||||
label="%CSearchActionSet.label"
|
label="%CSearchActionSet.label"
|
||||||
|
@ -1996,6 +2003,12 @@
|
||||||
categoryId="org.eclipse.cdt.ui.category.refactoring"
|
categoryId="org.eclipse.cdt.ui.category.refactoring"
|
||||||
id="org.eclipse.cdt.ui.refactor.extract.function">
|
id="org.eclipse.cdt.ui.refactor.extract.function">
|
||||||
</command>
|
</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>
|
||||||
<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$
|
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
|
* Action definition ID of the refactor -> undo action
|
||||||
* (value <code>"org.eclipse.cdt.ui.edit.text.undo.action"</code>).
|
* (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_EnterName;
|
||||||
public static String ExtractInputPage_CheckName;
|
public static String ExtractInputPage_CheckName;
|
||||||
public static String VisibilitySelectionPanel_AccessModifier;
|
public static String VisibilitySelectionPanel_AccessModifier;
|
||||||
|
public static String ValidatingLabeledTextField_CantBeEmpty;
|
||||||
|
public static String ValidatingLabeledTextField_InvalidCharacters;
|
||||||
|
public static String ValidatingLabeledTextField_DuplicatedNames;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
|
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_EnterName=Enter a name
|
||||||
ExtractInputPage_CheckName=Check Name: {0}
|
ExtractInputPage_CheckName=Check Name: {0}
|
||||||
VisibilitySelectionPanel_AccessModifier=&Access modifier:
|
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$
|
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
|
* Refactor menu: name of standard Introduce Parameter global action
|
||||||
* (value <code>"org.eclipse.cdt.ui.actions.IntroduceParameter"</code>).
|
* (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 fExtractConstantAction;
|
||||||
private RefactoringAction fExtractFunctionAction;
|
private RefactoringAction fExtractFunctionAction;
|
||||||
private RefactoringAction fHideMethodAction;
|
private RefactoringAction fHideMethodAction;
|
||||||
|
private RefactoringAction fImplementMethodAction;
|
||||||
private IWorkbenchSite fSite;
|
private IWorkbenchSite fSite;
|
||||||
private List<RefactoringAction> fAllActions= new ArrayList<RefactoringAction>();
|
private List<RefactoringAction> fAllActions= new ArrayList<RefactoringAction>();
|
||||||
|
|
||||||
|
@ -159,6 +160,10 @@ public class CRefactoringActionGroup extends ActionGroup implements ISelectionCh
|
||||||
fHideMethodAction = new HideMethodAction();
|
fHideMethodAction = new HideMethodAction();
|
||||||
fHideMethodAction.setActionDefinitionId(ICEditorActionDefinitionIds.HIDE_METHOD);
|
fHideMethodAction.setActionDefinitionId(ICEditorActionDefinitionIds.HIDE_METHOD);
|
||||||
fAllActions.add(fHideMethodAction);
|
fAllActions.add(fHideMethodAction);
|
||||||
|
|
||||||
|
fImplementMethodAction = new ImplementMethodAction();
|
||||||
|
fImplementMethodAction.setActionDefinitionId(ICEditorActionDefinitionIds.IMPLEMENT_METHOD);
|
||||||
|
fAllActions.add(fImplementMethodAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setWorkbenchSite(IWorkbenchSite site) {
|
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_CONSTANT, fExtractConstantAction);
|
||||||
setActionHandler(actionBar, CdtActionConstants.EXTRACT_METHOD, fExtractFunctionAction);
|
setActionHandler(actionBar, CdtActionConstants.EXTRACT_METHOD, fExtractFunctionAction);
|
||||||
setActionHandler(actionBar, CdtActionConstants.HIDE_METHOD, fHideMethodAction);
|
setActionHandler(actionBar, CdtActionConstants.HIDE_METHOD, fHideMethodAction);
|
||||||
|
setActionHandler(actionBar, CdtActionConstants.IMPLEMENT_METHOD, fImplementMethodAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setActionHandler(IActionBars actionBar, String id, RefactoringAction action) {
|
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, fExtractConstantAction);
|
||||||
addAction(refactorSubmenu, fExtractFunctionAction);
|
addAction(refactorSubmenu, fExtractFunctionAction);
|
||||||
addAction(refactorSubmenu, fHideMethodAction);
|
addAction(refactorSubmenu, fHideMethodAction);
|
||||||
|
addAction(refactorSubmenu, fImplementMethodAction);
|
||||||
|
|
||||||
refactorSubmenu.add(new Separator(GROUP_REORG2));
|
refactorSubmenu.add(new Separator(GROUP_REORG2));
|
||||||
refactorSubmenu.add(new Separator(GROUP_TYPE));
|
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 ExtractConstantAction_label;
|
||||||
public static String ExtractFunctionAction_label;
|
public static String ExtractFunctionAction_label;
|
||||||
public static String HideMethodAction_label;
|
public static String HideMethodAction_label;
|
||||||
|
public static String ImplementMethodAction_label;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
// initialize resource bundle
|
// initialize resource bundle
|
||||||
|
|
|
@ -11,5 +11,6 @@
|
||||||
CRefactoringActionGroup_menu=Refactor
|
CRefactoringActionGroup_menu=Refactor
|
||||||
CRenameAction_label=Rename...
|
CRenameAction_label=Rename...
|
||||||
ExtractConstantAction_label=Extract Constant...
|
ExtractConstantAction_label=Extract Constant...
|
||||||
|
ImplementMethodAction_label=Implement Method... (work in progress)
|
||||||
HideMethodAction_label=Hide Member Function... (work in progress)
|
HideMethodAction_label=Hide Member Function... (work in progress)
|
||||||
ExtractFunctionAction_label=Extract Function... (work in progress)
|
ExtractFunctionAction_label=Extract Function... (work in progress)
|
||||||
|
|
Loading…
Add table
Reference in a new issue