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:
parent
915b4a1e35
commit
789b2ea330
31 changed files with 1033 additions and 463 deletions
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2007 IBM Corporation and others.
|
||||
* Copyright (c) 2005, 2008 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -64,11 +64,11 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
String code = "void f() { int x; x=3; }"; //$NON-NLS-1$
|
||||
int offset1 = code.indexOf( "x=" ); //$NON-NLS-1$
|
||||
int length = "x".length(); //$NON-NLS-1$
|
||||
IASTNode node = parse( code, ParserLanguage.C, offset1, length );
|
||||
IASTNode node = parse( code, ParserLanguage.C, offset1, length ).getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue( node instanceof IASTIdExpression );
|
||||
assertEquals(((IASTIdExpression)node).getName().toString(), "x"); //$NON-NLS-1$
|
||||
node = parse( code, ParserLanguage.CPP, offset1, length );
|
||||
node = parse( code, ParserLanguage.CPP, offset1, length ).getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue( node instanceof IASTIdExpression );
|
||||
assertEquals(((IASTIdExpression)node).getName().toString(), "x"); //$NON-NLS-1$
|
||||
|
@ -83,7 +83,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
String code = "int x(){x( );}"; //$NON-NLS-1$
|
||||
int offset1 = code.indexOf( "x( " ); //$NON-NLS-1$
|
||||
int length = "x".length(); //$NON-NLS-1$
|
||||
IASTNode node = parse( code, ParserLanguage.C, offset1, length );
|
||||
IASTNode node = parse( code, ParserLanguage.C, offset1, length ).getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue( node instanceof IASTIdExpression );
|
||||
assertEquals(((IASTIdExpression)node).getName().toString(), "x"); //$NON-NLS-1$
|
||||
|
@ -91,7 +91,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
assertNotNull(name.resolveBinding());
|
||||
assertTrue(name.resolveBinding() instanceof IFunction);
|
||||
assertEquals(((IFunction)name.resolveBinding()).getName(), "x"); //$NON-NLS-1$
|
||||
node = parse( code, ParserLanguage.CPP, offset1, length );
|
||||
node = parse( code, ParserLanguage.CPP, offset1, length ).getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue( node instanceof IASTIdExpression );
|
||||
assertEquals(((IASTIdExpression)node).getName().toString(), "x"); //$NON-NLS-1$
|
||||
|
@ -184,7 +184,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
String code = "int main( int argc ) { int x = argc; }"; //$NON-NLS-1$
|
||||
int offset1 = code.indexOf( "argc;" ); //$NON-NLS-1$
|
||||
int length = "argc".length(); //$NON-NLS-1$
|
||||
IASTNode node = parse( code, ParserLanguage.C, offset1, length );
|
||||
IASTNode node = parse( code, ParserLanguage.C, offset1, length ).getParent().getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue( node instanceof IASTInitializerExpression );
|
||||
assertEquals( ((IASTIdExpression)((IASTInitializerExpression)node).getExpression()).getName().toString(), "argc" ); //$NON-NLS-1$
|
||||
|
@ -192,7 +192,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
assertNotNull(name.resolveBinding());
|
||||
assertTrue(name.resolveBinding() instanceof IParameter);
|
||||
assertEquals(((IParameter)name.resolveBinding()).getName(), "argc"); //$NON-NLS-1$
|
||||
node = parse( code, ParserLanguage.CPP, offset1, length );
|
||||
node = parse( code, ParserLanguage.CPP, offset1, length ).getParent().getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue( node instanceof IASTInitializerExpression );
|
||||
assertEquals( ((IASTIdExpression)((IASTInitializerExpression)node).getExpression()).getName().toString(), "argc" ); //$NON-NLS-1$
|
||||
|
@ -357,6 +357,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
{
|
||||
case 0:
|
||||
case 1:
|
||||
node= node.getParent().getParent();
|
||||
assertTrue(node instanceof IASTTypeId);
|
||||
assertEquals(((IASTNamedTypeSpecifier)((IASTTypeId)node).getDeclSpecifier()).getName().toString(), "Gonzo"); //$NON-NLS-1$
|
||||
name = ((IASTNamedTypeSpecifier)((IASTTypeId)node).getDeclSpecifier()).getName();
|
||||
|
@ -425,7 +426,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
String code = writer.toString();
|
||||
int startIndex = code.indexOf( "foo(1)"); //$NON-NLS-1$
|
||||
int length = "foo".length(); //$NON-NLS-1$
|
||||
IASTNode node = parse( code, ParserLanguage.C, startIndex, length );
|
||||
IASTNode node = parse( code, ParserLanguage.C, startIndex, length ).getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue(node instanceof IASTIdExpression);
|
||||
assertEquals(((IASTIdExpression)node).getName().toString(), "foo"); //$NON-NLS-1$
|
||||
|
@ -433,7 +434,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
assertNotNull(name.resolveBinding());
|
||||
assertTrue(name.resolveBinding() instanceof IFunction);
|
||||
assertEquals(((IFunction)name.resolveBinding()).getName(), "foo"); //$NON-NLS-1$
|
||||
node = parse( code, ParserLanguage.CPP, startIndex, length );
|
||||
node = parse( code, ParserLanguage.CPP, startIndex, length ).getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue(node instanceof IASTIdExpression);
|
||||
assertEquals(((IASTIdExpression)node).getName().toString(), "foo"); //$NON-NLS-1$
|
||||
|
@ -466,7 +467,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
assertTrue(name.resolveBinding() instanceof IEnumeration);
|
||||
assertEquals(((IEnumeration)name.resolveBinding()).getName(), "EColours"); //$NON-NLS-1$
|
||||
startIndex = codeCPP.indexOf( "EColours color"); //$NON-NLS-1$
|
||||
node = parse( codeCPP, ParserLanguage.CPP, startIndex, length );
|
||||
node = parse( codeCPP, ParserLanguage.CPP, startIndex, length ).getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue(node instanceof IASTNamedTypeSpecifier);
|
||||
assertEquals(((IASTNamedTypeSpecifier)node).getName().toString(), "EColours"); //$NON-NLS-1$
|
||||
|
@ -519,7 +520,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
String code = writer.toString();
|
||||
int startIndex = code.indexOf( "static_function( file )"); //$NON-NLS-1$
|
||||
int length = "static_function".length(); //$NON-NLS-1$
|
||||
IASTNode node = parse( code, ParserLanguage.C, startIndex, length );
|
||||
IASTNode node = parse( code, ParserLanguage.C, startIndex, length ).getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue(node instanceof IASTIdExpression);
|
||||
assertEquals(((IASTIdExpression)node).getName().toString(), "static_function"); //$NON-NLS-1$
|
||||
|
@ -527,7 +528,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
assertNotNull(name.resolveBinding());
|
||||
assertTrue(name.resolveBinding() instanceof IFunction);
|
||||
assertEquals(((IFunction)name.resolveBinding()).getName(), "static_function"); //$NON-NLS-1$
|
||||
node = parse( code, ParserLanguage.CPP, startIndex, length );
|
||||
node = parse( code, ParserLanguage.CPP, startIndex, length ).getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue(node instanceof IASTIdExpression);
|
||||
assertEquals(((IASTIdExpression)node).getName().toString(), "static_function"); //$NON-NLS-1$
|
||||
|
@ -569,7 +570,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
int startIndex = code.indexOf( "/**/fprintf") + 4; //$NON-NLS-1$
|
||||
int length = "fprintf".length(); //$NON-NLS-1$
|
||||
|
||||
IASTNode node = parse( code, ParserLanguage.C, startIndex, length );
|
||||
IASTNode node = parse( code, ParserLanguage.C, startIndex, length ).getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue(node instanceof IASTIdExpression);
|
||||
assertEquals(((IASTIdExpression)node).getName().toString(), "fprintf"); //$NON-NLS-1$
|
||||
|
@ -577,7 +578,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
assertNotNull(name.resolveBinding());
|
||||
assertTrue(name.resolveBinding() instanceof IFunction);
|
||||
assertEquals(((IFunction)name.resolveBinding()).getName(), "fprintf"); //$NON-NLS-1$
|
||||
node = parse( code, ParserLanguage.CPP, startIndex, length );
|
||||
node = parse( code, ParserLanguage.CPP, startIndex, length ).getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue(node instanceof IASTIdExpression);
|
||||
assertEquals(((IASTIdExpression)node).getName().toString(), "fprintf"); //$NON-NLS-1$
|
||||
|
@ -614,7 +615,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
assertTrue(name.resolveBinding() instanceof ICompositeType);
|
||||
assertEquals(((ICompositeType)name.resolveBinding()).getName(), "Squaw"); //$NON-NLS-1$
|
||||
startIndex = codeCPP.indexOf( "sizeof( ") + "sizeof( ".length(); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
node = parse( codeCPP, ParserLanguage.CPP, startIndex, length );
|
||||
node = parse( codeCPP, ParserLanguage.CPP, startIndex, length ).getParent().getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue(node instanceof IASTTypeId);
|
||||
assertEquals(((IASTNamedTypeSpecifier)((IASTTypeId)node).getDeclSpecifier()).getName().toString(), "Squaw"); //$NON-NLS-1$
|
||||
|
@ -638,7 +639,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
String code = writer.toString();
|
||||
int startIndex = code.indexOf( "return ") + "return ".length(); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
int length = "FOUND_ME".length(); //$NON-NLS-1$
|
||||
IASTNode node = parse( code, ParserLanguage.CPP, startIndex, length );
|
||||
IASTNode node = parse( code, ParserLanguage.CPP, startIndex, length ).getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue(node instanceof IASTIdExpression);
|
||||
assertEquals(((IASTIdExpression)node).getName().toString(), "FOUND_ME"); //$NON-NLS-1$
|
||||
|
@ -739,7 +740,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
String code = writer.toString();
|
||||
int startIndex = code.indexOf( "new B" ) + 4; //$NON-NLS-1$
|
||||
int length = "B".length(); //$NON-NLS-1$
|
||||
IASTNode node = parse( code, ParserLanguage.CPP, startIndex, length );
|
||||
IASTNode node = parse( code, ParserLanguage.CPP, startIndex, length ).getParent().getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue(node instanceof IASTTypeId);
|
||||
assertEquals(((IASTNamedTypeSpecifier)((IASTTypeId)node).getDeclSpecifier()).getName().toString(), "B"); //$NON-NLS-1$
|
||||
|
@ -758,7 +759,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
String code = writer.toString();
|
||||
int startIndex = code.indexOf( "(A*)" ) + 1; //$NON-NLS-1$
|
||||
int length = "A".length(); //$NON-NLS-1$
|
||||
IASTNode node = parse( code, ParserLanguage.CPP, startIndex, length );
|
||||
IASTNode node = parse( code, ParserLanguage.CPP, startIndex, length ).getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue(node instanceof IASTNamedTypeSpecifier);
|
||||
assertEquals(((IASTNamedTypeSpecifier)node).getName().toString(), "A"); //$NON-NLS-1$
|
||||
|
@ -845,7 +846,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
|
||||
index = code.indexOf( "Card( int rank );") + 10; //$NON-NLS-1$
|
||||
length = "rank".length(); //$NON-NLS-1$
|
||||
node = parse( code, ParserLanguage.CPP, index, length );
|
||||
node = parse( code, ParserLanguage.CPP, index, length ).getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue(node instanceof IASTDeclarator);
|
||||
assertEquals(((IASTDeclarator)node).getName().toString(), "rank"); //$NON-NLS-1$
|
||||
|
@ -855,7 +856,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
assertEquals(((IVariable)name.resolveBinding()).getName(), "rank"); //$NON-NLS-1$
|
||||
|
||||
index = code.indexOf( "int rank;") + 4; //$NON-NLS-1$
|
||||
node = parse( code, ParserLanguage.CPP, index, length );
|
||||
node = parse( code, ParserLanguage.CPP, index, length ).getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue(node instanceof IASTDeclarator);
|
||||
assertEquals(((IASTDeclarator)node).getName().toString(), "rank"); //$NON-NLS-1$
|
||||
|
@ -898,7 +899,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
|
||||
index = code.indexOf( "Card::Card( int rank )") + 16; //$NON-NLS-1$
|
||||
length = "rank".length(); //$NON-NLS-1$
|
||||
node = parse( code, ParserLanguage.CPP, index, length );
|
||||
node = parse( code, ParserLanguage.CPP, index, length ).getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue(node instanceof IASTDeclarator);
|
||||
assertEquals(((IASTDeclarator)node).getName().toString(), "rank"); //$NON-NLS-1$
|
||||
|
@ -958,7 +959,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
assertEquals(((ICPPField)name.resolveBinding()).getName(), "rank"); //$NON-NLS-1$
|
||||
|
||||
index = code.indexOf( "this->rank = rank;") + 13; //$NON-NLS-1$
|
||||
node = parse( code, ParserLanguage.CPP, index, length );
|
||||
node = parse( code, ParserLanguage.CPP, index, length ).getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue(node instanceof IASTIdExpression);
|
||||
assertEquals(((IASTIdExpression)node).getName().toString(), "rank"); //$NON-NLS-1$
|
||||
|
@ -999,7 +1000,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
|
||||
index = code.indexOf( "this->rank = getRank();") + 13; //$NON-NLS-1$
|
||||
length = "getRank".length(); //$NON-NLS-1$
|
||||
node = parse( code, ParserLanguage.CPP, index, length );
|
||||
node = parse( code, ParserLanguage.CPP, index, length ).getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue(node instanceof IASTIdExpression);
|
||||
assertEquals(((IASTIdExpression)node).getName().toString(), "getRank"); //$NON-NLS-1$
|
||||
|
@ -1037,7 +1038,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
String code = writer.toString();
|
||||
int index = code.indexOf( "void f(int itself){}") + 11; //$NON-NLS-1$
|
||||
int length = "itself".length(); //$NON-NLS-1$
|
||||
IASTNode node = parse( code, ParserLanguage.C, index, length );
|
||||
IASTNode node = parse( code, ParserLanguage.C, index, length ).getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue(node instanceof IASTDeclarator);
|
||||
assertEquals(((IASTDeclarator)node).getName().toString(), "itself"); //$NON-NLS-1$
|
||||
|
@ -1045,7 +1046,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
assertNotNull(name.resolveBinding());
|
||||
assertTrue(name.resolveBinding() instanceof IVariable);
|
||||
assertEquals(((IVariable)name.resolveBinding()).getName(), "itself"); //$NON-NLS-1$
|
||||
node = parse( code, ParserLanguage.CPP, index, length );
|
||||
node = parse( code, ParserLanguage.CPP, index, length ).getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue(node instanceof IASTDeclarator);
|
||||
assertEquals(((IASTDeclarator)node).getName().toString(), "itself"); //$NON-NLS-1$
|
||||
|
@ -1119,7 +1120,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
String code = buffer.toString();
|
||||
int index = code.indexOf("x;"); //$NON-NLS-1$
|
||||
int length = "x".length(); //$NON-NLS-1$
|
||||
IASTNode node = parse( code, ParserLanguage.C, true, true, index, length );
|
||||
IASTNode node = parse( code, ParserLanguage.C, true, true, index, length ).getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue(node instanceof IASTDeclarator);
|
||||
assertEquals(((IASTDeclarator)node).getName().toString(), "x"); //$NON-NLS-1$
|
||||
|
@ -1138,7 +1139,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
String code = buffer.toString();
|
||||
int index = code.indexOf("x;"); //$NON-NLS-1$
|
||||
int length = "x".length(); //$NON-NLS-1$
|
||||
IASTNode node = parse( code, ParserLanguage.C, true, true, index, length );
|
||||
IASTNode node = parse( code, ParserLanguage.C, true, true, index, length ).getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue(node instanceof IASTDeclarator);
|
||||
assertEquals(((IASTDeclarator)node).getName().toString(), "x"); //$NON-NLS-1$
|
||||
|
@ -1177,7 +1178,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
String code = buffer.toString();
|
||||
int index = code.indexOf("y;"); //$NON-NLS-1$
|
||||
int length = "y".length(); //$NON-NLS-1$
|
||||
IASTNode node = parse( code, ParserLanguage.C, true, true, index, length );
|
||||
IASTNode node = parse( code, ParserLanguage.C, true, true, index, length ).getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue(node instanceof IASTDeclarator);
|
||||
assertEquals(((IASTDeclarator)node).getName().toString(), "y"); //$NON-NLS-1$
|
||||
|
@ -1198,7 +1199,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
String code = buffer.toString();
|
||||
int index = code.indexOf("c x;"); //$NON-NLS-1$
|
||||
int length = "c".length(); //$NON-NLS-1$
|
||||
IASTNode node = parse( code, ParserLanguage.C, true, true, index, length );
|
||||
IASTNode node = parse( code, ParserLanguage.C, true, true, index, length ).getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue(node instanceof IASTNamedTypeSpecifier);
|
||||
assertEquals(((IASTNamedTypeSpecifier)node).getName().toString(), "c"); //$NON-NLS-1$
|
||||
|
@ -1209,7 +1210,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
|
||||
index = code.indexOf("x;"); //$NON-NLS-1$
|
||||
length = "x".length(); //$NON-NLS-1$
|
||||
node = parse( code, ParserLanguage.C, true, true, index, length );
|
||||
node = parse( code, ParserLanguage.C, true, true, index, length ).getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue(node instanceof IASTDeclarator);
|
||||
assertEquals(((IASTDeclarator)node).getName().toString(), "x"); //$NON-NLS-1$
|
||||
|
@ -1308,7 +1309,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
String code = buffer.toString();
|
||||
int index = code.indexOf("b,a"); //$NON-NLS-1$
|
||||
int length = "b".length(); //$NON-NLS-1$
|
||||
IASTNode node = parse( code, ParserLanguage.C, true, true, index, length );
|
||||
IASTNode node = parse( code, ParserLanguage.C, true, true, index, length ).getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue(node instanceof IASTDeclarator);
|
||||
IASTName name = ((IASTDeclarator)node).getName();
|
||||
|
@ -1518,7 +1519,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
|
||||
index = code.indexOf("c;"); //$NON-NLS-1$
|
||||
length = "c".length(); //$NON-NLS-1$
|
||||
node = parse( code, ParserLanguage.CPP, index, length );
|
||||
node = parse( code, ParserLanguage.CPP, index, length ).getParent();
|
||||
assertNotNull(node);
|
||||
assertTrue( node instanceof IASTDeclarator);
|
||||
assertEquals(((IASTDeclarator)node).getName().toString(), "c"); //$NON-NLS-1$
|
||||
|
@ -1648,7 +1649,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest {
|
|||
public void testBug86126() throws Exception {
|
||||
String header= "foo"+System.currentTimeMillis()+".h";
|
||||
String source= "blah"+System.currentTimeMillis()+".c";
|
||||
importFile(header, "int x;\r\n"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
importFile(header, "int x;\r\n"); //$NON-NLS-1$
|
||||
String code = "#include \""+header+"\"\r\n"; //$NON-NLS-1$
|
||||
IFile file = importFile(source, code);
|
||||
int offset1 = code.indexOf( "#include \""+header+"\"" ); //$NON-NLS-1$
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2007 IBM Corporation and others.
|
||||
* Copyright (c) 2004, 2008 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -40,6 +40,7 @@ public class DOMParserTestSuite extends TestCase {
|
|||
suite.addTestSuite( AST2UtilTests.class );
|
||||
suite.addTestSuite( AST2UtilOldTests.class );
|
||||
suite.addTestSuite( AST2SelectionParseTest.class );
|
||||
suite.addTest( ASTNodeSelectorTest.suite());
|
||||
suite.addTestSuite( CodeReaderCacheTest.class );
|
||||
suite.addTestSuite( AST2CPPSpecTest.class );
|
||||
suite.addTestSuite( AST2CPPSpecFailingTest.class );
|
||||
|
|
|
@ -283,7 +283,7 @@ public class LocationMapTests extends BaseTestCase {
|
|||
private void checkMacroUndef(IASTPreprocessorStatement s, IBinding binding, String image, String name, String nameImage,
|
||||
String filename, int offset, int length, int line, int nameOffset, int nameLength) {
|
||||
IASTPreprocessorUndefStatement st= (IASTPreprocessorUndefStatement) s;
|
||||
checkName(st.getMacroName(), binding, name, st, IASTPreprocessorUndefStatement.MACRO_NAME, ROLE_UNCLEAR, filename, nameOffset, nameLength, line, line, nameImage);
|
||||
checkName(st.getMacroName(), binding, name, st, IASTPreprocessorStatement.MACRO_NAME, ROLE_UNCLEAR, filename, nameOffset, nameLength, line, line, nameImage);
|
||||
checkASTNode(st, fTu, PROP_PST, filename, offset, length, line, line, image);
|
||||
}
|
||||
|
||||
|
@ -344,8 +344,8 @@ public class LocationMapTests extends BaseTestCase {
|
|||
|
||||
public void testIf() {
|
||||
init(DIGITS);
|
||||
fLocationMap.encounterPoundIf(0, 0, 0, 0, false);
|
||||
fLocationMap.encounterPoundIf(0, 1, 3, 16, true);
|
||||
fLocationMap.encounterPoundIf(0, 0, 0, 0, false, IASTName.EMPTY_NAME_ARRAY);
|
||||
fLocationMap.encounterPoundIf(0, 1, 3, 16, true, IASTName.EMPTY_NAME_ARRAY);
|
||||
IASTPreprocessorStatement[] prep= fLocationMap.getAllPreprocessorStatements();
|
||||
assertEquals(2, prep.length);
|
||||
checkIf(prep[0], "", "", false, FN, 0, 0, 1);
|
||||
|
@ -354,8 +354,8 @@ public class LocationMapTests extends BaseTestCase {
|
|||
|
||||
public void testIfdef() {
|
||||
init(DIGITS);
|
||||
fLocationMap.encounterPoundIfdef(0, 0, 0, 0, false);
|
||||
fLocationMap.encounterPoundIfdef(0, 1, 3, 16, true);
|
||||
fLocationMap.encounterPoundIfdef(0, 0, 0, 0, false, null);
|
||||
fLocationMap.encounterPoundIfdef(0, 1, 3, 16, true, null);
|
||||
IASTPreprocessorStatement[] prep= fLocationMap.getAllPreprocessorStatements();
|
||||
assertEquals(2, prep.length);
|
||||
checkIfdef(prep[0], "", "", false, FN, 0, 0, 1);
|
||||
|
@ -364,8 +364,8 @@ public class LocationMapTests extends BaseTestCase {
|
|||
|
||||
public void testIfndef() {
|
||||
init(DIGITS);
|
||||
fLocationMap.encounterPoundIfndef(0, 0, 0, 0, false);
|
||||
fLocationMap.encounterPoundIfndef(0, 1, 3, 16, true);
|
||||
fLocationMap.encounterPoundIfndef(0, 0, 0, 0, false, null);
|
||||
fLocationMap.encounterPoundIfndef(0, 1, 3, 16, true, null);
|
||||
IASTPreprocessorStatement[] prep= fLocationMap.getAllPreprocessorStatements();
|
||||
assertEquals(2, prep.length);
|
||||
checkIfndef(prep[0], "", "", false, FN, 0, 0, 1);
|
||||
|
@ -374,8 +374,8 @@ public class LocationMapTests extends BaseTestCase {
|
|||
|
||||
public void testElif() {
|
||||
init(DIGITS);
|
||||
fLocationMap.encounterPoundElif(0, 0, 0, 0, false);
|
||||
fLocationMap.encounterPoundElif(0, 1, 3, 16, true);
|
||||
fLocationMap.encounterPoundElif(0, 0, 0, 0, false, IASTName.EMPTY_NAME_ARRAY);
|
||||
fLocationMap.encounterPoundElif(0, 1, 3, 16, true, IASTName.EMPTY_NAME_ARRAY);
|
||||
IASTPreprocessorStatement[] prep= fLocationMap.getAllPreprocessorStatements();
|
||||
assertEquals(2, prep.length);
|
||||
checkElif(prep[0], "", "", false, FN, 0, 0, 1);
|
||||
|
@ -476,11 +476,11 @@ public class LocationMapTests extends BaseTestCase {
|
|||
|
||||
refs= fLocationMap.getReferences(macro1);
|
||||
assertEquals(1, refs.length);
|
||||
checkName(refs[0], macro1, "n1", refs[0].getParent(), IASTPreprocessorMacroExpansion.EXPANSION_NAME, ROLE_REFERENCE, FN, 110, 15, 2, 2, new String(LONGDIGITS, 110, 15));
|
||||
checkName(refs[0], macro1, "n1", refs[0].getParent(), IASTPreprocessorMacroExpansion.NESTED_EXPANSION_NAME, ROLE_REFERENCE, FN, 110, 15, 2, 2, new String(LONGDIGITS, 110, 15));
|
||||
|
||||
refs= fLocationMap.getReferences(macro2);
|
||||
assertEquals(1, refs.length);
|
||||
checkName(refs[0], macro2, "n2", refs[0].getParent(), IASTPreprocessorMacroExpansion.EXPANSION_NAME, ROLE_REFERENCE, FN, 110, 15, 2, 2, new String(LONGDIGITS, 110, 15));
|
||||
checkName(refs[0], macro2, "n2", refs[0].getParent(), IASTPreprocessorMacroExpansion.NESTED_EXPANSION_NAME, ROLE_REFERENCE, FN, 110, 15, 2, 2, new String(LONGDIGITS, 110, 15));
|
||||
}
|
||||
|
||||
public void testContexts() {
|
||||
|
|
|
@ -11,8 +11,10 @@
|
|||
package org.eclipse.cdt.core.dom.ast;
|
||||
|
||||
/**
|
||||
* Interface for searching nodes of a file in a translation unit. An instance of this interface can
|
||||
* be obtained via {@link IASTTranslationUnit#getNodeSelector(String)}.
|
||||
* Interface for searching nodes in a translation unit. An instance of this interface, responsible
|
||||
* for one file contained in a translation-unit, can be obtained using
|
||||
* {@link IASTTranslationUnit#getNodeSelector(String)}.
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
public interface IASTNodeSelector {
|
||||
|
@ -23,9 +25,9 @@ public interface IASTNodeSelector {
|
|||
IASTName findName(int offset, int length);
|
||||
|
||||
/**
|
||||
* Returns the smallest name surrounding the given range, or <code>null</code> if there is no such node.
|
||||
* Returns the smallest name enclosing the given range, or <code>null</code> if there is no such node.
|
||||
*/
|
||||
IASTName findSurroundingName(int offset, int length);
|
||||
IASTName findEnclosingName(int offset, int length);
|
||||
|
||||
/**
|
||||
* Returns the first name contained in the given range, or <code>null</code> if there is no such node.
|
||||
|
@ -34,16 +36,31 @@ public interface IASTNodeSelector {
|
|||
|
||||
/**
|
||||
* Returns the node for the exact given range, or <code>null</code> if there is no such node.
|
||||
* <p>
|
||||
* For nodes with the same location, macro-expansions ({@link IASTPreprocessorMacroExpansion}) are preferred
|
||||
* over c/c++-nodes and children are preferred over their parents.
|
||||
*/
|
||||
IASTNode findNode(int offset, int length);
|
||||
|
||||
/**
|
||||
* Returns the smallest node surrounding the given range, or <code>null</code> if there is no such node.
|
||||
* Returns the smallest node enclosing the given range, or <code>null</code> if there is no such node.
|
||||
* <p>
|
||||
* For nodes with the same location, macro-expansions ({@link IASTPreprocessorMacroExpansion}) are preferred
|
||||
* over c/c++-nodes nodes and children are preferred over their parents.
|
||||
* Prefers children over parents.
|
||||
*/
|
||||
IASTNode findSurroundingNode(int offset, int length);
|
||||
IASTNode findEnclosingNode(int offset, int length);
|
||||
|
||||
/**
|
||||
* Returns the first node contained in the given range, or <code>null</code> if there is no such node.
|
||||
* <p>
|
||||
* For nodes with the same location, macro-expansions ({@link IASTPreprocessorMacroExpansion}) are preferred
|
||||
* over c/c++-nodes nodes and children are preferred over their parents.
|
||||
*/
|
||||
IASTNode findFirstContainedNode(int offset, int length);
|
||||
|
||||
/**
|
||||
* Returns a macro expansion enclosing the given range, or <code>null</code>.
|
||||
*/
|
||||
IASTPreprocessorMacroExpansion findEnclosingMacroExpansion(int offset, int length);
|
||||
}
|
||||
|
|
|
@ -1,35 +1,34 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2007 IBM Corporation and others.
|
||||
* Copyright (c) 2004, 2008 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
* Emanuel Graf (IFS)
|
||||
* IBM - Initial API and implementation
|
||||
* Emanuel Graf (IFS)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.dom.ast;
|
||||
|
||||
/**
|
||||
* This interface represent a preprocessor #ifdef statement.
|
||||
*
|
||||
* @author jcamelon
|
||||
*/
|
||||
public interface IASTPreprocessorIfdefStatement extends
|
||||
IASTPreprocessorStatement {
|
||||
public interface IASTPreprocessorIfdefStatement extends IASTPreprocessorStatement {
|
||||
|
||||
/**
|
||||
* Was this #ifdef branch taken?
|
||||
*
|
||||
* @return
|
||||
* Returns whether this branch was taken.
|
||||
*/
|
||||
public boolean taken();
|
||||
|
||||
/**
|
||||
* The condition of the ifdef.
|
||||
*
|
||||
* @return the Condition
|
||||
* The condition of the ifdef-statement.
|
||||
* @return the condition
|
||||
*/
|
||||
public char[] getCondition();
|
||||
|
||||
/**
|
||||
* Returns the macro reference, or <code>null</code> if the macro does not exist.
|
||||
*/
|
||||
IASTName getMacroReference();
|
||||
}
|
||||
|
|
|
@ -1,34 +1,34 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2007 IBM Corporation and others.
|
||||
* Copyright (c) 2004, 2008 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
* Emanuel Graf (IFS)
|
||||
* IBM - Initial API and implementation
|
||||
* Emanuel Graf (IFS)
|
||||
* Markus Schorn (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.dom.ast;
|
||||
|
||||
/**
|
||||
* This interface represent a preprocessor #ifndef statement.
|
||||
*
|
||||
* @author jcamelon
|
||||
*/
|
||||
public interface IASTPreprocessorIfndefStatement extends
|
||||
IASTPreprocessorStatement {
|
||||
public interface IASTPreprocessorIfndefStatement extends IASTPreprocessorStatement {
|
||||
|
||||
/**
|
||||
* Was this branch taken?
|
||||
*
|
||||
* @return
|
||||
* Returns whether this branch was taken.
|
||||
*/
|
||||
public boolean taken();
|
||||
|
||||
/**
|
||||
* The condition of the ifndef.
|
||||
*
|
||||
* @return the Condition
|
||||
* Returns the condition of the ifndef-statement.
|
||||
*/
|
||||
public char[] getCondition();
|
||||
|
||||
/**
|
||||
* Returns the macro reference, or <code>null</code> if the macro does not exist.
|
||||
*/
|
||||
IASTName getMacroReference();
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@ public interface IASTPreprocessorMacroExpansion extends IASTNode {
|
|||
public static final IASTPreprocessorMacroExpansion[] EMPTY_ARRAY = {};
|
||||
public static final ASTNodeProperty EXPANSION_NAME=
|
||||
new ASTNodeProperty("IASTPreprocessorMacroExpansion.EXPANSION_NAME - macro name"); //$NON-NLS-1$
|
||||
public static final ASTNodeProperty NESTED_EXPANSION_NAME=
|
||||
new ASTNodeProperty("IASTPreprocessorMacroExpansion.NESTED_EXPANSION_NAME - nested macro name"); //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Returns the macro definition used for the expansion.
|
||||
|
|
|
@ -1,20 +1,19 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2005 IBM Corporation and others.
|
||||
* Copyright (c) 2004, 2008 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
* IBM - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.dom.ast;
|
||||
|
||||
/**
|
||||
* This is the base interface for all preprocessor directives.
|
||||
*
|
||||
* @author jcamelon
|
||||
*/
|
||||
public interface IASTPreprocessorStatement extends IASTNode {
|
||||
|
||||
public static final ASTNodeProperty MACRO_NAME = new ASTNodeProperty( "IASTPreprocessorStatement.MACRO_NAME - the name of a macro"); //$NON-NLS-1$
|
||||
}
|
||||
|
|
|
@ -1,24 +1,23 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2005 IBM Corporation and others.
|
||||
* Copyright (c) 2004, 2008 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
* IBM - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.dom.ast;
|
||||
|
||||
/**
|
||||
* This interface represents a preprocessor #undef statement.
|
||||
*
|
||||
* @author jcamelon
|
||||
*/
|
||||
public interface IASTPreprocessorUndefStatement extends
|
||||
IASTPreprocessorStatement {
|
||||
public interface IASTPreprocessorUndefStatement extends IASTPreprocessorStatement {
|
||||
|
||||
public static final ASTNodeProperty MACRO_NAME = new ASTNodeProperty( "IASTPreprocessorUndefStatement.MACRO_NAME - the name of the macro being undefined"); //$NON-NLS-1$
|
||||
/**
|
||||
* Returns the reference to the macro, or <code>null</code>.
|
||||
*/
|
||||
public IASTName getMacroName();
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,16 +10,15 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTMacroExpansionLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNodeMatchKind.Relation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNodeSpecification.Relation;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.ILocationResolver;
|
||||
|
||||
/**
|
||||
* Class to support searching for nodes by offsets.
|
||||
* Class to support searching for nodes by file offsets.
|
||||
* @since 5.0
|
||||
*/
|
||||
public class ASTNodeSelector implements IASTNodeSelector {
|
||||
|
@ -49,85 +48,99 @@ public class ASTNodeSelector implements IASTNodeSelector {
|
|||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getNode(int, int)
|
||||
*/
|
||||
private IASTNode getNode(int offset, int length, ASTNodeMatchKind matchKind) {
|
||||
private <T extends IASTNode> T findNode(int offsetInFile, int lengthInFile, Relation relation, Class<T> requiredClass) {
|
||||
if (!fIsValid) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final int sequenceNumber= fLocationResolver.getSequenceNumberForFileOffset(fFilePath, offset);
|
||||
int sequenceLength;
|
||||
int altSequenceNumber= -1;
|
||||
int sequenceNumber= fLocationResolver.getSequenceNumberForFileOffset(fFilePath, offsetInFile);
|
||||
if (sequenceNumber < 0) {
|
||||
return null;
|
||||
}
|
||||
final int sequenceLength= length <= 0 ? 0 :
|
||||
fLocationResolver.getSequenceNumberForFileOffset(fFilePath, offset+length-1) + 1 - sequenceNumber;
|
||||
|
||||
ASTNode preCand= searchPreprocessor(sequenceNumber, sequenceLength, matchKind);
|
||||
if (preCand != null && matchKind.getRelationToSelection() != Relation.FIRST_CONTAINED) {
|
||||
return preCand;
|
||||
}
|
||||
ASTNode astCand= searchAST(sequenceNumber, sequenceLength, matchKind);
|
||||
return matchKind.isBetterMatch(preCand, astCand) ? preCand : astCand;
|
||||
}
|
||||
|
||||
private ASTNode searchPreprocessor(int sequenceNumber, int sequenceLength, ASTNodeMatchKind matchKind) {
|
||||
return fLocationResolver.findPreprocessorNode(sequenceNumber, sequenceLength, matchKind);
|
||||
}
|
||||
|
||||
private ASTNode searchAST(int sequenceNumber, int length, ASTNodeMatchKind matchKind) {
|
||||
FindNodeForOffsetAction nodeFinder= new FindNodeForOffsetAction(sequenceNumber, length, matchKind);
|
||||
fTu.accept(nodeFinder);
|
||||
ASTNode result= nodeFinder.getNode();
|
||||
// don't accept matches from the ast enclosed in a macro expansion (possible for contained matches, only)
|
||||
if (result != null &&
|
||||
matchKind.getRelationToSelection() == Relation.FIRST_CONTAINED) {
|
||||
IASTNodeLocation[] loc= result.getNodeLocations();
|
||||
if (loc.length > 0 && loc[0] instanceof IASTMacroExpansionLocation) {
|
||||
return null;
|
||||
if (lengthInFile > 0) {
|
||||
sequenceLength= fLocationResolver.getSequenceNumberForFileOffset(fFilePath, offsetInFile+lengthInFile-1) + 1 - sequenceNumber;
|
||||
}
|
||||
else {
|
||||
sequenceLength= 0;
|
||||
if (offsetInFile > 0) {
|
||||
altSequenceNumber= fLocationResolver.getSequenceNumberForFileOffset(fFilePath, offsetInFile-1);
|
||||
if (altSequenceNumber+1 == sequenceNumber) {
|
||||
altSequenceNumber= -1;
|
||||
}
|
||||
else {
|
||||
// we are on a context boundary and we need to check the variant to the left and
|
||||
// the one to the right
|
||||
sequenceLength= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
final ASTNodeSpecification<T> nodeSpec= new ASTNodeSpecification<T>(relation, requiredClass, offsetInFile, lengthInFile);
|
||||
nodeSpec.setRangeInSequence(sequenceNumber, sequenceLength);
|
||||
getNode(nodeSpec);
|
||||
if (altSequenceNumber != -1) {
|
||||
nodeSpec.setRangeInSequence(altSequenceNumber, sequenceLength);
|
||||
getNode(nodeSpec);
|
||||
}
|
||||
return nodeSpec.getBestNode();
|
||||
}
|
||||
|
||||
private <T extends IASTNode> T getNode(ASTNodeSpecification<T> nodeSpec) {
|
||||
fLocationResolver.findPreprocessorNode(nodeSpec);
|
||||
if (!nodeSpec.requiresClass(IASTPreprocessorMacroExpansion.class)) {
|
||||
FindNodeForOffsetAction nodeFinder= new FindNodeForOffsetAction(nodeSpec);
|
||||
fTu.accept(nodeFinder);
|
||||
}
|
||||
return nodeSpec.getBestNode();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getFirstContainedNode(int, int)
|
||||
*/
|
||||
public IASTNode findFirstContainedNode(int offset, int length) {
|
||||
return getNode(offset, length, ASTNodeMatchKind.MATCH_FIRST_CONTAINED);
|
||||
return findNode(offset, length, Relation.FIRST_CONTAINED, IASTNode.class);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getNode(int, int)
|
||||
*/
|
||||
public IASTNode findNode(int offset, int length) {
|
||||
return getNode(offset, length, ASTNodeMatchKind.MATCH_EXACT);
|
||||
return findNode(offset, length, Relation.EXACT_MATCH, IASTNode.class);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getSurroundingNode(int, int)
|
||||
*/
|
||||
public IASTNode findSurroundingNode(int offset, int length) {
|
||||
return getNode(offset, length, ASTNodeMatchKind.MATCH_SURROUNDING);
|
||||
public IASTNode findEnclosingNode(int offset, int length) {
|
||||
return findNode(offset, length, Relation.ENCLOSING, IASTNode.class);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getFirstContainedNode(int, int)
|
||||
*/
|
||||
public IASTName findFirstContainedName(int offset, int length) {
|
||||
return (IASTName) getNode(offset, length, ASTNodeMatchKind.MATCH_FIRST_NAME_CONTAINED);
|
||||
return findNode(offset, length, Relation.FIRST_CONTAINED, IASTName.class);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getNode(int, int)
|
||||
*/
|
||||
public IASTName findName(int offset, int length) {
|
||||
return (IASTName) getNode(offset, length, ASTNodeMatchKind.MATCH_EXACT_NAME);
|
||||
return findNode(offset, length, Relation.EXACT_MATCH, IASTName.class);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getSurroundingNode(int, int)
|
||||
*/
|
||||
public IASTName findSurroundingName(int offset, int length) {
|
||||
return (IASTName) getNode(offset, length, ASTNodeMatchKind.MATCH_SURROUNDING_NAME);
|
||||
public IASTName findEnclosingName(int offset, int length) {
|
||||
return findNode(offset, length, Relation.ENCLOSING, IASTName.class);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#findSurrundingMacroExpansion(int, int)
|
||||
*/
|
||||
public IASTPreprocessorMacroExpansion findEnclosingMacroExpansion(int offset, int length) {
|
||||
return findNode(offset, length, Relation.ENCLOSING, IASTPreprocessorMacroExpansion.class);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -38,16 +38,15 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisitor;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||
|
||||
/**
|
||||
* Visitor to search for nodes by file offsets.
|
||||
* @since 5.0
|
||||
*/
|
||||
public class FindNodeForOffsetAction extends CPPASTVisitor implements ICASTVisitor, ICPPASTVisitor {
|
||||
private ASTNode fCandidate= null;
|
||||
private final int fOffset;
|
||||
private final int fLength;
|
||||
private final ASTNodeMatchKind fMatchKind;
|
||||
private final ASTNodeSpecification<?> fNodeSpec;
|
||||
|
||||
public FindNodeForOffsetAction(int offset, int length, ASTNodeMatchKind matchKind) {
|
||||
fMatchKind= matchKind;
|
||||
fOffset = offset;
|
||||
fLength = length;
|
||||
public FindNodeForOffsetAction(ASTNodeSpecification<?> nodeSpec) {
|
||||
fNodeSpec= nodeSpec;
|
||||
|
||||
shouldVisitNames = true;
|
||||
shouldVisitDeclarations= true;
|
||||
|
@ -65,21 +64,16 @@ public class FindNodeForOffsetAction extends CPPASTVisitor implements ICASTVisit
|
|||
shouldVisitBaseSpecifiers=
|
||||
shouldVisitNamespaces=
|
||||
shouldVisitTemplateParameters=
|
||||
shouldVisitTranslationUnit= !matchKind.matchNamesOnly();
|
||||
shouldVisitTranslationUnit= !nodeSpec.requiresClass(IASTName.class);
|
||||
}
|
||||
|
||||
public int processNode(IASTNode node) {
|
||||
if (node instanceof ASTNode) {
|
||||
final ASTNode astNode = (ASTNode) node;
|
||||
if (astNode.getOffset() > fOffset+fLength || astNode.getOffset() + astNode.getLength() < fOffset) {
|
||||
if (!fNodeSpec.canContainMatches(astNode)) {
|
||||
return PROCESS_SKIP;
|
||||
}
|
||||
|
||||
if (fMatchKind.matches(astNode, fOffset, fLength)) {
|
||||
if (fCandidate == null || !fMatchKind.isBetterMatch(fCandidate, astNode)) {
|
||||
fCandidate= astNode;
|
||||
}
|
||||
}
|
||||
fNodeSpec.visit(astNode);
|
||||
}
|
||||
return PROCESS_CONTINUE;
|
||||
}
|
||||
|
@ -88,7 +82,7 @@ public class FindNodeForOffsetAction extends CPPASTVisitor implements ICASTVisit
|
|||
public int visit(IASTDeclaration declaration) {
|
||||
// use declarations to determine if the search has gone past the
|
||||
// offset (i.e. don't know the order the visitor visits the nodes)
|
||||
if (declaration instanceof ASTNode && ((ASTNode) declaration).getOffset() > fOffset + fLength)
|
||||
if (declaration instanceof ASTNode && ((ASTNode) declaration).getOffset() > fNodeSpec.getSequenceEnd())
|
||||
return PROCESS_ABORT;
|
||||
|
||||
return processNode(declaration);
|
||||
|
@ -204,8 +198,4 @@ public class FindNodeForOffsetAction extends CPPASTVisitor implements ICASTVisit
|
|||
public int visit(IASTTranslationUnit tu) {
|
||||
return processNode(tu);
|
||||
}
|
||||
|
||||
public ASTNode getNode() {
|
||||
return fCandidate;
|
||||
}
|
||||
}
|
|
@ -18,7 +18,6 @@ import org.eclipse.cdt.core.dom.ast.IASTImageLocation;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
|
||||
|
@ -127,8 +126,8 @@ class ASTBuiltinName extends ASTPreprocessorDefinition {
|
|||
class ASTMacroReferenceName extends ASTPreprocessorName {
|
||||
private ImageLocationInfo fImageLocationInfo;
|
||||
|
||||
public ASTMacroReferenceName(IASTPreprocessorMacroExpansion parent, int offset, int endOffset, IMacroBinding macro, ImageLocationInfo imgLocationInfo) {
|
||||
super(parent, IASTPreprocessorMacroExpansion.EXPANSION_NAME, offset, endOffset, macro.getNameCharArray(), macro);
|
||||
public ASTMacroReferenceName(IASTNode parent, ASTNodeProperty property, int offset, int endOffset, IMacroBinding macro, ImageLocationInfo imgLocationInfo) {
|
||||
super(parent, property, offset, endOffset, macro.getNameCharArray(), macro);
|
||||
fImageLocationInfo= imgLocationInfo;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorObjectStyleMacroDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorPragmaStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorUndefStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
|
@ -42,8 +43,7 @@ import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree.IASTInclusionNode;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNodeMatchKind;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNodeMatchKind.Relation;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNodeSpecification;
|
||||
|
||||
/**
|
||||
* Models various AST-constructs obtained from the preprocessor.
|
||||
|
@ -72,36 +72,10 @@ abstract class ASTPreprocessorNode extends ASTNode {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a matching node or null.
|
||||
* Searches nodes by file location.
|
||||
*/
|
||||
ASTNode findNode(int sequenceNumber, int length, ASTNodeMatchKind matchKind) {
|
||||
if (matchKind.matches(this, sequenceNumber, length)) {
|
||||
return this;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for preprocessor nodes containing a name
|
||||
*/
|
||||
protected ASTNode findNode(int sequenceNumber, int length, ASTPreprocessorName name, ASTNodeMatchKind matchKind) {
|
||||
ASTNode n1, n2;
|
||||
if (matchKind.getRelationToSelection() == Relation.SURROUNDING) {
|
||||
n1= name;
|
||||
n2= this;
|
||||
}
|
||||
else {
|
||||
n1= this;
|
||||
n2= name;
|
||||
}
|
||||
|
||||
if (matchKind.matches(n1, sequenceNumber, length)) {
|
||||
return n1;
|
||||
}
|
||||
if (matchKind.matches(n2, sequenceNumber, length)) {
|
||||
return n2;
|
||||
}
|
||||
return null;
|
||||
void findNode(ASTNodeSpecification<?> nodeSpec) {
|
||||
nodeSpec.visit(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -174,14 +148,35 @@ class ASTElse extends ASTPreprocessorNode implements IASTPreprocessorElseStateme
|
|||
}
|
||||
|
||||
class ASTIfndef extends ASTDirectiveWithCondition implements IASTPreprocessorIfndefStatement {
|
||||
public ASTIfndef(IASTTranslationUnit parent, int startNumber, int condNumber, int condEndNumber, boolean active) {
|
||||
super(parent, startNumber, condNumber, condEndNumber, active);
|
||||
private ASTMacroReferenceName fMacroRef;
|
||||
|
||||
public ASTIfndef(IASTTranslationUnit parent, int startNumber, int condNumber, int condEndNumber, boolean taken, IMacroBinding macro) {
|
||||
super(parent, startNumber, condNumber, condEndNumber, taken);
|
||||
if (macro != null) {
|
||||
fMacroRef= new ASTMacroReferenceName(this, IASTPreprocessorStatement.MACRO_NAME, condNumber, condEndNumber, macro, null);
|
||||
}
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IASTPreprocessorIfdefStatement#getMacroReference()
|
||||
*/
|
||||
public ASTPreprocessorName getMacroReference() {
|
||||
return fMacroRef;
|
||||
}
|
||||
}
|
||||
|
||||
class ASTIfdef extends ASTDirectiveWithCondition implements IASTPreprocessorIfdefStatement {
|
||||
public ASTIfdef(IASTTranslationUnit parent, int startNumber, int condNumber, int condEndNumber, boolean active) {
|
||||
super(parent, startNumber, condNumber, condEndNumber, active);
|
||||
ASTMacroReferenceName fMacroRef;
|
||||
public ASTIfdef(IASTTranslationUnit parent, int startNumber, int condNumber, int condEndNumber, boolean taken, IMacroBinding macro) {
|
||||
super(parent, startNumber, condNumber, condEndNumber, taken);
|
||||
if (macro != null) {
|
||||
fMacroRef= new ASTMacroReferenceName(this, IASTPreprocessorStatement.MACRO_NAME, condNumber, condEndNumber, macro, null);
|
||||
}
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IASTPreprocessorIfdefStatement#getMacroReference()
|
||||
*/
|
||||
public ASTPreprocessorName getMacroReference() {
|
||||
return fMacroRef;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,8 +245,9 @@ class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreproces
|
|||
}
|
||||
|
||||
@Override
|
||||
ASTNode findNode(int sequenceNumber, int length, ASTNodeMatchKind matchKind) {
|
||||
return findNode(sequenceNumber, length, fName, matchKind);
|
||||
void findNode(ASTNodeSpecification<?> nodeSpec) {
|
||||
super.findNode(nodeSpec);
|
||||
nodeSpec.visit(fName);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -308,8 +304,9 @@ class ASTMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessor
|
|||
}
|
||||
|
||||
@Override
|
||||
ASTNode findNode(int sequenceNumber, int length, ASTNodeMatchKind matchKind) {
|
||||
return findNode(sequenceNumber, length, fName, matchKind);
|
||||
void findNode(ASTNodeSpecification<?> nodeSpec) {
|
||||
super.findNode(nodeSpec);
|
||||
nodeSpec.visit(fName);
|
||||
}
|
||||
|
||||
public void setExpansion(String exp) {assert false;}
|
||||
|
@ -410,17 +407,12 @@ class ASTUndef extends ASTPreprocessorNode implements IASTPreprocessorUndefState
|
|||
private final ASTPreprocessorName fName;
|
||||
public ASTUndef(IASTTranslationUnit parent, char[] name, int startNumber, int nameNumber, int nameEndNumber, IBinding binding) {
|
||||
super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, startNumber, nameEndNumber);
|
||||
fName= new ASTPreprocessorName(this, IASTPreprocessorUndefStatement.MACRO_NAME, nameNumber, nameEndNumber, name, binding);
|
||||
fName= new ASTPreprocessorName(this, IASTPreprocessorStatement.MACRO_NAME, nameNumber, nameEndNumber, name, binding);
|
||||
}
|
||||
|
||||
public ASTPreprocessorName getMacroName() {
|
||||
return fName;
|
||||
}
|
||||
|
||||
@Override
|
||||
ASTNode findNode(int sequenceNumber, int length, ASTNodeMatchKind matchKind) {
|
||||
return findNode(sequenceNumber, length, fName, matchKind);
|
||||
}
|
||||
}
|
||||
|
||||
class ASTInclusionNode implements IASTInclusionNode {
|
||||
|
@ -546,9 +538,13 @@ class ASTMacroExpansion extends ASTPreprocessorNode implements IASTPreprocessorM
|
|||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion#getNestedExpansions()
|
||||
*/
|
||||
public IASTName[] getNestedMacroReferences() {
|
||||
public ASTPreprocessorName[] getNestedMacroReferences() {
|
||||
return fContext.getNestedMacroReferences();
|
||||
}
|
||||
|
||||
public LocationCtxMacroExpansion getContext() {
|
||||
return fContext;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
|
|
|
@ -883,7 +883,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
condEndOffset= lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
|
||||
int endOffset= lexer.currentToken().getEndOffset();
|
||||
if (fCurrentContext.changeBranch(ScannerContext.BRANCH_ELIF)) {
|
||||
fLocationMap.encounterPoundElif(startOffset, condOffset, condEndOffset, endOffset, false);
|
||||
fLocationMap.encounterPoundElif(startOffset, condOffset, condEndOffset, endOffset, false, IASTName.EMPTY_NAME_ARRAY);
|
||||
skipOverConditionalCode(lexer, false);
|
||||
}
|
||||
else {
|
||||
|
@ -1132,17 +1132,18 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
|
||||
final int endOffset= lexer.currentToken().getEndOffset();
|
||||
final char[] namechars= name.getCharImage();
|
||||
boolean isActive= (fMacroDictionary.get(namechars) != null) == positive;
|
||||
PreprocessorMacro macro= fMacroDictionary.get(namechars);
|
||||
boolean isActive= (macro != null) == positive;
|
||||
|
||||
fCurrentContext.changeBranch(ScannerContext.BRANCH_IF);
|
||||
if (positive) {
|
||||
fLocationMap.encounterPoundIfdef(startOffset, name.getOffset(), name.getEndOffset(), endOffset, isActive);
|
||||
fLocationMap.encounterPoundIfdef(startOffset, name.getOffset(), name.getEndOffset(), endOffset, isActive, macro);
|
||||
}
|
||||
else {
|
||||
fLocationMap.encounterPoundIfndef(startOffset, name.getOffset(), name.getEndOffset(), endOffset, isActive);
|
||||
fLocationMap.encounterPoundIfndef(startOffset, name.getOffset(), name.getEndOffset(), endOffset, isActive, macro);
|
||||
}
|
||||
|
||||
if (!isActive) {
|
||||
if ((macro == null) == positive) {
|
||||
skipOverConditionalCode(lexer, true);
|
||||
}
|
||||
}
|
||||
|
@ -1154,19 +1155,20 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
final int condEndOffset= getTokensWithinPPDirective(lexer, true, condition);
|
||||
final int endOffset= lexer.currentToken().getEndOffset();
|
||||
|
||||
fExpressionEvaluator.clearMacrosInDefinedExpression();
|
||||
if (condition.first() == null) {
|
||||
handleProblem(IProblem.SCANNER_EXPRESSION_SYNTAX_ERROR, null, startOffset, endOffset);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
isActive= fExpressionEvaluator.evaluate(condition, fMacroDictionary);
|
||||
isActive= fExpressionEvaluator.evaluate(condition, fMacroDictionary, fLocationMap);
|
||||
} catch (EvalException e) {
|
||||
handleProblem(e.getProblemID(), e.getProblemArg(), condOffset, endOffset);
|
||||
}
|
||||
}
|
||||
|
||||
fCurrentContext.changeBranch(ScannerContext.BRANCH_IF);
|
||||
fLocationMap.encounterPoundIf(startOffset, condOffset, condEndOffset, endOffset, isActive);
|
||||
fLocationMap.encounterPoundIf(startOffset, condOffset, condEndOffset, endOffset, isActive, fExpressionEvaluator.clearMacrosInDefinedExpression());
|
||||
|
||||
if (!isActive) {
|
||||
skipOverConditionalCode(lexer, true);
|
||||
|
@ -1247,21 +1249,21 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
int endOffset= lexer.currentToken().getEndOffset();
|
||||
nesting++;
|
||||
fCurrentContext.changeBranch(ScannerContext.BRANCH_IF);
|
||||
fLocationMap.encounterPoundIfdef(pound.getOffset(), ident.getOffset(), ident.getEndOffset(), endOffset, false);
|
||||
fLocationMap.encounterPoundIfdef(pound.getOffset(), ident.getOffset(), ident.getEndOffset(), endOffset, false, null);
|
||||
break;
|
||||
case IPreprocessorDirective.ppIfndef:
|
||||
lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
|
||||
endOffset= lexer.currentToken().getEndOffset();
|
||||
nesting++;
|
||||
fCurrentContext.changeBranch(ScannerContext.BRANCH_IF);
|
||||
fLocationMap.encounterPoundIfndef(pound.getOffset(), ident.getOffset(), ident.getEndOffset(), endOffset, false);
|
||||
fLocationMap.encounterPoundIfndef(pound.getOffset(), ident.getOffset(), ident.getEndOffset(), endOffset, false, null);
|
||||
break;
|
||||
case IPreprocessorDirective.ppIf:
|
||||
int condEndOffset= lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
|
||||
endOffset= lexer.currentToken().getEndOffset();
|
||||
nesting++;
|
||||
fCurrentContext.changeBranch(ScannerContext.BRANCH_IF);
|
||||
fLocationMap.encounterPoundIf(pound.getOffset(), ident.getOffset(), condEndOffset, endOffset, false);
|
||||
fLocationMap.encounterPoundIf(pound.getOffset(), ident.getOffset(), condEndOffset, endOffset, false, IASTName.EMPTY_NAME_ARRAY);
|
||||
break;
|
||||
case IPreprocessorDirective.ppElse:
|
||||
lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
|
||||
|
@ -1279,13 +1281,14 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
case IPreprocessorDirective.ppElif:
|
||||
if (fCurrentContext.changeBranch(ScannerContext.BRANCH_ELIF)) {
|
||||
boolean isActive= false;
|
||||
fExpressionEvaluator.clearMacrosInDefinedExpression();
|
||||
int condOffset= lexer.nextToken().getOffset();
|
||||
if (nesting == 0 && takeElseBranch) {
|
||||
TokenList condition= new TokenList();
|
||||
condEndOffset= getTokensWithinPPDirective(lexer, true, condition);
|
||||
if (condition.first() != null) {
|
||||
try {
|
||||
isActive= fExpressionEvaluator.evaluate(condition, fMacroDictionary);
|
||||
isActive= fExpressionEvaluator.evaluate(condition, fMacroDictionary, fLocationMap);
|
||||
} catch (EvalException e) {
|
||||
handleProblem(e.getProblemID(), e.getProblemArg(), condOffset, condEndOffset);
|
||||
}
|
||||
|
@ -1296,7 +1299,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
}
|
||||
endOffset= lexer.currentToken().getEndOffset();
|
||||
fCurrentContext.changeBranch(ScannerContext.BRANCH_ELIF);
|
||||
fLocationMap.encounterPoundElif(pound.getOffset(), condOffset, condEndOffset, endOffset, isActive);
|
||||
fLocationMap.encounterPoundElif(pound.getOffset(), condOffset, condEndOffset, endOffset, isActive, fExpressionEvaluator.clearMacrosInDefinedExpression());
|
||||
|
||||
if (isActive) {
|
||||
return;
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.parser.IProblem;
|
||||
import org.eclipse.cdt.core.parser.IToken;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayMap;
|
||||
|
@ -41,13 +44,22 @@ class ExpressionEvaluator {
|
|||
|
||||
private Token fTokens;
|
||||
private CharArrayMap<PreprocessorMacro> fDictionary;
|
||||
private ArrayList<IASTName> fMacrosInDefinedExpressions= new ArrayList<IASTName>();
|
||||
private LocationMap fLocationMap;
|
||||
|
||||
public boolean evaluate(TokenList condition, CharArrayMap<PreprocessorMacro> macroDictionary) throws EvalException {
|
||||
public boolean evaluate(TokenList condition, CharArrayMap<PreprocessorMacro> macroDictionary, LocationMap map) throws EvalException {
|
||||
fTokens= condition.first();
|
||||
fDictionary= macroDictionary;
|
||||
fLocationMap= map;
|
||||
fMacrosInDefinedExpressions.clear();
|
||||
return expression() != 0;
|
||||
}
|
||||
|
||||
|
||||
public IASTName[] clearMacrosInDefinedExpression() {
|
||||
IASTName[] result= fMacrosInDefinedExpressions.toArray(new IASTName[fMacrosInDefinedExpressions.size()]);
|
||||
fMacrosInDefinedExpressions.clear();
|
||||
return result;
|
||||
}
|
||||
|
||||
private long expression() throws EvalException {
|
||||
return conditionalExpression();
|
||||
|
@ -254,7 +266,11 @@ class ExpressionEvaluator {
|
|||
if (LA() != IToken.tIDENTIFIER) {
|
||||
throw new EvalException(IProblem.SCANNER_ILLEGAL_IDENTIFIER, null);
|
||||
}
|
||||
int result= fDictionary.containsKey(fTokens.getCharImage()) ? 1 : 0;
|
||||
PreprocessorMacro macro= fDictionary.get(fTokens.getCharImage());
|
||||
if (macro != null) {
|
||||
fMacrosInDefinedExpressions.add(fLocationMap.encounterDefinedExpression(macro, fTokens.getOffset(), fTokens.getEndOffset()));
|
||||
}
|
||||
int result= macro != null ? 1 : 0;
|
||||
consume();
|
||||
if (parenthesis) {
|
||||
if (LA() != IToken.tRPAREN) {
|
||||
|
|
|
@ -32,22 +32,21 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisitor;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNodeMatchKind;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNodeSpecification;
|
||||
|
||||
/**
|
||||
* Visitor to select nodes by image-location.
|
||||
* @since 5.0
|
||||
*/
|
||||
public class FindNodeByImageLocation extends CPPASTVisitor implements ICASTVisitor, ICPPASTVisitor {
|
||||
private ASTNode fCandidate= null;
|
||||
private final int fOffset;
|
||||
private final int fLength;
|
||||
private final ASTNodeMatchKind fMatchKind;
|
||||
private int fImageOffset;
|
||||
private int fImageLength;
|
||||
private final ASTNodeSpecification<?> fNodeSpec;
|
||||
|
||||
public FindNodeByImageLocation(int offset, int length, int imgOffset, int imgLength, ASTNodeMatchKind matchKind) {
|
||||
fMatchKind= matchKind;
|
||||
public FindNodeByImageLocation(int offset, int length, ASTNodeSpecification<?> nodeSpec) {
|
||||
fNodeSpec= nodeSpec;
|
||||
fOffset = offset;
|
||||
fLength = length;
|
||||
fImageOffset= imgOffset;
|
||||
fImageLength= imgLength;
|
||||
|
||||
shouldVisitNames = true;
|
||||
shouldVisitDeclarations= true;
|
||||
|
@ -65,7 +64,7 @@ public class FindNodeByImageLocation extends CPPASTVisitor implements ICASTVisit
|
|||
shouldVisitBaseSpecifiers=
|
||||
shouldVisitNamespaces=
|
||||
shouldVisitTemplateParameters=
|
||||
shouldVisitTranslationUnit= !matchKind.matchNamesOnly();
|
||||
shouldVisitTranslationUnit= !nodeSpec.requiresClass(IASTName.class);
|
||||
}
|
||||
|
||||
public int processNode(IASTNode node) {
|
||||
|
@ -75,14 +74,10 @@ public class FindNodeByImageLocation extends CPPASTVisitor implements ICASTVisit
|
|||
return PROCESS_SKIP;
|
||||
}
|
||||
|
||||
if (fMatchKind.isAcceptableNode(astNode)) {
|
||||
if (fNodeSpec.isAcceptableNode(astNode)) {
|
||||
IASTImageLocation imageLocation= astNode.getImageLocation();
|
||||
if (imageLocation != null && imageLocation.getLocationKind() == IASTImageLocation.ARGUMENT_TO_MACRO_EXPANSION) {
|
||||
if (fMatchKind.rangeMatches(imageLocation.getNodeOffset(), imageLocation.getNodeLength(), fImageOffset, fImageLength)) {
|
||||
if (fCandidate == null || !fMatchKind.isBetterMatch(fCandidate, astNode)) {
|
||||
fCandidate= astNode;
|
||||
}
|
||||
}
|
||||
fNodeSpec.visit(astNode, imageLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -184,8 +179,4 @@ public class FindNodeByImageLocation extends CPPASTVisitor implements ICASTVisit
|
|||
public int visit(IASTTranslationUnit tu) {
|
||||
return processNode(tu);
|
||||
}
|
||||
|
||||
public ASTNode getNode() {
|
||||
return fCandidate;
|
||||
}
|
||||
}
|
|
@ -24,8 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IASTProblem;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNodeMatchKind;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNodeSpecification;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -136,16 +135,13 @@ public interface ILocationResolver {
|
|||
char[] getUnpreprocessedSignature(IASTFileLocation loc);
|
||||
|
||||
/**
|
||||
* Returns a preprocessor node surrounding the given range, or <code>null</code>. The result is either a
|
||||
* preprocessing directive ({@link IASTPreprocessorStatement}) or a name contained therein {@link IASTName} or
|
||||
* a macro expansion ({@link IASTName}).
|
||||
* Searches for a preprocessor node matching the given specification. Candidates are passed to
|
||||
* nodeSpec, which selects and stores the best result.
|
||||
*
|
||||
* @param sequenceNumber the sequence number of the start of the interesting region.
|
||||
* @param length the sequence length of the interesting region.
|
||||
* @param matchOption the kind of the desired match.
|
||||
* @param nodeSpec specification of node to search for.
|
||||
*/
|
||||
ASTNode findPreprocessorNode(int sequenceNumber, int length, ASTNodeMatchKind matchOption);
|
||||
|
||||
void findPreprocessorNode(ASTNodeSpecification<?> nodeSpec);
|
||||
|
||||
/**
|
||||
* Returns whether the specified sequence number points into the root file of the
|
||||
* translation unit, or not.
|
||||
|
|
|
@ -94,7 +94,7 @@ abstract class LocationCtx implements ILocationCtx {
|
|||
/**
|
||||
* Returns the macro-expansion surrounding or augmenting the given range, or <code>null</code>.
|
||||
*/
|
||||
public LocationCtxMacroExpansion findSurroundingMacroExpansion(int sequenceNumber, int length) {
|
||||
public LocationCtxMacroExpansion findEnclosingMacroExpansion(int sequenceNumber, int length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -101,11 +101,11 @@ class LocationCtxContainer extends LocationCtx {
|
|||
}
|
||||
|
||||
@Override
|
||||
public final LocationCtxMacroExpansion findSurroundingMacroExpansion(int sequenceNumber, int length) {
|
||||
public final LocationCtxMacroExpansion findEnclosingMacroExpansion(int sequenceNumber, int length) {
|
||||
int testEnd= length > 1 ? sequenceNumber+length-1 : sequenceNumber;
|
||||
final LocationCtx child= findChildLessOrEqualThan(sequenceNumber, true);
|
||||
if (child != null && child.fSequenceNumber+child.getSequenceLength() > testEnd) {
|
||||
return child.findSurroundingMacroExpansion(sequenceNumber, length);
|
||||
return child.findEnclosingMacroExpansion(sequenceNumber, length);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -16,9 +16,6 @@ import org.eclipse.cdt.core.dom.ast.IASTImageLocation;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNodeMatchKind;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNodeMatchKind.Relation;
|
||||
|
||||
/**
|
||||
* A location context representing macro expansions.
|
||||
|
@ -74,7 +71,7 @@ class LocationCtxMacroExpansion extends LocationCtx {
|
|||
}
|
||||
|
||||
@Override
|
||||
public LocationCtxMacroExpansion findSurroundingMacroExpansion(int sequenceNumber, int length) {
|
||||
public LocationCtxMacroExpansion findEnclosingMacroExpansion(int sequenceNumber, int length) {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -109,26 +106,6 @@ class LocationCtxMacroExpansion extends LocationCtx {
|
|||
return null;
|
||||
}
|
||||
|
||||
public ASTNode findNode(int sequenceNumber, int length, ASTNodeMatchKind matchKind) {
|
||||
ASTNode n1, n2;
|
||||
if (matchKind.getRelationToSelection() == Relation.SURROUNDING) {
|
||||
n1= fExpansionName;
|
||||
n2= (ASTNode) fExpansionName.getParent();
|
||||
}
|
||||
else {
|
||||
n1= (ASTNode) fExpansionName.getParent();
|
||||
n2= fExpansionName;
|
||||
}
|
||||
|
||||
if (matchKind.matches(n1, sequenceNumber, length)) {
|
||||
return n1;
|
||||
}
|
||||
if (matchKind.matches(n2, sequenceNumber, length)) {
|
||||
return n2;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ASTPreprocessorName[] getNestedMacroReferences() {
|
||||
return fLocationMap.getNestedMacroReferences((ASTMacroExpansion) fExpansionName.getParent());
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.eclipse.cdt.core.dom.ast.IASTComment;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTImageLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
|
||||
|
@ -31,10 +32,8 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
|
|||
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNodeMatchKind;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNodeSpecification;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTProblem;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNodeMatchKind.Relation;
|
||||
|
||||
/**
|
||||
* Converts the offsets relative to various contexts to the global sequence number. Also creates and stores
|
||||
|
@ -138,9 +137,20 @@ public class LocationMap implements ILocationResolver {
|
|||
* @param imageLocationInfo the image-location for the name of the macro.
|
||||
*/
|
||||
public IASTName encounterImplicitMacroExpansion(IMacroBinding macro, ImageLocationInfo imageLocationInfo) {
|
||||
return new ASTMacroReferenceName(null, 0, 0, macro, imageLocationInfo);
|
||||
return new ASTMacroReferenceName(null, IASTPreprocessorMacroExpansion.NESTED_EXPANSION_NAME, 0, 0, macro, imageLocationInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a name representing a macro in a defined-expression. The returned name can be fed into
|
||||
* {@link #encounterPoundIf(int, int, int, int, boolean, IASTName[])}.
|
||||
*/
|
||||
public IASTName encounterDefinedExpression(IMacroBinding macro, int startOffset, int endOffset) {
|
||||
int startNumber= getSequenceNumberForOffset(startOffset);
|
||||
int endNumber= getSequenceNumberForOffset(endOffset);
|
||||
return new ASTMacroReferenceName(null, IASTPreprocessorStatement.MACRO_NAME, startNumber, endNumber, macro, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new context for the result of a (recursive) macro-expansion.
|
||||
* @param nameOffset offset within the current context where the name for the macro-expansion starts.
|
||||
|
@ -160,14 +170,14 @@ public class LocationMap implements ILocationResolver {
|
|||
final int length= endNumber-nameNumber;
|
||||
|
||||
ASTMacroExpansion expansion= new ASTMacroExpansion(fTranslationUnit, nameNumber, endNumber);
|
||||
ASTMacroReferenceName explicitRef= new ASTMacroReferenceName(expansion, nameNumber, nameEndNumber, macro, null);
|
||||
ASTMacroReferenceName explicitRef= new ASTMacroReferenceName(expansion, IASTPreprocessorMacroExpansion.EXPANSION_NAME, nameNumber, nameEndNumber, macro, null);
|
||||
addMacroReference(explicitRef);
|
||||
for (int i = 0; i < implicitMacroReferences.length; i++) {
|
||||
ASTMacroReferenceName name = (ASTMacroReferenceName) implicitMacroReferences[i];
|
||||
name.setParent(expansion);
|
||||
name.setOffsetAndLength(nameNumber, length);
|
||||
addMacroReference(name);
|
||||
}
|
||||
addMacroReference(explicitRef);
|
||||
|
||||
LocationCtxMacroExpansion expansionCtx= new LocationCtxMacroExpansion(this, (LocationCtxContainer) fCurrentContext, nameOffset, endOffset, endNumber, contextLength, imageLocations, explicitRef);
|
||||
expansion.setContext(expansionCtx);
|
||||
|
@ -177,7 +187,9 @@ public class LocationMap implements ILocationResolver {
|
|||
}
|
||||
|
||||
private void addMacroReference(ASTPreprocessorName name) {
|
||||
fMacroReferences.add(name);
|
||||
if (name != null) {
|
||||
fMacroReferences.add(name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -233,12 +245,22 @@ public class LocationMap implements ILocationResolver {
|
|||
fDirectives.add(new ASTElse(fTranslationUnit, startOffset, endOffset, isActive));
|
||||
}
|
||||
|
||||
public void encounterPoundElif(int startOffset, int condOffset, int condEndOffset, int endOffset, boolean isActive) {
|
||||
public void encounterPoundElif(int startOffset, int condOffset, int condEndOffset, int endOffset, boolean isActive,
|
||||
IASTName[] macrosInDefinedExpression) {
|
||||
startOffset= getSequenceNumberForOffset(startOffset);
|
||||
condOffset= getSequenceNumberForOffset(condOffset);
|
||||
condEndOffset= getSequenceNumberForOffset(condEndOffset);
|
||||
// compatible with 4.0: endOffset= getSequenceNumberForOffset(endOffset);
|
||||
fDirectives.add(new ASTElif(fTranslationUnit, startOffset, condOffset, condEndOffset, isActive));
|
||||
final ASTElif elif = new ASTElif(fTranslationUnit, startOffset, condOffset, condEndOffset, isActive);
|
||||
fDirectives.add(elif);
|
||||
|
||||
for (int i = 0; i < macrosInDefinedExpression.length; i++) {
|
||||
ASTMacroReferenceName name = (ASTMacroReferenceName) macrosInDefinedExpression[i];
|
||||
name.setParent(elif);
|
||||
name.setPropertyInParent(IASTPreprocessorStatement.MACRO_NAME);
|
||||
addMacroReference(name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void encounterPoundEndIf(int startOffset, int endOffset) {
|
||||
|
@ -263,30 +285,42 @@ public class LocationMap implements ILocationResolver {
|
|||
fDirectives.add(new ASTPragma(fTranslationUnit, startOffset, condOffset, condEndOffset));
|
||||
}
|
||||
|
||||
public void encounterPoundIfdef(int startOffset, int condOffset, int condEndOffset, int endOffset, boolean isActive) {
|
||||
public void encounterPoundIfdef(int startOffset, int condOffset, int condEndOffset, int endOffset, boolean taken, IMacroBinding macro) {
|
||||
startOffset= getSequenceNumberForOffset(startOffset);
|
||||
condOffset= getSequenceNumberForOffset(condOffset);
|
||||
condEndOffset= getSequenceNumberForOffset(condEndOffset);
|
||||
// not using endOffset, compatible with 4.0: endOffset= getSequenceNumberForOffset(endOffset);
|
||||
fDirectives.add(new ASTIfdef(fTranslationUnit, startOffset, condOffset, condEndOffset, isActive));
|
||||
final ASTIfdef ifdef = new ASTIfdef(fTranslationUnit, startOffset, condOffset, condEndOffset, taken, macro);
|
||||
fDirectives.add(ifdef);
|
||||
addMacroReference(ifdef.getMacroReference());
|
||||
}
|
||||
|
||||
public void encounterPoundIfndef(int startOffset, int condOffset, int condEndOffset, int endOffset, boolean isActive) {
|
||||
public void encounterPoundIfndef(int startOffset, int condOffset, int condEndOffset, int endOffset, boolean taken, IMacroBinding macro) {
|
||||
startOffset= getSequenceNumberForOffset(startOffset);
|
||||
condOffset= getSequenceNumberForOffset(condOffset);
|
||||
condEndOffset= getSequenceNumberForOffset(condEndOffset);
|
||||
// not using endOffset, compatible with 4.0: endOffset= getSequenceNumberForOffset(endOffset);
|
||||
fDirectives.add(new ASTIfndef(fTranslationUnit, startOffset, condOffset, condEndOffset, isActive));
|
||||
final ASTIfndef ifndef = new ASTIfndef(fTranslationUnit, startOffset, condOffset, condEndOffset, taken, macro);
|
||||
fDirectives.add(ifndef);
|
||||
addMacroReference(ifndef.getMacroReference());
|
||||
}
|
||||
|
||||
public void encounterPoundIf(int startOffset, int condOffset, int condEndOffset, int endOffset, boolean isActive) {
|
||||
public void encounterPoundIf(int startOffset, int condOffset, int condEndOffset, int endOffset, boolean isActive,
|
||||
IASTName[] macrosInDefinedExpression) {
|
||||
startOffset= getSequenceNumberForOffset(startOffset);
|
||||
condOffset= getSequenceNumberForOffset(condOffset);
|
||||
condEndOffset= getSequenceNumberForOffset(condEndOffset);
|
||||
// not using endOffset, compatible with 4.0: endOffset= getSequenceNumberForOffset(endOffset);
|
||||
fDirectives.add(new ASTIf(fTranslationUnit, startOffset, condOffset, condEndOffset, isActive));
|
||||
final ASTIf astif = new ASTIf(fTranslationUnit, startOffset, condOffset, condEndOffset, isActive);
|
||||
fDirectives.add(astif);
|
||||
for (int i = 0; i < macrosInDefinedExpression.length; i++) {
|
||||
ASTMacroReferenceName name = (ASTMacroReferenceName) macrosInDefinedExpression[i];
|
||||
name.setParent(astif);
|
||||
name.setPropertyInParent(IASTPreprocessorStatement.MACRO_NAME);
|
||||
addMacroReference(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void encounterPoundDefine(int startOffset, int nameOffset, int nameEndOffset, int expansionOffset, int endOffset, IMacroBinding macrodef) {
|
||||
startOffset= getSequenceNumberForOffset(startOffset);
|
||||
nameOffset= getSequenceNumberForOffset(nameOffset);
|
||||
|
@ -434,59 +468,93 @@ public class LocationMap implements ILocationResolver {
|
|||
return null;
|
||||
}
|
||||
|
||||
public ASTNode findPreprocessorNode(int sequenceNumber, int length, ASTNodeMatchKind matchKind) {
|
||||
int lower=0;
|
||||
int upper= fDirectives.size()-1;
|
||||
while(lower <= upper) {
|
||||
int middle= (lower+upper)/2;
|
||||
ASTPreprocessorNode candidate= fDirectives.get(middle);
|
||||
ASTNode result= candidate.findNode(sequenceNumber, length, matchKind);
|
||||
if (result != null) {
|
||||
if (matchKind.getRelationToSelection() == Relation.FIRST_CONTAINED) {
|
||||
if (middle>lower) {
|
||||
upper= middle; // if (upper-lower == 1) then middle==lower
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if (matchKind.isLowerBound(candidate, sequenceNumber, length)) {
|
||||
lower= middle+1;
|
||||
}
|
||||
else {
|
||||
upper= middle-1;
|
||||
public void findPreprocessorNode(ASTNodeSpecification<?> nodeSpec) {
|
||||
final int sequenceStart= nodeSpec.getSequenceStart();
|
||||
final int sequenceEnd= nodeSpec.getSequenceEnd();
|
||||
|
||||
// check directives
|
||||
int from= findLastNodeBefore(fDirectives, sequenceStart);
|
||||
for (int i= from+1; i < fDirectives.size(); i++) {
|
||||
ASTPreprocessorNode directive= fDirectives.get(i);
|
||||
if (directive.getOffset() > sequenceEnd) {
|
||||
break;
|
||||
}
|
||||
directive.findNode(nodeSpec);
|
||||
}
|
||||
// search for a macro-expansion
|
||||
LocationCtxMacroExpansion ctx= fRootContext.findSurroundingMacroExpansion(sequenceNumber, length);
|
||||
if (ctx != null) {
|
||||
ASTNode candidate= ctx.findNode(sequenceNumber, length, matchKind);
|
||||
int imageOffset= ctx.fEndOffsetInParent + sequenceNumber - ctx.fSequenceNumber;
|
||||
if (fTranslationUnit != null) {
|
||||
FindNodeByImageLocation visitor= new FindNodeByImageLocation(ctx.fSequenceNumber, ctx.getSequenceLength(), imageOffset, length, matchKind);
|
||||
fTranslationUnit.accept(visitor);
|
||||
ASTNode candidate2= visitor.getNode();
|
||||
if (matchKind.isBetterMatch(candidate2, candidate)) {
|
||||
candidate= candidate2;
|
||||
}
|
||||
|
||||
// check macro references and expansions
|
||||
from= findLastMacroReferenceBefore(fMacroReferences, sequenceStart);
|
||||
for (int i= from+1; i < fMacroReferences.size(); i++) {
|
||||
ASTPreprocessorNode macroRef= fMacroReferences.get(i);
|
||||
if (macroRef.getOffset() > sequenceEnd) {
|
||||
break;
|
||||
}
|
||||
ASTPreprocessorName[] nested= ctx.getNestedMacroReferences();
|
||||
for (ASTPreprocessorName name : nested) {
|
||||
IASTImageLocation imageLoc= name.getImageLocation();
|
||||
if (imageLoc != null && imageLoc.getLocationKind() == IASTImageLocation.ARGUMENT_TO_MACRO_EXPANSION) {
|
||||
if (matchKind.rangeMatches(imageLoc.getNodeOffset(), imageLoc.getNodeLength(), imageOffset, length)) {
|
||||
if (matchKind.isBetterMatch(name, candidate)) {
|
||||
candidate= name;
|
||||
if (macroRef.getPropertyInParent() == IASTPreprocessorMacroExpansion.NESTED_EXPANSION_NAME) {
|
||||
continue;
|
||||
}
|
||||
nodeSpec.visit(macroRef);
|
||||
IASTNode parent= macroRef.getParent();
|
||||
if (parent instanceof ASTMacroExpansion) {
|
||||
ASTMacroExpansion expansion= (ASTMacroExpansion) parent;
|
||||
assert expansion.getMacroReference() == macroRef;
|
||||
|
||||
if (nodeSpec.canContainMatches(expansion)) {
|
||||
nodeSpec.visit(expansion);
|
||||
if (!nodeSpec.requiresClass(IASTPreprocessorMacroExpansion.class)) {
|
||||
LocationCtxMacroExpansion ctx= expansion.getContext();
|
||||
if (fTranslationUnit != null) {
|
||||
FindNodeByImageLocation visitor= new FindNodeByImageLocation(ctx.fSequenceNumber, ctx.getSequenceLength(), nodeSpec);
|
||||
fTranslationUnit.accept(visitor);
|
||||
}
|
||||
ASTPreprocessorName[] nestedMacros= expansion.getNestedMacroReferences();
|
||||
for (ASTPreprocessorName nested : nestedMacros) {
|
||||
IASTImageLocation imgLoc= nested.getImageLocation();
|
||||
if (imgLoc != null && imgLoc.getLocationKind() == IASTImageLocation.ARGUMENT_TO_MACRO_EXPANSION) {
|
||||
nodeSpec.visit(nested, imgLoc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private int findLastNodeBefore(ArrayList<? extends ASTPreprocessorNode> nodes, int sequenceStart) {
|
||||
int lower=-1;
|
||||
int upper= nodes.size()-1;
|
||||
while(lower < upper) {
|
||||
int middle= (lower+upper+1)/2;
|
||||
ASTPreprocessorNode candidate= nodes.get(middle);
|
||||
if (candidate.getOffset() + candidate.getLength() >= sequenceStart) {
|
||||
upper= middle-1;
|
||||
}
|
||||
else {
|
||||
lower= middle;
|
||||
}
|
||||
}
|
||||
return lower;
|
||||
}
|
||||
|
||||
private int findLastMacroReferenceBefore(ArrayList<? extends ASTPreprocessorName> nodes, int sequenceStart) {
|
||||
int lower=-1;
|
||||
int upper= nodes.size()-1;
|
||||
while(lower < upper) {
|
||||
int middle= (lower+upper+1)/2;
|
||||
ASTPreprocessorNode candidate= nodes.get(middle);
|
||||
IASTNode parent= candidate.getParent();
|
||||
if (parent instanceof ASTMacroExpansion) {
|
||||
candidate= (ASTMacroExpansion) parent;
|
||||
}
|
||||
if (candidate.getOffset() + candidate.getLength() >= sequenceStart) {
|
||||
upper= middle-1;
|
||||
}
|
||||
else {
|
||||
lower= middle;
|
||||
}
|
||||
}
|
||||
return lower;
|
||||
}
|
||||
|
||||
public int getSequenceNumberForFileOffset(String filePath, int fileOffset) {
|
||||
LocationCtx ctx= fRootContext;
|
||||
if (filePath != null) {
|
||||
|
|
|
@ -1073,4 +1073,29 @@ public abstract class CPPSelectionTestsAnyIndexer extends BaseSelectionTestsInde
|
|||
input = part.getEditorInput();
|
||||
assertEquals("s.c", ((FileEditorInput)input).getFile().getName());
|
||||
}
|
||||
|
||||
// #define ADD_TEXT(txt1,txt2) txt1" "txt2
|
||||
// #define ADD(a,b) (a + b)
|
||||
// void main(void) {
|
||||
// #if defined(ADD_TEXT) && defined(ADD)
|
||||
// #endif
|
||||
// }
|
||||
public void testNavigationInDefinedExpression_215906() throws Exception {
|
||||
StringBuffer[] buffers= getContents(1);
|
||||
String code= buffers[0].toString();
|
||||
IFile file = importFile("s.cpp", code);
|
||||
TestSourceReader.waitUntilFileIsIndexed(index, file, MAX_WAIT_TIME);
|
||||
IASTNode decl;
|
||||
int offset1, offset2;
|
||||
|
||||
offset1 = code.indexOf("ADD_TEXT");
|
||||
offset2 = code.indexOf("ADD_TEXT", offset1+1);
|
||||
decl= testF3(file, offset2);
|
||||
assertNode("ADD_TEXT", offset1, decl);
|
||||
|
||||
offset1 = code.indexOf("ADD", offset1+1);
|
||||
offset2 = code.indexOf("ADD", offset2+1);
|
||||
decl= testF3(file, offset2);
|
||||
assertNode("ADD", offset1, decl);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -299,6 +299,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
super(parent, verticalRuler, overviewRuler, showAnnotationsOverview, styles, store);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IContentAssistant getContentAssistant() {
|
||||
return fContentAssistant;
|
||||
}
|
||||
|
@ -306,6 +307,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/*
|
||||
* @see ITextOperationTarget#doOperation(int)
|
||||
*/
|
||||
@Override
|
||||
public void doOperation(int operation) {
|
||||
|
||||
if (getTextWidget() == null)
|
||||
|
@ -332,6 +334,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/*
|
||||
* @see IWidgetTokenOwner#requestWidgetToken(IWidgetTokenKeeper)
|
||||
*/
|
||||
@Override
|
||||
public boolean requestWidgetToken(IWidgetTokenKeeper requester) {
|
||||
if (PlatformUI.getWorkbench().getHelpSystem().isContextHelpDisplayed())
|
||||
return false;
|
||||
|
@ -342,6 +345,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
* @see IWidgetTokenOwnerExtension#requestWidgetToken(IWidgetTokenKeeper, int)
|
||||
* @since 3.0
|
||||
*/
|
||||
@Override
|
||||
public boolean requestWidgetToken(IWidgetTokenKeeper requester, int priority) {
|
||||
if (PlatformUI.getWorkbench().getHelpSystem().isContextHelpDisplayed())
|
||||
return false;
|
||||
|
@ -352,6 +356,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
* @see org.eclipse.jface.text.source.SourceViewer#createFormattingContext()
|
||||
* @since 3.0
|
||||
*/
|
||||
@Override
|
||||
public IFormattingContext createFormattingContext() {
|
||||
IFormattingContext context= new FormattingContext();
|
||||
|
||||
|
@ -796,6 +801,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/*
|
||||
* @see org.eclipse.jface.action.IAction#run()
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
// Check whether sub word navigation is enabled.
|
||||
final IPreferenceStore store = getPreferenceStore();
|
||||
|
@ -861,6 +867,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/*
|
||||
* @see org.eclipse.cdt.internal.ui.editor.CEditor.NextSubWordAction#setCaretPosition(int)
|
||||
*/
|
||||
@Override
|
||||
protected void setCaretPosition(final int position) {
|
||||
getTextWidget().setCaretOffset(modelOffset2WidgetOffset(getSourceViewer(), position));
|
||||
}
|
||||
|
@ -883,6 +890,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/*
|
||||
* @see org.eclipse.cdt.internal.ui.editor.CEditor.NextSubWordAction#setCaretPosition(int)
|
||||
*/
|
||||
@Override
|
||||
protected void setCaretPosition(final int position) {
|
||||
if (!validateEditorInputState())
|
||||
return;
|
||||
|
@ -908,6 +916,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/*
|
||||
* @see org.eclipse.cdt.internal.ui.editor.CEditor.NextSubWordAction#findNextPosition(int)
|
||||
*/
|
||||
@Override
|
||||
protected int findNextPosition(int position) {
|
||||
return fIterator.following(position);
|
||||
}
|
||||
|
@ -937,6 +946,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/*
|
||||
* @see org.eclipse.cdt.internal.ui.editor.CEditor.NextSubWordAction#setCaretPosition(int)
|
||||
*/
|
||||
@Override
|
||||
protected void setCaretPosition(final int position) {
|
||||
final ISourceViewer viewer = getSourceViewer();
|
||||
|
||||
|
@ -976,6 +986,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/*
|
||||
* @see org.eclipse.jface.action.IAction#run()
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
// Check whether sub word navigation is enabled.
|
||||
final IPreferenceStore store = getPreferenceStore();
|
||||
|
@ -1041,6 +1052,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/*
|
||||
* @see org.eclipse.cdt.internal.ui.editor.CEditor.PreviousSubWordAction#setCaretPosition(int)
|
||||
*/
|
||||
@Override
|
||||
protected void setCaretPosition(final int position) {
|
||||
getTextWidget().setCaretOffset(modelOffset2WidgetOffset(getSourceViewer(), position));
|
||||
}
|
||||
|
@ -1063,6 +1075,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/*
|
||||
* @see org.eclipse.cdt.internal.ui.editor.CEditor.PreviousSubWordAction#setCaretPosition(int)
|
||||
*/
|
||||
@Override
|
||||
protected void setCaretPosition(int position) {
|
||||
if (!validateEditorInputState())
|
||||
return;
|
||||
|
@ -1087,6 +1100,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/*
|
||||
* @see org.eclipse.cdt.internal.ui.editor.CEditor.PreviousSubWordAction#findPreviousPosition(int)
|
||||
*/
|
||||
@Override
|
||||
protected int findPreviousPosition(int position) {
|
||||
return fIterator.preceding(position);
|
||||
}
|
||||
|
@ -1116,6 +1130,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/*
|
||||
* @see org.eclipse.cdt.internal.ui.editor.CEditor.PreviousSubWordAction#setCaretPosition(int)
|
||||
*/
|
||||
@Override
|
||||
protected void setCaretPosition(final int position) {
|
||||
final ISourceViewer viewer = getSourceViewer();
|
||||
|
||||
|
@ -1253,12 +1268,14 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/**
|
||||
* @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#initializeEditor()
|
||||
*/
|
||||
@Override
|
||||
protected void initializeEditor() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.ui.texteditor.AbstractTextEditor#doSetInput(org.eclipse.ui.IEditorInput)
|
||||
*/
|
||||
@Override
|
||||
protected void doSetInput(IEditorInput input) throws CoreException {
|
||||
ISourceViewer sourceViewer= getSourceViewer();
|
||||
if (!(sourceViewer instanceof ISourceViewerExtension2)) {
|
||||
|
@ -1313,6 +1330,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
* @see org.eclipse.ui.texteditor.AbstractTextEditor#setPreferenceStore(org.eclipse.jface.preference.IPreferenceStore)
|
||||
* @since 5.0
|
||||
*/
|
||||
@Override
|
||||
protected void setPreferenceStore(IPreferenceStore store) {
|
||||
super.setPreferenceStore(store);
|
||||
SourceViewerConfiguration sourceViewerConfiguration= getSourceViewerConfiguration();
|
||||
|
@ -1349,7 +1367,8 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/**
|
||||
* @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed()
|
||||
*/
|
||||
public boolean isSaveAsAllowed() {
|
||||
@Override
|
||||
public boolean isSaveAsAllowed() {
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
|
@ -1368,6 +1387,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/**
|
||||
* @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
public Object getAdapter(Class required) {
|
||||
if (IContentOutlinePage.class.equals(required)) {
|
||||
return getOutlinePage();
|
||||
|
@ -1421,6 +1441,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
*
|
||||
* @param event the property change event
|
||||
*/
|
||||
@Override
|
||||
protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
|
||||
String property = event.getProperty();
|
||||
|
||||
|
@ -1547,6 +1568,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/*
|
||||
* @see org.eclipse.ui.texteditor.AbstractTextEditor#initializeViewerColors(org.eclipse.jface.text.source.ISourceViewer)
|
||||
*/
|
||||
@Override
|
||||
protected void initializeViewerColors(ISourceViewer viewer) {
|
||||
// is handled by CSourceViewer
|
||||
}
|
||||
|
@ -1821,6 +1843,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
* @see org.eclipse.ui.texteditor.AbstractTextEditor#installTabsToSpacesConverter()
|
||||
* @since 4.0
|
||||
*/
|
||||
@Override
|
||||
protected void installTabsToSpacesConverter() {
|
||||
ISourceViewer sourceViewer= getSourceViewer();
|
||||
SourceViewerConfiguration config= getSourceViewerConfiguration();
|
||||
|
@ -1856,6 +1879,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
* @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#isTabsToSpacesConversionEnabled()
|
||||
* @since 4.0
|
||||
*/
|
||||
@Override
|
||||
protected boolean isTabsToSpacesConversionEnabled() {
|
||||
ICElement element= getInputCElement();
|
||||
ICProject project= element == null ? null : element.getCProject();
|
||||
|
@ -1870,7 +1894,8 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/**
|
||||
* @see org.eclipse.ui.IWorkbenchPart#dispose()
|
||||
*/
|
||||
public void dispose() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
|
||||
ISourceViewer sourceViewer = getSourceViewer();
|
||||
if (sourceViewer instanceof ITextViewerExtension)
|
||||
|
@ -1943,6 +1968,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/**
|
||||
* @see org.eclipse.ui.texteditor.AbstractTextEditor#canHandleMove(org.eclipse.ui.IEditorInput, org.eclipse.ui.IEditorInput)
|
||||
*/
|
||||
@Override
|
||||
protected boolean canHandleMove(IEditorInput originalElement, IEditorInput movedElement) {
|
||||
String oldLanguage = ""; //$NON-NLS-1$
|
||||
if (originalElement instanceof IFileEditorInput) {
|
||||
|
@ -1977,6 +2003,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/**
|
||||
* @see org.eclipse.ui.texteditor.AbstractTextEditor#createActions()
|
||||
*/
|
||||
@Override
|
||||
protected void createActions() {
|
||||
super.createActions();
|
||||
|
||||
|
@ -2088,6 +2115,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/**
|
||||
* @see org.eclipse.ui.texteditor.AbstractTextEditor#editorContextMenuAboutToShow(org.eclipse.jface.action.IMenuManager)
|
||||
*/
|
||||
@Override
|
||||
public void editorContextMenuAboutToShow(IMenuManager menu) {
|
||||
// marker for contributions to the top
|
||||
menu.add(new GroupMarker(ICommonMenuConstants.GROUP_TOP));
|
||||
|
@ -2135,6 +2163,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/*
|
||||
* @see org.eclipse.ui.texteditor.AbstractTextEditor#rulerContextMenuAboutToShow(org.eclipse.jface.action.IMenuManager)
|
||||
*/
|
||||
@Override
|
||||
protected void rulerContextMenuAboutToShow(IMenuManager menu) {
|
||||
super.rulerContextMenuAboutToShow(menu);
|
||||
IMenuManager foldingMenu= new MenuManager(CEditorMessages.getString("CEditor.menu.folding"), "projection"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
@ -2174,6 +2203,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
* @see org.eclipse.ui.part.WorkbenchPart#getOrientation()
|
||||
* @since 4.0
|
||||
*/
|
||||
@Override
|
||||
public int getOrientation() {
|
||||
// C/C++ editors are always left to right by default
|
||||
return SWT.LEFT_TO_RIGHT;
|
||||
|
@ -2182,6 +2212,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/*
|
||||
* @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#createPartControl(org.eclipse.swt.widgets.Composite)
|
||||
*/
|
||||
@Override
|
||||
public void createPartControl(Composite parent) {
|
||||
super.createPartControl(parent);
|
||||
|
||||
|
@ -2213,6 +2244,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/*
|
||||
* @see org.eclipse.ui.texteditor.AbstractTextEditor#installTextDragAndDrop(org.eclipse.jface.text.source.ISourceViewer)
|
||||
*/
|
||||
@Override
|
||||
protected void installTextDragAndDrop(ISourceViewer viewer) {
|
||||
if (fTextViewerDragAdapter != null) {
|
||||
// already installed, enable it
|
||||
|
@ -2239,6 +2271,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/*
|
||||
* @see org.eclipse.ui.texteditor.AbstractTextEditor#uninstallTextDragAndDrop(org.eclipse.jface.text.source.ISourceViewer)
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallTextDragAndDrop(ISourceViewer viewer) {
|
||||
if (fTextViewerDragAdapter != null) {
|
||||
// uninstall not possible, disable instead
|
||||
|
@ -2249,6 +2282,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/*
|
||||
* @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#getSourceViewerDecorationSupport(org.eclipse.jface.text.source.ISourceViewer)
|
||||
*/
|
||||
@Override
|
||||
protected SourceViewerDecorationSupport getSourceViewerDecorationSupport(ISourceViewer viewer) {
|
||||
if (fSourceViewerDecorationSupport == null) {
|
||||
fSourceViewerDecorationSupport= new CSourceViewerDecorationSupport(this, viewer, getOverviewRuler(), getAnnotationAccess(), getSharedColors());
|
||||
|
@ -2260,6 +2294,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/*
|
||||
* @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#configureSourceViewerDecorationSupport(org.eclipse.ui.texteditor.SourceViewerDecorationSupport)
|
||||
*/
|
||||
@Override
|
||||
protected void configureSourceViewerDecorationSupport(SourceViewerDecorationSupport support) {
|
||||
super.configureSourceViewerDecorationSupport(support);
|
||||
//Enhance the stock source viewer decorator with a bracket matcher
|
||||
|
@ -2387,6 +2422,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/*
|
||||
* Get the dektop's StatusLineManager
|
||||
*/
|
||||
@Override
|
||||
protected IStatusLineManager getStatusLineManager() {
|
||||
IEditorActionBarContributor contributor = getEditorSite().getActionBarContributor();
|
||||
if (contributor instanceof EditorActionBarContributor) {
|
||||
|
@ -2412,6 +2448,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/*
|
||||
* @see org.eclipse.ui.texteditor.AbstractTextEditor#createNavigationActions()
|
||||
*/
|
||||
@Override
|
||||
protected void createNavigationActions() {
|
||||
super.createNavigationActions();
|
||||
|
||||
|
@ -2457,6 +2494,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/*
|
||||
* @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#createSourceViewer(org.eclipse.swt.widgets.Composite, org.eclipse.jface.text.source.IVerticalRuler, int)
|
||||
*/
|
||||
@Override
|
||||
protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
|
||||
IPreferenceStore store= getPreferenceStore();
|
||||
ISourceViewer sourceViewer =
|
||||
|
@ -2555,6 +2593,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/*
|
||||
* @see org.eclipse.ui.editors.text.TextEditor#initializeKeyBindingScopes()
|
||||
*/
|
||||
@Override
|
||||
protected void initializeKeyBindingScopes() {
|
||||
setKeyBindingScopes(new String [] { "org.eclipse.cdt.ui.cEditorScope" } ); //$NON-NLS-1$
|
||||
}
|
||||
|
@ -2562,6 +2601,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/*
|
||||
* @see AbstractTextEditor#affectsTextPresentation(PropertyChangeEvent)
|
||||
*/
|
||||
@Override
|
||||
protected boolean affectsTextPresentation(PropertyChangeEvent event) {
|
||||
SourceViewerConfiguration configuration = getSourceViewerConfiguration();
|
||||
if (configuration instanceof CSourceViewerConfiguration) {
|
||||
|
@ -2582,6 +2622,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/*
|
||||
* @see org.eclipse.ui.texteditor.AbstractTextEditor#performRevert()
|
||||
*/
|
||||
@Override
|
||||
protected void performRevert() {
|
||||
ProjectionViewer projectionViewer = (ProjectionViewer) getSourceViewer();
|
||||
projectionViewer.setRedraw(false);
|
||||
|
@ -2612,7 +2653,8 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
*
|
||||
* @param msg message to be set
|
||||
*/
|
||||
protected void setStatusLineErrorMessage(String msg) {
|
||||
@Override
|
||||
protected void setStatusLineErrorMessage(String msg) {
|
||||
IEditorStatusLine statusLine = (IEditorStatusLine) getAdapter(IEditorStatusLine.class);
|
||||
if (statusLine != null)
|
||||
statusLine.setMessage(true, msg, null);
|
||||
|
@ -2624,6 +2666,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
* @param msg message to be set
|
||||
* @since 3.0
|
||||
*/
|
||||
@Override
|
||||
protected void setStatusLineMessage(String msg) {
|
||||
IEditorStatusLine statusLine = (IEditorStatusLine) getAdapter(IEditorStatusLine.class);
|
||||
if (statusLine != null)
|
||||
|
@ -2719,6 +2762,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/*
|
||||
* @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#collectContextMenuPreferencePages()
|
||||
*/
|
||||
@Override
|
||||
protected String[] collectContextMenuPreferencePages() {
|
||||
// Add C/C++ Editor relevant pages
|
||||
String[] parentPrefPageIds = super.collectContextMenuPreferencePages();
|
||||
|
@ -2848,6 +2892,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/*
|
||||
* @see org.eclipse.ui.texteditor.AbstractTextEditor#updateStateDependentActions()
|
||||
*/
|
||||
@Override
|
||||
protected void updateStateDependentActions() {
|
||||
super.updateStateDependentActions();
|
||||
fGenerateActionGroup.editorStateChanged();
|
||||
|
@ -2905,6 +2950,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
/*
|
||||
* @see Job#run(org.eclipse.core.runtime.IProgressMonitor)
|
||||
*/
|
||||
@Override
|
||||
public IStatus run(IProgressMonitor progressMonitor) {
|
||||
if (isCanceled(progressMonitor))
|
||||
return Status.CANCEL_STATUS;
|
||||
|
@ -3078,7 +3124,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
OccurrenceLocation[] locations= null;
|
||||
|
||||
IASTNodeSelector selector= astRoot.getNodeSelector(astRoot.getFilePath());
|
||||
IASTName name= selector.findSurroundingName(wordRegion.getOffset(), wordRegion.getLength());
|
||||
IASTName name= selector.findEnclosingName(wordRegion.getOffset(), wordRegion.getLength());
|
||||
|
||||
if (name != null) {
|
||||
IBinding binding= name.resolveBinding();
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
* IBM Corporation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.internal.ui.editor;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
@ -83,7 +82,7 @@ public class CElementHyperlinkDetector implements IHyperlinkDetector {
|
|||
final int offset= region.getOffset();
|
||||
final int length= Math.max(1, region.getLength());
|
||||
final IASTNodeSelector nodeSelector= ast.getNodeSelector(null);
|
||||
IASTName selectedName= nodeSelector.findSurroundingName(offset, length);
|
||||
IASTName selectedName= nodeSelector.findEnclosingName(offset, length);
|
||||
IASTFileLocation linkLocation= null;
|
||||
if (selectedName != null) { // found a name
|
||||
// prefer include statement over the include name
|
||||
|
@ -96,7 +95,7 @@ public class CElementHyperlinkDetector implements IHyperlinkDetector {
|
|||
}
|
||||
else {
|
||||
// search for include statement
|
||||
final IASTNode cand= nodeSelector.findSurroundingNode(offset, length);
|
||||
final IASTNode cand= nodeSelector.findEnclosingNode(offset, length);
|
||||
if (cand instanceof IASTPreprocessorIncludeStatement) {
|
||||
linkLocation= cand.getFileLocation();
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ public class PDOMSearchTextSelectionQuery extends PDOMSearchQuery {
|
|||
return ASTProvider.getASTProvider().runOnAST(tu, ASTProvider.WAIT_YES, monitor, new ASTRunnable() {
|
||||
public IStatus runOnAST(ILanguage language, IASTTranslationUnit ast) throws CoreException {
|
||||
if (ast != null) {
|
||||
IASTName searchName= ast.getNodeSelector(null).findSurroundingName(selection.getOffset(), selection.getLength());
|
||||
IASTName searchName= ast.getNodeSelector(null).findEnclosingName(selection.getOffset(), selection.getLength());
|
||||
if (searchName != null) {
|
||||
IBinding binding = searchName.resolveBinding();
|
||||
if (binding != null)
|
||||
|
|
|
@ -130,7 +130,7 @@ public class OpenDeclarationsAction extends SelectionParseAction {
|
|||
int selectionStart = selNode.getOffset();
|
||||
int selectionLength = selNode.getLength();
|
||||
|
||||
IASTName searchName= ast.getNodeSelector(null).findSurroundingName(selectionStart, selectionLength);
|
||||
IASTName searchName= ast.getNodeSelector(null).findEnclosingName(selectionStart, selectionLength);
|
||||
if (searchName != null) { // just right, only one name selected
|
||||
boolean found= false;
|
||||
final IASTNode parent = searchName.getParent();
|
||||
|
|
|
@ -95,7 +95,7 @@ public class CMacroExpansionInput {
|
|||
}
|
||||
if (fAllowSelection) {
|
||||
// selection
|
||||
fEnclosingNode= nodeSelector.findSurroundingNode(fTextRegion.getOffset(), fTextRegion.getLength());
|
||||
fEnclosingNode= nodeSelector.findEnclosingNode(fTextRegion.getOffset(), fTextRegion.getLength());
|
||||
if (fEnclosingNode != null) {
|
||||
boolean macroOccurrence= false;
|
||||
IASTNodeLocation[] locations= fEnclosingNode.getNodeLocations();
|
||||
|
@ -105,7 +105,7 @@ public class CMacroExpansionInput {
|
|||
IASTFileLocation fileLocation= location.asFileLocation();
|
||||
if (fileLocation != null && ast.getFilePath().equals(fileLocation.getFileName())) {
|
||||
if (fTextRegion.overlapsWith(fileLocation.getNodeOffset(), fileLocation.getNodeLength())) {
|
||||
addExpansionNode(nodeSelector.findSurroundingNode(fileLocation.getNodeOffset(), fileLocation.getNodeLength()));
|
||||
addExpansionNode(nodeSelector.findEnclosingNode(fileLocation.getNodeOffset(), fileLocation.getNodeLength()));
|
||||
macroOccurrence= true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -128,7 +128,7 @@ public class CSourceHover extends AbstractCEditorTextHover implements ITextHover
|
|||
public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) {
|
||||
if (ast != null) {
|
||||
try {
|
||||
IASTName name= ast.getNodeSelector(null).findSurroundingName(fTextRegion.getOffset(), fTextRegion.getLength());
|
||||
IASTName name= ast.getNodeSelector(null).findEnclosingName(fTextRegion.getOffset(), fTextRegion.getLength());
|
||||
if (name != null) {
|
||||
IBinding binding= name.resolveBinding();
|
||||
if (binding != null) {
|
||||
|
|
Loading…
Add table
Reference in a new issue