1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-06 17:26:01 +02:00

Patch for Devin Steffler

Fixed 72611 [Parser] Timeout strategy does not affect scanner infinite loops
This commit is contained in:
John Camelon 2004-10-11 03:00:10 +00:00
parent 9d7f94cc12
commit 06b4f414c0
7 changed files with 488 additions and 272 deletions

View file

@ -14,300 +14,35 @@
*/
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.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
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.Parser;
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.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
/**
* @author aniefer
*/
public class CompleteParsePluginTest extends TestCase {
static NullProgressMonitor monitor;
static IWorkspace workspace;
static IProject project;
static FileManager fileManager;
{
if( CCorePlugin.getDefault() != null && CCorePlugin.getDefault().getCoreModel() != null){
(CCorePlugin.getDefault().getCoreModel().getIndexManager()).reset();
monitor = new NullProgressMonitor();
workspace = ResourcesPlugin.getWorkspace();
ICProject cPrj;
try {
cPrj = CProjectHelper.createCCProject("ParserTestProject", "bin"); //$NON-NLS-1$ //$NON-NLS-2$
project = cPrj.getProject();
project.setSessionProperty(IndexManager.activationKey,new Boolean(false));
} catch ( CoreException e ) {
/*boo*/
}
if (project == null)
fail("Unable to create project"); //$NON-NLS-1$
public class CompleteParsePluginTest extends FileBasePluginTest {
//Create file manager
fileManager = new FileManager();
}
}
public CompleteParsePluginTest()
{
super();
}
/**
* @param name
*/
public CompleteParsePluginTest(String name)
{
super(name);
super(name, CompleteParsePluginTest.class);
}
public static Test suite() {
TestSuite suite = new TestSuite( CompleteParsePluginTest.class );
suite.addTest( new CompleteParsePluginTest("cleanupProject") ); //$NON-NLS-1$
return suite;
}
public void cleanupProject() throws Exception {
try{
project.delete( true, false, monitor );
project = null;
} catch( Throwable e ){
/*boo*/
}
}
protected void tearDown() throws Exception {
if( project == null || !project.exists() )
return;
IResource [] members = project.members();
for( int i = 0; i < members.length; i++ ){
if( members[i].getName().equals( ".project" ) || members[i].getName().equals( ".cdtproject" ) ) //$NON-NLS-1$ //$NON-NLS-2$
continue;
try{
members[i].delete( false, monitor );
} catch( Throwable e ){
/*boo*/
}
}
}
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 );
InputStream stream = code.getContents();
IParser parser = ParserFactory.createParser(
ParserFactory.createScanner( new CodeReader( code.getLocation().toOSString(), stream ), new ScannerInfo(), //$NON-NLS-1$
ParserMode.COMPLETE_PARSE, language, callback, new NullLogService(), null ), callback, ParserMode.COMPLETE_PARSE, language, null
);
stream.close();
boolean parseResult = parser.parse();
// throw exception if there are generated IProblems
if( !parseResult ) throw new ParserException( "FAILURE"); //$NON-NLS-1$
if( parseResult )
{
assertTrue( ((Parser)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$

View file

@ -0,0 +1,336 @@
/*******************************************************************************
* 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 Sept 28, 2004
*/
package org.eclipse.cdt.core.parser.tests;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
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.Parser;
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.CTestPlugin;
import org.eclipse.cdt.testplugin.FileManager;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.dialogs.SaveAsDialog;
/**
* @author dsteffle
*/
public class FileBasePluginTest extends TestCase {
static NullProgressMonitor monitor;
static IWorkspace workspace;
static IProject project;
static FileManager fileManager;
static int numProjects = 0;
static Class className;
static ICProject cPrj;
private void initialize(Class aClassName){
if( CCorePlugin.getDefault() != null && CCorePlugin.getDefault().getCoreModel() != null){
(CCorePlugin.getDefault().getCoreModel().getIndexManager()).reset();
monitor = new NullProgressMonitor();
workspace = ResourcesPlugin.getWorkspace();
try {
cPrj = CProjectHelper.createCCProject("ParserTestProject", "bin"); //$NON-NLS-1$ //$NON-NLS-2$
project = cPrj.getProject();
project.setSessionProperty(IndexManager.activationKey,new Boolean(false));
// ugly
if (className == null || !className.equals(aClassName)) {
className = aClassName;
numProjects++;
}
} catch ( CoreException e ) {
/*boo*/
}
if (project == null)
throw new NullPointerException("Unable to create project"); //$NON-NLS-1$
//Create file manager
fileManager = new FileManager();
}
}
public FileBasePluginTest(String name, Class className)
{
super(name);
initialize(className);
}
public void cleanupProject() throws Exception {
numProjects--;
try{
if (numProjects == 0) {
project.delete( true, false, monitor );
project = null;
}
} catch( Throwable e ){
/*boo*/
}
}
protected void tearDown() throws Exception {
if( project == null || !project.exists() )
return;
IResource [] members = project.members();
for( int i = 0; i < members.length; i++ ){
if( members[i].getName().equals( ".project" ) || members[i].getName().equals( ".cdtproject" ) ) //$NON-NLS-1$ //$NON-NLS-2$
continue;
try{
members[i].delete( false, monitor );
} catch( Throwable e ){
/*boo*/
}
}
}
// below can be used to work with large files (too large for memory)
// protected IFile importFile(String fileName) throws Exception {
// IFile file = cPrj.getProject().getFile(fileName);
// if (!file.exists()) {
// try{
// FileInputStream fileIn = new FileInputStream(
// CTestPlugin.getDefault().getFileInPlugin(new Path("resources/parser/" + fileName)));
// file.create(fileIn,false, monitor);
// } catch (CoreException e) {
// e.printStackTrace();
// } catch (FileNotFoundException e) {
// e.printStackTrace();
// }
// }
//
// return file;
// }
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 );
InputStream stream = code.getContents();
IParser parser = ParserFactory.createParser(
ParserFactory.createScanner( new CodeReader( code.getLocation().toOSString(), stream ), new ScannerInfo(), //$NON-NLS-1$
ParserMode.COMPLETE_PARSE, language, callback, new NullLogService(), null ), callback, ParserMode.COMPLETE_PARSE, language, null
);
stream.close();
boolean parseResult = parser.parse();
// throw exception if there are generated IProblems
if( !parseResult ) throw new ParserException( "FAILURE"); //$NON-NLS-1$
if( parseResult )
{
assertTrue( ((Parser)parser).validateCaches());
}
return callback.getCompilationUnit();
}
}

View file

@ -48,6 +48,7 @@ public class ParserTestSuite extends TestCase {
suite.addTestSuite( StructuralParseTest.class );
suite.addTestSuite( ObjectMapTest.class );
suite.addTest( CompleteParsePluginTest.suite() );
suite.addTest( ScannerParserLoopTest.suite() );
suite.addTest( GCCParserExtensionTestSuite.suite() );
return suite;
}

View file

@ -0,0 +1,130 @@
/*******************************************************************************
* 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 Sept 30, 2004
*/
package org.eclipse.cdt.core.parser.tests;
import java.io.StringWriter;
import java.io.Writer;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.IParser;
import org.eclipse.cdt.core.parser.ISourceElementRequestor;
import org.eclipse.cdt.core.parser.NullLogService;
import org.eclipse.cdt.core.parser.NullSourceElementRequestor;
import org.eclipse.cdt.core.parser.ParseError;
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.ScannerInfo;
import org.eclipse.core.resources.IFile;
import org.eclipse.cdt.core.parser.ast.IASTMacro;
import org.eclipse.cdt.core.parser.ast.IASTVariable;
/**
* @author dsteffle
*/
public class ScannerParserLoopTest extends FileBasePluginTest {
private static final int NUMBER_ITERATIONS = 30000;
public ScannerParserLoopTest(String name) {
super(name, ScannerParserLoopTest.class);
}
public static Test suite() {
TestSuite suite = new TestSuite(ScannerParserLoopTest.class);
suite.addTest(new ScannerParserLoopTest("cleanupProject")); //$NON-NLS-1$
return suite;
}
// test scanner cancel()
public void testBug72611A() throws Exception {
Writer writer = new StringWriter();
for (int i = 0; i < NUMBER_ITERATIONS; i++) {
writer.write("#define A");
writer.write(String.valueOf(i));
writer.write(" B");
writer.write(String.valueOf(i));
writer.write("\n");
writer.write("#define B");
writer.write(String.valueOf(i));
writer.write(" C");
writer.write(String.valueOf(i));
writer.write("\n");
writer.write("#define C");
writer.write(String.valueOf(i));
writer.write(" D");
writer.write(String.valueOf(i));
writer.write("\n");
}
runCancelTest(writer);
}
// test parser cancel()
public void testBug72611B() throws Exception {
Writer writer = new StringWriter();
for (int i = 0; i < NUMBER_ITERATIONS; i++) {
writer.write("int a");
writer.write(String.valueOf(i));
writer.write("; // comment\n");
}
runCancelTest(writer);
}
private void runCancelTest(Writer writer) throws Exception {
IFile file = importFile("code.cpp", writer.toString()); //$NON-NLS-1$
try {
TimeoutCallback callback = new TimeoutCallback();
IParser parser = ParserFactory.createParser(ParserFactory
.createScanner(new CodeReader(file.getRawLocation()
.toString()), new ScannerInfo(), //$NON-NLS-1$
ParserMode.COMPLETE_PARSE, ParserLanguage.CPP,
callback, new NullLogService(), null), callback,
ParserMode.COMPLETE_PARSE, ParserLanguage.CPP, null);
callback.setParser(parser);
parser.parse();
assertTrue(false); // fail if parse succeeds before being cancelled
} catch (ParseError pe) { // expected
assertEquals(pe.getErrorKind(),
ParseError.ParseErrorKind.TIMEOUT_OR_CANCELLED);
}
}
private static class TimeoutCallback extends NullSourceElementRequestor
implements ISourceElementRequestor {
private IParser parser;
private boolean timerStarted = false;
public void setParser(IParser parser) {
this.parser = parser;
}
public void acceptMacro(IASTMacro macro) {
parser.cancel();
}
public void acceptVariable(IASTVariable variable) {
parser.cancel();
}
}
}

View file

@ -36,5 +36,5 @@ public interface IScanner {
public int getCount();
public boolean isOnTopContext();
public CharArrayObjectMap getRealDefinitions();
public void cancel();
}

View file

@ -6275,6 +6275,7 @@ public class Parser implements IParserData, IParser
*/
public synchronized void cancel() {
isCancelled = true;
scanner.cancel();
}
/* (non-Javadoc)

View file

@ -31,6 +31,7 @@ import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.core.parser.KeywordSetKey;
import org.eclipse.cdt.core.parser.Keywords;
import org.eclipse.cdt.core.parser.OffsetLimitReachedException;
import org.eclipse.cdt.core.parser.ParseError;
import org.eclipse.cdt.core.parser.ParserFactory;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.ParserMode;
@ -380,8 +381,13 @@ public class Scanner2 implements IScanner, IScannerData {
private static final String EMPTY_STRING = ""; //$NON-NLS-1$
private static final char[] EMPTY_STRING_CHAR_ARRAY = new char[0];
private boolean isCancelled = false;
public synchronized void cancel() {
isCancelled = true;
int index = bufferStackPos < 0 ? 0 : bufferStackPos;
bufferPos[index] = bufferLimit[index];
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.IScanner#nextToken()
@ -397,6 +403,8 @@ public class Scanner2 implements IScanner, IScannerData {
{
if( e instanceof OffsetLimitReachedException )
throw (OffsetLimitReachedException) e;
if( e instanceof ArrayIndexOutOfBoundsException && isCancelled )
throw new ParseError( ParseError.ParseErrorKind.TIMEOUT_OR_CANCELLED);
exception = true;
errorHandle();
@ -413,6 +421,9 @@ public class Scanner2 implements IScanner, IScannerData {
if (finished)
{
if (isCancelled == true)
throw new ParseError(ParseError.ParseErrorKind.TIMEOUT_OR_CANCELLED);
if( offsetBoundary == -1 )
throw EOF;
throwOLRE();
@ -491,7 +502,9 @@ public class Scanner2 implements IScanner, IScannerData {
++count;
contextLoop:
while (bufferStackPos >= 0) {
if (isCancelled == true)
throw new ParseError(ParseError.ParseErrorKind.TIMEOUT_OR_CANCELLED);
// Find the first thing we would care about
skipOverWhiteSpace();