mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-28 19:35:36 +02:00
FIXED - bug 280432: Refactoring removes comments in class header file and reformats file.
https://bugs.eclipse.org/bugs/show_bug.cgi?id=280432
This commit is contained in:
parent
df498b476f
commit
b86829cf94
3 changed files with 244 additions and 17 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik
|
* Copyright (c) 2008, 2009 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
|
||||||
|
@ -11,10 +11,27 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom.rewrite.astwriter;
|
package org.eclipse.cdt.internal.core.dom.rewrite.astwriter;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTMacroExpansionLocation;
|
import org.eclipse.cdt.core.dom.ast.IASTMacroExpansionLocation;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
|
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
|
import org.eclipse.cdt.core.index.IIndex;
|
||||||
|
import org.eclipse.cdt.core.index.IIndexMacro;
|
||||||
|
import org.eclipse.cdt.core.index.IIndexName;
|
||||||
|
import org.eclipse.cdt.core.index.IndexFilter;
|
||||||
|
import org.eclipse.cdt.internal.core.pdom.dom.PDOMMacroReferenceName;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -27,6 +44,8 @@ public class MacroExpansionHandler {
|
||||||
|
|
||||||
private int lastMacroExpOffset;
|
private int lastMacroExpOffset;
|
||||||
private final Scribe scribe;
|
private final Scribe scribe;
|
||||||
|
private IASTTranslationUnit tu;
|
||||||
|
private Map<String, List<IIndexName>> macroExpansion = new TreeMap<String, List<IIndexName>>();
|
||||||
|
|
||||||
public MacroExpansionHandler(Scribe scribe) {
|
public MacroExpansionHandler(Scribe scribe) {
|
||||||
this.scribe = scribe;
|
this.scribe = scribe;
|
||||||
|
@ -61,6 +80,10 @@ public class MacroExpansionHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean checkisMacroExpansionNode(IASTNode node, boolean write) {
|
protected boolean checkisMacroExpansionNode(IASTNode node, boolean write) {
|
||||||
|
IASTTranslationUnit unit = node.getTranslationUnit();
|
||||||
|
if(tu == null || !tu.equals(unit)) {
|
||||||
|
initEmptyMacros(unit);
|
||||||
|
}
|
||||||
IASTNodeLocation[] locs = node.getNodeLocations();
|
IASTNodeLocation[] locs = node.getNodeLocations();
|
||||||
if (locs != null && locs.length ==1) {
|
if (locs != null && locs.length ==1) {
|
||||||
if (locs[0] instanceof IASTMacroExpansionLocation) {
|
if (locs[0] instanceof IASTMacroExpansionLocation) {
|
||||||
|
@ -77,9 +100,78 @@ public class MacroExpansionHandler {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
handleEmptyMacroExpansion(node);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
if(fileLocation != null) {
|
||||||
|
int nOff = fileLocation.getNodeOffset();
|
||||||
|
for (IIndexName iIndexName : exps) {
|
||||||
|
if (iIndexName instanceof PDOMMacroReferenceName) {
|
||||||
|
PDOMMacroReferenceName mName = (PDOMMacroReferenceName) iIndexName;
|
||||||
|
int eOff = mName.getFileLocation().getNodeOffset();
|
||||||
|
int eLength = mName.getFileLocation().getNodeLength();
|
||||||
|
if(eOff < nOff && Math.abs((eOff+eLength-nOff)) < 3) {
|
||||||
|
scribe.print(mName.toString() + " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initEmptyMacros(IASTTranslationUnit unit) {
|
||||||
|
if (unit != null) {
|
||||||
|
tu = unit;
|
||||||
|
IIndex index = tu.getIndex();
|
||||||
|
if(index != null) {
|
||||||
|
macroExpansion = new TreeMap<String, List<IIndexName>>();
|
||||||
|
IASTPreprocessorMacroDefinition[] md = tu.getMacroDefinitions();
|
||||||
|
|
||||||
|
TreeSet<String>paths = new TreeSet<String>();
|
||||||
|
for(IASTPreprocessorIncludeStatement is :tu.getIncludeDirectives()) {
|
||||||
|
if(!is.isSystemInclude()) {
|
||||||
|
paths.add(is.getContainingFilename());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
paths.add(tu.getContainingFilename());
|
||||||
|
|
||||||
|
for (IASTPreprocessorMacroDefinition iastPreprocessorMacroDefinition : md) {
|
||||||
|
if(iastPreprocessorMacroDefinition.getExpansion().length() == 0) {
|
||||||
|
try {
|
||||||
|
IIndexMacro[] macroBinding = index.findMacros(iastPreprocessorMacroDefinition.getName().toCharArray(), IndexFilter.ALL, null);
|
||||||
|
if(macroBinding.length > 0) {
|
||||||
|
IIndexName[] refs = index.findReferences(macroBinding[0]);
|
||||||
|
for (IIndexName iIndexName : refs) {
|
||||||
|
String filename2 = iIndexName.getFileLocation().getFileName();
|
||||||
|
List<IIndexName>fileList = macroExpansion.get(filename2);
|
||||||
|
if (paths.contains(filename2)) {
|
||||||
|
if(fileList == null) {
|
||||||
|
fileList = new ArrayList<IIndexName>();
|
||||||
|
macroExpansion.put(filename2, fileList);
|
||||||
|
}
|
||||||
|
fileList.add(iIndexName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (CoreException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
macroExpansion = Collections.emptyMap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void reset(){
|
public void reset(){
|
||||||
lastMacroExpOffset = -1;
|
lastMacroExpOffset = -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik
|
* Copyright (c) 2008, 2009 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
|
||||||
|
@ -15,11 +15,28 @@ import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTComment;
|
import org.eclipse.cdt.core.dom.ast.IASTComment;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
|
||||||
|
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.IASTParameterDeclaration;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
import org.eclipse.cdt.internal.core.dom.rewrite.util.OffsetHelper;
|
import org.eclipse.cdt.internal.core.dom.rewrite.util.OffsetHelper;
|
||||||
import org.eclipse.core.resources.IProject;
|
import org.eclipse.core.resources.IProject;
|
||||||
import org.eclipse.core.resources.ResourcesPlugin;
|
import org.eclipse.core.resources.ResourcesPlugin;
|
||||||
|
@ -39,6 +56,116 @@ import org.eclipse.core.runtime.Path;
|
||||||
*/
|
*/
|
||||||
public class ASTCommenter {
|
public class ASTCommenter {
|
||||||
|
|
||||||
|
private static final class PPRangeChecker extends CPPASTVisitor {
|
||||||
|
|
||||||
|
int ppOffset;
|
||||||
|
int commentOffset;
|
||||||
|
boolean isPrePPComment = true;
|
||||||
|
|
||||||
|
private PPRangeChecker(boolean visitNodes, int nextPPOfset, int commentNodeOffset) {
|
||||||
|
super(visitNodes);
|
||||||
|
ppOffset = nextPPOfset;
|
||||||
|
commentOffset = commentNodeOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int checkOffsets(IASTNode node) {
|
||||||
|
int offset = ((ASTNode)node).getOffset();
|
||||||
|
int status = ASTVisitor.PROCESS_CONTINUE;
|
||||||
|
|
||||||
|
if(offset > commentOffset && offset < ppOffset) {
|
||||||
|
isPrePPComment = false;
|
||||||
|
status = ASTVisitor.PROCESS_ABORT;
|
||||||
|
}else if ((offset + ((ASTNode)node).getLength() < commentOffset)) {
|
||||||
|
status = ASTVisitor.PROCESS_SKIP;
|
||||||
|
}else if(offset > ppOffset) {
|
||||||
|
status = ASTVisitor.PROCESS_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int visit(ICPPASTBaseSpecifier baseSpecifier) {
|
||||||
|
return checkOffsets(baseSpecifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int visit(ICPPASTNamespaceDefinition namespaceDefinition) {
|
||||||
|
return checkOffsets(namespaceDefinition);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int visit(ICPPASTTemplateParameter templateParameter) {
|
||||||
|
return checkOffsets(templateParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int visit(IASTArrayModifier arrayModifier) {
|
||||||
|
return checkOffsets(arrayModifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int visit(IASTDeclaration declaration) {
|
||||||
|
return checkOffsets(declaration);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int visit(IASTDeclarator declarator) {
|
||||||
|
return checkOffsets(declarator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int visit(IASTDeclSpecifier declSpec) {
|
||||||
|
return checkOffsets(declSpec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int visit(IASTEnumerator enumerator) {
|
||||||
|
return checkOffsets(enumerator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int visit(IASTExpression expression) {
|
||||||
|
return checkOffsets(expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int visit(IASTInitializer initializer) {
|
||||||
|
return checkOffsets(initializer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int visit(IASTName name) {
|
||||||
|
return checkOffsets(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int visit(IASTParameterDeclaration parameterDeclaration) {
|
||||||
|
return checkOffsets(parameterDeclaration);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int visit(IASTPointerOperator ptrOperator) {
|
||||||
|
return checkOffsets(ptrOperator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int visit(IASTStatement statement) {
|
||||||
|
return checkOffsets(statement);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int visit(IASTTranslationUnit tu) {
|
||||||
|
return checkOffsets(tu);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int visit(IASTTypeId typeId) {
|
||||||
|
return checkOffsets(typeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a NodeCommentMap for the given TranslationUnit. This is the only way
|
* Creates a NodeCommentMap for the given TranslationUnit. This is the only way
|
||||||
* to get a NodeCommentMap which contains all the comments mapped against nodes.
|
* to get a NodeCommentMap which contains all the comments mapped against nodes.
|
||||||
|
@ -96,7 +223,7 @@ public class ASTCommenter {
|
||||||
offsetList = new ArrayList<Integer>();
|
offsetList = new ArrayList<Integer>();
|
||||||
ppOffsetForFiles.put(fileName, offsetList);
|
ppOffsetForFiles.put(fileName, offsetList);
|
||||||
}
|
}
|
||||||
offsetList.add(statement.getFileLocation().getNodeOffset());
|
offsetList.add(((ASTNode)statement).getOffset());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +236,7 @@ public class ASTCommenter {
|
||||||
)) {
|
)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(commentIsAtTheBeginningBeforePreprocessorStatements(comment, ppOffsetForFiles.get(fileName))) {
|
if(commentIsAtTheBeginningBeforePreprocessorStatements(comment, ppOffsetForFiles.get(fileName), tu)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
commentsInCode.add(comment);
|
commentsInCode.add(comment);
|
||||||
|
@ -119,7 +246,7 @@ public class ASTCommenter {
|
||||||
|
|
||||||
private static boolean commentIsAtTheBeginningBeforePreprocessorStatements(
|
private static boolean commentIsAtTheBeginningBeforePreprocessorStatements(
|
||||||
IASTComment comment,
|
IASTComment comment,
|
||||||
ArrayList<Integer> listOfPreProcessorOffset) {
|
ArrayList<Integer> listOfPreProcessorOffset, IASTTranslationUnit tu) {
|
||||||
if(listOfPreProcessorOffset == null) {
|
if(listOfPreProcessorOffset == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -128,25 +255,27 @@ public class ASTCommenter {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
IASTDeclaration decl = comment.getTranslationUnit().getDeclarations()[0];
|
IASTDeclaration decl = comment.getTranslationUnit().getDeclarations()[0];
|
||||||
boolean sameFile = decl.getFileLocation().getFileName().equals(comment.getFileLocation().getFileName());
|
String commentFileName = comment.getFileLocation().getFileName();
|
||||||
|
boolean sameFile = decl.getFileLocation().getFileName().equals(commentFileName);
|
||||||
|
int commentNodeOffset = ((ASTNode)comment).getOffset();
|
||||||
if(sameFile) {
|
if(sameFile) {
|
||||||
if(decl.getFileLocation().getNodeOffset() < comment.getFileLocation().getNodeOffset()) {
|
if(decl.getFileLocation().getNodeOffset() < commentNodeOffset) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Collections.sort(listOfPreProcessorOffset);
|
Collections.sort(listOfPreProcessorOffset);
|
||||||
if(listOfPreProcessorOffset.get(0) < comment.getFileLocation().getNodeOffset()) {
|
int nextPPOfset = -1;
|
||||||
return false;
|
for (Integer integer : listOfPreProcessorOffset) {
|
||||||
}
|
if(integer > commentNodeOffset) {
|
||||||
|
nextPPOfset = integer;
|
||||||
if(sameFile) {
|
PPRangeChecker visti = new PPRangeChecker(true, nextPPOfset, commentNodeOffset);
|
||||||
if(listOfPreProcessorOffset.get(0) < decl.getFileLocation().getNodeOffset()) {
|
tu.accept(visti);
|
||||||
return true;
|
if(visti.isPrePPComment) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}else {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
|
||||||
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
|
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
|
||||||
import org.eclipse.text.edits.TextEditGroup;
|
import org.eclipse.text.edits.TextEditGroup;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
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.IASTComment;
|
import org.eclipse.cdt.core.dom.ast.IASTComment;
|
||||||
|
@ -78,6 +79,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||||
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
|
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
|
||||||
|
import org.eclipse.cdt.core.index.IIndex;
|
||||||
import org.eclipse.cdt.core.model.ICProject;
|
import org.eclipse.cdt.core.model.ICProject;
|
||||||
import org.eclipse.cdt.ui.CUIPlugin;
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
|
|
||||||
|
@ -211,6 +213,10 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(unit != null) {
|
||||||
|
IIndex index = CCorePlugin.getIndexManager().getIndex(project);
|
||||||
|
unit.setIndex(index);
|
||||||
|
}
|
||||||
|
|
||||||
sm.done();
|
sm.done();
|
||||||
return status;
|
return status;
|
||||||
|
|
Loading…
Add table
Reference in a new issue