mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-07 17:56:01 +02:00
Bug 422727 - Extract Function doesn't properly handle auto types
This commit is contained in:
parent
eb421c9fec
commit
772066afce
7 changed files with 135 additions and 151 deletions
|
@ -2167,6 +2167,51 @@ public class ExtractFunctionRefactoringTest extends RefactoringTestBase {
|
||||||
assertRefactoringSuccess();
|
assertRefactoringSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Test.h
|
||||||
|
//#ifndef TEST_H_
|
||||||
|
//#define TEST_H_
|
||||||
|
//
|
||||||
|
//struct A {
|
||||||
|
// typedef A B;
|
||||||
|
// const B* m(const char* p);
|
||||||
|
//};
|
||||||
|
//
|
||||||
|
//#endif // TEST_H_
|
||||||
|
//====================
|
||||||
|
//#ifndef TEST_H_
|
||||||
|
//#define TEST_H_
|
||||||
|
//
|
||||||
|
//struct A {
|
||||||
|
// typedef A B;
|
||||||
|
// const B* m(const char* p);
|
||||||
|
//};
|
||||||
|
//
|
||||||
|
//#endif // TEST_H_
|
||||||
|
|
||||||
|
//Test.cpp
|
||||||
|
//#include "Test.h"
|
||||||
|
//
|
||||||
|
//void test() {
|
||||||
|
// auto x = new A();
|
||||||
|
// const auto* y = "";
|
||||||
|
// auto r = /*$*/x->m(y)/*$$*/;
|
||||||
|
//}
|
||||||
|
//====================
|
||||||
|
//#include "Test.h"
|
||||||
|
//
|
||||||
|
//const A::B* extracted(A* x, const char* y) {
|
||||||
|
// return x->m(y);
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//void test() {
|
||||||
|
// auto x = new A();
|
||||||
|
// const auto* y = "";
|
||||||
|
// auto r = extracted(x, y);
|
||||||
|
//}
|
||||||
|
public void testAuto_Bug422727() throws Exception {
|
||||||
|
assertRefactoringSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
//testString.h
|
//testString.h
|
||||||
//namespace test {
|
//namespace test {
|
||||||
//
|
//
|
||||||
|
@ -2300,7 +2345,7 @@ public class ExtractFunctionRefactoringTest extends RefactoringTestBase {
|
||||||
//====================
|
//====================
|
||||||
//#include "testString.h"
|
//#include "testString.h"
|
||||||
//
|
//
|
||||||
//const char endTag(test::string name) {
|
//const char* endTag(test::string name) {
|
||||||
// return "</" + name + ">";
|
// return "</" + name + ">";
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
|
@ -2350,7 +2395,7 @@ public class ExtractFunctionRefactoringTest extends RefactoringTestBase {
|
||||||
//====================
|
//====================
|
||||||
//#include "testString.h"
|
//#include "testString.h"
|
||||||
//
|
//
|
||||||
//const char extracted() {
|
//const char* extracted() {
|
||||||
// return ">" + "</";
|
// return ">" + "</";
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2008, 2012 Institute for Software, HSR Hochschule fuer Technik
|
* Copyright (c) 2008, 2013 Institute for Software, HSR Hochschule fuer Technik
|
||||||
* Rapperswil, University of applied sciences and others
|
* Rapperswil, University of applied sciences and others
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
@ -21,19 +21,23 @@ import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
|
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTLabelStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
|
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.INodeFactory;
|
import org.eclipse.cdt.core.dom.ast.INodeFactory;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNodeFactory;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNodeFactory;
|
||||||
|
import org.eclipse.cdt.core.dom.rewrite.DeclarationGenerator;
|
||||||
import org.eclipse.cdt.core.dom.rewrite.TypeHelper;
|
import org.eclipse.cdt.core.dom.rewrite.TypeHelper;
|
||||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
||||||
import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.ASTWriterVisitor;
|
import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.ASTWriterVisitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -185,7 +189,8 @@ public class NameInformation {
|
||||||
}
|
}
|
||||||
|
|
||||||
void setDeclarationName(IASTName declarationName) {
|
void setDeclarationName(IASTName declarationName) {
|
||||||
Assert.isTrue(declarationName.getParent() instanceof IASTDeclarator);
|
Assert.isTrue(declarationName.getPropertyInParent() == IASTDeclarator.DECLARATOR_NAME ||
|
||||||
|
declarationName.getPropertyInParent() == IASTLabelStatement.NAME);
|
||||||
this.declarationName = declarationName;
|
this.declarationName = declarationName;
|
||||||
indirection = null;
|
indirection = null;
|
||||||
}
|
}
|
||||||
|
@ -210,6 +215,8 @@ public class NameInformation {
|
||||||
return newTypeName;
|
return newTypeName;
|
||||||
INodeFactory nodeFactory = name.getTranslationUnit().getASTNodeFactory();
|
INodeFactory nodeFactory = name.getTranslationUnit().getASTNodeFactory();
|
||||||
IASTParameterDeclaration declaration = getParameterDeclaration(nodeFactory, null);
|
IASTParameterDeclaration declaration = getParameterDeclaration(nodeFactory, null);
|
||||||
|
if (declaration == null)
|
||||||
|
return null;
|
||||||
ASTWriterVisitor writer = new ASTWriterVisitor();
|
ASTWriterVisitor writer = new ASTWriterVisitor();
|
||||||
declaration.accept(writer);
|
declaration.accept(writer);
|
||||||
return writer.toString();
|
return writer.toString();
|
||||||
|
@ -242,9 +249,21 @@ public class NameInformation {
|
||||||
}
|
}
|
||||||
|
|
||||||
private IASTParameterDeclaration getParameterDeclaration(INodeFactory nodeFactory, String paramName) {
|
private IASTParameterDeclaration getParameterDeclaration(INodeFactory nodeFactory, String paramName) {
|
||||||
|
IASTDeclSpecifier sourceDeclSpec = getDeclSpecifier();
|
||||||
IASTDeclarator sourceDeclarator = getDeclarator();
|
IASTDeclarator sourceDeclarator = getDeclarator();
|
||||||
IASTDeclSpecifier declSpec = safeCopy(getDeclSpecifier());
|
IASTDeclSpecifier declSpec;
|
||||||
IASTDeclarator declarator = createDeclarator(nodeFactory, sourceDeclarator, paramName);
|
IASTDeclarator declarator;
|
||||||
|
if (sourceDeclSpec instanceof IASTSimpleDeclSpecifier &&
|
||||||
|
((IASTSimpleDeclSpecifier) sourceDeclSpec).getType() == IASTSimpleDeclSpecifier.t_auto) {
|
||||||
|
IType type = CPPVisitor.createType(sourceDeclarator);
|
||||||
|
DeclarationGenerator generator = DeclarationGenerator.create(nodeFactory);
|
||||||
|
declSpec = generator.createDeclSpecFromType(type);
|
||||||
|
declarator = generator.createDeclaratorFromType(type,
|
||||||
|
paramName == null ? null : paramName.toCharArray());
|
||||||
|
} else {
|
||||||
|
declSpec = safeCopy(sourceDeclSpec);
|
||||||
|
declarator = createDeclarator(nodeFactory, sourceDeclarator, paramName);
|
||||||
|
}
|
||||||
|
|
||||||
Indirection indirection = getIndirection();
|
Indirection indirection = getIndirection();
|
||||||
if (indirection == Indirection.POINTER) {
|
if (indirection == Indirection.POINTER) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2008, 2012 Institute for Software, HSR Hochschule fuer Technik
|
* Copyright (c) 2008, 2013 Institute for Software, HSR Hochschule fuer Technik
|
||||||
* Rapperswil, University of applied sciences and others
|
* Rapperswil, University of applied sciences and others
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
@ -22,33 +22,27 @@ import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
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;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
|
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBasicType;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
|
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.INodeFactory;
|
import org.eclipse.cdt.core.dom.ast.INodeFactory;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
||||||
import org.eclipse.cdt.core.dom.ast.IVariable;
|
import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
|
|
||||||
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
|
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
|
||||||
import org.eclipse.cdt.core.dom.rewrite.DeclarationGenerator;
|
import org.eclipse.cdt.core.dom.rewrite.DeclarationGenerator;
|
||||||
|
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTBinaryExpression;
|
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.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.CPPBasicType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclaration;
|
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.NameInformation;
|
import org.eclipse.cdt.internal.ui.refactoring.NameInformation;
|
||||||
|
|
||||||
|
@ -88,21 +82,28 @@ public class ExpressionExtractor extends FunctionExtractor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IASTDeclSpecifier determineReturnType(IASTNode extractedNode, NameInformation _) {
|
public IASTDeclSpecifier determineReturnType(IASTNode extractedNode, NameInformation _,
|
||||||
|
List<IASTPointerOperator> pointerOperators) {
|
||||||
|
IType returnType = determineReturnType(extractedNode);
|
||||||
|
INodeFactory factory = extractedNode.getTranslationUnit().getASTNodeFactory();
|
||||||
|
DeclarationGenerator generator = DeclarationGenerator.create(factory);
|
||||||
|
IASTDeclarator declarator = generator.createDeclaratorFromType(returnType, null);
|
||||||
|
ArrayUtil.addAll(pointerOperators, declarator.getPointerOperators());
|
||||||
|
return generator.createDeclSpecFromType(returnType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IType determineReturnType(IASTNode extractedNode) {
|
||||||
List<ITypedef> typedefs = getTypedefs(extractedNode);
|
List<ITypedef> typedefs = getTypedefs(extractedNode);
|
||||||
if (extractedNode instanceof IASTExpression) {
|
if (extractedNode instanceof IASTExpression) {
|
||||||
IASTExpression exp = (IASTExpression) extractedNode;
|
IType expressionType = ((IASTExpression) extractedNode).getExpressionType();
|
||||||
INodeFactory factory = extractedNode.getTranslationUnit().getASTNodeFactory();
|
|
||||||
DeclarationGenerator generator = DeclarationGenerator.create(factory);
|
|
||||||
IType expressionType = exp.getExpressionType();
|
|
||||||
for (ITypedef typedef : typedefs) {
|
for (ITypedef typedef : typedefs) {
|
||||||
if (typedef.getType().isSameType(expressionType)) {
|
if (typedef.getType().isSameType(expressionType)) {
|
||||||
return generator.createDeclSpecFromType(typedef);
|
return typedef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return generator.createDeclSpecFromType(expressionType);
|
return expressionType;
|
||||||
} else { // Fallback
|
} else { // Fallback
|
||||||
return createSimpleDeclSpecifier(Kind.eVoid);
|
return new CPPBasicType(Kind.eVoid, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,63 +137,6 @@ public class ExpressionExtractor extends FunctionExtractor {
|
||||||
return typeDefs;
|
return typeDefs;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IASTDeclSpecifier createSimpleDeclSpecifier(IBasicType.Kind type) {
|
|
||||||
IASTSimpleDeclSpecifier declSpec = new CPPASTSimpleDeclSpecifier();
|
|
||||||
declSpec.setType(type);
|
|
||||||
return declSpec;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IASTName findCalledFunctionName(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();
|
|
||||||
}
|
|
||||||
return functionName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean hasPointerReturnType(IASTNode node) {
|
|
||||||
if (node instanceof ICPPASTNewExpression) {
|
|
||||||
return true;
|
|
||||||
} else if (!(node instanceof IASTFunctionCallExpression)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
IASTName functionName = findCalledFunctionName((IASTFunctionCallExpression) node);
|
|
||||||
if (functionName != null) {
|
|
||||||
IBinding binding = functionName.resolveBinding();
|
|
||||||
if (binding instanceof CPPFunction) {
|
|
||||||
CPPFunction function = (CPPFunction) binding;
|
|
||||||
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
|
@Override
|
||||||
public IASTNode createReturnAssignment(IASTNode node, IASTExpressionStatement stmt,
|
public IASTNode createReturnAssignment(IASTNode node, IASTExpressionStatement stmt,
|
||||||
IASTExpression callExpression) {
|
IASTExpression callExpression) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2008, 2012 Institute for Software, HSR Hochschule fuer Technik
|
* Copyright (c) 2008, 2013 Institute for Software, HSR Hochschule fuer Technik
|
||||||
* Rapperswil, University of applied sciences and others
|
* Rapperswil, University of applied sciences and others
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
@ -70,6 +70,7 @@ 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.ICPPASTConversionName;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTName;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNameSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNameSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTOperatorName;
|
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.ICPPASTQualifiedName;
|
||||||
|
@ -592,7 +593,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
|
|
||||||
private void addMethod(IASTName methodName, MethodContext context, ASTRewrite rewrite,
|
private void addMethod(IASTName methodName, MethodContext context, ASTRewrite rewrite,
|
||||||
IASTNode functionToExtractFrom, TextEditGroup group) {
|
IASTNode functionToExtractFrom, TextEditGroup group) {
|
||||||
ICPPASTQualifiedName qname = new CPPASTQualifiedName();
|
ICPPASTQualifiedName qname = new CPPASTQualifiedName((ICPPASTName) methodName);
|
||||||
if (context.getType() == ContextType.METHOD) {
|
if (context.getType() == ContextType.METHOD) {
|
||||||
if (context.getMethodQName() != null) {
|
if (context.getMethodQName() != null) {
|
||||||
for (ICPPASTNameSpecifier segment : context.getMethodQName().getQualifier()) {
|
for (ICPPASTNameSpecifier segment : context.getMethodQName().getQualifier()) {
|
||||||
|
@ -600,19 +601,22 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
qname.addName(methodName);
|
|
||||||
|
|
||||||
IASTFunctionDefinition func = new CPPASTFunctionDefinition();
|
IASTFunctionDefinition func = new CPPASTFunctionDefinition();
|
||||||
func.setParent(ast);
|
func.setParent(ast);
|
||||||
|
|
||||||
IASTDeclSpecifier returnType = getReturnType();
|
List<IASTPointerOperator> pointerOperators = new ArrayList<IASTPointerOperator>();
|
||||||
|
IASTDeclSpecifier returnType = getReturnType(pointerOperators);
|
||||||
func.setDeclSpecifier(returnType);
|
func.setDeclSpecifier(returnType);
|
||||||
|
|
||||||
IASTStandardFunctionDeclarator createdFunctionDeclarator =
|
IASTStandardFunctionDeclarator declarator =
|
||||||
extractor.createFunctionDeclarator(qname,
|
extractor.createFunctionDeclarator(qname,
|
||||||
info.getDeclarator(), info.getReturnVariable(), container.getNodesToWrite(),
|
info.getDeclarator(), info.getReturnVariable(), container.getNodesToWrite(),
|
||||||
info.getParameters(), nodeFactory);
|
info.getParameters(), nodeFactory);
|
||||||
func.setDeclarator(createdFunctionDeclarator);
|
for (IASTPointerOperator operator : pointerOperators) {
|
||||||
|
declarator.addPointerOperator(operator);
|
||||||
|
}
|
||||||
|
func.setDeclarator(declarator);
|
||||||
|
|
||||||
IASTCompoundStatement compound = new CPPASTCompoundStatement();
|
IASTCompoundStatement compound = new CPPASTCompoundStatement();
|
||||||
func.setBody(compound);
|
func.setBody(compound);
|
||||||
|
@ -680,11 +684,10 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
return new CPPASTName(declaration.toCharArray());
|
return new CPPASTName(declaration.toCharArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
private IASTDeclSpecifier getReturnType() {
|
private IASTDeclSpecifier getReturnType(List<IASTPointerOperator> pointerOperators) {
|
||||||
IASTNode firstNodeToWrite = container.getNodesToWrite().get(0);
|
IASTNode firstNodeToWrite = container.getNodesToWrite().get(0);
|
||||||
NameInformation returnVariable = info.getReturnVariable();
|
NameInformation returnVariable = info.getReturnVariable();
|
||||||
return extractor.determineReturnType(firstNodeToWrite,
|
return extractor.determineReturnType(firstNodeToWrite, returnVariable, pointerOperators);
|
||||||
returnVariable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IASTNode getMethodCall(IASTName astMethodName, Map<String, Integer> trailNameTable,
|
protected IASTNode getMethodCall(IASTName astMethodName, Map<String, Integer> trailNameTable,
|
||||||
|
@ -820,7 +823,8 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
}
|
}
|
||||||
|
|
||||||
private IASTSimpleDeclaration getDeclaration(ModificationCollector collector, IASTName name) {
|
private IASTSimpleDeclaration getDeclaration(ModificationCollector collector, IASTName name) {
|
||||||
IASTDeclSpecifier declSpec = getReturnType();
|
List<IASTPointerOperator> pointerOperators = new ArrayList<IASTPointerOperator>();
|
||||||
|
IASTDeclSpecifier declSpec = getReturnType(pointerOperators);
|
||||||
IASTSimpleDeclaration simpleDecl = nodeFactory.newSimpleDeclaration(declSpec);
|
IASTSimpleDeclaration simpleDecl = nodeFactory.newSimpleDeclaration(declSpec);
|
||||||
if (info.isVirtual() && declSpec instanceof ICPPASTDeclSpecifier) {
|
if (info.isVirtual() && declSpec instanceof ICPPASTDeclSpecifier) {
|
||||||
((ICPPASTDeclSpecifier) declSpec).setVirtual(true);
|
((ICPPASTDeclSpecifier) declSpec).setVirtual(true);
|
||||||
|
@ -830,6 +834,9 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
extractor.createFunctionDeclarator(name,
|
extractor.createFunctionDeclarator(name,
|
||||||
info.getDeclarator(), info.getReturnVariable(), container.getNodesToWrite(),
|
info.getDeclarator(), info.getReturnVariable(), container.getNodesToWrite(),
|
||||||
info.getParameters(), nodeFactory);
|
info.getParameters(), nodeFactory);
|
||||||
|
for (IASTPointerOperator operator : pointerOperators) {
|
||||||
|
declarator.addPointerOperator(operator);
|
||||||
|
}
|
||||||
simpleDecl.addDeclarator(declarator);
|
simpleDecl.addDeclarator(declarator);
|
||||||
return simpleDecl;
|
return simpleDecl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2008, 2012 Institute for Software, HSR Hochschule fuer Technik
|
* Copyright (c) 2008, 2013 Institute for Software, HSR Hochschule fuer Technik
|
||||||
* Rapperswil, University of applied sciences and others
|
* Rapperswil, University of applied sciences and others
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
@ -23,7 +23,6 @@ import org.eclipse.text.edits.TextEditGroup;
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
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;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
|
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
|
||||||
|
@ -59,16 +58,21 @@ public abstract class FunctionExtractor {
|
||||||
public abstract void constructMethodBody(IASTCompoundStatement compound, List<IASTNode> nodes,
|
public abstract void constructMethodBody(IASTCompoundStatement compound, List<IASTNode> nodes,
|
||||||
List<NameInformation> parameters, ASTRewrite rewrite, TextEditGroup group);
|
List<NameInformation> parameters, ASTRewrite rewrite, TextEditGroup group);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the declarator specifier and the pointer operators for the return type of
|
||||||
|
* the extracted function.
|
||||||
|
*
|
||||||
|
* @param extractedNode the first extracted node, used for expression extraction
|
||||||
|
* @param returnVariable the return variable or {@code null} if the there is no return variable
|
||||||
|
* @param pointerOperators output parameter - pointer operators for the function declarator
|
||||||
|
* @return the declarator specifier of the function
|
||||||
|
*/
|
||||||
public abstract IASTDeclSpecifier determineReturnType(IASTNode extractedNode,
|
public abstract IASTDeclSpecifier determineReturnType(IASTNode extractedNode,
|
||||||
NameInformation returnVariable);
|
NameInformation returnVariable, List<IASTPointerOperator> pointerOperators);
|
||||||
|
|
||||||
public abstract IASTNode createReturnAssignment(IASTNode node, IASTExpressionStatement stmt,
|
public abstract IASTNode createReturnAssignment(IASTNode node, IASTExpressionStatement stmt,
|
||||||
IASTExpression callExpression);
|
IASTExpression callExpression);
|
||||||
|
|
||||||
protected boolean hasPointerReturnType(IASTNode node) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
IASTStandardFunctionDeclarator createFunctionDeclarator(IASTName name,
|
IASTStandardFunctionDeclarator createFunctionDeclarator(IASTName name,
|
||||||
IASTStandardFunctionDeclarator functionDeclarator, NameInformation returnVariable,
|
IASTStandardFunctionDeclarator functionDeclarator, NameInformation returnVariable,
|
||||||
List<IASTNode> nodesToWrite, Collection<NameInformation> allUsedNames,
|
List<IASTNode> nodesToWrite, Collection<NameInformation> allUsedNames,
|
||||||
|
@ -82,22 +86,10 @@ public abstract class FunctionExtractor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (returnVariable != null) {
|
|
||||||
IASTDeclarator decl = returnVariable.getDeclarator();
|
|
||||||
IASTPointerOperator[] pointers = decl.getPointerOperators();
|
|
||||||
for (IASTPointerOperator operator : pointers) {
|
|
||||||
declarator.addPointerOperator(operator.copy(CopyStyle.withLocations));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (IASTParameterDeclaration param : getParameterDeclarations(allUsedNames, nodeFactory)) {
|
for (IASTParameterDeclaration param : getParameterDeclarations(allUsedNames, nodeFactory)) {
|
||||||
declarator.addParameterDeclaration(param);
|
declarator.addParameterDeclaration(param);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasPointerReturnType(nodesToWrite.get(0))) {
|
|
||||||
declarator.addPointerOperator(nodeFactory.newPointer());
|
|
||||||
}
|
|
||||||
|
|
||||||
return declarator;
|
return declarator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2008, 2012 Institute for Software, HSR Hochschule fuer Technik
|
* Copyright (c) 2008, 2013 Institute for Software, HSR Hochschule fuer Technik
|
||||||
* Rapperswil, University of applied sciences and others
|
* Rapperswil, University of applied sciences and others
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
@ -19,11 +19,13 @@ import org.eclipse.text.edits.TextEditGroup;
|
||||||
|
|
||||||
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;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
|
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.INodeFactory;
|
import org.eclipse.cdt.core.dom.ast.INodeFactory;
|
||||||
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
|
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
|
||||||
|
@ -55,9 +57,14 @@ public class StatementExtractor extends FunctionExtractor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IASTDeclSpecifier determineReturnType(IASTNode extractedNode,
|
public IASTDeclSpecifier determineReturnType(IASTNode extractedNode,
|
||||||
NameInformation returnVariable) {
|
NameInformation returnVariable, List<IASTPointerOperator> pointerOperators) {
|
||||||
if (returnVariable != null) {
|
if (returnVariable != null) {
|
||||||
IASTNode decl = ASTHelper.getDeclarationForNode(returnVariable.getDeclarationName());
|
IASTName declarationName = returnVariable.getDeclarationName();
|
||||||
|
IASTDeclarator declarator = ASTHelper.getDeclaratorForNode(declarationName);
|
||||||
|
for (IASTPointerOperator pointerOperator : declarator.getPointerOperators()) {
|
||||||
|
pointerOperators.add(pointerOperator.copy(CopyStyle.withLocations));
|
||||||
|
}
|
||||||
|
IASTNode decl = ASTHelper.getDeclarationForNode(declarationName);
|
||||||
IASTDeclSpecifier declSpec = ASTHelper.getDeclarationSpecifier(decl);
|
IASTDeclSpecifier declSpec = ASTHelper.getDeclarationSpecifier(decl);
|
||||||
return declSpec != null ? declSpec.copy(CopyStyle.withLocations) : null;
|
return declSpec != null ? declSpec.copy(CopyStyle.withLocations) : null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,10 +30,7 @@ import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
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.ICPPASTCompositeTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNameSpecifier;
|
|
||||||
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.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.ICPPASTUsingDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
|
||||||
|
|
||||||
|
@ -43,15 +40,15 @@ public class ASTHelper {
|
||||||
private ASTHelper() {
|
private ASTHelper() {
|
||||||
}
|
}
|
||||||
|
|
||||||
static public IASTNode getDeclarationForNode(IASTNode tmpNode) {
|
static public IASTNode getDeclarationForNode(IASTNode node) {
|
||||||
while (tmpNode != null && !(tmpNode instanceof IASTSimpleDeclaration) && !(tmpNode instanceof IASTParameterDeclaration)) {
|
while (node != null && !(node instanceof IASTSimpleDeclaration) && !(node instanceof IASTParameterDeclaration)) {
|
||||||
tmpNode = tmpNode.getParent();
|
node = node.getParent();
|
||||||
}
|
}
|
||||||
return tmpNode;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public IASTDeclarator getDeclaratorForNode(IASTNode aNode) {
|
static public IASTDeclarator getDeclaratorForNode(IASTNode node) {
|
||||||
IASTNode tmpNode = getDeclarationForNode(aNode);
|
IASTNode tmpNode = getDeclarationForNode(node);
|
||||||
|
|
||||||
IASTDeclarator declarator = null;
|
IASTDeclarator declarator = null;
|
||||||
if (tmpNode instanceof IASTSimpleDeclaration) {
|
if (tmpNode instanceof IASTSimpleDeclaration) {
|
||||||
|
@ -107,36 +104,9 @@ public class ASTHelper {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ArrayList<ICPPASTNamespaceDefinition> getNamespaces(IASTNode node) {
|
public static Collection<IASTDeclSpecifier> getCompositeTypeSpecifiers(IASTNode baseNode) {
|
||||||
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 (ICPPASTNameSpecifier aktQualifiedPartName : qualifiedName.getAllSegments()) {
|
|
||||||
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>();
|
final Collection<IASTDeclSpecifier> specifiers = new ArrayList<IASTDeclSpecifier>();
|
||||||
ASTVisitor visitor = new ASTVisitor() {
|
ASTVisitor visitor = new ASTVisitor() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int visit(IASTDeclSpecifier declSpec) {
|
public int visit(IASTDeclSpecifier declSpec) {
|
||||||
specifiers.add(declSpec);
|
specifiers.add(declSpec);
|
||||||
|
|
Loading…
Add table
Reference in a new issue