Skip to main content
aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorMarkus Schorn2008-04-16 06:19:55 -0400
committerMarkus Schorn2008-04-16 06:19:55 -0400
commitca61147d16a313e1ea8a8376f97626d9475d7b95 (patch)
tree8bdf1f39934e84f86b1bbfc599efc4c47914cbeb /core
parenta4274e1467cd8622fb7725433209e2c05ae64711 (diff)
downloadorg.eclipse.cdt-ca61147d16a313e1ea8a8376f97626d9475d7b95.tar.gz
org.eclipse.cdt-ca61147d16a313e1ea8a8376f97626d9475d7b95.tar.xz
org.eclipse.cdt-ca61147d16a313e1ea8a8376f97626d9475d7b95.zip
Extract Function (work in progress) by Emanuel Graf, bug 226484.
Diffstat (limited to 'core')
-rw-r--r--core/org.eclipse.cdt.core/META-INF/MANIFEST.MF2
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/MacroExpansionHandler.java2
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ASTModificationHelper.java41
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGeneratorWriterVisitor.java3
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclSpecWriter.java2
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclaratorWriter.java14
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTExpressionWriter.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTStatementWriter.java2
-rw-r--r--core/org.eclipse.cdt.ui.tests/META-INF/MANIFEST.MF1
-rw-r--r--core/org.eclipse.cdt.ui.tests/resources/refactoring/ExtractConstant.rts4
-rw-r--r--core/org.eclipse.cdt.ui.tests/resources/refactoring/ExtractExpression.rts429
-rw-r--r--core/org.eclipse.cdt.ui.tests/resources/refactoring/ExtractFunctionTemplates.rts98
-rw-r--r--core/org.eclipse.cdt.ui.tests/resources/refactoring/ExtractMethod.rts2139
-rw-r--r--core/org.eclipse.cdt.ui.tests/resources/refactoring/ExtractMethodDuplicates.rts1096
-rw-r--r--core/org.eclipse.cdt.ui.tests/resources/refactoring/ExtractMethodPreprocessor.rts295
-rw-r--r--core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/RefactoringTestSuite.java2
-rw-r--r--core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/extractfunction/ExtractFunctionRefactoringTest.java108
-rw-r--r--core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/extractfunction/ExtractFunctionTestSuite.java36
-rw-r--r--core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/UtilTestSuite.java4
-rw-r--r--core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF1
-rw-r--r--core/org.eclipse.cdt.ui/plugin.properties3
-rw-r--r--core/org.eclipse.cdt.ui/plugin.xml23
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ICEditorActionDefinitionIds.java6
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/CRefactoring.java20
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/ChangeTreeSet.java56
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/EqualityChecker.java16
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/Messages.java2
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/NodeContainer.java486
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/RefactoringRunner.java9
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractconstant/ExtractConstantRefactoringRunner.java7
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ChooserComposite.java203
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractExpression.java235
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractFunctionComposite.java130
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractFunctionInformation.java136
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractFunctionInputPage.java117
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractFunctionRefactoring.java963
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractFunctionRefactoringRunner.java46
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractFunctionRefactoringWizard.java36
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractStatement.java63
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractedFunctionConstructionHelper.java98
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/Messages.java52
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/NonExtractableStmtFinder.java60
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ReturnStatementFinder.java44
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/SimilarFinderVisitor.java156
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/TrailName.java74
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/TrailNodeEqualityChecker.java458
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/messages.properties35
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/messages.properties2
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/ASTHelper.java255
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/CPPASTAllVisitor.java148
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/CRefactoringActionGroup.java7
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/ExtractConstantAction.java2
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/ExtractFunctionAction.java57
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/Messages.java1
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/messages.properties1
55 files changed, 8244 insertions, 46 deletions
diff --git a/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF
index 1546a7debae..72b19e108b5 100644
--- a/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF
+++ b/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF
@@ -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",
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/MacroExpansionHandler.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/MacroExpansionHandler.java
index 5a1344f5fb9..08562c0426f 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/MacroExpansionHandler.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/MacroExpansionHandler.java
@@ -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];
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ASTModificationHelper.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ASTModificationHelper.java
index 9ffbc001c6f..fb1c516dee8 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ASTModificationHelper.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ASTModificationHelper.java
@@ -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();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGeneratorWriterVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGeneratorWriterVisitor.java
index b34302feed7..8821f0414ba 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGeneratorWriterVisitor.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGeneratorWriterVisitor.java
@@ -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);
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclSpecWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclSpecWriter.java
index de0dbc79d2c..2e249dbfe3a 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclSpecWriter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclSpecWriter.java
@@ -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);
}
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclaratorWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclaratorWriter.java
index 729b8496096..1a3db3621af 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclaratorWriter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclaratorWriter.java
@@ -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);
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTExpressionWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTExpressionWriter.java
index 62dadb7858d..9940c0fdc6f 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTExpressionWriter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTExpressionWriter.java
@@ -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;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTStatementWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTStatementWriter.java
index 5232835d4c4..156a84ffd5a 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTStatementWriter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTStatementWriter.java
@@ -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);
}
diff --git a/core/org.eclipse.cdt.ui.tests/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.ui.tests/META-INF/MANIFEST.MF
index 0ae4b96ec9f..2fe1e1e20b4 100644
--- a/core/org.eclipse.cdt.ui.tests/META-INF/MANIFEST.MF
+++ b/core/org.eclipse.cdt.ui.tests/META-INF/MANIFEST.MF
@@ -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,
diff --git a/core/org.eclipse.cdt.ui.tests/resources/refactoring/ExtractConstant.rts b/core/org.eclipse.cdt.ui.tests/resources/refactoring/ExtractConstant.rts
index e1a000aa607..54829d9960b 100644
--- a/core/org.eclipse.cdt.ui.tests/resources/refactoring/ExtractConstant.rts
+++ b/core/org.eclipse.cdt.ui.tests/resources/refactoring/ExtractConstant.rts
@@ -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()
diff --git a/core/org.eclipse.cdt.ui.tests/resources/refactoring/ExtractExpression.rts b/core/org.eclipse.cdt.ui.tests/resources/refactoring/ExtractExpression.rts
new file mode 100644
index 00000000000..15ea0199ad6
--- /dev/null
+++ b/core/org.eclipse.cdt.ui.tests/resources/refactoring/ExtractExpression.rts
@@ -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));
+}
+
diff --git a/core/org.eclipse.cdt.ui.tests/resources/refactoring/ExtractFunctionTemplates.rts b/core/org.eclipse.cdt.ui.tests/resources/refactoring/ExtractFunctionTemplates.rts
new file mode 100644
index 00000000000..2f1fa2e1733
--- /dev/null
+++ b/core/org.eclipse.cdt.ui.tests/resources/refactoring/ExtractFunctionTemplates.rts
@@ -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;
+}
+
diff --git a/core/org.eclipse.cdt.ui.tests/resources/refactoring/ExtractMethod.rts b/core/org.eclipse.cdt.ui.tests/resources/refactoring/ExtractMethod.rts
new file mode 100644
index 00000000000..58d114c9318
--- /dev/null
+++ b/core/org.eclipse.cdt.ui.tests/resources/refactoring/ExtractMethod.rts
@@ -0,0 +1,2139 @@
+//!ExtractFunctionRefactoringTest
+//#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 & i);
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+int A::foo()
+{
+ int i = 2;
+ //$++i;
+ help();$//
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//=
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+void A::exp(int & i)
+{
+ ++i;
+ help();
+}
+
+int A::foo()
+{
+ int i = 2;
+ exp(i);
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//@.config
+filename=A.cpp
+methodname=exp
+replaceduplicates=false
+returnvalue=false
+returnparameterindex=0
+
+//!Extract Function first extracted statement with leading comment
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@main.cpp
+int main(){
+
+ int i;
+ //$i= 7;$//
+ return i;
+}
+
+//=
+void exp(int & i)
+{
+ i = 7;
+}
+
+int main(){
+
+ int i;
+ exp(i);
+ return i;
+}
+
+//@.config
+filename=main.cpp
+methodname=exp
+replaceduplicates=false
+returnvalue=false
+returnparameterindex=0
+
+//!Extract Function last extracted statement with trailling comment
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@main.cpp
+int main(){
+
+ int i;
+ //$i= 7;$//
+ return i;
+}
+
+//=
+void exp(int & i)
+{
+ i = 7;
+}
+
+int main(){
+
+ int i;
+ exp(i);
+ return i;
+}
+
+//@.config
+filename=main.cpp
+methodname=exp
+replaceduplicates=false
+returnvalue=false
+returnparameterindex=0
+
+//!ExtractFunctionRefactoringTest variable defined in scope
+//#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();
+ int exp();
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}int A::foo()
+{
+ //$int i = 2;
+ ++i;
+ help();$//
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//=
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+int A::exp()
+{
+ int i = 2;
+ ++i;
+ help();
+ return i;
+}
+
+int A::foo()
+{
+ int i = exp();
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//!ExtractFunctionRefactoringTest with two variable defined in scope
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@.config
+fatalerror=true
+//@A.h
+#ifndef A_H_
+#define A_H_
+
+class A
+{
+public:
+ A();
+ virtual ~A();
+ int foo();
+
+private:
+ int help();
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+
+int A::foo()
+{
+ //$int o = 1;
+ int i = 2;
+ ++i;
+ o++;
+ help();$//
+ o++;
+ return i;
+}int A::help()
+{
+ return 42;
+}
+
+//!ExtractFunctionRefactoringTest with named typed field
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@A.h
+#ifndef A_H_
+#define A_H_
+
+#include "B.h"
+
+class A
+{
+public:
+ A();
+ virtual ~A();
+ void foo();
+ B b;
+
+private:
+ int help();
+};
+
+#endif /*A_H_*/
+
+//=
+#ifndef A_H_
+#define A_H_
+
+#include "B.h"
+
+class A
+{
+public:
+ A();
+ virtual ~A();
+ void foo();
+ B b;
+
+private:
+ int help();
+ void exp();
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+void A::foo()
+{
+ //$b = new B();
+ help();$//
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//=
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+void A::exp()
+{
+ b = new B();
+ help();
+}
+
+void A::foo()
+{
+ exp();
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//@B.h
+#ifndef B_H_
+#define B_H_
+
+class B
+{
+public:
+ B();
+ virtual ~B();
+};
+
+#endif /*B_H_*/
+
+//!ExtractFunctionRefactoringTest with named typed variable defined in scope
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@A.h
+#ifndef A_H_
+#define A_H_
+
+#include "B.h"
+
+class A
+{
+public:
+ A();
+ virtual ~A();
+ void foo();
+ B b;
+
+private:
+ int help();
+};
+
+#endif /*A_H_*/
+
+//=
+#ifndef A_H_
+#define A_H_
+
+#include "B.h"
+
+class A
+{
+public:
+ A();
+ virtual ~A();
+ void foo();
+ B b;
+
+private:
+ int help();
+ void exp();
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+void A::foo()
+{
+ //$b = new B();
+ help();$//
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//=
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+void A::exp()
+{
+ b = new B();
+ help();
+}
+
+void A::foo()
+{
+ exp();
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//@B.h
+#ifndef B_H_
+#define B_H_
+
+class B
+{
+public:
+ B();
+ virtual ~B();
+};
+
+#endif /*B_H_*/
+
+//!ExtractFunctionRefactoringTest with ObjectStyleMacro
+//#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 & i);
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+#define ZWO 2
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+int A::foo()
+{
+ int i = 2;
+ //$++i;
+ i += ZWO;
+ help();$//
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//=
+#include "A.h"
+
+#define ZWO 2
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+void A::exp(int & i)
+{
+ ++i;
+ i += ZWO;
+ help();
+}
+
+int A::foo()
+{
+ int i = 2;
+ exp(i);
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//!ExtractFunctionRefactoringTest with FunctionStyleMacro
+//#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 & i);
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+#define ADD(a,b) a + b + 2
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+int A::foo()
+{
+ int i = 2;
+ //$++i;
+ i = ADD(i, 42);
+ help();$//
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//=
+#include "A.h"
+
+#define ADD(a,b) a + b + 2
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+void A::exp(int & i)
+{
+ ++i;
+ i = ADD(i, 42);
+ help();
+}
+
+int A::foo()
+{
+ int i = 2;
+ exp(i);
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//!ExtractMethod with Pointer
+//#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 *& i);
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+int A::foo()
+{
+ int* i = new int(2);
+ //$++*i;
+ help();$//
+ return *i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//=
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+void A::exp(int *& i)
+{
+ ++*i;
+ help();
+}
+
+int A::foo()
+{
+ int* i = new int(2);
+ exp(i);
+ return *i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//!ExtractMethod with Pointer and Comment at the end
+//#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 *& i);
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+int A::foo()
+{
+ int* i = new int(2);
+ //$++*i;
+ help();
+ //A end-comment$//
+ return *i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//=
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+void A::exp(int *& i)
+{
+ ++*i;
+ help();
+}
+
+int A::foo()
+{
+ int* i = new int(2);
+ exp(i);
+ //A end-comment
+ return *i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//!ExtractMethod with Pointer and Comment
+//#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 *& i);
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+int A::foo()
+{
+ //A beautiful comment
+ int* i = new int(2);
+ //$++*i;
+ help();$//
+ return *i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//=
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+void A::exp(int *& i)
+{
+ ++*i;
+ help();
+}
+
+int A::foo()
+{
+ //A beautiful comment
+ int *i = new int(2);
+ exp(i);
+ return *i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//!ExtractFunctionRefactoringTest with Return Value
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@.config
+replaceduplicates=true
+returnvalue=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 i);
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+int A::foo()
+{
+ int i = 2;
+ //$++i;
+ help();$//
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//=
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+int A::exp(int i)
+{
+ ++i;
+ help();
+ return i;
+}
+
+int A::foo()
+{
+ int i = 2;
+ i = exp(i);
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//!ExtractFunctionRefactoringTest with Return Value and Ref Parameter
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@.config
+replaceduplicates=true
+returnvalue=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 i, int & b);
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+int A::foo()
+{
+ int i = 2;
+ int b = i;
+ //$++i;
+ i = i + b;
+ help();$//
+ ++b;
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//=
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+int A::exp(int i, int & b)
+{
+ ++i;
+ i = i + b;
+ help();
+ return i;
+}
+
+int A::foo()
+{
+ int i = 2;
+ int b = i;
+ i = exp(i, b);
+ ++b;
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//!ExtractFunctionRefactoringTest with Return Value and Ref Parameter and some more not used aferwards
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@.config
+replaceduplicates=true
+returnvalue=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 i, B *b, int y, float & x);
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+int A::foo()
+{
+ int i = 2;
+ float x = i;
+ B* b = new B();
+ int y = x + i;
+ //$++i;
+ b->hello(y);
+ i = i + x;
+ help();$//
+ ++x;
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//=
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+int A::exp(int i, B *b, int y, float & x)
+{
+ ++i;
+ b->hello(y);
+ i = i + x;
+ help();
+ return i;
+}
+
+int A::foo()
+{
+ int i = 2;
+ float x = i;
+ B* b = new B();
+ int y = x + i;
+ i = exp(i, b, y, x);
+ ++x;
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//!ExtractFunctionRefactoringTest with Return Value take the second and Ref Parameter and some more not used aferwards
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@.config
+returnparameterindex=1
+returnvalue=true
+//@A.h
+#ifndef A_H_
+#define A_H_
+
+#include "B.h"
+
+class A
+{
+public:
+ A();
+ virtual ~A();
+ int foo();
+
+private:
+ int help();
+};
+
+#endif /*A_H_*/
+
+//=
+#ifndef A_H_
+#define A_H_
+
+#include "B.h"
+
+class A
+{
+public:
+ A();
+ virtual ~A();
+ int foo();
+
+private:
+ int help();
+ float exp(int & i, B *b, int y, float x);
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+int A::foo()
+{
+ int i = 2;
+ float x = i;
+ B* b = new B();
+ int y = x + i;
+ //$++i;
+ b->hello(y);
+ i = i + x;
+ help();$//
+ ++x;
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//=
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+float A::exp(int & i, B *b, int y, float x)
+{
+ ++i;
+ b->hello(y);
+ i = i + x;
+ help();
+ return x;
+}
+
+int A::foo()
+{
+ int i = 2;
+ float x = i;
+ B* b = new B();
+ int y = x + i;
+ x = exp(i, b, y, x);
+ ++x;
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//@B.h
+#ifndef B_H_
+#define B_H_
+
+class B
+{
+public:
+ B();
+ virtual ~B();
+ void hello(float y);
+};
+
+#endif /*B_H_*/
+
+//!ExtractFunctionRefactoringTest with Return Value and a lot Ref Parameter
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@.config
+replaceduplicates=true
+returnvalue=true
+//@A.h
+#ifndef A_H_
+#define A_H_
+
+#include "B.h"
+
+class A
+{
+public:
+ A();
+ virtual ~A();
+ int foo();
+
+private:
+ int help();
+};
+
+#endif /*A_H_*/
+
+//=
+#ifndef A_H_
+#define A_H_
+
+#include "B.h"
+
+class A
+{
+public:
+ A();
+ virtual ~A();
+ int foo();
+
+private:
+ int help();
+ int exp(int i, B *& b, int & y, float & x);
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+int A::foo()
+{
+ int i = 2;
+ float x = i;
+ B* b = new B();
+ int y = x + i;
+ //$++i;
+ b->hello(y);
+ i = i + x;
+ help();$//
+ b->hello(y);
+ ++x;
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//=
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+int A::exp(int i, B *& b, int & y, float & x)
+{
+ ++i;
+ b->hello(y);
+ i = i + x;
+ help();
+ return i;
+}
+
+int A::foo()
+{
+ int i = 2;
+ float x = i;
+ B* b = new B();
+ int y = x + i;
+ i = exp(i, b, y, x);
+ b->hello(y);
+ ++x;
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//@B.h
+#ifndef B_H_
+#define B_H_
+
+class B
+{
+public:
+ B();
+ virtual ~B();
+ void hello(float y);
+};
+
+#endif /*B_H_*/
+//!ExtractMethod Bug #18 (problem with Qt's Q_FOREACH macro)
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@.config
+methodname=add_to_sum
+filename=main.cpp
+//@main.cpp
+#define for_each_int_in_array_with_index(list) for(int i = 0; i < sizeof(list) / sizeof(int); i++)
+
+struct Foreach
+{
+ int run()
+ {
+ int sum = 0;
+ int list [] = { 5, 6, 7 };
+ for_each_int_in_array_with_index(list)
+ {
+ //$sum += list[i];$//
+ }
+ return sum;
+ }
+};
+
+//=
+#define for_each_int_in_array_with_index(list) for(int i = 0; i < sizeof(list) / sizeof(int); i++)
+
+struct Foreach
+{
+ void add_to_sum(int & sum, int list[], int i)
+ {
+ sum += list[i];
+ }
+
+ int run()
+ {
+ int sum = 0;
+ int list [] = { 5, 6, 7 };
+ for_each_int_in_array_with_index(list)
+ {
+ add_to_sum(sum, list, i);
+ }
+ return sum;
+ }
+};
+
+//!ExtractFunctionRefactoringTest with Return Value take the second and Ref Parameter
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@.config
+returnparameterindex=1
+returnvalue=true
+//@A.h
+#ifndef A_H_
+#define A_H_
+
+#include "B.h"
+
+class A
+{
+public:
+ A();
+ virtual ~A();
+ int foo();
+
+private:
+ int help();
+};
+
+#endif /*A_H_*/
+
+//=
+#ifndef A_H_
+#define A_H_
+
+#include "B.h"
+
+class A
+{
+public:
+ A();
+ virtual ~A();
+ int foo();
+
+private:
+ int help();
+ B *exp(int & i, B *b, int & y, float & x);
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+int A::foo()
+{
+ int i = 2;
+ float x = i;
+ B* b = new B();
+ int y = x + i;
+ //$++i;
+ b->hello(y);
+ i = i + x;
+ help();$//
+ b->hello(y);
+ ++x;
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//=
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+B *A::exp(int & i, B *b, int & y, float & x)
+{
+ ++i;
+ b->hello(y);
+ i = i + x;
+ help();
+ return b;
+}
+
+int A::foo()
+{
+ int i = 2;
+ float x = i;
+ B* b = new B();
+ int y = x + i;
+ b = exp(i, b, y, x);
+ b->hello(y);
+ ++x;
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//@B.h
+#ifndef B_H_
+#define B_H_
+
+class B
+{
+public:
+ B();
+ virtual ~B();
+ void hello(float y);
+};
+
+#endif /*B_H_*/
+
+//!ExtractFunctionRefactoringTest protected visibility
+//#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();
+protected:
+ void exp(int & i);
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+int A::foo()
+{
+ int i = 2;
+ //$++i;
+ help();$//
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//=
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+void A::exp(int & i)
+{
+ ++i;
+ help();
+}
+
+int A::foo()
+{
+ int i = 2;
+ exp(i);
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//@.config
+filename=A.cpp
+methodname=exp
+replaceduplicates=false
+returnvalue=false
+returnparameterindex=0
+visibility=protected
+
+//!ExtractFunctionRefactoringTest public visibility
+//#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();
+ void exp(int & i);
+
+private:
+ int help();
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+int A::foo()
+{
+ int i = 2;
+ //$++i;
+ help();$//
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//=
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+void A::exp(int & i)
+{
+ ++i;
+ help();
+}
+
+int A::foo()
+{
+ int i = 2;
+ exp(i);
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//@.config
+filename=A.cpp
+methodname=exp
+replaceduplicates=false
+returnvalue=false
+returnparameterindex=0
+visibility=public
+
+//!ExtractFunctionRefactoringTest const Method Bug # 46
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@A.h
+#ifndef A_H_
+#define A_H_
+
+class A
+{
+public:
+ A();
+ virtual ~A();
+ int foo() const;
+
+private:
+ int help();
+};
+
+#endif /*A_H_*/
+
+//=
+#ifndef A_H_
+#define A_H_
+
+class A
+{
+public:
+ A();
+ virtual ~A();
+ int foo() const;
+
+private:
+ int help();
+ void exp(int & i) const;
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+int A::foo() const
+{
+ int i = 2;
+ //$++i;
+ help();$//
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//=
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+}
+void A::exp(int & i) const
+{
+ ++i;
+ help();
+}
+
+int A::foo() const
+{
+ int i = 2;
+ exp(i);
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//@.config
+filename=A.cpp
+methodname=exp
+replaceduplicates=false
+returnvalue=false
+returnparameterindex=0
+
+//!don't return variables that aren't used
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@.config
+filename=main.h
+methodname=loop
+//@main.h
+
+void method()
+{
+ //$for (int var = 0; var < 100; ++var) {
+ if(var < 50)
+ continue;
+ }$//
+}
+//=
+
+void loop()
+{
+ for(int var = 0;var < 100;++var){
+ if(var < 50)
+ continue;
+
+ }
+}
+
+void method()
+{
+ loop();
+}
+//!don't extract code that contains 'return'
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@.config
+filename=main.h
+fatalerror=true
+//@main.h
+
+void method()
+{
+ //$if(true)
+ return;$//
+ //unreachable
+}
+//!test if we don't allow to extract 'continue' Bug #53
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@.config
+fatalerror=true
+filename=A.h
+//@A.h
+
+void function()
+{
+ for (int var = 0; var < 100; ++var) {
+ //$if(var < 50)
+ continue;$//
+ }
+}
+
+//!ExtractMethod with Macros Bug #120 Extract Function generates superfluous characters
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@.config
+filename=Test.cpp
+methodname=createSuite
+//@Test.cpp
+#define CUTE(name) cute::test((&name),(#name))
+
+void runSuite(){
+ //$cute::suite s;
+ s.push_back(CUTE(thisIsATest));
+ s.push_back(CUTE(testFuerRainer));$//
+ cute::ide_listener lis;
+ cute::makeRunner(lis)(s, "The Suite");
+}
+//=
+#define CUTE(name) cute::test((&name),(#name))
+
+
+cute::suite createSuite()
+{
+ cute::suite s;
+ s.push_back(CUTE(thisIsATest));
+ s.push_back(CUTE(testFuerRainer));
+ return s;
+}
+
+void runSuite(){
+ cute::suite s = createSuite();
+ cute::ide_listener lis;
+ cute::makeRunner(lis)(s, "The Suite");
+}
+//! Bug #124 Extract Function with a Macro call in selected code "forgets" the macro
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@.config
+filename=Test.cpp
+methodname=runTest
+//@Test.cpp
+#define ASSERTM(msg,cond) if (!(cond)) throw cute::test_failure((msg),__FILE__,__LINE__)
+#define ASSERT(cond) ASSERTM(#cond, cond)
+
+void testFuerRainer(){
+ int i=int();
+ //$++i;
+ ASSERT (i);
+ --i;$//
+}
+
+//=
+#define ASSERTM(msg,cond) if (!(cond)) throw cute::test_failure((msg),__FILE__,__LINE__)
+#define ASSERT(cond) ASSERTM(#cond, cond)
+
+void runTest(int i)
+{
+ ++i;
+ ASSERT (i);
+ --i;
+}
+
+void testFuerRainer(){
+ int i=int();
+ runTest(i);
+}
+
+//! Bug #124 with comments Extract Function with a Macro call in selected code "forgets" the macro
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@.config
+filename=Test.cpp
+methodname=runTest
+//@Test.cpp
+#define ASSERTM(msg,cond) if (!(cond)) throw cute::test_failure((msg),__FILE__,__LINE__)
+#define ASSERT(cond) ASSERTM(#cond, cond)
+
+void testFuerRainer(){
+ int i=int();
+ //$++i;
+ ASSERT (i);
+ --i;$//
+}
+
+//=
+#define ASSERTM(msg,cond) if (!(cond)) throw cute::test_failure((msg),__FILE__,__LINE__)
+#define ASSERT(cond) ASSERTM(#cond, cond)
+
+void runTest(int i)
+{
+ ++i;
+ ASSERT (i);
+ --i;
+}
+
+void testFuerRainer(){
+ int i=int();
+ runTest(i);
+}
+
+//! Bug #137 String Array problem in Extract Function
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@.config
+filename=Test.cpp
+methodname=runTest
+//@Test.cpp
+#include <string>
+
+using namespace std;
+
+int const INITIAL_CAPACITY = 10;
+
+int main(){
+ int m_capacity;
+ //$m_capacity += INITIAL_CAPACITY;
+ string* newElements = new string[m_capacity];$//
+ newElements[0] = "s";
+}
+
+//=
+#include <string>
+
+using namespace std;
+
+int const INITIAL_CAPACITY = 10;
+
+
+string *runTest(int m_capacity)
+{
+ m_capacity += INITIAL_CAPACITY;
+ string *newElements = new string[m_capacity];
+ return newElements;
+}
+
+int main(){
+ int m_capacity;
+ string *newElements = runTest(m_capacity);
+ newElements[0] = "s";
+}
+
diff --git a/core/org.eclipse.cdt.ui.tests/resources/refactoring/ExtractMethodDuplicates.rts b/core/org.eclipse.cdt.ui.tests/resources/refactoring/ExtractMethodDuplicates.rts
new file mode 100644
index 00000000000..38844b321af
--- /dev/null
+++ b/core/org.eclipse.cdt.ui.tests/resources/refactoring/ExtractMethodDuplicates.rts
@@ -0,0 +1,1096 @@
+//!ExtractFunctionRefactoringTest with duplicates
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@.config
+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();
+ void exp(int & i);
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+ int i = 2;
+ ++i;
+ help();
+}
+int A::foo()
+{
+ int i = 2;
+ //$++i;
+ help();$//
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//=
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+ int i = 2;
+ exp(i);
+}
+void A::exp(int & i)
+{
+ ++i;
+ help();
+}
+
+int A::foo()
+{
+ int i = 2;
+ exp(i);
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//!ExtractFunctionRefactoringTest duplicates with different Names
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@.config
+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();
+ void exp(int & i);
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+ int oo = 99;
+ ++oo;
+ help();
+}
+int A::foo()
+{
+ int i = 2;
+ //$++i;
+ help();$//
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//=
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+ int oo = 99;
+ exp(oo);
+}
+void A::exp(int & i)
+{
+ ++i;
+ help();
+}
+
+int A::foo()
+{
+ int i = 2;
+ exp(i);
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//!ExtractFunctionRefactoringTest dublicate with field
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@.config
+replaceduplicates=true
+returnvalue=true
+//@A.h
+#ifndef A_H_
+#define A_H_
+
+class A
+{
+public:
+ A();
+ virtual ~A();
+ void foo();
+ int i;
+
+private:
+ int help();
+};
+
+#endif /*A_H_*/
+
+//=
+#ifndef A_H_
+#define A_H_
+
+class A
+{
+public:
+ A();
+ virtual ~A();
+ void foo();
+ int i;
+
+private:
+ int help();
+ int exp(int j, int & a);
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+ int j = 0;
+ i++;
+ j++;
+ help();
+}
+void A::foo()
+{
+ int j = 0;
+ int a = 1;
+ //$j++;
+ a++;
+ help();$//
+ a++;
+ j++;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//=
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+ int j = 0;
+ i = exp(i, j);
+}
+int A::exp(int j, int & a)
+{
+ j++;
+ a++;
+ help();
+ return j;
+}
+
+void A::foo()
+{
+ int j = 0;
+ int a = 1;
+ j = exp(j, a);
+ a++;
+ j++;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//!ExtractFunctionRefactoringTest dublicate with field in marked scope
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@.config
+replaceduplicates=true
+returnvalue=true
+//@A.h
+#ifndef A_H_
+#define A_H_
+
+class A
+{
+public:
+ A();
+ virtual ~A();
+ void foo();
+ int i;
+ int field;
+
+private:
+ int help();
+};
+
+#endif /*A_H_*/
+
+//=
+#ifndef A_H_
+#define A_H_
+
+class A
+{
+public:
+ A();
+ virtual ~A();
+ void foo();
+ int i;
+ int field;
+
+private:
+ int help();
+ int exp(int j);
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+ int j = 0;
+ int a = 1;
+ a++;
+ j++;
+ help();
+}
+void A::foo()
+{
+ int j = 0;
+
+ //$field++;
+ j++;
+ help();$//
+ field++;
+ j++;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//=
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+ int j = 0;
+ int a = 1;
+ a++;
+ j++;
+ help();
+}
+int A::exp(int j)
+{
+ field++;
+ j++;
+ help();
+ return j;
+}
+
+void A::foo()
+{
+ int j = 0;
+
+ j = exp(j);
+ field++;
+ j++;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//!ExtractFunctionRefactoringTest duplicates with different Names and return type
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@.config
+replaceduplicates=true
+returnvalue=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 i, float & j);
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+ int oo = 99;
+ float blabla = 0;
+ ++oo;
+ blabla += 1;
+ help();
+ blabla += 1;
+}
+int A::foo()
+{
+ int i = 2;
+ float j = 8989;
+ //$++i;
+ j+=1;
+ help();$//
+ j++;
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//=
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+ int oo = 99;
+ float blabla = 0;
+ oo = exp(oo, blabla);
+ blabla += 1;
+}
+int A::exp(int i, float & j)
+{
+ ++i;
+ j += 1;
+ help();
+ return i;
+}
+
+int A::foo()
+{
+ int i = 2;
+ float j = 8989;
+ i = exp(i, j);
+ j++;
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//!ExtractFunctionRefactoringTest duplicates with a lot of different Names an variable not used afterwards in the duplicate
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@.config
+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();
+ void exp(int & i, float j);
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+ int oo = 99;
+ float blabla = 0;
+ ++oo;
+ blabla += 1;
+ help();
+}
+int A::foo()
+{
+ int i = 2;
+ float j = 8989;
+ //$++i;
+ j+=1;
+ help();$//
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//=
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+ int oo = 99;
+ float blabla = 0;
+ exp(oo, blabla);
+}
+void A::exp(int & i, float j)
+{
+ ++i;
+ j += 1;
+ help();
+}
+
+int A::foo()
+{
+ int i = 2;
+ float j = 8989;
+ exp(i, j);
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//!ExtractFunctionRefactoringTest with duplicates name used afterwards in duplicate but not in original selection this is no dublicate
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@.config
+replaceduplicates=true
+//@A.h
+#ifndef A_H_
+#define A_H_
+
+class A
+{
+public:
+ A();
+ virtual ~A();
+ void foo();
+
+private:
+ int help();
+};
+
+#endif /*A_H_*/
+
+//=
+#ifndef A_H_
+#define A_H_
+
+class A
+{
+public:
+ A();
+ virtual ~A();
+ void foo();
+
+private:
+ int help();
+ void exp(int i);
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+ int i = 2;
+ ++i;// No Duplicate
+ help();
+ ++i;// this is the reason
+}
+void A::foo()
+{
+ int i = 2;
+ //$++i;
+ help();$//
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//=
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+ int i = 2;
+ ++i;// No Duplicate
+ help();
+ ++i;// this is the reason
+}
+void A::exp(int i)
+{
+ ++i;
+ help();
+}
+
+void A::foo()
+{
+ int i = 2;
+ exp(i);
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//!ExtractFunctionRefactoringTest with Return Value and a lot Ref Parameter and a method call
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@.config
+replaceduplicates=true
+returnvalue=true
+//@A.h
+#ifndef A_H_
+#define A_H_
+
+#include "B.h"
+
+class A
+{
+public:
+ A();
+ virtual ~A();
+ int foo();
+
+private:
+ int help();
+};
+
+#endif /*A_H_*/
+
+//=
+#ifndef A_H_
+#define A_H_
+
+#include "B.h"
+
+class A
+{
+public:
+ A();
+ virtual ~A();
+ int foo();
+
+private:
+ int help();
+ int exp(int i, B *& b, int & y, float & x);
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+ int i = 2;
+ float x = i;
+ B* b = new B();
+ int y = x + i;
+ ++i;
+ b->hello(y);
+ i = i + x;
+ help();
+ b->hello(y);
+ ++x;
+ i++;
+}
+int A::foo()
+{
+ int i = 2;
+ float x = i;
+ B* b = new B();
+ int y = x + i;
+ //$++i;
+ b->hello(y);
+ i = i + x;
+ help();$//
+ b->hello(y);
+ ++x;
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//=
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+ int i = 2;
+ float x = i;
+ B* b = new B();
+ int y = x + i;
+ i = exp(i, b, y, x);
+ b->hello(y);
+ ++x;
+ i++;
+}
+int A::exp(int i, B *& b, int & y, float & x)
+{
+ ++i;
+ b->hello(y);
+ i = i + x;
+ help();
+ return i;
+}
+
+int A::foo()
+{
+ int i = 2;
+ float x = i;
+ B* b = new B();
+ int y = x + i;
+ i = exp(i, b, y, x);
+ b->hello(y);
+ ++x;
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//@B.h
+#ifndef B_H_
+#define B_H_
+
+class B
+{
+public:
+ B();
+ virtual ~B();
+ void hello(float y);
+};
+
+#endif /*B_H_*/
+
+//!ExtractFunctionRefactoringTest with Return Value and a lot Ref Parameter and a method call, duplicate is not similar
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@.config
+replaceduplicates=true
+returnvalue=true
+//@A.h
+#ifndef A_H_
+#define A_H_
+
+#include "B.h"
+
+class A
+{
+public:
+ A();
+ virtual ~A();
+ int foo();
+
+private:
+ int help();
+};
+
+#endif /*A_H_*/
+
+//=
+#ifndef A_H_
+#define A_H_
+
+#include "B.h"
+
+class A
+{
+public:
+ A();
+ virtual ~A();
+ int foo();
+
+private:
+ int help();
+ int exp(int i, B *& b, int & y, float x);
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+ int i = 2;
+ float x = i;
+ B* b = new B();
+ int y = x + i;
+ ++i;
+ b->hello(y);
+ i = i + x;
+ help();
+ b->hello(y);
+ ++x;
+ i++;
+}
+int A::foo()
+{
+ int i = 2;
+ float x = i;
+ B* b = new B();
+ int y = x + i;
+ //$++i;
+ b->hello(y);
+ i = i + x;
+ help();$//
+ b->hello(y);
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//=
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+ int i = 2;
+ float x = i;
+ B* b = new B();
+ int y = x + i;
+ ++i;
+ b->hello(y);
+ i = i + x;
+ help();
+ b->hello(y);
+ ++x;
+ i++;
+}
+int A::exp(int i, B *& b, int & y, float x)
+{
+ ++i;
+ b->hello(y);
+ i = i + x;
+ help();
+ return i;
+}
+
+int A::foo()
+{
+ int i = 2;
+ float x = i;
+ B* b = new B();
+ int y = x + i;
+ i = exp(i, b, y, x);
+ b->hello(y);
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//@B.h
+#ifndef B_H_
+#define B_H_
+
+class B
+{
+public:
+ B();
+ virtual ~B();
+ void hello(float y);
+};
+
+#endif /*B_H_*/
+
+//!ExtractFunctionRefactoringTest with duplicates and comments
+//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
+//@.config
+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();
+ void exp(int & i);
+};
+
+#endif /*A_H_*/
+
+//@A.cpp
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+ int i = 2;
+ ++i;
+ help();
+}
+int A::foo()
+{
+ int i = 2;
+ //$++i;
+ help();$//
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
+//=
+#include "A.h"
+
+A::A()
+{
+}
+
+A::~A()
+{
+ int i = 2;
+ exp(i);
+}
+void A::exp(int & i)
+{
+ ++i;
+ help();
+}
+
+int A::foo()
+{
+ int i = 2;
+ exp(i);
+ return i;
+}
+
+int A::help()
+{
+ return 42;
+}
+
diff --git a/core/org.eclipse.cdt.ui.tests/resources/refactoring/ExtractMethodPreprocessor.rts b/core/org.eclipse.cdt.ui.tests/resources/refactoring/ExtractMethodPreprocessor.rts
new file mode 100644
index 00000000000..9263c03fb96
--- /dev/null
+++ b/core/org.eclipse.cdt.ui.tests/resources/refactoring/ExtractMethodPreprocessor.rts
@@ -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;
+}
+
diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/RefactoringTestSuite.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/RefactoringTestSuite.java
index 7a3fbf47520..1a0f3e7c193 100644
--- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/RefactoringTestSuite.java
+++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/RefactoringTestSuite.java
@@ -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;
diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/extractfunction/ExtractFunctionRefactoringTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/extractfunction/ExtractFunctionRefactoringTest.java
new file mode 100644
index 00000000000..4fac779c9d1
--- /dev/null
+++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/extractfunction/ExtractFunctionRefactoringTest.java
@@ -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$
+ }
+
+}
diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/extractfunction/ExtractFunctionTestSuite.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/extractfunction/ExtractFunctionTestSuite.java
new file mode 100644
index 00000000000..613e88bd22d
--- /dev/null
+++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/extractfunction/ExtractFunctionTestSuite.java
@@ -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;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/UtilTestSuite.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/UtilTestSuite.java
index b7270e19e01..37bf539f4fc 100644
--- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/UtilTestSuite.java
+++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/UtilTestSuite.java
@@ -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;
diff --git a/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF
index bfc38b4679c..a0b98067114 100644
--- a/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF
+++ b/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF
@@ -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,
diff --git a/core/org.eclipse.cdt.ui/plugin.properties b/core/org.eclipse.cdt.ui/plugin.properties
index abe99c4098d..fa7e0163118 100644
--- a/core/org.eclipse.cdt.ui/plugin.properties
+++ b/core/org.eclipse.cdt.ui/plugin.properties
@@ -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
diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml
index d9c4e83d501..3dc49bc5ebb 100644
--- a/core/org.eclipse.cdt.ui/plugin.xml
+++ b/core/org.eclipse.cdt.ui/plugin.xml
@@ -1151,6 +1151,13 @@
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"
menubarPath="org.eclipse.jdt.ui.refactoring.menu/codingGroup"
@@ -1606,6 +1613,11 @@
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"
contextId="org.eclipse.cdt.ui.cEditorScope"
@@ -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
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ICEditorActionDefinitionIds.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ICEditorActionDefinitionIds.java
index 0dfeca9dc11..436c2c988bc 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ICEditorActionDefinitionIds.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ICEditorActionDefinitionIds.java
@@ -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
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/CRefactoring.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/CRefactoring.java
index a261cbe2602..61fd238d171 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/CRefactoring.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/CRefactoring.java
@@ -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();
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/ChangeTreeSet.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/ChangeTreeSet.java
new file mode 100644
index 00000000000..3e5ea98cbde
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/ChangeTreeSet.java
@@ -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();
+ }
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/EqualityChecker.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/EqualityChecker.java
new file mode 100644
index 00000000000..42f5d0e12fd
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/EqualityChecker.java
@@ -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);
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/Messages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/Messages.java
index 87eaa0e3483..c796a39e9ec 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/Messages.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/Messages.java
@@ -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 {
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/NodeContainer.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/NodeContainer.java
new file mode 100644
index 00000000000..913ecb7f761
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/NodeContainer.java
@@ -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;
+ }
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/RefactoringRunner.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/RefactoringRunner.java
index f7ab9356367..d5b1805f593 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/RefactoringRunner.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/RefactoringRunner.java
@@ -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();
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractconstant/ExtractConstantRefactoringRunner.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractconstant/ExtractConstantRefactoringRunner.java
index 5933a61e7b0..2a6f285f0e8 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractconstant/ExtractConstantRefactoringRunner.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractconstant/ExtractConstantRefactoringRunner.java
@@ -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();
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ChooserComposite.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ChooserComposite.java
new file mode 100644
index 00000000000..83ac0597d65
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ChooserComposite.java
@@ -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);
+
+ }
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractExpression.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractExpression.java
new file mode 100644
index 00000000000..36b9a29dd47
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractExpression.java
@@ -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;
+ }
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractFunctionComposite.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractFunctionComposite.java
new file mode 100644
index 00000000000..5af1c941b94
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractFunctionComposite.java
@@ -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();
+ }
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractFunctionInformation.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractFunctionInformation.java
new file mode 100644
index 00000000000..b34b719a7ff
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractFunctionInformation.java
@@ -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;
+ }
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractFunctionInputPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractFunctionInputPage.java
new file mode 100644
index 00000000000..c46d20bfba8
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractFunctionInputPage.java
@@ -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$
+ }
+ }
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractFunctionRefactoring.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractFunctionRefactoring.java
new file mode 100644
index 00000000000..c3b21f44a2e
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractFunctionRefactoring.java
@@ -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);
+ }
+ }
+ }
+
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractFunctionRefactoringRunner.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractFunctionRefactoringRunner.java
new file mode 100644
index 00000000000..653e54f6bf6
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractFunctionRefactoringRunner.java
@@ -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.
+ }
+ }
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractFunctionRefactoringWizard.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractFunctionRefactoringWizard.java
new file mode 100644
index 00000000000..627a893b849
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractFunctionRefactoringWizard.java
@@ -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);
+
+ }
+
+}
+
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractStatement.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractStatement.java
new file mode 100644
index 00000000000..17bd3d47911
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractStatement.java
@@ -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;
+ }
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractedFunctionConstructionHelper.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractedFunctionConstructionHelper.java
new file mode 100644
index 00000000000..db6b5aac8de
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractedFunctionConstructionHelper.java
@@ -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;
+ }
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/Messages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/Messages.java
new file mode 100644
index 00000000000..f91c0d5509c
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/Messages.java
@@ -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);
+ }
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/NonExtractableStmtFinder.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/NonExtractableStmtFinder.java
new file mode 100644
index 00000000000..df474c898ee
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/NonExtractableStmtFinder.java
@@ -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;
+ }
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ReturnStatementFinder.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ReturnStatementFinder.java
new file mode 100644
index 00000000000..0f901d18346
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ReturnStatementFinder.java
@@ -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;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/SimilarFinderVisitor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/SimilarFinderVisitor.java
new file mode 100644
index 00000000000..83dd0ed65fb
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/SimilarFinderVisitor.java
@@ -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);
+ }
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/TrailName.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/TrailName.java
new file mode 100644
index 00000000000..6e1b0aa773d
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/TrailName.java
@@ -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();
+ }
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/TrailNodeEqualityChecker.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/TrailNodeEqualityChecker.java
new file mode 100644
index 00000000000..f407530f9e9
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/TrailNodeEqualityChecker.java
@@ -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;
+ }
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/messages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/messages.properties
new file mode 100644
index 00000000000..1fbb64204ae
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/messages.properties
@@ -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.
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/messages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/messages.properties
index a0c1a59f1a8..dc2f353c41b 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/messages.properties
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/messages.properties
@@ -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=\ \ No newline at end of file
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/ASTHelper.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/ASTHelper.java
new file mode 100644
index 00000000000..073f5a551db
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/ASTHelper.java
@@ -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;
+ }
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/CPPASTAllVisitor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/CPPASTAllVisitor.java
new file mode 100644
index 00000000000..3c4c8341a10
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/CPPASTAllVisitor.java
@@ -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;
+ }
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/CRefactoringActionGroup.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/CRefactoringActionGroup.java
index da24db11f83..4392ca6dcaf 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/CRefactoringActionGroup.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/CRefactoringActionGroup.java
@@ -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));
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/ExtractConstantAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/ExtractConstantAction.java
index d2cbc1e5cba..e25801eb781 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/ExtractConstantAction.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/ExtractConstantAction.java
@@ -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();
}
}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/ExtractFunctionAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/ExtractFunctionAction.java
new file mode 100644
index 00000000000..689574ee526
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/ExtractFunctionAction.java
@@ -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);
+ }
+
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/Messages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/Messages.java
index 95be61cea71..5e039d03ece 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/Messages.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/Messages.java
@@ -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);
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/messages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/messages.properties
index 65445cd7ca7..40b345509f4 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/messages.properties
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/messages.properties
@@ -11,3 +11,4 @@
CRefactoringActionGroup_menu=Refactor
CRenameAction_label=Rename...
ExtractConstantAction_label=Extract Constant...
+ExtractFunctionAction_label=Extract Function... (work in progress)

Back to the top