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();
|
||||
}
|
||||
|
||||
//!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.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
||||
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.cpp.ICPPASTBinaryExpression;
|
||||
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.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.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.CPPASTName;
|
||||
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.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.CPPNamespace;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTypedef;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer.NameInformation;
|
||||
|
@ -121,32 +126,99 @@ public class ExtractExpression extends ExtractedFunctionConstructionHelper {
|
|||
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 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) {
|
||||
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) {
|
||||
|
||||
CPPBasicType basicType = (CPPBasicType) expressionType;
|
||||
return createSimpleDeclSpecifier(basicType.getType());
|
||||
|
||||
} else if (expressionType instanceof CPPTypedef) {
|
||||
|
||||
return getDeclSpecForType(((CPPTypedef)expressionType));
|
||||
|
||||
} else if (expressionType instanceof CPPClassType) {
|
||||
|
||||
return getDeclSpecForType((CPPClassType)expressionType);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
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) {
|
||||
IASTSimpleDeclSpecifier declSpec = new CPPASTSimpleDeclSpecifier();
|
||||
|
|
Loading…
Add table
Reference in a new issue