1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 08:55:25 +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:
Emanuel Graf 2009-07-29 08:46:31 +00:00
parent df498b476f
commit b86829cf94
3 changed files with 244 additions and 17 deletions

View file

@ -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
* All rights reserved. This program and the accompanying materials
* 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;
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.IASTNode;
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.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 final Scribe scribe;
private IASTTranslationUnit tu;
private Map<String, List<IIndexName>> macroExpansion = new TreeMap<String, List<IIndexName>>();
public MacroExpansionHandler(Scribe scribe) {
this.scribe = scribe;
@ -61,6 +80,10 @@ public class MacroExpansionHandler {
}
protected boolean checkisMacroExpansionNode(IASTNode node, boolean write) {
IASTTranslationUnit unit = node.getTranslationUnit();
if(tu == null || !tu.equals(unit)) {
initEmptyMacros(unit);
}
IASTNodeLocation[] locs = node.getNodeLocations();
if (locs != null && locs.length ==1) {
if (locs[0] instanceof IASTMacroExpansionLocation) {
@ -77,9 +100,78 @@ public class MacroExpansionHandler {
}
}
handleEmptyMacroExpansion(node);
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(){
lastMacroExpOffset = -1;
}

View file

@ -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
* All rights reserved. This program and the accompanying materials
* 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.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.IASTDeclSpecifier;
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.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
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.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.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
@ -39,6 +56,116 @@ import org.eclipse.core.runtime.Path;
*/
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
* to get a NodeCommentMap which contains all the comments mapped against nodes.
@ -96,7 +223,7 @@ public class ASTCommenter {
offsetList = new ArrayList<Integer>();
ppOffsetForFiles.put(fileName, offsetList);
}
offsetList.add(statement.getFileLocation().getNodeOffset());
offsetList.add(((ASTNode)statement).getOffset());
}
}
@ -109,7 +236,7 @@ public class ASTCommenter {
)) {
continue;
}
if(commentIsAtTheBeginningBeforePreprocessorStatements(comment, ppOffsetForFiles.get(fileName))) {
if(commentIsAtTheBeginningBeforePreprocessorStatements(comment, ppOffsetForFiles.get(fileName), tu)) {
continue;
}
commentsInCode.add(comment);
@ -119,7 +246,7 @@ public class ASTCommenter {
private static boolean commentIsAtTheBeginningBeforePreprocessorStatements(
IASTComment comment,
ArrayList<Integer> listOfPreProcessorOffset) {
ArrayList<Integer> listOfPreProcessorOffset, IASTTranslationUnit tu) {
if(listOfPreProcessorOffset == null) {
return false;
}
@ -128,25 +255,27 @@ public class ASTCommenter {
return true;
}
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(decl.getFileLocation().getNodeOffset() < comment.getFileLocation().getNodeOffset()) {
if(decl.getFileLocation().getNodeOffset() < commentNodeOffset) {
return false;
}
}
Collections.sort(listOfPreProcessorOffset);
if(listOfPreProcessorOffset.get(0) < comment.getFileLocation().getNodeOffset()) {
return false;
}
if(sameFile) {
if(listOfPreProcessorOffset.get(0) < decl.getFileLocation().getNodeOffset()) {
return true;
int nextPPOfset = -1;
for (Integer integer : listOfPreProcessorOffset) {
if(integer > commentNodeOffset) {
nextPPOfset = integer;
PPRangeChecker visti = new PPRangeChecker(true, nextPPOfset, commentNodeOffset);
tu.accept(visti);
if(visti.isPrePPComment) {
return true;
}
}
}else {
return true;
}
return false;
}

View file

@ -35,6 +35,7 @@ import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
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.IASTBinaryExpression;
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.ICPPMethod;
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.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();
return status;