mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-09 02:36:01 +02:00
fix 72219
This commit is contained in:
parent
967b0b1812
commit
72ff239e40
3 changed files with 415 additions and 18 deletions
|
@ -0,0 +1,364 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Common Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/cpl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
/*
|
||||
* Created on Aug 23, 2004
|
||||
*/
|
||||
package org.eclipse.cdt.core.parser.tests;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
import org.eclipse.cdt.core.parser.CodeReader;
|
||||
import org.eclipse.cdt.core.parser.IParser;
|
||||
import org.eclipse.cdt.core.parser.IProblem;
|
||||
import org.eclipse.cdt.core.parser.ISourceElementRequestor;
|
||||
import org.eclipse.cdt.core.parser.NullLogService;
|
||||
import org.eclipse.cdt.core.parser.ParserFactory;
|
||||
import org.eclipse.cdt.core.parser.ParserLanguage;
|
||||
import org.eclipse.cdt.core.parser.ParserMode;
|
||||
import org.eclipse.cdt.core.parser.ParserUtil;
|
||||
import org.eclipse.cdt.core.parser.ScannerInfo;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTASMDefinition;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTAbstractTypeSpecifierDeclaration;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTClassReference;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTCodeScope;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTCompilationUnit;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTDeclaration;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTElaboratedTypeSpecifier;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTEnumerationReference;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTEnumerationSpecifier;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTEnumeratorReference;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTField;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTFieldReference;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTFunction;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTFunctionReference;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTInclusion;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTLinkageSpecification;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTMacro;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTMethod;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTMethodReference;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTNamespaceReference;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTParameterReference;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTScope;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTTemplateInstantiation;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTTemplateParameterReference;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTTemplateSpecialization;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTTypedefDeclaration;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTTypedefReference;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTUsingDeclaration;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTUsingDirective;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTVariable;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTVariableReference;
|
||||
import org.eclipse.cdt.internal.core.parser.CompleteParser;
|
||||
import org.eclipse.cdt.internal.core.parser.ParserException;
|
||||
import org.eclipse.cdt.internal.core.search.indexing.IndexManager;
|
||||
import org.eclipse.cdt.testplugin.CProjectHelper;
|
||||
import org.eclipse.cdt.testplugin.FileManager;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IWorkspace;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
*/
|
||||
public class CompleteParsePluginTest extends TestCase {
|
||||
NullProgressMonitor monitor;
|
||||
IWorkspace workspace;
|
||||
IProject project;
|
||||
FileManager fileManager;
|
||||
|
||||
public CompleteParsePluginTest()
|
||||
{
|
||||
super();
|
||||
try{
|
||||
initProject();
|
||||
} catch( Exception e){ /*boo*/ }
|
||||
}
|
||||
/**
|
||||
* @param name
|
||||
*/
|
||||
public CompleteParsePluginTest(String name)
|
||||
{
|
||||
super(name);
|
||||
try{
|
||||
initProject();
|
||||
} catch( Exception e){ /*boo*/ }
|
||||
}
|
||||
protected void initProject() throws Exception {
|
||||
(CCorePlugin.getDefault().getCoreModel().getIndexManager()).reset();
|
||||
monitor = new NullProgressMonitor();
|
||||
|
||||
workspace = ResourcesPlugin.getWorkspace();
|
||||
|
||||
ICProject cPrj = CProjectHelper.createCCProject("ParserTestProject", "bin"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
project = cPrj.getProject();
|
||||
project.setSessionProperty(IndexManager.activationKey,new Boolean(false));
|
||||
|
||||
if (project == null)
|
||||
fail("Unable to create project"); //$NON-NLS-1$
|
||||
|
||||
//Create file manager
|
||||
fileManager = new FileManager();
|
||||
}
|
||||
|
||||
protected IFile importFile(String fileName, String contents ) throws Exception{
|
||||
//Obtain file handle
|
||||
IFile file = project.getProject().getFile(fileName);
|
||||
|
||||
InputStream stream = new ByteArrayInputStream( contents.getBytes() );
|
||||
//Create file input stream
|
||||
if( file.exists() )
|
||||
file.setContents( stream, false, false, monitor );
|
||||
else
|
||||
file.create( stream, false, monitor );
|
||||
|
||||
fileManager.addFile(file);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
public static class CallbackTracker implements ISourceElementRequestor{
|
||||
private List callbacks;
|
||||
private IASTScope compUnit;
|
||||
public CallbackTracker( List callbacks ){
|
||||
this.callbacks = callbacks;
|
||||
}
|
||||
|
||||
public IASTScope getCompilationUnit()
|
||||
{
|
||||
return compUnit;
|
||||
}
|
||||
public static final String ACCEPT_PROBLEM = "ACCEPT_PROBLEM"; //$NON-NLS-1$
|
||||
public static final String ACCEPT_MACRO = "ACCEPT_MACRO"; //$NON-NLS-1$
|
||||
public static final String ACCEPT_VARIABLE = "ACCEPT_VARIABLE"; //$NON-NLS-1$
|
||||
public static final String ACCEPT_FUNCTION_DECL = "ACCEPT_FUNCTION_DECL"; //$NON-NLS-1$
|
||||
public static final String ACCEPT_USING_DIRECTIVE = "ACCEPT_USING_DIRECTIVE"; //$NON-NLS-1$
|
||||
public static final String ACCEPT_USING_DECL = "ACCEPT_USING_DECL"; //$NON-NLS-1$
|
||||
public static final String ACCEPT_ASM_DEF = "ACCEPT_ASM_DEF"; //$NON-NLS-1$
|
||||
public static final String ACCEPT_TYPEDEF = "ACCEPT_TYPEDEF"; //$NON-NLS-1$
|
||||
public static final String ACCEPT_ENUMERATION = "ACCEPT_ENUMERATION"; //$NON-NLS-1$
|
||||
public static final String ACCEPT_ELABORATED = "ACCEPT_ELABORATED"; //$NON-NLS-1$
|
||||
public static final String ACCEPT_ABSTRACT_TYPESPEC = "ACCEPT_ABSTRACT_TYPESPEC"; //$NON-NLS-1$
|
||||
public static final String ACCEPT_METHOD = "ACCEPT_METHOD"; //$NON-NLS-1$
|
||||
public static final String ACCEPT_FIELD = "ACCEPT_FIELD"; //$NON-NLS-1$
|
||||
public static final String ACCEPT_REFERENCE = "ACCEPT_REFERENCE"; //$NON-NLS-1$
|
||||
public static final String ACCEPT_FRIEND = "ACCEPT_FRIEND"; //$NON-NLS-1$
|
||||
public static final String ENTER_FUNCTION = "ENTER_FUNCTION"; //$NON-NLS-1$
|
||||
public static final String ENTER_CODE_BLOCK = "ENTER_CODE_BLOCK"; //$NON-NLS-1$
|
||||
public static final String ENTER_COMPILATION_UNIT = "ENTER_COMPILATION_UNIT"; //$NON-NLS-1$
|
||||
public static final String ENTER_INCLUSION = "ENTER_INCLUSION"; //$NON-NLS-1$
|
||||
public static final String ENTER_NAMESPACE = "ENTER_NAMESPACE"; //$NON-NLS-1$
|
||||
public static final String ENTER_CLASS_SPEC = "ENTER_CLASS_SPEC"; //$NON-NLS-1$
|
||||
public static final String ENTER_LINKAGE = "ENTER_LINKAGE"; //$NON-NLS-1$
|
||||
public static final String ENTER_TEMPLATE_DECL = "ENTER_TEMPLATE_DECL"; //$NON-NLS-1$
|
||||
public static final String ENTER_TEMPLATE_SPEC = "ENTER_TEMPLATE_SPEC"; //$NON-NLS-1$
|
||||
public static final String ENTER_TEMPLATE_INSTANCE = "ENTER_TEMPLATE_INSTANCE"; //$NON-NLS-1$
|
||||
public static final String ENTER_METHOD = "ENTER_METHOD"; //$NON-NLS-1$
|
||||
public static final String EXIT_FUNCTION = "EXIT_FUNCTION"; //$NON-NLS-1$
|
||||
public static final String EXIT_CODE_BLOCK = "EXIT_CODE_BLOCK"; //$NON-NLS-1$
|
||||
public static final String EXIT_METHOD = "EXIT_METHOD"; //$NON-NLS-1$
|
||||
public static final String EXIT_TEMPLATE_DECL = "EXIT_TEMPLATE_DECL"; //$NON-NLS-1$
|
||||
public static final String EXIT_TEMPLATE_SPEC = "EXIT_TEMPLATE_SPEC"; //$NON-NLS-1$
|
||||
public static final String EXIT_TEMPLATE_INSTANCE = "EXIT_TEMPLATE_INSTANCE"; //$NON-NLS-1$
|
||||
public static final String EXIT_LINKAGE = "EXIT_LINKAGE"; //$NON-NLS-1$
|
||||
public static final String EXIT_CLASS = "EXIT_CLASS"; //$NON-NLS-1$
|
||||
public static final String EXIT_NAMESPACE = "EXIT_NAMESPACE"; //$NON-NLS-1$
|
||||
public static final String EXIT_INCLUSION = "EXIT_INCLUSION"; //$NON-NLS-1$
|
||||
public static final String EXIT_COMPILATION_UNIT = "EXIT_COMPILATION_UNIT"; //$NON-NLS-1$
|
||||
|
||||
|
||||
public boolean acceptProblem( IProblem problem ) {
|
||||
callbacks.add( ACCEPT_PROBLEM );
|
||||
return false;
|
||||
}
|
||||
public void acceptMacro( IASTMacro macro ) { callbacks.add( ACCEPT_MACRO ); }
|
||||
public void acceptVariable( IASTVariable variable ) { callbacks.add( ACCEPT_VARIABLE ); }
|
||||
public void acceptFunctionDeclaration( IASTFunction function ) { callbacks.add( ACCEPT_FUNCTION_DECL); }
|
||||
public void acceptUsingDirective( IASTUsingDirective usageDirective ) { callbacks.add( ACCEPT_USING_DIRECTIVE ); }
|
||||
public void acceptUsingDeclaration( IASTUsingDeclaration usageDeclaration ) { callbacks.add( ACCEPT_USING_DECL ); }
|
||||
public void acceptASMDefinition( IASTASMDefinition asmDefinition ) { callbacks.add( ACCEPT_ASM_DEF ); }
|
||||
public void acceptTypedefDeclaration( IASTTypedefDeclaration typedef ) { callbacks.add( ACCEPT_TYPEDEF ); }
|
||||
public void acceptEnumerationSpecifier( IASTEnumerationSpecifier enumeration ) { callbacks.add( ACCEPT_ENUMERATION); }
|
||||
public void acceptElaboratedForewardDeclaration( IASTElaboratedTypeSpecifier elaboratedType ) { callbacks.add( ACCEPT_ELABORATED ); }
|
||||
public void acceptAbstractTypeSpecDeclaration( IASTAbstractTypeSpecifierDeclaration abstractDeclaration ) { callbacks.add( ACCEPT_ABSTRACT_TYPESPEC); }
|
||||
public void enterFunctionBody( IASTFunction function ) { callbacks.add( ENTER_FUNCTION ); }
|
||||
public void exitFunctionBody( IASTFunction function ) { callbacks.add( EXIT_FUNCTION ); }
|
||||
public void enterCodeBlock( IASTCodeScope scope ) { callbacks.add( ENTER_CODE_BLOCK ); }
|
||||
public void exitCodeBlock( IASTCodeScope scope ) { callbacks.add( EXIT_CODE_BLOCK ); }
|
||||
public void enterInclusion( IASTInclusion inclusion ) { callbacks.add( ENTER_INCLUSION ); }
|
||||
public void enterNamespaceDefinition( IASTNamespaceDefinition namespaceDefinition ) { callbacks.add( ENTER_NAMESPACE ); }
|
||||
public void enterClassSpecifier( IASTClassSpecifier classSpecification ) { callbacks.add( ENTER_CLASS_SPEC ); }
|
||||
public void enterLinkageSpecification( IASTLinkageSpecification linkageSpec ) { callbacks.add( ENTER_LINKAGE ); }
|
||||
public void enterTemplateDeclaration( IASTTemplateDeclaration declaration ) { callbacks.add( ENTER_TEMPLATE_DECL ); }
|
||||
public void enterTemplateSpecialization( IASTTemplateSpecialization specialization ) { callbacks.add( ENTER_TEMPLATE_SPEC ); }
|
||||
public void enterTemplateInstantiation( IASTTemplateInstantiation instantiation ) { callbacks.add( ENTER_TEMPLATE_INSTANCE ); }
|
||||
public void acceptMethodDeclaration( IASTMethod method ) { callbacks.add( ACCEPT_METHOD ); }
|
||||
public void enterMethodBody( IASTMethod method ) { callbacks.add( ENTER_METHOD ); }
|
||||
public void exitMethodBody( IASTMethod method ) { callbacks.add( EXIT_METHOD ); }
|
||||
public void acceptField( IASTField field ) { callbacks.add( ACCEPT_FIELD ); }
|
||||
public void acceptClassReference( IASTClassReference reference ) { callbacks.add( ACCEPT_REFERENCE ); }
|
||||
public void acceptTypedefReference( IASTTypedefReference reference ) { callbacks.add( ACCEPT_REFERENCE ); }
|
||||
public void acceptNamespaceReference( IASTNamespaceReference reference ) { callbacks.add( ACCEPT_REFERENCE ); }
|
||||
public void acceptEnumerationReference( IASTEnumerationReference reference ) { callbacks.add( ACCEPT_REFERENCE ); }
|
||||
public void acceptVariableReference( IASTVariableReference reference ) { callbacks.add( ACCEPT_REFERENCE ); }
|
||||
public void acceptFunctionReference( IASTFunctionReference reference ) { callbacks.add( ACCEPT_REFERENCE ); }
|
||||
public void acceptFieldReference( IASTFieldReference reference ) { callbacks.add( ACCEPT_REFERENCE ); }
|
||||
public void acceptMethodReference( IASTMethodReference reference ) { callbacks.add( ACCEPT_REFERENCE ); }
|
||||
public void acceptEnumeratorReference( IASTEnumeratorReference reference ) { callbacks.add( ACCEPT_REFERENCE ); }
|
||||
public void acceptParameterReference( IASTParameterReference reference ) { callbacks.add( ACCEPT_REFERENCE ); }
|
||||
public void acceptTemplateParameterReference( IASTTemplateParameterReference reference ) { callbacks.add( ACCEPT_REFERENCE ); }
|
||||
public void acceptFriendDeclaration( IASTDeclaration declaration ) { callbacks.add( ACCEPT_FRIEND ); }
|
||||
public void exitTemplateDeclaration( IASTTemplateDeclaration declaration ) { callbacks.add( EXIT_TEMPLATE_DECL); }
|
||||
public void exitTemplateSpecialization( IASTTemplateSpecialization specialization ) { callbacks.add( EXIT_TEMPLATE_SPEC ); }
|
||||
public void exitTemplateExplicitInstantiation( IASTTemplateInstantiation instantiation ) { callbacks.add( EXIT_TEMPLATE_INSTANCE ); }
|
||||
public void exitLinkageSpecification( IASTLinkageSpecification linkageSpec ) { callbacks.add( ACCEPT_MACRO ); }
|
||||
public void exitClassSpecifier( IASTClassSpecifier classSpecification ) { callbacks.add( EXIT_CLASS ); }
|
||||
public void exitNamespaceDefinition( IASTNamespaceDefinition namespaceDefinition ) { callbacks.add( EXIT_NAMESPACE); }
|
||||
public void exitInclusion( IASTInclusion inclusion ) { callbacks.add( EXIT_INCLUSION ); }
|
||||
public void exitCompilationUnit( IASTCompilationUnit compilationUnit ) { callbacks.add( EXIT_COMPILATION_UNIT ); }
|
||||
public void enterCompilationUnit( IASTCompilationUnit compilationUnit )
|
||||
{
|
||||
callbacks.add( ENTER_COMPILATION_UNIT );
|
||||
compUnit = compilationUnit;
|
||||
}
|
||||
public CodeReader createReader( String finalPath, Iterator workingCopies ) {
|
||||
return ParserUtil.createReader(finalPath,workingCopies);
|
||||
}
|
||||
|
||||
}
|
||||
public CallbackTracker callback;
|
||||
protected IASTScope parse( IFile code, List callbacks ) throws Exception
|
||||
{
|
||||
return parse( code, callbacks, ParserLanguage.CPP );
|
||||
}
|
||||
|
||||
protected IASTScope parse(IFile code, List callbackList, ParserLanguage language) throws Exception
|
||||
{
|
||||
callback = new CallbackTracker( callbackList );
|
||||
IParser parser = ParserFactory.createParser(
|
||||
ParserFactory.createScanner( new CodeReader( code.getLocation().toOSString(), code.getContents() ), new ScannerInfo(), //$NON-NLS-1$
|
||||
ParserMode.COMPLETE_PARSE, language, callback, new NullLogService(), null ), callback, ParserMode.COMPLETE_PARSE, language, null
|
||||
);
|
||||
boolean parseResult = parser.parse();
|
||||
// throw exception if there are generated IProblems
|
||||
if( !parseResult ) throw new ParserException( "FAILURE"); //$NON-NLS-1$
|
||||
if( parseResult )
|
||||
{
|
||||
assertTrue( ((CompleteParser)parser).validateCaches());
|
||||
}
|
||||
return callback.getCompilationUnit();
|
||||
}
|
||||
|
||||
public void testBug72219() throws Exception {
|
||||
String foo = "int FOO;"; //$NON-NLS-1$
|
||||
String code = "#include \"foo.h\" \n int bar;"; //$NON-NLS-1$
|
||||
|
||||
importFile( "foo.h", foo ); //$NON-NLS-1$
|
||||
IFile cpp = importFile( "code.cpp", code ); //$NON-NLS-1$
|
||||
|
||||
List calls = new ArrayList();
|
||||
Iterator i = parse( cpp, calls ).getDeclarations();
|
||||
|
||||
assertTrue( i.next() instanceof IASTVariable );
|
||||
assertTrue( i.next() instanceof IASTVariable );
|
||||
assertFalse( i.hasNext() );
|
||||
|
||||
i = calls.iterator();
|
||||
assertEquals( i.next(), CallbackTracker.ENTER_COMPILATION_UNIT );
|
||||
assertEquals( i.next(), CallbackTracker.ENTER_INCLUSION );
|
||||
assertEquals( i.next(), CallbackTracker.ACCEPT_VARIABLE );
|
||||
assertEquals( i.next(), CallbackTracker.EXIT_INCLUSION );
|
||||
assertEquals( i.next(), CallbackTracker.ACCEPT_VARIABLE );
|
||||
assertEquals( i.next(), CallbackTracker.EXIT_COMPILATION_UNIT );
|
||||
assertFalse( i.hasNext() );
|
||||
}
|
||||
|
||||
public void testBug72219_2() throws Exception {
|
||||
String foo = "int FOO;"; //$NON-NLS-1$
|
||||
String code = "int bar; \n #include \"foo.h\""; //$NON-NLS-1$
|
||||
|
||||
importFile( "foo.h", foo ); //$NON-NLS-1$
|
||||
IFile cpp = importFile( "code.cpp", code ); //$NON-NLS-1$
|
||||
|
||||
List calls = new ArrayList();
|
||||
Iterator i = parse( cpp, calls ).getDeclarations();
|
||||
|
||||
assertTrue( i.next() instanceof IASTVariable );
|
||||
assertTrue( i.next() instanceof IASTVariable );
|
||||
assertFalse( i.hasNext() );
|
||||
|
||||
i = calls.iterator();
|
||||
assertEquals( i.next(), CallbackTracker.ENTER_COMPILATION_UNIT );
|
||||
assertEquals( i.next(), CallbackTracker.ACCEPT_VARIABLE );
|
||||
assertEquals( i.next(), CallbackTracker.ENTER_INCLUSION );
|
||||
assertEquals( i.next(), CallbackTracker.ACCEPT_VARIABLE );
|
||||
assertEquals( i.next(), CallbackTracker.EXIT_INCLUSION );
|
||||
assertEquals( i.next(), CallbackTracker.EXIT_COMPILATION_UNIT );
|
||||
assertFalse( i.hasNext() );
|
||||
}
|
||||
|
||||
public void testBug72219_3() throws Exception {
|
||||
String defs = "#define A \n #define B \n"; //$NON-NLS-1$
|
||||
String code = "int foo; \n #include \"defs.h\" \n int bar;"; //$NON-NLS-1$
|
||||
|
||||
importFile( "defs.h", defs); //$NON-NLS-1$
|
||||
IFile cpp = importFile( "code.cpp", code ); //$NON-NLS-1$
|
||||
|
||||
List calls = new ArrayList();
|
||||
Iterator i = parse( cpp, calls ).getDeclarations();
|
||||
|
||||
assertTrue( i.next() instanceof IASTVariable );
|
||||
assertTrue( i.next() instanceof IASTVariable );
|
||||
assertFalse( i.hasNext() );
|
||||
|
||||
i = calls.iterator();
|
||||
assertEquals( i.next(), CallbackTracker.ENTER_COMPILATION_UNIT );
|
||||
assertEquals( i.next(), CallbackTracker.ACCEPT_VARIABLE );
|
||||
assertEquals( i.next(), CallbackTracker.ENTER_INCLUSION );
|
||||
assertEquals( i.next(), CallbackTracker.ACCEPT_MACRO );
|
||||
assertEquals( i.next(), CallbackTracker.ACCEPT_MACRO );
|
||||
assertEquals( i.next(), CallbackTracker.EXIT_INCLUSION );
|
||||
assertEquals( i.next(), CallbackTracker.ACCEPT_VARIABLE );
|
||||
assertEquals( i.next(), CallbackTracker.EXIT_COMPILATION_UNIT );
|
||||
assertFalse( i.hasNext() );
|
||||
}
|
||||
|
||||
public void test72219_4() throws Exception{
|
||||
String code = "int a; \n #define A\n int b;\n #define B\n"; //$NON-NLS-1$
|
||||
|
||||
IFile cpp = importFile( "code.cpp", code ); //$NON-NLS-1$
|
||||
List calls = new ArrayList();
|
||||
|
||||
parse( cpp, calls );
|
||||
|
||||
Iterator i = calls.iterator();
|
||||
assertEquals( i.next(), CallbackTracker.ENTER_COMPILATION_UNIT );
|
||||
assertEquals( i.next(), CallbackTracker.ACCEPT_VARIABLE );
|
||||
assertEquals( i.next(), CallbackTracker.ACCEPT_MACRO );
|
||||
assertEquals( i.next(), CallbackTracker.ACCEPT_VARIABLE );
|
||||
assertEquals( i.next(), CallbackTracker.ACCEPT_MACRO );
|
||||
assertEquals( i.next(), CallbackTracker.EXIT_COMPILATION_UNIT );
|
||||
assertFalse( i.hasNext() );
|
||||
}
|
||||
}
|
|
@ -47,6 +47,7 @@ public class ParserTestSuite extends TestCase {
|
|||
suite.addTestSuite( CompleteParseASTTemplateTest.class );
|
||||
suite.addTestSuite( StructuralParseTest.class );
|
||||
suite.addTestSuite( ObjectMapTest.class );
|
||||
suite.addTestSuite( CompleteParsePluginTest.class );
|
||||
// suite.addTest( GCCParserExtensionTestSuite.suite() );
|
||||
return suite;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.eclipse.cdt.core.parser.ScannerException;
|
|||
import org.eclipse.cdt.core.parser.ast.IASTCompletionNode;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTFactory;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTInclusion;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTMacro;
|
||||
import org.eclipse.cdt.core.parser.extension.IScannerExtension;
|
||||
import org.eclipse.cdt.internal.core.parser.ast.ASTCompletionNode;
|
||||
import org.eclipse.cdt.internal.core.parser.ast.EmptyIterator;
|
||||
|
@ -102,6 +103,10 @@ public class Scanner2 implements IScanner, IScannerData {
|
|||
private int[] lineNumbers = new int[bufferInitialSize];
|
||||
private int[] lineOffsets = new int[bufferInitialSize];
|
||||
|
||||
//inclusion stack
|
||||
private Object[] callbackStack = new Object[bufferInitialSize];
|
||||
private int callbackPos = -1;
|
||||
|
||||
//branch tracking
|
||||
private int branchStackPos = -1;
|
||||
private int[] branches = new int[bufferInitialSize];
|
||||
|
@ -215,7 +220,7 @@ public class Scanner2 implements IScanner, IScannerData {
|
|||
bufferData[bufferStackPos] = data;
|
||||
if( data instanceof InclusionData )
|
||||
{
|
||||
requestor.enterInclusion( ((InclusionData)data).inclusion );
|
||||
pushCallback( data );
|
||||
if( log.isTracing() )
|
||||
{
|
||||
StringBuffer b = new StringBuffer( "Entering inclusion "); //$NON-NLS-1$
|
||||
|
@ -236,12 +241,38 @@ public class Scanner2 implements IScanner, IScannerData {
|
|||
buffer.append( ((InclusionData)bufferData[bufferStackPos]).reader.filename );
|
||||
log.traceLog( buffer.toString() );
|
||||
}
|
||||
requestor.exitInclusion( ((InclusionData)bufferData[bufferStackPos]).inclusion );
|
||||
pushCallback( ((InclusionData) bufferData[bufferStackPos]).inclusion );
|
||||
}
|
||||
bufferData[bufferStackPos] = null;
|
||||
--bufferStackPos;
|
||||
}
|
||||
|
||||
private void pushCallback( Object obj ){
|
||||
if( ++callbackPos == callbackStack.length ){
|
||||
Object[] temp = new Object[ callbackStack.length << 1 ];
|
||||
System.arraycopy( callbackStack, 0, temp, 0, callbackStack.length );
|
||||
callbackStack = temp;
|
||||
}
|
||||
callbackStack[ callbackPos ] = obj;
|
||||
}
|
||||
|
||||
private void popCallbacks(){
|
||||
Object obj = null;
|
||||
for( int i = 0; i <= callbackPos; i++ ){
|
||||
obj = callbackStack[i];
|
||||
//on the stack, InclusionData means enter, IASTInclusion means exit
|
||||
if( obj instanceof InclusionData )
|
||||
requestor.enterInclusion( ((InclusionData)obj).inclusion );
|
||||
else if( obj instanceof IASTInclusion )
|
||||
requestor.exitInclusion( (IASTInclusion) obj );
|
||||
else if( obj instanceof IASTMacro )
|
||||
requestor.acceptMacro( (IASTMacro) obj );
|
||||
else if( obj instanceof IProblem )
|
||||
requestor.acceptProblem( (IProblem) obj );
|
||||
}
|
||||
callbackPos = -1;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.IScanner#addDefinition(java.lang.String, org.eclipse.cdt.core.parser.IMacroDescriptor)
|
||||
*/
|
||||
|
@ -325,6 +356,18 @@ public class Scanner2 implements IScanner, IScannerData {
|
|||
* @see org.eclipse.cdt.core.parser.IScanner#nextToken()
|
||||
*/
|
||||
public IToken nextToken() throws ScannerException, EndOfFileException {
|
||||
if (nextToken == null && !finished ) {
|
||||
nextToken = fetchToken();
|
||||
if (nextToken == null)
|
||||
{
|
||||
finished = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( callbackPos != -1 ){
|
||||
popCallbacks();
|
||||
}
|
||||
|
||||
if (finished)
|
||||
{
|
||||
if( offsetBoundary == -1 )
|
||||
|
@ -332,16 +375,6 @@ public class Scanner2 implements IScanner, IScannerData {
|
|||
throwOLRE();
|
||||
}
|
||||
|
||||
if (nextToken == null) {
|
||||
nextToken = fetchToken();
|
||||
if (nextToken == null)
|
||||
{
|
||||
if( offsetBoundary == -1 )
|
||||
throw EOF;
|
||||
throwOLRE();
|
||||
}
|
||||
}
|
||||
|
||||
if (lastToken != null)
|
||||
lastToken.setNext(nextToken);
|
||||
IToken oldToken = lastToken;
|
||||
|
@ -963,7 +996,7 @@ public class Scanner2 implements IScanner, IScannerData {
|
|||
private void handleProblem(int id, int startOffset, char [] arg ) {
|
||||
if( parserMode == ParserMode.COMPLETION_PARSE ) return;
|
||||
IProblem p = spf.createProblem( id, startOffset, bufferPos[bufferStackPos], getLineNumber( bufferPos[bufferStackPos] ), getCurrentFilename(), arg != null ? arg : emptyCharArray, false, true );
|
||||
requestor.acceptProblem( p );
|
||||
pushCallback( p );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1443,8 +1476,8 @@ public class Scanner2 implements IScanner, IScannerData {
|
|||
if( parserMode == ParserMode.QUICK_PARSE )
|
||||
{
|
||||
IASTInclusion inclusion = getASTFactory().createInclusion( fileNameArray, EMPTY_STRING_CHAR_ARRAY, local, startOffset, startingLineNumber, nameOffset, nameEndOffset, nameLine, endOffset, endLine, getCurrentFilename() );
|
||||
requestor.enterInclusion( inclusion );
|
||||
requestor.exitInclusion( inclusion );
|
||||
pushCallback( new InclusionData( null, inclusion ) );
|
||||
pushCallback( inclusion );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1633,8 +1666,7 @@ public class Scanner2 implements IScanner, IScannerData {
|
|||
? new ObjectStyleMacro(name, text)
|
||||
: new FunctionStyleMacro(name, text, arglist) );
|
||||
|
||||
requestor.acceptMacro( getASTFactory().createMacro( name, startingOffset, startingLineNumber, idstart, idstart + idlen, nameLine, textstart + textlen, endingLine, null, getCurrentFilename() )); //TODO - IMacroDescriptor?
|
||||
|
||||
pushCallback( getASTFactory().createMacro( name, startingOffset, startingLineNumber, idstart, idstart + idlen, nameLine, textstart + textlen, endingLine, null, getCurrentFilename() ) );//TODO - IMacroDescriptor?
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue