mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
FIXED - bug 248238: Extract Method Produces Wrong Return Type
https://bugs.eclipse.org/bugs/show_bug.cgi?id=248238
This commit is contained in:
parent
3eef8dc96a
commit
55ac9ffc6a
2 changed files with 207 additions and 21 deletions
|
@ -2226,3 +2226,117 @@ void Test::test()
|
||||||
RetType v = exp();
|
RetType v = exp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//!Bug 248238: Extract Method Produces Wrong Return Type Or Just Fails Classtype
|
||||||
|
//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
|
||||||
|
//@.config
|
||||||
|
filename=Test.cpp
|
||||||
|
methodname=startTag
|
||||||
|
//@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"
|
||||||
|
|
||||||
|
test::string startTag(test::string & name)
|
||||||
|
{
|
||||||
|
return "<" + name + ">";
|
||||||
|
}
|
||||||
|
|
||||||
|
test::string toXML() {
|
||||||
|
test::string name;
|
||||||
|
name = "hello";
|
||||||
|
return startTag(name) + "</" + name + ">";
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//!Bug 248238: Extract Method Produces Wrong Return Type Or Just Fails Typedef
|
||||||
|
//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
|
||||||
|
//@.config
|
||||||
|
filename=Test.cpp
|
||||||
|
methodname=startTag
|
||||||
|
//@testString.h
|
||||||
|
|
||||||
|
namespace test{
|
||||||
|
|
||||||
|
class string2{
|
||||||
|
public:
|
||||||
|
|
||||||
|
friend string2 operator+(const string2& lhs, const string2& rhs)
|
||||||
|
{
|
||||||
|
return rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string2 operator+(const string2& rhs){return rhs;}
|
||||||
|
string2(char* cp){}
|
||||||
|
string2(){};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef string2 string;
|
||||||
|
}
|
||||||
|
|
||||||
|
//@Test.cpp
|
||||||
|
#include "testString.h"
|
||||||
|
|
||||||
|
test::string toXML() {
|
||||||
|
test::string name;
|
||||||
|
name = "hello";
|
||||||
|
return /*$*/"<" + name + ">"/*$$*/ + "</" + name + ">";
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//=
|
||||||
|
#include "testString.h"
|
||||||
|
|
||||||
|
test::string startTag(test::string & name)
|
||||||
|
{
|
||||||
|
return "<" + name + ">";
|
||||||
|
}
|
||||||
|
|
||||||
|
test::string toXML() {
|
||||||
|
test::string name;
|
||||||
|
name = "hello";
|
||||||
|
return startTag(name) + "</" + name + ">";
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.text.edits.TextEditGroup;
|
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.IASTBinaryExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||||
|
@ -29,21 +30,25 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
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.ICPPASTBinaryExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleDeclSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleDeclSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
|
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTBinaryExpression;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFieldReference;
|
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.CPPASTFunctionDefinition;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression;
|
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.CPPASTLiteralExpression;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNamedTypeSpecifier;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNamedTypeSpecifier;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTQualifiedName;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTReturnStatement;
|
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.CPPASTSimpleDeclSpecifier;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclaration;
|
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.CPPBasicType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassType;
|
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.CPPFunction;
|
||||||
|
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.core.dom.parser.cpp.CPPTypedef;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer.NameInformation;
|
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer.NameInformation;
|
||||||
|
@ -122,11 +127,35 @@ public class ExtractExpression extends ExtractedFunctionConstructionHelper {
|
||||||
case IASTBinaryExpression.op_divideAssign:
|
case IASTBinaryExpression.op_divideAssign:
|
||||||
case IASTBinaryExpression.op_assign:
|
case IASTBinaryExpression.op_assign:
|
||||||
|
|
||||||
/* Assume that the expression's return type is the same as the left operand's.*/
|
|
||||||
|
|
||||||
|
return getTypeFromBinaryExp(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null /* not yet handled */;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IASTDeclSpecifier getTypeFromBinaryExp(ICPPASTBinaryExpression node) {
|
||||||
|
if(node.getOperand1() instanceof ICPPASTBinaryExpression) {
|
||||||
|
IASTDeclSpecifier ret = getTypeFromBinaryExp(((CPPASTBinaryExpression)node.getOperand1()));
|
||||||
|
if(ret != null) return ret;
|
||||||
|
}else {
|
||||||
if(node.getOperand1() instanceof CPPASTIdExpression) {
|
if(node.getOperand1() instanceof CPPASTIdExpression) {
|
||||||
IType expressionType = ((CPPASTIdExpression) node.getOperand1()).getExpressionType();
|
return getBinaryExpressionType(((CPPASTIdExpression) node.getOperand1()).getExpressionType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(node.getOperand2() instanceof ICPPASTBinaryExpression) {
|
||||||
|
IASTDeclSpecifier ret = getTypeFromBinaryExp(((CPPASTBinaryExpression)node.getOperand2()));
|
||||||
|
if(ret != null) return ret;
|
||||||
|
}else {
|
||||||
|
if(node.getOperand2() instanceof CPPASTIdExpression) {
|
||||||
|
return getBinaryExpressionType(((CPPASTIdExpression) node.getOperand2()).getExpressionType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IASTDeclSpecifier getBinaryExpressionType(IType expressionType) {
|
||||||
if (expressionType instanceof CPPBasicType) {
|
if (expressionType instanceof CPPBasicType) {
|
||||||
|
|
||||||
CPPBasicType basicType = (CPPBasicType) expressionType;
|
CPPBasicType basicType = (CPPBasicType) expressionType;
|
||||||
|
@ -134,18 +163,61 @@ public class ExtractExpression extends ExtractedFunctionConstructionHelper {
|
||||||
|
|
||||||
} else if (expressionType instanceof CPPTypedef) {
|
} else if (expressionType instanceof CPPTypedef) {
|
||||||
|
|
||||||
CPPTypedef typedef = (CPPTypedef) expressionType;
|
return getDeclSpecForType(((CPPTypedef)expressionType));
|
||||||
return new CPPASTNamedTypeSpecifier((IASTName) typedef.getDefinition(), false);
|
|
||||||
|
|
||||||
} else if (expressionType instanceof CPPClassType) {
|
} else if (expressionType instanceof CPPClassType) {
|
||||||
|
|
||||||
CPPClassType classType = (CPPClassType) expressionType;
|
return getDeclSpecForType((CPPClassType)expressionType);
|
||||||
return new CPPASTNamedTypeSpecifier((IASTName) classType.getDefinition(), false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null /* not yet handled */;
|
private CPPASTNamedTypeSpecifier getDeclSpecForType(CPPClassType classType) {
|
||||||
|
|
||||||
|
IASTName name = null;
|
||||||
|
try {
|
||||||
|
IBinding bind = classType.getOwner();
|
||||||
|
if (bind instanceof CPPNamespace) {
|
||||||
|
ICPPASTQualifiedName qname = getQname(classType, bind);
|
||||||
|
qname.addName((IASTName) classType.getDefinition());
|
||||||
|
name = qname;
|
||||||
|
}else {
|
||||||
|
name = (IASTName) classType.getDefinition();
|
||||||
|
}
|
||||||
|
} catch (DOMException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CPPASTNamedTypeSpecifier(name, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ICPPASTQualifiedName getQname(IBinding classType, IBinding bind) {
|
||||||
|
CPPNamespace namespace = (CPPNamespace) bind;
|
||||||
|
char[][] names = namespace.getFullyQualifiedNameCharArray();
|
||||||
|
CPPASTQualifiedName qname = new CPPASTQualifiedName();
|
||||||
|
for (char[] string : names) {
|
||||||
|
qname.addName(new CPPASTName(string));
|
||||||
|
}
|
||||||
|
return qname;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IASTDeclSpecifier getDeclSpecForType(CPPTypedef typedef) {
|
||||||
|
IASTName name = null;
|
||||||
|
try {
|
||||||
|
IBinding bind = typedef.getOwner();
|
||||||
|
if (bind instanceof CPPNamespace) {
|
||||||
|
ICPPASTQualifiedName qname = getQname(typedef, bind);
|
||||||
|
qname.addName((IASTName) typedef.getDefinition());
|
||||||
|
name = qname;
|
||||||
|
}else {
|
||||||
|
name = (IASTName) typedef.getDefinition();
|
||||||
|
}
|
||||||
|
} catch (DOMException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return new CPPASTNamedTypeSpecifier(name, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IASTDeclSpecifier createSimpleDeclSpecifier(int type) {
|
private static IASTDeclSpecifier createSimpleDeclSpecifier(int type) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue