From 4aa04977c3f65d67dfa55325bb248fe5f6fb30af Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Mon, 3 Mar 2008 12:56:38 +0000 Subject: [PATCH] Combines IASTTranslationUnit.selectNodeForLocation() and ILanguage.getSelectedNodes() into new API. --- .../core/parser/tests/ast2/AST2BaseTest.java | 27 ++-- .../ast2/AST2SelectionParseBaseTest.java | 7 +- .../tests/ast2/DOMLocationMacroTests.java | 86 +++++------ .../tests/ast2/DOMSelectionParseBaseTest.java | 19 +-- .../tests/scanner/LocationMapTests.java | 7 +- .../tests/IndexBindingResolutionTestBase.java | 66 +++------ .../internal/index/tests/IndexBugsTests.java | 2 +- .../tests/IndexCPPBindingResolutionBugs.java | 8 +- .../org/eclipse/cdt/core/model/ILanguage.java | 8 +- .../cdt/core/dom/ast/IASTMacroExpansion.java | 8 +- .../dom/ast/IASTMacroExpansionLocation.java | 38 +++++ .../eclipse/cdt/core/dom/ast/IASTNode.java | 4 +- .../cdt/core/dom/ast/IASTNodeSelector.java | 49 +++++++ .../ast/IASTPreprocessorMacroExpansion.java | 36 +++++ .../cdt/core/dom/ast/IASTTranslationUnit.java | 36 +++-- .../dom/parser/AbstractCLikeLanguage.java | 7 +- .../core/dom/parser/ASTNodeMatchKind.java | 113 +++++++++++++++ .../core/dom/parser/ASTNodeSelector.java | 133 ++++++++++++++++++ .../core/dom/parser/ASTTranslationUnit.java | 35 ++--- .../dom/parser/FindNodeForOffsetAction.java | 69 +++++---- .../parser/scanner/ASTPreprocessorName.java | 12 +- .../parser/scanner/ASTPreprocessorNode.java | 108 ++++++++++---- .../parser/scanner/ILocationResolver.java | 26 ++-- .../core/parser/scanner/LocationCtxFile.java | 6 +- .../scanner/LocationCtxMacroExpansion.java | 48 ++++++- .../core/parser/scanner/LocationMap.java | 64 +++++---- .../scanner/MultiMacroExpansionExplorer.java | 16 +-- .../ui/tests/DOMAST/ShowInDOMViewAction.java | 8 +- .../cdt/ui/tests/text/HyperlinkTest.java | 1 + .../selection/BaseSelectionTestsIndexer.java | 7 +- .../CPPSelectionTestsAnyIndexer.java | 2 +- .../selection/CPPSelectionTestsNoIndexer.java | 9 +- .../selection/CSelectionTestsNoIndexer.java | 5 +- .../text/selection/ResolveBindingTests.java | 8 +- .../ui/editor/CElementHyperlinkDetector.java | 84 ++++------- .../SemanticHighlightingReconciler.java | 4 + .../search/PDOMSearchTextSelectionQuery.java | 20 ++- .../ui/search/actions/FindAction.java | 2 +- .../actions/OpenDeclarationsAction.java | 8 +- .../search/actions/SelectionParseAction.java | 116 +-------------- .../ui/text/c/hover/CSourceHover.java | 37 +++-- 41 files changed, 826 insertions(+), 523 deletions(-) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTMacroExpansionLocation.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTNodeSelector.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTPreprocessorMacroExpansion.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNodeMatchKind.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNodeSelector.java diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java index 98f418c2663..315f03479fe 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java @@ -13,9 +13,7 @@ package org.eclipse.cdt.core.parser.tests.ast2; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; -import java.util.ListIterator; import org.eclipse.cdt.core.dom.ast.ASTSignatureUtil; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; @@ -44,8 +42,6 @@ import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.c.CASTVisitor; import org.eclipse.cdt.core.dom.ast.c.ICASTTypeIdInitializerExpression; import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor; -import org.eclipse.cdt.core.dom.ast.gnu.c.GCCLanguage; -import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage; import org.eclipse.cdt.core.dom.parser.IScannerExtensionConfiguration; import org.eclipse.cdt.core.dom.parser.ISourceCodeParser; import org.eclipse.cdt.core.dom.parser.c.ANSICParserExtensionConfiguration; @@ -56,7 +52,6 @@ import org.eclipse.cdt.core.dom.parser.cpp.ANSICPPParserExtensionConfiguration; import org.eclipse.cdt.core.dom.parser.cpp.GPPParserExtensionConfiguration; import org.eclipse.cdt.core.dom.parser.cpp.GPPScannerExtensionConfiguration; import org.eclipse.cdt.core.dom.parser.cpp.ICPPParserExtensionConfiguration; -import org.eclipse.cdt.core.model.ILanguage; import org.eclipse.cdt.core.parser.CodeReader; import org.eclipse.cdt.core.parser.IParserLogService; import org.eclipse.cdt.core.parser.IScanner; @@ -443,22 +438,16 @@ public class AST2BaseTest extends BaseTestCase { } private IBinding binding(String section, int len) { - ILanguage language = isCPP ? GPPLanguage.getDefault() : GCCLanguage.getDefault(); - IASTName[] names= language.getSelectedNames(tu, contents.indexOf(section), len); - List lnames= new ArrayList(Arrays.asList(names)); - for(ListIterator li= lnames.listIterator(); li.hasNext(); ) { - IASTName name= (IASTName) li.next(); - if(name.getRawSignature().length()!=len) { - li.remove(); - } - } - names= (IASTName[]) lnames.toArray(new IASTName[lnames.size()]); - assertEquals("found " + names.length + " names for \""+section.substring(0, len)+"\"", 1, names.length); + final int offset = contents.indexOf(section); + final String selection = section.substring(0, len); + IASTName name= tu.getNodeSelector(null).findName(offset, len); + assertNotNull("did not find \""+selection+"\"", name); + assertEquals(selection, name.getRawSignature()); - IBinding binding = names[0].resolveBinding(); - assertNotNull("No binding for "+names[0].getRawSignature(), binding); + IBinding binding = name.resolveBinding(); + assertNotNull("No binding for "+name.getRawSignature(), binding); - return names[0].resolveBinding(); + return name.resolveBinding(); } } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2SelectionParseBaseTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2SelectionParseBaseTest.java index d383f308005..4d3ef2d8e4d 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2SelectionParseBaseTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2SelectionParseBaseTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. + * Copyright (c) 2005, 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 @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.core.parser.tests.ast2; @@ -60,7 +61,7 @@ public class AST2SelectionParseBaseTest extends FileBasePluginTest { protected IASTNode parse(IFile file, ParserLanguage lang, int offset, int length) throws ParserException { IASTTranslationUnit tu = parse(file, lang, false, false); - return tu.selectNodeForLocation(tu.getFilePath(), offset, length); + return tu.getNodeSelector(null).findNode(offset, length); } protected IASTNode parse(String code, ParserLanguage lang, int offset, int length, boolean expectedToPass) throws ParserException { @@ -69,7 +70,7 @@ public class AST2SelectionParseBaseTest extends FileBasePluginTest { protected IASTNode parse(String code, ParserLanguage lang, boolean useGNUExtensions, boolean expectNoProblems, int offset, int length) throws ParserException { IASTTranslationUnit tu = parse(code, lang, useGNUExtensions, expectNoProblems); - return tu.selectNodeForLocation(tu.getFilePath(), offset, length); + return tu.getNodeSelector(null).findNode(offset, length); } /** diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMLocationMacroTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMLocationMacroTests.java index 14c844e862c..401fea7a0fb 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMLocationMacroTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMLocationMacroTests.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 @@ -18,12 +18,13 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression; -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.IASTNodeLocation; import org.eclipse.cdt.core.dom.ast.IASTPointer; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorFunctionStyleMacroDefinition; 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.IASTPreprocessorUndefStatement; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier; @@ -57,12 +58,12 @@ public class DOMLocationMacroTests extends AST2BaseTest { assertEquals( d.getName().toString(), "D"); //$NON-NLS-1$ IASTNodeLocation [] declaratorLocations = d.getNodeLocations(); assertEquals( declaratorLocations.length, 1 ); - IASTMacroExpansion expansion = (IASTMacroExpansion) declaratorLocations[0]; - IASTPreprocessorObjectStyleMacroDefinition fromExpansion = (IASTPreprocessorObjectStyleMacroDefinition) expansion.getMacroDefinition(); + IASTMacroExpansionLocation expansion = (IASTMacroExpansionLocation) declaratorLocations[0]; + IASTPreprocessorObjectStyleMacroDefinition fromExpansion = (IASTPreprocessorObjectStyleMacroDefinition) expansion.getExpansion().getMacroDefinition(); assertEqualsMacros( fromExpansion, ABC ); assertEquals( expansion.getNodeOffset(), 0 ); assertEquals( expansion.getNodeLength(), 1 ); - IASTNodeLocation [] macroLocation = expansion.getExpansionLocations(); + IASTNodeLocation [] macroLocation = expansion.getExpansion().getNodeLocations(); assertEquals( macroLocation.length, 1 ); assertTrue( macroLocation[0] instanceof IASTFileLocation ); assertEquals( macroLocation[0].getNodeOffset(), code.indexOf( "int ABC;") + "int ".length() ); //$NON-NLS-1$ //$NON-NLS-2$ @@ -84,12 +85,12 @@ public class DOMLocationMacroTests extends AST2BaseTest { assertEquals( d.getPointerOperators().length, 1 ); IASTNodeLocation [] declaratorLocations = d.getNodeLocations(); assertEquals( declaratorLocations.length, 1 ); - IASTMacroExpansion expansion = (IASTMacroExpansion) declaratorLocations[0]; - IASTPreprocessorObjectStyleMacroDefinition fromExpansion = (IASTPreprocessorObjectStyleMacroDefinition) expansion.getMacroDefinition(); + IASTMacroExpansionLocation expansion = (IASTMacroExpansionLocation) declaratorLocations[0]; + IASTPreprocessorObjectStyleMacroDefinition fromExpansion = (IASTPreprocessorObjectStyleMacroDefinition) expansion.getExpansion().getMacroDefinition(); assertEqualsMacros( fromExpansion, ABC ); assertEquals( expansion.getNodeOffset(), 0 ); assertEquals( 2, expansion.getNodeLength() ); - IASTNodeLocation [] macroLocation = expansion.getExpansionLocations(); + IASTNodeLocation [] macroLocation = expansion.getExpansion().getNodeLocations(); assertEquals( macroLocation.length, 1 ); assertTrue( macroLocation[0] instanceof IASTFileLocation ); assertEquals( macroLocation[0].getNodeOffset(), code.indexOf( "int ABC;") + "int ".length() ); //$NON-NLS-1$ //$NON-NLS-2$ @@ -98,22 +99,22 @@ public class DOMLocationMacroTests extends AST2BaseTest { IASTName n = d.getName(); IASTNodeLocation [] nameLocations = n.getNodeLocations(); assertEquals( nameLocations.length, 1 ); - final IASTMacroExpansion nodeLocation = (IASTMacroExpansion) nameLocations[0]; + final IASTMacroExpansionLocation nodeLocation = (IASTMacroExpansionLocation) nameLocations[0]; assertEquals( nodeLocation.getNodeOffset(), 1 ); assertEquals( nodeLocation.getNodeLength(), 1 ); - assertEquals( nodeLocation.getExpansionLocations()[0].getNodeOffset(), macroLocation[0].getNodeOffset() ); - assertEquals( nodeLocation.getExpansionLocations()[0].getNodeLength(), macroLocation[0].getNodeLength() ); + assertEquals( nodeLocation.getExpansion().getNodeLocations()[0].getNodeOffset(), macroLocation[0].getNodeOffset() ); + assertEquals( nodeLocation.getExpansion().getNodeLocations()[0].getNodeLength(), macroLocation[0].getNodeLength() ); IASTPointer po = (IASTPointer) d.getPointerOperators()[0]; assertFalse( po.isConst() ); assertFalse( po.isVolatile() ); - IASTMacroExpansion pointerLocation = (IASTMacroExpansion) po.getNodeLocations()[0]; + IASTMacroExpansionLocation pointerLocation = (IASTMacroExpansionLocation) po.getNodeLocations()[0]; assertEquals( pointerLocation.getNodeOffset(), 0 ); assertEquals( pointerLocation.getNodeLength(), 1 ); - assertEquals( pointerLocation.getExpansionLocations()[0].getNodeOffset(), macroLocation[0].getNodeOffset() ); - assertEquals( pointerLocation.getExpansionLocations()[0].getNodeLength(), macroLocation[0].getNodeLength() ); - assertEqualsMacros( pointerLocation.getMacroDefinition(), nodeLocation.getMacroDefinition() ); + assertEquals( pointerLocation.getExpansion().getNodeLocations()[0].getNodeOffset(), macroLocation[0].getNodeOffset() ); + assertEquals( pointerLocation.getExpansion().getNodeLocations()[0].getNodeLength(), macroLocation[0].getNodeLength() ); + assertEqualsMacros( pointerLocation.getExpansion().getMacroDefinition(), nodeLocation.getExpansion().getMacroDefinition() ); } } @@ -129,11 +130,11 @@ public class DOMLocationMacroTests extends AST2BaseTest { IASTSimpleDeclSpecifier declSpec = (IASTSimpleDeclSpecifier) var.getDeclSpecifier(); IASTNodeLocation [] declSpecLocations = declSpec.getNodeLocations(); assertEquals( declSpecLocations.length, 2 ); - IASTMacroExpansion expansion = (IASTMacroExpansion) declSpecLocations[0]; - assertEqualsMacros( defXYZ, expansion.getMacroDefinition() ); + IASTMacroExpansionLocation expansion = (IASTMacroExpansionLocation) declSpecLocations[0]; + assertEqualsMacros( defXYZ, expansion.getExpansion().getMacroDefinition() ); assertEquals( expansion.getNodeOffset(), 0 ); assertEquals( expansion.getNodeLength(), 1 ); - IASTNodeLocation [] expansionLocations = expansion.getExpansionLocations(); + IASTNodeLocation [] expansionLocations = expansion.getExpansion().getNodeLocations(); assertEquals( expansionLocations.length, 1 ); assertTrue( expansionLocations[0] instanceof IASTFileLocation ); assertEquals( expansionLocations[0].getNodeOffset(), code.indexOf( "XYZ int")); //$NON-NLS-1$ @@ -165,8 +166,8 @@ public class DOMLocationMacroTests extends AST2BaseTest { IASTFileLocation start_loc = (IASTFileLocation) locations[0]; assertEquals( start_loc.getNodeOffset(), code.indexOf( "int") ); //$NON-NLS-1$ assertEquals( start_loc.getNodeLength(), "int ".length()); //$NON-NLS-1$ - IASTMacroExpansion mac_loc = (IASTMacroExpansion) locations[1]; - final IASTPreprocessorMacroDefinition C_PO2 = mac_loc.getMacroDefinition(); + IASTMacroExpansionLocation mac_loc = (IASTMacroExpansionLocation) locations[1]; + final IASTPreprocessorMacroDefinition C_PO2 = mac_loc.getExpansion().getMacroDefinition(); assertEqualsMacros( C_PO, C_PO2 ); assertEquals( 0, mac_loc.getNodeOffset()); assertEquals( 2, mac_loc.getNodeLength() ); @@ -198,24 +199,24 @@ public class DOMLocationMacroTests extends AST2BaseTest { final IASTNodeLocation[] nodeLocations = var.getNodeLocations(); assertEquals( 10, nodeLocations.length ); - IASTMacroExpansion first_loc = (IASTMacroExpansion) nodeLocations[0]; - assertEqualsMacros( first_loc.getMacroDefinition(), XYZ ); + IASTMacroExpansionLocation first_loc = (IASTMacroExpansionLocation) nodeLocations[0]; + assertEqualsMacros( first_loc.getExpansion().getMacroDefinition(), XYZ ); IASTFileLocation second_loc = (IASTFileLocation) nodeLocations[1]; assertEquals( 1, second_loc.getNodeLength() ); - IASTMacroExpansion third_loc = (IASTMacroExpansion) nodeLocations[2]; - assertEqualsMacros( third_loc.getMacroDefinition(), IT ); + IASTMacroExpansionLocation third_loc = (IASTMacroExpansionLocation) nodeLocations[2]; + assertEqualsMacros( third_loc.getExpansion().getMacroDefinition(), IT ); IASTFileLocation fourth_loc = (IASTFileLocation) nodeLocations[3]; assertEquals( 1, fourth_loc.getNodeLength() ); - IASTMacroExpansion fifth_loc = (IASTMacroExpansion) nodeLocations[4]; - assertEqualsMacros( fifth_loc.getMacroDefinition(), C_PO ); + IASTMacroExpansionLocation fifth_loc = (IASTMacroExpansionLocation) nodeLocations[4]; + assertEqualsMacros( fifth_loc.getExpansion().getMacroDefinition(), C_PO ); IASTFileLocation sixth_loc = (IASTFileLocation) nodeLocations[5]; assertEquals( 1, sixth_loc.getNodeLength() ); - IASTMacroExpansion seventh_loc = (IASTMacroExpansion) nodeLocations[6]; - assertEqualsMacros( seventh_loc.getMacroDefinition(), C_PO ); + IASTMacroExpansionLocation seventh_loc = (IASTMacroExpansionLocation) nodeLocations[6]; + assertEqualsMacros( seventh_loc.getExpansion().getMacroDefinition(), C_PO ); IASTFileLocation eighth_loc = (IASTFileLocation) nodeLocations[7]; assertEquals( 1, eighth_loc.getNodeLength() ); - IASTMacroExpansion ninth_loc = (IASTMacroExpansion) nodeLocations[8]; - assertEqualsMacros( ninth_loc.getMacroDefinition(), V ); + IASTMacroExpansionLocation ninth_loc = (IASTMacroExpansionLocation) nodeLocations[8]; + assertEqualsMacros( ninth_loc.getExpansion().getMacroDefinition(), V ); IASTFileLocation tenth_loc = (IASTFileLocation) nodeLocations[9]; assertEquals( 1, tenth_loc.getNodeLength() ); @@ -244,13 +245,13 @@ public class DOMLocationMacroTests extends AST2BaseTest { IASTSimpleDeclaration memchr = (IASTSimpleDeclaration) tu.getDeclarations()[0]; IASTNodeLocation [] locations = memchr.getNodeLocations(); assertEquals( locations.length, 4 ); - IASTMacroExpansion loc_1 = (IASTMacroExpansion) locations[0]; - assertEqualsMacros( _PTR, loc_1.getMacroDefinition() ); + IASTMacroExpansionLocation loc_1 = (IASTMacroExpansionLocation) locations[0]; + assertEqualsMacros( _PTR, loc_1.getExpansion().getMacroDefinition() ); IASTFileLocation loc_2 = (IASTFileLocation) locations[1]; assertEquals( loc_2.getNodeOffset(), code.indexOf( " _EXFUN(")); //$NON-NLS-1$ assertEquals( loc_2.getNodeLength(), " ".length() ); //$NON-NLS-1$ - IASTMacroExpansion loc_3 = (IASTMacroExpansion) locations[2]; - assertEqualsMacros( _EXFUN, loc_3.getMacroDefinition() ); + IASTMacroExpansionLocation loc_3 = (IASTMacroExpansionLocation) locations[2]; + assertEqualsMacros( _EXFUN, loc_3.getExpansion().getMacroDefinition() ); IASTFileLocation loc_4 = (IASTFileLocation) locations[3]; assertEquals( loc_4.getNodeOffset(), code.indexOf( ";")); //$NON-NLS-1$ assertEquals( loc_4.getNodeLength(), 1 ); @@ -292,8 +293,8 @@ public class DOMLocationMacroTests extends AST2BaseTest { IASTName [] firstReferences = tu.getReferences( binding1 ); IASTName [] firstDeclarations = tu.getDeclarationsInAST( binding1 ); assertEquals( firstReferences.length, 2 ); - assertEquals( firstReferences[0].getPropertyInParent(), IASTTranslationUnit.EXPANSION_NAME ); - assertEquals( firstReferences[0].getParent(), tu ); + assertEquals( firstReferences[0].getPropertyInParent(), IASTPreprocessorMacroExpansion.EXPANSION_NAME ); + assertEquals( firstReferences[0].getParent().getParent(), tu ); assertEquals( firstReferences[1].getPropertyInParent(), IASTPreprocessorUndefStatement.MACRO_NAME ); assertTrue( firstReferences[1].getParent() instanceof IASTPreprocessorUndefStatement ); assertEquals( firstDeclarations.length, 1 ); @@ -301,10 +302,9 @@ public class DOMLocationMacroTests extends AST2BaseTest { IASTName [] secondReferences = tu.getReferences(binding2); IASTName [] secondDeclarations = tu.getDeclarationsInAST( binding2 ); assertEquals( 1, secondReferences.length ); - assertEquals( secondReferences[0].getPropertyInParent(), IASTTranslationUnit.EXPANSION_NAME ); - assertEquals( secondReferences[0].getParent(), tu ); + assertEquals( secondReferences[0].getPropertyInParent(), IASTPreprocessorMacroExpansion.EXPANSION_NAME ); + assertEquals( secondReferences[0].getParent().getParent(), tu ); assertSame( ABC2.getName(), secondDeclarations[0]); - } } @@ -357,8 +357,8 @@ public class DOMLocationMacroTests extends AST2BaseTest { assertNotNull(expr.getFileLocation()); IASTNodeLocation [] locations = expr.getNodeLocations(); assertEquals(1, locations.length); - IASTMacroExpansion macroExpansion = (IASTMacroExpansion) locations[0]; - IASTNodeLocation[] expLocations= macroExpansion.getExpansionLocations(); + IASTMacroExpansionLocation macroExpansion = (IASTMacroExpansionLocation) locations[0]; + IASTNodeLocation[] expLocations= macroExpansion.getExpansion().getNodeLocations(); assertEquals(1, expLocations.length); assertEquals(code.indexOf("FUNCTION(1)"), expLocations[0].getNodeOffset()); assertEquals("FUNCTION(1)".length(), expLocations[0].getNodeLength()); @@ -373,8 +373,8 @@ public class DOMLocationMacroTests extends AST2BaseTest { assertNotNull(expr.getFileLocation()); IASTNodeLocation [] locations = expr.getNodeLocations(); assertEquals(1, locations.length); - IASTMacroExpansion macroExpansion = (IASTMacroExpansion) locations[0]; - IASTNodeLocation[] expLocations= macroExpansion.getExpansionLocations(); + IASTMacroExpansionLocation macroExpansion = (IASTMacroExpansionLocation) locations[0]; + IASTNodeLocation[] expLocations= macroExpansion.getExpansion().getNodeLocations(); assertEquals(1, expLocations.length); IASTFileLocation fileLocation = expLocations[0].asFileLocation(); assertEquals(index, fileLocation.getNodeOffset()); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMSelectionParseBaseTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMSelectionParseBaseTest.java index 24b98f8f62e..a54b623bec7 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMSelectionParseBaseTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMSelectionParseBaseTest.java @@ -1,13 +1,13 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. + * Copyright (c) 2005, 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 * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * IBM Rational Software - Initial API and implementation - * Markus Schorn (Wind River Systems) + * IBM Rational Software - Initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.core.parser.tests.ast2; @@ -48,17 +48,12 @@ public class DOMSelectionParseBaseTest extends DOMFileBasePluginTest { protected IASTNode parse(IFile file, int offset1, int offset2, boolean expectedToPass) throws Exception { ITranslationUnit tu = (ITranslationUnit)CCorePlugin.getDefault().getCoreModel().create(file); IASTTranslationUnit ast = tu.getAST(); - IASTName[] names = tu.getLanguage().getSelectedNames(ast, offset1, offset2 - offset1); - + IASTName name= ast.getNodeSelector(null).findName(offset1, offset2 - offset1); + if (!expectedToPass) return null; - if (names.length == 0) { - assertFalse(true); - } else { - return names[0]; - } - - return null; + assertNotNull(name); + return name; } protected IName[] getDeclarationOffTU(IASTName name) { diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/LocationMapTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/LocationMapTests.java index d041523c32f..4a43f8cec18 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/LocationMapTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/LocationMapTests.java @@ -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.IASTPreprocessorPragmaStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorUndefStatement; @@ -471,15 +472,15 @@ public class LocationMapTests extends BaseTestCase { IASTName[] refs= fLocationMap.getReferences(macro3); assertEquals(1, refs.length); IASTName macro3ref= refs[0]; - checkName(refs[0], macro3, "n3", fTu, IASTTranslationUnit.EXPANSION_NAME, ROLE_REFERENCE, FN, 110, 5, 2, 2, new String(LONGDIGITS, 110, 5)); + checkName(refs[0], macro3, "n3", refs[0].getParent(), IASTPreprocessorMacroExpansion.EXPANSION_NAME, ROLE_REFERENCE, FN, 110, 5, 2, 2, new String(LONGDIGITS, 110, 5)); refs= fLocationMap.getReferences(macro1); assertEquals(1, refs.length); - checkName(refs[0], macro1, "n1", macro3ref, IASTTranslationUnit.EXPANSION_NAME, ROLE_REFERENCE, FN, 110, 15, 2, 2, new String(LONGDIGITS, 110, 15)); + checkName(refs[0], macro1, "n1", refs[0].getParent(), IASTPreprocessorMacroExpansion.EXPANSION_NAME, ROLE_REFERENCE, FN, 110, 15, 2, 2, new String(LONGDIGITS, 110, 15)); refs= fLocationMap.getReferences(macro2); assertEquals(1, refs.length); - checkName(refs[0], macro2, "n2", macro3ref, IASTTranslationUnit.EXPANSION_NAME, ROLE_REFERENCE, FN, 110, 15, 2, 2, new String(LONGDIGITS, 110, 15)); + checkName(refs[0], macro2, "n2", refs[0].getParent(), IASTPreprocessorMacroExpansion.EXPANSION_NAME, ROLE_REFERENCE, FN, 110, 15, 2, 2, new String(LONGDIGITS, 110, 15)); } public void testContexts() { diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBindingResolutionTestBase.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBindingResolutionTestBase.java index 7f7240bb309..1875fba33e3 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBindingResolutionTestBase.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBindingResolutionTestBase.java @@ -1,21 +1,18 @@ /******************************************************************************* - * Copyright (c) 2006, 2007 Symbian Software Systems and others. + * Copyright (c) 2006, 2008 Symbian Software Systems 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: - * Andrew Ferguson (Symbian) - Initial implementation - * IBM Corporation + * Andrew Ferguson (Symbian) - Initial implementation + * IBM Corporation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.index.tests; import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.ListIterator; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.IPDOMManager; @@ -32,11 +29,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexManager; -import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.ICProject; -import org.eclipse.cdt.core.model.ILanguage; -import org.eclipse.cdt.core.model.LanguageManager; -import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.testplugin.CProjectHelper; import org.eclipse.cdt.core.testplugin.CTestPlugin; import org.eclipse.cdt.core.testplugin.TestScannerProvider; @@ -74,30 +67,21 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase { this.strategy = strategy; } + @Override protected void setUp() throws Exception { super.setUp(); strategy.setUp(); } + @Override protected void tearDown() throws Exception { strategy.tearDown(); super.tearDown(); } - protected IASTName[] findNames(String section, int len) { - // get the language from the language manager - ILanguage language = null; + protected IASTName findName(String section, int len) { IASTTranslationUnit ast = strategy.getAst(); - try { - IProject project = strategy.getCProject().getProject(); - ICConfigurationDescription configuration = CoreModel.getDefault().getProjectDescription(project, false).getActiveConfiguration(); - language = LanguageManager.getInstance().getLanguageForFile(ast.getFilePath(), project, configuration); - } catch (CoreException e) { - fail("Unexpected exception while getting language for file."); - } - - assertNotNull("No language for file " + ast.getFilePath().toString(), language); - return language.getSelectedNames(ast, strategy.getTestData()[1].indexOf(section), len); + return ast.getNodeSelector(null).findName(strategy.getTestData()[1].indexOf(section), len); } /** @@ -113,21 +97,14 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase { * @return the associated name's binding */ protected IBinding getBindingFromASTName(String section, int len) { - IASTName[] names= findNames(section, len); - List lnames= new ArrayList(Arrays.asList(names)); - for(ListIterator li= lnames.listIterator(); li.hasNext(); ) { - IASTName name= (IASTName) li.next(); - if(name.getRawSignature().length()!=len) { - li.remove(); - } - } - names= (IASTName[]) lnames.toArray(new IASTName[lnames.size()]); - assertEquals("<>1 name found for \""+section+"\"", 1, names.length); + IASTName name= findName(section, len); + assertNotNull("name not found for \""+section+"\"", name); + assertEquals(section.substring(0, len), name.getRawSignature()); - IBinding binding = names[0].resolveBinding(); - assertNotNull("No binding for "+names[0].getRawSignature(), binding); - assertFalse("Binding is a ProblemBinding for name "+names[0].getRawSignature(), IProblemBinding.class.isAssignableFrom(names[0].resolveBinding().getClass())); - return names[0].resolveBinding(); + IBinding binding = name.resolveBinding(); + assertNotNull("No binding for "+name.getRawSignature(), binding); + assertFalse("Binding is a ProblemBinding for name "+name.getRawSignature(), IProblemBinding.class.isAssignableFrom(name.resolveBinding().getClass())); + return name.resolveBinding(); } /** @@ -137,13 +114,14 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase { * @return the associated name's binding */ protected IBinding getProblemFromASTName(String section, int len) { - IASTName[] names= findNames(section, len); - assertEquals("<>1 name found for \""+section+"\"", 1, names.length); + IASTName name= findName(section, len); + assertNotNull("name not found for \""+section+"\"", name); + assertEquals(section.substring(0, len), name.getRawSignature()); - IBinding binding = names[0].resolveBinding(); - assertNotNull("No binding for "+names[0].getRawSignature(), binding); - assertTrue("Binding is not a ProblemBinding for name "+names[0].getRawSignature(), IProblemBinding.class.isAssignableFrom(names[0].resolveBinding().getClass())); - return names[0].resolveBinding(); + IBinding binding = name.resolveBinding(); + assertNotNull("No binding for "+name.getRawSignature(), binding); + assertTrue("Binding is not a ProblemBinding for name "+name.getRawSignature(), IProblemBinding.class.isAssignableFrom(name.resolveBinding().getClass())); + return name.resolveBinding(); } protected static void assertQNEquals(String expectedQN, IBinding b) { diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java index 914eb4be4bb..6bb116616ac 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java @@ -232,7 +232,7 @@ public class IndexBugsTests extends BaseTestCase { // make sure the ast is correct ITranslationUnit tu= (ITranslationUnit) fCProject.findElement(new Path(fileName)); IASTTranslationUnit ast= tu.getAST(); - IASTName name= (IASTName) ast.selectNodeForLocation(tu.getLocation().toString(), indexOfDecl, funcName.length()); + IASTName name= (IASTName) ast.getNodeSelector(null).findNode(indexOfDecl, funcName.length()); IBinding astBinding= name.resolveBinding(); IName[] astDecls= ast.getDeclarations(astBinding); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionBugs.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionBugs.java index 70fe54991b6..66ed296ec7c 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionBugs.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionBugs.java @@ -234,7 +234,7 @@ public class IndexCPPBindingResolutionBugs extends IndexBindingResolutionTestBas // ns::A a; // class B {}; public void testBug188324() throws Exception { - IASTName name= findNames("B", 1)[0]; + IASTName name= findName("B", 1); IBinding b0= getBindingFromASTName("ns::A", 2); assertInstance(b0, ICPPNamespace.class); ICPPNamespace ns= (ICPPNamespace) b0; @@ -389,9 +389,9 @@ public class IndexCPPBindingResolutionBugs extends IndexBindingResolutionTestBas IBinding binding= getBindingFromASTName("Y {", 1); assertTrue(binding instanceof ICPPNamespace); ICPPNamespace adapted= (ICPPNamespace) strategy.getIndex().adaptBinding(binding); - IASTName[] names= findNames("Ambiguity problem", 9); - assertEquals(1, names.length); - IBinding binding2= adapted.getNamespaceScope().getBinding(names[0], true); + IASTName name= findName("Ambiguity problem", 9); + assertNotNull(name); + IBinding binding2= adapted.getNamespaceScope().getBinding(name, true); } // namespace X {int i;} diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ILanguage.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ILanguage.java index 3d7c49cdbd4..30f86e68acf 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ILanguage.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ILanguage.java @@ -95,13 +95,9 @@ public interface ILanguage extends IAdaptable { /** * Gather the list of IASTNames that appear the selection with the given start offset * and length in the given ITranslationUnit. - * - * @param tu - * @param start - * @param length - * @param style - * @return + * @deprecated use {@link IASTTranslationUnit#getNodeSelector(String)}, instead. */ + @Deprecated public IASTName[] getSelectedNames(IASTTranslationUnit ast, int start, int length); /** 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 null if there is no such node. + */ + IASTName findName(int offset, int length); + + /** + * Returns the smallest name surrounding the given range, or null if there is no such node. + */ + IASTName findSurroundingName(int offset, int length); + + /** + * Returns the first name contained in the given range, or null if there is no such node. + */ + IASTName findFirstContainedName(int offset, int length); + + /** + * Returns the node for the exact given range, or null if there is no such node. + */ + IASTNode findNode(int offset, int length); + + /** + * Returns the smallest node surrounding the given range, or null if there is no such node. + */ + IASTNode findSurroundingNode(int offset, int length); + + /** + * Returns the first node contained in the given range, or null 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 null 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 IASTNode that best fits + * @deprecated use {@link #getNodeSelector(String)}, instead. */ + @Deprecated public IASTNode selectNodeForLocation(String path, int offset, int length); /** @@ -157,6 +165,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 IASTProblem[] @@ -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 -1 if this file * is not part of the translation-unit. * @param filePath a file path or null 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 -1. */ int getSequenceNumberForFileOffset(String filePath, int fileOffset); @@ -139,8 +139,12 @@ public interface ILocationResolver { * Returns a preprocessor node surrounding the given range, or null. 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 result) { + public void collectMacroExpansions(int offset, int length, ArrayList list) { Collection 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 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 list= new ArrayList(); + ArrayList list= new ArrayList(); - 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 result= new ArrayList(); 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 refs= new ArrayList(); 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) { diff --git a/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/ShowInDOMViewAction.java b/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/ShowInDOMViewAction.java index 72936f09539..403442511f1 100644 --- a/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/ShowInDOMViewAction.java +++ b/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/ShowInDOMViewAction.java @@ -1,13 +1,13 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. + * Copyright (c) 2005, 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 * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * IBM Rational Software - Initial API and implementation - * Anton Leherbauer (Wind River Systems) + * IBM Rational Software - Initial API and implementation + * Anton Leherbauer (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.ui.tests.DOMAST; @@ -180,7 +180,7 @@ public class ShowInDOMViewAction extends ActionDelegate implements // the selection is within a file currently shown in the DOM AST View if (tu != null && file != null && view instanceof DOMAST) { - IASTNode node = tu.selectNodeForLocation(file, offset, length); + IASTNode node = tu.getNodeSelector(file).findNode(offset, length); if (node != null && ((DOMAST)view).getContentProvider() instanceof DOMAST.ViewContentProvider) { boolean success = ((DOMAST.ViewContentProvider)((DOMAST)view).getContentProvider()).findAndSelect(node, true); // use offsets when searching for node equality if( ! success ) diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/HyperlinkTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/HyperlinkTest.java index 551153337d5..5ebadb7b674 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/HyperlinkTest.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/HyperlinkTest.java @@ -122,6 +122,7 @@ public class HyperlinkTest extends TestCase { assertHyperlink(CPP_CODE.indexOf("#include") + 2, 0, "#include ".length()); assertHyperlink(CPP_CODE.indexOf("") + 2, 0, "#include ".length()); + assertHyperlink(CPP_CODE.indexOf("") + "".length()); // hovering over the whitspace inside an include still results in a hyperlink assertHyperlink(CPP_CODE.indexOf("") - 1, 0, "#include ".length()); diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/BaseSelectionTestsIndexer.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/BaseSelectionTestsIndexer.java index af9d0e082fb..d17454d6f25 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/BaseSelectionTestsIndexer.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/BaseSelectionTestsIndexer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. + * Copyright (c) 2005, 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 @@ -220,10 +220,7 @@ public class BaseSelectionTestsIndexer extends BaseUITestCase { ITranslationUnit tu = (ITranslationUnit)CoreModel.getDefault().create(file); IStatus ok= ASTProvider.getASTProvider().runOnAST(tu, ASTProvider.WAIT_YES, monitor, new ASTRunnable() { public IStatus runOnAST(ILanguage language, IASTTranslationUnit ast) throws CoreException { - IASTName[] names = language.getSelectedNames(ast, textSel.getOffset(), textSel.getLength()); - if (names != null && names.length > 0) - result[0]= names[0]; - + result[0]= ast.getNodeSelector(null).findName(textSel.getOffset(), textSel.getLength()); return Status.OK_STATUS; } }); diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CPPSelectionTestsAnyIndexer.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CPPSelectionTestsAnyIndexer.java index 12b7445dbf4..7d6ea99fa42 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CPPSelectionTestsAnyIndexer.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CPPSelectionTestsAnyIndexer.java @@ -111,7 +111,7 @@ public abstract class CPPSelectionTestsAnyIndexer extends BaseSelectionTestsInde // (2); // return (0); // } - public void _testBug93281() throws Exception { + public void testBug93281() throws Exception { StringBuffer[] buffers= getContents(2); String hcode= buffers[0].toString(); String scode= buffers[1].toString(); diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CPPSelectionTestsNoIndexer.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CPPSelectionTestsNoIndexer.java index 245a43909e4..54614ad3eb5 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CPPSelectionTestsNoIndexer.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CPPSelectionTestsNoIndexer.java @@ -265,10 +265,7 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase { ITranslationUnit tu= CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(editor.getEditorInput()); IStatus ok= ASTProvider.getASTProvider().runOnAST(tu, ASTProvider.WAIT_YES, monitor, new ASTRunnable() { public IStatus runOnAST(ILanguage language, IASTTranslationUnit ast) throws CoreException { - IASTName[] names = language.getSelectedNames(ast, textSel.getOffset(), textSel.getLength()); - if (names != null && names.length > 0) - result[0]= names[0]; - + result[0]= ast.getNodeSelector(null).findName(textSel.getOffset(), textSel.getLength()); return Status.OK_STATUS; } }); @@ -280,7 +277,7 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase { return null; } - public void _testBug93281() throws Exception { + public void testBug93281() throws Exception { StringBuffer buffer = new StringBuffer(); buffer.append("class Point{ \n"); //$NON-NLS-1$ buffer.append("public: \n"); //$NON-NLS-1$ @@ -900,7 +897,7 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase { assertEquals(((ASTNode)decl).getLength(), 1); } - public void _testBug95229() throws Exception { + public void testBug95229() throws Exception { StringBuffer buffer = new StringBuffer(); buffer.append("struct A {\n"); //$NON-NLS-1$ buffer.append("operator short(); // F3 on operator causes an infinite loop\n"); //$NON-NLS-1$ diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CSelectionTestsNoIndexer.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CSelectionTestsNoIndexer.java index a08bdf1b6ae..8a6a92f345b 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CSelectionTestsNoIndexer.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CSelectionTestsNoIndexer.java @@ -287,10 +287,7 @@ public class CSelectionTestsNoIndexer extends BaseUITestCase { ITranslationUnit tu = (ITranslationUnit)CoreModel.getDefault().create(file); IStatus ok= ASTProvider.getASTProvider().runOnAST(tu, ASTProvider.WAIT_YES, monitor, new ASTRunnable() { public IStatus runOnAST(ILanguage language, IASTTranslationUnit ast) throws CoreException { - IASTName[] names = language.getSelectedNames(ast, textSel.getOffset(), textSel.getLength()); - if (names != null && names.length > 0) - result[0]= names[0]; - + result[0]= ast.getNodeSelector(null).findName(textSel.getOffset(), textSel.getLength()); return Status.OK_STATUS; } }); diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/ResolveBindingTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/ResolveBindingTests.java index eb7b2c646a0..acac50cd312 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/ResolveBindingTests.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/ResolveBindingTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2007 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 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 @@ -76,9 +76,9 @@ public class ResolveBindingTests extends BaseUITestCase { assertNotNull("No language for file " + astTU.getFilePath().toString(), language); - IASTName[] names= language.getSelectedNames(astTU, offset, len); - assertEquals(1, names.length); - return names[0]; + IASTName name= astTU.getNodeSelector(null).findName(offset, len); + assertNotNull(name); + return name; } private void checkBinding(IASTName name, Class clazz) { diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CElementHyperlinkDetector.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CElementHyperlinkDetector.java index 42330aad915..c9ae76a3599 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CElementHyperlinkDetector.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CElementHyperlinkDetector.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2007 QNX Software Systems and others. + * Copyright (c) 2000, 2008 QNX Software Systems 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 @@ -18,7 +18,6 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.action.IAction; import org.eclipse.jface.text.IRegion; -import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.ITextViewer; import org.eclipse.jface.text.Region; import org.eclipse.jface.text.hyperlink.IHyperlink; @@ -28,8 +27,9 @@ import org.eclipse.ui.texteditor.ITextEditor; import org.eclipse.cdt.core.CCorePlugin; 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.IASTNodeSelector; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement; -import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexManager; @@ -39,8 +39,6 @@ import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable; -import org.eclipse.cdt.internal.ui.search.actions.OpenDeclarationsAction; - public class CElementHyperlinkDetector implements IHyperlinkDetector { private ITextEditor fTextEditor; @@ -50,23 +48,15 @@ public class CElementHyperlinkDetector implements IHyperlinkDetector { } - public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) { - if (region == null || canShowMultipleHyperlinks || !(fTextEditor instanceof CEditor)) + public IHyperlink[] detectHyperlinks(ITextViewer textViewer, final IRegion region, boolean canShowMultipleHyperlinks) { + if (region == null || canShowMultipleHyperlinks || fTextEditor == null) return null; - CEditor editor = (CEditor) fTextEditor; - int offset = region.getOffset(); - - final IAction openAction= editor.getAction("OpenDeclarations"); //$NON-NLS-1$ + final IAction openAction= fTextEditor.getAction("OpenDeclarations"); //$NON-NLS-1$ if (openAction == null) return null; - - // reuse the logic from Open Decl that recognizes a word in the editor - final ITextSelection selection = OpenDeclarationsAction.selectWord(offset, editor); - if(selection == null) - return null; - final IWorkingCopy workingCopy = CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(editor.getEditorInput()); + final IWorkingCopy workingCopy = CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(fTextEditor.getEditorInput()); if (workingCopy == null) { return null; } @@ -90,28 +80,31 @@ public class CElementHyperlinkDetector implements IHyperlinkDetector { IStatus status= ASTProvider.getASTProvider().runOnAST(workingCopy, ASTProvider.WAIT_YES, null, new ASTRunnable() { public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) { if (ast != null) { - IASTName[] selectedNames= - lang.getSelectedNames(ast, selection.getOffset(), selection.getLength()); - - IRegion linkRegion= null; - if(selectedNames.length > 0 && selectedNames[0] != null) { // found a name + final int offset= region.getOffset(); + final int length= Math.max(1, region.getLength()); + final IASTNodeSelector nodeSelector= ast.getNodeSelector(null); + IASTName selectedName= nodeSelector.findSurroundingName(offset, length); + IASTFileLocation linkLocation= null; + if (selectedName != null) { // found a name // prefer include statement over the include name - if (selectedNames[0].getParent() instanceof IASTPreprocessorIncludeStatement) { - IASTFileLocation loc= selectedNames[0].getParent().getFileLocation(); - if (loc != null) { - linkRegion= new Region(loc.getNodeOffset(), loc.getNodeLength()); - } + if (selectedName.getParent() instanceof IASTPreprocessorIncludeStatement) { + linkLocation= selectedName.getParent().getFileLocation(); } - if (linkRegion == null) { - linkRegion = new Region(selection.getOffset(), selection.getLength()); + else { + linkLocation= selectedName.getFileLocation(); } } else { - linkRegion = matchIncludeStatement(ast, selection); + // search for include statement + final IASTNode cand= nodeSelector.findSurroundingNode(offset, length); + if (cand instanceof IASTPreprocessorIncludeStatement) { + linkLocation= cand.getFileLocation(); + } + } + if (linkLocation != null) { + result[0]= new CElementHyperlink( + new Region(linkLocation.getNodeOffset(), linkLocation.getNodeLength()), openAction); } - - if(linkRegion != null) - result[0]= new CElementHyperlink(linkRegion, openAction); } return Status.OK_STATUS; } @@ -125,29 +118,4 @@ public class CElementHyperlinkDetector implements IHyperlinkDetector { return result[0] == null ? null : result; } - - - /** - * Returns the region that represents an include directive if one is found - * that matches the selection, null otherwise. - */ - private IRegion matchIncludeStatement(IASTTranslationUnit ast, ITextSelection selection) { - IASTPreprocessorStatement[] preprocs = ast.getAllPreprocessorStatements(); - for (int i = 0; i < preprocs.length; ++i) { - - if (!(preprocs[i] instanceof IASTPreprocessorIncludeStatement)) - continue; - - IASTFileLocation loc = preprocs[i].getFileLocation(); - if (loc != null - && loc.getFileName().equals(ast.getFilePath()) - && loc.getNodeOffset() < selection.getOffset() - && loc.getNodeOffset() + loc.getNodeLength() > selection.getOffset()) { - - return new Region(loc.getNodeOffset(), loc.getNodeLength()); - } - } - return null; - } - } 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 651d06982a2..bdb33e94e38 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 @@ -43,6 +43,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition; +import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion; import org.eclipse.cdt.core.dom.ast.IASTProblem; import org.eclipse.cdt.core.dom.ast.IASTStatement; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; @@ -359,6 +360,9 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener { macroLength= macroDef.getName().toCharArray().length; } IASTNode macroNode= node.getTranslationUnit().selectNodeForLocation(fFilePath, useOffset, macroLength); + if (macroNode instanceof IASTPreprocessorMacroExpansion) { + macroNode= ((IASTPreprocessorMacroExpansion) macroNode).getMacroReference(); + } if (macroNode != null && visitMacro(macroNode, macroLength)) { fMinLocation= useOffset + macroLength; } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchTextSelectionQuery.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchTextSelectionQuery.java index 878d41b818f..f67ef8ea9d0 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchTextSelectionQuery.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchTextSelectionQuery.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2007 QNX Software Systems and others. + * Copyright (c) 2006, 2008 QNX Software Systems 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 @@ -9,7 +9,6 @@ * QNX - Initial API and implementation * Markus Schorn (Wind River Systems) *******************************************************************************/ - package org.eclipse.cdt.internal.ui.search; import org.eclipse.core.runtime.CoreException; @@ -31,8 +30,7 @@ import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable; import org.eclipse.cdt.internal.ui.editor.ASTProvider; /** - * @author Doug Schaefer - * + * Query for searching the index based on a text selection. */ public class PDOMSearchTextSelectionQuery extends PDOMSearchQuery { @@ -45,17 +43,16 @@ public class PDOMSearchTextSelectionQuery extends PDOMSearchQuery { this.selection = selection; } + @Override protected IStatus runWithIndex(final IIndex index, IProgressMonitor monitor) { return ASTProvider.getASTProvider().runOnAST(tu, ASTProvider.WAIT_YES, monitor, new ASTRunnable() { public IStatus runOnAST(ILanguage language, IASTTranslationUnit ast) throws CoreException { if (ast != null) { - IASTName[] names = language.getSelectedNames(ast, selection.getOffset(), selection.getLength()); - if (names != null) { - for (int i = 0; i < names.length; ++i) { - IBinding binding = names[i].resolveBinding(); - if (binding != null) - createMatches(index, binding); - } + IASTName searchName= ast.getNodeSelector(null).findSurroundingName(selection.getOffset(), selection.getLength()); + if (searchName != null) { + IBinding binding = searchName.resolveBinding(); + if (binding != null) + createMatches(index, binding); } } return Status.OK_STATUS; @@ -63,6 +60,7 @@ public class PDOMSearchTextSelectionQuery extends PDOMSearchQuery { }); } + @Override public String getLabel() { return super.getLabel() + " " + selection.getText(); //$NON-NLS-1$ } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/FindAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/FindAction.java index 57183529c59..586fec7629e 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/FindAction.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/FindAction.java @@ -47,7 +47,7 @@ public abstract class FindAction extends SelectionParseAction { if (object instanceof ISourceReference) searchJob = createQuery((ISourceReference) object); } else if (selection instanceof ITextSelection) { - ITextSelection selNode = getSelection((ITextSelection)selection); + ITextSelection selNode = (ITextSelection)selection; ICElement element = fEditor.getInputCElement(); while (element != null && !(element instanceof ITranslationUnit)) element = element.getParent(); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsAction.java index 41dca325b79..c1ad3e09733 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsAction.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsAction.java @@ -130,11 +130,9 @@ public class OpenDeclarationsAction extends SelectionParseAction { int selectionStart = selNode.getOffset(); int selectionLength = selNode.getLength(); - IASTName[] selectedNames = lang.getSelectedNames(ast, selectionStart, selectionLength); - - if (selectedNames.length > 0 && selectedNames[0] != null) { // just right, only one name selected - boolean found = false; - IASTName searchName = selectedNames[0]; + IASTName searchName= ast.getNodeSelector(null).findSurroundingName(selectionStart, selectionLength); + if (searchName != null) { // just right, only one name selected + boolean found= false; final IASTNode parent = searchName.getParent(); if (parent instanceof IASTPreprocessorIncludeStatement) { openInclude(((IASTPreprocessorIncludeStatement) parent)); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/SelectionParseAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/SelectionParseAction.java index 6acbf7cfbcf..e6dd194a6ed 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/SelectionParseAction.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/SelectionParseAction.java @@ -20,19 +20,14 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jface.action.Action; -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITextSelection; -import org.eclipse.jface.text.TextSelection; import org.eclipse.jface.viewers.ISelection; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbenchSite; -import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.ui.texteditor.ITextEditor; import org.eclipse.cdt.core.dom.IName; import org.eclipse.cdt.core.dom.ast.IASTFileLocation; -import org.eclipse.cdt.core.parser.Keywords; import org.eclipse.cdt.internal.ui.editor.CEditor; import org.eclipse.cdt.internal.ui.search.CSearchMessages; @@ -73,104 +68,7 @@ public class SelectionParseAction extends Action { protected void clearStatusLine() { StatusLineHandler.clearStatusLine(fSite); } - - public ITextSelection getSelection( int fPos ) { - return selectWord(fPos, fEditor); - } - - - //TODO: Change this to work with qualified identifiers - public static ITextSelection selectWord(int fPos, ITextEditor editor) { - IDocumentProvider prov = ( editor != null ) ? editor.getDocumentProvider() : null; - IDocument doc = ( prov != null ) ? prov.getDocument(editor.getEditorInput()) : null; - - if( doc == null ) - return null; - - int pos= fPos; - char c; - int fStartPos =0, fEndPos=0; - int nonJavaStart=-1, nonJavaEnd=-1; - String selectedWord=null; - - try{ - while (pos >= 0) { - c= doc.getChar(pos); - - // TODO this logic needs to be improved - // ex: ~destr[cursor]uctors, p2->ope[cursor]rator=(zero), etc - if (nonJavaStart == -1 && !Character.isJavaIdentifierPart(c)) { - nonJavaStart=pos+1; - } - - if (Character.isWhitespace(c)) - break; - - --pos; - } - fStartPos= pos + 1; - - pos= fPos; - int length= doc.getLength(); - while (pos < length) { - c= doc.getChar(pos); - - if (nonJavaEnd == -1 && !Character.isJavaIdentifierPart(c)) { - nonJavaEnd=pos; - } - if (Character.isWhitespace(c)) - break; - ++pos; - } - fEndPos= pos; - selectedWord = doc.get(fStartPos, (fEndPos - fStartPos)); - } - catch(BadLocationException e){ - } - - // TODO Devin this only works for definitions of destructors right now - // if there is a destructor and the cursor is in the destructor name's segment then get the entire destructor - if (selectedWord != null && selectedWord.indexOf('~') >= 0 && fPos - 2 >= fStartPos + selectedWord.lastIndexOf(new String(Keywords.cpCOLONCOLON))) { - int tildePos = selectedWord.indexOf('~'); - int actualStart=fStartPos + tildePos; - int length=0; - char temp; - char[] lastSegment = selectedWord.substring(tildePos).toCharArray(); - for(int i=1; i= actualStart + length) { - return new TextSelection(doc, nonJavaStart, length); - } else { - return new TextSelection(doc, actualStart, length); - } - } else { - // otherwise use the non-java identifier parts as boundaries for the selection - return new TextSelection(doc, nonJavaStart, nonJavaEnd - nonJavaStart); - } - } - - /** - * Return the selected string from the editor - * @return The string currently selected, or null if there is no valid selection - */ - protected ITextSelection getSelection( ITextSelection textSelection ) { - if( textSelection == null ) - return null; - - if (textSelection.getLength() == 0) { - return getSelection(textSelection.getOffset()); - } else { - return textSelection; - } - } - + protected ISelection getSelection() { ISelection sel = null; if (fSite != null && fSite.getSelectionProvider() != null ){ @@ -185,7 +83,7 @@ public class SelectionParseAction extends Action { if( selection == null || !(selection instanceof ITextSelection) ) return null; - return getSelection( (ITextSelection)selection ); + return (ITextSelection)selection; } /** @@ -221,14 +119,10 @@ public class SelectionParseAction extends Action { } } - public void update() { - setEnabled(getSelectedStringFromEditor() != null); - } - protected void reportSourceFileOpenFailure(IPath path) { showStatusLineMessage(MessageFormat.format( CSearchMessages.SelectionParseAction_FileOpenFailure_format, - new String[] { path.toOSString() })); + path.toOSString())); } protected void reportSelectionMatchFailure() { @@ -238,13 +132,13 @@ public class SelectionParseAction extends Action { protected void reportSymbolLookupFailure(String symbol) { showStatusLineMessage(MessageFormat.format( CSearchMessages.SelectionParseAction_SymbolNotFoundInIndex_format, - new String[] { symbol })); + symbol)); } protected void reportIncludeLookupFailure(String filename) { showStatusLineMessage(MessageFormat.format( CSearchMessages.SelectionParseAction_IncludeNotFound_format, - new String[] { filename })); + filename)); } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/c/hover/CSourceHover.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/c/hover/CSourceHover.java index f8a2f7a1919..4f9d5a96049 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/c/hover/CSourceHover.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/c/hover/CSourceHover.java @@ -6,10 +6,9 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * QNX Software Systems - Initial API and implementation - * Anton Leherbauer (Wind River Systems) + * QNX Software Systems - Initial API and implementation + * Anton Leherbauer (Wind River Systems) *******************************************************************************/ - package org.eclipse.cdt.internal.ui.text.c.hover; import java.io.IOException; @@ -124,23 +123,19 @@ public class CSourceHover extends AbstractCEditorTextHover implements ITextHover public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) { if (ast != null) { try { - IASTName[] names; - names = lang.getSelectedNames(ast, fTextRegion.getOffset(), fTextRegion.getLength()); - if (names != null && names.length >= 1) { - for (int i = 0; i < names.length; i++) { - IASTName name= names[i]; - IBinding binding= name.resolveBinding(); - if (binding != null) { - if (binding instanceof IProblemBinding) { - if (DEBUG) fSource= "Cannot resolve " + new String(name.toCharArray()); //$NON-NLS-1$ - } else if (binding instanceof IMacroBinding) { - fSource= computeSourceForMacro(ast, name, binding); - } else { - fSource= computeSourceForBinding(ast, binding); - } - if (fSource != null) { - return Status.OK_STATUS; - } + IASTName name= ast.getNodeSelector(null).findSurroundingName(fTextRegion.getOffset(), fTextRegion.getLength()); + if (name != null) { + IBinding binding= name.resolveBinding(); + if (binding != null) { + if (binding instanceof IProblemBinding) { + if (DEBUG) fSource= "Cannot resolve " + new String(name.toCharArray()); //$NON-NLS-1$ + } else if (binding instanceof IMacroBinding) { + fSource= computeSourceForMacro(ast, name, binding); + } else { + fSource= computeSourceForBinding(ast, binding); + } + if (fSource != null) { + return Status.OK_STATUS; } } } @@ -559,6 +554,7 @@ public class CSourceHover extends AbstractCEditorTextHover implements ITextHover /* * @see ITextHover#getHoverInfo(ITextViewer, IRegion) */ + @Override public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) { IEditorPart editor = getEditor(); if (editor != null) { @@ -777,6 +773,7 @@ public class CSourceHover extends AbstractCEditorTextHover implements ITextHover * @see org.eclipse.jface.text.ITextHoverExtension#getHoverControlCreator() * @since 3.0 */ + @Override public IInformationControlCreator getHoverControlCreator() { return new IInformationControlCreator() { public IInformationControl createInformationControl(Shell parent) {