Skip to main content
aboutsummaryrefslogblamecommitdiffstats
blob: fba3e4f2c50b9573f037adb391db6a3241680c15 (plain) (tree)
1
2
3
4
5
6
7
8
9
                                                                                
                                                                


                                                                       
                                                           


                                         


                                                    
                                                                                 











                                                                           
                                               






                                                                       
                                                       




                                                        


                                             
 





                                                 
 





                                                 
                                                                   








                                                                                                                            







                                                                      
                                                                                  





                                                                                                                  
                        


                                                                                
                                





                                                                          
                                                                                  



                                                             
                                                                    



                                                             
                                                                    



                                                                      
                                                                             



                                                                      
                                                                             



                                                                  
                                                                                                            








                                     




                                                                              
                                                                   

                                                                           
 
                                                                                         
                                                                   



                                                                           
                                                                  


                                                                          
 
                                                                      
                                                                  




                                                                                             










                                                   





                                                                              
                                                                   

                                                                      
 
                                                                                              
                                                                   















                                                                         
                                                                     



                                                                              
                                                                      


                                                                              
 
                                                                         
                                                                     



                                                                                         
                                                                      




                                                                                                             
                                                                 



                                                                         
         
 







                                                        




















                                                        
                                                


                                                        
 

                                                    
                                            

                                                    









                                                    




















                                                        
                                                


                                                        
 

                                                    
                                            

                                                    











                                              





















                                                        
                                                


                                                        
 

                                                    
                                            

                                                    
         
 






                                                    
                                                    
                                                                  
                                                 
                                                      








                                                
                                                  
                                                                
                                               
                                                    
         
 



                                          


                                                    
 

                                                       
                                               
                                                       
 

                                                       
                                               
                                                       
 

                                                                   
         
 









                                    

                                                
                                                
                                                       
                                               



                                                
                                               

                                                       
 


                                                
                                               





                                                       
                                               

                                                       
         
 


                                           

                                                 


                                                      
 
/*******************************************************************************
 * Copyright (c) 2008, 2013 Wind River Systems, Inc. and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * 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.FileContent;
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 AST2TestBase {

	static public TestSuite suite() {
		return suite(ASTNodeSelectorTest.class);
	}

	protected String fCode;
	protected IASTTranslationUnit fTu;
	protected IASTNodeSelector fSelector;

	public ASTNodeSelectorTest() {
	}

	public ASTNodeSelectorTest(String name) {
		super(name);
	}

	@Override
	protected void setUp() throws Exception {
		super.setUp();
		createTranslationUnit();
	}

	protected void createTranslationUnit() throws IOException {
		fCode = getContents(1)[0].toString();
		FileContent codeReader = FileContent.create("<test-code>", fCode.toCharArray());
		ScannerInfo scannerInfo = new ScannerInfo();
		IScanner scanner = AST2TestBase.createScanner(codeReader, ParserLanguage.CPP, ParserMode.COMPLETE_PARSE,
				scannerInfo);
		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, x1, "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, x1, "NESTED");
	}

	// #define id(x,y) x y
	// id(int a, =1);
	// id(int b=, a);
	public void testImageLocations() {
		int a1 = fCode.indexOf("a");
		int a2 = fCode.indexOf("a", a1 + 1);
		int b1 = fCode.indexOf("b");

		testName(a1, a1 + 1, "a");
		testContainedName(a1 - 1, a2 + 2, "a");
		testEnclosingName(a1, a1, "a");
		testEnclosingName(a1 + 1, a1 + 1, "a");

		testName(a2, a2 + 1, "a");
		testContainedName(a2 - 1, a2 + 2, "a");
		testEnclosingName(a2, a2, "a");
		testEnclosingName(a2 + 1, a2 + 1, "a");

		testEnclosingNode(a1 - 1, a1 + 1, "id(int a, =1)");
		testContainedNode(a1 - 8, a1 + 1, "id");
	}

	// namespace ns {int a;}
	// int x= ns::a;
	// #define M int b;
	// M
	// #define N() int c;
	// N()
	// #define O
	// #define P()
	// P()O
	public void testOrdering() {
		int x1 = fCode.indexOf("ns::a");
		int x2 = x1 + "ns::a".length();
		testContainedName(x1, x2, "ns");
		testEnclosingName(x2 - 1, x2 - 1, "a");
		testEnclosingName(x2, x2, "a");

		x1 = fCode.indexOf("M");
		x1 = fCode.indexOf("M", x1 + 1);
		testNode(x1, x1 + 1, "M");
		testEnclosingNode(x1, x1, "M");
		testEnclosingNode(x1 + 1, x1 + 1, "M");
		testContainedNode(x1 - 1, x1 + 2, "M");

		x1 = fCode.indexOf("N");
		x1 = fCode.indexOf("N", x1 + 1);
		testNode(x1, x1 + 1, "N");
		testEnclosingNode(x1, x1, "N");
		testEnclosingNode(x1 + 1, x1 + 1, "N");
		testContainedNode(x1 - 1, x1 + 2, "N");

		x1 = fCode.indexOf("O");
		x1 = fCode.indexOf("O", x1 + 1);
		testNode(x1, x1 + 1, "O");
		testEnclosingNode(x1, x1, "O");
		testEnclosingNode(x1 + 1, x1 + 1, "O");
		testContainedNode(x1 - 1, x1 + 2, "O");
	}

	// #define MACRO void m
	// MACRO();
	public void testEnclosingAMacro() {
		int x1 = fCode.indexOf("MACRO(");
		int x2 = x1 + "MACRO(".length();
		testContainedName(x1, x2, "MACRO");
		testEnclosingNode(x1, x2, "MACRO();");
	}
}

Back to the top