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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * 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$ String code = "void f() { int x; x=3; }"; //$NON-NLS-1$
int offset1 = code.indexOf( "x=" ); //$NON-NLS-1$ int offset1 = code.indexOf( "x=" ); //$NON-NLS-1$
int length = "x".length(); //$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); assertNotNull(node);
assertTrue( node instanceof IASTIdExpression ); assertTrue( node instanceof IASTIdExpression );
assertEquals(((IASTIdExpression)node).getName().toString(), "x"); //$NON-NLS-1$ 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); assertNotNull(node);
assertTrue( node instanceof IASTIdExpression ); assertTrue( node instanceof IASTIdExpression );
assertEquals(((IASTIdExpression)node).getName().toString(), "x"); //$NON-NLS-1$ 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$ String code = "int x(){x( );}"; //$NON-NLS-1$
int offset1 = code.indexOf( "x( " ); //$NON-NLS-1$ int offset1 = code.indexOf( "x( " ); //$NON-NLS-1$
int length = "x".length(); //$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); assertNotNull(node);
assertTrue( node instanceof IASTIdExpression ); assertTrue( node instanceof IASTIdExpression );
assertEquals(((IASTIdExpression)node).getName().toString(), "x"); //$NON-NLS-1$ assertEquals(((IASTIdExpression)node).getName().toString(), "x"); //$NON-NLS-1$
@ -91,7 +91,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
assertNotNull(name.resolveBinding()); assertNotNull(name.resolveBinding());
assertTrue(name.resolveBinding() instanceof IFunction); assertTrue(name.resolveBinding() instanceof IFunction);
assertEquals(((IFunction)name.resolveBinding()).getName(), "x"); //$NON-NLS-1$ 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); assertNotNull(node);
assertTrue( node instanceof IASTIdExpression ); assertTrue( node instanceof IASTIdExpression );
assertEquals(((IASTIdExpression)node).getName().toString(), "x"); //$NON-NLS-1$ 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$ String code = "int main( int argc ) { int x = argc; }"; //$NON-NLS-1$
int offset1 = code.indexOf( "argc;" ); //$NON-NLS-1$ int offset1 = code.indexOf( "argc;" ); //$NON-NLS-1$
int length = "argc".length(); //$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); assertNotNull(node);
assertTrue( node instanceof IASTInitializerExpression ); assertTrue( node instanceof IASTInitializerExpression );
assertEquals( ((IASTIdExpression)((IASTInitializerExpression)node).getExpression()).getName().toString(), "argc" ); //$NON-NLS-1$ assertEquals( ((IASTIdExpression)((IASTInitializerExpression)node).getExpression()).getName().toString(), "argc" ); //$NON-NLS-1$
@ -192,7 +192,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
assertNotNull(name.resolveBinding()); assertNotNull(name.resolveBinding());
assertTrue(name.resolveBinding() instanceof IParameter); assertTrue(name.resolveBinding() instanceof IParameter);
assertEquals(((IParameter)name.resolveBinding()).getName(), "argc"); //$NON-NLS-1$ 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); assertNotNull(node);
assertTrue( node instanceof IASTInitializerExpression ); assertTrue( node instanceof IASTInitializerExpression );
assertEquals( ((IASTIdExpression)((IASTInitializerExpression)node).getExpression()).getName().toString(), "argc" ); //$NON-NLS-1$ assertEquals( ((IASTIdExpression)((IASTInitializerExpression)node).getExpression()).getName().toString(), "argc" ); //$NON-NLS-1$
@ -357,6 +357,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
{ {
case 0: case 0:
case 1: case 1:
node= node.getParent().getParent();
assertTrue(node instanceof IASTTypeId); assertTrue(node instanceof IASTTypeId);
assertEquals(((IASTNamedTypeSpecifier)((IASTTypeId)node).getDeclSpecifier()).getName().toString(), "Gonzo"); //$NON-NLS-1$ assertEquals(((IASTNamedTypeSpecifier)((IASTTypeId)node).getDeclSpecifier()).getName().toString(), "Gonzo"); //$NON-NLS-1$
name = ((IASTNamedTypeSpecifier)((IASTTypeId)node).getDeclSpecifier()).getName(); name = ((IASTNamedTypeSpecifier)((IASTTypeId)node).getDeclSpecifier()).getName();
@ -425,7 +426,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
String code = writer.toString(); String code = writer.toString();
int startIndex = code.indexOf( "foo(1)"); //$NON-NLS-1$ int startIndex = code.indexOf( "foo(1)"); //$NON-NLS-1$
int length = "foo".length(); //$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); assertNotNull(node);
assertTrue(node instanceof IASTIdExpression); assertTrue(node instanceof IASTIdExpression);
assertEquals(((IASTIdExpression)node).getName().toString(), "foo"); //$NON-NLS-1$ assertEquals(((IASTIdExpression)node).getName().toString(), "foo"); //$NON-NLS-1$
@ -433,7 +434,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
assertNotNull(name.resolveBinding()); assertNotNull(name.resolveBinding());
assertTrue(name.resolveBinding() instanceof IFunction); assertTrue(name.resolveBinding() instanceof IFunction);
assertEquals(((IFunction)name.resolveBinding()).getName(), "foo"); //$NON-NLS-1$ 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); assertNotNull(node);
assertTrue(node instanceof IASTIdExpression); assertTrue(node instanceof IASTIdExpression);
assertEquals(((IASTIdExpression)node).getName().toString(), "foo"); //$NON-NLS-1$ assertEquals(((IASTIdExpression)node).getName().toString(), "foo"); //$NON-NLS-1$
@ -466,7 +467,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
assertTrue(name.resolveBinding() instanceof IEnumeration); assertTrue(name.resolveBinding() instanceof IEnumeration);
assertEquals(((IEnumeration)name.resolveBinding()).getName(), "EColours"); //$NON-NLS-1$ assertEquals(((IEnumeration)name.resolveBinding()).getName(), "EColours"); //$NON-NLS-1$
startIndex = codeCPP.indexOf( "EColours color"); //$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); assertNotNull(node);
assertTrue(node instanceof IASTNamedTypeSpecifier); assertTrue(node instanceof IASTNamedTypeSpecifier);
assertEquals(((IASTNamedTypeSpecifier)node).getName().toString(), "EColours"); //$NON-NLS-1$ assertEquals(((IASTNamedTypeSpecifier)node).getName().toString(), "EColours"); //$NON-NLS-1$
@ -519,7 +520,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
String code = writer.toString(); String code = writer.toString();
int startIndex = code.indexOf( "static_function( file )"); //$NON-NLS-1$ int startIndex = code.indexOf( "static_function( file )"); //$NON-NLS-1$
int length = "static_function".length(); //$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); assertNotNull(node);
assertTrue(node instanceof IASTIdExpression); assertTrue(node instanceof IASTIdExpression);
assertEquals(((IASTIdExpression)node).getName().toString(), "static_function"); //$NON-NLS-1$ assertEquals(((IASTIdExpression)node).getName().toString(), "static_function"); //$NON-NLS-1$
@ -527,7 +528,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
assertNotNull(name.resolveBinding()); assertNotNull(name.resolveBinding());
assertTrue(name.resolveBinding() instanceof IFunction); assertTrue(name.resolveBinding() instanceof IFunction);
assertEquals(((IFunction)name.resolveBinding()).getName(), "static_function"); //$NON-NLS-1$ 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); assertNotNull(node);
assertTrue(node instanceof IASTIdExpression); assertTrue(node instanceof IASTIdExpression);
assertEquals(((IASTIdExpression)node).getName().toString(), "static_function"); //$NON-NLS-1$ 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 startIndex = code.indexOf( "/**/fprintf") + 4; //$NON-NLS-1$
int length = "fprintf".length(); //$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); assertNotNull(node);
assertTrue(node instanceof IASTIdExpression); assertTrue(node instanceof IASTIdExpression);
assertEquals(((IASTIdExpression)node).getName().toString(), "fprintf"); //$NON-NLS-1$ assertEquals(((IASTIdExpression)node).getName().toString(), "fprintf"); //$NON-NLS-1$
@ -577,7 +578,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
assertNotNull(name.resolveBinding()); assertNotNull(name.resolveBinding());
assertTrue(name.resolveBinding() instanceof IFunction); assertTrue(name.resolveBinding() instanceof IFunction);
assertEquals(((IFunction)name.resolveBinding()).getName(), "fprintf"); //$NON-NLS-1$ 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); assertNotNull(node);
assertTrue(node instanceof IASTIdExpression); assertTrue(node instanceof IASTIdExpression);
assertEquals(((IASTIdExpression)node).getName().toString(), "fprintf"); //$NON-NLS-1$ assertEquals(((IASTIdExpression)node).getName().toString(), "fprintf"); //$NON-NLS-1$
@ -614,7 +615,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
assertTrue(name.resolveBinding() instanceof ICompositeType); assertTrue(name.resolveBinding() instanceof ICompositeType);
assertEquals(((ICompositeType)name.resolveBinding()).getName(), "Squaw"); //$NON-NLS-1$ assertEquals(((ICompositeType)name.resolveBinding()).getName(), "Squaw"); //$NON-NLS-1$
startIndex = codeCPP.indexOf( "sizeof( ") + "sizeof( ".length(); //$NON-NLS-1$ //$NON-NLS-2$ 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); assertNotNull(node);
assertTrue(node instanceof IASTTypeId); assertTrue(node instanceof IASTTypeId);
assertEquals(((IASTNamedTypeSpecifier)((IASTTypeId)node).getDeclSpecifier()).getName().toString(), "Squaw"); //$NON-NLS-1$ assertEquals(((IASTNamedTypeSpecifier)((IASTTypeId)node).getDeclSpecifier()).getName().toString(), "Squaw"); //$NON-NLS-1$
@ -638,7 +639,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
String code = writer.toString(); String code = writer.toString();
int startIndex = code.indexOf( "return ") + "return ".length(); //$NON-NLS-1$ //$NON-NLS-2$ int startIndex = code.indexOf( "return ") + "return ".length(); //$NON-NLS-1$ //$NON-NLS-2$
int length = "FOUND_ME".length(); //$NON-NLS-1$ 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); assertNotNull(node);
assertTrue(node instanceof IASTIdExpression); assertTrue(node instanceof IASTIdExpression);
assertEquals(((IASTIdExpression)node).getName().toString(), "FOUND_ME"); //$NON-NLS-1$ assertEquals(((IASTIdExpression)node).getName().toString(), "FOUND_ME"); //$NON-NLS-1$
@ -739,7 +740,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
String code = writer.toString(); String code = writer.toString();
int startIndex = code.indexOf( "new B" ) + 4; //$NON-NLS-1$ int startIndex = code.indexOf( "new B" ) + 4; //$NON-NLS-1$
int length = "B".length(); //$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); assertNotNull(node);
assertTrue(node instanceof IASTTypeId); assertTrue(node instanceof IASTTypeId);
assertEquals(((IASTNamedTypeSpecifier)((IASTTypeId)node).getDeclSpecifier()).getName().toString(), "B"); //$NON-NLS-1$ assertEquals(((IASTNamedTypeSpecifier)((IASTTypeId)node).getDeclSpecifier()).getName().toString(), "B"); //$NON-NLS-1$
@ -758,7 +759,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
String code = writer.toString(); String code = writer.toString();
int startIndex = code.indexOf( "(A*)" ) + 1; //$NON-NLS-1$ int startIndex = code.indexOf( "(A*)" ) + 1; //$NON-NLS-1$
int length = "A".length(); //$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); assertNotNull(node);
assertTrue(node instanceof IASTNamedTypeSpecifier); assertTrue(node instanceof IASTNamedTypeSpecifier);
assertEquals(((IASTNamedTypeSpecifier)node).getName().toString(), "A"); //$NON-NLS-1$ 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$ index = code.indexOf( "Card( int rank );") + 10; //$NON-NLS-1$
length = "rank".length(); //$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); assertNotNull(node);
assertTrue(node instanceof IASTDeclarator); assertTrue(node instanceof IASTDeclarator);
assertEquals(((IASTDeclarator)node).getName().toString(), "rank"); //$NON-NLS-1$ 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$ assertEquals(((IVariable)name.resolveBinding()).getName(), "rank"); //$NON-NLS-1$
index = code.indexOf( "int rank;") + 4; //$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); assertNotNull(node);
assertTrue(node instanceof IASTDeclarator); assertTrue(node instanceof IASTDeclarator);
assertEquals(((IASTDeclarator)node).getName().toString(), "rank"); //$NON-NLS-1$ 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$ index = code.indexOf( "Card::Card( int rank )") + 16; //$NON-NLS-1$
length = "rank".length(); //$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); assertNotNull(node);
assertTrue(node instanceof IASTDeclarator); assertTrue(node instanceof IASTDeclarator);
assertEquals(((IASTDeclarator)node).getName().toString(), "rank"); //$NON-NLS-1$ 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$ assertEquals(((ICPPField)name.resolveBinding()).getName(), "rank"); //$NON-NLS-1$
index = code.indexOf( "this->rank = rank;") + 13; //$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); assertNotNull(node);
assertTrue(node instanceof IASTIdExpression); assertTrue(node instanceof IASTIdExpression);
assertEquals(((IASTIdExpression)node).getName().toString(), "rank"); //$NON-NLS-1$ 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$ index = code.indexOf( "this->rank = getRank();") + 13; //$NON-NLS-1$
length = "getRank".length(); //$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); assertNotNull(node);
assertTrue(node instanceof IASTIdExpression); assertTrue(node instanceof IASTIdExpression);
assertEquals(((IASTIdExpression)node).getName().toString(), "getRank"); //$NON-NLS-1$ assertEquals(((IASTIdExpression)node).getName().toString(), "getRank"); //$NON-NLS-1$
@ -1037,7 +1038,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
String code = writer.toString(); String code = writer.toString();
int index = code.indexOf( "void f(int itself){}") + 11; //$NON-NLS-1$ int index = code.indexOf( "void f(int itself){}") + 11; //$NON-NLS-1$
int length = "itself".length(); //$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); assertNotNull(node);
assertTrue(node instanceof IASTDeclarator); assertTrue(node instanceof IASTDeclarator);
assertEquals(((IASTDeclarator)node).getName().toString(), "itself"); //$NON-NLS-1$ assertEquals(((IASTDeclarator)node).getName().toString(), "itself"); //$NON-NLS-1$
@ -1045,7 +1046,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
assertNotNull(name.resolveBinding()); assertNotNull(name.resolveBinding());
assertTrue(name.resolveBinding() instanceof IVariable); assertTrue(name.resolveBinding() instanceof IVariable);
assertEquals(((IVariable)name.resolveBinding()).getName(), "itself"); //$NON-NLS-1$ 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); assertNotNull(node);
assertTrue(node instanceof IASTDeclarator); assertTrue(node instanceof IASTDeclarator);
assertEquals(((IASTDeclarator)node).getName().toString(), "itself"); //$NON-NLS-1$ assertEquals(((IASTDeclarator)node).getName().toString(), "itself"); //$NON-NLS-1$
@ -1119,7 +1120,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
String code = buffer.toString(); String code = buffer.toString();
int index = code.indexOf("x;"); //$NON-NLS-1$ int index = code.indexOf("x;"); //$NON-NLS-1$
int length = "x".length(); //$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); assertNotNull(node);
assertTrue(node instanceof IASTDeclarator); assertTrue(node instanceof IASTDeclarator);
assertEquals(((IASTDeclarator)node).getName().toString(), "x"); //$NON-NLS-1$ assertEquals(((IASTDeclarator)node).getName().toString(), "x"); //$NON-NLS-1$
@ -1138,7 +1139,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
String code = buffer.toString(); String code = buffer.toString();
int index = code.indexOf("x;"); //$NON-NLS-1$ int index = code.indexOf("x;"); //$NON-NLS-1$
int length = "x".length(); //$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); assertNotNull(node);
assertTrue(node instanceof IASTDeclarator); assertTrue(node instanceof IASTDeclarator);
assertEquals(((IASTDeclarator)node).getName().toString(), "x"); //$NON-NLS-1$ assertEquals(((IASTDeclarator)node).getName().toString(), "x"); //$NON-NLS-1$
@ -1177,7 +1178,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
String code = buffer.toString(); String code = buffer.toString();
int index = code.indexOf("y;"); //$NON-NLS-1$ int index = code.indexOf("y;"); //$NON-NLS-1$
int length = "y".length(); //$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); assertNotNull(node);
assertTrue(node instanceof IASTDeclarator); assertTrue(node instanceof IASTDeclarator);
assertEquals(((IASTDeclarator)node).getName().toString(), "y"); //$NON-NLS-1$ assertEquals(((IASTDeclarator)node).getName().toString(), "y"); //$NON-NLS-1$
@ -1198,7 +1199,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
String code = buffer.toString(); String code = buffer.toString();
int index = code.indexOf("c x;"); //$NON-NLS-1$ int index = code.indexOf("c x;"); //$NON-NLS-1$
int length = "c".length(); //$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); assertNotNull(node);
assertTrue(node instanceof IASTNamedTypeSpecifier); assertTrue(node instanceof IASTNamedTypeSpecifier);
assertEquals(((IASTNamedTypeSpecifier)node).getName().toString(), "c"); //$NON-NLS-1$ 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$ index = code.indexOf("x;"); //$NON-NLS-1$
length = "x".length(); //$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); assertNotNull(node);
assertTrue(node instanceof IASTDeclarator); assertTrue(node instanceof IASTDeclarator);
assertEquals(((IASTDeclarator)node).getName().toString(), "x"); //$NON-NLS-1$ assertEquals(((IASTDeclarator)node).getName().toString(), "x"); //$NON-NLS-1$
@ -1308,7 +1309,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
String code = buffer.toString(); String code = buffer.toString();
int index = code.indexOf("b,a"); //$NON-NLS-1$ int index = code.indexOf("b,a"); //$NON-NLS-1$
int length = "b".length(); //$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); assertNotNull(node);
assertTrue(node instanceof IASTDeclarator); assertTrue(node instanceof IASTDeclarator);
IASTName name = ((IASTDeclarator)node).getName(); IASTName name = ((IASTDeclarator)node).getName();
@ -1518,7 +1519,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
index = code.indexOf("c;"); //$NON-NLS-1$ index = code.indexOf("c;"); //$NON-NLS-1$
length = "c".length(); //$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); assertNotNull(node);
assertTrue( node instanceof IASTDeclarator); assertTrue( node instanceof IASTDeclarator);
assertEquals(((IASTDeclarator)node).getName().toString(), "c"); //$NON-NLS-1$ assertEquals(((IASTDeclarator)node).getName().toString(), "c"); //$NON-NLS-1$
@ -1648,7 +1649,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
public void testBug86126() throws Exception { public void testBug86126() throws Exception {
String header= "foo"+System.currentTimeMillis()+".h"; String header= "foo"+System.currentTimeMillis()+".h";
String source= "blah"+System.currentTimeMillis()+".c"; 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$ String code = "#include \""+header+"\"\r\n"; //$NON-NLS-1$
IFile file = importFile(source, code); IFile file = importFile(source, code);
int offset1 = code.indexOf( "#include \""+header+"\"" ); //$NON-NLS-1$ 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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -40,6 +40,7 @@ public class DOMParserTestSuite extends TestCase {
suite.addTestSuite( AST2UtilTests.class ); suite.addTestSuite( AST2UtilTests.class );
suite.addTestSuite( AST2UtilOldTests.class ); suite.addTestSuite( AST2UtilOldTests.class );
suite.addTestSuite( AST2SelectionParseTest.class ); suite.addTestSuite( AST2SelectionParseTest.class );
suite.addTest( ASTNodeSelectorTest.suite());
suite.addTestSuite( CodeReaderCacheTest.class ); suite.addTestSuite( CodeReaderCacheTest.class );
suite.addTestSuite( AST2CPPSpecTest.class ); suite.addTestSuite( AST2CPPSpecTest.class );
suite.addTestSuite( AST2CPPSpecFailingTest.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, 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) { String filename, int offset, int length, int line, int nameOffset, int nameLength) {
IASTPreprocessorUndefStatement st= (IASTPreprocessorUndefStatement) s; 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); checkASTNode(st, fTu, PROP_PST, filename, offset, length, line, line, image);
} }
@ -344,8 +344,8 @@ public class LocationMapTests extends BaseTestCase {
public void testIf() { public void testIf() {
init(DIGITS); init(DIGITS);
fLocationMap.encounterPoundIf(0, 0, 0, 0, false); fLocationMap.encounterPoundIf(0, 0, 0, 0, false, IASTName.EMPTY_NAME_ARRAY);
fLocationMap.encounterPoundIf(0, 1, 3, 16, true); fLocationMap.encounterPoundIf(0, 1, 3, 16, true, IASTName.EMPTY_NAME_ARRAY);
IASTPreprocessorStatement[] prep= fLocationMap.getAllPreprocessorStatements(); IASTPreprocessorStatement[] prep= fLocationMap.getAllPreprocessorStatements();
assertEquals(2, prep.length); assertEquals(2, prep.length);
checkIf(prep[0], "", "", false, FN, 0, 0, 1); checkIf(prep[0], "", "", false, FN, 0, 0, 1);
@ -354,8 +354,8 @@ public class LocationMapTests extends BaseTestCase {
public void testIfdef() { public void testIfdef() {
init(DIGITS); init(DIGITS);
fLocationMap.encounterPoundIfdef(0, 0, 0, 0, false); fLocationMap.encounterPoundIfdef(0, 0, 0, 0, false, null);
fLocationMap.encounterPoundIfdef(0, 1, 3, 16, true); fLocationMap.encounterPoundIfdef(0, 1, 3, 16, true, null);
IASTPreprocessorStatement[] prep= fLocationMap.getAllPreprocessorStatements(); IASTPreprocessorStatement[] prep= fLocationMap.getAllPreprocessorStatements();
assertEquals(2, prep.length); assertEquals(2, prep.length);
checkIfdef(prep[0], "", "", false, FN, 0, 0, 1); checkIfdef(prep[0], "", "", false, FN, 0, 0, 1);
@ -364,8 +364,8 @@ public class LocationMapTests extends BaseTestCase {
public void testIfndef() { public void testIfndef() {
init(DIGITS); init(DIGITS);
fLocationMap.encounterPoundIfndef(0, 0, 0, 0, false); fLocationMap.encounterPoundIfndef(0, 0, 0, 0, false, null);
fLocationMap.encounterPoundIfndef(0, 1, 3, 16, true); fLocationMap.encounterPoundIfndef(0, 1, 3, 16, true, null);
IASTPreprocessorStatement[] prep= fLocationMap.getAllPreprocessorStatements(); IASTPreprocessorStatement[] prep= fLocationMap.getAllPreprocessorStatements();
assertEquals(2, prep.length); assertEquals(2, prep.length);
checkIfndef(prep[0], "", "", false, FN, 0, 0, 1); checkIfndef(prep[0], "", "", false, FN, 0, 0, 1);
@ -374,8 +374,8 @@ public class LocationMapTests extends BaseTestCase {
public void testElif() { public void testElif() {
init(DIGITS); init(DIGITS);
fLocationMap.encounterPoundElif(0, 0, 0, 0, false); fLocationMap.encounterPoundElif(0, 0, 0, 0, false, IASTName.EMPTY_NAME_ARRAY);
fLocationMap.encounterPoundElif(0, 1, 3, 16, true); fLocationMap.encounterPoundElif(0, 1, 3, 16, true, IASTName.EMPTY_NAME_ARRAY);
IASTPreprocessorStatement[] prep= fLocationMap.getAllPreprocessorStatements(); IASTPreprocessorStatement[] prep= fLocationMap.getAllPreprocessorStatements();
assertEquals(2, prep.length); assertEquals(2, prep.length);
checkElif(prep[0], "", "", false, FN, 0, 0, 1); checkElif(prep[0], "", "", false, FN, 0, 0, 1);
@ -476,11 +476,11 @@ public class LocationMapTests extends BaseTestCase {
refs= fLocationMap.getReferences(macro1); refs= fLocationMap.getReferences(macro1);
assertEquals(1, refs.length); 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); refs= fLocationMap.getReferences(macro2);
assertEquals(1, refs.length); 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() { public void testContexts() {

View file

@ -11,8 +11,10 @@
package org.eclipse.cdt.core.dom.ast; package org.eclipse.cdt.core.dom.ast;
/** /**
* Interface for searching nodes of a file in a translation unit. An instance of this interface can * Interface for searching nodes in a translation unit. An instance of this interface, responsible
* be obtained via {@link IASTTranslationUnit#getNodeSelector(String)}. * for one file contained in a translation-unit, can be obtained using
* {@link IASTTranslationUnit#getNodeSelector(String)}.
*
* @since 5.0 * @since 5.0
*/ */
public interface IASTNodeSelector { public interface IASTNodeSelector {
@ -23,9 +25,9 @@ public interface IASTNodeSelector {
IASTName findName(int offset, int length); 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. * 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. * 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); 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. * 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); 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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM - Initial API and implementation * IBM - Initial API and implementation
* Emanuel Graf (IFS) * Emanuel Graf (IFS)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.dom.ast; package org.eclipse.cdt.core.dom.ast;
/** /**
* This interface represent a preprocessor #ifdef statement. * This interface represent a preprocessor #ifdef statement.
*
* @author jcamelon
*/ */
public interface IASTPreprocessorIfdefStatement extends public interface IASTPreprocessorIfdefStatement extends IASTPreprocessorStatement {
IASTPreprocessorStatement {
/** /**
* Was this #ifdef branch taken? * Returns whether this branch was taken.
*
* @return
*/ */
public boolean taken(); public boolean taken();
/** /**
* The condition of the ifdef. * The condition of the ifdef-statement.
* * @return the condition
* @return the Condition
*/ */
public char[] getCondition(); 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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM - Initial API and implementation * IBM - Initial API and implementation
* Emanuel Graf (IFS) * Emanuel Graf (IFS)
* Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.dom.ast; package org.eclipse.cdt.core.dom.ast;
/** /**
* This interface represent a preprocessor #ifndef statement. * This interface represent a preprocessor #ifndef statement.
*
* @author jcamelon
*/ */
public interface IASTPreprocessorIfndefStatement extends public interface IASTPreprocessorIfndefStatement extends IASTPreprocessorStatement {
IASTPreprocessorStatement {
/** /**
* Was this branch taken? * Returns whether this branch was taken.
*
* @return
*/ */
public boolean taken(); public boolean taken();
/** /**
* The condition of the ifndef. * Returns the condition of the ifndef-statement.
*
* @return the Condition
*/ */
public char[] getCondition(); 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 IASTPreprocessorMacroExpansion[] EMPTY_ARRAY = {};
public static final ASTNodeProperty EXPANSION_NAME= public static final ASTNodeProperty EXPANSION_NAME=
new ASTNodeProperty("IASTPreprocessorMacroExpansion.EXPANSION_NAME - macro name"); //$NON-NLS-1$ 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. * 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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM - Initial API and implementation * IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.dom.ast; package org.eclipse.cdt.core.dom.ast;
/** /**
* This is the base interface for all preprocessor directives. * This is the base interface for all preprocessor directives.
*
* @author jcamelon
*/ */
public interface IASTPreprocessorStatement extends IASTNode { 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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM - Initial API and implementation * IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.dom.ast; package org.eclipse.cdt.core.dom.ast;
/** /**
* This interface represents a preprocessor #undef statement. * This interface represents a preprocessor #undef statement.
*
* @author jcamelon
*/ */
public interface IASTPreprocessorUndefStatement extends public interface IASTPreprocessorUndefStatement extends IASTPreprocessorStatement {
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(); 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; 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.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTNodeSelector; import org.eclipse.cdt.core.dom.ast.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; 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 * @since 5.0
*/ */
public class ASTNodeSelector implements IASTNodeSelector { public class ASTNodeSelector implements IASTNodeSelector {
@ -49,85 +48,99 @@ public class ASTNodeSelector implements IASTNodeSelector {
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getNode(int, int) * @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) { if (!fIsValid) {
return null; return null;
} }
int sequenceLength;
final int sequenceNumber= fLocationResolver.getSequenceNumberForFileOffset(fFilePath, offset); int altSequenceNumber= -1;
int sequenceNumber= fLocationResolver.getSequenceNumberForFileOffset(fFilePath, offsetInFile);
if (sequenceNumber < 0) { if (sequenceNumber < 0) {
return null; return null;
} }
final int sequenceLength= length <= 0 ? 0 : if (lengthInFile > 0) {
fLocationResolver.getSequenceNumberForFileOffset(fFilePath, offset+length-1) + 1 - sequenceNumber; sequenceLength= fLocationResolver.getSequenceNumberForFileOffset(fFilePath, offsetInFile+lengthInFile-1) + 1 - sequenceNumber;
}
ASTNode preCand= searchPreprocessor(sequenceNumber, sequenceLength, matchKind); else {
if (preCand != null && matchKind.getRelationToSelection() != Relation.FIRST_CONTAINED) { sequenceLength= 0;
return preCand; if (offsetInFile > 0) {
} altSequenceNumber= fLocationResolver.getSequenceNumberForFileOffset(fFilePath, offsetInFile-1);
ASTNode astCand= searchAST(sequenceNumber, sequenceLength, matchKind); if (altSequenceNumber+1 == sequenceNumber) {
return matchKind.isBetterMatch(preCand, astCand) ? preCand : astCand; altSequenceNumber= -1;
} }
else {
private ASTNode searchPreprocessor(int sequenceNumber, int sequenceLength, ASTNodeMatchKind matchKind) { // we are on a context boundary and we need to check the variant to the left and
return fLocationResolver.findPreprocessorNode(sequenceNumber, sequenceLength, matchKind); // the one to the right
} sequenceLength= 1;
}
private ASTNode searchAST(int sequenceNumber, int length, ASTNodeMatchKind matchKind) {
FindNodeForOffsetAction nodeFinder= new FindNodeForOffsetAction(sequenceNumber, length, matchKind);
fTu.accept(nodeFinder);
ASTNode result= nodeFinder.getNode();
// don't accept matches from the ast enclosed in a macro expansion (possible for contained matches, only)
if (result != null &&
matchKind.getRelationToSelection() == Relation.FIRST_CONTAINED) {
IASTNodeLocation[] loc= result.getNodeLocations();
if (loc.length > 0 && loc[0] instanceof IASTMacroExpansionLocation) {
return null;
} }
} }
return result; 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) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getFirstContainedNode(int, int) * @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getFirstContainedNode(int, int)
*/ */
public IASTNode findFirstContainedNode(int offset, int length) { 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) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getNode(int, int) * @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getNode(int, int)
*/ */
public IASTNode findNode(int offset, int length) { 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) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getSurroundingNode(int, int) * @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getSurroundingNode(int, int)
*/ */
public IASTNode findSurroundingNode(int offset, int length) { public IASTNode findEnclosingNode(int offset, int length) {
return getNode(offset, length, ASTNodeMatchKind.MATCH_SURROUNDING); return findNode(offset, length, Relation.ENCLOSING, IASTNode.class);
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getFirstContainedNode(int, int) * @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getFirstContainedNode(int, int)
*/ */
public IASTName findFirstContainedName(int offset, int length) { 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) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getNode(int, int) * @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getNode(int, int)
*/ */
public IASTName findName(int offset, int length) { 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) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getSurroundingNode(int, int) * @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getSurroundingNode(int, int)
*/ */
public IASTName findSurroundingName(int offset, int length) { public IASTName findEnclosingName(int offset, int length) {
return (IASTName) getNode(offset, length, ASTNodeMatchKind.MATCH_SURROUNDING_NAME); 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.ICPPASTVisitor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; 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 { public class FindNodeForOffsetAction extends CPPASTVisitor implements ICASTVisitor, ICPPASTVisitor {
private ASTNode fCandidate= null; private final ASTNodeSpecification<?> fNodeSpec;
private final int fOffset;
private final int fLength;
private final ASTNodeMatchKind fMatchKind;
public FindNodeForOffsetAction(int offset, int length, ASTNodeMatchKind matchKind) { public FindNodeForOffsetAction(ASTNodeSpecification<?> nodeSpec) {
fMatchKind= matchKind; fNodeSpec= nodeSpec;
fOffset = offset;
fLength = length;
shouldVisitNames = true; shouldVisitNames = true;
shouldVisitDeclarations= true; shouldVisitDeclarations= true;
@ -65,21 +64,16 @@ public class FindNodeForOffsetAction extends CPPASTVisitor implements ICASTVisit
shouldVisitBaseSpecifiers= shouldVisitBaseSpecifiers=
shouldVisitNamespaces= shouldVisitNamespaces=
shouldVisitTemplateParameters= shouldVisitTemplateParameters=
shouldVisitTranslationUnit= !matchKind.matchNamesOnly(); shouldVisitTranslationUnit= !nodeSpec.requiresClass(IASTName.class);
} }
public int processNode(IASTNode node) { public int processNode(IASTNode node) {
if (node instanceof ASTNode) { if (node instanceof ASTNode) {
final ASTNode astNode = (ASTNode) node; final ASTNode astNode = (ASTNode) node;
if (astNode.getOffset() > fOffset+fLength || astNode.getOffset() + astNode.getLength() < fOffset) { if (!fNodeSpec.canContainMatches(astNode)) {
return PROCESS_SKIP; return PROCESS_SKIP;
} }
fNodeSpec.visit(astNode);
if (fMatchKind.matches(astNode, fOffset, fLength)) {
if (fCandidate == null || !fMatchKind.isBetterMatch(fCandidate, astNode)) {
fCandidate= astNode;
}
}
} }
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
@ -88,7 +82,7 @@ public class FindNodeForOffsetAction extends CPPASTVisitor implements ICASTVisit
public int visit(IASTDeclaration declaration) { public int visit(IASTDeclaration declaration) {
// use declarations to determine if the search has gone past the // use declarations to determine if the search has gone past the
// offset (i.e. don't know the order the visitor visits the nodes) // 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 PROCESS_ABORT;
return processNode(declaration); return processNode(declaration);
@ -204,8 +198,4 @@ public class FindNodeForOffsetAction extends CPPASTVisitor implements ICASTVisit
public int visit(IASTTranslationUnit tu) { public int visit(IASTTranslationUnit tu) {
return processNode(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.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; 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.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IMacroBinding; import org.eclipse.cdt.core.dom.ast.IMacroBinding;
@ -127,8 +126,8 @@ class ASTBuiltinName extends ASTPreprocessorDefinition {
class ASTMacroReferenceName extends ASTPreprocessorName { class ASTMacroReferenceName extends ASTPreprocessorName {
private ImageLocationInfo fImageLocationInfo; private ImageLocationInfo fImageLocationInfo;
public ASTMacroReferenceName(IASTPreprocessorMacroExpansion parent, int offset, int endOffset, IMacroBinding macro, ImageLocationInfo imgLocationInfo) { public ASTMacroReferenceName(IASTNode parent, ASTNodeProperty property, int offset, int endOffset, IMacroBinding macro, ImageLocationInfo imgLocationInfo) {
super(parent, IASTPreprocessorMacroExpansion.EXPANSION_NAME, offset, endOffset, macro.getNameCharArray(), macro); super(parent, property, offset, endOffset, macro.getNameCharArray(), macro);
fImageLocationInfo= imgLocationInfo; 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.IASTPreprocessorMacroExpansion;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorObjectStyleMacroDefinition; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorObjectStyleMacroDefinition;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorPragmaStatement; 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.IASTPreprocessorUndefStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding; 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.dom.ast.IASTTranslationUnit.IDependencyTree.IASTInclusionNode;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; 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.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.ASTNodeMatchKind.Relation;
/** /**
* Models various AST-constructs obtained from the preprocessor. * 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) { void findNode(ASTNodeSpecification<?> nodeSpec) {
if (matchKind.matches(this, sequenceNumber, length)) { nodeSpec.visit(this);
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;
} }
} }
@ -174,14 +148,35 @@ class ASTElse extends ASTPreprocessorNode implements IASTPreprocessorElseStateme
} }
class ASTIfndef extends ASTDirectiveWithCondition implements IASTPreprocessorIfndefStatement { class ASTIfndef extends ASTDirectiveWithCondition implements IASTPreprocessorIfndefStatement {
public ASTIfndef(IASTTranslationUnit parent, int startNumber, int condNumber, int condEndNumber, boolean active) { private ASTMacroReferenceName fMacroRef;
super(parent, startNumber, condNumber, condEndNumber, active);
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 { class ASTIfdef extends ASTDirectiveWithCondition implements IASTPreprocessorIfdefStatement {
public ASTIfdef(IASTTranslationUnit parent, int startNumber, int condNumber, int condEndNumber, boolean active) { ASTMacroReferenceName fMacroRef;
super(parent, startNumber, condNumber, condEndNumber, active); 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 @Override
ASTNode findNode(int sequenceNumber, int length, ASTNodeMatchKind matchKind) { void findNode(ASTNodeSpecification<?> nodeSpec) {
return findNode(sequenceNumber, length, fName, matchKind); super.findNode(nodeSpec);
nodeSpec.visit(fName);
} }
} }
@ -308,8 +304,9 @@ class ASTMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessor
} }
@Override @Override
ASTNode findNode(int sequenceNumber, int length, ASTNodeMatchKind matchKind) { void findNode(ASTNodeSpecification<?> nodeSpec) {
return findNode(sequenceNumber, length, fName, matchKind); super.findNode(nodeSpec);
nodeSpec.visit(fName);
} }
public void setExpansion(String exp) {assert false;} public void setExpansion(String exp) {assert false;}
@ -410,17 +407,12 @@ class ASTUndef extends ASTPreprocessorNode implements IASTPreprocessorUndefState
private final ASTPreprocessorName fName; private final ASTPreprocessorName fName;
public ASTUndef(IASTTranslationUnit parent, char[] name, int startNumber, int nameNumber, int nameEndNumber, IBinding binding) { public ASTUndef(IASTTranslationUnit parent, char[] name, int startNumber, int nameNumber, int nameEndNumber, IBinding binding) {
super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, startNumber, nameEndNumber); 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() { public ASTPreprocessorName getMacroName() {
return fName; return fName;
} }
@Override
ASTNode findNode(int sequenceNumber, int length, ASTNodeMatchKind matchKind) {
return findNode(sequenceNumber, length, fName, matchKind);
}
} }
class ASTInclusionNode implements IASTInclusionNode { class ASTInclusionNode implements IASTInclusionNode {
@ -546,9 +538,13 @@ class ASTMacroExpansion extends ASTPreprocessorNode implements IASTPreprocessorM
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion#getNestedExpansions() * @see org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion#getNestedExpansions()
*/ */
public IASTName[] getNestedMacroReferences() { public ASTPreprocessorName[] getNestedMacroReferences() {
return fContext.getNestedMacroReferences(); return fContext.getNestedMacroReferences();
} }
public LocationCtxMacroExpansion getContext() {
return fContext;
}
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")

View file

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

View file

@ -13,6 +13,9 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner; 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.IProblem;
import org.eclipse.cdt.core.parser.IToken; import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.core.parser.util.CharArrayMap; import org.eclipse.cdt.core.parser.util.CharArrayMap;
@ -41,13 +44,22 @@ class ExpressionEvaluator {
private Token fTokens; private Token fTokens;
private CharArrayMap<PreprocessorMacro> fDictionary; 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(); fTokens= condition.first();
fDictionary= macroDictionary; fDictionary= macroDictionary;
fLocationMap= map;
fMacrosInDefinedExpressions.clear();
return expression() != 0; return expression() != 0;
} }
public IASTName[] clearMacrosInDefinedExpression() {
IASTName[] result= fMacrosInDefinedExpressions.toArray(new IASTName[fMacrosInDefinedExpressions.size()]);
fMacrosInDefinedExpressions.clear();
return result;
}
private long expression() throws EvalException { private long expression() throws EvalException {
return conditionalExpression(); return conditionalExpression();
@ -254,7 +266,11 @@ class ExpressionEvaluator {
if (LA() != IToken.tIDENTIFIER) { if (LA() != IToken.tIDENTIFIER) {
throw new EvalException(IProblem.SCANNER_ILLEGAL_IDENTIFIER, null); 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(); consume();
if (parenthesis) { if (parenthesis) {
if (LA() != IToken.tRPAREN) { 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.ICPPASTVisitor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; 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.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 { public class FindNodeByImageLocation extends CPPASTVisitor implements ICASTVisitor, ICPPASTVisitor {
private ASTNode fCandidate= null;
private final int fOffset; private final int fOffset;
private final int fLength; private final int fLength;
private final ASTNodeMatchKind fMatchKind; private final ASTNodeSpecification<?> fNodeSpec;
private int fImageOffset;
private int fImageLength;
public FindNodeByImageLocation(int offset, int length, int imgOffset, int imgLength, ASTNodeMatchKind matchKind) { public FindNodeByImageLocation(int offset, int length, ASTNodeSpecification<?> nodeSpec) {
fMatchKind= matchKind; fNodeSpec= nodeSpec;
fOffset = offset; fOffset = offset;
fLength = length; fLength = length;
fImageOffset= imgOffset;
fImageLength= imgLength;
shouldVisitNames = true; shouldVisitNames = true;
shouldVisitDeclarations= true; shouldVisitDeclarations= true;
@ -65,7 +64,7 @@ public class FindNodeByImageLocation extends CPPASTVisitor implements ICASTVisit
shouldVisitBaseSpecifiers= shouldVisitBaseSpecifiers=
shouldVisitNamespaces= shouldVisitNamespaces=
shouldVisitTemplateParameters= shouldVisitTemplateParameters=
shouldVisitTranslationUnit= !matchKind.matchNamesOnly(); shouldVisitTranslationUnit= !nodeSpec.requiresClass(IASTName.class);
} }
public int processNode(IASTNode node) { public int processNode(IASTNode node) {
@ -75,14 +74,10 @@ public class FindNodeByImageLocation extends CPPASTVisitor implements ICASTVisit
return PROCESS_SKIP; return PROCESS_SKIP;
} }
if (fMatchKind.isAcceptableNode(astNode)) { if (fNodeSpec.isAcceptableNode(astNode)) {
IASTImageLocation imageLocation= astNode.getImageLocation(); IASTImageLocation imageLocation= astNode.getImageLocation();
if (imageLocation != null && imageLocation.getLocationKind() == IASTImageLocation.ARGUMENT_TO_MACRO_EXPANSION) { if (imageLocation != null && imageLocation.getLocationKind() == IASTImageLocation.ARGUMENT_TO_MACRO_EXPANSION) {
if (fMatchKind.rangeMatches(imageLocation.getNodeOffset(), imageLocation.getNodeLength(), fImageOffset, fImageLength)) { fNodeSpec.visit(astNode, imageLocation);
if (fCandidate == null || !fMatchKind.isBetterMatch(fCandidate, astNode)) {
fCandidate= astNode;
}
}
} }
} }
} }
@ -184,8 +179,4 @@ public class FindNodeByImageLocation extends CPPASTVisitor implements ICASTVisit
public int visit(IASTTranslationUnit tu) { public int visit(IASTTranslationUnit tu) {
return processNode(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.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IMacroBinding; import org.eclipse.cdt.core.dom.ast.IMacroBinding;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree; 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.ASTNodeSpecification;
import org.eclipse.cdt.internal.core.dom.parser.ASTNodeMatchKind;
/** /**
@ -136,16 +135,13 @@ public interface ILocationResolver {
char[] getUnpreprocessedSignature(IASTFileLocation loc); char[] getUnpreprocessedSignature(IASTFileLocation loc);
/** /**
* Returns a preprocessor node surrounding the given range, or <code>null</code>. The result is either a * Searches for a preprocessor node matching the given specification. Candidates are passed to
* preprocessing directive ({@link IASTPreprocessorStatement}) or a name contained therein {@link IASTName} or * nodeSpec, which selects and stores the best result.
* a macro expansion ({@link IASTName}).
* *
* @param sequenceNumber the sequence number of the start of the interesting region. * @param nodeSpec specification of node to search for.
* @param length the sequence length of the interesting region.
* @param matchOption the kind of the desired match.
*/ */
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 * Returns whether the specified sequence number points into the root file of the
* translation unit, or not. * 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>. * 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; return null;
} }

View file

@ -101,11 +101,11 @@ class LocationCtxContainer extends LocationCtx {
} }
@Override @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; int testEnd= length > 1 ? sequenceNumber+length-1 : sequenceNumber;
final LocationCtx child= findChildLessOrEqualThan(sequenceNumber, true); final LocationCtx child= findChildLessOrEqualThan(sequenceNumber, true);
if (child != null && child.fSequenceNumber+child.getSequenceLength() > testEnd) { if (child != null && child.fSequenceNumber+child.getSequenceLength() > testEnd) {
return child.findSurroundingMacroExpansion(sequenceNumber, length); return child.findEnclosingMacroExpansion(sequenceNumber, length);
} }
return null; 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.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
import org.eclipse.cdt.core.dom.ast.IMacroBinding; 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. * A location context representing macro expansions.
@ -74,7 +71,7 @@ class LocationCtxMacroExpansion extends LocationCtx {
} }
@Override @Override
public LocationCtxMacroExpansion findSurroundingMacroExpansion(int sequenceNumber, int length) { public LocationCtxMacroExpansion findEnclosingMacroExpansion(int sequenceNumber, int length) {
return this; return this;
} }
@ -109,26 +106,6 @@ class LocationCtxMacroExpansion extends LocationCtx {
return null; 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() { public ASTPreprocessorName[] getNestedMacroReferences() {
return fLocationMap.getNestedMacroReferences((ASTMacroExpansion) fExpansionName.getParent()); 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.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTImageLocation; import org.eclipse.cdt.core.dom.ast.IASTImageLocation;
import org.eclipse.cdt.core.dom.ast.IASTName; 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.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition; 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.IMacroBinding;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; 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.ASTNodeSpecification;
import org.eclipse.cdt.internal.core.dom.parser.ASTNodeMatchKind;
import org.eclipse.cdt.internal.core.dom.parser.ASTProblem; import org.eclipse.cdt.internal.core.dom.parser.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 * 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. * @param imageLocationInfo the image-location for the name of the macro.
*/ */
public IASTName encounterImplicitMacroExpansion(IMacroBinding macro, ImageLocationInfo imageLocationInfo) { 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. * 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. * @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; final int length= endNumber-nameNumber;
ASTMacroExpansion expansion= new ASTMacroExpansion(fTranslationUnit, nameNumber, endNumber); 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++) { for (int i = 0; i < implicitMacroReferences.length; i++) {
ASTMacroReferenceName name = (ASTMacroReferenceName) implicitMacroReferences[i]; ASTMacroReferenceName name = (ASTMacroReferenceName) implicitMacroReferences[i];
name.setParent(expansion); name.setParent(expansion);
name.setOffsetAndLength(nameNumber, length); name.setOffsetAndLength(nameNumber, length);
addMacroReference(name); addMacroReference(name);
} }
addMacroReference(explicitRef);
LocationCtxMacroExpansion expansionCtx= new LocationCtxMacroExpansion(this, (LocationCtxContainer) fCurrentContext, nameOffset, endOffset, endNumber, contextLength, imageLocations, explicitRef); LocationCtxMacroExpansion expansionCtx= new LocationCtxMacroExpansion(this, (LocationCtxContainer) fCurrentContext, nameOffset, endOffset, endNumber, contextLength, imageLocations, explicitRef);
expansion.setContext(expansionCtx); expansion.setContext(expansionCtx);
@ -177,7 +187,9 @@ public class LocationMap implements ILocationResolver {
} }
private void addMacroReference(ASTPreprocessorName name) { 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)); 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); startOffset= getSequenceNumberForOffset(startOffset);
condOffset= getSequenceNumberForOffset(condOffset); condOffset= getSequenceNumberForOffset(condOffset);
condEndOffset= getSequenceNumberForOffset(condEndOffset); condEndOffset= getSequenceNumberForOffset(condEndOffset);
// compatible with 4.0: endOffset= getSequenceNumberForOffset(endOffset); // 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) { public void encounterPoundEndIf(int startOffset, int endOffset) {
@ -263,30 +285,42 @@ public class LocationMap implements ILocationResolver {
fDirectives.add(new ASTPragma(fTranslationUnit, startOffset, condOffset, condEndOffset)); 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); startOffset= getSequenceNumberForOffset(startOffset);
condOffset= getSequenceNumberForOffset(condOffset); condOffset= getSequenceNumberForOffset(condOffset);
condEndOffset= getSequenceNumberForOffset(condEndOffset); condEndOffset= getSequenceNumberForOffset(condEndOffset);
// not using endOffset, compatible with 4.0: endOffset= getSequenceNumberForOffset(endOffset); // 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); startOffset= getSequenceNumberForOffset(startOffset);
condOffset= getSequenceNumberForOffset(condOffset); condOffset= getSequenceNumberForOffset(condOffset);
condEndOffset= getSequenceNumberForOffset(condEndOffset); condEndOffset= getSequenceNumberForOffset(condEndOffset);
// not using endOffset, compatible with 4.0: endOffset= getSequenceNumberForOffset(endOffset); // 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); startOffset= getSequenceNumberForOffset(startOffset);
condOffset= getSequenceNumberForOffset(condOffset); condOffset= getSequenceNumberForOffset(condOffset);
condEndOffset= getSequenceNumberForOffset(condEndOffset); condEndOffset= getSequenceNumberForOffset(condEndOffset);
// not using endOffset, compatible with 4.0: endOffset= getSequenceNumberForOffset(endOffset); // 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) { public void encounterPoundDefine(int startOffset, int nameOffset, int nameEndOffset, int expansionOffset, int endOffset, IMacroBinding macrodef) {
startOffset= getSequenceNumberForOffset(startOffset); startOffset= getSequenceNumberForOffset(startOffset);
nameOffset= getSequenceNumberForOffset(nameOffset); nameOffset= getSequenceNumberForOffset(nameOffset);
@ -434,59 +468,93 @@ public class LocationMap implements ILocationResolver {
return null; return null;
} }
public ASTNode findPreprocessorNode(int sequenceNumber, int length, ASTNodeMatchKind matchKind) { public void findPreprocessorNode(ASTNodeSpecification<?> nodeSpec) {
int lower=0; final int sequenceStart= nodeSpec.getSequenceStart();
int upper= fDirectives.size()-1; final int sequenceEnd= nodeSpec.getSequenceEnd();
while(lower <= upper) {
int middle= (lower+upper)/2; // check directives
ASTPreprocessorNode candidate= fDirectives.get(middle); int from= findLastNodeBefore(fDirectives, sequenceStart);
ASTNode result= candidate.findNode(sequenceNumber, length, matchKind); for (int i= from+1; i < fDirectives.size(); i++) {
if (result != null) { ASTPreprocessorNode directive= fDirectives.get(i);
if (matchKind.getRelationToSelection() == Relation.FIRST_CONTAINED) { if (directive.getOffset() > sequenceEnd) {
if (middle>lower) { break;
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;
} }
directive.findNode(nodeSpec);
} }
// search for a macro-expansion
LocationCtxMacroExpansion ctx= fRootContext.findSurroundingMacroExpansion(sequenceNumber, length); // check macro references and expansions
if (ctx != null) { from= findLastMacroReferenceBefore(fMacroReferences, sequenceStart);
ASTNode candidate= ctx.findNode(sequenceNumber, length, matchKind); for (int i= from+1; i < fMacroReferences.size(); i++) {
int imageOffset= ctx.fEndOffsetInParent + sequenceNumber - ctx.fSequenceNumber; ASTPreprocessorNode macroRef= fMacroReferences.get(i);
if (fTranslationUnit != null) { if (macroRef.getOffset() > sequenceEnd) {
FindNodeByImageLocation visitor= new FindNodeByImageLocation(ctx.fSequenceNumber, ctx.getSequenceLength(), imageOffset, length, matchKind); break;
fTranslationUnit.accept(visitor);
ASTNode candidate2= visitor.getNode();
if (matchKind.isBetterMatch(candidate2, candidate)) {
candidate= candidate2;
}
} }
ASTPreprocessorName[] nested= ctx.getNestedMacroReferences(); if (macroRef.getPropertyInParent() == IASTPreprocessorMacroExpansion.NESTED_EXPANSION_NAME) {
for (ASTPreprocessorName name : nested) { continue;
IASTImageLocation imageLoc= name.getImageLocation(); }
if (imageLoc != null && imageLoc.getLocationKind() == IASTImageLocation.ARGUMENT_TO_MACRO_EXPANSION) { nodeSpec.visit(macroRef);
if (matchKind.rangeMatches(imageLoc.getNodeOffset(), imageLoc.getNodeLength(), imageOffset, length)) { IASTNode parent= macroRef.getParent();
if (matchKind.isBetterMatch(name, candidate)) { if (parent instanceof ASTMacroExpansion) {
candidate= name; 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) { public int getSequenceNumberForFileOffset(String filePath, int fileOffset) {
LocationCtx ctx= fRootContext; LocationCtx ctx= fRootContext;
if (filePath != null) { if (filePath != null) {

View file

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

View file

@ -10,7 +10,6 @@
* IBM Corporation * IBM Corporation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.ui.editor; package org.eclipse.cdt.internal.ui.editor;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
@ -83,7 +82,7 @@ public class CElementHyperlinkDetector implements IHyperlinkDetector {
final int offset= region.getOffset(); final int offset= region.getOffset();
final int length= Math.max(1, region.getLength()); final int length= Math.max(1, region.getLength());
final IASTNodeSelector nodeSelector= ast.getNodeSelector(null); final IASTNodeSelector nodeSelector= ast.getNodeSelector(null);
IASTName selectedName= nodeSelector.findSurroundingName(offset, length); IASTName selectedName= nodeSelector.findEnclosingName(offset, length);
IASTFileLocation linkLocation= null; IASTFileLocation linkLocation= null;
if (selectedName != null) { // found a name if (selectedName != null) { // found a name
// prefer include statement over the include name // prefer include statement over the include name
@ -96,7 +95,7 @@ public class CElementHyperlinkDetector implements IHyperlinkDetector {
} }
else { else {
// search for include statement // search for include statement
final IASTNode cand= nodeSelector.findSurroundingNode(offset, length); final IASTNode cand= nodeSelector.findEnclosingNode(offset, length);
if (cand instanceof IASTPreprocessorIncludeStatement) { if (cand instanceof IASTPreprocessorIncludeStatement) {
linkLocation= cand.getFileLocation(); 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() { return ASTProvider.getASTProvider().runOnAST(tu, ASTProvider.WAIT_YES, monitor, new ASTRunnable() {
public IStatus runOnAST(ILanguage language, IASTTranslationUnit ast) throws CoreException { public IStatus runOnAST(ILanguage language, IASTTranslationUnit ast) throws CoreException {
if (ast != null) { 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) { if (searchName != null) {
IBinding binding = searchName.resolveBinding(); IBinding binding = searchName.resolveBinding();
if (binding != null) if (binding != null)

View file

@ -130,7 +130,7 @@ public class OpenDeclarationsAction extends SelectionParseAction {
int selectionStart = selNode.getOffset(); int selectionStart = selNode.getOffset();
int selectionLength = selNode.getLength(); 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 if (searchName != null) { // just right, only one name selected
boolean found= false; boolean found= false;
final IASTNode parent = searchName.getParent(); final IASTNode parent = searchName.getParent();

View file

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

View file

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