mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-23 17:05:26 +02:00
Extract Function (work in progress) by Emanuel Graf, bug 226484.
This commit is contained in:
parent
a4274e1467
commit
ca61147d16
55 changed files with 8244 additions and 46 deletions
|
@ -48,7 +48,7 @@ Export-Package: org.eclipse.cdt.core,
|
|||
org.eclipse.cdt.internal.core.dom.parser.cpp;x-friends:="org.eclipse.cdt.ui",
|
||||
org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;x-friends:="org.eclipse.cdt.ui",
|
||||
org.eclipse.cdt.internal.core.dom.rewrite;x-friends:="org.eclipse.cdt.core.tests,org.eclipse.cdt.ui",
|
||||
org.eclipse.cdt.internal.core.dom.rewrite.astwriter;x-internal:=true,
|
||||
org.eclipse.cdt.internal.core.dom.rewrite.astwriter;x-friends:="org.eclipse.cdt.ui",
|
||||
org.eclipse.cdt.internal.core.dom.rewrite.changegenerator;x-internal:=true,
|
||||
org.eclipse.cdt.internal.core.dom.rewrite.commenthandler;x-internal:=true,
|
||||
org.eclipse.cdt.internal.core.envvar;x-friends:="org.eclipse.cdt.ui",
|
||||
|
|
|
@ -62,7 +62,7 @@ public class MacroExpansionHandler {
|
|||
|
||||
protected boolean checkisMacroExpansionNode(IASTNode node, boolean write) {
|
||||
IASTNodeLocation[] locs = node.getNodeLocations();
|
||||
if(locs.length ==1) {
|
||||
if (locs != null && locs.length ==1) {
|
||||
if (locs[0] instanceof IASTMacroExpansionLocation) {
|
||||
IASTMacroExpansionLocation macroNode = (IASTMacroExpansionLocation) locs[0];
|
||||
|
||||
|
|
|
@ -34,22 +34,23 @@ public class ASTModificationHelper {
|
|||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends IASTNode> T[] createModifiedChildArray(IASTNode parent, T[] unmodifiedChildren){
|
||||
public <T extends IASTNode> T[] createModifiedChildArray(IASTNode parent, T[] unmodifiedChildren, Class<T> clazz){
|
||||
ArrayList<T> modifiedChildren = new ArrayList<T>(Arrays.asList(unmodifiedChildren));
|
||||
for(T currentChild : unmodifiedChildren){
|
||||
for(ASTModification childModification : modificationsForNode(currentChild)){
|
||||
try{
|
||||
T newNode = (T) childModification.getNewNode();
|
||||
final T newNode = cast(childModification.getNewNode(), clazz);
|
||||
switch(childModification.getKind()){
|
||||
case REPLACE:
|
||||
if(childModification.getNewNode() != null){
|
||||
if (newNode != null) {
|
||||
modifiedChildren.add(modifiedChildren.indexOf(childModification.getTargetNode()), newNode);
|
||||
}
|
||||
modifiedChildren.remove(childModification.getTargetNode());
|
||||
break;
|
||||
case INSERT_BEFORE:
|
||||
modifiedChildren.add(modifiedChildren.indexOf(childModification.getTargetNode()), newNode);
|
||||
if (newNode != null) {
|
||||
modifiedChildren.add(modifiedChildren.indexOf(childModification.getTargetNode()), newNode);
|
||||
}
|
||||
break;
|
||||
case APPEND_CHILD:
|
||||
throw new UnhandledASTModificationException(childModification);
|
||||
|
@ -61,27 +62,43 @@ public class ASTModificationHelper {
|
|||
}
|
||||
}
|
||||
|
||||
Class<?> componentType = unmodifiedChildren.getClass().getComponentType();
|
||||
for(ASTModification parentModification : modificationsForNode(parent)){
|
||||
if(parentModification.getKind() == ModificationKind.APPEND_CHILD){
|
||||
IASTNode newNode = parentModification.getNewNode();
|
||||
if(componentType.isAssignableFrom(newNode.getClass())){
|
||||
modifiedChildren.add((T) newNode);
|
||||
T newTNode= cast(newNode, clazz);
|
||||
if (newTNode != null) {
|
||||
modifiedChildren.add(newTNode);
|
||||
}
|
||||
else if(newNode instanceof ContainerNode){
|
||||
else if (newNode instanceof ContainerNode){
|
||||
ContainerNode nodeContainer = (ContainerNode) newNode;
|
||||
for(IASTNode currentNode : nodeContainer.getNodes()){
|
||||
if(componentType.isAssignableFrom(currentNode.getClass())){
|
||||
modifiedChildren.add((T)currentNode);
|
||||
T tnode= cast(currentNode, clazz);
|
||||
if(tnode != null){
|
||||
modifiedChildren.add(tnode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return modifiedChildren.toArray((T[]) Array.newInstance(componentType, 0));
|
||||
return modifiedChildren.toArray(newArrayInstance(clazz, modifiedChildren.size()));
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T[] newArrayInstance(Class<T> clazz, int size) {
|
||||
return (T[]) Array.newInstance(clazz, size);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T cast(IASTNode node, Class<T> clazz) {
|
||||
if (clazz.isInstance(node)){
|
||||
return (T) node;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public List<ASTModification> modificationsForNode(
|
||||
IASTNode targetNode) {
|
||||
ASTModificationMap rootModifications = modificationStore.getRootModifications();
|
||||
|
|
|
@ -306,8 +306,7 @@ public class ChangeGeneratorWriterVisitor extends ASTWriterVisitor {
|
|||
ASTModificationHelper helper = new ASTModificationHelper(
|
||||
modificationStore);
|
||||
|
||||
IASTDeclaration[] declarations = helper.createModifiedChildArray(tu, tu
|
||||
.getDeclarations());
|
||||
IASTDeclaration[] declarations = helper.createModifiedChildArray(tu, tu.getDeclarations(), IASTDeclaration.class);
|
||||
for (IASTDeclaration currentDeclaration : declarations) {
|
||||
currentDeclaration.accept(this);
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ public class ModifiedASTDeclSpecWriter extends DeclSpecWriter {
|
|||
@Override
|
||||
protected IASTDeclaration[] getMembers(
|
||||
IASTCompositeTypeSpecifier compDeclSpec) {
|
||||
return modificationHelper.createModifiedChildArray(compDeclSpec, compDeclSpec.getMembers());
|
||||
return modificationHelper.createModifiedChildArray(compDeclSpec, compDeclSpec.getMembers(), IASTDeclaration.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -44,14 +44,14 @@ public class ModifiedASTDeclaratorWriter extends DeclaratorWriter {
|
|||
protected void writeParameterDeclarations(
|
||||
IASTStandardFunctionDeclarator funcDec,
|
||||
IASTParameterDeclaration[] paraDecls) {
|
||||
IASTParameterDeclaration[] modifiedParameters = modificationHelper.createModifiedChildArray(funcDec, paraDecls);
|
||||
IASTParameterDeclaration[] modifiedParameters = modificationHelper.createModifiedChildArray(funcDec, paraDecls, IASTParameterDeclaration.class);
|
||||
super.writeParameterDeclarations(funcDec, modifiedParameters);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writePointerOperators(IASTDeclarator declarator,IASTPointerOperator[] unmodifiedPointerOperations) {
|
||||
IASTPointerOperator[] modifiedPointer = modificationHelper.createModifiedChildArray(declarator, unmodifiedPointerOperations);
|
||||
IASTPointerOperator[] modifiedPointer = modificationHelper.createModifiedChildArray(declarator, unmodifiedPointerOperations, IASTPointerOperator.class);
|
||||
super.writePointerOperators(declarator, modifiedPointer);
|
||||
}
|
||||
|
||||
|
@ -60,20 +60,20 @@ public class ModifiedASTDeclaratorWriter extends DeclaratorWriter {
|
|||
@Override
|
||||
protected void writeCtorChainInitializer(ICPPASTFunctionDeclarator funcDec,
|
||||
ICPPASTConstructorChainInitializer[] ctorInitChain) {
|
||||
ICPPASTConstructorChainInitializer[] modifiedChainInitializer = modificationHelper.createModifiedChildArray(funcDec, ctorInitChain);
|
||||
ICPPASTConstructorChainInitializer[] modifiedChainInitializer = modificationHelper.createModifiedChildArray(funcDec, ctorInitChain, ICPPASTConstructorChainInitializer.class);
|
||||
super.writeCtorChainInitializer(funcDec, modifiedChainInitializer);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeArrayModifiers(IASTArrayDeclarator arrDecl,
|
||||
IASTArrayModifier[] arrMods) {
|
||||
IASTArrayModifier[] modifiedModifiers = modificationHelper.createModifiedChildArray(arrDecl, arrMods);
|
||||
IASTArrayModifier[] modifiedModifiers = modificationHelper.createModifiedChildArray(arrDecl, arrMods, IASTArrayModifier.class);
|
||||
super.writeArrayModifiers(arrDecl, modifiedModifiers);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeExceptionSpecification(ICPPASTFunctionDeclarator funcDec, IASTTypeId[] exceptions ) {
|
||||
IASTTypeId[] modifiedExceptions = modificationHelper.createModifiedChildArray(funcDec, exceptions);
|
||||
IASTTypeId[] modifiedExceptions = modificationHelper.createModifiedChildArray(funcDec, exceptions, IASTTypeId.class);
|
||||
super.writeExceptionSpecification(funcDec, modifiedExceptions);
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ public class ModifiedASTDeclaratorWriter extends DeclaratorWriter {
|
|||
protected void writeKnRParameterDeclarations(
|
||||
ICASTKnRFunctionDeclarator knrFunct,
|
||||
IASTDeclaration[] knrDeclarations) {
|
||||
IASTDeclaration[] modifiedDeclarations = modificationHelper.createModifiedChildArray(knrFunct, knrDeclarations);
|
||||
IASTDeclaration[] modifiedDeclarations = modificationHelper.createModifiedChildArray(knrFunct, knrDeclarations, IASTDeclaration.class);
|
||||
|
||||
super.writeKnRParameterDeclarations(knrFunct, modifiedDeclarations);
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ public class ModifiedASTDeclaratorWriter extends DeclaratorWriter {
|
|||
@Override
|
||||
protected void writeKnRParameterNames(
|
||||
ICASTKnRFunctionDeclarator knrFunct, IASTName[] parameterNames) {
|
||||
IASTName[] modifiedNames = modificationHelper.createModifiedChildArray(knrFunct, parameterNames);
|
||||
IASTName[] modifiedNames = modificationHelper.createModifiedChildArray(knrFunct, parameterNames, IASTName.class);
|
||||
super.writeKnRParameterNames(knrFunct, modifiedNames);
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ public class ModifiedASTExpressionWriter extends ExpressionWriter {
|
|||
@Override
|
||||
protected void writeExpressions(IASTExpressionList expList,
|
||||
IASTExpression[] expressions) {
|
||||
IASTExpression[] modifiedExpressions = modificationHelper.createModifiedChildArray(expList, expressions);
|
||||
IASTExpression[] modifiedExpressions = modificationHelper.createModifiedChildArray(expList, expressions, IASTExpression.class);
|
||||
super.writeExpressions(expList, modifiedExpressions);
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ public class ModifiedASTExpressionWriter extends ExpressionWriter {
|
|||
@Override
|
||||
protected IASTExpression[] getNewTypeIdArrayExpressions(
|
||||
ICPPASTNewExpression newExp, IASTExpression[] expressions) {
|
||||
IASTExpression[] modifiedExpressions = modificationHelper.createModifiedChildArray(newExp, expressions);
|
||||
IASTExpression[] modifiedExpressions = modificationHelper.createModifiedChildArray(newExp, expressions, IASTExpression.class);
|
||||
return modifiedExpressions;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ public class ModifiedASTStatementWriter extends StatementWriter {
|
|||
|
||||
@Override
|
||||
protected IASTStatement[] getNestedStatements(IASTCompoundStatement compoundStatement) {
|
||||
return modificationHelper.createModifiedChildArray(compoundStatement, compoundStatement.getStatements());
|
||||
return modificationHelper.createModifiedChildArray(compoundStatement, compoundStatement.getStatements(), IASTStatement.class);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ Export-Package: org.eclipse.cdt.ui.testplugin,
|
|||
org.eclipse.cdt.ui.tests,
|
||||
org.eclipse.cdt.ui.tests.DOMAST,
|
||||
org.eclipse.cdt.ui.tests.chelp,
|
||||
org.eclipse.cdt.ui.tests.refactoring,
|
||||
org.eclipse.cdt.ui.tests.refactoring.rename,
|
||||
org.eclipse.cdt.ui.tests.text,
|
||||
org.eclipse.cdt.ui.tests.text.contentassist,
|
||||
|
|
|
@ -46,7 +46,7 @@ A::~A()
|
|||
|
||||
int A::foo()
|
||||
{
|
||||
return //$42$//;
|
||||
return //$42$//; //Hallo
|
||||
}
|
||||
|
||||
void A::bar()
|
||||
|
@ -68,7 +68,7 @@ A::~A()
|
|||
|
||||
int A::foo()
|
||||
{
|
||||
return theAnswer;
|
||||
return theAnswer; //Hallo
|
||||
}
|
||||
|
||||
void A::bar()
|
||||
|
|
|
@ -0,0 +1,429 @@
|
|||
//!Extract boolean comparison from if-condition.
|
||||
//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
|
||||
|
||||
//@.config
|
||||
filename=test.cpp
|
||||
methodname=check
|
||||
|
||||
//@test.h
|
||||
class Test
|
||||
{
|
||||
void test();
|
||||
};
|
||||
|
||||
|
||||
//=
|
||||
class Test
|
||||
{
|
||||
void test();
|
||||
bool check();
|
||||
};
|
||||
|
||||
|
||||
//@test.cpp
|
||||
#include "test.h"
|
||||
|
||||
void Test::test()
|
||||
{
|
||||
if(//$5 == 3 + 2$//) {
|
||||
//...
|
||||
}
|
||||
}
|
||||
|
||||
//=
|
||||
#include "test.h"
|
||||
|
||||
bool Test::check()
|
||||
{
|
||||
return 5 == 3 + 2;
|
||||
}
|
||||
|
||||
void Test::test()
|
||||
{
|
||||
if(check()) {
|
||||
//...
|
||||
}
|
||||
}
|
||||
|
||||
//!Extract boolean comparison from if-condition with parameter.
|
||||
//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
|
||||
|
||||
//@.config
|
||||
filename=test.cpp
|
||||
methodname=check
|
||||
|
||||
//@test.h
|
||||
class Test
|
||||
{
|
||||
void test();
|
||||
};
|
||||
|
||||
|
||||
//=
|
||||
class Test
|
||||
{
|
||||
void test();
|
||||
bool check(int num);
|
||||
};
|
||||
|
||||
|
||||
//@test.cpp
|
||||
#include "test.h"
|
||||
|
||||
void Test::test()
|
||||
{
|
||||
int num = 1;
|
||||
if(//$5 != 3 + num$//) {
|
||||
//...
|
||||
}
|
||||
}
|
||||
|
||||
//=
|
||||
#include "test.h"
|
||||
|
||||
bool Test::check(int num)
|
||||
{
|
||||
return 5 != 3 + num;
|
||||
}
|
||||
|
||||
void Test::test()
|
||||
{
|
||||
int num = 1;
|
||||
if(check(num)) {
|
||||
//...
|
||||
}
|
||||
}
|
||||
|
||||
//!Extract binary expression that results in a function with the same return type (BasicType) as the LHS.
|
||||
//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
|
||||
|
||||
//@.config
|
||||
filename=test.cpp
|
||||
methodname=add
|
||||
|
||||
//@test.h
|
||||
class Test
|
||||
{
|
||||
void test();
|
||||
};
|
||||
|
||||
|
||||
//=
|
||||
class Test
|
||||
{
|
||||
void test();
|
||||
int add(int five, int six);
|
||||
};
|
||||
|
||||
|
||||
//@test.cpp
|
||||
#include "test.h"
|
||||
|
||||
void Test::test()
|
||||
{
|
||||
int five = 5;
|
||||
int six = 6;
|
||||
int result = //$five + six$//;
|
||||
}
|
||||
|
||||
//=
|
||||
#include "test.h"
|
||||
|
||||
int Test::add(int five, int six)
|
||||
{
|
||||
return five + six;
|
||||
}
|
||||
|
||||
void Test::test()
|
||||
{
|
||||
int five = 5;
|
||||
int six = 6;
|
||||
int result = add(five, six);
|
||||
}
|
||||
|
||||
//!Extract binary expression that results in a function with the same return type (ClassType) as the LHS
|
||||
//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
|
||||
|
||||
//@.config
|
||||
filename=test.cpp
|
||||
methodname=cat
|
||||
|
||||
//@test.h
|
||||
struct helper {};
|
||||
|
||||
class Test
|
||||
{
|
||||
void test();
|
||||
};
|
||||
|
||||
|
||||
//=
|
||||
struct helper {};
|
||||
|
||||
class Test
|
||||
{
|
||||
void test();
|
||||
helper cat(helper s1, helper s2);
|
||||
};
|
||||
|
||||
|
||||
//@test.cpp
|
||||
#include "test.h"
|
||||
|
||||
void Test::test()
|
||||
{
|
||||
helper s1 = "a";
|
||||
helper s2 = "b";
|
||||
helper result = //$s1 + s2$//;
|
||||
}
|
||||
|
||||
//=
|
||||
#include "test.h"
|
||||
|
||||
helper Test::cat(helper s1, helper s2)
|
||||
{
|
||||
return s1 + s2;
|
||||
}
|
||||
|
||||
void Test::test()
|
||||
{
|
||||
helper s1 = "a";
|
||||
helper s2 = "b";
|
||||
helper result = cat(s1, s2);
|
||||
}
|
||||
|
||||
//!Extract binary expression that results in a function with the same return type (Typedef) as the LHS
|
||||
//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
|
||||
|
||||
//@.config
|
||||
filename=test.cpp
|
||||
methodname=cat
|
||||
|
||||
//@test.h
|
||||
struct helper {};
|
||||
typedef helper new_helper;
|
||||
|
||||
class Test
|
||||
{
|
||||
void test();
|
||||
};
|
||||
|
||||
|
||||
//=
|
||||
struct helper {};
|
||||
typedef helper new_helper;
|
||||
|
||||
class Test
|
||||
{
|
||||
void test();
|
||||
new_helper cat(new_helper s1, new_helper s2);
|
||||
};
|
||||
|
||||
|
||||
//@test.cpp
|
||||
#include "test.h"
|
||||
|
||||
void Test::test()
|
||||
{
|
||||
new_helper s1 = "a";
|
||||
new_helper s2 = "b";
|
||||
new_helper result = //$s1 + s2$//;
|
||||
}
|
||||
|
||||
//=
|
||||
#include "test.h"
|
||||
|
||||
new_helper Test::cat(new_helper s1, new_helper s2)
|
||||
{
|
||||
return s1 + s2;
|
||||
}
|
||||
|
||||
void Test::test()
|
||||
{
|
||||
new_helper s1 = "a";
|
||||
new_helper s2 = "b";
|
||||
new_helper result = cat(s1, s2);
|
||||
}
|
||||
|
||||
//!Extract new-Expression
|
||||
//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
|
||||
|
||||
//@.config
|
||||
filename=test.cpp
|
||||
methodname=new_helper
|
||||
|
||||
//@test.cpp
|
||||
|
||||
struct helper {};
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
helper* h = //$new helper$//;
|
||||
return 0;
|
||||
}
|
||||
//=
|
||||
|
||||
struct helper {};
|
||||
|
||||
helper *new_helper()
|
||||
{
|
||||
return new helper();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
helper* h = new_helper();
|
||||
return 0;
|
||||
}
|
||||
//!Extract function call
|
||||
//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
|
||||
|
||||
//@.config
|
||||
filename=test.cpp
|
||||
methodname=join_with_world
|
||||
|
||||
//@test.cpp
|
||||
class string {};
|
||||
|
||||
string join(string s1, char* s2)
|
||||
{
|
||||
return s1 + " " + s2;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
string hello = "Hello";
|
||||
cout << //$join(hello, "World")$// << endl;
|
||||
}
|
||||
//=
|
||||
class string {};
|
||||
|
||||
string join(string s1, char* s2)
|
||||
{
|
||||
return s1 + " " + s2;
|
||||
}
|
||||
|
||||
string join_with_world(string hello)
|
||||
{
|
||||
return join(hello, "World");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
string hello = "Hello";
|
||||
cout << join_with_world(hello) << endl;
|
||||
}
|
||||
//!Extract method call
|
||||
//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
|
||||
|
||||
//@.config
|
||||
filename=test.cpp
|
||||
methodname=value_from
|
||||
|
||||
//@test.cpp
|
||||
struct other
|
||||
{
|
||||
bool value() {}
|
||||
};
|
||||
|
||||
class Klass
|
||||
{
|
||||
void set(bool b){};
|
||||
void test()
|
||||
{
|
||||
other o;
|
||||
this->set(//$o.value()$//);
|
||||
}
|
||||
};
|
||||
|
||||
//=
|
||||
struct other
|
||||
{
|
||||
bool value() {}
|
||||
};
|
||||
|
||||
class Klass
|
||||
{
|
||||
void set(bool b){};
|
||||
bool value_from(other o)
|
||||
{
|
||||
return o.value();
|
||||
}
|
||||
|
||||
void test()
|
||||
{
|
||||
other o;
|
||||
this->set(value_from(o));
|
||||
}
|
||||
};
|
||||
|
||||
//!Extract function call [we only have the declaration] that returns a pointer
|
||||
//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
|
||||
|
||||
//@.config
|
||||
filename=test.cpp
|
||||
methodname=has
|
||||
|
||||
//@test.cpp
|
||||
class Cursor{};
|
||||
|
||||
Cursor* contains(const Cursor& pos);
|
||||
|
||||
int main() {
|
||||
Cursor c;
|
||||
contains(//$contains(c)$//);
|
||||
}
|
||||
|
||||
//=
|
||||
class Cursor{};
|
||||
|
||||
Cursor* contains(const Cursor& pos);
|
||||
|
||||
Cursor *has(Cursor c)
|
||||
{
|
||||
return contains(c);
|
||||
}
|
||||
|
||||
int main() {
|
||||
Cursor c;
|
||||
contains(has(c));
|
||||
}
|
||||
|
||||
//!Extract function call [we have the definition] that returns a pointer
|
||||
//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
|
||||
|
||||
//@.config
|
||||
filename=test.cpp
|
||||
methodname=has
|
||||
|
||||
//@test.cpp
|
||||
class Cursor{};
|
||||
|
||||
Cursor* contains(const Cursor& pos)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
int main() {
|
||||
Cursor c;
|
||||
contains(//$contains(c)$//);
|
||||
}
|
||||
|
||||
//=
|
||||
class Cursor{};
|
||||
|
||||
Cursor* contains(const Cursor& pos)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
Cursor *has(Cursor c)
|
||||
{
|
||||
return contains(c);
|
||||
}
|
||||
|
||||
int main() {
|
||||
Cursor c;
|
||||
contains(has(c));
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
//!Extract template function
|
||||
//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
|
||||
//@A.cpp
|
||||
void test(){
|
||||
}template <typename T>
|
||||
int tempFunct(){
|
||||
|
||||
T i;
|
||||
i = 0;
|
||||
//$i++;
|
||||
i+=3;$//
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//=
|
||||
void test(){
|
||||
}
|
||||
template <typename T>
|
||||
void exp(T i)
|
||||
{
|
||||
i++;
|
||||
i += 3;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int tempFunct(){
|
||||
|
||||
T i;
|
||||
i = 0;
|
||||
exp(i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//!Extract template function with template parameter Bug #12
|
||||
//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
|
||||
//@A.cpp
|
||||
void test(){
|
||||
}template <typename T>
|
||||
int tempFunct(T p){
|
||||
|
||||
//$++p;
|
||||
p + 4;$//
|
||||
return 0;
|
||||
}
|
||||
|
||||
//=
|
||||
void test(){
|
||||
}
|
||||
template <typename T>
|
||||
void exp(T p)
|
||||
{
|
||||
++p;
|
||||
p + 4;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int tempFunct(T p){
|
||||
|
||||
exp(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//!Extract template function with template type declaration Bug #11
|
||||
//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
|
||||
//@A.cpp
|
||||
void test(){
|
||||
}template <typename T>
|
||||
int tempFunct(){
|
||||
|
||||
//$T p;
|
||||
p = 0;
|
||||
p + 4;$//
|
||||
p + 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//=
|
||||
void test(){
|
||||
}
|
||||
template <typename T>
|
||||
T exp()
|
||||
{
|
||||
T p;
|
||||
p = 0;
|
||||
p + 4;
|
||||
return p;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int tempFunct(){
|
||||
|
||||
T p = exp();
|
||||
p + 2;
|
||||
return 0;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,295 @@
|
|||
//!ExtractFunctionRefactoringTest with FunctionStyleMacro2
|
||||
//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
|
||||
//@A.h
|
||||
#ifndef A_H_
|
||||
#define A_H_
|
||||
|
||||
class A
|
||||
{
|
||||
public:
|
||||
A();
|
||||
virtual ~A();
|
||||
int foo();
|
||||
|
||||
private:
|
||||
int help();
|
||||
};
|
||||
|
||||
#endif /*A_H_*/
|
||||
|
||||
//=
|
||||
#ifndef A_H_
|
||||
#define A_H_
|
||||
|
||||
class A
|
||||
{
|
||||
public:
|
||||
A();
|
||||
virtual ~A();
|
||||
int foo();
|
||||
|
||||
private:
|
||||
int help();
|
||||
void exp(int & ii);
|
||||
};
|
||||
|
||||
#endif /*A_H_*/
|
||||
|
||||
//@A.cpp
|
||||
#include "A.h"
|
||||
|
||||
#define ADD(a,ab) a + ab + 2 + a
|
||||
|
||||
A::A()
|
||||
{
|
||||
}
|
||||
|
||||
A::~A()
|
||||
{
|
||||
}
|
||||
int A::foo()
|
||||
{
|
||||
int ii = 2;
|
||||
//$++ii;
|
||||
ii = ADD(ii, 42);
|
||||
help();$//
|
||||
return ii;
|
||||
}
|
||||
|
||||
int A::help()
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
|
||||
//=
|
||||
#include "A.h"
|
||||
|
||||
#define ADD(a,ab) a + ab + 2 + a
|
||||
|
||||
A::A()
|
||||
{
|
||||
}
|
||||
|
||||
A::~A()
|
||||
{
|
||||
}
|
||||
void A::exp(int & ii)
|
||||
{
|
||||
++ii;
|
||||
ii = ADD(ii, 42);
|
||||
help();
|
||||
}
|
||||
|
||||
int A::foo()
|
||||
{
|
||||
int ii = 2;
|
||||
exp(ii);
|
||||
return ii;
|
||||
}
|
||||
|
||||
int A::help()
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
|
||||
//!Extract Method return value assinged to Macrocall Bug
|
||||
//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
|
||||
//@.config
|
||||
returnvalue=true
|
||||
returnparameterindex=1
|
||||
//@A.h
|
||||
#ifndef A_H_
|
||||
#define A_H_
|
||||
|
||||
class A
|
||||
{
|
||||
public:
|
||||
A();
|
||||
virtual ~A();
|
||||
int foo();
|
||||
private:
|
||||
int help();
|
||||
};
|
||||
|
||||
#endif /*A_H_*/
|
||||
|
||||
//=
|
||||
#ifndef A_H_
|
||||
#define A_H_
|
||||
|
||||
class A
|
||||
{
|
||||
public:
|
||||
A();
|
||||
virtual ~A();
|
||||
int foo();
|
||||
private:
|
||||
int help();
|
||||
int exp(int & i, int b);
|
||||
};
|
||||
|
||||
#endif /*A_H_*/
|
||||
|
||||
//@A.cpp
|
||||
#include "A.h"
|
||||
|
||||
#define ADD(b) b = b + 2
|
||||
|
||||
A::A()
|
||||
{
|
||||
}
|
||||
|
||||
A::~A()
|
||||
{
|
||||
}
|
||||
int A::foo()
|
||||
{
|
||||
int i = 2;
|
||||
int b = 42;
|
||||
//$++i;
|
||||
help();
|
||||
ADD(b);$//
|
||||
b += 2;
|
||||
return i;
|
||||
}
|
||||
|
||||
int A::help()
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
|
||||
//=
|
||||
#include "A.h"
|
||||
|
||||
#define ADD(b) b = b + 2
|
||||
|
||||
A::A()
|
||||
{
|
||||
}
|
||||
|
||||
A::~A()
|
||||
{
|
||||
}
|
||||
int A::exp(int & i, int b)
|
||||
{
|
||||
++i;
|
||||
help();
|
||||
ADD(b);
|
||||
return b;
|
||||
}
|
||||
|
||||
int A::foo()
|
||||
{
|
||||
int i = 2;
|
||||
int b = 42;
|
||||
b = exp(i, b);
|
||||
b += 2;
|
||||
return i;
|
||||
}
|
||||
|
||||
int A::help()
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
|
||||
//!Extract Method Methodlength with more than 1 Macrocall Bug
|
||||
//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
|
||||
//@.config
|
||||
returnvalue=true
|
||||
returnparameterindex=0
|
||||
replaceduplicates=true
|
||||
//@A.h
|
||||
#ifndef A_H_
|
||||
#define A_H_
|
||||
|
||||
class A
|
||||
{
|
||||
public:
|
||||
A();
|
||||
virtual ~A();
|
||||
int foo();
|
||||
private:
|
||||
int help();
|
||||
};
|
||||
|
||||
#endif /*A_H_*/
|
||||
|
||||
//=
|
||||
#ifndef A_H_
|
||||
#define A_H_
|
||||
|
||||
class A
|
||||
{
|
||||
public:
|
||||
A();
|
||||
virtual ~A();
|
||||
int foo();
|
||||
private:
|
||||
int help();
|
||||
int exp(int bb);
|
||||
};
|
||||
|
||||
#endif /*A_H_*/
|
||||
|
||||
//@A.cpp
|
||||
#include "A.h"
|
||||
|
||||
#define ADD(b) b = b + 2
|
||||
|
||||
A::A()
|
||||
{
|
||||
}
|
||||
|
||||
A::~A()
|
||||
{
|
||||
}
|
||||
int A::foo()
|
||||
{
|
||||
int i = 2;
|
||||
int bb = 42;
|
||||
++i;
|
||||
//$ADD(bb);
|
||||
ADD(bb);$//
|
||||
bb += 2;
|
||||
return i;
|
||||
}
|
||||
|
||||
int A::help()
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
|
||||
//=
|
||||
#include "A.h"
|
||||
|
||||
#define ADD(b) b = b + 2
|
||||
|
||||
A::A()
|
||||
{
|
||||
}
|
||||
|
||||
A::~A()
|
||||
{
|
||||
}
|
||||
int A::exp(int bb)
|
||||
{
|
||||
ADD(bb);
|
||||
ADD(bb);
|
||||
return bb;
|
||||
}
|
||||
|
||||
int A::foo()
|
||||
{
|
||||
int i = 2;
|
||||
int bb = 42;
|
||||
++i;
|
||||
bb = exp(bb);
|
||||
bb += 2;
|
||||
return i;
|
||||
}
|
||||
|
||||
int A::help()
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
|
|
@ -14,6 +14,7 @@ package org.eclipse.cdt.ui.tests.refactoring;
|
|||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionTestSuite;
|
||||
import org.eclipse.cdt.ui.tests.refactoring.rename.RenameRegressionTests;
|
||||
import org.eclipse.cdt.ui.tests.refactoring.utils.UtilTestSuite;
|
||||
|
||||
|
@ -26,6 +27,7 @@ public class RefactoringTestSuite extends TestSuite {
|
|||
public static Test suite() throws Exception {
|
||||
TestSuite suite = new RefactoringTestSuite();
|
||||
suite.addTest(RenameRegressionTests.suite());
|
||||
suite.addTest(ExtractFunctionTestSuite.suite());
|
||||
suite.addTest(RefactoringTester.suite("ExtractConstantRefactoringTests", "resources/refactoring/ExtractConstant.rts"));
|
||||
suite.addTest(UtilTestSuite.suite());
|
||||
return suite;
|
||||
|
|
|
@ -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.ui.tests.refactoring.extractfunction;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
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.NodeContainer.NameInformation;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.extractfunction.ExtractFunctionInformation;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.extractfunction.ExtractFunctionRefactoring;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.utils.VisibilityEnum;
|
||||
|
||||
/**
|
||||
* @author Emanuel Graf
|
||||
*
|
||||
*/
|
||||
public class ExtractFunctionRefactoringTest extends RefactoringTest {
|
||||
|
||||
protected String methodName;
|
||||
protected boolean replaceDuplicates;
|
||||
protected boolean returnValue;
|
||||
protected int returnParameterIndex;
|
||||
protected boolean fatalError;
|
||||
private VisibilityEnum visibility;
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @param files
|
||||
*/
|
||||
public ExtractFunctionRefactoringTest(String name, Vector<TestSourceFile> files) {
|
||||
super(name, files);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runTest() throws Throwable {
|
||||
IFile refFile = project.getFile(fileName);
|
||||
ExtractFunctionInformation info = new ExtractFunctionInformation();
|
||||
CRefactoring refactoring = new ExtractFunctionRefactoring( refFile, selection, info);
|
||||
RefactoringStatus checkInitialConditions = refactoring.checkInitialConditions(NULL_PROGRESS_MONITOR);
|
||||
|
||||
if(fatalError){
|
||||
assertConditionsFatalError(checkInitialConditions);
|
||||
return;
|
||||
}
|
||||
else{
|
||||
assertConditionsOk(checkInitialConditions);
|
||||
executeRefactoring(info, refactoring);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void executeRefactoring(ExtractFunctionInformation info, CRefactoring refactoring) throws CoreException, Exception {
|
||||
info.setMethodName(methodName);
|
||||
info.setReplaceDuplicates(replaceDuplicates);
|
||||
if(info.getInScopeDeclaredVariable() == null){
|
||||
if(returnValue) {
|
||||
info.setReturnVariable(info.getAllAfterUsedNames().elementAt(returnParameterIndex));
|
||||
}
|
||||
} else {
|
||||
info.setReturnVariable( info.getInScopeDeclaredVariable() );
|
||||
}
|
||||
info.setVisibility(visibility);
|
||||
|
||||
for (NameInformation name : info.getAllAfterUsedNames()) {
|
||||
if(!name.isUserSetIsReturnValue()){
|
||||
name.setUserSetIsReference(name.isReference());
|
||||
}
|
||||
}
|
||||
|
||||
Change createChange = refactoring.createChange(NULL_PROGRESS_MONITOR);
|
||||
RefactoringStatus finalConditions = refactoring.checkFinalConditions(NULL_PROGRESS_MONITOR);
|
||||
assertConditionsOk(finalConditions);
|
||||
createChange.perform(NULL_PROGRESS_MONITOR);
|
||||
|
||||
compareFiles(fileMap);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void configureRefactoring(Properties refactoringProperties) {
|
||||
methodName = refactoringProperties.getProperty("methodname", "exp"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
replaceDuplicates = Boolean.valueOf(refactoringProperties.getProperty("replaceduplicates", "false")).booleanValue(); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
returnValue = Boolean.valueOf(refactoringProperties.getProperty("returnvalue", "false")).booleanValue(); //$NON-NLS-1$//$NON-NLS-2$
|
||||
returnParameterIndex = new Integer(refactoringProperties.getProperty("returnparameterindex", "0")).intValue(); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
fatalError = Boolean.valueOf(refactoringProperties.getProperty("fatalerror", "false")).booleanValue(); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
visibility = VisibilityEnum.getEnumForStringRepresentation(refactoringProperties.getProperty("visibility", VisibilityEnum.v_private.toString())); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*******************************************************************************
|
||||
* 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.extractfunction;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import org.eclipse.cdt.ui.tests.refactoring.RefactoringTester;
|
||||
|
||||
/**
|
||||
* @author Emanuel Graf
|
||||
*
|
||||
*/
|
||||
public class ExtractFunctionTestSuite extends TestSuite {
|
||||
|
||||
@SuppressWarnings("nls")
|
||||
public static Test suite() throws Exception {
|
||||
TestSuite suite = new ExtractFunctionTestSuite();
|
||||
suite.addTest(RefactoringTester.suite("Extract Expression", "resources/refactoring/ExtractExpression.rts"));
|
||||
suite.addTest(RefactoringTester.suite("ExtractMethodRefactoringTests", "resources/refactoring/ExtractMethod.rts"));
|
||||
suite.addTest(RefactoringTester.suite("ExtractMethodPreprocessorRefactoringTests", "resources/refactoring/ExtractMethodPreprocessor.rts"));
|
||||
suite.addTest(RefactoringTester.suite("ExtractMethodDuplicatesTests", "resources/refactoring/ExtractMethodDuplicates.rts"));
|
||||
suite.addTest(RefactoringTester.suite("Extract Function Templates Tests", "resources/refactoring/ExtractFunctionTemplates.rts"));
|
||||
return suite;
|
||||
}
|
||||
|
||||
}
|
|
@ -20,10 +20,10 @@ import org.eclipse.cdt.ui.tests.refactoring.RefactoringTester;
|
|||
* @author Thomas Corbat
|
||||
*
|
||||
*/
|
||||
public class UtilTestSuite {
|
||||
public class UtilTestSuite extends TestSuite {
|
||||
|
||||
public static Test suite() throws Exception {
|
||||
TestSuite suite = new TestSuite("UtilTests"); //$NON-NLS-1$
|
||||
UtilTestSuite suite = new UtilTestSuite();
|
||||
suite.addTest(IdentifierHelperTest.suite());
|
||||
suite.addTest(RefactoringTester.suite("TranslationUnitHelperTest", "resources/refactoring/TranslationunitHelper.rts")); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
return suite;
|
||||
|
|
|
@ -31,6 +31,7 @@ Export-Package: org.eclipse.cdt.internal.corext;x-internal:=true,
|
|||
org.eclipse.cdt.internal.ui.refactoring;x-friends:="org.eclipse.cdt.ui.tests",
|
||||
org.eclipse.cdt.internal.ui.refactoring.dialogs,
|
||||
org.eclipse.cdt.internal.ui.refactoring.extractconstant;x-friends:="org.eclipse.cdt.ui.tests",
|
||||
org.eclipse.cdt.internal.ui.refactoring.extractfunction,
|
||||
org.eclipse.cdt.internal.ui.refactoring.rename;x-friends:="org.eclipse.cdt.ui.tests",
|
||||
org.eclipse.cdt.internal.ui.refactoring.utils;x-friends:="org.eclipse.cdt.ui.tests",
|
||||
org.eclipse.cdt.internal.ui.search;x-internal:=true,
|
||||
|
|
|
@ -143,6 +143,8 @@ ActionDefinition.renameElement.name= Rename - Refactoring
|
|||
ActionDefinition.renameElement.description= Rename the selected element
|
||||
ActionDefinition.extractConstant.name= Extract Constant - Refactoring
|
||||
ActionDefinition.extractConstant.description= Extract a constant for the selected expression
|
||||
ActionDefinition.extractFunction.name= Extract Function - Refactoring
|
||||
ActionDefinition.extractFunction.description= Extract a function for the selected list of expressions or statements
|
||||
|
||||
# Action Set
|
||||
CodingActionSet.label= C/C++ Coding
|
||||
|
@ -151,6 +153,7 @@ CodingActionSet.description= Action set containing coding related C/C++ actions
|
|||
Refactoring.menu.label= Refac&tor
|
||||
Refactoring.renameAction.label=Re&name...
|
||||
Refactoring.extractConstant.label=Extr&act Constant...
|
||||
Refactoring.extractFunction.label=Extract &Function... (work in progress)
|
||||
|
||||
CEditor.name=C/C++ Editor
|
||||
|
||||
|
|
|
@ -1150,6 +1150,13 @@
|
|||
id="org.eclipse.cdt.ui.actions.Rename"
|
||||
retarget="true">
|
||||
</action>
|
||||
<action
|
||||
definitionId="org.eclipse.cdt.ui.refactor.extract.function"
|
||||
label="%Refactoring.extractFunction.label"
|
||||
menubarPath="org.eclipse.jdt.ui.refactoring.menu/codingGroup"
|
||||
id="org.eclipse.cdt.ui.actions.ExtractMethod"
|
||||
retarget="true">
|
||||
</action>
|
||||
<action
|
||||
definitionId="org.eclipse.cdt.ui.refactor.extract.constant"
|
||||
label="%Refactoring.extractConstant.label"
|
||||
|
@ -1605,6 +1612,11 @@
|
|||
schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
|
||||
contextId="org.eclipse.cdt.ui.cViewScope"
|
||||
commandId="org.eclipse.cdt.ui.edit.text.rename.element"/>
|
||||
<key
|
||||
sequence="M2+M3+M"
|
||||
schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
|
||||
contextId="org.eclipse.cdt.ui.cEditorScope"
|
||||
commandId="org.eclipse.cdt.ui.refactor.extract.function"/>
|
||||
<key
|
||||
sequence="M3+C"
|
||||
schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
|
||||
|
@ -1694,14 +1706,12 @@
|
|||
<key
|
||||
sequence="M1+F5"
|
||||
commandId="org.eclipse.debug.ui.commands.RunLast"
|
||||
contextId="org.eclipse.ui.globalScope"
|
||||
schemeId="org.eclipse.cdt.ui.visualstudio"/>
|
||||
|
||||
<!-- MSVS StartWithoutDebugging -->
|
||||
<key
|
||||
sequence="F5"
|
||||
commandId="org.eclipse.debug.ui.commands.DebugLast"
|
||||
contextId="org.eclipse.ui.globalScope"
|
||||
schemeId="org.eclipse.cdt.ui.visualstudio"/>
|
||||
|
||||
<!-- MSVS StepInto -->
|
||||
|
@ -1729,21 +1739,18 @@
|
|||
<key
|
||||
sequence="F9"
|
||||
commandId="org.eclipse.debug.ui.commands.ToggleBreakpoint"
|
||||
contextId="org.eclipse.ui.globalScope"
|
||||
schemeId="org.eclipse.cdt.ui.visualstudio"/>
|
||||
|
||||
<!-- MSVS RunToCursor -->
|
||||
<key
|
||||
sequence="M1+F10"
|
||||
commandId="org.eclipse.debug.ui.commands.RunToLine"
|
||||
contextId="org.eclipse.ui.globalScope"
|
||||
schemeId="org.eclipse.cdt.ui.visualstudio"/>
|
||||
|
||||
<!-- MSVS Breakpoints -->
|
||||
<key
|
||||
sequence="M1+M3+B"
|
||||
commandId="org.eclipse.debug.ui.BreakpointView"
|
||||
contextId="org.eclipse.ui.globalScope"
|
||||
schemeId="org.eclipse.cdt.ui.visualstudio"/>
|
||||
|
||||
<!-- Search Keys -->
|
||||
|
@ -1972,6 +1979,12 @@
|
|||
categoryId="org.eclipse.cdt.ui.category.refactoring"
|
||||
id="org.eclipse.cdt.ui.refactor.extract.constant">
|
||||
</command>
|
||||
<command
|
||||
name="%ActionDefinition.extractFunction.name"
|
||||
description="%ActionDefinition.extractFunction.description"
|
||||
categoryId="org.eclipse.cdt.ui.category.refactoring"
|
||||
id="org.eclipse.cdt.ui.refactor.extract.function">
|
||||
</command>
|
||||
|
||||
</extension>
|
||||
<extension
|
||||
|
|
|
@ -97,6 +97,12 @@ public interface ICEditorActionDefinitionIds extends ITextEditorActionDefinition
|
|||
* (value <code>"org.eclipse.cdt.ui.refactor.extract.constant"</code>).
|
||||
*/
|
||||
public static final String EXTRACT_CONSTANT= "org.eclipse.cdt.ui.refactor.extract.constant"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Action definition ID of the refactor -> extract function action (value
|
||||
* <code>"org.eclipse.cdt.ui.refactor.extract.function"</code>).
|
||||
*/
|
||||
public static final String EXTRACT_FUNCTION = "org.eclipse.cdt.ui.refactor.extract.function"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Action definition ID of the refactor -> undo action
|
||||
|
|
|
@ -65,10 +65,11 @@ import org.eclipse.cdt.internal.core.dom.parser.IASTDeclarationAmbiguity;
|
|||
public abstract class CRefactoring extends Refactoring {
|
||||
protected static final String EMPTY_STRING = ""; //$NON-NLS-1$
|
||||
private static final int AST_STYLE = ITranslationUnit.AST_CONFIGURE_USING_SOURCE_CONTEXT | ITranslationUnit.AST_SKIP_INDEXED_HEADERS;
|
||||
public static final String NEWLINE = "\n"; // mstodo //$NON-NLS-1$
|
||||
|
||||
protected String name = Messages.HSRRefactoring_name;
|
||||
protected IFile file;
|
||||
private ISelection selection;
|
||||
protected ISelection selection;
|
||||
protected RefactoringStatus initStatus;
|
||||
protected IASTTranslationUnit unit;
|
||||
private IIndex fIndex;
|
||||
|
@ -353,6 +354,13 @@ public abstract class CRefactoring extends Refactoring {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean isSelectedFile(ITextSelection textSelection, IASTNode node) {
|
||||
if( isInSameFile(node) ) {
|
||||
return isExpressionWhollyInSelection(textSelection, node);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected MethodContext findContext(IASTNode node) {
|
||||
boolean found = false;
|
||||
|
@ -400,6 +408,16 @@ public abstract class CRefactoring extends Refactoring {
|
|||
return af.ambiguityFound();
|
||||
}
|
||||
|
||||
protected IASTSimpleDeclaration findSimpleDeclarationInParents(IASTNode node) {
|
||||
while(node != null){
|
||||
if (node instanceof IASTSimpleDeclaration) {
|
||||
return (IASTSimpleDeclaration) node;
|
||||
}
|
||||
node = node.getParent();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void lockIndex() throws CoreException, InterruptedException {
|
||||
if (fIndex == null) {
|
||||
ICProject[] projects= CoreModel.getDefault().getCModel().getCProjects();
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/*******************************************************************************
|
||||
* 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;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.eclipse.ltk.core.refactoring.Change;
|
||||
import org.eclipse.ltk.core.refactoring.CompositeChange;
|
||||
|
||||
import org.eclipse.cdt.ui.refactoring.CTextFileChange;
|
||||
|
||||
/**
|
||||
* @author Emanuel Graf
|
||||
*
|
||||
*/
|
||||
public class ChangeTreeSet {
|
||||
|
||||
private static final class ChangePositionComparator implements Comparator<CTextFileChange> {
|
||||
public int compare(CTextFileChange o1, CTextFileChange o2) {
|
||||
if(o1.getFile().equals(o2.getFile())){
|
||||
return o2.getEdit().getOffset() - o1.getEdit().getOffset();
|
||||
}
|
||||
return o2.getFile().hashCode() - o1.getFile().hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
private final TreeSet<CTextFileChange> changes = new TreeSet<CTextFileChange>(new ChangePositionComparator());
|
||||
|
||||
public void add(CTextFileChange change) {
|
||||
changes.add(change);
|
||||
}
|
||||
|
||||
public CompositeChange getCompositeChange(String name) {
|
||||
CompositeChange allChanges = new CompositeChange(name);
|
||||
|
||||
for (Change change : changes) {
|
||||
allChanges.add(change);
|
||||
}
|
||||
return allChanges;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return changes.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/*******************************************************************************
|
||||
* 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;
|
||||
|
||||
public interface EqualityChecker<T> {
|
||||
boolean isEquals(T object1, T object2);
|
||||
}
|
|
@ -38,6 +38,8 @@ public final class Messages extends NLS {
|
|||
public static String HSRRefactoring_SelectionNotValid;
|
||||
public static String HSRRefactoring_CantLoadTU;
|
||||
public static String HSRRefactoring_Ambiguity;
|
||||
public static String NodeContainer_Name;
|
||||
public static String NodeContainer_Space;
|
||||
public static String NO_FILE;
|
||||
|
||||
static {
|
||||
|
|
|
@ -0,0 +1,486 @@
|
|||
/*******************************************************************************
|
||||
* 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;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.eclipse.core.runtime.ILog;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTMacroExpansionLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||
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.dom.ast.cpp.ICPPASTParameterDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeTemplateParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
|
||||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTArrayDeclarator;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTDeclarator;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTParameterDeclaration;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTReferenceOperator;
|
||||
import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.ASTWriter;
|
||||
|
||||
public class NodeContainer {
|
||||
|
||||
private final Vector<IASTNode> vec;
|
||||
private final Vector<NameInformation> names;
|
||||
|
||||
public class NameInformation {
|
||||
private IASTName name;
|
||||
private IASTName declaration;
|
||||
private final Vector<IASTName> references;
|
||||
private Vector<IASTName> referencesAfterCached;
|
||||
private int lastCachedReferencesHash;
|
||||
private boolean isReference;
|
||||
private boolean isReturnValue;
|
||||
|
||||
private boolean userSetIsReference;
|
||||
private boolean userSetIsReturnValue;
|
||||
private String userSetName;
|
||||
private int userOrder;
|
||||
|
||||
public int getUserOrder() {
|
||||
return userOrder;
|
||||
}
|
||||
|
||||
public void setUserOrder(int userOrder) {
|
||||
this.userOrder = userOrder;
|
||||
}
|
||||
|
||||
public NameInformation(IASTName name) {
|
||||
super();
|
||||
this.name = name;
|
||||
references = new Vector<IASTName>();
|
||||
}
|
||||
|
||||
public IASTName getDeclaration() {
|
||||
return declaration;
|
||||
}
|
||||
|
||||
public void setDeclaration(IASTName declaration) {
|
||||
this.declaration = declaration;
|
||||
}
|
||||
|
||||
public IASTName getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(IASTName name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void addReference(IASTName name) {
|
||||
references.add(name);
|
||||
}
|
||||
|
||||
public Vector<IASTName> getReferencesAfterSelection() {
|
||||
if (referencesAfterCached == null
|
||||
|| lastCachedReferencesHash == references.hashCode()) {
|
||||
|
||||
lastCachedReferencesHash = references.hashCode();
|
||||
referencesAfterCached = new Vector<IASTName>();
|
||||
for (IASTName ref : references) {
|
||||
IASTFileLocation loc = ref.getFileLocation();
|
||||
if (loc.getNodeOffset() >= getEndOffset()) {
|
||||
referencesAfterCached.add(ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
return referencesAfterCached;
|
||||
}
|
||||
|
||||
public boolean isUsedAfterReferences() {
|
||||
return getReferencesAfterSelection().size() > 0;
|
||||
}
|
||||
|
||||
public ICPPASTParameterDeclaration getICPPASTParameterDeclaration(
|
||||
boolean isReference) {
|
||||
ICPPASTParameterDeclaration para = new CPPASTParameterDeclaration();
|
||||
IASTDeclarator sourceDeclarator = (IASTDeclarator) getDeclaration()
|
||||
.getParent();
|
||||
|
||||
if (sourceDeclarator.getParent() instanceof IASTSimpleDeclaration) {
|
||||
IASTSimpleDeclaration decl = (IASTSimpleDeclaration) sourceDeclarator
|
||||
.getParent();
|
||||
para.setDeclSpecifier(decl.getDeclSpecifier());
|
||||
} else if (sourceDeclarator.getParent() instanceof IASTParameterDeclaration) {
|
||||
IASTParameterDeclaration decl = (IASTParameterDeclaration) sourceDeclarator
|
||||
.getParent();
|
||||
para.setDeclSpecifier(decl.getDeclSpecifier());
|
||||
}
|
||||
|
||||
IASTDeclarator declarator;
|
||||
if (sourceDeclarator instanceof IASTArrayDeclarator) {
|
||||
IASTArrayDeclarator arrDeclarator = (IASTArrayDeclarator)sourceDeclarator;
|
||||
declarator = new CPPASTArrayDeclarator();
|
||||
IASTArrayModifier[] arrayModifiers = arrDeclarator.getArrayModifiers();
|
||||
for (IASTArrayModifier arrayModifier : arrayModifiers) {
|
||||
((IASTArrayDeclarator)declarator).addArrayModifier(arrayModifier);
|
||||
}
|
||||
|
||||
}else {
|
||||
declarator = new CPPASTDeclarator();
|
||||
}
|
||||
declarator.setName(new CPPASTName(getDeclaration().toCharArray()));
|
||||
for (IASTPointerOperator pointerOp : sourceDeclarator
|
||||
.getPointerOperators()) {
|
||||
declarator.addPointerOperator(pointerOp);
|
||||
}
|
||||
|
||||
if (isReference) {
|
||||
declarator.addPointerOperator(new CPPASTReferenceOperator());
|
||||
}
|
||||
|
||||
declarator.setNestedDeclarator(sourceDeclarator
|
||||
.getNestedDeclarator());
|
||||
para.setDeclarator(declarator);
|
||||
|
||||
return para;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
IASTDeclSpecifier declSpec = null;
|
||||
|
||||
IASTNode node = getDeclaration().getParent();
|
||||
if (node instanceof ICPPASTSimpleTypeTemplateParameter) {
|
||||
ICPPASTSimpleTypeTemplateParameter parameter = (ICPPASTSimpleTypeTemplateParameter) node;
|
||||
return parameter.getName().toString();
|
||||
}
|
||||
IASTDeclarator sourceDeclarator = (IASTDeclarator) node;
|
||||
if (sourceDeclarator.getParent() instanceof IASTSimpleDeclaration) {
|
||||
IASTSimpleDeclaration decl = (IASTSimpleDeclaration) sourceDeclarator
|
||||
.getParent();
|
||||
declSpec = decl.getDeclSpecifier();
|
||||
} else if (sourceDeclarator.getParent() instanceof IASTParameterDeclaration) {
|
||||
IASTParameterDeclaration decl = (IASTParameterDeclaration) sourceDeclarator
|
||||
.getParent();
|
||||
declSpec = decl.getDeclSpecifier();
|
||||
}
|
||||
|
||||
ASTWriter writer = new ASTWriter();
|
||||
return writer.write(declSpec);
|
||||
}
|
||||
|
||||
public boolean isDeclarationInScope() {
|
||||
int declOffset = declaration.getFileLocation().getNodeOffset();
|
||||
return declOffset >= getStartOffset()
|
||||
&& declOffset <= getEndOffset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Messages.NodeContainer_Name + name + Messages.NodeContainer_Space + isDeclarationInScope();
|
||||
}
|
||||
|
||||
public boolean isReference() {
|
||||
return isReference;
|
||||
}
|
||||
|
||||
public void setReference(boolean isReference) {
|
||||
this.isReference = isReference;
|
||||
}
|
||||
|
||||
public boolean isReturnValue() {
|
||||
return isReturnValue;
|
||||
}
|
||||
|
||||
public void setReturnValue(boolean isReturnValue) {
|
||||
this.isReturnValue = isReturnValue;
|
||||
}
|
||||
|
||||
public boolean isUserSetIsReference() {
|
||||
return userSetIsReference;
|
||||
}
|
||||
|
||||
public void setUserSetIsReference(boolean userSetIsReference) {
|
||||
this.userSetIsReference = userSetIsReference;
|
||||
}
|
||||
|
||||
public boolean isUserSetIsReturnValue() {
|
||||
return userSetIsReturnValue;
|
||||
}
|
||||
|
||||
public void setUserSetIsReturnValue(boolean userSetIsReturnValue) {
|
||||
this.userSetIsReturnValue = userSetIsReturnValue;
|
||||
}
|
||||
|
||||
public String getUserSetName() {
|
||||
return userSetName;
|
||||
}
|
||||
|
||||
public void setUserSetName(String userSetName) {
|
||||
this.userSetName = userSetName;
|
||||
}
|
||||
}
|
||||
|
||||
public NodeContainer() {
|
||||
super();
|
||||
vec = new Vector<IASTNode>();
|
||||
names = new Vector<NameInformation>();
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return vec.size();
|
||||
}
|
||||
|
||||
public void add(IASTNode node) {
|
||||
vec.add(node);
|
||||
}
|
||||
|
||||
public void findAllNames() {
|
||||
for (IASTNode node : vec) {
|
||||
node.accept(new CPPASTVisitor() {
|
||||
{
|
||||
shouldVisitNames = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int visit(IASTName name) {
|
||||
IBinding bind = name.resolveBinding();
|
||||
|
||||
if (bind instanceof ICPPBinding
|
||||
&& !(bind instanceof ICPPTemplateTypeParameter)) {
|
||||
ICPPBinding cppBind = (ICPPBinding) bind;
|
||||
try {
|
||||
if (!cppBind.isGloballyQualified()) {
|
||||
NameInformation nameInformation = new NameInformation(
|
||||
name);
|
||||
|
||||
IASTName[] refs = name.getTranslationUnit()
|
||||
.getReferences(bind);
|
||||
for (IASTName ref : refs) {
|
||||
nameInformation.addReference(ref);
|
||||
}
|
||||
names.add(nameInformation);
|
||||
}
|
||||
} catch (DOMException e) {
|
||||
ILog logger = CUIPlugin.getDefault().getLog();
|
||||
IStatus status = new Status(IStatus.WARNING,
|
||||
CUIPlugin.PLUGIN_ID, IStatus.OK, e
|
||||
.getMessage(), e);
|
||||
logger.log(status);
|
||||
}
|
||||
}
|
||||
return super.visit(name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (NameInformation nameInf : names) {
|
||||
IASTName name = nameInf.getName();
|
||||
|
||||
IASTTranslationUnit unit = name.getTranslationUnit();
|
||||
IASTName[] decls = unit.getDeclarationsInAST(name.resolveBinding());
|
||||
for (IASTName declaration : decls) {
|
||||
nameInf.setDeclaration(declaration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns all local names in the selection which will be used after the
|
||||
* selection expected the ones which are pointers
|
||||
*/
|
||||
public Vector<NameInformation> getAllAfterUsedNames() {
|
||||
Vector<IASTName> declarations = new Vector<IASTName>();
|
||||
Vector<NameInformation> usedAfter = new Vector<NameInformation>();
|
||||
|
||||
if (names.size() <= 0) {
|
||||
findAllNames();
|
||||
}
|
||||
|
||||
for (NameInformation nameInf : names) {
|
||||
if (!declarations.contains(nameInf.getDeclaration())) {
|
||||
|
||||
declarations.add(nameInf.getDeclaration());
|
||||
if (nameInf.isUsedAfterReferences()) {
|
||||
usedAfter.add(nameInf);
|
||||
nameInf.setReference(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return usedAfter;
|
||||
}
|
||||
|
||||
public Vector<NameInformation> getAllAfterUsedNamesChoosenByUser() {
|
||||
Vector<IASTName> declarations = new Vector<IASTName>();
|
||||
Vector<NameInformation> usedAfter = new Vector<NameInformation>();
|
||||
|
||||
for (NameInformation nameInf : names) {
|
||||
if (!declarations.contains(nameInf.getDeclaration())) {
|
||||
|
||||
declarations.add(nameInf.getDeclaration());
|
||||
if (nameInf.isUserSetIsReference()
|
||||
|| nameInf.isUserSetIsReturnValue()) {
|
||||
usedAfter.add(nameInf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return usedAfter;
|
||||
}
|
||||
|
||||
public Vector<NameInformation> getUsedNamesUnique() {
|
||||
Vector<IASTName> declarations = new Vector<IASTName>();
|
||||
Vector<NameInformation> usedAfter = new Vector<NameInformation>();
|
||||
|
||||
if (names.size() <= 0) {
|
||||
findAllNames();
|
||||
}
|
||||
|
||||
for (NameInformation nameInf : names) {
|
||||
if (!declarations.contains(nameInf.getDeclaration())) {
|
||||
|
||||
declarations.add(nameInf.getDeclaration());
|
||||
usedAfter.add(nameInf);
|
||||
}
|
||||
}
|
||||
|
||||
return usedAfter;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns all local names in the selection which will be used after the
|
||||
* selection expected the ones which are pointers
|
||||
* XXX Was soll dieser Kommentar aussagen? --Mirko
|
||||
*/
|
||||
public Vector<NameInformation> getAllDeclaredInScope() {
|
||||
Vector<IASTName> declarations = new Vector<IASTName>();
|
||||
Vector<NameInformation> usedAfter = new Vector<NameInformation>();
|
||||
|
||||
for (NameInformation nameInf : names) {
|
||||
if (nameInf.isDeclarationInScope()
|
||||
&& !declarations.contains(nameInf.getDeclaration()) && nameInf.isUsedAfterReferences()) {
|
||||
|
||||
declarations.add(nameInf.getDeclaration());
|
||||
usedAfter.add(nameInf);
|
||||
// is return value candidate, set returnvalue to true and
|
||||
// reference to false
|
||||
nameInf.setReturnValue(true);
|
||||
nameInf.setReference(false);
|
||||
}
|
||||
}
|
||||
|
||||
return usedAfter;
|
||||
}
|
||||
|
||||
public List<IASTNode> getNodesToWrite() {
|
||||
return vec;
|
||||
}
|
||||
|
||||
public int getStartOffset() {
|
||||
return getOffset(false);
|
||||
}
|
||||
|
||||
public int getStartOffsetIncludingComments() {
|
||||
return getOffset(true);
|
||||
}
|
||||
|
||||
private int getOffset(boolean includeComments) {
|
||||
int start = Integer.MAX_VALUE;
|
||||
|
||||
for (IASTNode node : vec) {
|
||||
int nodeStart = Integer.MAX_VALUE;
|
||||
|
||||
IASTNodeLocation[] nodeLocations = node.getNodeLocations();
|
||||
if (nodeLocations.length != 1) {
|
||||
for (IASTNodeLocation location : nodeLocations) {
|
||||
int nodeOffset;
|
||||
if (location instanceof IASTMacroExpansionLocation) {
|
||||
IASTMacroExpansionLocation macroLoc = (IASTMacroExpansionLocation) location;
|
||||
nodeOffset = macroLoc.asFileLocation().getNodeOffset();
|
||||
}else {
|
||||
nodeOffset = node.getFileLocation().getNodeOffset();
|
||||
}
|
||||
if(nodeOffset < nodeStart) {
|
||||
nodeStart = nodeOffset;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
nodeStart = node.getFileLocation().getNodeOffset();
|
||||
}
|
||||
if (nodeStart < start) {
|
||||
start = nodeStart;
|
||||
}
|
||||
}
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
public int getEndOffset() {
|
||||
return getEndOffset(false);
|
||||
}
|
||||
|
||||
public int getEndOffsetIncludingComments() {
|
||||
return getEndOffset(true);
|
||||
}
|
||||
|
||||
private int getEndOffset(boolean includeComments) {
|
||||
int end = 0;
|
||||
|
||||
for (IASTNode node : vec) {
|
||||
int fileOffset = 0;
|
||||
int length = 0;
|
||||
|
||||
IASTNodeLocation[] nodeLocations = node.getNodeLocations();
|
||||
for (IASTNodeLocation location : nodeLocations) {
|
||||
int nodeOffset, nodeLength;
|
||||
if (location instanceof IASTMacroExpansionLocation) {
|
||||
IASTMacroExpansionLocation macroLoc = (IASTMacroExpansionLocation) location;
|
||||
nodeOffset = macroLoc.asFileLocation().getNodeOffset();
|
||||
nodeLength = macroLoc.asFileLocation().getNodeLength();
|
||||
}else {
|
||||
nodeOffset = location.getNodeOffset();
|
||||
nodeLength = location.getNodeLength();
|
||||
}
|
||||
if(fileOffset < nodeOffset) {
|
||||
fileOffset = nodeOffset;
|
||||
length = nodeLength;
|
||||
}
|
||||
}
|
||||
int endNode = fileOffset + length;
|
||||
if (endNode > end) {
|
||||
end = endNode;
|
||||
}
|
||||
}
|
||||
|
||||
return end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return vec.toString();
|
||||
}
|
||||
|
||||
public Vector<NameInformation> getNames() {
|
||||
return names;
|
||||
}
|
||||
}
|
|
@ -13,8 +13,7 @@ package org.eclipse.cdt.internal.ui.refactoring;
|
|||
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.jface.viewers.ISelection;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
import org.eclipse.ui.PlatformUI;
|
||||
import org.eclipse.jface.window.IShellProvider;
|
||||
|
||||
/**
|
||||
* Base class for all refactoring runners.
|
||||
|
@ -26,12 +25,12 @@ public abstract class RefactoringRunner {
|
|||
|
||||
protected IFile file;
|
||||
protected ISelection selection;
|
||||
protected Shell shell;
|
||||
protected IShellProvider shellProvider;
|
||||
|
||||
public RefactoringRunner(IFile file, ISelection selection) {
|
||||
public RefactoringRunner(IFile file, ISelection selection, IShellProvider shellProvider) {
|
||||
this.file = file;
|
||||
this.selection = selection;
|
||||
shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
|
||||
this.shellProvider= shellProvider;
|
||||
}
|
||||
|
||||
public abstract void run();
|
||||
|
|
|
@ -14,6 +14,7 @@ package org.eclipse.cdt.internal.ui.refactoring.extractconstant;
|
|||
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.ui.CUIPlugin;
|
||||
|
@ -28,8 +29,8 @@ import org.eclipse.cdt.internal.ui.refactoring.RefactoringRunner;
|
|||
*/
|
||||
public class ExtractConstantRefactoringRunner extends RefactoringRunner {
|
||||
|
||||
public ExtractConstantRefactoringRunner(IFile file, ISelection selection) {
|
||||
super(file, selection);
|
||||
public ExtractConstantRefactoringRunner(IFile file, ISelection selection, IShellProvider shellProvider) {
|
||||
super(file, selection, shellProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -42,7 +43,7 @@ public class ExtractConstantRefactoringRunner extends RefactoringRunner {
|
|||
try {
|
||||
refactoring.lockIndex();
|
||||
try {
|
||||
operator.run(shell, refactoring.getName());
|
||||
operator.run(shellProvider.getShell(), refactoring.getName());
|
||||
}
|
||||
finally {
|
||||
refactoring.unlockIndex();
|
||||
|
|
|
@ -0,0 +1,203 @@
|
|||
/*******************************************************************************
|
||||
* 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.extractfunction;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.custom.TableEditor;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.events.SelectionListener;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Event;
|
||||
import org.eclipse.swt.widgets.Table;
|
||||
import org.eclipse.swt.widgets.TableColumn;
|
||||
import org.eclipse.swt.widgets.TableItem;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer.NameInformation;
|
||||
|
||||
public class ChooserComposite extends Composite {
|
||||
|
||||
private static final String COLUMN_RETURN = Messages.ChooserComposite_Return;
|
||||
private static final String COLUMN_REFERENCE = Messages.ChooserComposite_CallByRef;
|
||||
private static final String COLUMN_NAME = Messages.ChooserComposite_Name;
|
||||
private static final String COLUMN_TYPE = Messages.ChooserComposite_Type;
|
||||
|
||||
|
||||
private Button voidReturn;
|
||||
|
||||
private final ExtractFunctionInputPage ip;
|
||||
|
||||
public ChooserComposite(Composite parent,
|
||||
final ExtractFunctionInformation info, ExtractFunctionInputPage ip) {
|
||||
super(parent, SWT.NONE);
|
||||
|
||||
this.ip = ip;
|
||||
|
||||
GridLayout layout = new GridLayout();
|
||||
setLayout(layout);
|
||||
|
||||
boolean hasNoPredefinedReturnValue = true;
|
||||
if (info.getInScopeDeclaredVariable() != null) {
|
||||
info.getInScopeDeclaredVariable().setUserSetIsReturnValue(true);
|
||||
hasNoPredefinedReturnValue = false;
|
||||
}
|
||||
|
||||
final Vector<Button> returnButtons = new Vector<Button>();
|
||||
final Vector<Button> referenceButtons = new Vector<Button>();
|
||||
|
||||
final Table table = new Table(parent, SWT.BORDER | SWT.MULTI | SWT.FILL);
|
||||
|
||||
GridData tableLayoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||
table.setLayoutData(tableLayoutData);
|
||||
|
||||
table.setLinesVisible(true);
|
||||
table.setHeaderVisible(true);
|
||||
|
||||
addColumnToTable(table, COLUMN_TYPE);
|
||||
addColumnToTable(table, COLUMN_NAME);
|
||||
addColumnToTable(table, COLUMN_REFERENCE);
|
||||
if(!info.isExtractExpression()) {
|
||||
addColumnToTable(table, COLUMN_RETURN);
|
||||
}
|
||||
addColumnToTable(table, ""); //$NON-NLS-1$
|
||||
|
||||
for (int i = 0; i < info.getAllUsedNames().size(); i++) {
|
||||
if (!info.getAllUsedNames().get(i).isDeclarationInScope()) {
|
||||
TableItem item = new TableItem(table, SWT.NONE);
|
||||
|
||||
TableEditor editor = new TableEditor(table);
|
||||
int columnIndex = 0;
|
||||
|
||||
final NameInformation name = info.getAllUsedNames().get(i);
|
||||
|
||||
// Text
|
||||
item.setText(columnIndex++, name.getType());
|
||||
item.setText(columnIndex++, name.getName().toString());
|
||||
|
||||
// Button
|
||||
editor = new TableEditor(table);
|
||||
final Button referenceButton = new Button(table, SWT.CHECK);
|
||||
referenceButton.setSelection(name.isReference());
|
||||
referenceButton.setBackground(table.getBackground());
|
||||
referenceButton.addSelectionListener(new SelectionListener() {
|
||||
|
||||
public void widgetDefaultSelected(SelectionEvent e) {
|
||||
name.setUserSetIsReference(referenceButton
|
||||
.getSelection());
|
||||
onVisibilityOrReturnChange(info.getAllUsedNames());
|
||||
}
|
||||
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
widgetDefaultSelected(e);
|
||||
}
|
||||
|
||||
});
|
||||
referenceButton.pack();
|
||||
editor.minimumWidth = referenceButton.getSize().x;
|
||||
editor.horizontalAlignment = SWT.CENTER;
|
||||
referenceButtons.add(referenceButton);
|
||||
editor.setEditor(referenceButton, item, columnIndex++);
|
||||
|
||||
if(info.isExtractExpression())
|
||||
continue; // Skip the return radiobutton
|
||||
|
||||
// Button
|
||||
editor = new TableEditor(table);
|
||||
final Button returnButton = new Button(table, SWT.RADIO);
|
||||
returnButton.setSelection(name.isReturnValue());
|
||||
name.setUserSetIsReference(name.isReference());
|
||||
returnButton.setEnabled(hasNoPredefinedReturnValue);
|
||||
returnButton.setBackground(table.getBackground());
|
||||
returnButton.addSelectionListener(new SelectionListener() {
|
||||
|
||||
public void widgetDefaultSelected(SelectionEvent e) {
|
||||
name.setUserSetIsReturnValue(returnButton
|
||||
.getSelection());
|
||||
if (returnButton.getSelection()) {
|
||||
referenceButton.setSelection(false);
|
||||
referenceButton.notifyListeners(SWT.Selection,
|
||||
new Event());
|
||||
} else {
|
||||
if (name.isReference()) {
|
||||
referenceButton.setSelection(true);
|
||||
referenceButton.notifyListeners(SWT.Selection,
|
||||
new Event());
|
||||
}
|
||||
}
|
||||
onVisibilityOrReturnChange(info.getAllUsedNames());
|
||||
}
|
||||
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
widgetDefaultSelected(e);
|
||||
}
|
||||
|
||||
});
|
||||
returnButton.pack();
|
||||
editor.minimumWidth = returnButton.getSize().x;
|
||||
editor.horizontalAlignment = SWT.CENTER;
|
||||
returnButtons.add(returnButton);
|
||||
editor.setEditor(returnButton, item, columnIndex++);
|
||||
}
|
||||
}
|
||||
|
||||
if(!info.isExtractExpression()) {
|
||||
voidReturn = new Button(parent, SWT.CHECK | SWT.LEFT);
|
||||
voidReturn.setText(Messages.ChooserComposite_NoReturnValue);
|
||||
voidReturn.setEnabled(hasNoPredefinedReturnValue);
|
||||
voidReturn.addSelectionListener(new SelectionListener() {
|
||||
|
||||
public void widgetDefaultSelected(SelectionEvent e) {
|
||||
info.setReturnVariable(null);
|
||||
|
||||
for (Button button : returnButtons) {
|
||||
if (voidReturn.getSelection()) {
|
||||
button.setSelection(false);
|
||||
button.notifyListeners(SWT.Selection, new Event());
|
||||
}
|
||||
button.setEnabled(!voidReturn.getSelection());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
widgetDefaultSelected(e);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
layout();
|
||||
}
|
||||
|
||||
private void addColumnToTable(final Table table, String string) {
|
||||
TableColumn column = new TableColumn(table, SWT.NONE);
|
||||
column.setText(string);
|
||||
column.setWidth(100);
|
||||
}
|
||||
|
||||
void onVisibilityOrReturnChange(Vector<NameInformation> name){
|
||||
String variableUsedAfterBlock = null;
|
||||
for (NameInformation information : name) {
|
||||
if(information.isUsedAfterReferences()
|
||||
&& !(information.isUserSetIsReference() || information.isUserSetIsReturnValue())){
|
||||
variableUsedAfterBlock = information.getName().toString();
|
||||
}
|
||||
}
|
||||
|
||||
ip.errorWithAfterUsedVariable(variableUsedAfterBlock);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,235 @@
|
|||
/*******************************************************************************
|
||||
* 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.extractfunction;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.text.edits.TextEditGroup;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
|
||||
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFieldReference;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionDefinition;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTLiteralExpression;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNamedTypeSpecifier;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTReturnStatement;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclSpecifier;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclaration;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassType;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTypedef;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer.NameInformation;
|
||||
|
||||
/**
|
||||
* Handles the extraction of expression nodes, like return type determination.
|
||||
*
|
||||
* @author Mirko Stocker
|
||||
*
|
||||
*/
|
||||
public class ExtractExpression extends ExtractedFunctionConstructionHelper {
|
||||
|
||||
@Override
|
||||
public void constructMethodBody(IASTCompoundStatement compound,
|
||||
List<IASTNode> list, ASTRewrite rewrite, TextEditGroup group) {
|
||||
|
||||
CPPASTReturnStatement statement = new CPPASTReturnStatement();
|
||||
IASTExpression nullReturnExp = new CPPASTLiteralExpression(IASTLiteralExpression.lk_integer_constant, "0"); //$NON-NLS-1$
|
||||
statement.setReturnValue(nullReturnExp);
|
||||
ASTRewrite nestedRewrite = rewrite.insertBefore(compound, null, statement, group);
|
||||
|
||||
nestedRewrite.replace(nullReturnExp, list.get(0), group);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public IASTDeclSpecifier determineReturnType(IASTNode extractedNode, NameInformation _) {
|
||||
IASTDeclSpecifier declSpecifier = null;
|
||||
|
||||
if (extractedNode instanceof ICPPASTBinaryExpression) {
|
||||
declSpecifier = handleBinaryExpression((ICPPASTBinaryExpression) extractedNode);
|
||||
}
|
||||
|
||||
if (extractedNode instanceof ICPPASTNewExpression) {
|
||||
declSpecifier = handleNewExpression((ICPPASTNewExpression) extractedNode);
|
||||
}
|
||||
|
||||
if (extractedNode instanceof IASTFunctionCallExpression) {
|
||||
declSpecifier = handleFunctionCallExpression((IASTFunctionCallExpression) extractedNode);
|
||||
}
|
||||
|
||||
if(declSpecifier == null) {
|
||||
return createSimpleDeclSpecifier(IASTSimpleDeclSpecifier.t_void);
|
||||
}
|
||||
|
||||
return declSpecifier;
|
||||
}
|
||||
|
||||
private IASTDeclSpecifier handleNewExpression(ICPPASTNewExpression expression) {
|
||||
return expression.getTypeId().getDeclSpecifier();
|
||||
}
|
||||
|
||||
private IASTDeclSpecifier handleBinaryExpression(ICPPASTBinaryExpression node) {
|
||||
|
||||
switch (node.getOperator()) {
|
||||
case IASTBinaryExpression.op_equals:
|
||||
case IASTBinaryExpression.op_notequals:
|
||||
case IASTBinaryExpression.op_logicalOr:
|
||||
case IASTBinaryExpression.op_logicalAnd:
|
||||
case IASTBinaryExpression.op_greaterEqual:
|
||||
case IASTBinaryExpression.op_greaterThan:
|
||||
case IASTBinaryExpression.op_lessEqual:
|
||||
case IASTBinaryExpression.op_lessThan:
|
||||
|
||||
/* We assume that these operations evaluate to bool and don't
|
||||
* consider overriden operators from custom types for now.*/
|
||||
return createSimpleDeclSpecifier(ICPPASTSimpleDeclSpecifier.t_bool);
|
||||
|
||||
case IASTBinaryExpression.op_plus:
|
||||
case IASTBinaryExpression.op_plusAssign:
|
||||
case IASTBinaryExpression.op_minus:
|
||||
case IASTBinaryExpression.op_minusAssign:
|
||||
case IASTBinaryExpression.op_multiply:
|
||||
case IASTBinaryExpression.op_multiplyAssign:
|
||||
case IASTBinaryExpression.op_divide:
|
||||
case IASTBinaryExpression.op_divideAssign:
|
||||
case IASTBinaryExpression.op_assign:
|
||||
|
||||
/* Assume that the expression's return type is the same as the left operand's.*/
|
||||
|
||||
if(node.getOperand1() instanceof CPPASTIdExpression) {
|
||||
IType expressionType = ((CPPASTIdExpression) node.getOperand1()).getExpressionType();
|
||||
|
||||
if (expressionType instanceof CPPBasicType) {
|
||||
|
||||
CPPBasicType basicType = (CPPBasicType) expressionType;
|
||||
return createSimpleDeclSpecifier(basicType.getType());
|
||||
|
||||
} else if (expressionType instanceof CPPTypedef) {
|
||||
|
||||
CPPTypedef typedef = (CPPTypedef) expressionType;
|
||||
return new CPPASTNamedTypeSpecifier((IASTName) typedef.getDefinition(), false);
|
||||
|
||||
} else if (expressionType instanceof CPPClassType) {
|
||||
|
||||
CPPClassType classType = (CPPClassType) expressionType;
|
||||
return new CPPASTNamedTypeSpecifier((IASTName) classType.getDefinition(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null /* not yet handled */;
|
||||
}
|
||||
|
||||
private static IASTDeclSpecifier createSimpleDeclSpecifier(int type) {
|
||||
IASTSimpleDeclSpecifier declSpec = new CPPASTSimpleDeclSpecifier();
|
||||
declSpec.setType(type);
|
||||
return declSpec;
|
||||
}
|
||||
|
||||
private static CPPFunction findCalledFunction(IASTFunctionCallExpression callExpression) {
|
||||
IASTExpression functionNameExpression = callExpression.getFunctionNameExpression();
|
||||
IASTName functionName = null;
|
||||
|
||||
if(functionNameExpression instanceof CPPASTIdExpression) {
|
||||
CPPASTIdExpression idExpression = (CPPASTIdExpression) functionNameExpression;
|
||||
functionName = idExpression.getName();
|
||||
} else if(functionNameExpression instanceof CPPASTFieldReference) {
|
||||
CPPASTFieldReference fieldReference = (CPPASTFieldReference) functionNameExpression;
|
||||
functionName = fieldReference.getFieldName();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (functionName.resolveBinding() instanceof CPPFunction) {
|
||||
return (CPPFunction) functionName.resolveBinding();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static IASTDeclSpecifier handleFunctionCallExpression(IASTFunctionCallExpression callExpression) {
|
||||
CPPFunction function = findCalledFunction(callExpression);
|
||||
|
||||
if (function != null) {
|
||||
if(function.getDefinition() != null) {
|
||||
IASTNode parent = function.getDefinition().getParent();
|
||||
if(parent instanceof CPPASTFunctionDefinition) {
|
||||
CPPASTFunctionDefinition definition = (CPPASTFunctionDefinition) parent;
|
||||
return definition.getDeclSpecifier();
|
||||
}
|
||||
} else if(hasDeclaration(function)) {
|
||||
IASTNode parent = function.getDeclarations()[0].getParent();
|
||||
if (parent instanceof CPPASTSimpleDeclaration) {
|
||||
CPPASTSimpleDeclaration declaration = (CPPASTSimpleDeclaration) parent;
|
||||
return declaration.getDeclSpecifier();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isReturnTypeAPointer(IASTNode node) {
|
||||
if(node instanceof ICPPASTNewExpression) {
|
||||
return true;
|
||||
} else if(!(node instanceof IASTFunctionCallExpression)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CPPFunction function = findCalledFunction((IASTFunctionCallExpression) node);
|
||||
|
||||
if (function != null) {
|
||||
if(function.getDefinition() != null) {
|
||||
IASTNode parent = function.getDefinition().getParent();
|
||||
if(parent instanceof CPPASTFunctionDefinition) {
|
||||
CPPASTFunctionDefinition definition = (CPPASTFunctionDefinition) parent;
|
||||
return definition.getDeclarator().getPointerOperators().length > 0;
|
||||
}
|
||||
} else if(hasDeclaration(function)) {
|
||||
IASTNode parent = function.getDeclarations()[0].getParent();
|
||||
if (parent instanceof CPPASTSimpleDeclaration) {
|
||||
CPPASTSimpleDeclaration declaration = (CPPASTSimpleDeclaration) parent;
|
||||
return declaration.getDeclarators().length > 0 && declaration.getDeclarators()[0].getPointerOperators().length > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean hasDeclaration(CPPFunction function) {
|
||||
return function != null && function.getDeclarations() != null && function.getDeclarations().length > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IASTNode createReturnAssignment(IASTNode node, IASTExpressionStatement stmt, IASTExpression callExpression) {
|
||||
return callExpression;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
/*******************************************************************************
|
||||
* 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.extractfunction;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Group;
|
||||
import org.eclipse.swt.widgets.Text;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.refactoring.MethodContext;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.dialogs.NameAndVisibilityComposite;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.utils.VisibilityEnum;
|
||||
|
||||
public class ExtractFunctionComposite extends Composite {
|
||||
|
||||
private Button replaceSimilar;
|
||||
private ChooserComposite comp;
|
||||
private NameAndVisibilityComposite nameVisiComp;
|
||||
private final ExtractFunctionInformation info;
|
||||
|
||||
public ExtractFunctionComposite(Composite parent, ExtractFunctionInformation info, ExtractFunctionInputPage ip) {
|
||||
super(parent, SWT.NONE);
|
||||
this.info = info;
|
||||
setLayout(new GridLayout());
|
||||
|
||||
createNewMethodNameComposite(this);
|
||||
|
||||
Group returnGroup = createReturnGroup(nameVisiComp);
|
||||
createReturnValueChooser(returnGroup, info, ip);
|
||||
|
||||
createReplaceCheckBox(nameVisiComp);
|
||||
|
||||
if (info.getMethodContext().getType() == MethodContext.ContextType.METHOD) {
|
||||
visibilityPanelSetVisible(true);
|
||||
}else {
|
||||
visibilityPanelSetVisible(false);
|
||||
}
|
||||
|
||||
layout();
|
||||
}
|
||||
|
||||
|
||||
private Group createReturnGroup(Composite parent) {
|
||||
Group returnGroup = new Group(parent,SWT.NONE);
|
||||
|
||||
returnGroup.setText(Messages.ExtractFunctionComposite_ReturnValue);
|
||||
returnGroup.setLayout(new GridLayout());
|
||||
GridData gridData = new GridData();
|
||||
gridData.horizontalAlignment = GridData.FILL;
|
||||
gridData.grabExcessHorizontalSpace = true;
|
||||
returnGroup.setLayoutData(gridData);
|
||||
return returnGroup;
|
||||
}
|
||||
|
||||
|
||||
private void createReturnValueChooser(Composite parent, ExtractFunctionInformation info, ExtractFunctionInputPage ip) {
|
||||
|
||||
GridData gridData = new GridData();
|
||||
gridData.horizontalAlignment = GridData.FILL;
|
||||
gridData.grabExcessHorizontalSpace = true;
|
||||
comp = new ChooserComposite(parent, info, ip);
|
||||
comp.setLayoutData(gridData);
|
||||
comp.redraw();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public Text getMethodNameText() {
|
||||
return nameVisiComp.getConstantNameText();
|
||||
}
|
||||
|
||||
public Button getReplaceSimilarButton() {
|
||||
return replaceSimilar;
|
||||
}
|
||||
|
||||
public void visibilityPanelSetVisible(boolean visible) {
|
||||
nameVisiComp.visibilityPanelsetVisible(visible);
|
||||
}
|
||||
|
||||
private void createNewMethodNameComposite(Composite parent) {
|
||||
|
||||
String label;
|
||||
if (info.getMethodContext().getType() == MethodContext.ContextType.METHOD) {
|
||||
label = Messages.ExtractFunctionComposite_MethodName;
|
||||
}else {
|
||||
label = Messages.ExtractFunctionComposite_FunctionName;
|
||||
}
|
||||
nameVisiComp = new NameAndVisibilityComposite(parent, label, VisibilityEnum.v_private, ""); //$NON-NLS-1$
|
||||
GridData gridData = new GridData();
|
||||
gridData.horizontalAlignment = GridData.FILL;
|
||||
gridData.grabExcessHorizontalSpace = true;
|
||||
nameVisiComp.setLayoutData(gridData);
|
||||
}
|
||||
|
||||
|
||||
private void createReplaceCheckBox(Composite parent) {
|
||||
replaceSimilar = new Button(parent, SWT.CHECK | SWT.LEFT);
|
||||
GridData buttonLayoutData = new GridData(SWT.None);
|
||||
buttonLayoutData.verticalIndent = 5;
|
||||
replaceSimilar.setLayoutData(buttonLayoutData);
|
||||
replaceSimilar.setText(Messages.ExtractFunctionComposite_ReplaceDuplicates);
|
||||
}
|
||||
|
||||
|
||||
public ChooserComposite getReturnChooser() {
|
||||
return comp;
|
||||
}
|
||||
|
||||
public String getMethodName(){
|
||||
return nameVisiComp.getConstantNameText().getText();
|
||||
}
|
||||
|
||||
|
||||
public Composite getVisibiltyGroup() {
|
||||
|
||||
return nameVisiComp.getVisibiltyGroup();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
/*******************************************************************************
|
||||
* 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.extractfunction;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.refactoring.MethodContext;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer.NameInformation;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.utils.VisibilityEnum;
|
||||
|
||||
|
||||
public class ExtractFunctionInformation {
|
||||
|
||||
public final int VISIBILITY_PRIVATE = 1;
|
||||
public final int VISIBILITY_PROTECTED = 3;
|
||||
public final int VISIBILITY_PUBLIC = 2;
|
||||
|
||||
private VisibilityEnum visibility = VisibilityEnum.v_private;
|
||||
private String methodName;
|
||||
private boolean replaceDuplicates;
|
||||
private Vector<NameInformation> allAfterUsedNames;
|
||||
private Vector<NameInformation> allUsedNames;
|
||||
private NameInformation inScopeDeclaredVariable;
|
||||
private NameInformation returnVariable;
|
||||
private ICPPASTFunctionDeclarator declarator;
|
||||
private MethodContext context;
|
||||
private boolean isExtractExpression;
|
||||
|
||||
/**
|
||||
* Returns the function declarator of the method / function from were the statements
|
||||
* are extacted from.
|
||||
* @return the function declarator or null
|
||||
*/
|
||||
public ICPPASTFunctionDeclarator getDeclarator() {
|
||||
return declarator;
|
||||
}
|
||||
|
||||
public void setDeclarator(ICPPASTFunctionDeclarator declarator) {
|
||||
this.declarator = declarator;
|
||||
}
|
||||
|
||||
public String getMethodName() {
|
||||
return methodName;
|
||||
}
|
||||
|
||||
public void setMethodName(String methodName) {
|
||||
this.methodName = methodName;
|
||||
}
|
||||
|
||||
public boolean isReplaceDuplicates() {
|
||||
return replaceDuplicates;
|
||||
}
|
||||
|
||||
public void setReplaceDuplicates(boolean replaceDuplicates) {
|
||||
this.replaceDuplicates = replaceDuplicates;
|
||||
}
|
||||
|
||||
public Vector<NameInformation> getAllAfterUsedNames() {
|
||||
if(allAfterUsedNames == null){
|
||||
allAfterUsedNames = new Vector<NameInformation>();
|
||||
for (NameInformation name : getAllUsedNames()) {
|
||||
if(name.isReference()||name.isReturnValue()){
|
||||
allAfterUsedNames.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allAfterUsedNames;
|
||||
}
|
||||
|
||||
public void setAllAfterUsedNames(Vector<NameInformation> allAfterUsedNames) {
|
||||
this.allAfterUsedNames = allAfterUsedNames;
|
||||
}
|
||||
|
||||
public NameInformation getReturnVariable() {
|
||||
return returnVariable;
|
||||
}
|
||||
|
||||
public void setReturnVariable(NameInformation returnVariable) {
|
||||
if(returnVariable != null) {
|
||||
returnVariable.setUserSetIsReturnValue(true);
|
||||
}
|
||||
this.returnVariable = returnVariable;
|
||||
}
|
||||
|
||||
public NameInformation getInScopeDeclaredVariable() {
|
||||
return inScopeDeclaredVariable;
|
||||
}
|
||||
|
||||
public void setInScopeDeclaredVariable(NameInformation inScopeDeclaredVariable) {
|
||||
this.inScopeDeclaredVariable = inScopeDeclaredVariable;
|
||||
}
|
||||
|
||||
public Vector<NameInformation> getAllUsedNames() {
|
||||
return allUsedNames;
|
||||
}
|
||||
|
||||
public void setAllUsedNames(Vector<NameInformation> allUsedNames) {
|
||||
this.allUsedNames = allUsedNames;
|
||||
}
|
||||
|
||||
public VisibilityEnum getVisibility() {
|
||||
return visibility;
|
||||
}
|
||||
|
||||
public void setVisibility(VisibilityEnum visibility) {
|
||||
this.visibility = visibility;
|
||||
}
|
||||
|
||||
public MethodContext getMethodContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
public void setMethodContext(MethodContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public boolean isExtractExpression() {
|
||||
return isExtractExpression;
|
||||
}
|
||||
|
||||
public void setExtractExpression(boolean isExtractExpression) {
|
||||
this.isExtractExpression = isExtractExpression;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
/*******************************************************************************
|
||||
* 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.extractfunction;
|
||||
|
||||
import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;
|
||||
import org.eclipse.swt.events.KeyEvent;
|
||||
import org.eclipse.swt.events.KeyListener;
|
||||
import org.eclipse.swt.events.MouseEvent;
|
||||
import org.eclipse.swt.events.MouseListener;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.events.SelectionListener;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.refactoring.utils.IdentifierHelper;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.utils.IdentifierResult;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.utils.VisibilityEnum;
|
||||
|
||||
|
||||
public class ExtractFunctionInputPage extends UserInputWizardPage {
|
||||
|
||||
private final ExtractFunctionInformation info;
|
||||
private ExtractFunctionComposite comp;
|
||||
protected final String NO_NAME_ERROR_LABEL = Messages.ExtractFunctionInputPage_EnterName;
|
||||
|
||||
|
||||
public ExtractFunctionInputPage(String name, ExtractFunctionInformation info) {
|
||||
super(name);
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public void createControl(final Composite parent) {
|
||||
|
||||
comp = new ExtractFunctionComposite(parent, info, this);
|
||||
|
||||
setPageComplete(false);
|
||||
|
||||
comp.getMethodNameText().addKeyListener(new KeyListener(){
|
||||
|
||||
public void keyPressed(KeyEvent e) {}
|
||||
|
||||
public void keyReleased(KeyEvent e) {
|
||||
info.setMethodName(comp.getMethodName());
|
||||
checkName();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
for (Control buttons : comp.getVisibiltyGroup().getChildren()) {
|
||||
buttons.addMouseListener(new MouseListener() {
|
||||
|
||||
public void mouseDoubleClick(MouseEvent e) {}
|
||||
|
||||
public void mouseDown(MouseEvent e) {}
|
||||
|
||||
public void mouseUp(MouseEvent e) {
|
||||
String text = ((Button)e.getSource()).getText();
|
||||
visibilityChange(text);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
comp.getReplaceSimilarButton().addSelectionListener(new SelectionListener(){
|
||||
|
||||
public void widgetDefaultSelected(SelectionEvent e) {
|
||||
info.setReplaceDuplicates(comp.getReplaceSimilarButton().isEnabled());
|
||||
}
|
||||
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
widgetDefaultSelected(e);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
setControl(comp);
|
||||
|
||||
}
|
||||
|
||||
protected void visibilityChange(String text) {
|
||||
info.setVisibility(VisibilityEnum.getEnumForStringRepresentation(text));
|
||||
|
||||
}
|
||||
|
||||
private void checkName() {
|
||||
|
||||
String methodName = comp.getMethodName();
|
||||
IdentifierResult result = IdentifierHelper.checkIdentifierName(methodName);
|
||||
if(result.isCorrect()){
|
||||
setErrorMessage(null);
|
||||
setPageComplete(true);
|
||||
}
|
||||
else{
|
||||
setErrorMessage(Messages.ExtractFunctionInputPage_CheckMethodName + result.getMessage());
|
||||
setPageComplete(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void errorWithAfterUsedVariable(String variableUsedAfterBlock ) {
|
||||
if(variableUsedAfterBlock == null) {
|
||||
setErrorMessage(null);
|
||||
checkName();
|
||||
}else {
|
||||
setErrorMessage("The parameter '" + variableUsedAfterBlock + "' " + Messages.ExtractFunctionInputPage_1); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,963 @@
|
|||
/*******************************************************************************
|
||||
* 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.extractfunction;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.ILog;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.OperationCanceledException;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.SubMonitor;
|
||||
import org.eclipse.jface.text.ITextSelection;
|
||||
import org.eclipse.jface.viewers.ISelection;
|
||||
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
|
||||
import org.eclipse.text.edits.TextEditGroup;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTComment;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IField;
|
||||
import org.eclipse.cdt.core.dom.ast.IParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTOperatorName;
|
||||
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.ICPPASTTemplateId;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
|
||||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
|
||||
import org.eclipse.cdt.internal.core.dom.parser.c.CASTBinaryExpression;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTCompoundStatement;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTDeclarator;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTExpressionList;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTExpressionStatement;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionCallExpression;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionDefinition;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTInitializerExpression;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTQualifiedName;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTReturnStatement;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclaration;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.refactoring.AddDeclarationNodeToClassChange;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.CRefactoring;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.Container;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.MethodContext;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.ModificationCollector;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.MethodContext.ContextType;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer.NameInformation;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.utils.ASTHelper;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.utils.CPPASTAllVisitor;
|
||||
|
||||
public class ExtractFunctionRefactoring extends CRefactoring {
|
||||
|
||||
// egtodo
|
||||
// private static final String COMMA_SPACE = ", "; //$NON-NLS-1$
|
||||
// private static final String TYPENAME = "typename "; //$NON-NLS-1$
|
||||
// private static final String TEMPLATE_START = "template <"; //$NON-NLS-1$
|
||||
|
||||
static final Integer NULL_INTEGER = Integer.valueOf(0);
|
||||
|
||||
NodeContainer container;
|
||||
final ExtractFunctionInformation info;
|
||||
|
||||
final Map<String, Integer> names;
|
||||
final Container<Integer> namesCounter;
|
||||
final Container<Integer> trailPos;
|
||||
private final Container<Integer> returnNumber;
|
||||
|
||||
protected boolean hasNameResolvingForSimilarError = false;
|
||||
|
||||
HashMap<String, Integer> nameTrail;
|
||||
|
||||
private ExtractedFunctionConstructionHelper extractedFunctionConstructionHelper;
|
||||
|
||||
public ExtractFunctionRefactoring(IFile file, ISelection selection,
|
||||
ExtractFunctionInformation info) {
|
||||
super(file, selection);
|
||||
this.info = info;
|
||||
name = Messages.ExtractFunctionRefactoring_ExtractFunction;
|
||||
names = new HashMap<String, Integer>();
|
||||
namesCounter = new Container<Integer>(NULL_INTEGER);
|
||||
trailPos = new Container<Integer>(NULL_INTEGER);
|
||||
returnNumber = new Container<Integer>(NULL_INTEGER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RefactoringStatus checkInitialConditions(IProgressMonitor pm)
|
||||
throws CoreException, OperationCanceledException {
|
||||
SubMonitor sm = SubMonitor.convert(pm, 10);
|
||||
RefactoringStatus status = super.checkInitialConditions(sm.newChild(6));
|
||||
|
||||
container = findExtractableNodes();
|
||||
sm.worked(1);
|
||||
|
||||
if (isProgressMonitorCanceld(sm, initStatus))
|
||||
return initStatus;
|
||||
|
||||
checkForNonExtractableStatements(container, status);
|
||||
sm.worked(1);
|
||||
|
||||
if (isProgressMonitorCanceld(sm, initStatus))
|
||||
return initStatus;
|
||||
|
||||
container.findAllNames();
|
||||
sm.worked(1);
|
||||
|
||||
if (isProgressMonitorCanceld(sm, initStatus))
|
||||
return initStatus;
|
||||
|
||||
container.getAllAfterUsedNames();
|
||||
info.setAllUsedNames(container.getUsedNamesUnique());
|
||||
|
||||
if (container.size() < 1) {
|
||||
status
|
||||
.addFatalError(Messages.ExtractFunctionRefactoring_NoStmtSelected);
|
||||
sm.done();
|
||||
return status;
|
||||
}
|
||||
|
||||
if (container.getAllDeclaredInScope().size() > 1) {
|
||||
status
|
||||
.addFatalError(Messages.ExtractFunctionRefactoring_TooManySelected);
|
||||
} else if (container.getAllDeclaredInScope().size() == 1) {
|
||||
info.setInScopeDeclaredVariable(container.getAllDeclaredInScope()
|
||||
.firstElement());
|
||||
}
|
||||
|
||||
extractedFunctionConstructionHelper = ExtractedFunctionConstructionHelper
|
||||
.createFor(container.getNodesToWrite());
|
||||
|
||||
boolean isExtractExpression = container.getNodesToWrite().get(0) instanceof IASTExpression;
|
||||
info.setExtractExpression(isExtractExpression);
|
||||
|
||||
if (isExtractExpression && container.getNodesToWrite().size() > 1) {
|
||||
status
|
||||
.addFatalError(Messages.ExtractFunctionRefactoring_TooManySelected);
|
||||
}
|
||||
|
||||
info.setDeclarator(getDeclaration(container.getNodesToWrite().get(0)));
|
||||
MethodContext context = findContext(container.getNodesToWrite().get(0));
|
||||
info.setMethodContext(context);
|
||||
sm.done();
|
||||
return status;
|
||||
}
|
||||
|
||||
private void checkForNonExtractableStatements(NodeContainer cont,
|
||||
RefactoringStatus status) {
|
||||
|
||||
NonExtractableStmtFinder vis = new NonExtractableStmtFinder();
|
||||
for (IASTNode node : cont.getNodesToWrite()) {
|
||||
node.accept(vis);
|
||||
if (vis.containsContinue()) {
|
||||
initStatus
|
||||
.addFatalError(Messages.ExtractFunctionRefactoring_Error_Continue);
|
||||
break;
|
||||
} else if (vis.containsBreak()) {
|
||||
initStatus
|
||||
.addFatalError(Messages.ExtractFunctionRefactoring_Error_Break);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnStatementFinder rFinder = new ReturnStatementFinder();
|
||||
for (IASTNode node : cont.getNodesToWrite()) {
|
||||
node.accept(rFinder);
|
||||
if (rFinder.containsReturn()) {
|
||||
initStatus
|
||||
.addFatalError(Messages.ExtractFunctionRefactoring_Error_Return);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private ICPPASTFunctionDeclarator getDeclaration(IASTNode node) {
|
||||
|
||||
while (node != null && !(node instanceof IASTFunctionDefinition)) {
|
||||
node = node.getParent();
|
||||
}
|
||||
if (node != null) {
|
||||
IASTFunctionDeclarator declarator = ((IASTFunctionDefinition) node)
|
||||
.getDeclarator();
|
||||
if (declarator instanceof ICPPASTFunctionDeclarator) {
|
||||
return (ICPPASTFunctionDeclarator) declarator;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RefactoringStatus checkFinalConditions(IProgressMonitor pm)
|
||||
throws CoreException, OperationCanceledException {
|
||||
RefactoringStatus status = super.checkFinalConditions(pm);
|
||||
|
||||
final IASTName astMethodName = new CPPASTName(info.getMethodName()
|
||||
.toCharArray());
|
||||
MethodContext context = findContext(container.getNodesToWrite().get(0));
|
||||
|
||||
if (context.getType() == ContextType.METHOD) {
|
||||
ICPPASTCompositeTypeSpecifier classDeclaration = (ICPPASTCompositeTypeSpecifier) context
|
||||
.getMethodDeclaration().getParent();
|
||||
IASTSimpleDeclaration methodDeclaration = getDeclaration(astMethodName);
|
||||
|
||||
if (isMethodAllreadyDefined(methodDeclaration, classDeclaration)) {
|
||||
status.addError(Messages.ExtractFunctionRefactoring_NameInUse);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
for (NameInformation name : info.getAllUsedNames()) {
|
||||
if (name.isUserSetIsReturnValue()) {
|
||||
info.setReturnVariable(name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void collectModifications(IProgressMonitor pm,
|
||||
ModificationCollector collector) throws CoreException,
|
||||
OperationCanceledException {
|
||||
final IASTName astMethodName = new CPPASTName(info.getMethodName()
|
||||
.toCharArray());
|
||||
|
||||
MethodContext context = findContext(container.getNodesToWrite().get(0));
|
||||
|
||||
// Create Declaration in Class
|
||||
if (context.getType() == ContextType.METHOD) {
|
||||
createMethodDeclaration(astMethodName, context, collector);
|
||||
}
|
||||
// Create Method Definition
|
||||
IASTNode firstNode = container.getNodesToWrite().get(0);
|
||||
IPath implPath = new Path(firstNode.getContainingFilename());
|
||||
final IFile implementationFile = ResourcesPlugin.getWorkspace()
|
||||
.getRoot().getFileForLocation(implPath);
|
||||
|
||||
createMethodDefinition(astMethodName, context, firstNode,
|
||||
implementationFile, collector);
|
||||
|
||||
createMethodCalls(astMethodName, implementationFile, context, collector);
|
||||
|
||||
}
|
||||
|
||||
private void createMethodCalls(final IASTName astMethodName,
|
||||
final IFile implementationFile, MethodContext context,
|
||||
ModificationCollector collector) throws CoreException {
|
||||
|
||||
String title;
|
||||
if (context.getType() == MethodContext.ContextType.METHOD) {
|
||||
title = Messages.ExtractFunctionRefactoring_CreateMethodCall;
|
||||
} else {
|
||||
title = Messages.ExtractFunctionRefactoring_CreateFunctionCall;
|
||||
}
|
||||
|
||||
IASTNode methodCall = getMethodCall(astMethodName);
|
||||
|
||||
IASTNode firstNodeToWrite = container.getNodesToWrite().get(0);
|
||||
ASTRewrite rewriter = collector
|
||||
.rewriterForTranslationUnit(firstNodeToWrite
|
||||
.getTranslationUnit());
|
||||
TextEditGroup editGroup = new TextEditGroup(title);
|
||||
rewriter.replace(firstNodeToWrite, methodCall, editGroup);
|
||||
for (IASTNode node : container.getNodesToWrite()) {
|
||||
if (node != firstNodeToWrite) {
|
||||
rewriter.remove(node, editGroup);
|
||||
}
|
||||
}
|
||||
|
||||
//Replace Dublicates not yet implemented
|
||||
/*
|
||||
* if(info.isReplaceDuplicates()){ replaceSimilar(astMethodName,
|
||||
* changesTreeSet, implementationFile, context.getType()); }
|
||||
*/
|
||||
}
|
||||
|
||||
private void createMethodDefinition(final IASTName astMethodName,
|
||||
MethodContext context, IASTNode firstNode,
|
||||
final IFile implementationFile, ModificationCollector collector) {
|
||||
|
||||
IASTNode node = firstNode;
|
||||
boolean found = false;
|
||||
boolean templateFunction = false;
|
||||
|
||||
while (node != null && !found) {
|
||||
node = node.getParent();
|
||||
if (node instanceof IASTFunctionDefinition) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (found && node != null) {
|
||||
templateFunction = node.getParent() instanceof ICPPASTTemplateDeclaration;
|
||||
|
||||
String title;
|
||||
if (context.getType() == MethodContext.ContextType.METHOD) {
|
||||
title = Messages.ExtractFunctionRefactoring_CreateMethodDef;
|
||||
} else {
|
||||
title = Messages.ExtractFunctionRefactoring_CreateFunctionDef;
|
||||
}
|
||||
|
||||
ASTRewrite rewriter = collector.rewriterForTranslationUnit(node
|
||||
.getTranslationUnit());
|
||||
getMethod(astMethodName, context, rewriter, node,
|
||||
new TextEditGroup(title));
|
||||
|
||||
if (templateFunction) {
|
||||
// egtodo
|
||||
// methodContent = getTemplateDeclarationString(
|
||||
// (ICPPASTTemplateDeclaration) node.getParent(),
|
||||
// getTemplateParameterNames())
|
||||
// + methodContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createMethodDeclaration(final IASTName astMethodName,
|
||||
MethodContext context, ModificationCollector collector) {
|
||||
ICPPASTCompositeTypeSpecifier classDeclaration = (ICPPASTCompositeTypeSpecifier) context
|
||||
.getMethodDeclaration().getParent();
|
||||
|
||||
IASTSimpleDeclaration methodDeclaration = getDeclaration(astMethodName);
|
||||
|
||||
AddDeclarationNodeToClassChange.createChange(classDeclaration, info
|
||||
.getVisibility(), methodDeclaration, false, collector);
|
||||
}
|
||||
|
||||
// egtodo
|
||||
// private Set<IASTName> getTemplateParameterNames() {
|
||||
// Set<IASTName> names = new TreeSet<IASTName>(new Comparator<IASTName>() {
|
||||
//
|
||||
// public int compare(IASTName o1, IASTName o2) {
|
||||
// return o1.toString().compareTo(o2.toString());
|
||||
// }
|
||||
// });
|
||||
// for (NameInformation nameInfo : container.getNames()) {
|
||||
// IASTName declName = nameInfo.getDeclaration();
|
||||
// IBinding binding = declName.resolveBinding();
|
||||
// if (binding instanceof CPPVariable) {
|
||||
// CPPVariable cppVariable = (CPPVariable) binding;
|
||||
// IASTNode defNode = cppVariable.getDefinition();
|
||||
// if (defNode.getParent().getParent() instanceof IASTSimpleDeclaration) {
|
||||
// IASTSimpleDeclaration decl = (IASTSimpleDeclaration) defNode
|
||||
// .getParent().getParent();
|
||||
// if (decl.getDeclSpecifier() instanceof CPPASTNamedTypeSpecifier) {
|
||||
// CPPASTNamedTypeSpecifier namedSpecifier = (CPPASTNamedTypeSpecifier) decl
|
||||
// .getDeclSpecifier();
|
||||
// if (namedSpecifier.getName().resolveBinding() instanceof CPPTemplateTypeParameter) {
|
||||
// names.add(namedSpecifier.getName());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// } else if (binding instanceof CPPParameter) {
|
||||
// CPPParameter parameter = (CPPParameter) binding;
|
||||
// IASTNode decNode = parameter.getDeclarations()[0];
|
||||
// if (decNode.getParent().getParent() instanceof ICPPASTParameterDeclaration) {
|
||||
// ICPPASTParameterDeclaration paraDecl = (ICPPASTParameterDeclaration) decNode
|
||||
// .getParent().getParent();
|
||||
// if (paraDecl.getDeclSpecifier() instanceof ICPPASTNamedTypeSpecifier) {
|
||||
// ICPPASTNamedTypeSpecifier namedDeclSpec = (ICPPASTNamedTypeSpecifier) paraDecl
|
||||
// .getDeclSpecifier();
|
||||
// if (namedDeclSpec.getName().resolveBinding() instanceof ICPPTemplateTypeParameter) {
|
||||
// names.add(namedDeclSpec.getName());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return names;
|
||||
// }
|
||||
//
|
||||
// private String getTemplateDeclarationString(
|
||||
// ICPPASTTemplateDeclaration templateDeclaration, Set<IASTName> names) {
|
||||
// if (names.isEmpty()) {
|
||||
// return EMPTY_STRING;
|
||||
// } else {
|
||||
// StringBuffer buf = new StringBuffer();
|
||||
//
|
||||
// buf.append(TEMPLATE_START);
|
||||
// for (Iterator<IASTName> it = names.iterator(); it.hasNext();) {
|
||||
// IASTName name = it.next();
|
||||
// buf.append(TYPENAME);
|
||||
// buf.append(name.toString());
|
||||
//
|
||||
// if (it.hasNext()) {
|
||||
// buf.append(COMMA_SPACE);
|
||||
// }
|
||||
// }
|
||||
// buf.append('>');
|
||||
// buf.append(CRefactoring.NEWLINE);
|
||||
//
|
||||
// return buf.toString();
|
||||
// }
|
||||
// }
|
||||
|
||||
private boolean isMethodAllreadyDefined(
|
||||
IASTSimpleDeclaration methodDeclaration,
|
||||
ICPPASTCompositeTypeSpecifier classDeclaration) {
|
||||
TrailNodeEqualityChecker equalityChecker = new TrailNodeEqualityChecker(
|
||||
names, namesCounter);
|
||||
|
||||
IBinding bind = classDeclaration.getName().resolveBinding();
|
||||
IASTStandardFunctionDeclarator declarator = (IASTStandardFunctionDeclarator) methodDeclaration
|
||||
.getDeclarators()[0];
|
||||
String name = new String(declarator.getName().toCharArray());
|
||||
if (bind instanceof ICPPClassType) {
|
||||
ICPPClassType classBind = (ICPPClassType) bind;
|
||||
try {
|
||||
IField[] fields = classBind.getFields();
|
||||
for (IField field : fields) {
|
||||
if (field.getName().equals(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
ICPPMethod[] methods = classBind.getAllDeclaredMethods();
|
||||
for (ICPPMethod method : methods) {
|
||||
if (!method.takesVarArgs() && name.equals(method.getName())) {
|
||||
IParameter[] parameters = method.getParameters();
|
||||
if (parameters.length == declarator.getParameters().length) {
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
IASTName[] origParameterName = unit
|
||||
.getDeclarationsInAST(parameters[i]);
|
||||
|
||||
IASTParameterDeclaration origParameter = (IASTParameterDeclaration) origParameterName[0]
|
||||
.getParent().getParent();
|
||||
IASTParameterDeclaration newParameter = declarator
|
||||
.getParameters()[i];
|
||||
|
||||
// if not the same break;
|
||||
if (!(equalityChecker.isEquals(origParameter
|
||||
.getDeclSpecifier(), newParameter
|
||||
.getDeclSpecifier()) && ASTHelper
|
||||
.samePointers(origParameter
|
||||
.getDeclarator()
|
||||
.getPointerOperators(),
|
||||
newParameter.getDeclarator()
|
||||
.getPointerOperators(),
|
||||
equalityChecker))) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(i < (parameters.length - 1))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} catch (DOMException e) {
|
||||
ILog logger = CUIPlugin.getDefault().getLog();
|
||||
IStatus status = new Status(IStatus.WARNING,
|
||||
CUIPlugin.PLUGIN_ID, IStatus.OK, e.getMessage(), e);
|
||||
|
||||
logger.log(status);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// egtodo
|
||||
// private int calculateLength(IASTFunctionDefinition node) {
|
||||
// int diff = 0;
|
||||
// if (node.getParent() instanceof ICPPASTTemplateDeclaration) {
|
||||
// ICPPASTTemplateDeclaration tempDec = (ICPPASTTemplateDeclaration) node
|
||||
// .getParent();
|
||||
// diff = node.getFileLocation().getNodeOffset()
|
||||
// - tempDec.getFileLocation().getNodeOffset();
|
||||
// }
|
||||
//
|
||||
// return diff;
|
||||
// }
|
||||
//
|
||||
// private void replaceSimilar(final IASTName astMethodName,
|
||||
// final ChangeTreeSet changesTreeSet, final IFile implementationFile,
|
||||
// final ContextType contextType) {
|
||||
// // Find similar code
|
||||
// final List<IASTNode> nodesToRewriteWithoutComments = new LinkedList<IASTNode>();
|
||||
//
|
||||
// for (IASTNode node : container.getNodesToWrite()) {
|
||||
// if (!(node instanceof IASTComment)) {
|
||||
// nodesToRewriteWithoutComments.add(node);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// final Vector<IASTNode> initTrail = getTrail(nodesToRewriteWithoutComments);
|
||||
// final String title;
|
||||
// if (contextType == MethodContext.ContextType.METHOD) {
|
||||
// title = Messages.ExtractFunctionRefactoring_CreateMethodCall;
|
||||
// } else {
|
||||
// title = Messages.ExtractFunctionRefactoring_CreateFunctionCall;
|
||||
// }
|
||||
//
|
||||
// if (!hasNameResolvingForSimilarError) {
|
||||
// unit.accept(new SimilarFinderVisitor(this, changesTreeSet,
|
||||
// initTrail, implementationFile, astMethodName,
|
||||
// nodesToRewriteWithoutComments, title));
|
||||
// }
|
||||
// }
|
||||
|
||||
protected Vector<IASTNode> getTrail(List<IASTNode> stmts) {
|
||||
final Vector<IASTNode> trail = new Vector<IASTNode>();
|
||||
|
||||
nameTrail = new HashMap<String, Integer>();
|
||||
final Container<Integer> trailCounter = new Container<Integer>(
|
||||
NULL_INTEGER);
|
||||
|
||||
for (IASTNode node : stmts) {
|
||||
node.accept(new CPPASTAllVisitor() {
|
||||
@Override
|
||||
public int visitAll(IASTNode node) {
|
||||
|
||||
if (node instanceof IASTComment) {
|
||||
// Visit Comment, but don't add them to the trail
|
||||
return super.visitAll(node);
|
||||
} else if (node instanceof IASTNamedTypeSpecifier) {
|
||||
// Skip if somewhere is a named Type Specifier
|
||||
trail.add(node);
|
||||
return PROCESS_SKIP;
|
||||
} else if (node instanceof IASTName) {
|
||||
if (node instanceof ICPPASTConversionName
|
||||
&& node instanceof ICPPASTOperatorName
|
||||
&& node instanceof ICPPASTTemplateId) {
|
||||
trail.add(node);
|
||||
return super.visitAll(node);
|
||||
}
|
||||
// Save Name Sequenz Number
|
||||
IASTName name = (IASTName) node;
|
||||
TrailName trailName = new TrailName();
|
||||
int actCount = trailCounter.getObject().intValue();
|
||||
if (nameTrail.containsKey(name.getRawSignature())) {
|
||||
Integer value = nameTrail.get(name
|
||||
.getRawSignature());
|
||||
actCount = value.intValue();
|
||||
} else {
|
||||
trailCounter.setObject(Integer
|
||||
.valueOf(++actCount));
|
||||
nameTrail.put(name.getRawSignature(),
|
||||
trailCounter.getObject());
|
||||
}
|
||||
trailName.setNameNumber(actCount);
|
||||
trailName.setRealName(name);
|
||||
|
||||
if (info.getReturnVariable() != null
|
||||
&& info.getReturnVariable().getName()
|
||||
.getRawSignature().equals(
|
||||
name.getRawSignature())) {
|
||||
returnNumber.setObject(Integer
|
||||
.valueOf(actCount));
|
||||
}
|
||||
|
||||
// Save type informations for the name
|
||||
IBinding bind = name.resolveBinding();
|
||||
IASTName[] declNames = name.getTranslationUnit()
|
||||
.getDeclarationsInAST(bind);
|
||||
if (declNames.length > 0) {
|
||||
IASTNode tmpNode = ASTHelper
|
||||
.getDeclarationForNode(declNames[0]);
|
||||
|
||||
IBinding declbind = declNames[0]
|
||||
.resolveBinding();
|
||||
if (declbind instanceof ICPPBinding) {
|
||||
ICPPBinding cppBind = (ICPPBinding) declbind;
|
||||
try {
|
||||
trailName.setGloballyQualified(cppBind
|
||||
.isGloballyQualified());
|
||||
} catch (DOMException e) {
|
||||
ILog logger = CUIPlugin.getDefault()
|
||||
.getLog();
|
||||
IStatus status = new Status(
|
||||
IStatus.WARNING,
|
||||
CUIPlugin.PLUGIN_ID,
|
||||
IStatus.OK, e.getMessage(), e);
|
||||
|
||||
logger.log(status);
|
||||
}
|
||||
}
|
||||
|
||||
if (tmpNode != null) {
|
||||
trailName.setDeclaration(tmpNode);
|
||||
} else {
|
||||
hasNameResolvingForSimilarError = true;
|
||||
}
|
||||
}
|
||||
|
||||
trail.add(trailName);
|
||||
return PROCESS_SKIP;
|
||||
} else {
|
||||
trail.add(node);
|
||||
return super.visitAll(node);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return trail;
|
||||
}
|
||||
|
||||
protected boolean isStatementInTrail(IASTStatement stmt,
|
||||
final Vector<IASTNode> trail) {
|
||||
final Container<Boolean> same = new Container<Boolean>(Boolean.TRUE);
|
||||
final TrailNodeEqualityChecker equalityChecker = new TrailNodeEqualityChecker(
|
||||
names, namesCounter);
|
||||
|
||||
stmt.accept(new CPPASTAllVisitor() {
|
||||
@Override
|
||||
public int visitAll(IASTNode node) {
|
||||
|
||||
int pos = trailPos.getObject().intValue();
|
||||
|
||||
if (trail.size() <= 0 || pos >= trail.size()) {
|
||||
same.setObject(Boolean.FALSE);
|
||||
return PROCESS_ABORT;
|
||||
}
|
||||
|
||||
if (node instanceof IASTComment) {
|
||||
// Visit Comment, but they are not in the trail
|
||||
return super.visitAll(node);
|
||||
}
|
||||
|
||||
IASTNode trailNode = trail.get(pos);
|
||||
trailPos.setObject(Integer.valueOf(pos + 1));
|
||||
|
||||
if (equalityChecker.isEquals(trailNode, node)) {
|
||||
if (node instanceof ICPPASTQualifiedName
|
||||
|| node instanceof IASTNamedTypeSpecifier) {
|
||||
return PROCESS_SKIP;
|
||||
}
|
||||
return super.visitAll(node);
|
||||
|
||||
}
|
||||
same.setObject(new Boolean(false));
|
||||
return PROCESS_ABORT;
|
||||
}
|
||||
});
|
||||
|
||||
return same.getObject().booleanValue();
|
||||
}
|
||||
|
||||
private void getMethod(IASTName astMethodName, MethodContext context,
|
||||
ASTRewrite rewriter, IASTNode insertpoint, TextEditGroup group) {
|
||||
ICPPASTQualifiedName qname = new CPPASTQualifiedName();
|
||||
if (context.getType() == ContextType.METHOD) {
|
||||
for (int i = 0; i < (context.getMethodQName().getNames().length - 1); i++) {
|
||||
qname.addName(context.getMethodQName().getNames()[i]);
|
||||
}
|
||||
}
|
||||
qname.addName(astMethodName);
|
||||
|
||||
IASTFunctionDefinition func = new CPPASTFunctionDefinition();
|
||||
func.setParent(unit);
|
||||
func.setDeclSpecifier(getReturnType());
|
||||
func.setDeclarator(extractedFunctionConstructionHelper
|
||||
.createFunctionDeclarator(qname, info.getDeclarator(), info
|
||||
.getReturnVariable(), container.getNodesToWrite(), info
|
||||
.getAllUsedNames()));
|
||||
|
||||
IASTCompoundStatement compound = new CPPASTCompoundStatement();
|
||||
func.setBody(compound);
|
||||
|
||||
ASTRewrite insertRW = rewriter.insertBefore(insertpoint.getParent(),
|
||||
insertpoint, func, group);
|
||||
insertRW = rewriter;
|
||||
|
||||
extractedFunctionConstructionHelper.constructMethodBody(compound,
|
||||
container.getNodesToWrite(), insertRW, group);
|
||||
|
||||
// Set return value
|
||||
if (info.getReturnVariable() != null) {
|
||||
IASTReturnStatement returnStmt = new CPPASTReturnStatement();
|
||||
if (info.getReturnVariable().getDeclaration().getParent() instanceof IASTExpression) {
|
||||
IASTExpression returnValue = (IASTExpression) info
|
||||
.getReturnVariable().getDeclaration().getParent();
|
||||
returnStmt.setReturnValue(returnValue);
|
||||
} else {
|
||||
IASTIdExpression expr = new CPPASTIdExpression();
|
||||
if (info.getReturnVariable().getUserSetName() == null) {
|
||||
expr.setName(newName(info.getReturnVariable().getName()));
|
||||
} else {
|
||||
expr.setName(new CPPASTName(info.getReturnVariable()
|
||||
.getUserSetName().toCharArray()));
|
||||
}
|
||||
returnStmt.setReturnValue(expr);
|
||||
}
|
||||
insertRW.insertBefore(compound, null, returnStmt, group);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private IASTName newName(IASTName declaration) {
|
||||
return new CPPASTName(declaration.toCharArray());
|
||||
}
|
||||
|
||||
private IASTDeclSpecifier getReturnType() {
|
||||
|
||||
IASTNode firstNodeToWrite = container.getNodesToWrite().get(0);
|
||||
NameInformation returnVariable = info.getReturnVariable();
|
||||
|
||||
return extractedFunctionConstructionHelper.determineReturnType(
|
||||
firstNodeToWrite, returnVariable);
|
||||
}
|
||||
|
||||
protected IASTNode getMethodCall(IASTName astMethodName,
|
||||
Map<String, Integer> trailNameTable,
|
||||
Map<String, Integer> similarNameTable, NodeContainer myContainer,
|
||||
NodeContainer mySimilarContainer) {
|
||||
IASTExpressionStatement stmt = new CPPASTExpressionStatement();
|
||||
IASTFunctionCallExpression callExpression = new CPPASTFunctionCallExpression();
|
||||
IASTIdExpression idExpression = new CPPASTIdExpression();
|
||||
idExpression.setName(astMethodName);
|
||||
IASTExpressionList paramList = new CPPASTExpressionList();
|
||||
|
||||
Vector<IASTName> declarations = new Vector<IASTName>();
|
||||
IASTName retName = null;
|
||||
boolean theRetName = false;
|
||||
|
||||
for (NameInformation nameInfo : myContainer.getNames()) {
|
||||
Integer trailSeqNumber = trailNameTable.get(nameInfo
|
||||
.getDeclaration().getRawSignature());
|
||||
String orgName = null;
|
||||
for (Entry<String, Integer> entry : similarNameTable.entrySet()) {
|
||||
if (entry.getValue().equals(trailSeqNumber)) {
|
||||
orgName = entry.getKey();
|
||||
if (info.getReturnVariable() != null
|
||||
&& trailSeqNumber.equals(returnNumber.getObject())) {
|
||||
theRetName = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (orgName != null) {
|
||||
boolean found = false;
|
||||
for (NameInformation simNameInfo : mySimilarContainer
|
||||
.getNames()) {
|
||||
if (orgName.equals(simNameInfo.getDeclaration()
|
||||
.getRawSignature())) {
|
||||
addAParameterIfPossible(paramList, declarations,
|
||||
simNameInfo);
|
||||
found = true;
|
||||
|
||||
if (theRetName) {
|
||||
theRetName = false;
|
||||
retName = new CPPASTName(simNameInfo
|
||||
.getDeclaration().getRawSignature()
|
||||
.toCharArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
// should be a field, use the old name
|
||||
IASTIdExpression expression = new CPPASTIdExpression();
|
||||
CPPASTName fieldName = new CPPASTName(orgName.toCharArray());
|
||||
expression.setName(fieldName);
|
||||
paramList.addExpression(expression);
|
||||
|
||||
if (theRetName) {
|
||||
theRetName = false;
|
||||
retName = fieldName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
callExpression.setParameterExpression(paramList);
|
||||
callExpression.setFunctionNameExpression(idExpression);
|
||||
|
||||
if (info.getReturnVariable() == null) {
|
||||
return getReturnAssignment(stmt, callExpression);
|
||||
}
|
||||
return getReturnAssignment(stmt, callExpression, retName);
|
||||
}
|
||||
|
||||
private IASTNode getMethodCall(IASTName astMethodName) {
|
||||
IASTExpressionStatement stmt = new CPPASTExpressionStatement();
|
||||
|
||||
IASTFunctionCallExpression callExpression = new CPPASTFunctionCallExpression();
|
||||
IASTIdExpression idExpression = new CPPASTIdExpression();
|
||||
idExpression.setName(astMethodName);
|
||||
IASTExpressionList paramList = getCallParameters();
|
||||
callExpression.setParameterExpression(paramList);
|
||||
callExpression.setFunctionNameExpression(idExpression);
|
||||
|
||||
if (info.getReturnVariable() == null) {
|
||||
return getReturnAssignment(stmt, callExpression);
|
||||
}
|
||||
IASTName retname = newName(info.getReturnVariable().getName());
|
||||
return getReturnAssignment(stmt, callExpression, retname);
|
||||
|
||||
}
|
||||
|
||||
private IASTNode getReturnAssignment(IASTExpressionStatement stmt,
|
||||
IASTFunctionCallExpression callExpression, IASTName retname) {
|
||||
if (info.getReturnVariable().equals(info.getInScopeDeclaredVariable())) {
|
||||
IASTSimpleDeclaration orgDecl = findSimpleDeclarationInParents(info
|
||||
.getReturnVariable().getDeclaration());
|
||||
IASTSimpleDeclaration decl = new CPPASTSimpleDeclaration();
|
||||
|
||||
decl.setDeclSpecifier(orgDecl.getDeclSpecifier());
|
||||
|
||||
IASTDeclarator declarator = new CPPASTDeclarator();
|
||||
|
||||
declarator.setName(retname);
|
||||
|
||||
for (IASTPointerOperator pointer : orgDecl.getDeclarators()[0]
|
||||
.getPointerOperators()) {
|
||||
declarator.addPointerOperator(pointer);
|
||||
}
|
||||
|
||||
IASTInitializerExpression initializer = new CPPASTInitializerExpression();
|
||||
initializer.setExpression(callExpression);
|
||||
declarator.setInitializer(initializer);
|
||||
|
||||
decl.addDeclarator(declarator);
|
||||
|
||||
return decl;
|
||||
}
|
||||
IASTBinaryExpression binaryExpression = new CASTBinaryExpression();
|
||||
binaryExpression.setOperator(IASTBinaryExpression.op_assign);
|
||||
IASTIdExpression nameExpression = new CPPASTIdExpression();
|
||||
|
||||
nameExpression.setName(retname);
|
||||
binaryExpression.setOperand1(nameExpression);
|
||||
binaryExpression.setOperand2(callExpression);
|
||||
|
||||
return getReturnAssignment(stmt, binaryExpression);
|
||||
}
|
||||
|
||||
private IASTNode getReturnAssignment(IASTExpressionStatement stmt,
|
||||
IASTExpression callExpression) {
|
||||
|
||||
IASTNode node = container.getNodesToWrite().get(0);
|
||||
return extractedFunctionConstructionHelper.createReturnAssignment(node,
|
||||
stmt, callExpression);
|
||||
|
||||
}
|
||||
|
||||
private IASTSimpleDeclaration getDeclaration(IASTName name) {
|
||||
IASTSimpleDeclaration simpleDecl = new CPPASTSimpleDeclaration();
|
||||
simpleDecl.setParent(unit);
|
||||
IASTDeclSpecifier declSpec = getReturnType();
|
||||
simpleDecl.setDeclSpecifier(declSpec);
|
||||
IASTStandardFunctionDeclarator declarator = extractedFunctionConstructionHelper
|
||||
.createFunctionDeclarator(name, info.getDeclarator(), info
|
||||
.getReturnVariable(), container.getNodesToWrite(), info
|
||||
.getAllUsedNames());
|
||||
simpleDecl.addDeclarator(declarator);
|
||||
return simpleDecl;
|
||||
}
|
||||
|
||||
private NodeContainer findExtractableNodes() {
|
||||
final NodeContainer container = new NodeContainer();
|
||||
if (selection instanceof ITextSelection) {
|
||||
final ITextSelection textSelection = (ITextSelection) selection;
|
||||
|
||||
unit.accept(new CPPASTVisitor() {
|
||||
|
||||
{
|
||||
shouldVisitStatements = true;
|
||||
shouldVisitExpressions = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int visit(IASTStatement stmt) {
|
||||
if (!(stmt instanceof IASTCompoundStatement)
|
||||
&& isSelectedFile(textSelection, stmt)) {
|
||||
container.add(stmt);
|
||||
return PROCESS_SKIP;
|
||||
}
|
||||
return super.visit(stmt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int visit(IASTExpression expression) {
|
||||
if (isSelectedFile(textSelection, expression)) {
|
||||
container.add(expression);
|
||||
return PROCESS_SKIP;
|
||||
}
|
||||
return super.visit(expression);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
public IASTExpressionList getCallParameters() {
|
||||
IASTExpressionList paramList = new CPPASTExpressionList();
|
||||
Vector<IASTName> declarations = new Vector<IASTName>();
|
||||
for (NameInformation nameInf : container.getNames()) {
|
||||
addAParameterIfPossible(paramList, declarations, nameInf);
|
||||
}
|
||||
return paramList;
|
||||
}
|
||||
|
||||
private void addAParameterIfPossible(IASTExpressionList paramList,
|
||||
Vector<IASTName> declarations, NameInformation nameInf) {
|
||||
if (!nameInf.isDeclarationInScope()) {
|
||||
IASTName declaration = nameInf.getDeclaration();
|
||||
if (!declarations.contains(declaration)) {
|
||||
declarations.add(declaration);
|
||||
IASTIdExpression expression = new CPPASTIdExpression();
|
||||
expression.setName(newName(declaration));
|
||||
paramList.addExpression(expression);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*******************************************************************************
|
||||
* 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.extractfunction;
|
||||
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.jface.viewers.ISelection;
|
||||
import org.eclipse.jface.window.IShellProvider;
|
||||
import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.refactoring.CRefactoring;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.RefactoringRunner;
|
||||
|
||||
/**
|
||||
* @author Emanuel Graf
|
||||
*
|
||||
*/
|
||||
public class ExtractFunctionRefactoringRunner extends RefactoringRunner {
|
||||
|
||||
public ExtractFunctionRefactoringRunner(IFile file, ISelection selection, IShellProvider shellProvider) {
|
||||
super(file, selection, shellProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
ExtractFunctionInformation info = new ExtractFunctionInformation();
|
||||
|
||||
CRefactoring refactoring = new ExtractFunctionRefactoring(file,selection,info);
|
||||
ExtractFunctionRefactoringWizard wizard = new ExtractFunctionRefactoringWizard(refactoring,info);
|
||||
RefactoringWizardOpenOperation operator = new RefactoringWizardOpenOperation(wizard);
|
||||
|
||||
try {
|
||||
operator.run(shellProvider.getShell(), refactoring.getName());
|
||||
} catch (InterruptedException e) {
|
||||
//initial condition checking got canceled by the user.
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*******************************************************************************
|
||||
* 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.extractfunction;
|
||||
|
||||
import org.eclipse.ltk.core.refactoring.Refactoring;
|
||||
import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
|
||||
import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;
|
||||
|
||||
public class ExtractFunctionRefactoringWizard extends RefactoringWizard {
|
||||
|
||||
private ExtractFunctionInformation info;
|
||||
|
||||
public ExtractFunctionRefactoringWizard(Refactoring refactoring, ExtractFunctionInformation info) {
|
||||
super(refactoring, WIZARD_BASED_USER_INTERFACE);
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addUserInputPages() {
|
||||
UserInputWizardPage page = new ExtractFunctionInputPage(Messages.ExtractFunctionRefactoringWizard_FunctionName,info);
|
||||
page.setTitle(Messages.ExtractFunctionRefactoringWizard_FunctionName);
|
||||
addPage(page);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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.extractfunction;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.text.edits.TextEditGroup;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
|
||||
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclSpecifier;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer.NameInformation;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.utils.ASTHelper;
|
||||
|
||||
/**
|
||||
* @author Mirko Stocker
|
||||
*
|
||||
*/
|
||||
public class ExtractStatement extends ExtractedFunctionConstructionHelper {
|
||||
|
||||
@Override
|
||||
public void constructMethodBody(IASTCompoundStatement compound,
|
||||
List<IASTNode> list, ASTRewrite rewrite, TextEditGroup group) {
|
||||
|
||||
for (IASTNode each : list) {
|
||||
rewrite.insertBefore(compound, null, each, group);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IASTDeclSpecifier determineReturnType(IASTNode extractedNode, NameInformation returnVariable) {
|
||||
|
||||
if(returnVariable != null) {
|
||||
IASTNode decl = ASTHelper.getDeclarationForNode(returnVariable.getDeclaration());
|
||||
return ASTHelper.getDeclarationSpecifier(decl);
|
||||
}
|
||||
IASTDeclSpecifier declSpec = new CPPASTSimpleDeclSpecifier();
|
||||
((IASTSimpleDeclSpecifier)declSpec).setType(IASTSimpleDeclSpecifier.t_void);
|
||||
return declSpec;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IASTNode createReturnAssignment(IASTNode node, IASTExpressionStatement stmt, IASTExpression callExpression) {
|
||||
stmt.setExpression(callExpression);
|
||||
return stmt;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/*******************************************************************************
|
||||
* 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.extractfunction;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.text.edits.TextEditGroup;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration;
|
||||
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
|
||||
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionDeclarator;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTPointer;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer.NameInformation;
|
||||
|
||||
/**
|
||||
* @author Mirko Stocker
|
||||
*
|
||||
*/
|
||||
public abstract class ExtractedFunctionConstructionHelper {
|
||||
|
||||
public static ExtractedFunctionConstructionHelper createFor (List<IASTNode> list) {
|
||||
if(list.get(0) instanceof IASTExpression) {
|
||||
return new ExtractExpression();
|
||||
}
|
||||
return new ExtractStatement();
|
||||
}
|
||||
|
||||
public abstract void constructMethodBody(IASTCompoundStatement compound,
|
||||
List<IASTNode> list, ASTRewrite rewrite, TextEditGroup group);
|
||||
|
||||
public abstract IASTDeclSpecifier determineReturnType(IASTNode extractedNode, NameInformation returnVariable);
|
||||
|
||||
public abstract IASTNode createReturnAssignment(IASTNode node, IASTExpressionStatement stmt, IASTExpression callExpression);
|
||||
|
||||
protected boolean isReturnTypeAPointer(IASTNode node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
IASTStandardFunctionDeclarator createFunctionDeclarator(IASTName name, ICPPASTFunctionDeclarator functionDeclarator, NameInformation returnVariable, List<IASTNode> nodesToWrite, Collection<NameInformation> allUsedNames) {
|
||||
ICPPASTFunctionDeclarator declarator = new CPPASTFunctionDeclarator();
|
||||
declarator.setName(name);
|
||||
|
||||
if(functionDeclarator != null && functionDeclarator.isConst()) {
|
||||
declarator.setConst(true);
|
||||
}
|
||||
|
||||
if(returnVariable != null) {
|
||||
IASTDeclarator decl = (IASTDeclarator) returnVariable.getDeclaration().getParent();
|
||||
IASTPointerOperator[] pointers = decl.getPointerOperators();
|
||||
for (IASTPointerOperator operator : pointers) {
|
||||
declarator.addPointerOperator(operator);
|
||||
}
|
||||
}
|
||||
|
||||
for (ICPPASTParameterDeclaration param : getParameterDeclarations(allUsedNames)) {
|
||||
declarator.addParameterDeclaration(param);
|
||||
}
|
||||
|
||||
if(isReturnTypeAPointer(nodesToWrite.get(0))) {
|
||||
declarator.addPointerOperator(new CPPASTPointer());
|
||||
}
|
||||
|
||||
return declarator;
|
||||
}
|
||||
|
||||
public Collection<ICPPASTParameterDeclaration> getParameterDeclarations(Collection<NameInformation> allUsedNames) {
|
||||
Collection<ICPPASTParameterDeclaration> result = new ArrayList<ICPPASTParameterDeclaration>();
|
||||
for (NameInformation name : allUsedNames) {
|
||||
if(!name.isDeclarationInScope()){
|
||||
result.add(name.getICPPASTParameterDeclaration(name.isUserSetIsReference()));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*******************************************************************************
|
||||
* 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.extractfunction;
|
||||
|
||||
import org.eclipse.osgi.util.NLS;
|
||||
|
||||
public final class Messages extends NLS {
|
||||
|
||||
private static final String BUNDLE_NAME = "org.eclipse.cdt.internal.ui.refactoring.extractfunction.messages";//$NON-NLS-1$
|
||||
|
||||
private Messages() {
|
||||
// Do not instantiate
|
||||
}
|
||||
|
||||
public static String ExtractFunctionRefactoringWizard_FunctionName;
|
||||
public static String ExtractFunctionRefactoring_ExtractFunction;
|
||||
public static String ExtractFunctionRefactoring_NoStmtSelected;
|
||||
public static String ExtractFunctionRefactoring_TooManySelected;
|
||||
public static String ExtractFunctionRefactoring_NameInUse;
|
||||
public static String ExtractFunctionComposite_MethodName;
|
||||
public static String ExtractFunctionComposite_FunctionName;
|
||||
public static String ExtractFunctionInputPage_EnterName;
|
||||
public static String ExtractFunctionInputPage_CheckMethodName;
|
||||
public static String ExtractFunctionInputPage_1;
|
||||
public static String ExtractFunctionComposite_ReturnValue;
|
||||
public static String ExtractFunctionRefactoring_CreateMethodDef;
|
||||
public static String ExtractFunctionRefactoring_CreateFunctionDef;
|
||||
public static String ExtractFunctionComposite_ReplaceDuplicates;
|
||||
public static String ExtractFunctionRefactoring_CreateMethodCall;
|
||||
public static String ExtractFunctionRefactoring_CreateFunctionCall;
|
||||
public static String ChooserComposite_Return;
|
||||
public static String ChooserComposite_CallByRef;
|
||||
public static String ChooserComposite_Name;
|
||||
public static String ChooserComposite_Type;
|
||||
public static String ChooserComposite_NoReturnValue;
|
||||
public static String ExtractFunctionRefactoring_Error_Return;
|
||||
public static String ExtractFunctionRefactoring_Error_Continue;
|
||||
public static String ExtractFunctionRefactoring_Error_Break;
|
||||
|
||||
static {
|
||||
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*******************************************************************************
|
||||
* 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.extractfunction;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTBreakStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTContinueStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDoStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTForStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTWhileStatement;
|
||||
|
||||
/**
|
||||
* @author Emanuel Graf IFS
|
||||
*
|
||||
*/
|
||||
class NonExtractableStmtFinder extends ASTVisitor{
|
||||
|
||||
private boolean containsContinueStmt = false;
|
||||
private boolean containsBreakStmt = false;
|
||||
|
||||
{
|
||||
shouldVisitStatements = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int visit(IASTStatement statement) {
|
||||
if (statement instanceof IASTContinueStatement) {
|
||||
containsContinueStmt = true;
|
||||
return ASTVisitor.PROCESS_SKIP;
|
||||
}else if (statement instanceof IASTBreakStatement) {
|
||||
containsBreakStmt = true;
|
||||
return ASTVisitor.PROCESS_SKIP;
|
||||
}else if(statement instanceof IASTForStatement|| //Extracting hole loop statements is ok
|
||||
statement instanceof IASTWhileStatement||
|
||||
statement instanceof IASTSwitchStatement||
|
||||
statement instanceof IASTDoStatement) {
|
||||
return ASTVisitor.PROCESS_SKIP;
|
||||
}
|
||||
return ASTVisitor.PROCESS_CONTINUE;
|
||||
}
|
||||
|
||||
public boolean containsContinue() {
|
||||
return containsContinueStmt;
|
||||
}
|
||||
|
||||
public boolean containsBreak() {
|
||||
return containsBreakStmt;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*******************************************************************************
|
||||
* 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.extractfunction;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||
|
||||
/**
|
||||
* @author Emanuel Graf IFS
|
||||
*
|
||||
*/
|
||||
class ReturnStatementFinder extends ASTVisitor{
|
||||
|
||||
private boolean containsReturnStmt = false;
|
||||
|
||||
|
||||
{
|
||||
shouldVisitStatements = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int visit(IASTStatement statement) {
|
||||
if (statement instanceof IASTReturnStatement) {
|
||||
containsReturnStmt = true;
|
||||
return ASTVisitor.PROCESS_SKIP;
|
||||
}
|
||||
return ASTVisitor.PROCESS_CONTINUE;
|
||||
}
|
||||
|
||||
public boolean containsReturn() {
|
||||
return containsReturnStmt;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
/*******************************************************************************
|
||||
* 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.extractfunction;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.eclipse.core.resources.IFile;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.refactoring.ChangeTreeSet;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer.NameInformation;
|
||||
|
||||
final class SimilarFinderVisitor extends CPPASTVisitor {
|
||||
|
||||
private final ExtractFunctionRefactoring extractFunctionRefactoring;
|
||||
|
||||
// egtodo
|
||||
// private final ChangeTreeSet set;
|
||||
// private final IFile file;
|
||||
// private final IASTName name;
|
||||
|
||||
private final Vector<IASTNode> trail;
|
||||
private final List<IASTNode> stmts;
|
||||
private int i = 0;
|
||||
// private int start;
|
||||
private NodeContainer similarContainer;
|
||||
// private final String title;
|
||||
|
||||
SimilarFinderVisitor(ExtractFunctionRefactoring extractFunctionRefactoring, ChangeTreeSet set, Vector<IASTNode> trail, IFile file, IASTName name, List<IASTNode> stmts, String title) {
|
||||
this.extractFunctionRefactoring = extractFunctionRefactoring;
|
||||
// this.set = set;
|
||||
this.trail = trail;
|
||||
// this.file = file;
|
||||
// this.name = name;
|
||||
this.stmts = stmts;
|
||||
// this.title = title;
|
||||
|
||||
this.similarContainer = new NodeContainer();
|
||||
}
|
||||
|
||||
{
|
||||
shouldVisitStatements = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int visit(IASTStatement stmt) {
|
||||
|
||||
boolean isAllreadyInMainRefactoring = isInSelection(stmt);
|
||||
|
||||
if( (!isAllreadyInMainRefactoring)
|
||||
&& this.extractFunctionRefactoring.isStatementInTrail(stmt, trail)){
|
||||
if(i == 0){
|
||||
// start = stmt.getFileLocation().getNodeOffset();
|
||||
}
|
||||
similarContainer.add(stmt);
|
||||
++i;
|
||||
|
||||
if(i==stmts.size()){
|
||||
//found similar code
|
||||
|
||||
boolean similarOnReturnWays = true;
|
||||
for (NameInformation nameInfo : similarContainer.getAllAfterUsedNames()) {
|
||||
if(this.extractFunctionRefactoring.names.containsKey(nameInfo.getDeclaration().getRawSignature())){
|
||||
Integer nameOrderNumber = this.extractFunctionRefactoring.names.get(nameInfo.getDeclaration().getRawSignature());
|
||||
if(this.extractFunctionRefactoring.nameTrail.containsValue(nameOrderNumber)){
|
||||
String orgName = null;
|
||||
boolean found = false;
|
||||
for (Entry<String, Integer> entry : this.extractFunctionRefactoring.nameTrail.entrySet()) {
|
||||
if(entry.getValue().equals(nameOrderNumber)){
|
||||
orgName = entry.getKey();
|
||||
}
|
||||
}
|
||||
if(orgName != null){
|
||||
for (NameInformation orgNameInfo : this.extractFunctionRefactoring.container.getAllAfterUsedNamesChoosenByUser()) {
|
||||
if( orgName.equals(orgNameInfo.getDeclaration().getRawSignature()) ){
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!found){
|
||||
similarOnReturnWays = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (similarOnReturnWays) {
|
||||
// egtodo
|
||||
// CTextFileChange replace = new CTextFileChange(title, file);
|
||||
// IASTFileLocation loc = stmt.getFileLocation();
|
||||
// int end = loc.getNodeOffset() + loc.getNodeLength() - start;
|
||||
// try {
|
||||
// end = this.extractFunctionRefactoring
|
||||
// .getLengthWithNewLine(file, start, loc
|
||||
// .getNodeOffset()
|
||||
// + loc.getNodeLength() - start);
|
||||
// } catch (CoreException e) {
|
||||
// // Keep current length
|
||||
// }
|
||||
// ReplaceEdit replaceEdit = new ReplaceEdit(start, end,
|
||||
// this.extractFunctionRefactoring.getMethodCall(name,
|
||||
// this.extractFunctionRefactoring.nameTrail,
|
||||
// this.extractFunctionRefactoring.names,
|
||||
// this.extractFunctionRefactoring.container,
|
||||
// similarContainer));
|
||||
// replace.setEdit(replaceEdit);
|
||||
// set.add(replace);
|
||||
}
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
return PROCESS_SKIP;
|
||||
}
|
||||
clear();
|
||||
return super.visit(stmt);
|
||||
|
||||
}
|
||||
|
||||
private boolean isInSelection(IASTStatement stmt) {
|
||||
List<IASTNode>nodes = this.extractFunctionRefactoring.container.getNodesToWrite();
|
||||
for (IASTNode node : nodes) {
|
||||
if(node.equals(stmt)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
// return container.getNodesToWrite().contains(stmt);
|
||||
}
|
||||
|
||||
private void clear() {
|
||||
i = 0;
|
||||
this.extractFunctionRefactoring.names.clear();
|
||||
similarContainer = new NodeContainer();
|
||||
this.extractFunctionRefactoring.namesCounter.setObject(ExtractFunctionRefactoring.NULL_INTEGER);
|
||||
this.extractFunctionRefactoring.trailPos.setObject(ExtractFunctionRefactoring.NULL_INTEGER);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/*******************************************************************************
|
||||
* 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.extractfunction;
|
||||
|
||||
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.internal.core.dom.parser.cpp.CPPASTName;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.refactoring.utils.ASTHelper;
|
||||
|
||||
class TrailName extends CPPASTName {
|
||||
|
||||
private int nameNumber;
|
||||
private IASTNode declaration = null;
|
||||
private IASTName realName = null;
|
||||
private boolean isGloballyQualified = false;
|
||||
|
||||
@Override
|
||||
public String getRawSignature() {
|
||||
return realName.getRawSignature();
|
||||
}
|
||||
|
||||
public int getNameNumber() {
|
||||
return nameNumber;
|
||||
}
|
||||
|
||||
public void setNameNumber(int nameNumber) {
|
||||
this.nameNumber = nameNumber;
|
||||
}
|
||||
|
||||
public IASTNode getDeclaration() {
|
||||
return declaration;
|
||||
}
|
||||
|
||||
public void setDeclaration(IASTNode declaration) {
|
||||
this.declaration = declaration;
|
||||
}
|
||||
|
||||
public IASTDeclSpecifier getDeclSpecifier() {
|
||||
return ASTHelper.getDeclarationSpecifier(declaration);
|
||||
}
|
||||
|
||||
public IASTName getRealName() {
|
||||
return realName;
|
||||
}
|
||||
|
||||
public void setRealName(IASTName realName) {
|
||||
this.realName = realName;
|
||||
}
|
||||
|
||||
public boolean isGloballyQualified() {
|
||||
return isGloballyQualified;
|
||||
}
|
||||
|
||||
public void setGloballyQualified(boolean isGloballyQualified) {
|
||||
this.isGloballyQualified = isGloballyQualified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return realName.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,458 @@
|
|||
/*******************************************************************************
|
||||
* 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.extractfunction;
|
||||
|
||||
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTASMDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPointer;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.c.ICASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.c.ICASTPointer;
|
||||
import org.eclipse.cdt.core.dom.ast.c.ICASTSimpleDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTOperatorName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeConstructorExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypenameExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisiblityLabel;
|
||||
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTExplicitTemplateInstantiation;
|
||||
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointer;
|
||||
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTSimpleDeclSpecifier;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.refactoring.Container;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.EqualityChecker;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.utils.ASTHelper;
|
||||
|
||||
public class TrailNodeEqualityChecker implements EqualityChecker<IASTNode> {
|
||||
|
||||
private final Map<String, Integer> names;
|
||||
private final Container<Integer> namesCounter;
|
||||
|
||||
public TrailNodeEqualityChecker(Map<String, Integer> names, Container<Integer> namesCounter) {
|
||||
super();
|
||||
this.names = names;
|
||||
this.namesCounter = namesCounter;
|
||||
}
|
||||
|
||||
public boolean isEquals(IASTNode trailNode, IASTNode node) {
|
||||
if( (trailNode instanceof TrailName && node instanceof IASTName)
|
||||
|| Arrays.equals(getInterfaces(node), getInterfaces(trailNode)) ) {
|
||||
//Is same type
|
||||
if(node instanceof IASTExpression){
|
||||
return isExpressionEquals(trailNode, node);
|
||||
} else if(node instanceof IASTStatement){
|
||||
return isStatementEquals(trailNode, node);
|
||||
} else if(node instanceof IASTPointerOperator){
|
||||
return isPointerOperatorEquals(trailNode, node);
|
||||
} else if(node instanceof IASTDeclaration){
|
||||
return isDeclarationEquals(trailNode, node);
|
||||
} else if(node instanceof IASTDeclarator){
|
||||
return isDeclaratorEquals(trailNode, node);
|
||||
} else if(node instanceof IASTInitializer){
|
||||
//no speciality, is the same type return true
|
||||
return true;
|
||||
} else if(node instanceof IASTDeclSpecifier){
|
||||
return isDeclSpecifierEquals(trailNode, node);
|
||||
} else if(node instanceof IASTName){
|
||||
return isNameEquals(trailNode, node);
|
||||
} else {
|
||||
assert true : "Unexpected Node, this code shoud nod reached"; //$NON-NLS-1$
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
private boolean isNameEquals(IASTNode trailNode, IASTNode node) {
|
||||
if(trailNode instanceof ICPPASTConversionName) {
|
||||
return true;
|
||||
} else if(trailNode instanceof ICPPASTOperatorName) {
|
||||
ICPPASTOperatorName trailName= ( ICPPASTOperatorName )trailNode;
|
||||
ICPPASTOperatorName name = ( ICPPASTOperatorName )node;
|
||||
|
||||
return trailName.equals(name);
|
||||
} else if(trailNode instanceof TrailName && node instanceof IASTName) {
|
||||
TrailName trailName = (TrailName) trailNode;
|
||||
IASTName name = (IASTName)node;
|
||||
|
||||
return isNameEquals(trailName, name);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isDeclSpecifierEquals(IASTNode trailNode, IASTNode node) {
|
||||
if (trailNode instanceof IGPPASTSimpleDeclSpecifier) {
|
||||
IGPPASTSimpleDeclSpecifier trailSimpleDecl = (IGPPASTSimpleDeclSpecifier) trailNode;
|
||||
IGPPASTSimpleDeclSpecifier simpleDecl = (IGPPASTSimpleDeclSpecifier) node;
|
||||
|
||||
return isSimpleDeclSpecifierEquals(trailSimpleDecl, simpleDecl)
|
||||
&& trailSimpleDecl.isComplex() == simpleDecl.isComplex()
|
||||
&& trailSimpleDecl.isImaginary() == simpleDecl.isImaginary()
|
||||
&& trailSimpleDecl.isLongLong() == simpleDecl.isLongLong()
|
||||
&& trailSimpleDecl.isComplex() == simpleDecl.isComplex()
|
||||
&& trailSimpleDecl.isExplicit() == simpleDecl.isExplicit()
|
||||
&& trailSimpleDecl.isFriend() == simpleDecl.isFriend();
|
||||
} else if (trailNode instanceof IGPPASTDeclSpecifier) {
|
||||
IGPPASTDeclSpecifier trailDecl = (IGPPASTDeclSpecifier) trailNode;
|
||||
IGPPASTDeclSpecifier decl = (IGPPASTDeclSpecifier) node;
|
||||
|
||||
return isDeclSpecifierEquals(trailDecl, decl)
|
||||
&& trailDecl.isRestrict() == decl.isRestrict();
|
||||
} else if (trailNode instanceof ICASTSimpleDeclSpecifier) {
|
||||
ICASTSimpleDeclSpecifier trailDecl = (ICASTSimpleDeclSpecifier) trailNode;
|
||||
ICASTSimpleDeclSpecifier decl = (ICASTSimpleDeclSpecifier) node;
|
||||
|
||||
return isSimpleDeclSpecifierEquals(trailDecl, decl)
|
||||
&& trailDecl.isRestrict() == decl.isRestrict()
|
||||
&& trailDecl.isComplex() == decl.isComplex()
|
||||
&& trailDecl.isImaginary() == decl.isImaginary()
|
||||
&& trailDecl.isLongLong() == decl.isLongLong();
|
||||
} else if (trailNode instanceof IASTSimpleDeclSpecifier) {
|
||||
IASTSimpleDeclSpecifier trailDecl = (IASTSimpleDeclSpecifier) trailNode;
|
||||
IASTSimpleDeclSpecifier decl = (IASTSimpleDeclSpecifier) node;
|
||||
|
||||
return isSimpleDeclSpecifierEquals(trailDecl, decl);
|
||||
} else if (trailNode instanceof ICPPASTNamedTypeSpecifier) {
|
||||
ICPPASTNamedTypeSpecifier trailDecl = (ICPPASTNamedTypeSpecifier) trailNode;
|
||||
ICPPASTNamedTypeSpecifier decl = (ICPPASTNamedTypeSpecifier) node;
|
||||
|
||||
|
||||
boolean isSame = isDeclSpecifierEquals(trailDecl, decl)
|
||||
&& isSameNamedTypeSpecifierName(trailDecl, decl)
|
||||
&& trailDecl.isTypename() == decl.isTypename()
|
||||
&& trailDecl.isExplicit() == decl.isExplicit()
|
||||
&& trailDecl.isFriend() == decl.isFriend()
|
||||
&& trailDecl.isVirtual() == decl.isVirtual();
|
||||
return isSame;
|
||||
} else if (trailNode instanceof IASTNamedTypeSpecifier) {
|
||||
IASTNamedTypeSpecifier trailDecl = (IASTNamedTypeSpecifier) trailNode;
|
||||
IASTNamedTypeSpecifier decl = (IASTNamedTypeSpecifier) node;
|
||||
|
||||
return isDeclSpecifierEquals(trailDecl, decl)
|
||||
&& isSameNamedTypeSpecifierName(trailDecl, decl);
|
||||
} else if (trailNode instanceof IASTElaboratedTypeSpecifier) {
|
||||
IASTElaboratedTypeSpecifier trailDecl = (IASTElaboratedTypeSpecifier) trailNode;
|
||||
IASTElaboratedTypeSpecifier decl = (IASTElaboratedTypeSpecifier) node;
|
||||
|
||||
return isDeclSpecifierEquals(trailDecl, decl)
|
||||
&& trailDecl.getKind() == decl.getKind();
|
||||
} else if (trailNode instanceof IASTCompositeTypeSpecifier) {
|
||||
IASTCompositeTypeSpecifier trailDecl = (IASTCompositeTypeSpecifier) trailNode;
|
||||
IASTCompositeTypeSpecifier decl = (IASTCompositeTypeSpecifier) node;
|
||||
|
||||
return isDeclSpecifierEquals(trailDecl, decl)
|
||||
&& trailDecl.getKey() == decl.getKey();
|
||||
} else if (trailNode instanceof ICPPASTDeclSpecifier) {
|
||||
ICPPASTDeclSpecifier trailDecl = (ICPPASTDeclSpecifier) trailNode;
|
||||
ICPPASTDeclSpecifier decl = (ICPPASTDeclSpecifier) node;
|
||||
|
||||
return isDeclSpecifierEquals(trailDecl, decl)
|
||||
&& trailDecl.isExplicit() == decl.isExplicit()
|
||||
&& trailDecl.isFriend() == decl.isFriend()
|
||||
&& trailDecl.isVirtual() == decl.isVirtual();
|
||||
} else if (trailNode instanceof ICASTDeclSpecifier) {
|
||||
ICASTDeclSpecifier trailDecl = (ICASTDeclSpecifier) trailNode;
|
||||
ICASTDeclSpecifier decl = (ICASTDeclSpecifier) node;
|
||||
|
||||
return isDeclSpecifierEquals(trailDecl, decl)
|
||||
&& trailDecl.isRestrict() == decl.isRestrict();
|
||||
} else if (trailNode instanceof IASTDeclSpecifier) {
|
||||
IASTDeclSpecifier trailDecl = (IASTDeclSpecifier) trailNode;
|
||||
IASTDeclSpecifier decl = (IASTDeclSpecifier) node;
|
||||
|
||||
return isDeclSpecifierEquals(trailDecl, decl);
|
||||
} else {
|
||||
//is same
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isDeclaratorEquals(IASTNode trailNode, IASTNode node) {
|
||||
if (trailNode instanceof IASTStandardFunctionDeclarator) {
|
||||
IASTStandardFunctionDeclarator trailFunc = (IASTStandardFunctionDeclarator) trailNode;
|
||||
IASTStandardFunctionDeclarator func = (IASTStandardFunctionDeclarator) node;
|
||||
|
||||
return trailFunc.takesVarArgs() == func.takesVarArgs();
|
||||
} else if (trailNode instanceof ICPPASTFunctionDeclarator) {
|
||||
ICPPASTFunctionDeclarator trailFunc = (ICPPASTFunctionDeclarator) trailNode;
|
||||
ICPPASTFunctionDeclarator func = (ICPPASTFunctionDeclarator) node;
|
||||
|
||||
return trailFunc.isConst() == func.isConst()
|
||||
&& trailFunc.isPureVirtual() == func.isPureVirtual()
|
||||
&& trailFunc.isVolatile() == func.isVolatile();
|
||||
} else {
|
||||
//same type
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isDeclarationEquals(IASTNode trailNode, IASTNode node) {
|
||||
if (trailNode instanceof IASTASMDeclaration) {
|
||||
IASTASMDeclaration trailASMDecl = (IASTASMDeclaration) trailNode;
|
||||
IASTASMDeclaration asmDecl = (IASTASMDeclaration) node;
|
||||
|
||||
return trailASMDecl.getAssembly().equals(asmDecl.getAssembly());
|
||||
} else if (trailNode instanceof IGPPASTExplicitTemplateInstantiation) {
|
||||
IGPPASTExplicitTemplateInstantiation trailTempl = (IGPPASTExplicitTemplateInstantiation) trailNode;
|
||||
IGPPASTExplicitTemplateInstantiation templ = (IGPPASTExplicitTemplateInstantiation) node;
|
||||
|
||||
return trailTempl.getModifier() == templ.getModifier();
|
||||
} else if (trailNode instanceof ICPPASTLinkageSpecification) {
|
||||
ICPPASTLinkageSpecification trailLink = (ICPPASTLinkageSpecification) trailNode;
|
||||
ICPPASTLinkageSpecification link = (ICPPASTLinkageSpecification) node;
|
||||
|
||||
return trailLink.getLiteral().equals(link.getLiteral());
|
||||
} else if (trailNode instanceof ICPPASTTemplateDeclaration) {
|
||||
ICPPASTTemplateDeclaration trailTempl = (ICPPASTTemplateDeclaration) trailNode;
|
||||
ICPPASTTemplateDeclaration templ = (ICPPASTTemplateDeclaration) node;
|
||||
|
||||
return trailTempl.isExported() == templ.isExported();
|
||||
} else if (trailNode instanceof ICPPASTUsingDeclaration) {
|
||||
ICPPASTUsingDeclaration trailUsing = (ICPPASTUsingDeclaration) trailNode;
|
||||
ICPPASTUsingDeclaration using = (ICPPASTUsingDeclaration) node;
|
||||
|
||||
return trailUsing.isTypename() == using.isTypename();
|
||||
} else if (trailNode instanceof ICPPASTVisiblityLabel) {
|
||||
ICPPASTVisiblityLabel trailVisibility = (ICPPASTVisiblityLabel) trailNode;
|
||||
ICPPASTVisiblityLabel visibility = (ICPPASTVisiblityLabel) node;
|
||||
|
||||
return trailVisibility.getVisibility() == visibility.getVisibility();
|
||||
} else {
|
||||
//same type
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPointerOperatorEquals(IASTNode trailNode, IASTNode node) {
|
||||
if (trailNode instanceof IGPPASTPointer) {
|
||||
IGPPASTPointer trailGPointer = (IGPPASTPointer) trailNode;
|
||||
IGPPASTPointer gPointer = (IGPPASTPointer) node;
|
||||
|
||||
return trailGPointer.isConst() == gPointer.isConst()
|
||||
&& trailGPointer.isRestrict() == gPointer.isRestrict()
|
||||
&& trailGPointer.isVolatile() == gPointer.isVolatile();
|
||||
} else if (trailNode instanceof ICASTPointer) {
|
||||
ICASTPointer trailCPointer = (ICASTPointer) trailNode;
|
||||
ICASTPointer cPointer = (ICASTPointer) node;
|
||||
|
||||
return trailCPointer.isConst() == cPointer.isConst()
|
||||
&& trailCPointer.isRestrict() == cPointer.isRestrict()
|
||||
&& trailCPointer.isVolatile() == cPointer.isVolatile();
|
||||
} else if (trailNode instanceof IASTPointer) {
|
||||
IASTPointer trailCPointer = (IASTPointer) trailNode;
|
||||
IASTPointer cPointer = (IASTPointer) node;
|
||||
|
||||
return trailCPointer.isConst() == cPointer.isConst()
|
||||
&& trailCPointer.isVolatile() == cPointer.isVolatile();
|
||||
} else {
|
||||
//same type
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isStatementEquals(IASTNode trailNode, IASTNode node) {
|
||||
if (trailNode instanceof ICPPASTCatchHandler) {
|
||||
ICPPASTCatchHandler trailCatch = (ICPPASTCatchHandler) trailNode;
|
||||
ICPPASTCatchHandler nodeCatch = (ICPPASTCatchHandler) node;
|
||||
|
||||
return trailCatch.isCatchAll() == nodeCatch.isCatchAll();
|
||||
}
|
||||
//same type
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isExpressionEquals(IASTNode trailNode, IASTNode node) {
|
||||
if (trailNode instanceof IASTBinaryExpression) {
|
||||
IASTBinaryExpression trailExpr = (IASTBinaryExpression) trailNode;
|
||||
IASTBinaryExpression expr = (IASTBinaryExpression) node;
|
||||
|
||||
return trailExpr.getOperator() == expr.getOperator();
|
||||
} else if (trailNode instanceof ICPPASTFieldReference) {
|
||||
ICPPASTFieldReference trailFieldRef = (ICPPASTFieldReference) trailNode;
|
||||
ICPPASTFieldReference fieldRef = (ICPPASTFieldReference) node;
|
||||
|
||||
return trailFieldRef.isPointerDereference() == fieldRef.isPointerDereference()
|
||||
&& trailFieldRef.isTemplate() == fieldRef.isTemplate();
|
||||
} else if (trailNode instanceof IASTFieldReference) {
|
||||
IASTFieldReference trailFieldRef = (IASTFieldReference) trailNode;
|
||||
IASTFieldReference fieldRef = (IASTFieldReference) node;
|
||||
|
||||
return trailFieldRef.isPointerDereference() == fieldRef.isPointerDereference();
|
||||
} else if (trailNode instanceof IASTLiteralExpression) {
|
||||
IASTLiteralExpression trailLiteral = (IASTLiteralExpression) trailNode;
|
||||
IASTLiteralExpression literal = (IASTLiteralExpression) node;
|
||||
|
||||
return trailLiteral.getKind() == literal.getKind() && trailLiteral.toString().equals(literal.toString());
|
||||
} else if (trailNode instanceof IASTUnaryExpression) {
|
||||
IASTUnaryExpression trailExpr = (IASTUnaryExpression) trailNode;
|
||||
IASTUnaryExpression expr = (IASTUnaryExpression) node;
|
||||
|
||||
return trailExpr.getOperator() == expr.getOperator();
|
||||
} else if (trailNode instanceof IASTTypeIdExpression) {
|
||||
IASTTypeIdExpression trailIdExpr = (IASTTypeIdExpression) trailNode;
|
||||
IASTTypeIdExpression idExpr = (IASTTypeIdExpression) node;
|
||||
|
||||
return trailIdExpr.getTypeId() == idExpr.getTypeId();
|
||||
} else if (trailNode instanceof ICPPASTDeleteExpression) {
|
||||
ICPPASTDeleteExpression trailDelete = (ICPPASTDeleteExpression) trailNode;
|
||||
ICPPASTDeleteExpression delete = (ICPPASTDeleteExpression) node;
|
||||
|
||||
return trailDelete.isGlobal() == delete.isGlobal() && trailDelete.isVectored() == delete.isVectored();
|
||||
} else if (trailNode instanceof ICPPASTNewExpression) {
|
||||
ICPPASTNewExpression trailNew = (ICPPASTNewExpression) trailNode;
|
||||
ICPPASTNewExpression nodeNew = (ICPPASTNewExpression) node;
|
||||
|
||||
return trailNew.isGlobal() == nodeNew.isGlobal() && trailNew.isNewTypeId() == nodeNew.isNewTypeId();
|
||||
} else if (trailNode instanceof ICPPASTSimpleTypeConstructorExpression) {
|
||||
ICPPASTSimpleTypeConstructorExpression trailConsExpr = (ICPPASTSimpleTypeConstructorExpression) trailNode;
|
||||
ICPPASTSimpleTypeConstructorExpression consExpr = (ICPPASTSimpleTypeConstructorExpression) node;
|
||||
|
||||
return trailConsExpr.getSimpleType() == consExpr.getSimpleType();
|
||||
} else if (trailNode instanceof ICPPASTTypenameExpression) {
|
||||
ICPPASTTypenameExpression trailTypenameExpr = (ICPPASTTypenameExpression) trailNode;
|
||||
ICPPASTTypenameExpression typenameExpr = (ICPPASTTypenameExpression) node;
|
||||
|
||||
return trailTypenameExpr.isTemplate() == typenameExpr.isTemplate();
|
||||
} else {
|
||||
// same type
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isSameNamedTypeSpecifierName(IASTNamedTypeSpecifier trailDecl, IASTNamedTypeSpecifier decl) {
|
||||
return trailDecl.getName().getRawSignature().equals(decl.getName().getRawSignature());
|
||||
}
|
||||
|
||||
private Class<?>[] getInterfaces(IASTNode node) {
|
||||
Class<?>[] interfaces = node.getClass().getInterfaces();
|
||||
List<Class<?>> interfaceList = Arrays.asList(interfaces);
|
||||
Class<?>[] returnArray = new Class[interfaceList.size()];
|
||||
return interfaceList.toArray(returnArray);
|
||||
}
|
||||
|
||||
private boolean isDeclSpecifierEquals(IASTDeclSpecifier trailDeclSpeci, IASTDeclSpecifier declSpeci){
|
||||
return trailDeclSpeci.isConst() == declSpeci.isConst()
|
||||
&& trailDeclSpeci.isInline() == declSpeci.isInline()
|
||||
&& trailDeclSpeci.isVolatile() == declSpeci.isVolatile()
|
||||
&& trailDeclSpeci.getStorageClass() == declSpeci.getStorageClass();
|
||||
}
|
||||
|
||||
private boolean isSimpleDeclSpecifierEquals(IASTSimpleDeclSpecifier trailDeclSpeci, IASTSimpleDeclSpecifier declSpeci){
|
||||
return isDeclSpecifierEquals(trailDeclSpeci, declSpeci)
|
||||
&& trailDeclSpeci.isLong() == declSpeci.isLong()
|
||||
&& trailDeclSpeci.isShort() == declSpeci.isShort()
|
||||
&& trailDeclSpeci.isSigned() == declSpeci.isSigned()
|
||||
&& trailDeclSpeci.isUnsigned() == declSpeci.isUnsigned()
|
||||
&& trailDeclSpeci.getType() == declSpeci.getType();
|
||||
}
|
||||
|
||||
private boolean isNameEquals(TrailName trailName, IASTName name) {
|
||||
int actCount = namesCounter.getObject().intValue();
|
||||
if(names.containsKey(name.getRawSignature())){
|
||||
Integer nameId = names.get(name.getRawSignature());
|
||||
actCount = nameId.intValue();
|
||||
} else {
|
||||
++actCount;
|
||||
namesCounter.setObject(Integer.valueOf(actCount));
|
||||
names.put(name.getRawSignature(), namesCounter.getObject());
|
||||
}
|
||||
|
||||
if(actCount != trailName.getNameNumber()){
|
||||
return false;
|
||||
}
|
||||
|
||||
IBinding bind = name.resolveBinding();
|
||||
IASTName[] declNames = name.getTranslationUnit().getDeclarationsInAST(bind);
|
||||
if(declNames.length > 0){
|
||||
IASTNode tmpNode = ASTHelper.getDeclarationForNode(declNames[0]);
|
||||
|
||||
if(tmpNode != null){
|
||||
if(trailName.isGloballyQualified()){
|
||||
//global Node
|
||||
if(tmpNode.equals(trailName.getDeclaration())){
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
//localNode
|
||||
IASTDeclSpecifier decl = ASTHelper.getDeclarationSpecifier(tmpNode);
|
||||
IASTDeclSpecifier trailDecl = trailName.getDeclSpecifier();
|
||||
|
||||
IASTDeclarator declarator = ASTHelper.getDeclaratorForNode(declNames[0]);
|
||||
IASTDeclarator trailDeclarator = ASTHelper.getDeclaratorForNode(trailName.getDeclaration());
|
||||
|
||||
IASTPointerOperator[] pointerOperators1 = declarator.getPointerOperators();
|
||||
IASTPointerOperator[] pointerOperators2 = trailDeclarator.getPointerOperators();
|
||||
|
||||
if(trailDecl != null && decl != null
|
||||
&& decl.getStorageClass() == trailDecl.getStorageClass()
|
||||
&& ASTHelper.samePointers(pointerOperators1, pointerOperators2, this)){
|
||||
if (decl instanceof IASTSimpleDeclSpecifier
|
||||
&& trailDecl instanceof IASTSimpleDeclSpecifier) {
|
||||
IASTSimpleDeclSpecifier simpleDecl = (IASTSimpleDeclSpecifier) decl;
|
||||
IASTSimpleDeclSpecifier simpleTrailDecl = (IASTSimpleDeclSpecifier) trailDecl;
|
||||
if(simpleDecl.getType() == simpleTrailDecl.getType()){
|
||||
return true;
|
||||
}
|
||||
} else if (decl instanceof IASTNamedTypeSpecifier
|
||||
&& trailDecl instanceof IASTNamedTypeSpecifier) {
|
||||
|
||||
IASTNamedTypeSpecifier namedDecl = (IASTNamedTypeSpecifier) decl;
|
||||
IASTNamedTypeSpecifier trailNamedDecl = (IASTNamedTypeSpecifier) trailDecl;
|
||||
if(namedDecl.getName().getRawSignature().equals(trailNamedDecl.getName().getRawSignature())){
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
###############################################################################
|
||||
ExtractFunctionRefactoringWizard_FunctionName=Function Name
|
||||
ExtractFunctionRefactoring_ExtractFunction=Extract Function
|
||||
ExtractFunctionRefactoring_NoStmtSelected=No statement selected
|
||||
ExtractFunctionRefactoring_TooManySelected=Too many declarations in selection.
|
||||
ExtractFunctionRefactoring_NameInUse=Name already in use.
|
||||
ExtractFunctionComposite_MethodName=Method &name:
|
||||
ExtractFunctionComposite_FunctionName=Function &name:
|
||||
ExtractFunctionInputPage_EnterName=Enter a name
|
||||
ExtractFunctionInputPage_CheckMethodName=Check Method Name:
|
||||
ExtractFunctionInputPage_1=is used after the extracted block - it needs to be passed by reference or must be the return value.
|
||||
ExtractFunctionComposite_ReturnValue=Return value:
|
||||
ExtractFunctionRefactoring_CreateMethodDef=Create Method Definition
|
||||
ExtractFunctionRefactoring_CreateFunctionDef=Create Function Definition
|
||||
ExtractFunctionComposite_ReplaceDuplicates=Replace all occurrences of statements with method.
|
||||
ExtractFunctionRefactoring_CreateMethodCall=Create Method Call
|
||||
ExtractFunctionRefactoring_CreateFunctionCall=Create Function Call
|
||||
ChooserComposite_Return=Return
|
||||
ChooserComposite_CallByRef=Call by Reference
|
||||
ChooserComposite_Name=Name
|
||||
ChooserComposite_Type=Type
|
||||
ChooserComposite_NoReturnValue=No return-value (void)
|
||||
ExtractFunctionRefactoring_Error_Return=Extracting return statements is not supported
|
||||
ExtractFunctionRefactoring_Error_Continue=Extracting cotinue statements without the surrounding loop is not possible. Please adjust your selection.
|
||||
ExtractFunctionRefactoring_Error_Break=Extracting break statements without the surrounding loop is not possible. Please adjust your selection.
|
|
@ -27,3 +27,5 @@ HSRRefactoring_SelectionNotValid=Selection is not valid.
|
|||
HSRRefactoring_CantLoadTU=Can not load translation unit.
|
||||
HSRRefactoring_Ambiguity=Translation unit is ambiguous.
|
||||
NO_FILE=File not found.
|
||||
NodeContainer_Name=name:
|
||||
NodeContainer_Space=\
|
|
@ -0,0 +1,255 @@
|
|||
/*******************************************************************************
|
||||
* 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.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||
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.IASTParameterDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
|
||||
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.ICPPASTCompositeTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.refactoring.extractfunction.TrailNodeEqualityChecker;
|
||||
|
||||
public class ASTHelper {
|
||||
private ASTHelper() {
|
||||
}
|
||||
|
||||
static public IASTNode getDeclarationForNode(IASTNode tmpNode) {
|
||||
while (tmpNode != null && !(tmpNode instanceof IASTSimpleDeclaration) && !(tmpNode instanceof IASTParameterDeclaration)) {
|
||||
tmpNode = tmpNode.getParent();
|
||||
}
|
||||
return tmpNode;
|
||||
}
|
||||
|
||||
static public IASTDeclarator getDeclaratorForNode(IASTNode aNode) {
|
||||
IASTNode tmpNode = getDeclarationForNode(aNode);
|
||||
|
||||
IASTDeclarator declarator = null;
|
||||
if (tmpNode instanceof IASTSimpleDeclaration) {
|
||||
IASTSimpleDeclaration decl = (IASTSimpleDeclaration) tmpNode;
|
||||
if (decl.getDeclarators().length > 0) {
|
||||
declarator = decl.getDeclarators()[0];
|
||||
}
|
||||
} else if (tmpNode instanceof IASTParameterDeclaration) {
|
||||
IASTParameterDeclaration decl = (IASTParameterDeclaration) tmpNode;
|
||||
declarator = decl.getDeclarator();
|
||||
}
|
||||
return declarator;
|
||||
}
|
||||
|
||||
static public IASTDeclSpecifier getDeclarationSpecifier(IASTNode declaration) {
|
||||
if (declaration != null) {
|
||||
if (declaration instanceof IASTSimpleDeclaration) {
|
||||
IASTSimpleDeclaration simpleDecl = (IASTSimpleDeclaration) declaration;
|
||||
return simpleDecl.getDeclSpecifier();
|
||||
} else if (declaration instanceof ICPPASTParameterDeclaration) {
|
||||
ICPPASTParameterDeclaration paramDecl = (ICPPASTParameterDeclaration) declaration;
|
||||
return paramDecl.getDeclSpecifier();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean samePointers(IASTPointerOperator[] pointerOperators1, IASTPointerOperator[] pointerOperators2, TrailNodeEqualityChecker checker) {
|
||||
if (pointerOperators2.length == pointerOperators1.length) {
|
||||
for (int i = 0; i < pointerOperators2.length; i++) {
|
||||
IASTPointerOperator operator1 = pointerOperators1[i];
|
||||
IASTPointerOperator operator2 = pointerOperators2[i];
|
||||
if (!checker.isEquals(operator1, operator2)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isClassDeklarationName(IASTName astName) {
|
||||
if (astName == null)
|
||||
return false;
|
||||
IASTNode parent = astName.getParent();
|
||||
if (parent instanceof ICPPASTCompositeTypeSpecifier) {
|
||||
ICPPASTCompositeTypeSpecifier typeSpecifier = (ICPPASTCompositeTypeSpecifier) parent;
|
||||
return typeSpecifier.getKey() == ICPPASTCompositeTypeSpecifier.k_class;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static ArrayList<ICPPASTNamespaceDefinition> getNamespaces(IASTNode node) {
|
||||
ArrayList<ICPPASTNamespaceDefinition> namespaces = new ArrayList<ICPPASTNamespaceDefinition>();
|
||||
for (IASTNode aktNode = node; aktNode != null; aktNode = aktNode.getParent()) {
|
||||
if (aktNode instanceof ICPPASTNamespaceDefinition) {
|
||||
namespaces.add(0, (ICPPASTNamespaceDefinition) aktNode);
|
||||
} else if(aktNode instanceof ICPPASTQualifiedName) {
|
||||
namespaces.addAll(getNamespaces((ICPPASTQualifiedName) aktNode));
|
||||
}
|
||||
}
|
||||
return namespaces;
|
||||
}
|
||||
|
||||
public static ArrayList<ICPPASTNamespaceDefinition> getNamespaces(ICPPASTQualifiedName qualifiedName) {
|
||||
ArrayList<ICPPASTNamespaceDefinition> namespaces = new ArrayList<ICPPASTNamespaceDefinition>();
|
||||
for(IASTName aktQualifiedPartName : qualifiedName.getNames()) {
|
||||
IBinding binding = aktQualifiedPartName.resolveBinding();
|
||||
for(IASTName aktResolvedName : qualifiedName.getTranslationUnit().getDefinitionsInAST(binding)) {
|
||||
if(aktResolvedName.getParent() instanceof ICPPASTNamespaceDefinition) {
|
||||
namespaces.add((ICPPASTNamespaceDefinition) aktResolvedName.getParent());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return namespaces;
|
||||
}
|
||||
|
||||
public static Collection<IASTDeclSpecifier> getCompositTypeSpecifiers(IASTNode baseNode) {
|
||||
final Collection<IASTDeclSpecifier> specifiers = new ArrayList<IASTDeclSpecifier>();
|
||||
ASTVisitor visitor = new ASTVisitor() {
|
||||
|
||||
@Override
|
||||
public int visit(IASTDeclSpecifier declSpec) {
|
||||
specifiers.add(declSpec);
|
||||
return super.visit(declSpec);
|
||||
}
|
||||
};
|
||||
visitor.shouldVisitDeclSpecifiers = true;
|
||||
baseNode.accept(visitor);
|
||||
return specifiers;
|
||||
}
|
||||
|
||||
public static Collection<IASTPreprocessorStatement> getAllInFilePreprocessorStatements(IASTTranslationUnit unit, String aktFileName) {
|
||||
Collection<IASTPreprocessorStatement> statements = new ArrayList<IASTPreprocessorStatement>();
|
||||
for(IASTPreprocessorStatement aktStatement : unit.getAllPreprocessorStatements()) {
|
||||
if(aktStatement.getFileLocation() == null) {
|
||||
continue;
|
||||
} else if (aktStatement.getFileLocation().getFileName().equals(aktFileName)) {
|
||||
statements.add(aktStatement);
|
||||
}
|
||||
}
|
||||
return statements;
|
||||
}
|
||||
|
||||
public static Collection<IASTDeclaration> getAllInFileDeclarations(IASTTranslationUnit unit, String aktFileName) {
|
||||
Collection<IASTDeclaration> decls = new ArrayList<IASTDeclaration>();
|
||||
for(IASTDeclaration aktDecl: unit.getDeclarations()) {
|
||||
if(aktDecl.getFileLocation() == null) {
|
||||
continue;
|
||||
} else if(aktDecl.getFileLocation().getFileName().equals(aktFileName)) {
|
||||
decls.add(aktDecl);
|
||||
}
|
||||
}
|
||||
return decls;
|
||||
}
|
||||
|
||||
public static ICPPASTUsingDirective getActiveUsingDirecitveForNode(IASTNode node, IASTTranslationUnit unit) {
|
||||
ICPPASTUsingDirective activeDirective = null;
|
||||
for(IASTDeclaration aktDeclaration : getAllInFileDeclarations(unit, node.getFileLocation().getFileName())) {
|
||||
if(aktDeclaration.getFileLocation().getNodeOffset() >= node.getFileLocation().getNodeOffset()) {
|
||||
break;
|
||||
}
|
||||
if(aktDeclaration instanceof ICPPASTUsingDirective) {
|
||||
activeDirective = (ICPPASTUsingDirective) aktDeclaration;
|
||||
}
|
||||
}
|
||||
return activeDirective;
|
||||
}
|
||||
|
||||
public static Collection<ICPPASTUsingDeclaration> getUsingDeclarations(IASTTranslationUnit unit) {
|
||||
Collection<ICPPASTUsingDeclaration> usingDecls = new ArrayList<ICPPASTUsingDeclaration>();
|
||||
for(IASTDeclaration aktDecl : unit.getDeclarations()) {
|
||||
if (aktDecl instanceof ICPPASTUsingDeclaration) {
|
||||
usingDecls.add((ICPPASTUsingDeclaration) aktDecl);
|
||||
}
|
||||
}
|
||||
return usingDecls;
|
||||
}
|
||||
|
||||
public static boolean isClassDefinitionName(IASTName name) {
|
||||
try {
|
||||
if(!(name.getParent().getParent().getParent() instanceof IASTFunctionDefinition)) {
|
||||
return false;
|
||||
}
|
||||
ICPPASTQualifiedName qName = (ICPPASTQualifiedName) name.getParent();
|
||||
IASTName secondLastName = qName.getNames()[qName.getNames().length-2];
|
||||
if(!(name.equals(secondLastName))) {
|
||||
return false;
|
||||
}
|
||||
IBinding binding = name.resolveBinding();
|
||||
for(IASTName aktName : name.getTranslationUnit().getDeclarationsInAST(binding)) {
|
||||
if(!isClassDeklarationName(aktName)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (NullPointerException e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static IASTCompositeTypeSpecifier getCompositeTypeSpecifierForName(IASTName name) {
|
||||
IBinding binding = name.resolveBinding();
|
||||
for(IASTName aktName : name.getTranslationUnit().getDefinitionsInAST(binding)) {
|
||||
if(aktName.getParent() instanceof IASTCompositeTypeSpecifier) {
|
||||
return (IASTCompositeTypeSpecifier) aktName.getParent();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Collection<IASTFunctionDeclarator> getFunctionDeclaratorsForClass(IASTCompositeTypeSpecifier klass) {
|
||||
Collection<IASTFunctionDeclarator> declarators = new ArrayList<IASTFunctionDeclarator>();
|
||||
for(IASTDeclaration aktDeclaration : klass.getMembers()) {
|
||||
if(aktDeclaration instanceof IASTSimpleDeclaration) {
|
||||
for(IASTDeclarator aktDeclarator : ((IASTSimpleDeclaration) aktDeclaration).getDeclarators()) {
|
||||
if(aktDeclarator instanceof IASTFunctionDeclarator) {
|
||||
declarators.add((IASTFunctionDeclarator) aktDeclarator);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return declarators;
|
||||
}
|
||||
|
||||
public static Collection<IASTFunctionDefinition> getFunctionDefinitionsForClass(IASTCompositeTypeSpecifier klass) {
|
||||
Collection<IASTFunctionDefinition> definitions = new ArrayList<IASTFunctionDefinition>();
|
||||
for(IASTFunctionDeclarator aktDeclarator : getFunctionDeclaratorsForClass(klass)) {
|
||||
IBinding binding = aktDeclarator.getName().resolveBinding();
|
||||
for(IASTName aktName : aktDeclarator.getTranslationUnit().getDefinitionsInAST(binding)) {
|
||||
if(aktName.getParent().getParent().getParent() instanceof IASTFunctionDefinition) {
|
||||
definitions.add((IASTFunctionDefinition) aktName.getParent().getParent().getParent());
|
||||
}
|
||||
}
|
||||
}
|
||||
return definitions;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
/*******************************************************************************
|
||||
* 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.IASTComment;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTProblem;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||
|
||||
public class CPPASTAllVisitor extends CPPASTVisitor {
|
||||
|
||||
{
|
||||
shouldVisitNames = true;
|
||||
shouldVisitDeclarations = true;
|
||||
shouldVisitInitializers = true;
|
||||
shouldVisitParameterDeclarations = true;
|
||||
shouldVisitDeclarators = true;
|
||||
shouldVisitDeclSpecifiers = true;
|
||||
shouldVisitExpressions = true;
|
||||
shouldVisitStatements = true;
|
||||
shouldVisitTypeIds = true;
|
||||
shouldVisitEnumerators = true;
|
||||
shouldVisitTranslationUnit = true;
|
||||
shouldVisitProblems = true;
|
||||
|
||||
shouldVisitBaseSpecifiers = true;
|
||||
shouldVisitNamespaces = true;
|
||||
shouldVisitTemplateParameters = true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int visit(IASTTranslationUnit tu) {
|
||||
return visitAll(tu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int visit(IASTName name) {
|
||||
return visitAll(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int visit(IASTDeclaration declaration) {
|
||||
return visitAll(declaration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int visit(IASTInitializer initializer) {
|
||||
return visitAll(initializer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int visit(IASTParameterDeclaration parameterDeclaration) {
|
||||
return visitAll(parameterDeclaration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int visit(IASTDeclarator declarator) {
|
||||
return visitAll(declarator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int visit(IASTDeclSpecifier declSpec) {
|
||||
return visitAll(declSpec);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int visit(IASTExpression expression) {
|
||||
return visitAll(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int visit(IASTStatement statement) {
|
||||
return visitAll(statement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int visit(IASTTypeId typeId) {
|
||||
return visitAll(typeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int visit(IASTEnumerator enumerator) {
|
||||
return visitAll(enumerator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int visit( IASTProblem problem ){
|
||||
return visitAll(problem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int visit( IASTComment comment ){
|
||||
return visitAll(comment);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Visit BaseSpecifiers.
|
||||
*/
|
||||
@Override
|
||||
public int visit(ICPPASTBaseSpecifier specifier) {
|
||||
return visitAll(specifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visit namespace definitions.
|
||||
*/
|
||||
@Override
|
||||
public int visit(ICPPASTNamespaceDefinition namespace) {
|
||||
return visitAll(namespace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visit template parameter.
|
||||
*/
|
||||
@Override
|
||||
public int visit(ICPPASTTemplateParameter parameter) {
|
||||
return visitAll(parameter);
|
||||
}
|
||||
|
||||
public int visitAll(IASTNode node){
|
||||
return PROCESS_CONTINUE;
|
||||
}
|
||||
}
|
|
@ -113,6 +113,7 @@ public class CRefactoringActionGroup extends ActionGroup implements ISelectionCh
|
|||
private String fGroupName= IWorkbenchActionConstants.GROUP_REORGANIZE;
|
||||
private CRenameAction fRenameAction;
|
||||
private RefactoringAction fExtractConstantAction;
|
||||
private RefactoringAction fExtractFunctionAction;
|
||||
private IWorkbenchSite fSite;
|
||||
private List<RefactoringAction> fAllActions= new ArrayList<RefactoringAction>();
|
||||
|
||||
|
@ -148,6 +149,10 @@ public class CRefactoringActionGroup extends ActionGroup implements ISelectionCh
|
|||
fExtractConstantAction= new ExtractConstantAction();
|
||||
fExtractConstantAction.setActionDefinitionId(ICEditorActionDefinitionIds.EXTRACT_CONSTANT);
|
||||
fAllActions.add(fExtractConstantAction);
|
||||
|
||||
fExtractFunctionAction = new ExtractFunctionAction();
|
||||
fExtractFunctionAction.setActionDefinitionId(ICEditorActionDefinitionIds.EXTRACT_FUNCTION);
|
||||
fAllActions.add(fExtractFunctionAction);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,6 +189,7 @@ public class CRefactoringActionGroup extends ActionGroup implements ISelectionCh
|
|||
super.fillActionBars(actionBar);
|
||||
setActionHandler(actionBar, CdtActionConstants.RENAME, fRenameAction);
|
||||
setActionHandler(actionBar, CdtActionConstants.EXTRACT_CONSTANT, fExtractConstantAction);
|
||||
setActionHandler(actionBar, CdtActionConstants.EXTRACT_METHOD, fExtractFunctionAction);
|
||||
}
|
||||
|
||||
private void setActionHandler(IActionBars actionBar, String id, RefactoringAction action) {
|
||||
|
@ -212,6 +218,7 @@ public class CRefactoringActionGroup extends ActionGroup implements ISelectionCh
|
|||
addAction(refactorSubmenu, fRenameAction);
|
||||
refactorSubmenu.add(new Separator(GROUP_CODING));
|
||||
addAction(refactorSubmenu, fExtractConstantAction);
|
||||
addAction(refactorSubmenu, fExtractFunctionAction);
|
||||
refactorSubmenu.add(new Separator(GROUP_REORG2));
|
||||
refactorSubmenu.add(new Separator(GROUP_TYPE));
|
||||
refactorSubmenu.add(new Separator(GROUP_TYPE2));
|
||||
|
|
|
@ -39,7 +39,7 @@ public class ExtractConstantAction extends RefactoringAction {
|
|||
public void run(IShellProvider shellProvider, IWorkingCopy wc, ITextSelection selection) {
|
||||
IResource res= wc.getResource();
|
||||
if (res instanceof IFile) {
|
||||
new ExtractConstantRefactoringRunner((IFile) res, selection).run();
|
||||
new ExtractConstantRefactoringRunner((IFile) res, selection, shellProvider).run();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik
|
||||
* Rapperswil, University of applied sciences and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Institute for Software (IFS)- initial API and implementation
|
||||
******************************************************************************/
|
||||
package org.eclipse.cdt.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.viewers.ISelection;
|
||||
import org.eclipse.jface.window.IShellProvider;
|
||||
|
||||
import org.eclipse.cdt.core.model.ICElement;
|
||||
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.refactoring.extractfunction.ExtractFunctionRefactoringRunner;
|
||||
|
||||
/**
|
||||
*
|
||||
* @since 5.0
|
||||
* @author Emanuel Graf IFS
|
||||
*
|
||||
*/
|
||||
public class ExtractFunctionAction extends RefactoringAction {
|
||||
|
||||
public ExtractFunctionAction() {
|
||||
super(Messages.ExtractFunctionAction_label);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(IShellProvider shellProvider, ICElement elem) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(IShellProvider shellProvider, IWorkingCopy wc,
|
||||
ITextSelection s) {
|
||||
IResource res = wc.getResource();
|
||||
if (res instanceof IFile) {
|
||||
final ISelection selection = fEditor.getSelectionProvider().getSelection();
|
||||
new ExtractFunctionRefactoringRunner((IFile) res, selection, fEditor.getSite()).run();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSelection(ICElement elem) {
|
||||
super.updateSelection(elem);
|
||||
setEnabled(false);
|
||||
}
|
||||
|
||||
}
|
|
@ -17,6 +17,7 @@ public class Messages extends NLS {
|
|||
public static String CRefactoringActionGroup_menu;
|
||||
public static String CRenameAction_label;
|
||||
public static String ExtractConstantAction_label;
|
||||
public static String ExtractFunctionAction_label;
|
||||
static {
|
||||
// initialize resource bundle
|
||||
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
|
||||
|
|
|
@ -11,3 +11,4 @@
|
|||
CRefactoringActionGroup_menu=Refactor
|
||||
CRenameAction_label=Rename...
|
||||
ExtractConstantAction_label=Extract Constant...
|
||||
ExtractFunctionAction_label=Extract Function... (work in progress)
|
||||
|
|
Loading…
Add table
Reference in a new issue