mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-08 02:06:01 +02:00
Bug 322750: Expanding selection with macro expansion.
This commit is contained in:
parent
45540144be
commit
b25a75fc64
4 changed files with 43 additions and 37 deletions
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008, 2009 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2008, 2010 Wind River Systems, Inc. and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -72,10 +72,18 @@ public interface IASTNodeSelector {
|
|||
* <p>
|
||||
* For nodes with the same location, macro-expansions ({@link IASTPreprocessorMacroExpansion}) are preferred
|
||||
* over c/c++-nodes nodes and children are preferred over their parents.
|
||||
* Prefers children over parents.
|
||||
*/
|
||||
IASTNode findEnclosingNode(int offset, int length);
|
||||
|
||||
/**
|
||||
* Returns the smallest node strictly enclosing the given range, or <code>null</code> if there is no such node.
|
||||
* <p>
|
||||
* For nodes with the same location, macro-expansions ({@link IASTPreprocessorMacroExpansion}) are preferred
|
||||
* over c/c++-nodes nodes and children are preferred over their parents.
|
||||
* @since 5.3
|
||||
*/
|
||||
IASTNode findStrictlyEnclosingNode(int offset, int length);
|
||||
|
||||
/**
|
||||
* Returns the first node contained in the given range, or <code>null</code> if there is no such node.
|
||||
* <p>
|
||||
|
|
|
@ -108,7 +108,7 @@ public class ASTNodeSelector implements IASTNodeSelector {
|
|||
expansion= nodeSpec.findTrailingMacroExpansion(this);
|
||||
if (expansion != null) {
|
||||
IASTFileLocation floc= expansion.getFileLocation();
|
||||
seqend= fLocationResolver.getSequenceNumberForFileOffset(fFilePath, floc.getNodeOffset() + floc.getNodeLength())-1;
|
||||
seqend= fLocationResolver.getSequenceNumberForFileOffset(fFilePath, floc.getNodeOffset() + floc.getNodeLength());
|
||||
}
|
||||
nodeSpec.setRangeInSequence(seqbegin, seqend-seqbegin);
|
||||
|
||||
|
@ -131,6 +131,10 @@ public class ASTNodeSelector implements IASTNodeSelector {
|
|||
return findNode(offset, length, Relation.ENCLOSING, IASTNode.class);
|
||||
}
|
||||
|
||||
public IASTNode findStrictlyEnclosingNode(int offset, int length) {
|
||||
return findNode(offset, length, Relation.STRICTLY_ENCLOSING, IASTNode.class);
|
||||
}
|
||||
|
||||
public IASTNode findFirstContainedNodeInExpansion(int offset, int length) {
|
||||
return findNode(offset, length, Relation.FIRST_CONTAINED, IASTNode.class, true);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2008, 2010 Wind River Systems, Inc. and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -23,7 +23,7 @@ import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion;
|
|||
* @since 5.0
|
||||
*/
|
||||
public class ASTNodeSpecification<T extends IASTNode> {
|
||||
public enum Relation {FIRST_CONTAINED, EXACT_MATCH, ENCLOSING}
|
||||
public enum Relation {FIRST_CONTAINED, EXACT_MATCH, ENCLOSING, STRICTLY_ENCLOSING}
|
||||
|
||||
private final Class<T> fClass;
|
||||
private final Relation fRelation;
|
||||
|
@ -105,10 +105,14 @@ public class ASTNodeSpecification<T extends IASTNode> {
|
|||
return selOffset <= offset && endOffset <= selEndOffset;
|
||||
case ENCLOSING:
|
||||
return offset <= selOffset && selEndOffset <= endOffset;
|
||||
default:
|
||||
assert false;
|
||||
case STRICTLY_ENCLOSING:
|
||||
if (offset <= selOffset && selEndOffset <= endOffset) {
|
||||
return offset != selOffset || selEndOffset != endOffset;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
assert false;
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isAcceptableNode(IASTNode astNode) {
|
||||
|
@ -134,13 +138,17 @@ public class ASTNodeSpecification<T extends IASTNode> {
|
|||
case EXACT_MATCH:
|
||||
case ENCLOSING:
|
||||
return offset <= fSeqNumber && fSeqEndNumber <= endOffset;
|
||||
case STRICTLY_ENCLOSING:
|
||||
if (offset <= fSeqNumber && fSeqEndNumber <= endOffset) {
|
||||
return offset != fSeqNumber || fSeqEndNumber != endOffset;
|
||||
}
|
||||
return false;
|
||||
case FIRST_CONTAINED:
|
||||
return offset <= fSeqEndNumber && fSeqNumber <= endOffset;
|
||||
default:
|
||||
}
|
||||
assert false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void storeIfBest(IASTFileLocation loc, T astNode) {
|
||||
if (loc != null) {
|
||||
|
@ -179,6 +187,7 @@ public class ASTNodeSpecification<T extends IASTNode> {
|
|||
}
|
||||
return false;
|
||||
case ENCLOSING:
|
||||
case STRICTLY_ENCLOSING:
|
||||
final int bestLength= fBestEndOffset-fBestOffset;
|
||||
if (length < bestLength) {
|
||||
return true;
|
||||
|
@ -202,7 +211,7 @@ public class ASTNodeSpecification<T extends IASTNode> {
|
|||
|
||||
public IASTPreprocessorMacroExpansion findLeadingMacroExpansion(ASTNodeSelector nodeSelector) {
|
||||
IASTPreprocessorMacroExpansion exp= nodeSelector.findEnclosingMacroExpansion(fZeroToLeft ? fFileOffset-1 : fFileOffset, 1);
|
||||
if (fRelation == Relation.ENCLOSING)
|
||||
if (fRelation == Relation.ENCLOSING || fRelation == Relation.STRICTLY_ENCLOSING)
|
||||
return exp;
|
||||
|
||||
if (exp != null) {
|
||||
|
@ -219,7 +228,7 @@ public class ASTNodeSpecification<T extends IASTNode> {
|
|||
|
||||
public IASTPreprocessorMacroExpansion findTrailingMacroExpansion(ASTNodeSelector nodeSelector) {
|
||||
IASTPreprocessorMacroExpansion exp= nodeSelector.findEnclosingMacroExpansion(fFileEndOffset==fFileOffset && !fZeroToLeft ? fFileEndOffset : fFileEndOffset-1, 1);
|
||||
if (fRelation == Relation.ENCLOSING)
|
||||
if (fRelation == Relation.ENCLOSING || fRelation == Relation.STRICTLY_ENCLOSING)
|
||||
return exp;
|
||||
|
||||
if (exp != null) {
|
||||
|
|
|
@ -14,7 +14,9 @@ import java.util.ResourceBundle;
|
|||
|
||||
import org.eclipse.ui.texteditor.ITextEditor;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.model.ISourceRange;
|
||||
|
||||
|
@ -44,29 +46,12 @@ public class StructureSelectEnclosingAction extends StructureSelectionAction {
|
|||
* Made public to serve as fallback for other expansions
|
||||
*/
|
||||
public static ISourceRange expandToEnclosing(IASTTranslationUnit ast, SourceRange current) {
|
||||
IASTNode enclosingNode = ast.getNodeSelector(null).findEnclosingNode(current.getStartPos(),
|
||||
current.getLength());
|
||||
|
||||
int newOffset = enclosingNode.getFileLocation().getNodeOffset();
|
||||
int newLength = enclosingNode.getFileLocation().getNodeLength();
|
||||
|
||||
// we can have some nested nodes with same position, so traverse until we have a new position.
|
||||
while (newOffset == current.getStartPos() && newLength == current.getLength()) {
|
||||
IASTNode toBeSelected = enclosingNode.getParent();
|
||||
// if we can't traverse further, give up
|
||||
if (toBeSelected == null
|
||||
|| toBeSelected.getFileLocation().getFileName() != enclosingNode.getFileLocation()
|
||||
.getFileName()) {
|
||||
final IASTNodeSelector nodeSelector = ast.getNodeSelector(null);
|
||||
IASTNode node = nodeSelector.findStrictlyEnclosingNode(current.getStartPos(), current.getLength());
|
||||
if (node == null)
|
||||
return null;
|
||||
|
||||
final IASTFileLocation fileLocation = node.getFileLocation();
|
||||
return new SourceRange(fileLocation.getNodeOffset(), fileLocation.getNodeLength());
|
||||
}
|
||||
newOffset = toBeSelected.getFileLocation().getNodeOffset();
|
||||
newLength = toBeSelected.getFileLocation().getNodeLength();
|
||||
|
||||
enclosingNode = toBeSelected;
|
||||
}
|
||||
|
||||
return new SourceRange(newOffset, newLength);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue