From e18fdc081caf86dbd57f2e2be52fcedb1b9628b9 Mon Sep 17 00:00:00 2001 From: Anton Leherbauer Date: Thu, 7 Dec 2006 12:31:41 +0000 Subject: [PATCH] Semantic highlighting: Improve handling of macro expansions --- .../resources/semanticHighlighting/SHTest.cpp | 8 +- .../tests/text/SemanticHighlightingTest.java | 8 +- .../SemanticHighlightingReconciler.java | 111 +++++++++++------- .../ui/editor/SemanticHighlightings.java | 8 +- 4 files changed, 85 insertions(+), 50 deletions(-) diff --git a/core/org.eclipse.cdt.ui.tests/resources/semanticHighlighting/SHTest.cpp b/core/org.eclipse.cdt.ui.tests/resources/semanticHighlighting/SHTest.cpp index 875eb016fbf..e5c782d8283 100644 --- a/core/org.eclipse.cdt.ui.tests/resources/semanticHighlighting/SHTest.cpp +++ b/core/org.eclipse.cdt.ui.tests/resources/semanticHighlighting/SHTest.cpp @@ -1,4 +1,4 @@ -#define SIMPLE_MACRO +#define INT int #define FUNCTION_MACRO(arg) globalFunc(arg) enum Enumeration { @@ -102,16 +102,16 @@ namespace ns { } } -int ClassContainer::protMethod() { +INT ClassContainer::protMethod() { return protField; } -int ClassContainer::pubMethod() { +INT ClassContainer::pubMethod() { int localVar = 0; return pubField + localVar; } -int ClassContainer::staticPrivMethod() { +INT ClassContainer::staticPrivMethod() { CppStruct* st= new CppStruct(); st->structField= 1; CppUnion un; diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/SemanticHighlightingTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/SemanticHighlightingTest.java index 8fa1f0c84e8..7a9ac25cb73 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/SemanticHighlightingTest.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/SemanticHighlightingTest.java @@ -27,7 +27,7 @@ import org.eclipse.cdt.internal.ui.editor.SemanticHighlightings; */ public class SemanticHighlightingTest extends AbstractSemanticHighlightingTest { - private static final boolean PRINT_POSITIONS= false; + private static final boolean PRINT_POSITIONS= true; private static final Class THIS= SemanticHighlightingTest.class; @@ -206,6 +206,7 @@ public class SemanticHighlightingTest extends AbstractSemanticHighlightingTest { Position[] expected= new Position[] { createPosition(11, 20, 1), createPosition(28, 35, 3), + createPosition(29, 8, 19), createPosition(30, 19, 3), createPosition(77, 21, 4), createPosition(77, 30, 4), @@ -313,9 +314,11 @@ public class SemanticHighlightingTest extends AbstractSemanticHighlightingTest { createPosition(11, 5, 10), createPosition(12, 12, 16), createPosition(19, 16, 10), + createPosition(29, 8, 19), createPosition(30, 8, 10), createPosition(98, 8, 13), createPosition(99, 1, 16), + createPosition(120, 4, 17), }; if (PRINT_POSITIONS) System.out.println(toString(actual)); assertEqualPositions(expected, actual); @@ -342,6 +345,9 @@ public class SemanticHighlightingTest extends AbstractSemanticHighlightingTest { Position[] actual= getSemanticHighlightingPositions(); Position[] expected= new Position[] { createPosition(29, 8, 19), + createPosition(104, 0, 3), + createPosition(108, 0, 3), + createPosition(113, 0, 3), createPosition(120, 4, 17), }; if (PRINT_POSITIONS) System.out.println(toString(actual)); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightingReconciler.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightingReconciler.java index 3d39e6f924c..da232a4bf61 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightingReconciler.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightingReconciler.java @@ -31,8 +31,10 @@ import org.eclipse.ui.IWorkbenchPartSite; import org.eclipse.cdt.core.IPositionConverter; import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTExpression; +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.IASTNode; @@ -63,6 +65,7 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener { shouldVisitNames= true; shouldVisitDeclarations= true; shouldVisitExpressions= true; + shouldVisitDeclSpecifiers= true; } /** The semantic token */ @@ -86,11 +89,17 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener { if (!fFilePath.equals(declaration.getContainingFilename())) { return PROCESS_SKIP; } - IASTNodeLocation[] nodeLocations= declaration.getNodeLocations(); - if (nodeLocations.length > 0 && nodeLocations[0] instanceof IASTMacroExpansion) { - if (visitNode(declaration)) { - return PROCESS_SKIP; - } + if (checkForMacro(declaration)) { + return PROCESS_SKIP; + } + return PROCESS_CONTINUE; + } + + /* + * @see org.eclipse.cdt.core.dom.ast.ASTVisitor#visit(org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier) + */ + public int visit(IASTDeclSpecifier declSpec) { + if (checkForMacro(declSpec)) { return PROCESS_SKIP; } return PROCESS_CONTINUE; @@ -100,14 +109,7 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener { * @see org.eclipse.cdt.core.dom.ast.ASTVisitor#visit(org.eclipse.cdt.core.dom.ast.IASTExpression) */ public int visit(IASTExpression expression) { - if (!fFilePath.equals(expression.getContainingFilename())) { - return PROCESS_SKIP; - } - IASTNodeLocation[] nodeLocations= expression.getNodeLocations(); - if (nodeLocations.length > 0 && nodeLocations[0] instanceof IASTMacroExpansion) { - if (visitNode(expression)) { - return PROCESS_SKIP; - } + if (checkForMacro(expression)) { return PROCESS_SKIP; } return PROCESS_CONTINUE; @@ -117,23 +119,25 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener { * @see org.eclipse.cdt.core.dom.ast.ASTVisitor#visit(org.eclipse.cdt.core.dom.ast.IASTName) */ public int visit(IASTName node) { - if (!fFilePath.equals(node.getContainingFilename())) { - return PROCESS_SKIP; - } visitNode(node); return PROCESS_CONTINUE; } + private boolean checkForMacro(IASTNode node) { + IASTNodeLocation[] nodeLocations= node.getNodeLocations(); + if (nodeLocations.length == 1 && nodeLocations[0] instanceof IASTMacroExpansion) { + return visitNode(node); + } + return false; + } + private boolean visitNode(IASTNode node) { boolean consumed= false; fToken.update(node); for (int i= 0, n= fJobSemanticHighlightings.length; i < n; ++i) { SemanticHighlighting semanticHighlighting= fJobSemanticHighlightings[i]; if (fJobHighlightings[i].isEnabled() && semanticHighlighting.consumes(fToken)) { - IASTNodeLocation[] nodeLocations= node.getNodeLocations(); - if (nodeLocations.length > 0) { - addNodeLocations(nodeLocations, fJobHighlightings[i]); - } + addNodeLocations(node.getNodeLocations(), fJobHighlightings[i]); consumed= true; break; } @@ -143,34 +147,61 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener { } /** - * Add all node locations for the given highlighting. + * Add the a location range for the given highlighting. * * @param nodeLocations The node locations * @param highlighting The highlighting */ private void addNodeLocations(IASTNodeLocation[] nodeLocations, HighlightingStyle highlighting) { - for (int j = 0; j < nodeLocations.length; j++) { - IASTNodeLocation nodeLocation = nodeLocations[j]; - if (nodeLocation instanceof IASTMacroExpansion) { - IASTMacroExpansion macroExpansion= (IASTMacroExpansion)nodeLocation; - IASTNodeLocation[] expansionLocations = macroExpansion.getExpansionLocations(); - addNodeLocations(expansionLocations, highlighting); - } else { - int offset= nodeLocation.getNodeOffset(); - int length= nodeLocation.getNodeLength(); - if (fPositionTracker != null) { - IRegion actualPos= fPositionTracker.historicToActual(new Region(offset, length)); - offset= actualPos.getOffset(); - length= actualPos.getLength(); - } - if (offset > -1 && length > 0) { - addPosition(offset, length, highlighting); - } - } + final IASTFileLocation minLocation= getMinFileLocation(nodeLocations); + if (minLocation == null) { + return; + } + final IASTFileLocation maxLocation= getMaxFileLocation(nodeLocations); + if (maxLocation == null) { + return; + } + int offset= minLocation.getNodeOffset(); + int length= maxLocation.getNodeOffset() + maxLocation.getNodeLength() - offset; + if (fPositionTracker != null) { + IRegion actualPos= fPositionTracker.historicToActual(new Region(offset, length)); + offset= actualPos.getOffset(); + length= actualPos.getLength(); + } + if (offset > -1 && length > 0) { + addPosition(offset, length, highlighting); } } - /** + private IASTFileLocation getMaxFileLocation(IASTNodeLocation[] locations) { + if (locations == null || locations.length == 0) { + return null; + } + final IASTNodeLocation nodeLocation= locations[locations.length-1]; + if (nodeLocation instanceof IASTFileLocation) { + return (IASTFileLocation)nodeLocation; + } else if (nodeLocation instanceof IASTMacroExpansion) { + IASTNodeLocation[] macroLocations= ((IASTMacroExpansion)nodeLocation).getExpansionLocations(); + return getMaxFileLocation(macroLocations); + } + return null; + } + + private IASTFileLocation getMinFileLocation(IASTNodeLocation[] locations) { + if (locations == null || locations.length == 0) { + return null; + } + final IASTNodeLocation nodeLocation= locations[0]; + if (nodeLocation instanceof IASTFileLocation) { + return (IASTFileLocation)nodeLocation; + } else if (nodeLocation instanceof IASTMacroExpansion) { + IASTNodeLocation[] macroLocations= ((IASTMacroExpansion)nodeLocation).getExpansionLocations(); + return getMinFileLocation(macroLocations); + } + return null; + } + + /** * Add a position with the given range and highlighting iff it does not exist already. * * @param offset The range offset diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java index cf0dead0473..075c74234e5 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java @@ -1492,11 +1492,9 @@ public class SemanticHighlightings { */ public boolean consumes(SemanticToken token) { IASTNode node= token.getNode(); - if (!(node instanceof IASTName)) { - IASTNodeLocation[] nodeLocations= node.getNodeLocations(); - if (nodeLocations.length == 1 && nodeLocations[0] instanceof IASTMacroExpansion) { - return true; - } + IASTNodeLocation[] nodeLocations= node.getNodeLocations(); + if (nodeLocations.length == 1 && nodeLocations[0] instanceof IASTMacroExpansion) { + return true; } return false; }