1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Testcases and fixes for selecting nodes by file offsets.

This commit is contained in:
Markus Schorn 2008-03-05 10:53:22 +00:00
parent 915b4a1e35
commit 789b2ea330
31 changed files with 1033 additions and 463 deletions

View file

@ -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
@ -64,11 +64,11 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
String code = "void f() { int x; x=3; }"; //$NON-NLS-1$
int offset1 = code.indexOf( "x=" ); //$NON-NLS-1$
int length = "x".length(); //$NON-NLS-1$
IASTNode node = parse( code, ParserLanguage.C, offset1, length );
IASTNode node = parse( code, ParserLanguage.C, offset1, length ).getParent();
assertNotNull(node);
assertTrue( node instanceof IASTIdExpression );
assertEquals(((IASTIdExpression)node).getName().toString(), "x"); //$NON-NLS-1$
node = parse( code, ParserLanguage.CPP, offset1, length );
node = parse( code, ParserLanguage.CPP, offset1, length ).getParent();
assertNotNull(node);
assertTrue( node instanceof IASTIdExpression );
assertEquals(((IASTIdExpression)node).getName().toString(), "x"); //$NON-NLS-1$
@ -83,7 +83,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
String code = "int x(){x( );}"; //$NON-NLS-1$
int offset1 = code.indexOf( "x( " ); //$NON-NLS-1$
int length = "x".length(); //$NON-NLS-1$
IASTNode node = parse( code, ParserLanguage.C, offset1, length );
IASTNode node = parse( code, ParserLanguage.C, offset1, length ).getParent();
assertNotNull(node);
assertTrue( node instanceof IASTIdExpression );
assertEquals(((IASTIdExpression)node).getName().toString(), "x"); //$NON-NLS-1$
@ -91,7 +91,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
assertNotNull(name.resolveBinding());
assertTrue(name.resolveBinding() instanceof IFunction);
assertEquals(((IFunction)name.resolveBinding()).getName(), "x"); //$NON-NLS-1$
node = parse( code, ParserLanguage.CPP, offset1, length );
node = parse( code, ParserLanguage.CPP, offset1, length ).getParent();
assertNotNull(node);
assertTrue( node instanceof IASTIdExpression );
assertEquals(((IASTIdExpression)node).getName().toString(), "x"); //$NON-NLS-1$
@ -184,7 +184,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
String code = "int main( int argc ) { int x = argc; }"; //$NON-NLS-1$
int offset1 = code.indexOf( "argc;" ); //$NON-NLS-1$
int length = "argc".length(); //$NON-NLS-1$
IASTNode node = parse( code, ParserLanguage.C, offset1, length );
IASTNode node = parse( code, ParserLanguage.C, offset1, length ).getParent().getParent();
assertNotNull(node);
assertTrue( node instanceof IASTInitializerExpression );
assertEquals( ((IASTIdExpression)((IASTInitializerExpression)node).getExpression()).getName().toString(), "argc" ); //$NON-NLS-1$
@ -192,7 +192,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
assertNotNull(name.resolveBinding());
assertTrue(name.resolveBinding() instanceof IParameter);
assertEquals(((IParameter)name.resolveBinding()).getName(), "argc"); //$NON-NLS-1$
node = parse( code, ParserLanguage.CPP, offset1, length );
node = parse( code, ParserLanguage.CPP, offset1, length ).getParent().getParent();
assertNotNull(node);
assertTrue( node instanceof IASTInitializerExpression );
assertEquals( ((IASTIdExpression)((IASTInitializerExpression)node).getExpression()).getName().toString(), "argc" ); //$NON-NLS-1$
@ -357,6 +357,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
{
case 0:
case 1:
node= node.getParent().getParent();
assertTrue(node instanceof IASTTypeId);
assertEquals(((IASTNamedTypeSpecifier)((IASTTypeId)node).getDeclSpecifier()).getName().toString(), "Gonzo"); //$NON-NLS-1$
name = ((IASTNamedTypeSpecifier)((IASTTypeId)node).getDeclSpecifier()).getName();
@ -425,7 +426,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
String code = writer.toString();
int startIndex = code.indexOf( "foo(1)"); //$NON-NLS-1$
int length = "foo".length(); //$NON-NLS-1$
IASTNode node = parse( code, ParserLanguage.C, startIndex, length );
IASTNode node = parse( code, ParserLanguage.C, startIndex, length ).getParent();
assertNotNull(node);
assertTrue(node instanceof IASTIdExpression);
assertEquals(((IASTIdExpression)node).getName().toString(), "foo"); //$NON-NLS-1$
@ -433,7 +434,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
assertNotNull(name.resolveBinding());
assertTrue(name.resolveBinding() instanceof IFunction);
assertEquals(((IFunction)name.resolveBinding()).getName(), "foo"); //$NON-NLS-1$
node = parse( code, ParserLanguage.CPP, startIndex, length );
node = parse( code, ParserLanguage.CPP, startIndex, length ).getParent();
assertNotNull(node);
assertTrue(node instanceof IASTIdExpression);
assertEquals(((IASTIdExpression)node).getName().toString(), "foo"); //$NON-NLS-1$
@ -466,7 +467,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
assertTrue(name.resolveBinding() instanceof IEnumeration);
assertEquals(((IEnumeration)name.resolveBinding()).getName(), "EColours"); //$NON-NLS-1$
startIndex = codeCPP.indexOf( "EColours color"); //$NON-NLS-1$
node = parse( codeCPP, ParserLanguage.CPP, startIndex, length );
node = parse( codeCPP, ParserLanguage.CPP, startIndex, length ).getParent();
assertNotNull(node);
assertTrue(node instanceof IASTNamedTypeSpecifier);
assertEquals(((IASTNamedTypeSpecifier)node).getName().toString(), "EColours"); //$NON-NLS-1$
@ -519,7 +520,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
String code = writer.toString();
int startIndex = code.indexOf( "static_function( file )"); //$NON-NLS-1$
int length = "static_function".length(); //$NON-NLS-1$
IASTNode node = parse( code, ParserLanguage.C, startIndex, length );
IASTNode node = parse( code, ParserLanguage.C, startIndex, length ).getParent();
assertNotNull(node);
assertTrue(node instanceof IASTIdExpression);
assertEquals(((IASTIdExpression)node).getName().toString(), "static_function"); //$NON-NLS-1$
@ -527,7 +528,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
assertNotNull(name.resolveBinding());
assertTrue(name.resolveBinding() instanceof IFunction);
assertEquals(((IFunction)name.resolveBinding()).getName(), "static_function"); //$NON-NLS-1$
node = parse( code, ParserLanguage.CPP, startIndex, length );
node = parse( code, ParserLanguage.CPP, startIndex, length ).getParent();
assertNotNull(node);
assertTrue(node instanceof IASTIdExpression);
assertEquals(((IASTIdExpression)node).getName().toString(), "static_function"); //$NON-NLS-1$
@ -569,7 +570,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
int startIndex = code.indexOf( "/**/fprintf") + 4; //$NON-NLS-1$
int length = "fprintf".length(); //$NON-NLS-1$
IASTNode node = parse( code, ParserLanguage.C, startIndex, length );
IASTNode node = parse( code, ParserLanguage.C, startIndex, length ).getParent();
assertNotNull(node);
assertTrue(node instanceof IASTIdExpression);
assertEquals(((IASTIdExpression)node).getName().toString(), "fprintf"); //$NON-NLS-1$
@ -577,7 +578,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
assertNotNull(name.resolveBinding());
assertTrue(name.resolveBinding() instanceof IFunction);
assertEquals(((IFunction)name.resolveBinding()).getName(), "fprintf"); //$NON-NLS-1$
node = parse( code, ParserLanguage.CPP, startIndex, length );
node = parse( code, ParserLanguage.CPP, startIndex, length ).getParent();
assertNotNull(node);
assertTrue(node instanceof IASTIdExpression);
assertEquals(((IASTIdExpression)node).getName().toString(), "fprintf"); //$NON-NLS-1$
@ -614,7 +615,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
assertTrue(name.resolveBinding() instanceof ICompositeType);
assertEquals(((ICompositeType)name.resolveBinding()).getName(), "Squaw"); //$NON-NLS-1$
startIndex = codeCPP.indexOf( "sizeof( ") + "sizeof( ".length(); //$NON-NLS-1$ //$NON-NLS-2$
node = parse( codeCPP, ParserLanguage.CPP, startIndex, length );
node = parse( codeCPP, ParserLanguage.CPP, startIndex, length ).getParent().getParent();
assertNotNull(node);
assertTrue(node instanceof IASTTypeId);
assertEquals(((IASTNamedTypeSpecifier)((IASTTypeId)node).getDeclSpecifier()).getName().toString(), "Squaw"); //$NON-NLS-1$
@ -638,7 +639,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
String code = writer.toString();
int startIndex = code.indexOf( "return ") + "return ".length(); //$NON-NLS-1$ //$NON-NLS-2$
int length = "FOUND_ME".length(); //$NON-NLS-1$
IASTNode node = parse( code, ParserLanguage.CPP, startIndex, length );
IASTNode node = parse( code, ParserLanguage.CPP, startIndex, length ).getParent();
assertNotNull(node);
assertTrue(node instanceof IASTIdExpression);
assertEquals(((IASTIdExpression)node).getName().toString(), "FOUND_ME"); //$NON-NLS-1$
@ -739,7 +740,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
String code = writer.toString();
int startIndex = code.indexOf( "new B" ) + 4; //$NON-NLS-1$
int length = "B".length(); //$NON-NLS-1$
IASTNode node = parse( code, ParserLanguage.CPP, startIndex, length );
IASTNode node = parse( code, ParserLanguage.CPP, startIndex, length ).getParent().getParent();
assertNotNull(node);
assertTrue(node instanceof IASTTypeId);
assertEquals(((IASTNamedTypeSpecifier)((IASTTypeId)node).getDeclSpecifier()).getName().toString(), "B"); //$NON-NLS-1$
@ -758,7 +759,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
String code = writer.toString();
int startIndex = code.indexOf( "(A*)" ) + 1; //$NON-NLS-1$
int length = "A".length(); //$NON-NLS-1$
IASTNode node = parse( code, ParserLanguage.CPP, startIndex, length );
IASTNode node = parse( code, ParserLanguage.CPP, startIndex, length ).getParent();
assertNotNull(node);
assertTrue(node instanceof IASTNamedTypeSpecifier);
assertEquals(((IASTNamedTypeSpecifier)node).getName().toString(), "A"); //$NON-NLS-1$
@ -845,7 +846,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
index = code.indexOf( "Card( int rank );") + 10; //$NON-NLS-1$
length = "rank".length(); //$NON-NLS-1$
node = parse( code, ParserLanguage.CPP, index, length );
node = parse( code, ParserLanguage.CPP, index, length ).getParent();
assertNotNull(node);
assertTrue(node instanceof IASTDeclarator);
assertEquals(((IASTDeclarator)node).getName().toString(), "rank"); //$NON-NLS-1$
@ -855,7 +856,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
assertEquals(((IVariable)name.resolveBinding()).getName(), "rank"); //$NON-NLS-1$
index = code.indexOf( "int rank;") + 4; //$NON-NLS-1$
node = parse( code, ParserLanguage.CPP, index, length );
node = parse( code, ParserLanguage.CPP, index, length ).getParent();
assertNotNull(node);
assertTrue(node instanceof IASTDeclarator);
assertEquals(((IASTDeclarator)node).getName().toString(), "rank"); //$NON-NLS-1$
@ -898,7 +899,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
index = code.indexOf( "Card::Card( int rank )") + 16; //$NON-NLS-1$
length = "rank".length(); //$NON-NLS-1$
node = parse( code, ParserLanguage.CPP, index, length );
node = parse( code, ParserLanguage.CPP, index, length ).getParent();
assertNotNull(node);
assertTrue(node instanceof IASTDeclarator);
assertEquals(((IASTDeclarator)node).getName().toString(), "rank"); //$NON-NLS-1$
@ -958,7 +959,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
assertEquals(((ICPPField)name.resolveBinding()).getName(), "rank"); //$NON-NLS-1$
index = code.indexOf( "this->rank = rank;") + 13; //$NON-NLS-1$
node = parse( code, ParserLanguage.CPP, index, length );
node = parse( code, ParserLanguage.CPP, index, length ).getParent();
assertNotNull(node);
assertTrue(node instanceof IASTIdExpression);
assertEquals(((IASTIdExpression)node).getName().toString(), "rank"); //$NON-NLS-1$
@ -999,7 +1000,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
index = code.indexOf( "this->rank = getRank();") + 13; //$NON-NLS-1$
length = "getRank".length(); //$NON-NLS-1$
node = parse( code, ParserLanguage.CPP, index, length );
node = parse( code, ParserLanguage.CPP, index, length ).getParent();
assertNotNull(node);
assertTrue(node instanceof IASTIdExpression);
assertEquals(((IASTIdExpression)node).getName().toString(), "getRank"); //$NON-NLS-1$
@ -1037,7 +1038,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
String code = writer.toString();
int index = code.indexOf( "void f(int itself){}") + 11; //$NON-NLS-1$
int length = "itself".length(); //$NON-NLS-1$
IASTNode node = parse( code, ParserLanguage.C, index, length );
IASTNode node = parse( code, ParserLanguage.C, index, length ).getParent();
assertNotNull(node);
assertTrue(node instanceof IASTDeclarator);
assertEquals(((IASTDeclarator)node).getName().toString(), "itself"); //$NON-NLS-1$
@ -1045,7 +1046,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
assertNotNull(name.resolveBinding());
assertTrue(name.resolveBinding() instanceof IVariable);
assertEquals(((IVariable)name.resolveBinding()).getName(), "itself"); //$NON-NLS-1$
node = parse( code, ParserLanguage.CPP, index, length );
node = parse( code, ParserLanguage.CPP, index, length ).getParent();
assertNotNull(node);
assertTrue(node instanceof IASTDeclarator);
assertEquals(((IASTDeclarator)node).getName().toString(), "itself"); //$NON-NLS-1$
@ -1119,7 +1120,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
String code = buffer.toString();
int index = code.indexOf("x;"); //$NON-NLS-1$
int length = "x".length(); //$NON-NLS-1$
IASTNode node = parse( code, ParserLanguage.C, true, true, index, length );
IASTNode node = parse( code, ParserLanguage.C, true, true, index, length ).getParent();
assertNotNull(node);
assertTrue(node instanceof IASTDeclarator);
assertEquals(((IASTDeclarator)node).getName().toString(), "x"); //$NON-NLS-1$
@ -1138,7 +1139,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
String code = buffer.toString();
int index = code.indexOf("x;"); //$NON-NLS-1$
int length = "x".length(); //$NON-NLS-1$
IASTNode node = parse( code, ParserLanguage.C, true, true, index, length );
IASTNode node = parse( code, ParserLanguage.C, true, true, index, length ).getParent();
assertNotNull(node);
assertTrue(node instanceof IASTDeclarator);
assertEquals(((IASTDeclarator)node).getName().toString(), "x"); //$NON-NLS-1$
@ -1177,7 +1178,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
String code = buffer.toString();
int index = code.indexOf("y;"); //$NON-NLS-1$
int length = "y".length(); //$NON-NLS-1$
IASTNode node = parse( code, ParserLanguage.C, true, true, index, length );
IASTNode node = parse( code, ParserLanguage.C, true, true, index, length ).getParent();
assertNotNull(node);
assertTrue(node instanceof IASTDeclarator);
assertEquals(((IASTDeclarator)node).getName().toString(), "y"); //$NON-NLS-1$
@ -1198,7 +1199,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
String code = buffer.toString();
int index = code.indexOf("c x;"); //$NON-NLS-1$
int length = "c".length(); //$NON-NLS-1$
IASTNode node = parse( code, ParserLanguage.C, true, true, index, length );
IASTNode node = parse( code, ParserLanguage.C, true, true, index, length ).getParent();
assertNotNull(node);
assertTrue(node instanceof IASTNamedTypeSpecifier);
assertEquals(((IASTNamedTypeSpecifier)node).getName().toString(), "c"); //$NON-NLS-1$
@ -1209,7 +1210,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
index = code.indexOf("x;"); //$NON-NLS-1$
length = "x".length(); //$NON-NLS-1$
node = parse( code, ParserLanguage.C, true, true, index, length );
node = parse( code, ParserLanguage.C, true, true, index, length ).getParent();
assertNotNull(node);
assertTrue(node instanceof IASTDeclarator);
assertEquals(((IASTDeclarator)node).getName().toString(), "x"); //$NON-NLS-1$
@ -1308,7 +1309,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
String code = buffer.toString();
int index = code.indexOf("b,a"); //$NON-NLS-1$
int length = "b".length(); //$NON-NLS-1$
IASTNode node = parse( code, ParserLanguage.C, true, true, index, length );
IASTNode node = parse( code, ParserLanguage.C, true, true, index, length ).getParent();
assertNotNull(node);
assertTrue(node instanceof IASTDeclarator);
IASTName name = ((IASTDeclarator)node).getName();
@ -1518,7 +1519,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
index = code.indexOf("c;"); //$NON-NLS-1$
length = "c".length(); //$NON-NLS-1$
node = parse( code, ParserLanguage.CPP, index, length );
node = parse( code, ParserLanguage.CPP, index, length ).getParent();
assertNotNull(node);
assertTrue( node instanceof IASTDeclarator);
assertEquals(((IASTDeclarator)node).getName().toString(), "c"); //$NON-NLS-1$
@ -1648,7 +1649,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
public void testBug86126() throws Exception {
String header= "foo"+System.currentTimeMillis()+".h";
String source= "blah"+System.currentTimeMillis()+".c";
importFile(header, "int x;\r\n"); //$NON-NLS-1$ //$NON-NLS-2$
importFile(header, "int x;\r\n"); //$NON-NLS-1$
String code = "#include \""+header+"\"\r\n"; //$NON-NLS-1$
IFile file = importFile(source, code);
int offset1 = code.indexOf( "#include \""+header+"\"" ); //$NON-NLS-1$

View file

@ -0,0 +1,372 @@
/*******************************************************************************
* 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.parser.tests.ast2;
import java.io.IOException;
import junit.framework.TestSuite;
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.IASTPreprocessorMacroExpansion;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.parser.cpp.GPPParserExtensionConfiguration;
import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.IScanner;
import org.eclipse.cdt.core.parser.NullLogService;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.ScannerInfo;
import org.eclipse.cdt.internal.core.dom.parser.cpp.GNUCPPSourceParser;
public class ASTNodeSelectorTest extends AST2BaseTest {
static public TestSuite suite() {
return suite(ASTNodeSelectorTest.class);
}
private String fCode;
private IASTTranslationUnit fTu;
private IASTNodeSelector fSelector;
public ASTNodeSelectorTest() {
}
public ASTNodeSelectorTest(String name) {
super(name);
}
@Override
protected void setUp() throws Exception {
super.setUp();
createTranslationUnit();
}
private void createTranslationUnit() throws IOException {
fCode= getContents(1)[0].toString();
CodeReader codeReader = new CodeReader(fCode.toCharArray());
ScannerInfo scannerInfo = new ScannerInfo();
IScanner scanner= AST2BaseTest.createScanner(codeReader, ParserLanguage.CPP, ParserMode.COMPLETE_PARSE, scannerInfo, false);
GNUCPPSourceParser parser= new GNUCPPSourceParser(scanner, ParserMode.COMPLETE_PARSE, new NullLogService(), new GPPParserExtensionConfiguration());
fTu= parser.parse();
fSelector= fTu.getNodeSelector(null);
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
}
private void testContainedName(int from, int to, String sig) {
IASTName name= fSelector.findFirstContainedName(from, to-from);
verify(sig, name);
}
private void verify(String sig, IASTNode node) {
if (sig == null) {
assertNull("unexpexted selection: " + (node == null ? "" : node.getRawSignature()), node);
}
else {
assertNotNull("unable to select " + sig, node);
if (node instanceof IASTName) {
assertEquals(sig, ((IASTName) node).toString());
}
else {
assertEquals(sig, node.getRawSignature());
}
}
}
private void testContainedNode(int from, int to, String sig) {
IASTNode node= fSelector.findFirstContainedNode(from, to-from);
verify(sig, node);
}
private void testName(int from, int to, String sig) {
IASTName name= fSelector.findName(from, to-from);
verify(sig, name);
}
private void testNode(int from, int to, String sig) {
IASTNode node= fSelector.findNode(from, to-from);
verify(sig, node);
}
private void testEnclosingName(int from, int to, String sig) {
IASTName name= fSelector.findEnclosingName(from, to-from);
verify(sig, name);
}
private void testEnclosingNode(int from, int to, String sig) {
IASTNode node= fSelector.findEnclosingNode(from, to-from);
verify(sig, node);
}
private void testExpansion(int from, int to, String sig) {
IASTPreprocessorMacroExpansion exp= fSelector.findEnclosingMacroExpansion(from, to-from);
verify(sig, exp);
}
// #define shift_offsets
// int shift= shift_offsets;
//
// #include <test>
// int a;
public void testInclusion() {
int include_start= fCode.indexOf("#include");
int name_start= fCode.indexOf("test");
int include_end= fCode.indexOf(">") + 1;
testContainedName(include_start-1, include_end+1, "test");
testContainedName(name_start, include_end, "test");
testContainedName(include_start+1, name_start+1, null);
testContainedName(name_start+1, name_start+7, null);
testContainedNode(include_start-1, include_end+1, "#include <test>");
testContainedNode(name_start, include_end, "test");
testContainedNode(include_start+1, name_start+1, null);
testContainedNode(name_start+1, name_start+7, null);
testEnclosingName(name_start, name_start+4, "test");
testEnclosingName(name_start, name_start, "test");
testEnclosingName(name_start+4, name_start+4, "test");
testEnclosingName(name_start-1, name_start+1, null);
testEnclosingName(name_start+4, name_start+5, null);
testEnclosingNode(name_start, name_start+4, "test");
testEnclosingNode(name_start, name_start, "test");
testEnclosingNode(name_start+4, name_start+4, "test");
testEnclosingNode(name_start-1, name_start+1, "#include <test>");
testEnclosingNode(name_start+4-1, name_start+4+1, "#include <test>");
testExpansion(name_start, name_start+4, null);
}
// #define shift_offsets
// int shift= shift_offsets;
//
// #define EMPTY
// #define TEST_H "test.h"
// void func() {
// #include EMPTY TEST_H
// }
public void testInclusionWithExpansions() {
int inclusion_start= fCode.indexOf("#include");
int empty_start= fCode.indexOf("EMPTY", inclusion_start);
int testh_start= fCode.indexOf("TEST_H", empty_start);
int file_end= fCode.length();
testContainedName(inclusion_start-1, file_end-1, "EMPTY");
testContainedName(testh_start, file_end, "TEST_H");
testContainedName(testh_start+1, file_end, null);
testContainedName(testh_start, testh_start+5, null);
testContainedNode(inclusion_start-1, file_end+1, "#include EMPTY TEST_H");
testContainedNode(testh_start, file_end, "TEST_H");
testContainedNode(testh_start+1, file_end, null);
testContainedNode(testh_start, testh_start+5, null);
testName(empty_start, empty_start+5, "EMPTY");
testName(empty_start-1, empty_start+5, null);
testName(empty_start+1, empty_start+5, null);
testName(empty_start, empty_start+4, null);
testName(empty_start, empty_start+6, null);
testNode(empty_start, empty_start+5, "EMPTY");
testNode(empty_start-1, empty_start+5, null);
testNode(empty_start+1, empty_start+5, null);
testNode(empty_start, empty_start+4, null);
testNode(empty_start, empty_start+6, null);
testEnclosingName(empty_start, empty_start+5, "EMPTY");
testEnclosingName(empty_start, empty_start, "EMPTY");
testEnclosingName(empty_start+5, empty_start+5, "EMPTY");
testEnclosingName(empty_start-1, empty_start, null);
testEnclosingName(empty_start+5, empty_start+6, "test.h");
testEnclosingName(testh_start, testh_start+6, "TEST_H");
testEnclosingName(testh_start, testh_start, "TEST_H");
testEnclosingName(testh_start+6, testh_start+6, "TEST_H");
testEnclosingName(testh_start-1, testh_start+1, "test.h");
testEnclosingName(testh_start+5, testh_start+7, null);
testEnclosingNode(empty_start, empty_start+5, "EMPTY");
testEnclosingNode(empty_start, empty_start, "EMPTY");
testEnclosingNode(empty_start+5, empty_start+5, "EMPTY");
testEnclosingNode(empty_start-1, empty_start, "#include EMPTY TEST_H");
testEnclosingNode(empty_start+5, empty_start+6, "test.h");
testEnclosingNode(testh_start, testh_start+6, "TEST_H");
testEnclosingNode(testh_start, testh_start, "TEST_H");
testEnclosingNode(testh_start+6, testh_start+6, "TEST_H");
testEnclosingNode(testh_start-1, testh_start+1, "test.h");
testEnclosingNode(testh_start+6-1, testh_start+6+1, "{\n #include EMPTY TEST_H\n }");
testExpansion(empty_start, empty_start+5, "EMPTY");
testExpansion(empty_start, empty_start, "EMPTY");
testExpansion(empty_start+5, empty_start+5, "EMPTY");
testExpansion(empty_start-1, empty_start, null);
testExpansion(empty_start+5, empty_start+6, null);
testExpansion(testh_start, testh_start+6, "TEST_H");
}
// #define shift_offsets
// int shift= shift_offsets;
//
// #define xx 1
// #if xx == 2
// #elif xx == 1
// #endif
public void testMacroInConditionalExpression() {
int x1= fCode.indexOf("xx");
int x2= fCode.indexOf("xx", x1+1);
int x3= fCode.indexOf("xx", x2+1);
testContainedName(x1, x1+2, "xx");
testContainedName(x2-1, x2+2, "xx");
testContainedName(x3, x3+3, "xx");
testContainedName(x1, x1+1, null);
testContainedName(x2+1, x2+2, null);
testContainedName(x3+1, x3+1, null);
testName(x1, x1+2, "xx");
testName(x2, x2+2, "xx");
testName(x3, x3+2, "xx");
testName(x1+1, x1+2, null);
testName(x2-1, x2+2, null);
testName(x3, x3+3, null);
testName(x3, x3+1, null);
testEnclosingName(x1, x1+2, "xx");
testEnclosingName(x2+2, x2+2, "xx");
testEnclosingName(x3, x3, "xx");
testEnclosingName(x1-1, x1+2, null);
testEnclosingName(x2+2, x2+3, null);
testEnclosingName(x3-1, x3-1, null);
testExpansion(x1, x1+2, null);
testExpansion(x2+2, x2+2, "xx");
testExpansion(x3, x3, "xx");
testExpansion(x2+2, x2+3, null);
testExpansion(x3-1, x3-1, null);
}
// #define shift_offsets
// int shift= shift_offsets;
//
// #define xx 1
// #if !defined(xx)
// #elif defined(xx) == 1
// #endif
public void testMacroInDefinedExpression() {
int x1= fCode.indexOf("xx");
int x2= fCode.indexOf("xx", x1+1);
int x3= fCode.indexOf("xx", x2+1);
testContainedName(x1, x1+2, "xx");
testContainedName(x2-1, x2+2, "xx");
testContainedName(x3, x3+3, "xx");
testContainedName(x1, x1+1, null);
testContainedName(x2+1, x2+2, null);
testContainedName(x3+1, x3+1, null);
testName(x1, x1+2, "xx");
testName(x2, x2+2, "xx");
testName(x3, x3+2, "xx");
testName(x1+1, x1+2, null);
testName(x2-1, x2+2, null);
testName(x3, x3+3, null);
testName(x3, x3+1, null);
testEnclosingName(x1, x1+2, "xx");
testEnclosingName(x2+2, x2+2, "xx");
testEnclosingName(x3, x3, "xx");
testEnclosingName(x1-1, x1+2, null);
testEnclosingName(x2+2, x2+3, null);
testEnclosingName(x3-1, x3-1, null);
testExpansion(x1, x1+2, null);
testExpansion(x2+2, x2+2, null);
testExpansion(x3, x3, null);
testExpansion(x2+2, x2+3, null);
testExpansion(x3-1, x3-1, null);
}
// #define shift_offsets
// int shift= shift_offsets;
//
// #define xx 1
// #ifndef xx
// #endif
// #ifdef xx
// #endif
// #undef xx
public void testMacroInConditional() {
int x1= fCode.indexOf("xx");
x1= fCode.indexOf("xx", x1+1);
int x2= fCode.indexOf("xx", x1+1);
int x3= fCode.indexOf("xx", x2+1);
testContainedName(x1, x1+2, "xx");
testContainedName(x2-1, x2+2, "xx");
testContainedName(x3, x3+3, "xx");
testContainedName(x1, x1+1, null);
testContainedName(x2+1, x2+2, null);
testContainedName(x3+1, x3+1, null);
testName(x1, x1+2, "xx");
testName(x2, x2+2, "xx");
testName(x3, x3+2, "xx");
testName(x1+1, x1+2, null);
testName(x2-1, x2+2, null);
testName(x3, x3+3, null);
testName(x3, x3+1, null);
testEnclosingName(x1, x1+2, "xx");
testEnclosingName(x2+2, x2+2, "xx");
testEnclosingName(x3, x3, "xx");
testEnclosingName(x1-1, x1+2, null);
testEnclosingName(x2+2, x2+3, null);
testEnclosingName(x3-1, x3-1, null);
testExpansion(x1, x1+2, null);
testExpansion(x2+2, x2+2, null);
testExpansion(x3, x3, null);
testExpansion(x2+2, x2+3, null);
testExpansion(x3-1, x3-1, null);
}
// #define shift_offsets
// int shift= shift_offsets;
//
// #define IMPLICIT 1
// #define EXPLICIT IMPLICIT
// int a= EXPLICIT;
public void testUnreachableImplicitMacro() {
int x1= fCode.indexOf("EXPLICIT;");
testContainedName(x1, fCode.length(), "EXPLICIT");
testName(x1, x1+8, "EXPLICIT");
testEnclosingName(x1, 0, "EXPLICIT");
}
// #define shift_offsets
// int shift= shift_offsets;
//
// #define NESTED 1
// #define EXPLICIT(x) x
// int a= EXPLICIT(NESTED);
public void testReachableNestedMacro() {
int x1= fCode.indexOf("NESTED)");
testContainedName(x1, fCode.length(), "NESTED");
testName(x1, x1+6, "NESTED");
testEnclosingName(x1, 0, "NESTED");
}
}

View file

@ -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
@ -40,6 +40,7 @@ public class DOMParserTestSuite extends TestCase {
suite.addTestSuite( AST2UtilTests.class );
suite.addTestSuite( AST2UtilOldTests.class );
suite.addTestSuite( AST2SelectionParseTest.class );
suite.addTest( ASTNodeSelectorTest.suite());
suite.addTestSuite( CodeReaderCacheTest.class );
suite.addTestSuite( AST2CPPSpecTest.class );
suite.addTestSuite( AST2CPPSpecFailingTest.class );

View file

@ -283,7 +283,7 @@ public class LocationMapTests extends BaseTestCase {
private void checkMacroUndef(IASTPreprocessorStatement s, IBinding binding, String image, String name, String nameImage,
String filename, int offset, int length, int line, int nameOffset, int nameLength) {
IASTPreprocessorUndefStatement st= (IASTPreprocessorUndefStatement) s;
checkName(st.getMacroName(), binding, name, st, IASTPreprocessorUndefStatement.MACRO_NAME, ROLE_UNCLEAR, filename, nameOffset, nameLength, line, line, nameImage);
checkName(st.getMacroName(), binding, name, st, IASTPreprocessorStatement.MACRO_NAME, ROLE_UNCLEAR, filename, nameOffset, nameLength, line, line, nameImage);
checkASTNode(st, fTu, PROP_PST, filename, offset, length, line, line, image);
}
@ -344,8 +344,8 @@ public class LocationMapTests extends BaseTestCase {
public void testIf() {
init(DIGITS);
fLocationMap.encounterPoundIf(0, 0, 0, 0, false);
fLocationMap.encounterPoundIf(0, 1, 3, 16, true);
fLocationMap.encounterPoundIf(0, 0, 0, 0, false, IASTName.EMPTY_NAME_ARRAY);
fLocationMap.encounterPoundIf(0, 1, 3, 16, true, IASTName.EMPTY_NAME_ARRAY);
IASTPreprocessorStatement[] prep= fLocationMap.getAllPreprocessorStatements();
assertEquals(2, prep.length);
checkIf(prep[0], "", "", false, FN, 0, 0, 1);
@ -354,8 +354,8 @@ public class LocationMapTests extends BaseTestCase {
public void testIfdef() {
init(DIGITS);
fLocationMap.encounterPoundIfdef(0, 0, 0, 0, false);
fLocationMap.encounterPoundIfdef(0, 1, 3, 16, true);
fLocationMap.encounterPoundIfdef(0, 0, 0, 0, false, null);
fLocationMap.encounterPoundIfdef(0, 1, 3, 16, true, null);
IASTPreprocessorStatement[] prep= fLocationMap.getAllPreprocessorStatements();
assertEquals(2, prep.length);
checkIfdef(prep[0], "", "", false, FN, 0, 0, 1);
@ -364,8 +364,8 @@ public class LocationMapTests extends BaseTestCase {
public void testIfndef() {
init(DIGITS);
fLocationMap.encounterPoundIfndef(0, 0, 0, 0, false);
fLocationMap.encounterPoundIfndef(0, 1, 3, 16, true);
fLocationMap.encounterPoundIfndef(0, 0, 0, 0, false, null);
fLocationMap.encounterPoundIfndef(0, 1, 3, 16, true, null);
IASTPreprocessorStatement[] prep= fLocationMap.getAllPreprocessorStatements();
assertEquals(2, prep.length);
checkIfndef(prep[0], "", "", false, FN, 0, 0, 1);
@ -374,8 +374,8 @@ public class LocationMapTests extends BaseTestCase {
public void testElif() {
init(DIGITS);
fLocationMap.encounterPoundElif(0, 0, 0, 0, false);
fLocationMap.encounterPoundElif(0, 1, 3, 16, true);
fLocationMap.encounterPoundElif(0, 0, 0, 0, false, IASTName.EMPTY_NAME_ARRAY);
fLocationMap.encounterPoundElif(0, 1, 3, 16, true, IASTName.EMPTY_NAME_ARRAY);
IASTPreprocessorStatement[] prep= fLocationMap.getAllPreprocessorStatements();
assertEquals(2, prep.length);
checkElif(prep[0], "", "", false, FN, 0, 0, 1);
@ -476,11 +476,11 @@ public class LocationMapTests extends BaseTestCase {
refs= fLocationMap.getReferences(macro1);
assertEquals(1, refs.length);
checkName(refs[0], macro1, "n1", refs[0].getParent(), IASTPreprocessorMacroExpansion.EXPANSION_NAME, ROLE_REFERENCE, FN, 110, 15, 2, 2, new String(LONGDIGITS, 110, 15));
checkName(refs[0], macro1, "n1", refs[0].getParent(), IASTPreprocessorMacroExpansion.NESTED_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", refs[0].getParent(), IASTPreprocessorMacroExpansion.EXPANSION_NAME, ROLE_REFERENCE, FN, 110, 15, 2, 2, new String(LONGDIGITS, 110, 15));
checkName(refs[0], macro2, "n2", refs[0].getParent(), IASTPreprocessorMacroExpansion.NESTED_EXPANSION_NAME, ROLE_REFERENCE, FN, 110, 15, 2, 2, new String(LONGDIGITS, 110, 15));
}
public void testContexts() {

View file

@ -11,8 +11,10 @@
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)}.
* Interface for searching nodes in a translation unit. An instance of this interface, responsible
* for one file contained in a translation-unit, can be obtained using
* {@link IASTTranslationUnit#getNodeSelector(String)}.
*
* @since 5.0
*/
public interface IASTNodeSelector {
@ -23,9 +25,9 @@ public interface IASTNodeSelector {
IASTName findName(int offset, int length);
/**
* Returns the smallest name surrounding the given range, or <code>null</code> if there is no such node.
* Returns the smallest name enclosing the given range, or <code>null</code> if there is no such node.
*/
IASTName findSurroundingName(int offset, int length);
IASTName findEnclosingName(int offset, int length);
/**
* Returns the first name contained in the given range, or <code>null</code> if there is no such node.
@ -34,16 +36,31 @@ public interface IASTNodeSelector {
/**
* Returns the node for the exact given range, or <code>null</code> if there is no such node.
* <p>
* For nodes with the same location, macro-expansions ({@link IASTPreprocessorMacroExpansion}) are preferred
* over c/c++-nodes and children are preferred over their parents.
*/
IASTNode findNode(int offset, int length);
/**
* Returns the smallest node surrounding the given range, or <code>null</code> if there is no such node.
* Returns the smallest node enclosing the given range, or <code>null</code> if there is no such node.
* <p>
* For nodes with the same location, macro-expansions ({@link IASTPreprocessorMacroExpansion}) are preferred
* over c/c++-nodes nodes and children are preferred over their parents.
* Prefers children over parents.
*/
IASTNode findSurroundingNode(int offset, int length);
IASTNode findEnclosingNode(int offset, int length);
/**
* Returns the first node contained in the given range, or <code>null</code> if there is no such node.
* <p>
* For nodes with the same location, macro-expansions ({@link IASTPreprocessorMacroExpansion}) are preferred
* over c/c++-nodes nodes and children are preferred over their parents.
*/
IASTNode findFirstContainedNode(int offset, int length);
/**
* Returns a macro expansion enclosing the given range, or <code>null</code>.
*/
IASTPreprocessorMacroExpansion findEnclosingMacroExpansion(int offset, int length);
}

View file

@ -1,35 +1,34 @@
/*******************************************************************************
* 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
* Emanuel Graf (IFS)
* IBM - Initial API and implementation
* Emanuel Graf (IFS)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
/**
* This interface represent a preprocessor #ifdef statement.
*
* @author jcamelon
*/
public interface IASTPreprocessorIfdefStatement extends
IASTPreprocessorStatement {
public interface IASTPreprocessorIfdefStatement extends IASTPreprocessorStatement {
/**
* Was this #ifdef branch taken?
*
* @return
* Returns whether this branch was taken.
*/
public boolean taken();
/**
* The condition of the ifdef.
*
* @return the Condition
* The condition of the ifdef-statement.
* @return the condition
*/
public char[] getCondition();
/**
* Returns the macro reference, or <code>null</code> if the macro does not exist.
*/
IASTName getMacroReference();
}

View file

@ -1,34 +1,34 @@
/*******************************************************************************
* 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
* Emanuel Graf (IFS)
* IBM - Initial API and implementation
* Emanuel Graf (IFS)
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
/**
* This interface represent a preprocessor #ifndef statement.
*
* @author jcamelon
*/
public interface IASTPreprocessorIfndefStatement extends
IASTPreprocessorStatement {
public interface IASTPreprocessorIfndefStatement extends IASTPreprocessorStatement {
/**
* Was this branch taken?
*
* @return
* Returns whether this branch was taken.
*/
public boolean taken();
/**
* The condition of the ifndef.
*
* @return the Condition
* Returns the condition of the ifndef-statement.
*/
public char[] getCondition();
/**
* Returns the macro reference, or <code>null</code> if the macro does not exist.
*/
IASTName getMacroReference();
}

View file

@ -18,6 +18,8 @@ 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$
public static final ASTNodeProperty NESTED_EXPANSION_NAME=
new ASTNodeProperty("IASTPreprocessorMacroExpansion.NESTED_EXPANSION_NAME - nested macro name"); //$NON-NLS-1$
/**
* Returns the macro definition used for the expansion.

View file

@ -1,20 +1,19 @@
/*******************************************************************************
* Copyright (c) 2004, 2005 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
* IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
/**
* This is the base interface for all preprocessor directives.
*
* @author jcamelon
*/
public interface IASTPreprocessorStatement extends IASTNode {
public static final ASTNodeProperty MACRO_NAME = new ASTNodeProperty( "IASTPreprocessorStatement.MACRO_NAME - the name of a macro"); //$NON-NLS-1$
}

View file

@ -1,24 +1,23 @@
/*******************************************************************************
* Copyright (c) 2004, 2005 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
* IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
/**
* This interface represents a preprocessor #undef statement.
*
* @author jcamelon
*/
public interface IASTPreprocessorUndefStatement extends
IASTPreprocessorStatement {
public interface IASTPreprocessorUndefStatement extends IASTPreprocessorStatement {
public static final ASTNodeProperty MACRO_NAME = new ASTNodeProperty( "IASTPreprocessorUndefStatement.MACRO_NAME - the name of the macro being undefined"); //$NON-NLS-1$
/**
* Returns the reference to the macro, or <code>null</code>.
*/
public IASTName getMacroName();
}

View file

@ -1,119 +0,0 @@
/*******************************************************************************
* 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) {
return isAcceptableNode(node) && rangeMatches(node.getOffset(), node.getLength(), selOffset, selLength);
}
public boolean isAcceptableNode(ASTNode astNode) {
return !fNamesOnly || astNode instanceof IASTName;
}
/**
* Returns whether the node range matches the selection.
*/
public boolean rangeMatches(final int nodeOffset, final int nodeLength, int selOffset,
int selLength) {
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;
}
}
}

View file

@ -10,16 +10,15 @@
*******************************************************************************/
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.core.dom.ast.IASTPreprocessorMacroExpansion;
import org.eclipse.cdt.internal.core.dom.parser.ASTNodeSpecification.Relation;
import org.eclipse.cdt.internal.core.parser.scanner.ILocationResolver;
/**
* Class to support searching for nodes by offsets.
* Class to support searching for nodes by file offsets.
* @since 5.0
*/
public class ASTNodeSelector implements IASTNodeSelector {
@ -49,85 +48,99 @@ public class ASTNodeSelector implements IASTNodeSelector {
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getNode(int, int)
*/
private IASTNode getNode(int offset, int length, ASTNodeMatchKind matchKind) {
private <T extends IASTNode> T findNode(int offsetInFile, int lengthInFile, Relation relation, Class<T> requiredClass) {
if (!fIsValid) {
return null;
}
final int sequenceNumber= fLocationResolver.getSequenceNumberForFileOffset(fFilePath, offset);
int sequenceLength;
int altSequenceNumber= -1;
int sequenceNumber= fLocationResolver.getSequenceNumberForFileOffset(fFilePath, offsetInFile);
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;
if (lengthInFile > 0) {
sequenceLength= fLocationResolver.getSequenceNumberForFileOffset(fFilePath, offsetInFile+lengthInFile-1) + 1 - sequenceNumber;
}
else {
sequenceLength= 0;
if (offsetInFile > 0) {
altSequenceNumber= fLocationResolver.getSequenceNumberForFileOffset(fFilePath, offsetInFile-1);
if (altSequenceNumber+1 == sequenceNumber) {
altSequenceNumber= -1;
}
else {
// we are on a context boundary and we need to check the variant to the left and
// the one to the right
sequenceLength= 1;
}
}
}
return result;
final ASTNodeSpecification<T> nodeSpec= new ASTNodeSpecification<T>(relation, requiredClass, offsetInFile, lengthInFile);
nodeSpec.setRangeInSequence(sequenceNumber, sequenceLength);
getNode(nodeSpec);
if (altSequenceNumber != -1) {
nodeSpec.setRangeInSequence(altSequenceNumber, sequenceLength);
getNode(nodeSpec);
}
return nodeSpec.getBestNode();
}
private <T extends IASTNode> T getNode(ASTNodeSpecification<T> nodeSpec) {
fLocationResolver.findPreprocessorNode(nodeSpec);
if (!nodeSpec.requiresClass(IASTPreprocessorMacroExpansion.class)) {
FindNodeForOffsetAction nodeFinder= new FindNodeForOffsetAction(nodeSpec);
fTu.accept(nodeFinder);
}
return nodeSpec.getBestNode();
}
/* (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);
return findNode(offset, length, Relation.FIRST_CONTAINED, IASTNode.class);
}
/* (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);
return findNode(offset, length, Relation.EXACT_MATCH, IASTNode.class);
}
/* (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);
public IASTNode findEnclosingNode(int offset, int length) {
return findNode(offset, length, Relation.ENCLOSING, IASTNode.class);
}
/* (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);
return findNode(offset, length, Relation.FIRST_CONTAINED, IASTName.class);
}
/* (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);
return findNode(offset, length, Relation.EXACT_MATCH, IASTName.class);
}
/* (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);
public IASTName findEnclosingName(int offset, int length) {
return findNode(offset, length, Relation.ENCLOSING, IASTName.class);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#findSurrundingMacroExpansion(int, int)
*/
public IASTPreprocessorMacroExpansion findEnclosingMacroExpansion(int offset, int length) {
return findNode(offset, length, Relation.ENCLOSING, IASTPreprocessorMacroExpansion.class);
}
}

View file

@ -0,0 +1,180 @@
/*******************************************************************************
* 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.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTImageLocation;
import org.eclipse.cdt.core.dom.ast.IASTNode;
/**
* 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 ASTNodeSpecification<T extends IASTNode> {
public enum Relation {FIRST_CONTAINED, EXACT_MATCH, ENCLOSING}
private final Class<T> fClass;
private final Relation fRelation;
private final int fFileOffset;
private final int fFileEndOffset;
private int fSeqNumber;
private int fSeqEndNumber;
private int fBestOffset;
private int fBestEndOffset;
private T fBestNode;
public ASTNodeSpecification(Relation relation, Class<T> clazz, int fileOffset, int fileLength) {
fRelation= relation;
fClass= clazz;
fFileOffset= fileOffset;
fFileEndOffset= fileOffset+fileLength;
}
public void setRangeInSequence(int offsetInSeq, int lengthInSeq) {
fSeqNumber= offsetInSeq;
fSeqEndNumber= offsetInSeq+lengthInSeq;
}
public Relation getRelationToSelection() {
return fRelation;
}
public int getSequenceStart() {
return fSeqNumber;
}
public int getSequenceEnd() {
return fSeqEndNumber;
}
public T getBestNode() {
return fBestNode;
}
public boolean requiresClass(Class<? extends IASTNode> clazz) {
return clazz.isAssignableFrom(fClass);
}
@SuppressWarnings("unchecked")
public void visit(ASTNode astNode) {
if (isAcceptableNode(astNode) && isMatchingRange(astNode.getOffset(), astNode.getLength(), fSeqNumber, fSeqEndNumber)) {
IASTFileLocation loc= astNode.getFileLocation();
if (loc != null) {
storeIfBest(loc, (T) astNode);
}
}
}
@SuppressWarnings("unchecked")
public void visit(ASTNode astNode, IASTImageLocation imageLocation) {
if (isAcceptableNode(astNode) && imageLocation != null) {
if (isMatchingRange(imageLocation.getNodeOffset(), imageLocation.getNodeLength(), fFileOffset, fFileEndOffset)) {
storeIfBest(imageLocation, (T) astNode);
}
}
}
private boolean isMatchingRange(int offset, int length, int selOffset, int selEndOffset) {
final int endOffset= offset+length;
switch(fRelation) {
case EXACT_MATCH:
return selOffset == offset && selEndOffset == endOffset;
case FIRST_CONTAINED:
return selOffset <= offset && endOffset <= selEndOffset;
case ENCLOSING:
return offset <= selOffset && selEndOffset <= endOffset;
default:
assert false;
return false;
}
}
public boolean isAcceptableNode(IASTNode astNode) {
return astNode != null && fClass.isAssignableFrom(astNode.getClass());
}
/**
* Returns whether the node can contain matches in its range.
*/
public boolean canContainMatches(ASTNode node) {
final int offset= node.getOffset();
final int endOffset= offset+node.getLength();
switch(fRelation) {
case EXACT_MATCH:
case ENCLOSING:
return offset <= fSeqNumber && fSeqEndNumber <= endOffset;
case FIRST_CONTAINED:
return offset <= fSeqEndNumber && fSeqNumber <= endOffset;
default:
assert false;
return false;
}
}
private void storeIfBest(IASTFileLocation loc, T astNode) {
if (loc != null) {
final int offset = loc.getNodeOffset();
final int length = loc.getNodeLength();
if (isBetterMatch(offset, length, astNode)) {
fBestNode= astNode;
fBestOffset= offset;
fBestEndOffset= offset+length;
}
}
}
/**
* Assuming that the given range matches, this method returns whether the match is better
* than the best match stored.
*/
private boolean isBetterMatch(int offset, int length, IASTNode cand) {
if (fBestNode == null) {
return true;
}
final int endOffset= offset+length;
switch(fRelation) {
case EXACT_MATCH:
return !isParent(cand, fBestNode);
case FIRST_CONTAINED:
if (offset < fBestOffset) {
return true;
}
if (offset == fBestOffset) {
if (endOffset < fBestEndOffset) {
return true;
}
return endOffset == fBestEndOffset && !isParent(cand, fBestNode);
}
return false;
case ENCLOSING:
final int bestLength= fBestEndOffset-fBestOffset;
if (length < bestLength) {
return true;
}
return length == bestLength && !isParent(cand, fBestNode);
default:
assert false;
return false;
}
}
private boolean isParent(IASTNode cand1, IASTNode cand2) {
while(cand2 != null) {
if (cand2 == cand1) {
return true;
}
cand2= cand2.getParent();
}
return false;
}
}

View file

@ -38,16 +38,15 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisitor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
/**
* Visitor to search for nodes by file offsets.
* @since 5.0
*/
public class FindNodeForOffsetAction extends CPPASTVisitor implements ICASTVisitor, ICPPASTVisitor {
private ASTNode fCandidate= null;
private final int fOffset;
private final int fLength;
private final ASTNodeMatchKind fMatchKind;
private final ASTNodeSpecification<?> fNodeSpec;
public FindNodeForOffsetAction(int offset, int length, ASTNodeMatchKind matchKind) {
fMatchKind= matchKind;
fOffset = offset;
fLength = length;
public FindNodeForOffsetAction(ASTNodeSpecification<?> nodeSpec) {
fNodeSpec= nodeSpec;
shouldVisitNames = true;
shouldVisitDeclarations= true;
@ -65,21 +64,16 @@ public class FindNodeForOffsetAction extends CPPASTVisitor implements ICASTVisit
shouldVisitBaseSpecifiers=
shouldVisitNamespaces=
shouldVisitTemplateParameters=
shouldVisitTranslationUnit= !matchKind.matchNamesOnly();
shouldVisitTranslationUnit= !nodeSpec.requiresClass(IASTName.class);
}
public int processNode(IASTNode node) {
if (node instanceof ASTNode) {
final ASTNode astNode = (ASTNode) node;
if (astNode.getOffset() > fOffset+fLength || astNode.getOffset() + astNode.getLength() < fOffset) {
if (!fNodeSpec.canContainMatches(astNode)) {
return PROCESS_SKIP;
}
if (fMatchKind.matches(astNode, fOffset, fLength)) {
if (fCandidate == null || !fMatchKind.isBetterMatch(fCandidate, astNode)) {
fCandidate= astNode;
}
}
fNodeSpec.visit(astNode);
}
return PROCESS_CONTINUE;
}
@ -88,7 +82,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 + fLength)
if (declaration instanceof ASTNode && ((ASTNode) declaration).getOffset() > fNodeSpec.getSequenceEnd())
return PROCESS_ABORT;
return processNode(declaration);
@ -204,8 +198,4 @@ public class FindNodeForOffsetAction extends CPPASTVisitor implements ICASTVisit
public int visit(IASTTranslationUnit tu) {
return processNode(tu);
}
public ASTNode getNode() {
return fCandidate;
}
}

View file

@ -18,7 +18,6 @@ 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;
@ -127,8 +126,8 @@ class ASTBuiltinName extends ASTPreprocessorDefinition {
class ASTMacroReferenceName extends ASTPreprocessorName {
private ImageLocationInfo fImageLocationInfo;
public ASTMacroReferenceName(IASTPreprocessorMacroExpansion parent, int offset, int endOffset, IMacroBinding macro, ImageLocationInfo imgLocationInfo) {
super(parent, IASTPreprocessorMacroExpansion.EXPANSION_NAME, offset, endOffset, macro.getNameCharArray(), macro);
public ASTMacroReferenceName(IASTNode parent, ASTNodeProperty property, int offset, int endOffset, IMacroBinding macro, ImageLocationInfo imgLocationInfo) {
super(parent, property, offset, endOffset, macro.getNameCharArray(), macro);
fImageLocationInfo= imgLocationInfo;
}

View file

@ -34,6 +34,7 @@ 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.IASTPreprocessorStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorUndefStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding;
@ -42,8 +43,7 @@ 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;
import org.eclipse.cdt.internal.core.dom.parser.ASTNodeSpecification;
/**
* Models various AST-constructs obtained from the preprocessor.
@ -72,36 +72,10 @@ abstract class ASTPreprocessorNode extends ASTNode {
}
/**
* Returns a matching node or null.
* Searches nodes by file location.
*/
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;
void findNode(ASTNodeSpecification<?> nodeSpec) {
nodeSpec.visit(this);
}
}
@ -174,14 +148,35 @@ class ASTElse extends ASTPreprocessorNode implements IASTPreprocessorElseStateme
}
class ASTIfndef extends ASTDirectiveWithCondition implements IASTPreprocessorIfndefStatement {
public ASTIfndef(IASTTranslationUnit parent, int startNumber, int condNumber, int condEndNumber, boolean active) {
super(parent, startNumber, condNumber, condEndNumber, active);
private ASTMacroReferenceName fMacroRef;
public ASTIfndef(IASTTranslationUnit parent, int startNumber, int condNumber, int condEndNumber, boolean taken, IMacroBinding macro) {
super(parent, startNumber, condNumber, condEndNumber, taken);
if (macro != null) {
fMacroRef= new ASTMacroReferenceName(this, IASTPreprocessorStatement.MACRO_NAME, condNumber, condEndNumber, macro, null);
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTPreprocessorIfdefStatement#getMacroReference()
*/
public ASTPreprocessorName getMacroReference() {
return fMacroRef;
}
}
class ASTIfdef extends ASTDirectiveWithCondition implements IASTPreprocessorIfdefStatement {
public ASTIfdef(IASTTranslationUnit parent, int startNumber, int condNumber, int condEndNumber, boolean active) {
super(parent, startNumber, condNumber, condEndNumber, active);
ASTMacroReferenceName fMacroRef;
public ASTIfdef(IASTTranslationUnit parent, int startNumber, int condNumber, int condEndNumber, boolean taken, IMacroBinding macro) {
super(parent, startNumber, condNumber, condEndNumber, taken);
if (macro != null) {
fMacroRef= new ASTMacroReferenceName(this, IASTPreprocessorStatement.MACRO_NAME, condNumber, condEndNumber, macro, null);
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTPreprocessorIfdefStatement#getMacroReference()
*/
public ASTPreprocessorName getMacroReference() {
return fMacroRef;
}
}
@ -250,8 +245,9 @@ class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreproces
}
@Override
ASTNode findNode(int sequenceNumber, int length, ASTNodeMatchKind matchKind) {
return findNode(sequenceNumber, length, fName, matchKind);
void findNode(ASTNodeSpecification<?> nodeSpec) {
super.findNode(nodeSpec);
nodeSpec.visit(fName);
}
}
@ -308,8 +304,9 @@ class ASTMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessor
}
@Override
ASTNode findNode(int sequenceNumber, int length, ASTNodeMatchKind matchKind) {
return findNode(sequenceNumber, length, fName, matchKind);
void findNode(ASTNodeSpecification<?> nodeSpec) {
super.findNode(nodeSpec);
nodeSpec.visit(fName);
}
public void setExpansion(String exp) {assert false;}
@ -410,17 +407,12 @@ class ASTUndef extends ASTPreprocessorNode implements IASTPreprocessorUndefState
private final ASTPreprocessorName fName;
public ASTUndef(IASTTranslationUnit parent, char[] name, int startNumber, int nameNumber, int nameEndNumber, IBinding binding) {
super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, startNumber, nameEndNumber);
fName= new ASTPreprocessorName(this, IASTPreprocessorUndefStatement.MACRO_NAME, nameNumber, nameEndNumber, name, binding);
fName= new ASTPreprocessorName(this, IASTPreprocessorStatement.MACRO_NAME, nameNumber, nameEndNumber, name, binding);
}
public ASTPreprocessorName getMacroName() {
return fName;
}
@Override
ASTNode findNode(int sequenceNumber, int length, ASTNodeMatchKind matchKind) {
return findNode(sequenceNumber, length, fName, matchKind);
}
}
class ASTInclusionNode implements IASTInclusionNode {
@ -546,9 +538,13 @@ class ASTMacroExpansion extends ASTPreprocessorNode implements IASTPreprocessorM
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion#getNestedExpansions()
*/
public IASTName[] getNestedMacroReferences() {
public ASTPreprocessorName[] getNestedMacroReferences() {
return fContext.getNestedMacroReferences();
}
public LocationCtxMacroExpansion getContext() {
return fContext;
}
}
@SuppressWarnings("deprecation")

View file

@ -883,7 +883,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
condEndOffset= lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
int endOffset= lexer.currentToken().getEndOffset();
if (fCurrentContext.changeBranch(ScannerContext.BRANCH_ELIF)) {
fLocationMap.encounterPoundElif(startOffset, condOffset, condEndOffset, endOffset, false);
fLocationMap.encounterPoundElif(startOffset, condOffset, condEndOffset, endOffset, false, IASTName.EMPTY_NAME_ARRAY);
skipOverConditionalCode(lexer, false);
}
else {
@ -1132,17 +1132,18 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
final int endOffset= lexer.currentToken().getEndOffset();
final char[] namechars= name.getCharImage();
boolean isActive= (fMacroDictionary.get(namechars) != null) == positive;
PreprocessorMacro macro= fMacroDictionary.get(namechars);
boolean isActive= (macro != null) == positive;
fCurrentContext.changeBranch(ScannerContext.BRANCH_IF);
if (positive) {
fLocationMap.encounterPoundIfdef(startOffset, name.getOffset(), name.getEndOffset(), endOffset, isActive);
fLocationMap.encounterPoundIfdef(startOffset, name.getOffset(), name.getEndOffset(), endOffset, isActive, macro);
}
else {
fLocationMap.encounterPoundIfndef(startOffset, name.getOffset(), name.getEndOffset(), endOffset, isActive);
fLocationMap.encounterPoundIfndef(startOffset, name.getOffset(), name.getEndOffset(), endOffset, isActive, macro);
}
if (!isActive) {
if ((macro == null) == positive) {
skipOverConditionalCode(lexer, true);
}
}
@ -1154,19 +1155,20 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
final int condEndOffset= getTokensWithinPPDirective(lexer, true, condition);
final int endOffset= lexer.currentToken().getEndOffset();
fExpressionEvaluator.clearMacrosInDefinedExpression();
if (condition.first() == null) {
handleProblem(IProblem.SCANNER_EXPRESSION_SYNTAX_ERROR, null, startOffset, endOffset);
}
else {
try {
isActive= fExpressionEvaluator.evaluate(condition, fMacroDictionary);
isActive= fExpressionEvaluator.evaluate(condition, fMacroDictionary, fLocationMap);
} catch (EvalException e) {
handleProblem(e.getProblemID(), e.getProblemArg(), condOffset, endOffset);
}
}
fCurrentContext.changeBranch(ScannerContext.BRANCH_IF);
fLocationMap.encounterPoundIf(startOffset, condOffset, condEndOffset, endOffset, isActive);
fLocationMap.encounterPoundIf(startOffset, condOffset, condEndOffset, endOffset, isActive, fExpressionEvaluator.clearMacrosInDefinedExpression());
if (!isActive) {
skipOverConditionalCode(lexer, true);
@ -1247,21 +1249,21 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
int endOffset= lexer.currentToken().getEndOffset();
nesting++;
fCurrentContext.changeBranch(ScannerContext.BRANCH_IF);
fLocationMap.encounterPoundIfdef(pound.getOffset(), ident.getOffset(), ident.getEndOffset(), endOffset, false);
fLocationMap.encounterPoundIfdef(pound.getOffset(), ident.getOffset(), ident.getEndOffset(), endOffset, false, null);
break;
case IPreprocessorDirective.ppIfndef:
lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
endOffset= lexer.currentToken().getEndOffset();
nesting++;
fCurrentContext.changeBranch(ScannerContext.BRANCH_IF);
fLocationMap.encounterPoundIfndef(pound.getOffset(), ident.getOffset(), ident.getEndOffset(), endOffset, false);
fLocationMap.encounterPoundIfndef(pound.getOffset(), ident.getOffset(), ident.getEndOffset(), endOffset, false, null);
break;
case IPreprocessorDirective.ppIf:
int condEndOffset= lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
endOffset= lexer.currentToken().getEndOffset();
nesting++;
fCurrentContext.changeBranch(ScannerContext.BRANCH_IF);
fLocationMap.encounterPoundIf(pound.getOffset(), ident.getOffset(), condEndOffset, endOffset, false);
fLocationMap.encounterPoundIf(pound.getOffset(), ident.getOffset(), condEndOffset, endOffset, false, IASTName.EMPTY_NAME_ARRAY);
break;
case IPreprocessorDirective.ppElse:
lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
@ -1279,13 +1281,14 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
case IPreprocessorDirective.ppElif:
if (fCurrentContext.changeBranch(ScannerContext.BRANCH_ELIF)) {
boolean isActive= false;
fExpressionEvaluator.clearMacrosInDefinedExpression();
int condOffset= lexer.nextToken().getOffset();
if (nesting == 0 && takeElseBranch) {
TokenList condition= new TokenList();
condEndOffset= getTokensWithinPPDirective(lexer, true, condition);
if (condition.first() != null) {
try {
isActive= fExpressionEvaluator.evaluate(condition, fMacroDictionary);
isActive= fExpressionEvaluator.evaluate(condition, fMacroDictionary, fLocationMap);
} catch (EvalException e) {
handleProblem(e.getProblemID(), e.getProblemArg(), condOffset, condEndOffset);
}
@ -1296,7 +1299,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
}
endOffset= lexer.currentToken().getEndOffset();
fCurrentContext.changeBranch(ScannerContext.BRANCH_ELIF);
fLocationMap.encounterPoundElif(pound.getOffset(), condOffset, condEndOffset, endOffset, isActive);
fLocationMap.encounterPoundElif(pound.getOffset(), condOffset, condEndOffset, endOffset, isActive, fExpressionEvaluator.clearMacrosInDefinedExpression());
if (isActive) {
return;

View file

@ -13,6 +13,9 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
import java.util.ArrayList;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.parser.IProblem;
import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.core.parser.util.CharArrayMap;
@ -41,13 +44,22 @@ class ExpressionEvaluator {
private Token fTokens;
private CharArrayMap<PreprocessorMacro> fDictionary;
private ArrayList<IASTName> fMacrosInDefinedExpressions= new ArrayList<IASTName>();
private LocationMap fLocationMap;
public boolean evaluate(TokenList condition, CharArrayMap<PreprocessorMacro> macroDictionary) throws EvalException {
public boolean evaluate(TokenList condition, CharArrayMap<PreprocessorMacro> macroDictionary, LocationMap map) throws EvalException {
fTokens= condition.first();
fDictionary= macroDictionary;
fLocationMap= map;
fMacrosInDefinedExpressions.clear();
return expression() != 0;
}
public IASTName[] clearMacrosInDefinedExpression() {
IASTName[] result= fMacrosInDefinedExpressions.toArray(new IASTName[fMacrosInDefinedExpressions.size()]);
fMacrosInDefinedExpressions.clear();
return result;
}
private long expression() throws EvalException {
return conditionalExpression();
@ -254,7 +266,11 @@ class ExpressionEvaluator {
if (LA() != IToken.tIDENTIFIER) {
throw new EvalException(IProblem.SCANNER_ILLEGAL_IDENTIFIER, null);
}
int result= fDictionary.containsKey(fTokens.getCharImage()) ? 1 : 0;
PreprocessorMacro macro= fDictionary.get(fTokens.getCharImage());
if (macro != null) {
fMacrosInDefinedExpressions.add(fLocationMap.encounterDefinedExpression(macro, fTokens.getOffset(), fTokens.getEndOffset()));
}
int result= macro != null ? 1 : 0;
consume();
if (parenthesis) {
if (LA() != IToken.tRPAREN) {

View file

@ -32,22 +32,21 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisitor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ASTNodeMatchKind;
import org.eclipse.cdt.internal.core.dom.parser.ASTNodeSpecification;
/**
* Visitor to select nodes by image-location.
* @since 5.0
*/
public class FindNodeByImageLocation extends CPPASTVisitor implements ICASTVisitor, ICPPASTVisitor {
private ASTNode fCandidate= null;
private final int fOffset;
private final int fLength;
private final ASTNodeMatchKind fMatchKind;
private int fImageOffset;
private int fImageLength;
private final ASTNodeSpecification<?> fNodeSpec;
public FindNodeByImageLocation(int offset, int length, int imgOffset, int imgLength, ASTNodeMatchKind matchKind) {
fMatchKind= matchKind;
public FindNodeByImageLocation(int offset, int length, ASTNodeSpecification<?> nodeSpec) {
fNodeSpec= nodeSpec;
fOffset = offset;
fLength = length;
fImageOffset= imgOffset;
fImageLength= imgLength;
shouldVisitNames = true;
shouldVisitDeclarations= true;
@ -65,7 +64,7 @@ public class FindNodeByImageLocation extends CPPASTVisitor implements ICASTVisit
shouldVisitBaseSpecifiers=
shouldVisitNamespaces=
shouldVisitTemplateParameters=
shouldVisitTranslationUnit= !matchKind.matchNamesOnly();
shouldVisitTranslationUnit= !nodeSpec.requiresClass(IASTName.class);
}
public int processNode(IASTNode node) {
@ -75,14 +74,10 @@ public class FindNodeByImageLocation extends CPPASTVisitor implements ICASTVisit
return PROCESS_SKIP;
}
if (fMatchKind.isAcceptableNode(astNode)) {
if (fNodeSpec.isAcceptableNode(astNode)) {
IASTImageLocation imageLocation= astNode.getImageLocation();
if (imageLocation != null && imageLocation.getLocationKind() == IASTImageLocation.ARGUMENT_TO_MACRO_EXPANSION) {
if (fMatchKind.rangeMatches(imageLocation.getNodeOffset(), imageLocation.getNodeLength(), fImageOffset, fImageLength)) {
if (fCandidate == null || !fMatchKind.isBetterMatch(fCandidate, astNode)) {
fCandidate= astNode;
}
}
fNodeSpec.visit(astNode, imageLocation);
}
}
}
@ -184,8 +179,4 @@ public class FindNodeByImageLocation extends CPPASTVisitor implements ICASTVisit
public int visit(IASTTranslationUnit tu) {
return processNode(tu);
}
public ASTNode getNode() {
return fCandidate;
}
}

View file

@ -24,8 +24,7 @@ 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;
import org.eclipse.cdt.internal.core.dom.parser.ASTNodeSpecification;
/**
@ -136,16 +135,13 @@ public interface ILocationResolver {
char[] getUnpreprocessedSignature(IASTFileLocation loc);
/**
* Returns a preprocessor node surrounding the given range, or <code>null</code>. The result is either a
* preprocessing directive ({@link IASTPreprocessorStatement}) or a name contained therein {@link IASTName} or
* a macro expansion ({@link IASTName}).
* Searches for a preprocessor node matching the given specification. Candidates are passed to
* nodeSpec, which selects and stores the best result.
*
* @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.
* @param nodeSpec specification of node to search for.
*/
ASTNode findPreprocessorNode(int sequenceNumber, int length, ASTNodeMatchKind matchOption);
void findPreprocessorNode(ASTNodeSpecification<?> nodeSpec);
/**
* Returns whether the specified sequence number points into the root file of the
* translation unit, or not.

View file

@ -94,7 +94,7 @@ abstract class LocationCtx implements ILocationCtx {
/**
* Returns the macro-expansion surrounding or augmenting the given range, or <code>null</code>.
*/
public LocationCtxMacroExpansion findSurroundingMacroExpansion(int sequenceNumber, int length) {
public LocationCtxMacroExpansion findEnclosingMacroExpansion(int sequenceNumber, int length) {
return null;
}

View file

@ -101,11 +101,11 @@ class LocationCtxContainer extends LocationCtx {
}
@Override
public final LocationCtxMacroExpansion findSurroundingMacroExpansion(int sequenceNumber, int length) {
public final LocationCtxMacroExpansion findEnclosingMacroExpansion(int sequenceNumber, int length) {
int testEnd= length > 1 ? sequenceNumber+length-1 : sequenceNumber;
final LocationCtx child= findChildLessOrEqualThan(sequenceNumber, true);
if (child != null && child.fSequenceNumber+child.getSequenceLength() > testEnd) {
return child.findSurroundingMacroExpansion(sequenceNumber, length);
return child.findEnclosingMacroExpansion(sequenceNumber, length);
}
return null;
}

View file

@ -16,9 +16,6 @@ import org.eclipse.cdt.core.dom.ast.IASTImageLocation;
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.
@ -74,7 +71,7 @@ class LocationCtxMacroExpansion extends LocationCtx {
}
@Override
public LocationCtxMacroExpansion findSurroundingMacroExpansion(int sequenceNumber, int length) {
public LocationCtxMacroExpansion findEnclosingMacroExpansion(int sequenceNumber, int length) {
return this;
}
@ -109,26 +106,6 @@ 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 ASTPreprocessorName[] getNestedMacroReferences() {
return fLocationMap.getNestedMacroReferences((ASTMacroExpansion) fExpansionName.getParent());
}

View file

@ -20,6 +20,7 @@ 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.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;
@ -31,10 +32,8 @@ 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.ASTNodeSpecification;
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
@ -138,9 +137,20 @@ 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(null, 0, 0, macro, imageLocationInfo);
return new ASTMacroReferenceName(null, IASTPreprocessorMacroExpansion.NESTED_EXPANSION_NAME, 0, 0, macro, imageLocationInfo);
}
/**
* Creates a name representing a macro in a defined-expression. The returned name can be fed into
* {@link #encounterPoundIf(int, int, int, int, boolean, IASTName[])}.
*/
public IASTName encounterDefinedExpression(IMacroBinding macro, int startOffset, int endOffset) {
int startNumber= getSequenceNumberForOffset(startOffset);
int endNumber= getSequenceNumberForOffset(endOffset);
return new ASTMacroReferenceName(null, IASTPreprocessorStatement.MACRO_NAME, startNumber, endNumber, macro, null);
}
/**
* Creates a new context for the result of a (recursive) macro-expansion.
* @param nameOffset offset within the current context where the name for the macro-expansion starts.
@ -160,14 +170,14 @@ public class LocationMap implements ILocationResolver {
final int length= endNumber-nameNumber;
ASTMacroExpansion expansion= new ASTMacroExpansion(fTranslationUnit, nameNumber, endNumber);
ASTMacroReferenceName explicitRef= new ASTMacroReferenceName(expansion, nameNumber, nameEndNumber, macro, null);
ASTMacroReferenceName explicitRef= new ASTMacroReferenceName(expansion, IASTPreprocessorMacroExpansion.EXPANSION_NAME, nameNumber, nameEndNumber, macro, null);
addMacroReference(explicitRef);
for (int i = 0; i < implicitMacroReferences.length; i++) {
ASTMacroReferenceName name = (ASTMacroReferenceName) implicitMacroReferences[i];
name.setParent(expansion);
name.setOffsetAndLength(nameNumber, length);
addMacroReference(name);
}
addMacroReference(explicitRef);
LocationCtxMacroExpansion expansionCtx= new LocationCtxMacroExpansion(this, (LocationCtxContainer) fCurrentContext, nameOffset, endOffset, endNumber, contextLength, imageLocations, explicitRef);
expansion.setContext(expansionCtx);
@ -177,7 +187,9 @@ public class LocationMap implements ILocationResolver {
}
private void addMacroReference(ASTPreprocessorName name) {
fMacroReferences.add(name);
if (name != null) {
fMacroReferences.add(name);
}
}
/**
@ -233,12 +245,22 @@ public class LocationMap implements ILocationResolver {
fDirectives.add(new ASTElse(fTranslationUnit, startOffset, endOffset, isActive));
}
public void encounterPoundElif(int startOffset, int condOffset, int condEndOffset, int endOffset, boolean isActive) {
public void encounterPoundElif(int startOffset, int condOffset, int condEndOffset, int endOffset, boolean isActive,
IASTName[] macrosInDefinedExpression) {
startOffset= getSequenceNumberForOffset(startOffset);
condOffset= getSequenceNumberForOffset(condOffset);
condEndOffset= getSequenceNumberForOffset(condEndOffset);
// compatible with 4.0: endOffset= getSequenceNumberForOffset(endOffset);
fDirectives.add(new ASTElif(fTranslationUnit, startOffset, condOffset, condEndOffset, isActive));
final ASTElif elif = new ASTElif(fTranslationUnit, startOffset, condOffset, condEndOffset, isActive);
fDirectives.add(elif);
for (int i = 0; i < macrosInDefinedExpression.length; i++) {
ASTMacroReferenceName name = (ASTMacroReferenceName) macrosInDefinedExpression[i];
name.setParent(elif);
name.setPropertyInParent(IASTPreprocessorStatement.MACRO_NAME);
addMacroReference(name);
}
}
public void encounterPoundEndIf(int startOffset, int endOffset) {
@ -263,30 +285,42 @@ public class LocationMap implements ILocationResolver {
fDirectives.add(new ASTPragma(fTranslationUnit, startOffset, condOffset, condEndOffset));
}
public void encounterPoundIfdef(int startOffset, int condOffset, int condEndOffset, int endOffset, boolean isActive) {
public void encounterPoundIfdef(int startOffset, int condOffset, int condEndOffset, int endOffset, boolean taken, IMacroBinding macro) {
startOffset= getSequenceNumberForOffset(startOffset);
condOffset= getSequenceNumberForOffset(condOffset);
condEndOffset= getSequenceNumberForOffset(condEndOffset);
// not using endOffset, compatible with 4.0: endOffset= getSequenceNumberForOffset(endOffset);
fDirectives.add(new ASTIfdef(fTranslationUnit, startOffset, condOffset, condEndOffset, isActive));
final ASTIfdef ifdef = new ASTIfdef(fTranslationUnit, startOffset, condOffset, condEndOffset, taken, macro);
fDirectives.add(ifdef);
addMacroReference(ifdef.getMacroReference());
}
public void encounterPoundIfndef(int startOffset, int condOffset, int condEndOffset, int endOffset, boolean isActive) {
public void encounterPoundIfndef(int startOffset, int condOffset, int condEndOffset, int endOffset, boolean taken, IMacroBinding macro) {
startOffset= getSequenceNumberForOffset(startOffset);
condOffset= getSequenceNumberForOffset(condOffset);
condEndOffset= getSequenceNumberForOffset(condEndOffset);
// not using endOffset, compatible with 4.0: endOffset= getSequenceNumberForOffset(endOffset);
fDirectives.add(new ASTIfndef(fTranslationUnit, startOffset, condOffset, condEndOffset, isActive));
final ASTIfndef ifndef = new ASTIfndef(fTranslationUnit, startOffset, condOffset, condEndOffset, taken, macro);
fDirectives.add(ifndef);
addMacroReference(ifndef.getMacroReference());
}
public void encounterPoundIf(int startOffset, int condOffset, int condEndOffset, int endOffset, boolean isActive) {
public void encounterPoundIf(int startOffset, int condOffset, int condEndOffset, int endOffset, boolean isActive,
IASTName[] macrosInDefinedExpression) {
startOffset= getSequenceNumberForOffset(startOffset);
condOffset= getSequenceNumberForOffset(condOffset);
condEndOffset= getSequenceNumberForOffset(condEndOffset);
// not using endOffset, compatible with 4.0: endOffset= getSequenceNumberForOffset(endOffset);
fDirectives.add(new ASTIf(fTranslationUnit, startOffset, condOffset, condEndOffset, isActive));
final ASTIf astif = new ASTIf(fTranslationUnit, startOffset, condOffset, condEndOffset, isActive);
fDirectives.add(astif);
for (int i = 0; i < macrosInDefinedExpression.length; i++) {
ASTMacroReferenceName name = (ASTMacroReferenceName) macrosInDefinedExpression[i];
name.setParent(astif);
name.setPropertyInParent(IASTPreprocessorStatement.MACRO_NAME);
addMacroReference(name);
}
}
public void encounterPoundDefine(int startOffset, int nameOffset, int nameEndOffset, int expansionOffset, int endOffset, IMacroBinding macrodef) {
startOffset= getSequenceNumberForOffset(startOffset);
nameOffset= getSequenceNumberForOffset(nameOffset);
@ -434,59 +468,93 @@ public class LocationMap implements ILocationResolver {
return null;
}
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 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;
public void findPreprocessorNode(ASTNodeSpecification<?> nodeSpec) {
final int sequenceStart= nodeSpec.getSequenceStart();
final int sequenceEnd= nodeSpec.getSequenceEnd();
// check directives
int from= findLastNodeBefore(fDirectives, sequenceStart);
for (int i= from+1; i < fDirectives.size(); i++) {
ASTPreprocessorNode directive= fDirectives.get(i);
if (directive.getOffset() > sequenceEnd) {
break;
}
directive.findNode(nodeSpec);
}
// search for a macro-expansion
LocationCtxMacroExpansion ctx= fRootContext.findSurroundingMacroExpansion(sequenceNumber, length);
if (ctx != null) {
ASTNode candidate= ctx.findNode(sequenceNumber, length, matchKind);
int imageOffset= ctx.fEndOffsetInParent + sequenceNumber - ctx.fSequenceNumber;
if (fTranslationUnit != null) {
FindNodeByImageLocation visitor= new FindNodeByImageLocation(ctx.fSequenceNumber, ctx.getSequenceLength(), imageOffset, length, matchKind);
fTranslationUnit.accept(visitor);
ASTNode candidate2= visitor.getNode();
if (matchKind.isBetterMatch(candidate2, candidate)) {
candidate= candidate2;
}
// check macro references and expansions
from= findLastMacroReferenceBefore(fMacroReferences, sequenceStart);
for (int i= from+1; i < fMacroReferences.size(); i++) {
ASTPreprocessorNode macroRef= fMacroReferences.get(i);
if (macroRef.getOffset() > sequenceEnd) {
break;
}
ASTPreprocessorName[] nested= ctx.getNestedMacroReferences();
for (ASTPreprocessorName name : nested) {
IASTImageLocation imageLoc= name.getImageLocation();
if (imageLoc != null && imageLoc.getLocationKind() == IASTImageLocation.ARGUMENT_TO_MACRO_EXPANSION) {
if (matchKind.rangeMatches(imageLoc.getNodeOffset(), imageLoc.getNodeLength(), imageOffset, length)) {
if (matchKind.isBetterMatch(name, candidate)) {
candidate= name;
if (macroRef.getPropertyInParent() == IASTPreprocessorMacroExpansion.NESTED_EXPANSION_NAME) {
continue;
}
nodeSpec.visit(macroRef);
IASTNode parent= macroRef.getParent();
if (parent instanceof ASTMacroExpansion) {
ASTMacroExpansion expansion= (ASTMacroExpansion) parent;
assert expansion.getMacroReference() == macroRef;
if (nodeSpec.canContainMatches(expansion)) {
nodeSpec.visit(expansion);
if (!nodeSpec.requiresClass(IASTPreprocessorMacroExpansion.class)) {
LocationCtxMacroExpansion ctx= expansion.getContext();
if (fTranslationUnit != null) {
FindNodeByImageLocation visitor= new FindNodeByImageLocation(ctx.fSequenceNumber, ctx.getSequenceLength(), nodeSpec);
fTranslationUnit.accept(visitor);
}
ASTPreprocessorName[] nestedMacros= expansion.getNestedMacroReferences();
for (ASTPreprocessorName nested : nestedMacros) {
IASTImageLocation imgLoc= nested.getImageLocation();
if (imgLoc != null && imgLoc.getLocationKind() == IASTImageLocation.ARGUMENT_TO_MACRO_EXPANSION) {
nodeSpec.visit(nested, imgLoc);
}
}
}
}
}
return candidate;
}
return null;
}
private int findLastNodeBefore(ArrayList<? extends ASTPreprocessorNode> nodes, int sequenceStart) {
int lower=-1;
int upper= nodes.size()-1;
while(lower < upper) {
int middle= (lower+upper+1)/2;
ASTPreprocessorNode candidate= nodes.get(middle);
if (candidate.getOffset() + candidate.getLength() >= sequenceStart) {
upper= middle-1;
}
else {
lower= middle;
}
}
return lower;
}
private int findLastMacroReferenceBefore(ArrayList<? extends ASTPreprocessorName> nodes, int sequenceStart) {
int lower=-1;
int upper= nodes.size()-1;
while(lower < upper) {
int middle= (lower+upper+1)/2;
ASTPreprocessorNode candidate= nodes.get(middle);
IASTNode parent= candidate.getParent();
if (parent instanceof ASTMacroExpansion) {
candidate= (ASTMacroExpansion) parent;
}
if (candidate.getOffset() + candidate.getLength() >= sequenceStart) {
upper= middle-1;
}
else {
lower= middle;
}
}
return lower;
}
public int getSequenceNumberForFileOffset(String filePath, int fileOffset) {
LocationCtx ctx= fRootContext;
if (filePath != null) {

View file

@ -1073,4 +1073,29 @@ public abstract class CPPSelectionTestsAnyIndexer extends BaseSelectionTestsInde
input = part.getEditorInput();
assertEquals("s.c", ((FileEditorInput)input).getFile().getName());
}
// #define ADD_TEXT(txt1,txt2) txt1" "txt2
// #define ADD(a,b) (a + b)
// void main(void) {
// #if defined(ADD_TEXT) && defined(ADD)
// #endif
// }
public void testNavigationInDefinedExpression_215906() throws Exception {
StringBuffer[] buffers= getContents(1);
String code= buffers[0].toString();
IFile file = importFile("s.cpp", code);
TestSourceReader.waitUntilFileIsIndexed(index, file, MAX_WAIT_TIME);
IASTNode decl;
int offset1, offset2;
offset1 = code.indexOf("ADD_TEXT");
offset2 = code.indexOf("ADD_TEXT", offset1+1);
decl= testF3(file, offset2);
assertNode("ADD_TEXT", offset1, decl);
offset1 = code.indexOf("ADD", offset1+1);
offset2 = code.indexOf("ADD", offset2+1);
decl= testF3(file, offset2);
assertNode("ADD", offset1, decl);
}
}

View file

@ -299,6 +299,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
super(parent, verticalRuler, overviewRuler, showAnnotationsOverview, styles, store);
}
@Override
public IContentAssistant getContentAssistant() {
return fContentAssistant;
}
@ -306,6 +307,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/*
* @see ITextOperationTarget#doOperation(int)
*/
@Override
public void doOperation(int operation) {
if (getTextWidget() == null)
@ -332,6 +334,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/*
* @see IWidgetTokenOwner#requestWidgetToken(IWidgetTokenKeeper)
*/
@Override
public boolean requestWidgetToken(IWidgetTokenKeeper requester) {
if (PlatformUI.getWorkbench().getHelpSystem().isContextHelpDisplayed())
return false;
@ -342,6 +345,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
* @see IWidgetTokenOwnerExtension#requestWidgetToken(IWidgetTokenKeeper, int)
* @since 3.0
*/
@Override
public boolean requestWidgetToken(IWidgetTokenKeeper requester, int priority) {
if (PlatformUI.getWorkbench().getHelpSystem().isContextHelpDisplayed())
return false;
@ -352,6 +356,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
* @see org.eclipse.jface.text.source.SourceViewer#createFormattingContext()
* @since 3.0
*/
@Override
public IFormattingContext createFormattingContext() {
IFormattingContext context= new FormattingContext();
@ -796,6 +801,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/*
* @see org.eclipse.jface.action.IAction#run()
*/
@Override
public void run() {
// Check whether sub word navigation is enabled.
final IPreferenceStore store = getPreferenceStore();
@ -861,6 +867,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/*
* @see org.eclipse.cdt.internal.ui.editor.CEditor.NextSubWordAction#setCaretPosition(int)
*/
@Override
protected void setCaretPosition(final int position) {
getTextWidget().setCaretOffset(modelOffset2WidgetOffset(getSourceViewer(), position));
}
@ -883,6 +890,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/*
* @see org.eclipse.cdt.internal.ui.editor.CEditor.NextSubWordAction#setCaretPosition(int)
*/
@Override
protected void setCaretPosition(final int position) {
if (!validateEditorInputState())
return;
@ -908,6 +916,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/*
* @see org.eclipse.cdt.internal.ui.editor.CEditor.NextSubWordAction#findNextPosition(int)
*/
@Override
protected int findNextPosition(int position) {
return fIterator.following(position);
}
@ -937,6 +946,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/*
* @see org.eclipse.cdt.internal.ui.editor.CEditor.NextSubWordAction#setCaretPosition(int)
*/
@Override
protected void setCaretPosition(final int position) {
final ISourceViewer viewer = getSourceViewer();
@ -976,6 +986,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/*
* @see org.eclipse.jface.action.IAction#run()
*/
@Override
public void run() {
// Check whether sub word navigation is enabled.
final IPreferenceStore store = getPreferenceStore();
@ -1041,6 +1052,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/*
* @see org.eclipse.cdt.internal.ui.editor.CEditor.PreviousSubWordAction#setCaretPosition(int)
*/
@Override
protected void setCaretPosition(final int position) {
getTextWidget().setCaretOffset(modelOffset2WidgetOffset(getSourceViewer(), position));
}
@ -1063,6 +1075,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/*
* @see org.eclipse.cdt.internal.ui.editor.CEditor.PreviousSubWordAction#setCaretPosition(int)
*/
@Override
protected void setCaretPosition(int position) {
if (!validateEditorInputState())
return;
@ -1087,6 +1100,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/*
* @see org.eclipse.cdt.internal.ui.editor.CEditor.PreviousSubWordAction#findPreviousPosition(int)
*/
@Override
protected int findPreviousPosition(int position) {
return fIterator.preceding(position);
}
@ -1116,6 +1130,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/*
* @see org.eclipse.cdt.internal.ui.editor.CEditor.PreviousSubWordAction#setCaretPosition(int)
*/
@Override
protected void setCaretPosition(final int position) {
final ISourceViewer viewer = getSourceViewer();
@ -1253,12 +1268,14 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/**
* @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#initializeEditor()
*/
@Override
protected void initializeEditor() {
}
/**
* @see org.eclipse.ui.texteditor.AbstractTextEditor#doSetInput(org.eclipse.ui.IEditorInput)
*/
@Override
protected void doSetInput(IEditorInput input) throws CoreException {
ISourceViewer sourceViewer= getSourceViewer();
if (!(sourceViewer instanceof ISourceViewerExtension2)) {
@ -1313,6 +1330,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
* @see org.eclipse.ui.texteditor.AbstractTextEditor#setPreferenceStore(org.eclipse.jface.preference.IPreferenceStore)
* @since 5.0
*/
@Override
protected void setPreferenceStore(IPreferenceStore store) {
super.setPreferenceStore(store);
SourceViewerConfiguration sourceViewerConfiguration= getSourceViewerConfiguration();
@ -1349,7 +1367,8 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/**
* @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed()
*/
public boolean isSaveAsAllowed() {
@Override
public boolean isSaveAsAllowed() {
return true;
}
/**
@ -1368,6 +1387,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/**
* @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
*/
@Override
public Object getAdapter(Class required) {
if (IContentOutlinePage.class.equals(required)) {
return getOutlinePage();
@ -1421,6 +1441,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
*
* @param event the property change event
*/
@Override
protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
String property = event.getProperty();
@ -1547,6 +1568,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/*
* @see org.eclipse.ui.texteditor.AbstractTextEditor#initializeViewerColors(org.eclipse.jface.text.source.ISourceViewer)
*/
@Override
protected void initializeViewerColors(ISourceViewer viewer) {
// is handled by CSourceViewer
}
@ -1821,6 +1843,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
* @see org.eclipse.ui.texteditor.AbstractTextEditor#installTabsToSpacesConverter()
* @since 4.0
*/
@Override
protected void installTabsToSpacesConverter() {
ISourceViewer sourceViewer= getSourceViewer();
SourceViewerConfiguration config= getSourceViewerConfiguration();
@ -1856,6 +1879,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
* @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#isTabsToSpacesConversionEnabled()
* @since 4.0
*/
@Override
protected boolean isTabsToSpacesConversionEnabled() {
ICElement element= getInputCElement();
ICProject project= element == null ? null : element.getCProject();
@ -1870,7 +1894,8 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/**
* @see org.eclipse.ui.IWorkbenchPart#dispose()
*/
public void dispose() {
@Override
public void dispose() {
ISourceViewer sourceViewer = getSourceViewer();
if (sourceViewer instanceof ITextViewerExtension)
@ -1943,6 +1968,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/**
* @see org.eclipse.ui.texteditor.AbstractTextEditor#canHandleMove(org.eclipse.ui.IEditorInput, org.eclipse.ui.IEditorInput)
*/
@Override
protected boolean canHandleMove(IEditorInput originalElement, IEditorInput movedElement) {
String oldLanguage = ""; //$NON-NLS-1$
if (originalElement instanceof IFileEditorInput) {
@ -1977,6 +2003,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/**
* @see org.eclipse.ui.texteditor.AbstractTextEditor#createActions()
*/
@Override
protected void createActions() {
super.createActions();
@ -2088,6 +2115,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/**
* @see org.eclipse.ui.texteditor.AbstractTextEditor#editorContextMenuAboutToShow(org.eclipse.jface.action.IMenuManager)
*/
@Override
public void editorContextMenuAboutToShow(IMenuManager menu) {
// marker for contributions to the top
menu.add(new GroupMarker(ICommonMenuConstants.GROUP_TOP));
@ -2135,6 +2163,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/*
* @see org.eclipse.ui.texteditor.AbstractTextEditor#rulerContextMenuAboutToShow(org.eclipse.jface.action.IMenuManager)
*/
@Override
protected void rulerContextMenuAboutToShow(IMenuManager menu) {
super.rulerContextMenuAboutToShow(menu);
IMenuManager foldingMenu= new MenuManager(CEditorMessages.getString("CEditor.menu.folding"), "projection"); //$NON-NLS-1$ //$NON-NLS-2$
@ -2174,6 +2203,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
* @see org.eclipse.ui.part.WorkbenchPart#getOrientation()
* @since 4.0
*/
@Override
public int getOrientation() {
// C/C++ editors are always left to right by default
return SWT.LEFT_TO_RIGHT;
@ -2182,6 +2212,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/*
* @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#createPartControl(org.eclipse.swt.widgets.Composite)
*/
@Override
public void createPartControl(Composite parent) {
super.createPartControl(parent);
@ -2213,6 +2244,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/*
* @see org.eclipse.ui.texteditor.AbstractTextEditor#installTextDragAndDrop(org.eclipse.jface.text.source.ISourceViewer)
*/
@Override
protected void installTextDragAndDrop(ISourceViewer viewer) {
if (fTextViewerDragAdapter != null) {
// already installed, enable it
@ -2239,6 +2271,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/*
* @see org.eclipse.ui.texteditor.AbstractTextEditor#uninstallTextDragAndDrop(org.eclipse.jface.text.source.ISourceViewer)
*/
@Override
protected void uninstallTextDragAndDrop(ISourceViewer viewer) {
if (fTextViewerDragAdapter != null) {
// uninstall not possible, disable instead
@ -2249,6 +2282,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/*
* @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#getSourceViewerDecorationSupport(org.eclipse.jface.text.source.ISourceViewer)
*/
@Override
protected SourceViewerDecorationSupport getSourceViewerDecorationSupport(ISourceViewer viewer) {
if (fSourceViewerDecorationSupport == null) {
fSourceViewerDecorationSupport= new CSourceViewerDecorationSupport(this, viewer, getOverviewRuler(), getAnnotationAccess(), getSharedColors());
@ -2260,6 +2294,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/*
* @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#configureSourceViewerDecorationSupport(org.eclipse.ui.texteditor.SourceViewerDecorationSupport)
*/
@Override
protected void configureSourceViewerDecorationSupport(SourceViewerDecorationSupport support) {
super.configureSourceViewerDecorationSupport(support);
//Enhance the stock source viewer decorator with a bracket matcher
@ -2387,6 +2422,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/*
* Get the dektop's StatusLineManager
*/
@Override
protected IStatusLineManager getStatusLineManager() {
IEditorActionBarContributor contributor = getEditorSite().getActionBarContributor();
if (contributor instanceof EditorActionBarContributor) {
@ -2412,6 +2448,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/*
* @see org.eclipse.ui.texteditor.AbstractTextEditor#createNavigationActions()
*/
@Override
protected void createNavigationActions() {
super.createNavigationActions();
@ -2457,6 +2494,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/*
* @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#createSourceViewer(org.eclipse.swt.widgets.Composite, org.eclipse.jface.text.source.IVerticalRuler, int)
*/
@Override
protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
IPreferenceStore store= getPreferenceStore();
ISourceViewer sourceViewer =
@ -2555,6 +2593,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/*
* @see org.eclipse.ui.editors.text.TextEditor#initializeKeyBindingScopes()
*/
@Override
protected void initializeKeyBindingScopes() {
setKeyBindingScopes(new String [] { "org.eclipse.cdt.ui.cEditorScope" } ); //$NON-NLS-1$
}
@ -2562,6 +2601,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/*
* @see AbstractTextEditor#affectsTextPresentation(PropertyChangeEvent)
*/
@Override
protected boolean affectsTextPresentation(PropertyChangeEvent event) {
SourceViewerConfiguration configuration = getSourceViewerConfiguration();
if (configuration instanceof CSourceViewerConfiguration) {
@ -2582,6 +2622,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/*
* @see org.eclipse.ui.texteditor.AbstractTextEditor#performRevert()
*/
@Override
protected void performRevert() {
ProjectionViewer projectionViewer = (ProjectionViewer) getSourceViewer();
projectionViewer.setRedraw(false);
@ -2612,7 +2653,8 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
*
* @param msg message to be set
*/
protected void setStatusLineErrorMessage(String msg) {
@Override
protected void setStatusLineErrorMessage(String msg) {
IEditorStatusLine statusLine = (IEditorStatusLine) getAdapter(IEditorStatusLine.class);
if (statusLine != null)
statusLine.setMessage(true, msg, null);
@ -2624,6 +2666,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
* @param msg message to be set
* @since 3.0
*/
@Override
protected void setStatusLineMessage(String msg) {
IEditorStatusLine statusLine = (IEditorStatusLine) getAdapter(IEditorStatusLine.class);
if (statusLine != null)
@ -2719,6 +2762,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/*
* @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#collectContextMenuPreferencePages()
*/
@Override
protected String[] collectContextMenuPreferencePages() {
// Add C/C++ Editor relevant pages
String[] parentPrefPageIds = super.collectContextMenuPreferencePages();
@ -2848,6 +2892,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/*
* @see org.eclipse.ui.texteditor.AbstractTextEditor#updateStateDependentActions()
*/
@Override
protected void updateStateDependentActions() {
super.updateStateDependentActions();
fGenerateActionGroup.editorStateChanged();
@ -2905,6 +2950,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
/*
* @see Job#run(org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public IStatus run(IProgressMonitor progressMonitor) {
if (isCanceled(progressMonitor))
return Status.CANCEL_STATUS;
@ -3078,7 +3124,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
OccurrenceLocation[] locations= null;
IASTNodeSelector selector= astRoot.getNodeSelector(astRoot.getFilePath());
IASTName name= selector.findSurroundingName(wordRegion.getOffset(), wordRegion.getLength());
IASTName name= selector.findEnclosingName(wordRegion.getOffset(), wordRegion.getLength());
if (name != null) {
IBinding binding= name.resolveBinding();

View file

@ -10,7 +10,6 @@
* IBM Corporation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.editor;
import org.eclipse.core.runtime.CoreException;
@ -83,7 +82,7 @@ public class CElementHyperlinkDetector implements IHyperlinkDetector {
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);
IASTName selectedName= nodeSelector.findEnclosingName(offset, length);
IASTFileLocation linkLocation= null;
if (selectedName != null) { // found a name
// prefer include statement over the include name
@ -96,7 +95,7 @@ public class CElementHyperlinkDetector implements IHyperlinkDetector {
}
else {
// search for include statement
final IASTNode cand= nodeSelector.findSurroundingNode(offset, length);
final IASTNode cand= nodeSelector.findEnclosingNode(offset, length);
if (cand instanceof IASTPreprocessorIncludeStatement) {
linkLocation= cand.getFileLocation();
}

View file

@ -48,7 +48,7 @@ public class PDOMSearchTextSelectionQuery extends PDOMSearchQuery {
return ASTProvider.getASTProvider().runOnAST(tu, ASTProvider.WAIT_YES, monitor, new ASTRunnable() {
public IStatus runOnAST(ILanguage language, IASTTranslationUnit ast) throws CoreException {
if (ast != null) {
IASTName searchName= ast.getNodeSelector(null).findSurroundingName(selection.getOffset(), selection.getLength());
IASTName searchName= ast.getNodeSelector(null).findEnclosingName(selection.getOffset(), selection.getLength());
if (searchName != null) {
IBinding binding = searchName.resolveBinding();
if (binding != null)

View file

@ -130,7 +130,7 @@ public class OpenDeclarationsAction extends SelectionParseAction {
int selectionStart = selNode.getOffset();
int selectionLength = selNode.getLength();
IASTName searchName= ast.getNodeSelector(null).findSurroundingName(selectionStart, selectionLength);
IASTName searchName= ast.getNodeSelector(null).findEnclosingName(selectionStart, selectionLength);
if (searchName != null) { // just right, only one name selected
boolean found= false;
final IASTNode parent = searchName.getParent();

View file

@ -95,7 +95,7 @@ public class CMacroExpansionInput {
}
if (fAllowSelection) {
// selection
fEnclosingNode= nodeSelector.findSurroundingNode(fTextRegion.getOffset(), fTextRegion.getLength());
fEnclosingNode= nodeSelector.findEnclosingNode(fTextRegion.getOffset(), fTextRegion.getLength());
if (fEnclosingNode != null) {
boolean macroOccurrence= false;
IASTNodeLocation[] locations= fEnclosingNode.getNodeLocations();
@ -105,7 +105,7 @@ public class CMacroExpansionInput {
IASTFileLocation fileLocation= location.asFileLocation();
if (fileLocation != null && ast.getFilePath().equals(fileLocation.getFileName())) {
if (fTextRegion.overlapsWith(fileLocation.getNodeOffset(), fileLocation.getNodeLength())) {
addExpansionNode(nodeSelector.findSurroundingNode(fileLocation.getNodeOffset(), fileLocation.getNodeLength()));
addExpansionNode(nodeSelector.findEnclosingNode(fileLocation.getNodeOffset(), fileLocation.getNodeLength()));
macroOccurrence= true;
}
}

View file

@ -128,7 +128,7 @@ public class CSourceHover extends AbstractCEditorTextHover implements ITextHover
public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) {
if (ast != null) {
try {
IASTName name= ast.getNodeSelector(null).findSurroundingName(fTextRegion.getOffset(), fTextRegion.getLength());
IASTName name= ast.getNodeSelector(null).findEnclosingName(fTextRegion.getOffset(), fTextRegion.getLength());
if (name != null) {
IBinding binding= name.resolveBinding();
if (binding != null) {