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( CompleteParseASTTemplateTest.class );
|
||||||
suite.addTestSuite( StructuralParseTest.class );
|
suite.addTestSuite( StructuralParseTest.class );
|
||||||
suite.addTestSuite( ObjectMapTest.class );
|
suite.addTestSuite( ObjectMapTest.class );
|
||||||
|
suite.addTestSuite( CompleteParsePluginTest.class );
|
||||||
// suite.addTest( GCCParserExtensionTestSuite.suite() );
|
// suite.addTest( GCCParserExtensionTestSuite.suite() );
|
||||||
return 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.IASTCompletionNode;
|
||||||
import org.eclipse.cdt.core.parser.ast.IASTFactory;
|
import org.eclipse.cdt.core.parser.ast.IASTFactory;
|
||||||
import org.eclipse.cdt.core.parser.ast.IASTInclusion;
|
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.core.parser.extension.IScannerExtension;
|
||||||
import org.eclipse.cdt.internal.core.parser.ast.ASTCompletionNode;
|
import org.eclipse.cdt.internal.core.parser.ast.ASTCompletionNode;
|
||||||
import org.eclipse.cdt.internal.core.parser.ast.EmptyIterator;
|
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[] lineNumbers = new int[bufferInitialSize];
|
||||||
private int[] lineOffsets = new int[bufferInitialSize];
|
private int[] lineOffsets = new int[bufferInitialSize];
|
||||||
|
|
||||||
|
//inclusion stack
|
||||||
|
private Object[] callbackStack = new Object[bufferInitialSize];
|
||||||
|
private int callbackPos = -1;
|
||||||
|
|
||||||
//branch tracking
|
//branch tracking
|
||||||
private int branchStackPos = -1;
|
private int branchStackPos = -1;
|
||||||
private int[] branches = new int[bufferInitialSize];
|
private int[] branches = new int[bufferInitialSize];
|
||||||
|
@ -215,7 +220,7 @@ public class Scanner2 implements IScanner, IScannerData {
|
||||||
bufferData[bufferStackPos] = data;
|
bufferData[bufferStackPos] = data;
|
||||||
if( data instanceof InclusionData )
|
if( data instanceof InclusionData )
|
||||||
{
|
{
|
||||||
requestor.enterInclusion( ((InclusionData)data).inclusion );
|
pushCallback( data );
|
||||||
if( log.isTracing() )
|
if( log.isTracing() )
|
||||||
{
|
{
|
||||||
StringBuffer b = new StringBuffer( "Entering inclusion "); //$NON-NLS-1$
|
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 );
|
buffer.append( ((InclusionData)bufferData[bufferStackPos]).reader.filename );
|
||||||
log.traceLog( buffer.toString() );
|
log.traceLog( buffer.toString() );
|
||||||
}
|
}
|
||||||
requestor.exitInclusion( ((InclusionData)bufferData[bufferStackPos]).inclusion );
|
pushCallback( ((InclusionData) bufferData[bufferStackPos]).inclusion );
|
||||||
}
|
}
|
||||||
bufferData[bufferStackPos] = null;
|
bufferData[bufferStackPos] = null;
|
||||||
--bufferStackPos;
|
--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)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.core.parser.IScanner#addDefinition(java.lang.String, org.eclipse.cdt.core.parser.IMacroDescriptor)
|
* @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()
|
* @see org.eclipse.cdt.core.parser.IScanner#nextToken()
|
||||||
*/
|
*/
|
||||||
public IToken nextToken() throws ScannerException, EndOfFileException {
|
public IToken nextToken() throws ScannerException, EndOfFileException {
|
||||||
|
if (nextToken == null && !finished ) {
|
||||||
|
nextToken = fetchToken();
|
||||||
|
if (nextToken == null)
|
||||||
|
{
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( callbackPos != -1 ){
|
||||||
|
popCallbacks();
|
||||||
|
}
|
||||||
|
|
||||||
if (finished)
|
if (finished)
|
||||||
{
|
{
|
||||||
if( offsetBoundary == -1 )
|
if( offsetBoundary == -1 )
|
||||||
|
@ -332,16 +375,6 @@ public class Scanner2 implements IScanner, IScannerData {
|
||||||
throwOLRE();
|
throwOLRE();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextToken == null) {
|
|
||||||
nextToken = fetchToken();
|
|
||||||
if (nextToken == null)
|
|
||||||
{
|
|
||||||
if( offsetBoundary == -1 )
|
|
||||||
throw EOF;
|
|
||||||
throwOLRE();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lastToken != null)
|
if (lastToken != null)
|
||||||
lastToken.setNext(nextToken);
|
lastToken.setNext(nextToken);
|
||||||
IToken oldToken = lastToken;
|
IToken oldToken = lastToken;
|
||||||
|
@ -963,7 +996,7 @@ public class Scanner2 implements IScanner, IScannerData {
|
||||||
private void handleProblem(int id, int startOffset, char [] arg ) {
|
private void handleProblem(int id, int startOffset, char [] arg ) {
|
||||||
if( parserMode == ParserMode.COMPLETION_PARSE ) return;
|
if( parserMode == ParserMode.COMPLETION_PARSE ) return;
|
||||||
IProblem p = spf.createProblem( id, startOffset, bufferPos[bufferStackPos], getLineNumber( bufferPos[bufferStackPos] ), getCurrentFilename(), arg != null ? arg : emptyCharArray, false, true );
|
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 )
|
if( parserMode == ParserMode.QUICK_PARSE )
|
||||||
{
|
{
|
||||||
IASTInclusion inclusion = getASTFactory().createInclusion( fileNameArray, EMPTY_STRING_CHAR_ARRAY, local, startOffset, startingLineNumber, nameOffset, nameEndOffset, nameLine, endOffset, endLine, getCurrentFilename() );
|
IASTInclusion inclusion = getASTFactory().createInclusion( fileNameArray, EMPTY_STRING_CHAR_ARRAY, local, startOffset, startingLineNumber, nameOffset, nameEndOffset, nameLine, endOffset, endLine, getCurrentFilename() );
|
||||||
requestor.enterInclusion( inclusion );
|
pushCallback( new InclusionData( null, inclusion ) );
|
||||||
requestor.exitInclusion( inclusion );
|
pushCallback( inclusion );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1633,8 +1666,7 @@ public class Scanner2 implements IScanner, IScannerData {
|
||||||
? new ObjectStyleMacro(name, text)
|
? new ObjectStyleMacro(name, text)
|
||||||
: new FunctionStyleMacro(name, text, arglist) );
|
: 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