1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00
Fixed Bug 47234 : new ParserMode required for a better CModel
	Updated IASTCompletionNode to include a scope as well as a context.  
	Begun parser updates to support code assist & selection search.  

TESTS
	Added ContextualParseTest.java and some test cases.
This commit is contained in:
John Camelon 2003-12-09 16:39:15 +00:00
parent 673877b222
commit b363b30e27
16 changed files with 1297 additions and 882 deletions

View file

@ -1,3 +1,6 @@
2003-12-09 John Camelon
Added ContextualParseTest.java and some test cases.
2003-12-04 John Camelon
Removed some warnings.
Moved testBug39678() from ASTFailedTests to QuickParseASTTests.

View file

@ -0,0 +1,69 @@
/*
* Created on Dec 8, 2003
*
* To change the template for this generated file go to Window - Preferences -
* Java - Code Generation - Code and Comments
*/
package org.eclipse.cdt.core.parser.tests;
import java.io.StringReader;
import junit.framework.TestCase;
import org.eclipse.cdt.core.parser.IParser;
import org.eclipse.cdt.core.parser.IParserLogService;
import org.eclipse.cdt.core.parser.ISourceElementRequestor;
import org.eclipse.cdt.core.parser.NullSourceElementRequestor;
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.cdt.core.parser.ast.IASTCompletionNode;
import org.eclipse.cdt.internal.core.parser.ParserLogService;
/**
* @author jcamelon
*
* To change the template for this generated type comment go to Window -
* Preferences - Java - Code Generation - Code and Comments
*/
public class ContextualParseTest extends TestCase {
public ContextualParseTest(String name) {
super(name);
}
protected IASTCompletionNode parse(String code, int offset)
throws Exception {
ISourceElementRequestor requestor = new NullSourceElementRequestor();
IParserLogService log = new ParserLogService();
IParser parser = null;
parser =
ParserFactory.createParser(
ParserFactory.createScanner(
new StringReader(code),
"completion-test",
new ScannerInfo(),
ParserMode.CONTEXTUAL_PARSE,
ParserLanguage.CPP,
requestor,
log),
requestor,
ParserMode.CONTEXTUAL_PARSE,
ParserLanguage.CPP,
log);
return parser.parse( offset );
}
public void testBaseCase() throws Exception
{
IASTCompletionNode node = parse( "class ABC { }; AB\n\n", 17);
assertNotNull( node );
assertNotNull( node.getCompletionPrefix() );
assertEquals( node.getCompletionPrefix(), "AB");
}
}

View file

@ -31,6 +31,7 @@ public class ParserTestSuite extends TestCase {
suite.addTestSuite(QuickParseASTTests.class);
suite.addTestSuite(ParserSymbolTableTest.class);
suite.addTestSuite(CModelElementsTests.class);
// suite.addTestSuite(ContextualParseTest.class);
// suite.addTestSuite(MacroTests.class);
suite.addTestSuite( PreprocessorTest.class );
suite.addTestSuite( PreprocessorConditionalTest.class );

View file

@ -0,0 +1,62 @@
/*
* Created on Dec 8, 2003
*
* To change the template for this generated file go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
package org.eclipse.cdt.core.parser;
import org.eclipse.cdt.core.parser.ast.IASTCompletionNode;
import org.eclipse.cdt.core.parser.ast.IASTNode;
import org.eclipse.cdt.core.parser.ast.IASTScope;
/**
* @author jcamelon
*
* To change the template for this generated type comment go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
public class CompletionNode implements IASTCompletionNode {
private final String prefix;
private final IASTNode context;
private final IASTScope scope;
private final CompletionKind kind;
public CompletionNode( CompletionKind kind, IASTScope scope, IASTNode context, String prefix )
{
this.kind = kind;
this.context = context;
this.scope = scope;
this.prefix = prefix;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTCompletionNode#getCompletionKind()
*/
public CompletionKind getCompletionKind() {
return kind;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTCompletionNode#getCompletionScope()
*/
public IASTScope getCompletionScope() {
return scope;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTCompletionNode#getCompletionContext()
*/
public IASTNode getCompletionContext() {
return context;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTCompletionNode#getCompletionPrefix()
*/
public String getCompletionPrefix() {
return prefix;
}
}

View file

@ -0,0 +1,117 @@
/*
* Created on Dec 8, 2003
*
* To change the template for this generated file go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
package org.eclipse.cdt.core.parser;
import org.eclipse.cdt.core.parser.ast.IASTCompletionNode;
import org.eclipse.cdt.core.parser.ast.IASTNode;
import org.eclipse.cdt.core.parser.ast.IASTScope;
import org.eclipse.cdt.core.parser.ast.IASTCompletionNode.CompletionKind;
import org.eclipse.cdt.internal.core.parser.Parser;
/**
* @author jcamelon
*
* To change the template for this generated type comment go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
public class ContextualParser extends Parser implements IParser {
private CompletionKind kind;
private IASTScope scope;
private IASTNode context;
/**
* @param scanner
* @param callback
* @param language
* @param log
*/
public ContextualParser(IScanner scanner, ISourceElementRequestor callback, ParserLanguage language, IParserLogService log) {
super(scanner, callback, language, log);
astFactory = ParserFactory.createASTFactory( ParserMode.COMPLETE_PARSE, language);
scanner.setASTFactory(astFactory);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.IParser#parse(int)
*/
public IASTCompletionNode parse(int offset) throws ParserNotImplementedException {
scanner.setOffsetBoundary(offset);
translationUnit();
return new CompletionNode( getCompletionKind(), getCompletionScope(), getCompletionContext(), getCompletionPrefix() );
}
/**
* @return
*/
private String getCompletionPrefix() {
return lastToken == null ? "" : lastToken.getImage();
}
/**
* @return
*/
private IASTNode getCompletionContext() {
return context;
}
/**
* @return
*/
private IASTScope getCompletionScope() {
return scope;
}
/**
* @return
*/
private IASTCompletionNode.CompletionKind getCompletionKind() {
return kind;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.IParser#parse(int, int)
*/
public IASTNode parse(int startingOffset, int endingOffset) throws ParserNotImplementedException {
scanner.setOffsetBoundary(endingOffset);
translationUnit();
return getCompletionContext();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.Parser#setCurrentScope(org.eclipse.cdt.core.parser.ast.IASTScope)
*/
protected void setCurrentScope(IASTScope scope) {
this.scope = scope;
}
protected void setCompletionContext( IASTNode node )
{
this.context = node;
}
protected void setCompletionKind( IASTCompletionNode.CompletionKind kind )
{
this.kind = kind;
}
protected void handleFunctionBody(IASTScope scope, boolean isInlineFunction) throws Backtrack, EndOfFile
{
if ( isInlineFunction )
skipOverCompoundStatement();
else
functionBody(scope);
}
protected void catchBlockCompoundStatement(IASTScope scope) throws Backtrack, EndOfFile
{
compoundStatement(scope, true);
}
}

View file

@ -37,7 +37,7 @@ public interface IParser {
* @param offset offset in the input file where code completion is being requested for
* @return an IASTCompletionConstruct that provides a mechanism for determining C/C++ code completion contributions
*/
public IASTCompletionNode parse( int offset );
public IASTCompletionNode parse( int offset )throws ParserNotImplementedException;
/**
*
@ -45,7 +45,7 @@ public interface IParser {
* @param endingOffset
* @return
*/
public IASTNode parse( int startingOffset, int endingOffset );
public IASTNode parse( int startingOffset, int endingOffset ) throws ParserNotImplementedException;
/**

View file

@ -13,6 +13,7 @@ package org.eclipse.cdt.core.parser;
import java.io.Reader;
import org.eclipse.cdt.core.parser.ast.IASTFactory;
import org.eclipse.cdt.internal.core.parser.*;
import org.eclipse.cdt.internal.core.parser.CompleteParser;
import org.eclipse.cdt.internal.core.parser.LineOffsetReconciler;
import org.eclipse.cdt.internal.core.parser.Preprocessor;
@ -46,6 +47,10 @@ public class ParserFactory {
ISourceElementRequestor ourCallback = (( callback == null) ? new NullSourceElementRequestor() : callback );
if( ourMode == ParserMode.COMPLETE_PARSE)
return new CompleteParser( scanner, ourCallback, language, logService );
else if( ourMode == ParserMode.STRUCTURAL_PARSE )
return new StructuralParser( scanner, ourCallback, language, logService );
else if( ourMode == ParserMode.CONTEXTUAL_PARSE )
return new ContextualParser( scanner, ourCallback, language, logService );
else
return new QuickParser( scanner, ourCallback, language, logService );
}

View file

@ -19,8 +19,14 @@ public class ParserMode extends Enum {
// follow inclusions, parse function/method bodies
public static final ParserMode COMPLETE_PARSE = new ParserMode( 1 );
// follow inclusions, do not parse function/method bodies
public static final ParserMode STRUCTURAL_PARSE = new ParserMode( 2 );
// do not follow inclusions, do not parse function/method bodies
public static final ParserMode QUICK_PARSE = new ParserMode( 2 );
public static final ParserMode QUICK_PARSE = new ParserMode( 3 );
// follow inclusions, parse function/method bodies, stop at particular offset
public static final ParserMode CONTEXTUAL_PARSE = new ParserMode( 4 );
protected ParserMode( int value )
{

View file

@ -0,0 +1,17 @@
/*
* Created on Dec 8, 2003
*
* To change the template for this generated file go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
package org.eclipse.cdt.core.parser;
/**
* @author jcamelon
*
* To change the template for this generated type comment go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
public class ParserNotImplementedException extends Exception {
}

View file

@ -49,7 +49,26 @@ public interface IASTCompletionNode {
}
public CompletionKind getCompletionKind();
/**
* @return kind of completion expected
*/
public CompletionKind getCompletionKind();
/**
* @return the scope the code completion is within
* should never be null
*/
public IASTScope getCompletionScope();
/**
* @return the context (inter-statement)
* e.g. LHS of postfix expression a->b, a.b or qualified name a::b is 'a'
* this can be null
*/
public IASTNode getCompletionContext();
/**
* @return the prefix
*/
public String getCompletionPrefix();
}

View file

@ -14,6 +14,9 @@ import org.eclipse.cdt.core.parser.ISourceElementRequestor;
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.ParserNotImplementedException;
import org.eclipse.cdt.core.parser.ast.IASTCompletionNode;
import org.eclipse.cdt.core.parser.ast.IASTNode;
import org.eclipse.cdt.core.parser.ast.IASTScope;
/**
@ -49,5 +52,19 @@ public class CompleteParser extends Parser {
{
compoundStatement(scope, true);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.IParser#parse(int)
*/
public IASTCompletionNode parse(int offset) throws ParserNotImplementedException {
throw new ParserNotImplementedException();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.IParser#parse(int, int)
*/
public IASTNode parse(int startingOffset, int endingOffset) throws ParserNotImplementedException {
throw new ParserNotImplementedException();
}
}

View file

@ -73,13 +73,13 @@ public abstract class Parser implements IParser
private static final List EMPTY_LIST = new ArrayList();
private static int DEFAULT_OFFSET = -1;
// sentinel initial value for offsets
private int firstErrorOffset = DEFAULT_OFFSET;
protected int firstErrorOffset = DEFAULT_OFFSET;
// offset where the first parse error occurred
// are we doing the high-level parse, or an in depth parse?
private boolean parsePassed = true; // did the parse pass?
private ParserLanguage language = ParserLanguage.CPP; // C or CPP
private ISourceElementRequestor requestor = null;
protected boolean parsePassed = true; // did the parse pass?
protected ParserLanguage language = ParserLanguage.CPP; // C or CPP
protected ISourceElementRequestor requestor = null;
// new callback mechanism
protected IASTFactory astFactory = null; // ast factory
/**
@ -143,7 +143,8 @@ public abstract class Parser implements IParser
+ (parsePassed ? "" : " - parse failure") );
return parsePassed;
}
/**
* This is the top-level entry point into the ANSI C++ grammar.
*
@ -703,6 +704,7 @@ public abstract class Parser implements IParser
IASTTemplate ownerTemplate)
throws Backtrack
{
setCurrentScope(scope);
switch (LT(1))
{
case IToken.t_asm :
@ -5095,17 +5097,23 @@ public abstract class Parser implements IParser
}
}
}
// the static instance we always use
private static Backtrack backtrack = new Backtrack();
// the static instance we always use
public static EndOfFile endOfFile = new EndOfFile();
// Token management
private IScanner scanner;
private IToken currToken, // current token we plan to consume next
protected IScanner scanner;
protected IToken currToken, // current token we plan to consume next
lastToken; // last token we consumed
private int highWaterOffset = 0;
protected void setCurrentScope( IASTScope scope )
{
}
/**
* Fetches a token from the scanner.
*
@ -5239,20 +5247,12 @@ public abstract class Parser implements IParser
{
return firstErrorOffset;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.IParser#parse(int)
*/
public IASTCompletionNode parse(int offset) {
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.IParser#parse(int, int)
*/
public IASTNode parse(int startingOffset, int endingOffset) {
// TODO Auto-generated method stub
return null;
}
protected void setCompletionContext( IASTNode node )
{
}
protected void setCompletionKind( IASTCompletionNode.CompletionKind kind )
{
}
}

View file

@ -14,6 +14,9 @@ import org.eclipse.cdt.core.parser.ISourceElementRequestor;
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.ParserNotImplementedException;
import org.eclipse.cdt.core.parser.ast.IASTCompletionNode;
import org.eclipse.cdt.core.parser.ast.IASTNode;
import org.eclipse.cdt.core.parser.ast.IASTScope;
/**
@ -47,4 +50,19 @@ public class QuickParser extends Parser {
skipOverCompoundStatement();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.IParser#parse(int)
*/
public IASTCompletionNode parse(int offset) throws ParserNotImplementedException {
throw new ParserNotImplementedException();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.IParser#parse(int, int)
*/
public IASTNode parse(int startingOffset, int endingOffset) throws ParserNotImplementedException {
throw new ParserNotImplementedException();
}
}

View file

@ -2351,7 +2351,7 @@ public class Scanner implements IScanner {
Object newDefinition, int beginningOffset )
throws ScannerException
{
if( mode == ParserMode.COMPLETE_PARSE && previousDefinition != null )
if( mode != ParserMode.QUICK_PARSE && previousDefinition != null )
{
if( newDefinition instanceof IMacroDescriptor )
{

View file

@ -0,0 +1,76 @@
/*
* Created on Dec 8, 2003
*
* To change the template for this generated file go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
package org.eclipse.cdt.internal.core.parser;
import org.eclipse.cdt.core.parser.Backtrack;
import org.eclipse.cdt.core.parser.EndOfFile;
import org.eclipse.cdt.core.parser.IParser;
import org.eclipse.cdt.core.parser.IParserLogService;
import org.eclipse.cdt.core.parser.IScanner;
import org.eclipse.cdt.core.parser.ISourceElementRequestor;
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.ParserNotImplementedException;
import org.eclipse.cdt.core.parser.ast.IASTCompletionNode;
import org.eclipse.cdt.core.parser.ast.IASTNode;
import org.eclipse.cdt.core.parser.ast.IASTScope;
/**
* @author jcamelon
*
* To change the template for this generated type comment go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
public class StructuralParser extends Parser implements IParser {
/**
* @param scanner
* @param ourCallback
* @param language
* @param logService
*/
public StructuralParser(IScanner scanner, ISourceElementRequestor ourCallback, ParserLanguage language, IParserLogService logService) {
super(scanner, ourCallback, language, logService);
astFactory = ParserFactory.createASTFactory( ParserMode.COMPLETE_PARSE, language);
scanner.setASTFactory(astFactory);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.Parser#handleFunctionBody(org.eclipse.cdt.core.parser.ast.IASTScope, boolean)
*/
protected void handleFunctionBody(
IASTScope scope,
boolean isInlineFunction)
throws Backtrack, EndOfFile {
skipOverCompoundStatement();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.Parser#catchBlockCompoundStatement(org.eclipse.cdt.core.parser.ast.IASTScope)
*/
protected void catchBlockCompoundStatement(IASTScope scope)
throws Backtrack, EndOfFile {
skipOverCompoundStatement();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.IParser#parse(int)
*/
public IASTCompletionNode parse(int offset) throws ParserNotImplementedException {
throw new ParserNotImplementedException();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.IParser#parse(int, int)
*/
public IASTNode parse(int startingOffset, int endingOffset) throws ParserNotImplementedException {
throw new ParserNotImplementedException();
}
}