Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Schorn2008-03-03 12:56:38 +0000
committerMarkus Schorn2008-03-03 12:56:38 +0000
commit4aa04977c3f65d67dfa55325bb248fe5f6fb30af (patch)
treec8bf6e660c1bf8f292d086d29b7c6d1bda454188 /core/org.eclipse.cdt.core/parser
parent90846e6bfa87c27ceef67ade5c5e3eecd24784d6 (diff)
downloadorg.eclipse.cdt-4aa04977c3f65d67dfa55325bb248fe5f6fb30af.tar.gz
org.eclipse.cdt-4aa04977c3f65d67dfa55325bb248fe5f6fb30af.tar.xz
org.eclipse.cdt-4aa04977c3f65d67dfa55325bb248fe5f6fb30af.zip
Combines IASTTranslationUnit.selectNodeForLocation() and ILanguage.getSelectedNodes() into new API.
Diffstat (limited to 'core/org.eclipse.cdt.core/parser')
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTMacroExpansion.java8
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTMacroExpansionLocation.java38
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTNode.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTNodeSelector.java49
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTPreprocessorMacroExpansion.java36
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java36
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/AbstractCLikeLanguage.java7
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNodeMatchKind.java113
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNodeSelector.java133
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTranslationUnit.java35
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/FindNodeForOffsetAction.java69
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorName.java12
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java108
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ILocationResolver.java26
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtxFile.java6
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtxMacroExpansion.java48
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationMap.java64
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MultiMacroExpansionExplorer.java16
18 files changed, 650 insertions, 158 deletions
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTMacroExpansion.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTMacroExpansion.java
index a650c2c3fee..d4d7270b5ee 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTMacroExpansion.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTMacroExpansion.java
@@ -12,12 +12,9 @@
package org.eclipse.cdt.core.dom.ast;
/**
- * A Macro expansion is a node location. Nodes that have locations that arrive
- * through the expansion of preprocessor macros will refer to these type of
- * objects.
- *
- * @author Doug Schaefer
+ * @deprecated, use IASTMacroExpansionLocation instead
*/
+@Deprecated
public interface IASTMacroExpansion extends IASTNodeLocation {
/**
@@ -54,5 +51,6 @@ public interface IASTMacroExpansion extends IASTNodeLocation {
* @return
* @deprecated use {@link IASTNodeLocation#asFileLocation()}.
*/
+ @Deprecated
public IASTNodeLocation[] getExpansionLocations();
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTMacroExpansionLocation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTMacroExpansionLocation.java
new file mode 100644
index 00000000000..d6808040620
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTMacroExpansionLocation.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.core.dom.ast;
+
+/**
+ * Node location inside of a macro expansion.
+ * @since 5.0
+ */
+public interface IASTMacroExpansionLocation extends IASTNodeLocation {
+
+ /**
+ * Returns the expansion node enclosing this location. This will be the outermost
+ * macro expansion that can actually be found in the code.
+ */
+ public IASTPreprocessorMacroExpansion getExpansion();
+
+ /**
+ * Returns an offset within the macro-expansion. The offset can be used to compare
+ * nodes within the same macro-expansion. However, it does not serve as an offset
+ * into a file.
+ */
+ public int getNodeOffset();
+
+ /**
+ * Returns the length of this location. The length can be used to compare this location
+ * with others from within the same macro-expansion. However, the length does not neccessarily
+ * relate to a length in terms of characters.
+ */
+ public int getNodeLength();
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTNode.java
index 1ddd1cbd6e8..0e6d288390d 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTNode.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTNode.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2007 IBM Corporation and others.
+ * Copyright (c) 2004, 2008 IBM Corporation 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
@@ -36,7 +36,7 @@ public interface IASTNode {
*
* Where the node is completely generated within a macro expansion,
* IASTNodeLocation [] result will have one element in it, and it will be an
- * IASTMacroExpansion.
+ * {@link IASTMacroExpansionLocation}.
*
* Nodes that span file context into a macro expansion (and potentially out
* of the macro expansion again) result in an IASTNodeLocation [] result
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTNodeSelector.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTNodeSelector.java
new file mode 100644
index 00000000000..636ee3cf6b4
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTNodeSelector.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.core.dom.ast;
+
+/**
+ * Interface for searching nodes of a file in a translation unit. An instance of this interface can
+ * be obtained via {@link IASTTranslationUnit#getNodeSelector(String)}.
+ * @since 5.0
+ */
+public interface IASTNodeSelector {
+
+ /**
+ * Returns the name for the exact given range, or <code>null</code> if there is no such node.
+ */
+ IASTName findName(int offset, int length);
+
+ /**
+ * Returns the smallest name surrounding the given range, or <code>null</code> if there is no such node.
+ */
+ IASTName findSurroundingName(int offset, int length);
+
+ /**
+ * Returns the first name contained in the given range, or <code>null</code> if there is no such node.
+ */
+ IASTName findFirstContainedName(int offset, int length);
+
+ /**
+ * Returns the node for the exact given range, or <code>null</code> if there is no such node.
+ */
+ IASTNode findNode(int offset, int length);
+
+ /**
+ * Returns the smallest node surrounding the given range, or <code>null</code> if there is no such node.
+ */
+ IASTNode findSurroundingNode(int offset, int length);
+
+ /**
+ * Returns the first node contained in the given range, or <code>null</code> if there is no such node.
+ */
+ IASTNode findFirstContainedNode(int offset, int length);
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTPreprocessorMacroExpansion.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTPreprocessorMacroExpansion.java
new file mode 100644
index 00000000000..84028700725
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTPreprocessorMacroExpansion.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.core.dom.ast;
+
+/**
+ * Models macro expansion found in the source code that is not nested inside another expansion.
+ * @since 5.0
+ */
+public interface IASTPreprocessorMacroExpansion extends IASTNode {
+ public static final IASTPreprocessorMacroExpansion[] EMPTY_ARRAY = {};
+ public static final ASTNodeProperty EXPANSION_NAME=
+ new ASTNodeProperty("IASTPreprocessorMacroExpansion.EXPANSION_NAME - macro name"); //$NON-NLS-1$
+
+ /**
+ * Returns the macro definition used for the expansion.
+ */
+ public IASTPreprocessorMacroDefinition getMacroDefinition();
+
+ /**
+ * Returns the reference to the macro that causes this expansion.
+ */
+ public IASTName getMacroReference();
+
+ /**
+ * Returns an array of nested macro expansions.
+ */
+ public IASTName[] getNestedMacroReferences();
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java
index 7c909837577..f2929181935 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java
@@ -115,15 +115,23 @@ public interface IASTTranslationUnit extends IASTNode, IAdaptable {
* @return List of IASTName nodes representing uses of the binding
*/
public IASTName[] getReferences(IBinding binding);
+
+
+ /**
+ * Returns an IASTNodeSelector object for finding nodes by file offsets.
+ * The object is suitable for working in one of the files that is part of
+ * the translation unit.
+ * @param filePath file of interest, as returned by {@link IASTFileLocation#getFileName()},
+ * or <code>null</code> to specify the root source of the translation-unit.
+ * @return an IASTNodeSelector.
+ * @since 5.0
+ */
+ public IASTNodeSelector getNodeSelector(String filePath);
/**
- * Select the node in the treat that best fits the offset/length/file path.
- *
- * @param path - file name specified through path
- * @param offset - location in the file as an offset
- * @param length - length of selection
- * @return <code>IASTNode</code> that best fits
+ * @deprecated use {@link #getNodeSelector(String)}, instead.
*/
+ @Deprecated
public IASTNode selectNodeForLocation(String path, int offset, int length);
/**
@@ -158,6 +166,11 @@ public interface IASTTranslationUnit extends IASTNode, IAdaptable {
public IASTPreprocessorStatement[] getAllPreprocessorStatements();
/**
+ * Returns an array with all macro expansions of this translation unit.
+ */
+ public IASTPreprocessorMacroExpansion[] getMacroExpansions();
+
+ /**
* Get all preprocessor and scanner problems.
* @return <code>IASTProblem[]</code>
*/
@@ -182,9 +195,16 @@ public interface IASTTranslationUnit extends IASTNode, IAdaptable {
*/
public IASTFileLocation flattenLocationsToFile( IASTNodeLocation [] nodeLocations );
- public static final ASTNodeProperty EXPANSION_NAME = new ASTNodeProperty(
+ /**
+ * @deprecated names for macro expansions are nested inside of {@link IASTPreprocessorMacroExpansion}.
+ */
+ @Deprecated
+ public static final ASTNodeProperty EXPANSION_NAME = new ASTNodeProperty(
"IASTTranslationUnit.EXPANSION_NAME - IASTName generated for macro expansions."); //$NON-NLS-1$
-
+
+ public static final ASTNodeProperty MACRO_EXPANSION = new ASTNodeProperty(
+ "IASTTranslationUnit.MACRO_EXPANSION - IASTPreprocessorMacroExpansion node for macro expansions."); //$NON-NLS-1$
+
public static interface IDependencyTree
{
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/AbstractCLikeLanguage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/AbstractCLikeLanguage.java
index 3bc79dd7596..b7b34d7c914 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/AbstractCLikeLanguage.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/AbstractCLikeLanguage.java
@@ -23,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTCompletionNode;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
+import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.model.AbstractLanguage;
@@ -180,13 +181,17 @@ public abstract class AbstractCLikeLanguage extends AbstractLanguage implements
public IASTName[] getSelectedNames(IASTTranslationUnit ast, int start, int length) {
- IASTNode selectedNode= ast.selectNodeForLocation(ast.getFilePath(), start, length);
+ IASTNode selectedNode= ast.getNodeSelector(null).findNode(start, length);
if (selectedNode == null)
return new IASTName[0];
if (selectedNode instanceof IASTName)
return new IASTName[] { (IASTName) selectedNode };
+
+ if (selectedNode instanceof IASTPreprocessorMacroExpansion) {
+ return new IASTName[] {((IASTPreprocessorMacroExpansion) selectedNode).getMacroReference()};
+ }
NameCollector collector = new NameCollector();
selectedNode.accept(collector);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNodeMatchKind.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNodeMatchKind.java
new file mode 100644
index 00000000000..ff4a186f9d3
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNodeMatchKind.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.dom.parser;
+
+import org.eclipse.cdt.core.dom.ast.IASTName;
+
+/**
+ * For searching ast-nodes by offset and length, instances of this class can be used to
+ * determine whether a node matches or not.
+ *
+ * @since 5.0
+ */
+public class ASTNodeMatchKind {
+ public enum Relation {FIRST_CONTAINED, EXACT, SURROUNDING}
+
+ static final ASTNodeMatchKind MATCH_EXACT= new ASTNodeMatchKind(Relation.EXACT, false);
+ static final ASTNodeMatchKind MATCH_EXACT_NAME= new ASTNodeMatchKind(Relation.EXACT, true);
+ static final ASTNodeMatchKind MATCH_FIRST_CONTAINED= new ASTNodeMatchKind(Relation.FIRST_CONTAINED, false);
+ static final ASTNodeMatchKind MATCH_FIRST_NAME_CONTAINED= new ASTNodeMatchKind(Relation.FIRST_CONTAINED, true);
+ static final ASTNodeMatchKind MATCH_SURROUNDING= new ASTNodeMatchKind(Relation.SURROUNDING, false);
+ static final ASTNodeMatchKind MATCH_SURROUNDING_NAME= new ASTNodeMatchKind(Relation.SURROUNDING, true);
+
+ private boolean fNamesOnly;
+ private Relation fRelation;
+
+ private ASTNodeMatchKind(Relation relation, boolean namesOnly) {
+ fRelation= relation;
+ fNamesOnly= namesOnly;
+ }
+
+ public Relation getRelationToSelection() {
+ return fRelation;
+ }
+
+ public boolean matchNamesOnly() {
+ return fNamesOnly;
+ }
+
+ /**
+ * Returns whether the node matches the selection.
+ */
+ public boolean matches(ASTNode node, int selOffset, int selLength) {
+ if (fNamesOnly && node instanceof IASTName == false) {
+ return false;
+ }
+
+ final int nodeOffset= node.getOffset();
+ final int nodeLength= node.getLength();
+ switch(fRelation) {
+ case EXACT:
+ return selOffset == nodeOffset && selLength == nodeLength;
+ case FIRST_CONTAINED:
+ return selOffset <= nodeOffset && nodeOffset+nodeLength <= selOffset+selLength;
+ case SURROUNDING:
+ return nodeOffset <= selOffset && selOffset+selLength <= nodeOffset+nodeLength;
+ default:
+ assert false;
+ return false;
+ }
+ }
+
+ /**
+ * Returns whether the node is a lower bound for matching the selection. A node is a lower
+ * bound when a node to the left of the given one cannot match the selection.
+ */
+ public boolean isLowerBound(ASTNode node, int selOffset, int selLength) {
+ final int nodeOffset= node.getOffset();
+ switch(fRelation) {
+ case SURROUNDING:
+ case EXACT:
+ return nodeOffset < selOffset+selLength;
+ case FIRST_CONTAINED:
+ return nodeOffset <= selOffset;
+ default:
+ assert false;
+ return false;
+ }
+ }
+
+ /**
+ * Returns whether cand1 is a better match than cand2, prefers cand1 in case of doubt.
+ */
+ public boolean isBetterMatch(ASTNode cand1, ASTNode cand2) {
+ if (cand1 == null)
+ return false;
+ if (cand2 == null)
+ return true;
+
+ final int nodeOffset1= cand1.getOffset();
+ final int nodeLength1= cand1.getLength();
+ final int nodeOffset2= cand2.getOffset();
+ final int nodeLength2= cand2.getLength();
+ switch(fRelation) {
+ case EXACT:
+ return true;
+ case FIRST_CONTAINED:
+ return nodeOffset1 < nodeOffset2 || (nodeOffset1 == nodeOffset2 && nodeLength1 <= nodeLength2);
+ case SURROUNDING:
+ return nodeLength1 <= nodeLength2;
+ default:
+ assert false;
+ return false;
+ }
+ }
+} \ No newline at end of file
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNodeSelector.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNodeSelector.java
new file mode 100644
index 00000000000..75b1fbe130f
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNodeSelector.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.dom.parser;
+
+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.IASTNodeLocation;
+import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
+import org.eclipse.cdt.internal.core.dom.parser.ASTNodeMatchKind.Relation;
+import org.eclipse.cdt.internal.core.parser.scanner.ILocationResolver;
+
+/**
+ * Class to support searching for nodes by offsets.
+ * @since 5.0
+ */
+public class ASTNodeSelector implements IASTNodeSelector {
+
+ private ASTTranslationUnit fTu;
+ private ILocationResolver fLocationResolver;
+ private String fFilePath;
+ private final boolean fIsValid;
+
+ public ASTNodeSelector(ASTTranslationUnit tu, ILocationResolver locationResolver, String filePath) {
+ fTu= tu;
+ fLocationResolver= locationResolver;
+ fFilePath= filePath;
+ fIsValid= verify();
+ }
+
+ private boolean verify() {
+ if (fLocationResolver != null) {
+ if (fFilePath == null) {
+ fFilePath= fLocationResolver.getTranslationUnitPath();
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getNode(int, int)
+ */
+ private IASTNode getNode(int offset, int length, ASTNodeMatchKind matchKind) {
+ if (!fIsValid) {
+ return null;
+ }
+
+ final int sequenceNumber= fLocationResolver.getSequenceNumberForFileOffset(fFilePath, offset);
+ if (sequenceNumber < 0) {
+ return null;
+ }
+ final int sequenceLength= length <= 0 ? 0 :
+ fLocationResolver.getSequenceNumberForFileOffset(fFilePath, offset+length-1) + 1 - sequenceNumber;
+
+ ASTNode preCand= searchPreprocessor(sequenceNumber, sequenceLength, matchKind);
+ if (preCand != null && matchKind.getRelationToSelection() != Relation.FIRST_CONTAINED) {
+ return preCand;
+ }
+ ASTNode astCand= searchAST(sequenceNumber, sequenceLength, matchKind);
+ return matchKind.isBetterMatch(preCand, astCand) ? preCand : astCand;
+ }
+
+ private ASTNode searchPreprocessor(int sequenceNumber, int sequenceLength, ASTNodeMatchKind matchKind) {
+ return fLocationResolver.findPreprocessorNode(sequenceNumber, sequenceLength, matchKind);
+ }
+
+ private ASTNode searchAST(int sequenceNumber, int length, ASTNodeMatchKind matchKind) {
+ FindNodeForOffsetAction nodeFinder= new FindNodeForOffsetAction(sequenceNumber, length, matchKind);
+ fTu.accept(nodeFinder);
+ ASTNode result= nodeFinder.getNode();
+ // don't accept matches from the ast enclosed in a macro expansion (possible for contained matches, only)
+ if (result != null &&
+ matchKind.getRelationToSelection() == Relation.FIRST_CONTAINED) {
+ IASTNodeLocation[] loc= result.getNodeLocations();
+ if (loc.length > 0 && loc[0] instanceof IASTMacroExpansionLocation) {
+ return null;
+ }
+ }
+ return result;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getFirstContainedNode(int, int)
+ */
+ public IASTNode findFirstContainedNode(int offset, int length) {
+ return getNode(offset, length, ASTNodeMatchKind.MATCH_FIRST_CONTAINED);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getNode(int, int)
+ */
+ public IASTNode findNode(int offset, int length) {
+ return getNode(offset, length, ASTNodeMatchKind.MATCH_EXACT);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getSurroundingNode(int, int)
+ */
+ public IASTNode findSurroundingNode(int offset, int length) {
+ return getNode(offset, length, ASTNodeMatchKind.MATCH_SURROUNDING);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getFirstContainedNode(int, int)
+ */
+ public IASTName findFirstContainedName(int offset, int length) {
+ return (IASTName) getNode(offset, length, ASTNodeMatchKind.MATCH_FIRST_NAME_CONTAINED);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getNode(int, int)
+ */
+ public IASTName findName(int offset, int length) {
+ return (IASTName) getNode(offset, length, ASTNodeMatchKind.MATCH_EXACT_NAME);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getSurroundingNode(int, int)
+ */
+ public IASTName findSurroundingName(int offset, int length) {
+ return (IASTName) getNode(offset, length, ASTNodeMatchKind.MATCH_SURROUNDING_NAME);
+ }
+
+} \ No newline at end of file
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTranslationUnit.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTranslationUnit.java
index caa28508919..4cdf3a28a88 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTranslationUnit.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTranslationUnit.java
@@ -21,8 +21,10 @@ import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
+import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
+import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
import org.eclipse.cdt.core.dom.ast.IASTProblem;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
@@ -139,11 +141,20 @@ public abstract class ASTTranslationUnit extends ASTNode implements IASTTranslat
return EMPTY_PREPROCESSOR_MACRODEF_ARRAY;
return fLocationResolver.getMacroDefinitions();
}
-
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.dom.ast.IASTTranslationUnit#getMacroExpansions()
+ */
+ public IASTPreprocessorMacroExpansion[] getMacroExpansions() {
+ if (fLocationResolver == null)
+ return IASTPreprocessorMacroExpansion.EMPTY_ARRAY;
+ return fLocationResolver.getMacroExpansions(getFileLocation());
+ }
+
/*
* (non-Javadoc)
*
- * @see org.eclipse.cdt.core.dom.ast.IASTTranslationUnit#getMacroDefinitions()
+ * @see org.eclipse.cdt.core.dom.ast.IASTTranslationUnit#getBuiltinMacroDefinitions()
*/
public final IASTPreprocessorMacroDefinition[] getBuiltinMacroDefinitions() {
if (fLocationResolver == null)
@@ -316,20 +327,10 @@ public abstract class ASTTranslationUnit extends ASTNode implements IASTTranslat
* @see org.eclipse.cdt.core.dom.ast.IASTTranslationUnit#getNodeForLocation(org.eclipse.cdt.core.dom.ast.IASTNodeLocation)
*/
public final IASTNode selectNodeForLocation(String path, int realOffset, int realLength) {
- IASTNode result= null;
- if (fLocationResolver != null) {
- int start= fLocationResolver.getSequenceNumberForFileOffset(path, realOffset);
- if (start >= 0) {
- int length= realLength < 1 ? 0 :
- fLocationResolver.getSequenceNumberForFileOffset(path, realOffset+realLength-1) + 1 - start;
- result= fLocationResolver.findSurroundingPreprocessorNode(start, length);
- if (result == null) {
- FindNodeForOffsetAction nodeFinder = new FindNodeForOffsetAction(start, length);
- accept(nodeFinder);
- result = nodeFinder.getNode();
- }
- }
- }
- return result;
+ return getNodeSelector(path).findNode(realOffset, realLength);
+ }
+
+ public final IASTNodeSelector getNodeSelector(String filePath) {
+ return new ASTNodeSelector(this, fLocationResolver, filePath);
}
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/FindNodeForOffsetAction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/FindNodeForOffsetAction.java
index a42d41926e6..143d932905d 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/FindNodeForOffsetAction.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/FindNodeForOffsetAction.java
@@ -39,49 +39,47 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisitor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
public class FindNodeForOffsetAction extends CPPASTVisitor implements ICASTVisitor, ICPPASTVisitor {
- private IASTNode fFoundNode = null;
- private int fOffset = 0;
- private int fLength = 0;
+ private ASTNode fCandidate= null;
+ private final int fOffset;
+ private final int fLength;
+ private final ASTNodeMatchKind fMatchKind;
- public FindNodeForOffsetAction(int offset, int length) {
+ public FindNodeForOffsetAction(int offset, int length, ASTNodeMatchKind matchKind) {
+ fMatchKind= matchKind;
fOffset = offset;
fLength = length;
shouldVisitNames = true;
- shouldVisitDeclarations = true;
- shouldVisitInitializers = true;
- shouldVisitParameterDeclarations = true;
- shouldVisitDeclarators = true;
- shouldVisitDeclSpecifiers = true;
- shouldVisitDesignators = true;
- shouldVisitEnumerators = true;
- shouldVisitExpressions = true;
- shouldVisitStatements = true;
- shouldVisitTypeIds = true;
- shouldVisitEnumerators = true;
- shouldVisitBaseSpecifiers = true;
- shouldVisitNamespaces = true;
- shouldVisitTemplateParameters= true;
- shouldVisitTranslationUnit= true;
+ shouldVisitDeclarations= true;
+
+ shouldVisitInitializers=
+ shouldVisitParameterDeclarations=
+ shouldVisitDeclarators=
+ shouldVisitDeclSpecifiers=
+ shouldVisitDesignators=
+ shouldVisitEnumerators=
+ shouldVisitExpressions=
+ shouldVisitStatements=
+ shouldVisitTypeIds=
+ shouldVisitEnumerators=
+ shouldVisitBaseSpecifiers=
+ shouldVisitNamespaces=
+ shouldVisitTemplateParameters=
+ shouldVisitTranslationUnit= !matchKind.matchNamesOnly();
}
public int processNode(IASTNode node) {
- if (fFoundNode != null)
- return PROCESS_ABORT;
-
if (node instanceof ASTNode) {
- final int offset = ((ASTNode) node).getOffset();
- final int length = ((ASTNode) node).getLength();
-
- if (offset == fOffset && length == fLength) {
- fFoundNode = node;
- return PROCESS_ABORT;
+ final ASTNode astNode = (ASTNode) node;
+ if (astNode.getOffset() > fOffset+fLength || astNode.getOffset() + astNode.getLength() < fOffset) {
+ return PROCESS_SKIP;
}
- // skip the rest of this node if the selection is outside of its
- // bounds
- if (fOffset > offset + length)
- return PROCESS_SKIP;
+ if (fMatchKind.matches(astNode, fOffset, fLength)) {
+ if (fCandidate == null || !fMatchKind.isBetterMatch(fCandidate, astNode)) {
+ fCandidate= astNode;
+ }
+ }
}
return PROCESS_CONTINUE;
}
@@ -90,8 +88,7 @@ public class FindNodeForOffsetAction extends CPPASTVisitor implements ICASTVisit
public int visit(IASTDeclaration declaration) {
// use declarations to determine if the search has gone past the
// offset (i.e. don't know the order the visitor visits the nodes)
- if (declaration instanceof ASTNode
- && ((ASTNode) declaration).getOffset() > fOffset)
+ if (declaration instanceof ASTNode && ((ASTNode) declaration).getOffset() > fOffset + fLength)
return PROCESS_ABORT;
return processNode(declaration);
@@ -208,7 +205,7 @@ public class FindNodeForOffsetAction extends CPPASTVisitor implements ICASTVisit
return processNode(tu);
}
- public IASTNode getNode() {
- return fFoundNode;
+ public ASTNode getNode() {
+ return fCandidate;
}
} \ No newline at end of file
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorName.java
index 59198c3b1af..8c97b1d4814 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorName.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorName.java
@@ -18,6 +18,7 @@ import org.eclipse.cdt.core.dom.ast.IASTImageLocation;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
+import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
@@ -60,6 +61,7 @@ class ASTPreprocessorName extends ASTPreprocessorNode implements IASTName {
public char[] toCharArray() {
return fName;
}
+ @Override
public String toString() {
return new String(fName);
}
@@ -72,6 +74,7 @@ class ASTPreprocessorDefinition extends ASTPreprocessorName {
super(parent, property, startNumber, endNumber, name, binding);
}
+ @Override
public boolean isDefinition() {
return true;
}
@@ -86,10 +89,12 @@ class ASTBuiltinName extends ASTPreprocessorDefinition {
fFileLocation= floc;
}
+ @Override
public boolean contains(IASTNode node) {
return node==this;
}
+ @Override
public String getContainingFilename() {
if (fFileLocation == null) {
return ""; //$NON-NLS-1$
@@ -97,10 +102,12 @@ class ASTBuiltinName extends ASTPreprocessorDefinition {
return fFileLocation.getFileName();
}
+ @Override
public IASTFileLocation getFileLocation() {
return fFileLocation;
}
+ @Override
public IASTNodeLocation[] getNodeLocations() {
if (fFileLocation == null) {
return new IASTNodeLocation[0];
@@ -108,6 +115,7 @@ class ASTBuiltinName extends ASTPreprocessorDefinition {
return new IASTNodeLocation[]{fFileLocation};
}
+ @Override
public String getRawSignature() {
if (fFileLocation == null) {
return ""; //$NON-NLS-1$
@@ -119,8 +127,8 @@ class ASTBuiltinName extends ASTPreprocessorDefinition {
class ASTMacroReferenceName extends ASTPreprocessorName {
private ImageLocationInfo fImageLocationInfo;
- public ASTMacroReferenceName(IASTNode parent, int offset, int endOffset, IMacroBinding macro, ImageLocationInfo imgLocationInfo) {
- super(parent, IASTTranslationUnit.EXPANSION_NAME, offset, endOffset, macro.getNameCharArray(), macro);
+ public ASTMacroReferenceName(IASTPreprocessorMacroExpansion parent, int offset, int endOffset, IMacroBinding macro, ImageLocationInfo imgLocationInfo) {
+ super(parent, IASTPreprocessorMacroExpansion.EXPANSION_NAME, offset, endOffset, macro.getNameCharArray(), macro);
fImageLocationInfo= imgLocationInfo;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java
index ab61429754a..3563065d0c8 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java
@@ -17,7 +17,7 @@ import org.eclipse.cdt.core.dom.ast.IASTComment;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTFunctionStyleMacroParameter;
import org.eclipse.cdt.core.dom.ast.IASTImageLocation;
-import org.eclipse.cdt.core.dom.ast.IASTMacroExpansion;
+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.IASTNodeLocation;
@@ -31,6 +31,7 @@ import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIfdefStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIfndefStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
+import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorObjectStyleMacroDefinition;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorPragmaStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorUndefStatement;
@@ -41,6 +42,8 @@ import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree.IASTInclusionNode;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
+import org.eclipse.cdt.internal.core.dom.parser.ASTNodeMatchKind;
+import org.eclipse.cdt.internal.core.dom.parser.ASTNodeMatchKind.Relation;
/**
* Models various AST-constructs obtained from the preprocessor.
@@ -69,10 +72,36 @@ abstract class ASTPreprocessorNode extends ASTNode {
}
/**
- * Returns a subnode surrounding the given range or this.
+ * Returns a matching node or null.
*/
- IASTNode findSurroundingNode(int sequenceNumber, int length) {
- return this;
+ ASTNode findNode(int sequenceNumber, int length, ASTNodeMatchKind matchKind) {
+ if (matchKind.matches(this, sequenceNumber, length)) {
+ return this;
+ }
+ return null;
+ }
+
+ /**
+ * Helper method for preprocessor nodes containing a name
+ */
+ protected ASTNode findNode(int sequenceNumber, int length, ASTPreprocessorName name, ASTNodeMatchKind matchKind) {
+ ASTNode n1, n2;
+ if (matchKind.getRelationToSelection() == Relation.SURROUNDING) {
+ n1= name;
+ n2= this;
+ }
+ else {
+ n1= this;
+ n2= name;
+ }
+
+ if (matchKind.matches(n1, sequenceNumber, length)) {
+ return n1;
+ }
+ if (matchKind.matches(n2, sequenceNumber, length)) {
+ return n2;
+ }
+ return null;
}
}
@@ -221,13 +250,8 @@ class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreproces
}
@Override
- IASTNode findSurroundingNode(int sequenceNumber, int length) {
- final int nameSequencNumber= fName.getOffset();
- final int nameEndSequencNumber= nameSequencNumber + fName.getLength();
- if (nameSequencNumber <= sequenceNumber && sequenceNumber+length <= nameEndSequencNumber) {
- return fName;
- }
- return this;
+ ASTNode findNode(int sequenceNumber, int length, ASTNodeMatchKind matchKind) {
+ return findNode(sequenceNumber, length, fName, matchKind);
}
}
@@ -284,13 +308,8 @@ class ASTMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessor
}
@Override
- IASTNode findSurroundingNode(int sequenceNumber, int length) {
- final int nameSequencNumber= fName.getOffset();
- final int nameEndSequencNumber= nameSequencNumber + fName.getLength();
- if (nameSequencNumber <= sequenceNumber && sequenceNumber+length <= nameEndSequencNumber) {
- return fName;
- }
- return this;
+ ASTNode findNode(int sequenceNumber, int length, ASTNodeMatchKind matchKind) {
+ return findNode(sequenceNumber, length, fName, matchKind);
}
public void setExpansion(String exp) {assert false;}
@@ -399,13 +418,8 @@ class ASTUndef extends ASTPreprocessorNode implements IASTPreprocessorUndefState
}
@Override
- IASTNode findSurroundingNode(int sequenceNumber, int length) {
- final int nameSequencNumber= fName.getOffset();
- final int nameEndSequencNumber= nameSequencNumber + fName.getLength();
- if (nameSequencNumber <= sequenceNumber && sequenceNumber+length <= nameEndSequencNumber) {
- return fName;
- }
- return this;
+ ASTNode findNode(int sequenceNumber, int length, ASTNodeMatchKind matchKind) {
+ return findNode(sequenceNumber, length, fName, matchKind);
}
}
@@ -503,7 +517,42 @@ class ASTFileLocation implements IASTFileLocation {
}
}
-class ASTMacroExpansionLocation implements IASTMacroExpansion {
+class ASTMacroExpansion extends ASTPreprocessorNode implements IASTPreprocessorMacroExpansion {
+
+ private LocationCtxMacroExpansion fContext;
+
+ public ASTMacroExpansion(IASTNode parent, int startNumber, int endNumber) {
+ super(parent, IASTTranslationUnit.MACRO_EXPANSION, startNumber, endNumber);
+ }
+
+ void setContext(LocationCtxMacroExpansion expansionCtx) {
+ fContext= expansionCtx;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion#getName()
+ */
+ public ASTMacroReferenceName getMacroReference() {
+ return fContext.getMacroReference();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion#getMacroDefinition()
+ */
+ public IASTPreprocessorMacroDefinition getMacroDefinition() {
+ return fContext.getMacroDefinition();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion#getNestedExpansions()
+ */
+ public IASTName[] getNestedMacroReferences() {
+ return fContext.getNestedMacroReferences();
+ }
+}
+
+@SuppressWarnings("deprecation")
+class ASTMacroExpansionLocation implements IASTMacroExpansionLocation, org.eclipse.cdt.core.dom.ast.IASTMacroExpansion {
private LocationCtxMacroExpansion fContext;
private int fOffset;
@@ -515,6 +564,13 @@ class ASTMacroExpansionLocation implements IASTMacroExpansion {
fLength= length;
}
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.dom.ast.IASTMacroExpansionLocation#getExpansion()
+ */
+ public IASTPreprocessorMacroExpansion getExpansion() {
+ return fContext.getExpansion();
+ }
+
public IASTNodeLocation[] getExpansionLocations() {
final IASTFileLocation fl= asFileLocation();
return fl == null ? new IASTNodeLocation[0] : new IASTNodeLocation[] {fl};
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ILocationResolver.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ILocationResolver.java
index 3a240b850f0..25e1bcebd21 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ILocationResolver.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ILocationResolver.java
@@ -14,25 +14,25 @@ package org.eclipse.cdt.internal.core.parser.scanner;
import org.eclipse.cdt.core.dom.ast.IASTComment;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTImageLocation;
-import org.eclipse.cdt.core.dom.ast.IASTMacroExpansion;
import org.eclipse.cdt.core.dom.ast.IASTName;
-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.IASTPreprocessorMacroExpansion;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
import org.eclipse.cdt.core.dom.ast.IASTProblem;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree;
+import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
+import org.eclipse.cdt.internal.core.dom.parser.ASTNodeMatchKind;
/**
* Interface between the ast and the location-resolver for resolving offsets.
* @since 5.0
*/
-public interface ILocationResolver {
-
+public interface ILocationResolver {
/**
* Introduces the ast translation unit to the location resolver. Must be called before any tokens from the
* scanner are obtained.
@@ -126,7 +126,7 @@ public interface ILocationResolver {
* Returns the sequence-number for the given file-path and offset, or <code>-1</code> if this file
* is not part of the translation-unit.
* @param filePath a file path or <code>null</code> to specify the root of the translation unit.
- * @param fileOffset an offset into the source of the file.
+ * @param fileOffset an offset into the source of the file, or <code>-1</code>.
*/
int getSequenceNumberForFileOffset(String filePath, int fileOffset);
@@ -139,8 +139,12 @@ public interface ILocationResolver {
* Returns a preprocessor node surrounding the given range, or <code>null</code>. The result is either a
* preprocessing directive ({@link IASTPreprocessorStatement}) or a name contained therein {@link IASTName} or
* a macro expansion ({@link IASTName}).
+ *
+ * @param sequenceNumber the sequence number of the start of the interesting region.
+ * @param length the sequence length of the interesting region.
+ * @param matchOption the kind of the desired match.
*/
- IASTNode findSurroundingPreprocessorNode(int sequenceNumber, int length);
+ ASTNode findPreprocessorNode(int sequenceNumber, int length, ASTNodeMatchKind matchOption);
/**
* Returns whether the specified sequence number points into the root file of the
@@ -161,13 +165,5 @@ public interface ILocationResolver {
* @return an array of macro expansions.
* @since 5.0
*/
- IASTMacroExpansion[] getMacroExpansions(IASTFileLocation loc);
-
- /**
- * Returns all implicit macro references related to an explicit one.
- * @param ref an explicit macro expansion.
- * @return an array of names representing implicit macro expansions.
- * @since 5.0
- */
- IASTName[] getImplicitMacroReferences(IASTName ref);
+ IASTPreprocessorMacroExpansion[] getMacroExpansions(IASTFileLocation loc);
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtxFile.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtxFile.java
index 0963ddadde0..b3110958bba 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtxFile.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtxFile.java
@@ -13,7 +13,7 @@ package org.eclipse.cdt.internal.core.parser.scanner;
import java.util.ArrayList;
import java.util.Collection;
-import org.eclipse.cdt.core.dom.ast.IASTMacroExpansion;
+import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion;
/**
* A location context representing a file.
@@ -105,7 +105,7 @@ class LocationCtxFile extends LocationCtxContainer {
return sequenceNumber >= child.fSequenceNumber + child.getSequenceLength();
}
- public void collectExplicitMacroExpansions(int offset, int length, ArrayList<IASTMacroExpansion> result) {
+ public void collectMacroExpansions(int offset, int length, ArrayList<IASTPreprocessorMacroExpansion> list) {
Collection<LocationCtx> children= getChildren();
for (LocationCtx ctx : children) {
// context must start before the end of the search range
@@ -115,7 +115,7 @@ class LocationCtxFile extends LocationCtxContainer {
if (ctx instanceof LocationCtxMacroExpansion) {
// expansion must end after the search start
if (ctx.fEndOffsetInParent > offset) {
- result.add(new ASTMacroExpansionLocation(((LocationCtxMacroExpansion) ctx), 0, ctx.getSequenceLength()));
+ list.add((IASTPreprocessorMacroExpansion) ((LocationCtxMacroExpansion)ctx).getMacroReference().getParent());
}
}
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtxMacroExpansion.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtxMacroExpansion.java
index 5c47a497076..0dc39f5a8c0 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtxMacroExpansion.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtxMacroExpansion.java
@@ -13,9 +13,13 @@ package org.eclipse.cdt.internal.core.parser.scanner;
import java.util.ArrayList;
import org.eclipse.cdt.core.dom.ast.IASTImageLocation;
+import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
+import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
+import org.eclipse.cdt.internal.core.dom.parser.ASTNodeMatchKind;
+import org.eclipse.cdt.internal.core.dom.parser.ASTNodeMatchKind.Relation;
/**
* A location context representing macro expansions.
@@ -24,22 +28,27 @@ import org.eclipse.cdt.core.dom.ast.IMacroBinding;
class LocationCtxMacroExpansion extends LocationCtx {
private final LocationMap fLocationMap;
private final int fLength;
- private final ASTMacroReferenceName fName;
private final ImageLocationInfo[] fLocationInfos;
+ private ASTMacroReferenceName fExpansionName;
public LocationCtxMacroExpansion(LocationMap map, LocationCtxContainer parent, int parentOffset, int parentEndOffset,
- int sequenceNumber, int length, ImageLocationInfo[] imageLocations, ASTMacroReferenceName expansion) {
+ int sequenceNumber, int length, ImageLocationInfo[] imageLocations, ASTMacroReferenceName expansionName) {
super(parent, parentOffset, parentEndOffset, sequenceNumber);
fLocationMap= map;
fLength= length;
- fName= expansion;
fLocationInfos= imageLocations;
+ fExpansionName= expansionName;
+ if (expansionName.getParent() instanceof ASTMacroExpansion == false) {
+ throw new IllegalArgumentException(expansionName.toString() + " is not a macro expansion name"); //$NON-NLS-1$
+ }
}
+ @Override
public int getSequenceLength() {
return fLength;
}
+ @Override
public boolean collectLocations(int start, int length, ArrayList<IASTNodeLocation> locations) {
final int offset= start-fSequenceNumber;
assert offset >= 0 && length >= 0;
@@ -53,14 +62,19 @@ class LocationCtxMacroExpansion extends LocationCtx {
return false;
}
+ public ASTMacroExpansion getExpansion() {
+ return (ASTMacroExpansion) fExpansionName.getParent();
+ }
+
public ASTMacroReferenceName getMacroReference() {
- return fName;
+ return fExpansionName;
}
public IASTPreprocessorMacroDefinition getMacroDefinition() {
- return fLocationMap.getMacroDefinition((IMacroBinding) fName.getBinding());
+ return fLocationMap.getMacroDefinition((IMacroBinding) fExpansionName.getBinding());
}
+ @Override
public LocationCtxMacroExpansion findSurroundingMacroExpansion(int sequenceNumber, int length) {
return this;
}
@@ -95,6 +109,30 @@ class LocationCtxMacroExpansion extends LocationCtx {
}
return null;
}
+
+ public ASTNode findNode(int sequenceNumber, int length, ASTNodeMatchKind matchKind) {
+ ASTNode n1, n2;
+ if (matchKind.getRelationToSelection() == Relation.SURROUNDING) {
+ n1= fExpansionName;
+ n2= (ASTNode) fExpansionName.getParent();
+ }
+ else {
+ n1= (ASTNode) fExpansionName.getParent();
+ n2= fExpansionName;
+ }
+
+ if (matchKind.matches(n1, sequenceNumber, length)) {
+ return n1;
+ }
+ if (matchKind.matches(n2, sequenceNumber, length)) {
+ return n2;
+ }
+ return null;
+ }
+
+ public IASTName[] getNestedMacroReferences() {
+ return fLocationMap.getNestedMacroReferences((ASTMacroExpansion) fExpansionName.getParent());
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationMap.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationMap.java
index 50f0be27aab..b0b54f63ce2 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationMap.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationMap.java
@@ -19,12 +19,11 @@ import java.util.List;
import org.eclipse.cdt.core.dom.ast.IASTComment;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTImageLocation;
-import org.eclipse.cdt.core.dom.ast.IASTMacroExpansion;
import org.eclipse.cdt.core.dom.ast.IASTName;
-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.IASTPreprocessorMacroExpansion;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
import org.eclipse.cdt.core.dom.ast.IASTProblem;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
@@ -32,7 +31,10 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
+import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
+import org.eclipse.cdt.internal.core.dom.parser.ASTNodeMatchKind;
import org.eclipse.cdt.internal.core.dom.parser.ASTProblem;
+import org.eclipse.cdt.internal.core.dom.parser.ASTNodeMatchKind.Relation;
/**
* Converts the offsets relative to various contexts to the global sequence number. Also creates and stores
@@ -136,7 +138,7 @@ public class LocationMap implements ILocationResolver {
* @param imageLocationInfo the image-location for the name of the macro.
*/
public IASTName encounterImplicitMacroExpansion(IMacroBinding macro, ImageLocationInfo imageLocationInfo) {
- return new ASTMacroReferenceName(fTranslationUnit, 0, 0, macro, imageLocationInfo);
+ return new ASTMacroReferenceName(null, 0, 0, macro, imageLocationInfo);
}
/**
@@ -157,16 +159,19 @@ public class LocationMap implements ILocationResolver {
int endNumber= getSequenceNumberForOffset(endOffset);
final int length= endNumber-nameNumber;
- ASTMacroReferenceName expansion= new ASTMacroReferenceName(fTranslationUnit, nameNumber, nameEndNumber, macro, null);
+ ASTMacroExpansion expansion= new ASTMacroExpansion(fTranslationUnit, nameNumber, endNumber);
+ ASTMacroReferenceName explicitRef= new ASTMacroReferenceName(expansion, nameNumber, nameEndNumber, macro, null);
for (int i = 0; i < implicitMacroReferences.length; i++) {
ASTMacroReferenceName name = (ASTMacroReferenceName) implicitMacroReferences[i];
- name.setOffsetAndLength(nameNumber, length);
name.setParent(expansion);
+ name.setOffsetAndLength(nameNumber, length);
addMacroReference(name);
}
- addMacroReference(expansion);
+ addMacroReference(explicitRef);
- fCurrentContext= new LocationCtxMacroExpansion(this, (LocationCtxContainer) fCurrentContext, nameOffset, endOffset, endNumber, contextLength, imageLocations, expansion);
+ LocationCtxMacroExpansion expansionCtx= new LocationCtxMacroExpansion(this, (LocationCtxContainer) fCurrentContext, nameOffset, endOffset, endNumber, contextLength, imageLocations, explicitRef);
+ expansion.setContext(expansionCtx);
+ fCurrentContext= expansionCtx;
fLastChildInsertionOffset= 0;
return fCurrentContext;
}
@@ -361,17 +366,17 @@ public class LocationMap implements ILocationResolver {
return floc.getSource();
}
- public IASTMacroExpansion[] getMacroExpansions(IASTFileLocation loc) {
+ public IASTPreprocessorMacroExpansion[] getMacroExpansions(IASTFileLocation loc) {
ASTFileLocation floc= convertFileLocation(loc);
if (floc == null) {
- return new IASTMacroExpansion[0];
+ return IASTPreprocessorMacroExpansion.EMPTY_ARRAY;
}
LocationCtxFile ctx= floc.getLocationContext();
- ArrayList<IASTMacroExpansion> list= new ArrayList<IASTMacroExpansion>();
+ ArrayList<IASTPreprocessorMacroExpansion> list= new ArrayList<IASTPreprocessorMacroExpansion>();
- ctx.collectExplicitMacroExpansions(floc.getNodeOffset(), floc.getNodeLength(), list);
- return list.toArray(new IASTMacroExpansion[list.size()]);
+ ctx.collectMacroExpansions(floc.getNodeOffset(), floc.getNodeLength(), list);
+ return list.toArray(new IASTPreprocessorMacroExpansion[list.size()]);
}
private ASTFileLocation convertFileLocation(IASTFileLocation loc) {
@@ -429,21 +434,24 @@ public class LocationMap implements ILocationResolver {
return null;
}
- public IASTNode findSurroundingPreprocessorNode(int sequenceNumber, int length) {
+ public ASTNode findPreprocessorNode(int sequenceNumber, int length, ASTNodeMatchKind matchKind) {
int lower=0;
int upper= fDirectives.size()-1;
while(lower <= upper) {
int middle= (lower+upper)/2;
- ASTPreprocessorNode node= fDirectives.get(middle);
- final int nodeSequenceNumber= node.getOffset();
- if (nodeSequenceNumber <= sequenceNumber) {
- final int nodeEndSequenceNumber= nodeSequenceNumber + node.getLength();
- if (sequenceNumber+length <= nodeEndSequenceNumber) {
- return node.findSurroundingNode(sequenceNumber, length);
- }
- else {
- lower= middle+1;
+ ASTPreprocessorNode candidate= fDirectives.get(middle);
+ ASTNode result= candidate.findNode(sequenceNumber, length, matchKind);
+ if (result != null) {
+ if (matchKind.getRelationToSelection() == Relation.FIRST_CONTAINED) {
+ if (middle>lower) {
+ upper= middle; // if (upper-lower == 1) then middle==lower
+ continue;
+ }
}
+ return result;
+ }
+ if (matchKind.isLowerBound(candidate, sequenceNumber, length)) {
+ lower= middle+1;
}
else {
upper= middle-1;
@@ -452,12 +460,7 @@ public class LocationMap implements ILocationResolver {
// search for a macro-expansion
LocationCtxMacroExpansion ctx= fRootContext.findSurroundingMacroExpansion(sequenceNumber, length);
if (ctx != null) {
- ASTMacroReferenceName candidate= ctx.getMacroReference();
- final int candSequenceNumber = candidate.getOffset();
- final int candEndSequenceNumber = candSequenceNumber + candidate.getLength();
- if (candSequenceNumber <= sequenceNumber && sequenceNumber + length <= candEndSequenceNumber) {
- return candidate;
- }
+ return ctx.findNode(sequenceNumber, length, matchKind);
}
return null;
@@ -587,10 +590,11 @@ public class LocationMap implements ILocationResolver {
return result.toArray(new IASTName[result.size()]);
}
- public IASTName[] getImplicitMacroReferences(IASTName ref) {
+ public IASTName[] getNestedMacroReferences(ASTMacroExpansion expansion) {
+ final IASTName explicitRef= expansion.getMacroReference();
List<IASTName> result= new ArrayList<IASTName>();
for (IASTName name : fMacroReferences) {
- if (name.getParent() == ref) {
+ if (name.getParent() == expansion && name != explicitRef) {
result.add(name);
}
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MultiMacroExpansionExplorer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MultiMacroExpansionExplorer.java
index 5a7d4b5a535..45fa127d5eb 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MultiMacroExpansionExplorer.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MultiMacroExpansionExplorer.java
@@ -17,9 +17,9 @@ import java.util.List;
import java.util.Map;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
-import org.eclipse.cdt.core.dom.ast.IASTMacroExpansion;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
+import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
@@ -65,7 +65,7 @@ public class MultiMacroExpansionExplorer extends MacroExpansionExplorer {
throw new IllegalArgumentException();
}
final ILocationResolver resolver = getResolver(tu);
- final IASTMacroExpansion[] expansions= resolver.getMacroExpansions(loc);
+ final IASTPreprocessorMacroExpansion[] expansions= resolver.getMacroExpansions(loc);
final int count= expansions.length;
loc = extendLocation(loc, expansions);
@@ -78,13 +78,13 @@ public class MultiMacroExpansionExplorer extends MacroExpansionExplorer {
final int firstOffset= loc.getNodeOffset();
int bidx= -1;
int didx= -1;
- for (IASTMacroExpansion expansion : expansions) {
+ for (IASTPreprocessorMacroExpansion expansion : expansions) {
IASTName ref= expansion.getMacroReference();
if (ref != null) {
ArrayList<IASTName> refs= new ArrayList<IASTName>();
refs.add(ref);
- refs.addAll(Arrays.asList(resolver.getImplicitMacroReferences(ref)));
- IASTFileLocation refLoc= expansion.asFileLocation();
+ refs.addAll(Arrays.asList(expansion.getNestedMacroReferences()));
+ IASTFileLocation refLoc= expansion.getFileLocation();
int from= refLoc.getNodeOffset()-firstOffset;
int to= from+refLoc.getNodeLength();
fBoundaries[++bidx]= from;
@@ -105,14 +105,14 @@ public class MultiMacroExpansionExplorer extends MacroExpansionExplorer {
return resolver;
}
- private IASTFileLocation extendLocation(IASTFileLocation loc, final IASTMacroExpansion[] expansions) {
+ private IASTFileLocation extendLocation(IASTFileLocation loc, final IASTPreprocessorMacroExpansion[] expansions) {
final int count= expansions.length;
if (count > 0) {
int from= loc.getNodeOffset();
int to= from+loc.getNodeLength();
- final int lfrom = expansions[0].asFileLocation().getNodeOffset();
- final IASTFileLocation l= expansions[count-1].asFileLocation();
+ final int lfrom = expansions[0].getFileLocation().getNodeOffset();
+ final IASTFileLocation l= expansions[count-1].getFileLocation();
final int lto= l.getNodeOffset() + l.getNodeLength();
if (lfrom < from || lto > to) {

Back to the top