1
0
Fork 0
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:
Markus Schorn 2008-04-16 10:19:55 +00:00
parent a4274e1467
commit ca61147d16
55 changed files with 8244 additions and 46 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -0,0 +1,108 @@
/*******************************************************************************
* Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Institute for Software - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.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$
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -0,0 +1,63 @@
/*******************************************************************************
* Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Institute for Software - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.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;
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -0,0 +1,35 @@
###############################################################################
# Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik
# Rapperswil, University of applied sciences and others
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html
#
# Contributors:
# Institute for Software - initial API and implementation
###############################################################################
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.

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -11,3 +11,4 @@
CRefactoringActionGroup_menu=Refactor
CRenameAction_label=Rename...
ExtractConstantAction_label=Extract Constant...
ExtractFunctionAction_label=Extract Function... (work in progress)