1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-30 21:55:31 +02:00

Bug 333936: When ASTNodes are moved (as in Extract Method) formatting is not preserved and macros are expanded

https://bugs.eclipse.org/bugs/show_bug.cgi?id=333936
This commit is contained in:
Emanuel Graf 2011-03-07 11:09:12 +00:00
parent 52cb9b810c
commit 28f527f165
13 changed files with 147 additions and 34 deletions

View file

@ -18,6 +18,7 @@ import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;
import org.eclipse.cdt.core.dom.ast.IASTCopyLocation;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTMacroExpansionLocation;
import org.eclipse.cdt.core.dom.ast.IASTNode;
@ -56,8 +57,9 @@ public class MacroExpansionHandler {
}
protected boolean isStatementWithMixedLocation(IASTStatement node) {
if(node.getNodeLocations() != null && node.getNodeLocations().length > 1) {
for (IASTNodeLocation loc : node.getNodeLocations()) {
IASTNodeLocation[] nodeLocations = getNodeLocations(node);
if(nodeLocations != null && nodeLocations.length > 1) {
for (IASTNodeLocation loc : nodeLocations) {
if (loc instanceof IASTMacroExpansionLocation) {
return true;
}
@ -84,7 +86,7 @@ public class MacroExpansionHandler {
if(tu == null || !tu.equals(unit)) {
initEmptyMacros(unit);
}
IASTNodeLocation[] locs = node.getNodeLocations();
IASTNodeLocation[] locs = getNodeLocations(node);
if (locs != null && locs.length ==1) {
if (locs[0] instanceof IASTMacroExpansionLocation) {
IASTMacroExpansionLocation macroNode = (IASTMacroExpansionLocation) locs[0];
@ -94,6 +96,7 @@ public class MacroExpansionHandler {
}
if (write) {
lastMacroExpOffset = macroNode.asFileLocation().getNodeOffset();
node = getOriginalNode(node);
scribe.print(node.getRawSignature());
}
return true;
@ -103,13 +106,29 @@ public class MacroExpansionHandler {
handleEmptyMacroExpansion(node);
return false;
}
private IASTNode getOriginalNode(IASTNode node) {
IASTNodeLocation[] locs = node.getNodeLocations();
if (locs != null && locs.length == 1 && locs[0] instanceof IASTCopyLocation) {
node = ((IASTCopyLocation) locs[0]).getOriginalNode();
}
return node;
}
private IASTNodeLocation[] getNodeLocations(IASTNode node) {
IASTNodeLocation[] locs = node.getNodeLocations();
if (locs != null && locs.length == 1 && locs[0] instanceof IASTCopyLocation) {
locs = ((IASTCopyLocation) locs[0]).getOriginalNode().getNodeLocations();
}
return locs;
}
private void handleEmptyMacroExpansion(IASTNode node) {
if(node.getTranslationUnit() == null)return;
String file = node.getContainingFilename();
List<IIndexName> exps = macroExpansion.get(file);
if(exps != null && !exps.isEmpty()) {
IASTFileLocation fileLocation = node.getFileLocation();
IASTFileLocation fileLocation = getFileLocation(node);
if(fileLocation != null) {
int nOff = fileLocation.getNodeOffset();
for (IIndexName iIndexName : exps) {
@ -127,6 +146,17 @@ public class MacroExpansionHandler {
}
private IASTFileLocation getFileLocation(IASTNode node) {
IASTFileLocation fileLocation = node.getFileLocation();
if (fileLocation == null) {
IASTNodeLocation[] locs = node.getNodeLocations();
if (locs != null && locs.length > 0 && locs[0] instanceof IASTCopyLocation) {
fileLocation = ((IASTCopyLocation) locs[0]).getOriginalNode().getFileLocation();
}
}
return fileLocation;
}
private void initEmptyMacros(IASTTranslationUnit unit) {
if (unit != null) {
tu = unit;

View file

@ -912,3 +912,71 @@ void foo(){
double y = bar(x);
}
//! Extract macro
//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
//@.config
filename=test.cpp
methodname=bar
//@test.cpp
#define five 5
#define ADD(a, b) a + b
int main(){
int i = five; //comment3
i = /*$*/ADD(i, five)/*$$*/;
return i;
}
//=
#define five 5
#define ADD(a, b) a + b
int bar(int & i)
{
return ADD(i, five);
}
int main(){
int i = five; //comment3
i = bar(i);
return i;
}
//! Extract macro
//#org.eclipse.cdt.ui.tests.refactoring.extractfunction.ExtractFunctionRefactoringTest
//@.config
filename=test.cpp
methodname=bar
//@test.cpp
#define five 5
#define ADD(a, b) a + b
int main(){
int i = five; //comment3
i = /*$*/ADD(i, five)/*$$*/;
return i;
}
//=
#define five 5
#define ADD(a, b) a + b
int bar(int & i)
{
return ADD(i, five);
}
int main(){
int i = five; //comment3
i = bar(i);
return i;
}

View file

@ -28,6 +28,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTMacroExpansionLocation;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
@ -131,10 +132,10 @@ public class NodeContainer {
if (sourceDeclarator.getParent() instanceof IASTSimpleDeclaration) {
IASTSimpleDeclaration decl = (IASTSimpleDeclaration) sourceDeclarator.getParent();
declSpec= decl.getDeclSpecifier().copy();
declSpec = decl.getDeclSpecifier().copy(CopyStyle.withLocations);
} else if (sourceDeclarator.getParent() instanceof IASTParameterDeclaration) {
IASTParameterDeclaration decl = (IASTParameterDeclaration) sourceDeclarator.getParent();
declSpec= decl.getDeclSpecifier().copy();
declSpec = decl.getDeclSpecifier().copy(CopyStyle.withLocations);
}
IASTName name= nodeFactory.newName(getDeclaration().toCharArray());
@ -143,14 +144,14 @@ public class NodeContainer {
IASTArrayDeclarator arrayDtor = nodeFactory.newArrayDeclarator(name);
IASTArrayModifier[] arrayModifiers = arrDeclarator.getArrayModifiers();
for (IASTArrayModifier arrayModifier : arrayModifiers) {
arrayDtor.addArrayModifier(arrayModifier.copy());
arrayDtor.addArrayModifier(arrayModifier.copy(CopyStyle.withLocations));
}
declarator= arrayDtor;
} else {
declarator = nodeFactory.newDeclarator(name);
}
for (IASTPointerOperator pointerOp : sourceDeclarator.getPointerOperators()) {
declarator.addPointerOperator(pointerOp.copy());
declarator.addPointerOperator(pointerOp.copy(CopyStyle.withLocations));
}
if (isReference && !hasReferenceOperartor(declarator)) {

View file

@ -27,6 +27,7 @@ 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.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
@ -78,12 +79,12 @@ public class ExtractExpression extends ExtractedFunctionConstructionHelper {
if(list.size()> 1 ) {
CPPASTBinaryExpression bExp = new CPPASTBinaryExpression();
bExp.setParent(list.get(0).getParent());
bExp.setOperand1((IASTExpression) list.get(0).copy());
bExp.setOperand1((IASTExpression) list.get(0).copy(CopyStyle.withLocations));
bExp.setOperator(((IASTBinaryExpression)list.get(1).getParent()).getOperator());
bExp.setOperand2(getExpression(list.subList(1, list.size())));
return bExp;
}else {
return (IASTExpression) list.get(0).copy();
return (IASTExpression) list.get(0).copy(CopyStyle.withLocations);
}
}

View file

@ -50,6 +50,7 @@ import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
@ -378,7 +379,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
IASTBinaryExpression newParentNode = new CPPASTBinaryExpression();
IASTBinaryExpression rootBinExp = getRootBinExp(parent, list);
newParentNode.setParent(rootBinExp.getParent());
newParentNode.setOperand1(leftSubTree.copy());
newParentNode.setOperand1(leftSubTree.copy(CopyStyle.withLocations));
newParentNode.setOperator(op);
newParentNode.setOperand2((IASTExpression) methodCall);
rewriter.replace(rootBinExp, newParentNode, editGroup);
@ -623,7 +624,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
templateDeclaration.setParent(ast);
for (ICPPASTTemplateParameter templateParameter : ((ICPPASTTemplateDeclaration) insertpoint.getParent()).getTemplateParameters()) {
templateDeclaration.addTemplateParameter(templateParameter.copy());
templateDeclaration.addTemplateParameter(templateParameter.copy(CopyStyle.withLocations));
}
templateDeclaration.setDeclaration(func);
@ -761,14 +762,14 @@ public class ExtractFunctionRefactoring extends CRefactoring {
.getReturnVariable().getDeclaration());
IASTSimpleDeclaration decl = new CPPASTSimpleDeclaration();
decl.setDeclSpecifier(orgDecl.getDeclSpecifier().copy());
decl.setDeclSpecifier(orgDecl.getDeclSpecifier().copy(CopyStyle.withLocations));
IASTDeclarator declarator = new CPPASTDeclarator();
declarator.setName(retname);
for (IASTPointerOperator pointer : orgDecl.getDeclarators()[0].getPointerOperators()) {
declarator.addPointerOperator(pointer.copy());
declarator.addPointerOperator(pointer.copy(CopyStyle.withLocations));
}
IASTEqualsInitializer initializer = new CPPASTEqualsInitializer();

View file

@ -20,6 +20,7 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
@ -48,11 +49,11 @@ public class ExtractStatement extends ExtractedFunctionConstructionHelper {
if(returnVariable != null) {
IASTNode decl = ASTHelper.getDeclarationForNode(returnVariable.getDeclaration());
return ASTHelper.getDeclarationSpecifier(decl).copy();
return ASTHelper.getDeclarationSpecifier(decl).copy(CopyStyle.withLocations);
}
IASTDeclSpecifier declSpec = new CPPASTSimpleDeclSpecifier();
((IASTSimpleDeclSpecifier)declSpec).setType(IASTSimpleDeclSpecifier.t_void);
return declSpec.copy();
return declSpec.copy(CopyStyle.withLocations);
}
@Override

View file

@ -24,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
@ -70,7 +71,7 @@ public abstract class ExtractedFunctionConstructionHelper {
IASTDeclarator decl = (IASTDeclarator) returnVariable.getDeclaration().getParent();
IASTPointerOperator[] pointers = decl.getPointerOperators();
for (IASTPointerOperator operator : pointers) {
declarator.addPointerOperator(operator.copy());
declarator.addPointerOperator(operator.copy(CopyStyle.withLocations));
}
}

View file

@ -40,6 +40,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
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.IASTNode.CopyStyle;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
@ -294,7 +295,7 @@ public class ExtractLocalVariableRefactoring extends CRefactoring {
newName.toCharArray());
IASTEqualsInitializer init = new CPPASTEqualsInitializer();
init.setInitializerClause(deblock(target.copy()));
init.setInitializerClause(deblock(target.copy(CopyStyle.withLocations)));
decl.setInitializer(init);
simple.addDeclarator(decl);

View file

@ -16,6 +16,7 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
@ -44,7 +45,7 @@ public class FunctionFactory {
IASTFunctionDefinition getter = new CPPASTFunctionDefinition();
getter.setDeclSpecifier(fieldDeclaration.getDeclSpecifier().copy());
getter.setDeclSpecifier(fieldDeclaration.getDeclSpecifier().copy(CopyStyle.withLocations));
IASTDeclarator getterDeclarator = getGetterDeclarator(varName, fieldDeclaration, name);
// IASTFunctionDefinition. expects the outermost IASTFunctionDeclarator in declarator hierarchy
while (!(getterDeclarator instanceof IASTFunctionDeclarator)) {
@ -77,7 +78,7 @@ public class FunctionFactory {
getterName.setName("get".concat(varPartOfGetterName).toCharArray()); //$NON-NLS-1$
// copy declarator hierarchy
IASTDeclarator topDeclarator = fieldDeclaration.getDeclarators()[0].copy();
IASTDeclarator topDeclarator = fieldDeclaration.getDeclarators()[0].copy(CopyStyle.withLocations);
// find the innermost declarator in hierarchy
IASTDeclarator innermost = topDeclarator;
@ -95,7 +96,7 @@ public class FunctionFactory {
functionDeclarator.setName(getterName);
}
for(IASTPointerOperator pointer : innermost.getPointerOperators()){
functionDeclarator.addPointerOperator(pointer.copy());
functionDeclarator.addPointerOperator(pointer.copy(CopyStyle.withLocations));
}
// replace innermost with functionDeclarator and return the whole declarator tree
@ -134,12 +135,12 @@ public class FunctionFactory {
innerDeclarator = innerDeclarator.getNestedDeclarator();
}
IASTName fieldName = innerDeclarator.getName();
fieldRef.setFieldName(fieldName.copy());
fieldRef.setFieldName(fieldName.copy(CopyStyle.withLocations));
fieldRef.setIsPointerDereference(true);
binExpr.setOperand1(fieldRef);
binExpr.setOperator(IASTBinaryExpression.op_assign);
CPPASTIdExpression idExpr = new CPPASTIdExpression();
idExpr.setName(fieldName.copy());
idExpr.setName(fieldName.copy(CopyStyle.withLocations));
binExpr.setOperand2(idExpr);
exprStmt.setExpression(binExpr);
compound.addStatement(exprStmt);
@ -159,9 +160,11 @@ public class FunctionFactory {
declarator.setName(setterName);
}
CPPASTParameterDeclaration parameterDeclaration = new CPPASTParameterDeclaration();
parameterDeclaration.setDeclarator(fieldDeclaration.getDeclarators()[0].copy());
parameterDeclaration.setDeclSpecifier(fieldDeclaration.getDeclSpecifier().copy());
declarator.addParameterDeclaration(parameterDeclaration.copy());
parameterDeclaration
.setDeclarator(fieldDeclaration.getDeclarators()[0].copy(CopyStyle.withLocations));
parameterDeclaration.setDeclSpecifier(fieldDeclaration.getDeclSpecifier().copy(
CopyStyle.withLocations));
declarator.addParameterDeclaration(parameterDeclaration.copy(CopyStyle.withLocations));
return declarator;
}
@ -174,7 +177,7 @@ public class FunctionFactory {
public static IASTSimpleDeclaration createGetterDeclaration(String name,
IASTSimpleDeclaration fieldDeclaration) {
IASTSimpleDeclaration getter = new CPPASTSimpleDeclaration();
getter.setDeclSpecifier(fieldDeclaration.getDeclSpecifier().copy());
getter.setDeclSpecifier(fieldDeclaration.getDeclSpecifier().copy(CopyStyle.withLocations));
getter.addDeclarator(getGetterDeclarator(name, fieldDeclaration, null));
return getter;

View file

@ -15,6 +15,7 @@ import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
@ -84,7 +85,7 @@ public class GetterSetterInsertEditProvider implements Comparable<GetterSetterIn
IASTCompositeTypeSpecifier comp = (IASTCompositeTypeSpecifier) n;
CPPASTQualifiedName qname = new CPPASTQualifiedName();
qname.addName(comp.getName().copy());
qname.addName(comp.getName().copy(CopyStyle.withLocations));
return qname;
}

View file

@ -31,6 +31,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
@ -181,7 +182,7 @@ public class ImplementMethodRefactoring extends CRefactoring {
private IASTDeclaration createFunctionDefinition(IASTTranslationUnit unit, IASTSimpleDeclaration methodDeclaration) throws CoreException {
return createFunctionDefinition(
methodDeclaration.getDeclSpecifier().copy(),
methodDeclaration.getDeclSpecifier().copy(CopyStyle.withLocations),
(ICPPASTFunctionDeclarator) methodDeclaration.getDeclarators()[0],
methodDeclaration.getParent(), unit);
}
@ -212,7 +213,7 @@ public class ImplementMethodRefactoring extends CRefactoring {
createdMethodDeclarator.setName(qname);
createdMethodDeclarator.setConst(functionDeclarator.isConst());
for (IASTPointerOperator pop : functionDeclarator.getPointerOperators()) {
createdMethodDeclarator.addPointerOperator(pop.copy());
createdMethodDeclarator.addPointerOperator(pop.copy(CopyStyle.withLocations));
}
func.setDeclarator(createdMethodDeclarator);
@ -223,7 +224,7 @@ public class ImplementMethodRefactoring extends CRefactoring {
templateDeclaration.setParent(unit);
for (ICPPASTTemplateParameter templateParameter : ((ICPPASTTemplateDeclaration) declarationParent.getParent().getParent() ).getTemplateParameters()) {
templateDeclaration.addTemplateParameter(templateParameter.copy());
templateDeclaration.addTemplateParameter(templateParameter.copy(CopyStyle.withLocations));
}
templateDeclaration.setDeclaration(func);

View file

@ -18,6 +18,7 @@ import org.eclipse.core.runtime.CoreException;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IType;
@ -77,7 +78,7 @@ public class NameHelper {
}
}
qname.addName(declaratorName.copy());
qname.addName(declaratorName.copy(CopyStyle.withLocations));
return qname;
}

View file

@ -17,6 +17,7 @@ import org.eclipse.core.runtime.CoreException;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
@ -91,7 +92,8 @@ public class NamespaceHelper {
private static IASTName createNameWithTemplates(IASTNode declarationParent) {
IASTName parentName;
parentName = ((ICPPASTCompositeTypeSpecifier) declarationParent).getName().copy();
parentName = ((ICPPASTCompositeTypeSpecifier) declarationParent).getName().copy(
CopyStyle.withLocations);
if(classHasTemplates(declarationParent)) {
CPPASTTemplateId templateId = new CPPASTTemplateId();
@ -105,7 +107,8 @@ public class NamespaceHelper {
CPPASTTypeId id = new CPPASTTypeId();
CPPASTNamedTypeSpecifier namedTypeSpecifier = new CPPASTNamedTypeSpecifier();
namedTypeSpecifier.setName(simpleTypeTemplateParameter.getName().copy());
namedTypeSpecifier.setName(simpleTypeTemplateParameter.getName().copy(
CopyStyle.withLocations));
id.setDeclSpecifier(namedTypeSpecifier);
templateId.addTemplateArgument(id);