1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

FIXED - bug 248622: Extract function fails to extract several expressions

https://bugs.eclipse.org/bugs/show_bug.cgi?id=248622
This commit is contained in:
Emanuel Graf 2008-11-11 15:20:14 +00:00
parent a4a4923f35
commit db3ef0bebe
6 changed files with 977 additions and 7 deletions

View file

@ -2340,3 +2340,227 @@ int main() {
return 0;
}
//!Bug 248622: Extract function fails to extract several expressions; Selection at the end
//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
//@.config
filename=Test.cpp
methodname=endTag
//@testString.h
namespace test{
class string{
public:
friend string operator+(const string& lhs, const string& rhs)
{
return rhs;
}
string operator+(const string& rhs){return rhs;}
string(char* cp){}
string(){};
};
}
//@Test.cpp
#include "testString.h"
test::string toXML() {
test::string name;
name = "hello";
return "<" + name + ">" + /*$*/"</" + name + ">"/*$$*/;
}
int main() {
return 0;
}
//=
#include "testString.h"
wchar_t endTag(test::string name)
{
return "</" + name + ">";
}
test::string toXML() {
test::string name;
name = "hello";
return "<" + name + ">" + endTag(name);
}
int main() {
return 0;
}
//!Bug 248622: Extract function fails to extract several expressions; Selection in the middle
//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
//@.config
filename=Test.cpp
methodname=exp
//@testString.h
namespace test{
class string{
public:
friend string operator+(const string& lhs, const string& rhs)
{
return rhs;
}
string operator+(const string& rhs){return rhs;}
string(char* cp){}
string(){};
};
}
//@Test.cpp
#include "testString.h"
test::string toXML() {
test::string name;
name = "hello";
return "<" + name + /*$*/">" + "</"/*$$*/ + name + ">";
}
int main() {
return 0;
}
//=
#include "testString.h"
wchar_t exp()
{
return ">" + "</";
}
test::string toXML() {
test::string name;
name = "hello";
return "<" + name + exp() + name + ">";
}
int main() {
return 0;
}
//!Bug 248622: Extract function fails to extract several expressions; Selection at the end
//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
//@.config
filename=Test.cpp
methodname=endTag
//@testString.h
namespace test{
class string{
public:
friend string operator+(const string& lhs, const string& rhs)
{
return rhs;
}
string operator+(const string& rhs){return rhs;}
string(char* cp){}
string(){};
};
}
//@Test.cpp
#include "testString.h"
test::string toXML() {
test::string name;
name = "hello";
return "<" + name + ">" + /*$*/"</" + name + ">"/*$$*/;
}
int main() {
return 0;
}
//=
#include "testString.h"
wchar_t endTag(test::string name)
{
return "</" + name + ">";
}
test::string toXML() {
test::string name;
name = "hello";
return "<" + name + ">" + endTag(name);
}
int main() {
return 0;
}
//!Bug 248622: Extract function fails to extract several expressions; Selection in the middle
//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
//@.config
filename=Test.cpp
methodname=exp
//@testString.h
namespace test{
class string{
public:
friend string operator+(const string& lhs, const string& rhs)
{
return rhs;
}
string operator+(const string& rhs){return rhs;}
string(char* cp){}
string(){};
};
}
//@Test.cpp
#include "testString.h"
test::string toXML() {
test::string name;
name = "hello";
return "<" + name + /*$*/">" + "</"/*$$*/ + name + ">";
}
int main() {
return 0;
}
//=
#include "testString.h"
wchar_t exp()
{
return ">" + "</";
}
test::string toXML() {
test::string name;
name = "hello";
return "<" + name + exp() + name + ">";
}
int main() {
return 0;
}

View file

@ -0,0 +1,398 @@
/*******************************************************************************
* 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.tests.refactoring.utils;
import junit.framework.TestCase;
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
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.ICPPASTNewExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeConstructorExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypenameExpression;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTArraySubscriptExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTBinaryExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTConditionalExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTExpressionList;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTFieldReference;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTFunctionCallExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTIdExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTLiteralExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTName;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTTypeIdExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTUnaryExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTArraySubscriptExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTBinaryExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTConditionalExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTDeleteExpression;
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.CPPASTName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNewExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleTypeConstructorExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTypenameExpression;
import org.eclipse.cdt.internal.ui.refactoring.utils.ExpressionCopier;
/**
* @author Emanuel Graf IFS
*
*/
public class ExpressionCopyTest extends TestCase {
private ExpressionCopier copier = new ExpressionCopier();
/**
* Test method for {@link org.eclipse.cdt.internal.ui.refactoring.utils.ExpressionCopier#copy(org.eclipse.cdt.core.dom.ast.IASTIdExpression)}.
*/
public void testCopyIASTIdExpression() {
IASTIdExpression castIdExp = new CASTIdExpression();
castIdExp.setName(getTestName(ParserLanguage.C));
IASTIdExpression copy = (IASTIdExpression) copier.createCopy(castIdExp);
assertTrue(copy instanceof CASTIdExpression);
assertEquals(castIdExp, copy);
IASTIdExpression cppAstIdExp = new CPPASTIdExpression(getTestName(ParserLanguage.CPP));
copy = (IASTIdExpression) copier.createCopy(cppAstIdExp);
assertTrue(copy instanceof CPPASTIdExpression);
assertEquals(cppAstIdExp, copy);
}
/**
* Test method for {@link org.eclipse.cdt.internal.ui.refactoring.utils.ExpressionCopier#copy(org.eclipse.cdt.core.dom.ast.IASTLiteralExpression)}.
*/
public void testCopyIASTLiteralExpression() {
IASTLiteralExpression litExp = getTestLiteralExp(ParserLanguage.C);
IASTLiteralExpression copy = (IASTLiteralExpression) copier.createCopy(litExp);
assertTrue(copy instanceof CASTLiteralExpression);
assertEquals(litExp, copy);
litExp = getTestLiteralExp(ParserLanguage.CPP);
copy = (IASTLiteralExpression) copier.createCopy(litExp);
assertTrue(copy instanceof CPPASTLiteralExpression);
assertEquals(litExp, copy);
}
/**
* Test method for {@link org.eclipse.cdt.internal.ui.refactoring.utils.ExpressionCopier#copy(IASTArraySubscriptExpression)}.
*/
public void testCopyIASTArraySubscriptExpression() {
IASTIdExpression idExp = new CASTIdExpression(getTestName(ParserLanguage.C));
IASTLiteralExpression litExp =getTestLiteralExp(ParserLanguage.C);
IASTArraySubscriptExpression arrSubExp = new CASTArraySubscriptExpression(idExp, litExp);
IASTArraySubscriptExpression copy = (IASTArraySubscriptExpression) copier.createCopy(arrSubExp);
assertFalse(arrSubExp == copy);
assertTrue(copy instanceof CASTArraySubscriptExpression);
assertFalse(arrSubExp.getArrayExpression() == copy.getArrayExpression());
assertEquals(idExp, (IASTIdExpression)copy.getArrayExpression());
assertEquals(litExp, (IASTLiteralExpression)copy.getSubscriptExpression());
idExp = new CPPASTIdExpression(getTestName(ParserLanguage.CPP));
litExp = getTestLiteralExp(ParserLanguage.CPP);
arrSubExp = new CPPASTArraySubscriptExpression(idExp, litExp);
copy = (IASTArraySubscriptExpression) copier.createCopy(arrSubExp);
assertFalse(arrSubExp == copy);
assertTrue(copy instanceof CPPASTArraySubscriptExpression);
assertFalse(arrSubExp.getArrayExpression() == copy.getArrayExpression());
assertEquals(idExp, (IASTIdExpression)copy.getArrayExpression());
assertEquals(litExp, (IASTLiteralExpression)copy.getSubscriptExpression());
}
public void testCopyASTBinaryExpression() {
IASTExpression op1 = getTestLiteralExp(ParserLanguage.C);
IASTExpression op2 = getTestLiteralExp(ParserLanguage.C);
IASTBinaryExpression binExp = new CASTBinaryExpression(IASTBinaryExpression.op_plus, op1, op2);
IASTBinaryExpression copy = (IASTBinaryExpression) copier.createCopy(binExp);
assertTrue(copy instanceof CASTBinaryExpression);
assertEquals(binExp, copy);
op1 = getTestLiteralExp(ParserLanguage.CPP);
op2 = getTestLiteralExp(ParserLanguage.CPP);
binExp = new CPPASTBinaryExpression(IASTBinaryExpression.op_plus, op1, op2);
copy = (IASTBinaryExpression) copier.createCopy(binExp);
assertTrue(copy instanceof CPPASTBinaryExpression);
assertEquals(binExp, copy);
}
public void testCopyCastExpression() {
IASTExpression op1 = getTestLiteralExp(ParserLanguage.C);
//TODO
}
public void testCopyConditionalExpression() {
IASTExpression pos = getTestLiteralExp(ParserLanguage.C);
IASTExpression neg = getTestLiteralExp(ParserLanguage.C);
IASTExpression cond = getTestLiteralExp(ParserLanguage.C);
IASTConditionalExpression condExp = new CASTConditionalExpression(cond, pos, neg);
IASTConditionalExpression copy = (IASTConditionalExpression) copier.createCopy(condExp);
assertTrue(copy instanceof CASTConditionalExpression);
assertEquals(condExp, copy);
pos = getTestLiteralExp(ParserLanguage.CPP);
neg = getTestLiteralExp(ParserLanguage.CPP);
cond = getTestLiteralExp(ParserLanguage.CPP);
condExp = new CPPASTConditionalExpression(cond, pos, neg);
copy = (IASTConditionalExpression) copier.createCopy(condExp);
assertTrue(copy instanceof CPPASTConditionalExpression);
assertEquals(condExp, copy);
}
public void testCopyExpressionList() {
IASTLiteralExpression lit1 = getTestLiteralExp(ParserLanguage.C);
IASTLiteralExpression lit2 = getTestLiteralExp(ParserLanguage.C);
IASTExpressionList list = new CASTExpressionList();
list.addExpression(lit1);
list.addExpression(lit2);
IASTExpressionList copy = (IASTExpressionList) copier.createCopy(list);
assertFalse(list == copy);
IASTExpression[] orgList = list.getExpressions();
IASTExpression[] copyList = copy.getExpressions();
assertEquals(orgList.length, copyList.length);
for(int i = 0; i < orgList.length; ++i ) {
assertEquals((IASTLiteralExpression)orgList[i], (IASTLiteralExpression)copyList[i]);
}
}
public void testCopyFieldExpression() {
IASTName name = getTestName(ParserLanguage.C);
IASTIdExpression id = new CASTIdExpression();
id.setName(getTestName(ParserLanguage.C));
IASTFieldReference exp = new CASTFieldReference(name, id, true);
IASTFieldReference copy = (IASTFieldReference) copier.createCopy(exp);
assertEquals(exp, copy);
}
public void testCopyFunctionCallExpression() {
IASTIdExpression funcName = new CASTIdExpression(getTestName(ParserLanguage.C));
IASTLiteralExpression parameter = getTestLiteralExp(ParserLanguage.C);
IASTFunctionCallExpression funcCall = new CASTFunctionCallExpression();
funcCall.setFunctionNameExpression(funcName);
funcCall.setParameterExpression(parameter);
IASTFunctionCallExpression copy = (IASTFunctionCallExpression) copier.createCopy(funcCall);
assertEquals(funcCall, copy);
}
public void testCopyTypeIdExpression() {
IASTTypeIdExpression type = new CASTTypeIdExpression();
type.setOperator(IASTTypeIdExpression.op_sizeof);
IASTTypeIdExpression copy = (IASTTypeIdExpression) copier.createCopy(type);
assertEquals(type, copy);
}
public void testCopyUnaryExpression() {
IASTUnaryExpression exp = new CASTUnaryExpression();
exp.setOperand(new CASTIdExpression(getTestName(ParserLanguage.C)));
exp.setOperator(IASTUnaryExpression.op_postFixDecr);
IASTUnaryExpression copy = (IASTUnaryExpression) copier.createCopy(exp);
assertEquals(exp,copy);
}
public void testCopyDeleteExp() {
ICPPASTDeleteExpression exp = new CPPASTDeleteExpression();
exp.setIsVectored(true);
exp.setOperand(new CASTIdExpression(getTestName(ParserLanguage.CPP)));
ICPPASTDeleteExpression copy = (ICPPASTDeleteExpression) copier.createCopy(exp);
assertEquals(exp, copy);
}
public void testCopyNewExp() {
ICPPASTNewExpression exp = new CPPASTNewExpression();
IASTIdExpression placement = new CPPASTIdExpression(getTestName(ParserLanguage.CPP));
IASTLiteralExpression init = getTestLiteralExp(ParserLanguage.CPP);
exp.setNewPlacement(placement);
exp.setNewInitializer(init);
ICPPASTNewExpression copy = (ICPPASTNewExpression) copier.createCopy(exp);
assertEquals(exp, copy);
}
public void testCopySimpleTypeConstructor() {
ICPPASTSimpleTypeConstructorExpression exp = new CPPASTSimpleTypeConstructorExpression();
exp.setSimpleType(ICPPASTSimpleTypeConstructorExpression.t_int);
exp.setInitialValue(getTestLiteralExp(ParserLanguage.CPP));
ICPPASTSimpleTypeConstructorExpression copy = (ICPPASTSimpleTypeConstructorExpression) copier.createCopy(exp);
assertEquals(exp, copy);
}
public void testCopyTypeIdInitExp() {
//TODO
}
public void testCopyTypenameExp() {
ICPPASTTypenameExpression exp = new CPPASTTypenameExpression();
exp.setName(getTestName(ParserLanguage.CPP));
exp.setIsTemplate(true);
exp.setInitialValue(getTestLiteralExp(ParserLanguage.CPP));
ICPPASTTypenameExpression copy = (ICPPASTTypenameExpression) copier.createCopy(exp);
assertEquals(exp, copy);
}
private void assertEquals(ICPPASTTypenameExpression exp, ICPPASTTypenameExpression copy) {
assertFalse(exp == copy);
assertFalse(exp.getName() == copy.getName());
assertFalse(exp.getInitialValue() == copy.getInitialValue());
assertEquals(exp.getName().toCharArray(), copy.getName().toCharArray());
assertEquals(exp.isTemplate(), copy.isTemplate());
}
private void assertEquals(ICPPASTSimpleTypeConstructorExpression exp, ICPPASTSimpleTypeConstructorExpression copy) {
assertFalse(exp == copy);
assertEquals(exp.getSimpleType(), copy.getSimpleType());
assertFalse(exp.getInitialValue() == copy.getInitialValue());
assertEquals((IASTLiteralExpression)exp.getInitialValue(), (IASTLiteralExpression)copy.getInitialValue());
}
private void assertEquals(ICPPASTNewExpression exp, ICPPASTNewExpression copy) {
assertFalse(exp == copy);
assertEquals(exp.isGlobal(), copy.isGlobal());
assertEquals(exp.isNewTypeId(), copy.isNewTypeId());
assertFalse(exp.getNewInitializer() == copy.getNewInitializer());
assertFalse(exp.getNewPlacement() == copy.getNewPlacement());
}
private void assertEquals(ICPPASTDeleteExpression exp, ICPPASTDeleteExpression copy) {
assertFalse(exp == copy);
assertEquals(exp.isGlobal(), copy.isGlobal());
assertEquals(exp.isVectored(), copy.isVectored());
assertFalse(exp.getOperand() == copy.getOperand());
assertEquals((IASTIdExpression)exp.getOperand(), (IASTIdExpression)copy.getOperand());
}
private void assertEquals(IASTUnaryExpression exp, IASTUnaryExpression copy) {
assertFalse(exp == copy);
assertEquals(exp.getOperator(), copy.getOperator());
assertEquals((IASTIdExpression)exp.getOperand(),(IASTIdExpression)copy.getOperand());
}
private void assertEquals(IASTTypeIdExpression exp, IASTTypeIdExpression copy) {
assertFalse(exp == copy);
assertEquals(exp.getOperator(), copy.getOperator());
}
private void assertEquals(IASTFunctionCallExpression exp, IASTFunctionCallExpression copy) {
assertFalse(exp == copy);
assertFalse(exp.getFunctionNameExpression() == copy.getFunctionNameExpression());
assertFalse(exp.getParameterExpression() == copy.getParameterExpression());
assertEquals((IASTIdExpression)exp.getFunctionNameExpression(), (IASTIdExpression)copy.getFunctionNameExpression());
assertEquals((IASTLiteralExpression)exp.getParameterExpression(),(IASTLiteralExpression)copy.getParameterExpression());
}
private void assertEquals(IASTFieldReference exp, IASTFieldReference copy) {
assertFalse(exp == copy);
assertEquals(exp.getFieldName().toString(), copy.getFieldName().toString());
assertEquals((IASTIdExpression) exp.getFieldOwner(), (IASTIdExpression) copy.getFieldOwner());
assertEquals(exp.isPointerDereference(), copy.isPointerDereference());
if (exp instanceof ICPPASTFieldReference) {
assertEquals(((ICPPASTFieldReference)exp.getFieldOwner()).isTemplate(),((ICPPASTFieldReference)copy.getFieldOwner()).isTemplate());
}
}
private void assertEquals(IASTConditionalExpression condExp, IASTConditionalExpression copy) {
assertFalse(condExp == copy);
assertEquals((IASTLiteralExpression) condExp.getLogicalConditionExpression(),
(IASTLiteralExpression) copy.getLogicalConditionExpression());
assertEquals((IASTLiteralExpression) condExp.getPositiveResultExpression(),
(IASTLiteralExpression) copy.getPositiveResultExpression());
assertEquals((IASTLiteralExpression) condExp.getNegativeResultExpression(),
(IASTLiteralExpression) copy.getNegativeResultExpression());
}
private void assertEquals(IASTBinaryExpression binExp,
IASTBinaryExpression copy) {
assertFalse(binExp == copy);
assertEquals((IASTLiteralExpression)binExp.getOperand1(), (IASTLiteralExpression)copy.getOperand1());
assertEquals((IASTLiteralExpression)binExp.getOperand2(), (IASTLiteralExpression)copy.getOperand2());
assertEquals(binExp.getOperator(), copy.getOperator());
}
private void assertEquals(IASTLiteralExpression org,
IASTLiteralExpression copy) {
assertFalse(org == copy);
assertEquals(org.getKind(), copy.getKind());
assertEquals(org.toString(), copy.toString());
}
private void assertEquals(IASTIdExpression castIdExp, IASTIdExpression copy) {
assertFalse(castIdExp == copy);
assertEquals(castIdExp.getName().toString(), copy.getName().toString());
}
private IASTLiteralExpression getTestLiteralExp(ParserLanguage lang) {
if(lang.isCPP()) {
return new CPPASTLiteralExpression(IASTLiteralExpression.lk_integer_constant, new char[]{'0'});
}else {
return new CASTLiteralExpression(IASTLiteralExpression.lk_integer_constant, new char[]{'0'});
}
}
private IASTName getTestName(ParserLanguage lang) {
if(lang.isCPP()) {
return new CPPASTName(new char[] {'t', 'e', 's', 't'});
}else {
return new CASTName(new char[] {'t', 'e', 's', 't'});
}
}
}

View file

@ -27,6 +27,7 @@ public class UtilTestSuite extends TestSuite {
suite.addTest(IdentifierHelperTest.suite());
suite.addTest(RefactoringTester.suite("TranslationUnitHelperTest", "resources/refactoring/TranslationunitHelper.rts")); //$NON-NLS-1$ //$NON-NLS-2$
suite.addTestSuite(PseudoNameGeneratorTest.class);
suite.addTestSuite(ExpressionCopyTest.class);
return suite;
}
}

View file

@ -52,6 +52,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPNamespace;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTypedef;
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer.NameInformation;
import org.eclipse.cdt.internal.ui.refactoring.utils.ExpressionCopier;
/**
* Handles the extraction of expression nodes, like return type determination.
@ -60,6 +61,8 @@ import org.eclipse.cdt.internal.ui.refactoring.NodeContainer.NameInformation;
*
*/
public class ExtractExpression extends ExtractedFunctionConstructionHelper {
ExpressionCopier expCopier = new ExpressionCopier();
final static char[] ZERO= {'0'};
@Override
@ -71,7 +74,21 @@ public class ExtractExpression extends ExtractedFunctionConstructionHelper {
statement.setReturnValue(nullReturnExp);
ASTRewrite nestedRewrite = rewrite.insertBefore(compound, null, statement, group);
nestedRewrite.replace(nullReturnExp, list.get(0), group);
nestedRewrite.replace(nullReturnExp, getExpression(list), group);
}
private IASTExpression getExpression(List<IASTNode> list) {
if(list.size()> 1 ) {
CPPASTBinaryExpression bExp = new CPPASTBinaryExpression();
bExp.setParent(list.get(0).getParent());
bExp.setOperand1(expCopier.createCopy((IASTExpression) list.get(0)));
bExp.setOperator(((IASTBinaryExpression)list.get(1).getParent()).getOperator());
bExp.setOperand2(getExpression(list.subList(1, list.size())));
return bExp;
}else {
return expCopier.createCopy((IASTExpression) list.get(0));
}
}

View file

@ -12,6 +12,7 @@
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;
@ -45,6 +46,7 @@ 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.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
@ -70,6 +72,7 @@ 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.CPPASTBinaryExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTCompoundStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTDeclarationStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTDeclarator;
@ -79,6 +82,7 @@ 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.CPPASTLiteralExpression;
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;
@ -174,11 +178,6 @@ public class ExtractFunctionRefactoring extends CRefactoring {
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 = NodeHelper.findMethodContext(container.getNodesToWrite().get(0), getIndex());
info.setMethodContext(context);
@ -307,7 +306,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
CPPASTDeclarationStatement declarationStatement = new CPPASTDeclarationStatement((IASTDeclaration) methodCall);
methodCall = declarationStatement;
}
rewriter.replace(firstNodeToWrite, methodCall, editGroup);
insertCallintoTree(methodCall, container.getNodesToWrite(), rewriter, editGroup);
for (IASTNode node : container.getNodesToWrite()) {
if (node != firstNodeToWrite) {
rewriter.remove(node, editGroup);
@ -315,6 +314,35 @@ public class ExtractFunctionRefactoring extends CRefactoring {
}
}
private void insertCallintoTree(IASTNode methodCall, List<IASTNode> list,
ASTRewrite rewriter, TextEditGroup editGroup) {
IASTNode firstNode = list.get(0);
if(list.size() > 1 && firstNode.getParent() instanceof IASTBinaryExpression &&
firstNode.getParent().getParent() instanceof IASTBinaryExpression) {
IASTBinaryExpression parent = (IASTBinaryExpression) firstNode.getParent();
IASTExpression leftSubTree = parent.getOperand1();
int op = parent.getOperator();
IASTBinaryExpression newParentNode = new CPPASTBinaryExpression();
CPPASTLiteralExpression placeholder = new CPPASTLiteralExpression(IASTLiteralExpression.lk_integer_constant, "0"); //$NON-NLS-1$
IASTBinaryExpression rootBinExp = getRootBinExp(parent, list);
newParentNode.setParent(rootBinExp.getParent());
newParentNode.setOperand1(placeholder);
newParentNode.setOperator(op);
newParentNode.setOperand2((IASTExpression) methodCall); // TODO check
ASTRewrite callRewrite = rewriter.replace(rootBinExp, newParentNode, editGroup);
callRewrite.replace(placeholder, leftSubTree, editGroup);
}else {
rewriter.replace(firstNode, methodCall, editGroup);
}
}
private IASTBinaryExpression getRootBinExp(IASTBinaryExpression binExp, List<IASTNode> nodeList) {
while(binExp.getParent() instanceof IASTBinaryExpression && nodeList.contains(((IASTBinaryExpression) binExp.getParent()).getOperand2())) {
binExp = (IASTBinaryExpression) binExp.getParent();
}
return binExp;
}
private void createMethodDefinition(final IASTName astMethodName,
MethodContext context, IASTNode firstNode,
final IFile implementationFile, ModificationCollector collector) {

View file

@ -0,0 +1,302 @@
/*******************************************************************************
* 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.internal.ui.refactoring.utils;
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTCastExpression;
import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression;
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.ICPPASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeConstructorExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypenameExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTArraySubscriptExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTBinaryExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTCastExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTConditionalExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTExpressionList;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTFieldReference;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTFunctionCallExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTIdExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTLiteralExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTTypeIdExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTUnaryExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTArraySubscriptExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTBinaryExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTCastExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTConditionalExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTDeleteExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTExpressionList;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFieldReference;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionCallExpression;
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.CPPASTName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNewExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleTypeConstructorExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTypeIdExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTypenameExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTUnaryExpression;
/**
*
* Creates a copy of an {@link IASTExpression}.
*
* @author Emanuel Graf IFS
*
*/
public class ExpressionCopier {
public IASTExpression createCopy(IASTExpression exp) {
if (exp instanceof IASTLiteralExpression) {
return copy((IASTLiteralExpression) exp);
}
if(exp instanceof IASTIdExpression) {
return copy((IASTIdExpression)exp);
}
if(exp instanceof IASTArraySubscriptExpression) {
return copy((IASTArraySubscriptExpression)exp);
}
if(exp instanceof IASTBinaryExpression) {
return copy((IASTBinaryExpression)exp);
}
if(exp instanceof IASTCastExpression) {
return copy((IASTCastExpression)exp);
}
if(exp instanceof IASTConditionalExpression) {
return copy((IASTConditionalExpression)exp);
}
if(exp instanceof IASTExpressionList) {
return copy((IASTExpressionList)exp);
}
if(exp instanceof IASTFieldReference) {
return copy((IASTFieldReference)exp);
}
if(exp instanceof IASTFunctionCallExpression) {
return copy((IASTFunctionCallExpression)exp);
}
if(exp instanceof IASTTypeIdExpression) {
return copy((IASTTypeIdExpression)exp);
}
if(exp instanceof IASTUnaryExpression) {
return copy((IASTUnaryExpression)exp);
}
if(exp instanceof ICPPASTDeleteExpression) {
return copy((ICPPASTDeleteExpression)exp);
}
if(exp instanceof ICPPASTNewExpression) {
return copy((ICPPASTNewExpression)exp);
}
if(exp instanceof ICPPASTSimpleTypeConstructorExpression) {
return copy((ICPPASTSimpleTypeConstructorExpression)exp);
}
if(exp instanceof ICPPASTTypenameExpression) {
return copy((ICPPASTTypenameExpression)exp);
}
return exp;
}
private IASTExpression copy(ICPPASTTypenameExpression exp) {
ICPPASTTypenameExpression copy = new CPPASTTypenameExpression();
copy.setIsTemplate(exp.isTemplate());
copy.setName(new CPPASTName(exp.getName().toCharArray()));
copy.setInitialValue(createCopy(exp.getInitialValue()));
return copy;
}
private IASTExpression copy(ICPPASTSimpleTypeConstructorExpression exp) {
ICPPASTSimpleTypeConstructorExpression copy = new CPPASTSimpleTypeConstructorExpression();
copy.setSimpleType(exp.getSimpleType());
copy.setInitialValue(createCopy(exp.getInitialValue()));
return copy;
}
private IASTExpression copy(ICPPASTNewExpression exp) {
ICPPASTNewExpression copy = new CPPASTNewExpression();
copy.setIsGlobal(exp.isGlobal());
copy.setIsNewTypeId(exp.isNewTypeId());
copy.setNewInitializer(createCopy(exp.getNewInitializer()));
copy.setNewPlacement(createCopy(exp.getNewPlacement()));
copy.setTypeId(exp.getTypeId());
return copy;
}
private IASTExpression copy(ICPPASTDeleteExpression exp) {
ICPPASTDeleteExpression copy = new CPPASTDeleteExpression();
copy.setIsGlobal(exp.isGlobal());
copy.setIsVectored(exp.isVectored());
copy.setOperand(createCopy(exp.getOperand()));
return copy;
}
private IASTExpression copy(IASTUnaryExpression exp) {
IASTUnaryExpression copy;
if(exp instanceof CPPASTUnaryExpression) {
copy = new CPPASTUnaryExpression();
}else {
copy = new CASTUnaryExpression();
}
copy.setOperator(exp.getOperator());
copy.setOperand(createCopy(exp.getOperand()));
return copy;
}
private IASTTypeIdExpression copy(IASTTypeIdExpression exp) {
IASTTypeIdExpression copy;
if(exp instanceof CPPASTTypeIdExpression) {
copy = new CPPASTTypeIdExpression();
}else {
copy = new CASTTypeIdExpression();
}
copy.setOperator(exp.getOperator());
copy.setTypeId(exp.getTypeId());
return copy;
}
private IASTExpression copy(IASTFunctionCallExpression exp) {
IASTFunctionCallExpression copy;
if(exp instanceof CPPASTFunctionCallExpression) {
copy = new CPPASTFunctionCallExpression();
}else {
copy = new CASTFunctionCallExpression();
}
copy.setFunctionNameExpression(createCopy(exp.getFunctionNameExpression()));
copy.setParameterExpression(createCopy(exp.getParameterExpression()));
return copy;
}
private IASTBinaryExpression copy(IASTBinaryExpression exp) {
IASTBinaryExpression copy;
if(exp instanceof CPPASTBinaryExpression) {
copy = new CPPASTBinaryExpression();
}else {
copy = new CASTBinaryExpression();
}
copy.setOperand1(createCopy(exp.getOperand1()));
copy.setOperand2(createCopy(exp.getOperand2()));
copy.setOperator(exp.getOperator());
return copy;
}
private IASTArraySubscriptExpression copy(IASTArraySubscriptExpression exp) {
IASTArraySubscriptExpression copy;
if(exp instanceof CPPASTArraySubscriptExpression) {
copy = new CPPASTArraySubscriptExpression();
}else {
copy = new CASTArraySubscriptExpression();
}
copy.setArrayExpression(createCopy(exp.getArrayExpression()));
copy.setSubscriptExpression(createCopy(exp.getSubscriptExpression()));
return copy;
}
private IASTIdExpression copy(IASTIdExpression exp) {
IASTIdExpression copy;
if (exp instanceof CPPASTIdExpression) {
copy = new CPPASTIdExpression();
}else {
copy = new CASTIdExpression();
}
copy.setName(exp.getName());
return copy;
}
private IASTLiteralExpression copy(IASTLiteralExpression exp) {
IASTLiteralExpression copy;
if (exp instanceof ICPPASTLiteralExpression) {
copy = new CPPASTLiteralExpression();
}else {
copy = new CASTLiteralExpression();
}
copy.setKind(exp.getKind());
copy.setValue(exp.toString());
return copy;
}
private IASTCastExpression copy(IASTCastExpression exp) {
IASTCastExpression copy;
if(exp instanceof ICPPASTCastExpression) {
copy = new CPPASTCastExpression();
}else {
copy = new CASTCastExpression();
}
copy.setOperator(exp.getOperator());
copy.setOperand(createCopy(exp.getOperand()));
copy.setTypeId(exp.getTypeId());
return copy;
}
private IASTConditionalExpression copy(IASTConditionalExpression exp) {
IASTConditionalExpression copy;
if(exp instanceof CASTConditionalExpression) {
copy = new CASTConditionalExpression();
}else {
copy = new CPPASTConditionalExpression();
}
copy.setLogicalConditionExpression(createCopy(exp.getLogicalConditionExpression()));
copy.setPositiveResultExpression(createCopy(exp.getPositiveResultExpression()));
copy.setNegativeResultExpression(createCopy(exp.getNegativeResultExpression()));
return copy;
}
private IASTExpressionList copy(IASTExpressionList exp) {
IASTExpressionList copy;
if(exp instanceof CASTExpressionList) {
copy = new CASTExpressionList();
}else {
copy = new CPPASTExpressionList();
}
for (IASTExpression expression : exp.getExpressions()) {
copy.addExpression(createCopy(expression));
}
return copy;
}
private IASTFieldReference copy(IASTFieldReference exp) {
IASTFieldReference copy;
if (exp instanceof ICPPASTFieldReference) {
copy = new CPPASTFieldReference();
((ICPPASTFieldReference)copy).setIsTemplate(((ICPPASTFieldReference)exp).isTemplate());
}else {
copy = new CASTFieldReference();
}
copy.setFieldName(exp.getFieldName());
copy.setFieldOwner(createCopy(exp.getFieldOwner()));
copy.setIsPointerDereference(exp.isPointerDereference());
return copy;
}
}