1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-20 15:35:24 +02:00
Fixed bug 48909 - Wrong completion node after a . or an ->
	Fixed bug 49702 - Wrong completion kind sent in const/dest and code blocks
	Added new CompletionKind - STATEMENT_START to indicate the beginning of a statement line.  

TESTS
	Updated ContextualParseTest to accommodate bugfixes 48909 & 49702.  

UI
	Updated CompletionEngine to handle IASTCompletionKind.CompletionKind.STATEMENT_START
This commit is contained in:
John Camelon 2004-01-13 17:07:02 +00:00
parent cfa54903d5
commit 2c18a23f89
10 changed files with 524 additions and 166 deletions

View file

@ -1,3 +1,6 @@
2004-01-13 John Camelon
Updated ContextualParseTest to accommodate bugfixes 48909 & 49702.
2004-01-08 Andrew Niefer 2004-01-08 Andrew Niefer
Added CompleteParseASTTest.testBug43110_XRef Added CompleteParseASTTest.testBug43110_XRef
Added ParserSymbolTableTest.testBug43110_Ellipses Added ParserSymbolTableTest.testBug43110_Ellipses

View file

@ -8,6 +8,7 @@ package org.eclipse.cdt.core.parser.tests;
import java.io.StringReader; import java.io.StringReader;
import java.io.StringWriter; import java.io.StringWriter;
import java.io.Writer;
import java.util.Iterator; import java.util.Iterator;
import org.eclipse.cdt.core.parser.IParser; import org.eclipse.cdt.core.parser.IParser;
@ -25,6 +26,7 @@ import org.eclipse.cdt.core.parser.ast.IASTMethod;
import org.eclipse.cdt.core.parser.ast.IASTNode; import org.eclipse.cdt.core.parser.ast.IASTNode;
import org.eclipse.cdt.core.parser.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.parser.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTVariable; import org.eclipse.cdt.core.parser.ast.IASTVariable;
import org.eclipse.cdt.core.parser.ast.IASTNode.LookupKind;
import org.eclipse.cdt.core.parser.ast.IASTNode.LookupResult; import org.eclipse.cdt.core.parser.ast.IASTNode.LookupResult;
import org.eclipse.cdt.internal.core.parser.ParserLogService; import org.eclipse.cdt.internal.core.parser.ParserLogService;
@ -126,30 +128,39 @@ public class ContextualParseTest extends CompleteParseBaseTest {
writer.write( "} " ); writer.write( "} " );
String code = writer.toString(); String code = writer.toString();
int index = code.indexOf( " a " );
IASTCompletionNode node = parse( code, index + 2 ); for( int i = 0; i < 2; ++i )
assertNotNull( node ); {
int index = ( i == 0 ? code.indexOf( " a " ) + 2 : code.indexOf( " a ") + 1 );
String prefix = node.getCompletionPrefix();
assertNotNull( prefix ); IASTCompletionNode node = parse( code, index );
assertTrue( node.getCompletionScope() instanceof IASTFunction ); assertNotNull( node );
assertEquals( prefix, "a" );
assertEquals( node.getCompletionKind(), IASTCompletionNode.CompletionKind.SINGLE_NAME_REFERENCE ); String prefix = node.getCompletionPrefix();
assertNotNull( prefix );
IASTNode.LookupKind[] kinds = new IASTNode.LookupKind[1]; assertTrue( node.getCompletionScope() instanceof IASTFunction );
kinds[0] = IASTNode.LookupKind.ALL; assertEquals( prefix, i == 0 ? "a" :"" );
LookupResult result = node.getCompletionScope().lookup( prefix, kinds, node.getCompletionContext() ); assertEquals( node.getCompletionKind(), IASTCompletionNode.CompletionKind.STATEMENT_START );
assertEquals( result.getPrefix(), prefix );
IASTNode.LookupKind[] kinds = new IASTNode.LookupKind[1];
Iterator iter = result.getNodes(); kinds[0] = IASTNode.LookupKind.ALL;
LookupResult result = node.getCompletionScope().lookup( prefix, kinds, node.getCompletionContext() );
IASTVariable anotherVar = (IASTVariable) iter.next(); assertEquals( result.getPrefix(), prefix );
IASTVariable aVar = (IASTVariable) iter.next();
Iterator iter = result.getNodes();
assertFalse( iter.hasNext() );
assertEquals( anotherVar.getName(), "anotherVar" ); IASTVariable anotherVar = (IASTVariable) iter.next();
assertEquals( aVar.getName(), "aVar" ); if( i != 0 )
{
IASTFunction foo = (IASTFunction) iter.next();
assertEquals( foo.getName(), "foo");
}
IASTVariable aVar = (IASTVariable) iter.next();
assertFalse( iter.hasNext() );
assertEquals( anotherVar.getName(), "anotherVar" );
assertEquals( aVar.getName(), "aVar" );
}
} }
public void testCompletionLookup_Qualified() throws Exception public void testCompletionLookup_Qualified() throws Exception
@ -206,6 +217,63 @@ public class ContextualParseTest extends CompleteParseBaseTest {
assertEquals( aField.getName(), "aField" ); assertEquals( aField.getName(), "aField" );
} }
public void testMemberCompletion_Arrow() throws Exception
{
StringWriter writer = new StringWriter();
writer.write( "class A {" );
writer.write( " public: void aPublicBaseMethod();" );
writer.write( " private: void aPrivateBaseMethod();" );
writer.write( "};" );
writer.write( "class B : public A {" );
writer.write( " public: void aMethod();" );
writer.write( "};" );
writer.write( "void foo(){" );
writer.write( " B * b = new B();" );
writer.write( " b-> \n" );
String code = writer.toString();
int index = code.indexOf( "b->" );
IASTCompletionNode node = parse( code, index + 3 );
assertNotNull(node);
assertEquals( node.getCompletionPrefix(), "" );
assertEquals(node.getCompletionKind(), IASTCompletionNode.CompletionKind.MEMBER_REFERENCE);
assertTrue(node.getCompletionScope() instanceof IASTFunction );
assertEquals( ((IASTFunction)node.getCompletionScope()).getName(), "foo" );
assertTrue(node.getCompletionContext() instanceof IASTClassSpecifier );
assertEquals( ((IASTClassSpecifier)node.getCompletionContext()).getName(), "B" );
}
public void testMemberCompletion_Dot() throws Exception
{
StringWriter writer = new StringWriter();
writer.write( "class A {" );
writer.write( " public: void aPublicBaseMethod();" );
writer.write( " private: void aPrivateBaseMethod();" );
writer.write( "};" );
writer.write( "class B : public A {" );
writer.write( " public: void aMethod();" );
writer.write( "};" );
writer.write( "void foo(){" );
writer.write( " B b;" );
writer.write( " b. \n" );
String code = writer.toString();
int index = code.indexOf( "b." );
IASTCompletionNode node = parse( code, index + 2 );
assertNotNull(node);
assertEquals( node.getCompletionPrefix(), "" );
assertEquals(node.getCompletionKind(), IASTCompletionNode.CompletionKind.MEMBER_REFERENCE);
assertTrue(node.getCompletionScope() instanceof IASTFunction );
assertEquals( ((IASTFunction)node.getCompletionScope()).getName(), "foo" );
assertTrue(node.getCompletionContext() instanceof IASTClassSpecifier );
assertEquals( ((IASTClassSpecifier)node.getCompletionContext()).getName(), "B" );
}
public void testCompletionLookup_Pointer() throws Exception{ public void testCompletionLookup_Pointer() throws Exception{
StringWriter writer = new StringWriter(); StringWriter writer = new StringWriter();
writer.write( "class A {" ); writer.write( "class A {" );
@ -219,34 +287,40 @@ public class ContextualParseTest extends CompleteParseBaseTest {
writer.write( " B * b = new B();" ); writer.write( " B * b = new B();" );
writer.write( " b->a \n" ); writer.write( " b->a \n" );
String code = writer.toString(); for( int i = 0; i < 2; ++i )
int index = code.indexOf( "b->a" ); {
String code = writer.toString();
IASTCompletionNode node = parse( code, index + 4 );
int index;
assertNotNull( node );
index = (i == 0 )? (code.indexOf( "b->a" )+4) :(code.indexOf( "b->") + 3);
String prefix = node.getCompletionPrefix();
assertEquals( prefix, "a" ); IASTCompletionNode node = parse( code, index);
assertTrue( node.getCompletionScope() instanceof IASTFunction ); assertNotNull( node );
assertEquals( node.getCompletionKind(), IASTCompletionNode.CompletionKind.MEMBER_REFERENCE ); String prefix = node.getCompletionPrefix();
assertNotNull( node.getCompletionContext() );
assertTrue( node.getCompletionContext() instanceof IASTClassSpecifier ); assertEquals( prefix, ( i == 0 ) ? "a" :"");
IASTNode.LookupKind[] kinds = new IASTNode.LookupKind[1]; assertTrue( node.getCompletionScope() instanceof IASTFunction );
kinds[0] = IASTNode.LookupKind.METHODS; assertEquals( node.getCompletionKind(), IASTCompletionNode.CompletionKind.MEMBER_REFERENCE );
LookupResult result = node.getCompletionScope().lookup( prefix, kinds, node.getCompletionContext() ); assertNotNull( node.getCompletionContext() );
assertEquals( result.getPrefix(), prefix ); assertTrue( node.getCompletionContext() instanceof IASTClassSpecifier );
Iterator iter = result.getNodes(); IASTNode.LookupKind[] kinds = new IASTNode.LookupKind[1];
IASTMethod method = (IASTMethod) iter.next(); kinds[0] = IASTNode.LookupKind.METHODS;
IASTMethod baseMethod = (IASTMethod) iter.next(); LookupResult result = node.getCompletionScope().lookup( prefix, kinds, node.getCompletionContext() );
assertEquals( result.getPrefix(), prefix );
assertFalse( iter.hasNext() );
Iterator iter = result.getNodes();
assertEquals( method.getName(), "aMethod" ); IASTMethod method = (IASTMethod) iter.next();
assertEquals( baseMethod.getName(), "aPublicBaseMethod" ); IASTMethod baseMethod = (IASTMethod) iter.next();
assertFalse( iter.hasNext() );
assertEquals( method.getName(), "aMethod" );
assertEquals( baseMethod.getName(), "aPublicBaseMethod" );
}
} }
public void testCompletionLookup_FriendClass_1() throws Exception{ public void testCompletionLookup_FriendClass_1() throws Exception{
@ -334,6 +408,7 @@ public class ContextualParseTest extends CompleteParseBaseTest {
assertEquals( method.getName(), "aPrivateMethod" ); assertEquals( method.getName(), "aPrivateMethod" );
} }
public void testCompletionLookup_ParametersAsLocalVariables() throws Exception{ public void testCompletionLookup_ParametersAsLocalVariables() throws Exception{
StringWriter writer = new StringWriter(); StringWriter writer = new StringWriter();
writer.write( "int foo( int aParameter ){" ); writer.write( "int foo( int aParameter ){" );
@ -353,7 +428,7 @@ public class ContextualParseTest extends CompleteParseBaseTest {
assertEquals( prefix, "a" ); assertEquals( prefix, "a" );
assertTrue( node.getCompletionScope() instanceof IASTCodeScope ); assertTrue( node.getCompletionScope() instanceof IASTCodeScope );
assertEquals( node.getCompletionKind(), IASTCompletionNode.CompletionKind.SINGLE_NAME_REFERENCE ); assertEquals( node.getCompletionKind(), IASTCompletionNode.CompletionKind.STATEMENT_START );
assertNull( node.getCompletionContext() ); assertNull( node.getCompletionContext() );
LookupResult result = node.getCompletionScope().lookup( prefix, new IASTNode.LookupKind [] { IASTNode.LookupKind.LOCAL_VARIABLES }, node.getCompletionContext() ); LookupResult result = node.getCompletionScope().lookup( prefix, new IASTNode.LookupKind [] { IASTNode.LookupKind.LOCAL_VARIABLES }, node.getCompletionContext() );
@ -421,4 +496,70 @@ public class ContextualParseTest extends CompleteParseBaseTest {
assertFalse( iter.hasNext() ); assertFalse( iter.hasNext() );
assertEquals( method.getName(), "aMethod" ); assertEquals( method.getName(), "aMethod" );
} }
public void testCompletionInConstructor() throws Exception
{
Writer writer = new StringWriter();
writer.write("class SimpleTest{");
writer.write(" public:");
writer.write("SimpleTest();");
writer.write("~SimpleTest();");
writer.write("int a, b, c, aa, bb, cc, abc;");
writer.write("};");
writer.write("SimpleTest::~SimpleTest()");
writer.write("{}");
writer.write("SimpleTest::SimpleTest()");
writer.write("{");
writer.write("/**/a");
writer.write("}");
IASTCompletionNode node = parse( writer.toString(), writer.toString().indexOf("/**/a") + 5 );
assertNotNull(node);
assertEquals(node.getCompletionPrefix(), "a");
assertTrue(node.getCompletionScope() instanceof IASTMethod);
IASTMethod inquestion = (IASTMethod)node.getCompletionScope();
assertEquals( inquestion.getName(), "SimpleTest");
assertTrue(inquestion.isConstructor());
assertEquals(node.getCompletionKind(), IASTCompletionNode.CompletionKind.STATEMENT_START );
assertNull(node.getCompletionContext());
LookupKind[] kinds = new LookupKind[ 1 ];
kinds[0] = LookupKind.FIELDS;
LookupResult result = inquestion.lookup( "a", kinds, null );
assertEquals(result.getResultsSize(), 3 );
}
public void testCompletionInDestructor() throws Exception
{
Writer writer = new StringWriter();
writer.write("class SimpleTest{");
writer.write(" public:");
writer.write("SimpleTest();");
writer.write("~SimpleTest();");
writer.write("int a, b, c, aa, bb, cc, abc;");
writer.write("};");
writer.write("SimpleTest::SimpleTest()");
writer.write("{}");
writer.write("SimpleTest::~SimpleTest()");
writer.write("{");
writer.write("/**/a");
writer.write("}");
IASTCompletionNode node = parse( writer.toString(), writer.toString().indexOf("/**/a") + 5 );
assertNotNull(node);
assertEquals(node.getCompletionPrefix(), "a");
assertTrue(node.getCompletionScope() instanceof IASTMethod);
IASTMethod inquestion = (IASTMethod)node.getCompletionScope();
assertEquals( inquestion.getName(), "~SimpleTest");
assertTrue(inquestion.isDestructor());
assertEquals(node.getCompletionKind(), IASTCompletionNode.CompletionKind.STATEMENT_START );
assertNull(node.getCompletionContext());
LookupKind[] kinds = new LookupKind[ 1 ];
kinds[0] = LookupKind.FIELDS;
LookupResult result = inquestion.lookup( "a", kinds, null );
assertEquals(result.getResultsSize(), 3 );
}
} }

View file

@ -1,3 +1,9 @@
2004-01-12 John Camelon
Fixed bug 48909 - Wrong completion node after a . or an ->
Fixed bug 49702 - Wrong completion kind sent in const/dest and code blocks
Added new CompletionKind - STATEMENT_START to indicate the beginning of a statement line.
2004-01-08 Andrew Niefer 2004-01-08 Andrew Niefer
fixing bug 43110 - Parser support needed for functions with ellipses fixing bug 43110 - Parser support needed for functions with ellipses
Added IParameterizedSymbol.setHasVariableArgs() & hasVariableArgs() Added IParameterizedSymbol.setHasVariableArgs() & hasVariableArgs()

View file

@ -24,6 +24,7 @@ public interface IASTCompletionNode {
{ {
// x.[ ] x->[ ] // x.[ ] x->[ ]
public static final CompletionKind MEMBER_REFERENCE = new CompletionKind( 0 ); public static final CompletionKind MEMBER_REFERENCE = new CompletionKind( 0 );
// x::[ ] // x::[ ]
public static final CompletionKind SCOPED_REFERENCE = new CompletionKind( 1 ); public static final CompletionKind SCOPED_REFERENCE = new CompletionKind( 1 );
@ -68,6 +69,9 @@ public interface IASTCompletionNode {
// any place where a type or variable name is expected to be introduced // any place where a type or variable name is expected to be introduced
public static final CompletionKind USER_SPECIFIED_NAME = new CompletionKind( 15 ); public static final CompletionKind USER_SPECIFIED_NAME = new CompletionKind( 15 );
// the beginning of a statement
public static final CompletionKind STATEMENT_START = new CompletionKind( 16 );
// error condition -- a place in the grammar where there is nothing to lookup // error condition -- a place in the grammar where there is nothing to lookup
public static final CompletionKind NO_SUCH_KIND = new CompletionKind( 200 ); public static final CompletionKind NO_SUCH_KIND = new CompletionKind( 200 );

View file

@ -60,6 +60,13 @@ public interface IASTNode {
public int getResultsSize(); public int getResultsSize();
} }
/**
* @param prefix
* @param kind
* @param context
* @return
* @throws LookupException
*/
public LookupResult lookup( String prefix, LookupKind[] kind, IASTNode context) throws LookupException; public LookupResult lookup( String prefix, LookupKind[] kind, IASTNode context) throws LookupException;
} }

View file

@ -42,6 +42,7 @@ public class ContextualParser extends Parser implements IParser {
protected IASTNode context; protected IASTNode context;
protected IToken finalToken; protected IToken finalToken;
private Set keywordSet; private Set keywordSet;
private int boundaryOffset;
/** /**
* @param scanner * @param scanner
@ -60,6 +61,7 @@ public class ContextualParser extends Parser implements IParser {
*/ */
public IASTCompletionNode parse(int offset) throws ParserNotImplementedException { public IASTCompletionNode parse(int offset) throws ParserNotImplementedException {
scanner.setOffsetBoundary(offset); scanner.setOffsetBoundary(offset);
boundaryOffset = offset;
translationUnit(); translationUnit();
return new ASTCompletionNode( getCompletionKind(), getCompletionScope(), getCompletionContext(), getCompletionPrefix(), reconcileKeywords( getKeywordSet(), getCompletionPrefix() ) ); return new ASTCompletionNode( getCompletionKind(), getCompletionScope(), getCompletionContext(), getCompletionPrefix(), reconcileKeywords( getKeywordSet(), getCompletionPrefix() ) );
} }
@ -164,15 +166,29 @@ public class ContextualParser extends Parser implements IParser {
* @see org.eclipse.cdt.internal.core.parser.Parser#handleOffsetLimitException() * @see org.eclipse.cdt.internal.core.parser.Parser#handleOffsetLimitException()
*/ */
protected void handleOffsetLimitException(OffsetLimitReachedException exception) throws EndOfFileException, OffsetLimitReachedException { protected void handleOffsetLimitException(OffsetLimitReachedException exception) throws EndOfFileException, OffsetLimitReachedException {
finalToken = exception.getFinalToken(); setCompletionToken( exception.getFinalToken() );
if( (finalToken!= null )&& (finalToken.getEndOffset() != boundaryOffset ))
setCompletionToken(null);
throw exception; throw exception;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.Parser#setCompletionKeywords(java.lang.String[]) * @see org.eclipse.cdt.internal.core.parser.Parser#setCompletionKeywords(java.lang.String[])
*/ */
protected void setCompletionKeywords(Set keywords) { protected void setCompletionKeywords(KeywordSets.Key key) {
this.keywordSet = keywords; this.keywordSet = KeywordSets.getKeywords( key, language );
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.Parser#setCompletionToken(org.eclipse.cdt.core.parser.IToken)
*/
protected void setCompletionToken(IToken token) {
finalToken = token;
}
protected IToken getCompletionToken()
{
return finalToken;
}
} }

View file

@ -29,6 +29,8 @@ public class KeywordSets {
{ {
public static final Key EMPTY = new Key( 0 ); public static final Key EMPTY = new Key( 0 );
public static final Key DECL_SPECIFIER_SEQUENCE = new Key( 1 ); public static final Key DECL_SPECIFIER_SEQUENCE = new Key( 1 );
public static final Key DECLARATION = new Key( 2 );
public static final Key STATEMENT = new Key(3);
/** /**
* @param enumValue * @param enumValue
*/ */
@ -44,6 +46,10 @@ public class KeywordSets {
return EMPTY; return EMPTY;
if( kind == Key.DECL_SPECIFIER_SEQUENCE ) if( kind == Key.DECL_SPECIFIER_SEQUENCE )
return (Set) DECL_SPECIFIER_SEQUENCE.get( language ); return (Set) DECL_SPECIFIER_SEQUENCE.get( language );
if( kind == Key.DECLARATION )
return (Set) DECLARATION.get( language );
if( kind == Key.STATEMENT )
return (Set) STATEMENT.get( language );
//TODO finish this //TODO finish this
return null; return null;
@ -109,4 +115,53 @@ public class KeywordSets {
DECL_SPECIFIER_SEQUENCE.put( ParserLanguage.C, DECL_SPECIFIER_SEQUENCE_C ); DECL_SPECIFIER_SEQUENCE.put( ParserLanguage.C, DECL_SPECIFIER_SEQUENCE_C );
} }
private static final Set DECLARATION_CPP;
static
{
DECLARATION_CPP = new TreeSet();
DECLARATION_CPP.addAll( DECL_SPECIFIER_SEQUENCE_CPP );
DECLARATION_CPP.add( Keywords.ASM );
// more to come
}
private static final Set DECLARATION_C;
static
{
DECLARATION_C = new TreeSet();
DECLARATION_C.addAll(DECL_SPECIFIER_SEQUENCE_C );
DECLARATION_C.add(Keywords.ASM );
// more to come
}
private static final Hashtable DECLARATION;
static
{
DECLARATION = new Hashtable();
DECLARATION.put( ParserLanguage.CPP, DECLARATION_CPP );
DECLARATION.put( ParserLanguage.C, DECLARATION_C );
}
private static final Set STATEMENT_C;
static
{
STATEMENT_C= new TreeSet();
STATEMENT_C.addAll( DECLARATION_C );
STATEMENT_C.add( Keywords.FOR );
// more to come
}
private static final Set STATEMENT_CPP;
static
{
STATEMENT_CPP = new TreeSet( STATEMENT_C );
STATEMENT_CPP.add( Keywords.TRY );
}
private static final Hashtable STATEMENT;
static
{
STATEMENT = new Hashtable();
STATEMENT.put( ParserLanguage.CPP, STATEMENT_CPP);
STATEMENT.put( ParserLanguage.C, STATEMENT_C );
}
} }

View file

@ -12,7 +12,6 @@ package org.eclipse.cdt.internal.core.parser;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.Stack; import java.util.Stack;
import org.eclipse.cdt.core.parser.BacktrackException; import org.eclipse.cdt.core.parser.BacktrackException;
@ -48,7 +47,6 @@ import org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition;
import org.eclipse.cdt.core.parser.ast.IASTNode; import org.eclipse.cdt.core.parser.ast.IASTNode;
import org.eclipse.cdt.core.parser.ast.IASTOffsetableElement; import org.eclipse.cdt.core.parser.ast.IASTOffsetableElement;
import org.eclipse.cdt.core.parser.ast.IASTScope; import org.eclipse.cdt.core.parser.ast.IASTScope;
import org.eclipse.cdt.core.parser.ast.IASTScopedElement;
import org.eclipse.cdt.core.parser.ast.IASTSimpleTypeSpecifier; import org.eclipse.cdt.core.parser.ast.IASTSimpleTypeSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTTemplate; import org.eclipse.cdt.core.parser.ast.IASTTemplate;
import org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration; import org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration;
@ -62,6 +60,7 @@ import org.eclipse.cdt.core.parser.ast.IASTUsingDirective;
import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier.ClassNameType; import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier.ClassNameType;
import org.eclipse.cdt.core.parser.ast.IASTCompletionNode.CompletionKind; import org.eclipse.cdt.core.parser.ast.IASTCompletionNode.CompletionKind;
import org.eclipse.cdt.core.parser.ast.IASTExpression.Kind; import org.eclipse.cdt.core.parser.ast.IASTExpression.Kind;
import org.eclipse.cdt.internal.core.parser.KeywordSets.Key;
/** /**
* This is our first implementation of the IParser interface, serving as a parser for * This is our first implementation of the IParser interface, serving as a parser for
@ -708,10 +707,12 @@ public abstract class Parser implements IParser
throws EndOfFileException, BacktrackException throws EndOfFileException, BacktrackException
{ {
setCurrentScope(scope); setCurrentScope(scope);
setCompletionKeywords( Key.DECLARATION );
switch (LT(1)) switch (LT(1))
{ {
case IToken.t_asm : case IToken.t_asm :
IToken first = consume(IToken.t_asm); IToken first = consume(IToken.t_asm);
setCompletionKind( CompletionKind.NO_SUCH_KIND );
consume(IToken.tLPAREN); consume(IToken.tLPAREN);
String assembly = consume(IToken.tSTRING).getImage(); String assembly = consume(IToken.tSTRING).getImage();
consume(IToken.tRPAREN); consume(IToken.tRPAREN);
@ -753,10 +754,9 @@ public abstract class Parser implements IParser
default : default :
simpleDeclarationStrategyUnion(scope, ownerTemplate); simpleDeclarationStrategyUnion(scope, ownerTemplate);
} }
if( scope instanceof IASTScopedElement ) setCurrentScope(scope);
setCurrentScope( ((IASTScopedElement)scope).getOwnerScope() ); setCompletionKeywords( Key.DECLARATION );
else
setCurrentScope( null );
} }
protected void simpleDeclarationStrategyUnion( protected void simpleDeclarationStrategyUnion(
IASTScope scope, IASTScope scope,
@ -919,8 +919,7 @@ public abstract class Parser implements IParser
* - work in functionTryBlock * - work in functionTryBlock
* *
* @param container IParserCallback object which serves as the owner scope for this declaration. * @param container IParserCallback object which serves as the owner scope for this declaration.
* @param tryConstructor true == take strategy1 (constructor ) : false == take strategy 2 ( pointer to function) * @param tryConstructor true == take strategy1 (constructor ) : false == take strategy 2 ( pointer to function)
* @param forKR Is this for K&R-style parameter declaration (true) or simple declaration (false)
* @throws BacktrackException request a backtrack * @throws BacktrackException request a backtrack
*/ */
protected void simpleDeclaration( protected void simpleDeclaration(
@ -933,8 +932,8 @@ public abstract class Parser implements IParser
DeclarationWrapper sdw = DeclarationWrapper sdw =
new DeclarationWrapper(scope, firstToken.getOffset(), ownerTemplate); new DeclarationWrapper(scope, firstToken.getOffset(), ownerTemplate);
setCompletionKeywords( KeywordSets.getKeywords( KeywordSets.Key.DECL_SPECIFIER_SEQUENCE, language ) ); setCompletionKeywords( Key.DECL_SPECIFIER_SEQUENCE );
declSpecifierSeq(false, strategy == SimpleDeclarationStrategy.TRY_CONSTRUCTOR, sdw ); declSpecifierSeq(sdw, false, strategy == SimpleDeclarationStrategy.TRY_CONSTRUCTOR );
if (sdw.getTypeSpecifier() == null && sdw.getSimpleType() != IASTSimpleTypeSpecifier.Type.UNSPECIFIED ) if (sdw.getTypeSpecifier() == null && sdw.getSimpleType() != IASTSimpleTypeSpecifier.Type.UNSPECIFIED )
try try
{ {
@ -1162,7 +1161,7 @@ public abstract class Parser implements IParser
DeclarationWrapper sdw = DeclarationWrapper sdw =
new DeclarationWrapper(scope, current.getOffset(), null); new DeclarationWrapper(scope, current.getOffset(), null);
declSpecifierSeq(true, false, sdw); declSpecifierSeq(sdw, true, false);
if (sdw.getTypeSpecifier() == null if (sdw.getTypeSpecifier() == null
&& sdw.getSimpleType() && sdw.getSimpleType()
!= IASTSimpleTypeSpecifier.Type.UNSPECIFIED) != IASTSimpleTypeSpecifier.Type.UNSPECIFIED)
@ -1357,9 +1356,9 @@ public abstract class Parser implements IParser
* @throws BacktrackException request a backtrack * @throws BacktrackException request a backtrack
*/ */
protected void declSpecifierSeq( protected void declSpecifierSeq(
DeclarationWrapper sdw,
boolean parm, boolean parm,
boolean tryConstructor, boolean tryConstructor )
DeclarationWrapper sdw )
throws BacktrackException, EndOfFileException throws BacktrackException, EndOfFileException
{ {
Flags flags = new Flags(parm, tryConstructor); Flags flags = new Flags(parm, tryConstructor);
@ -1783,47 +1782,62 @@ public abstract class Parser implements IParser
IToken last = null; IToken last = null;
IToken mark = mark(); IToken mark = mark();
if (LT(1) == IToken.tCOLONCOLON) try
last = consume( IToken.tCOLONCOLON ); {
// TODO - whacky way to deal with destructors, please revisit if (LT(1) == IToken.tCOLONCOLON)
if (LT(1) == IToken.tCOMPL) last = consume( IToken.tCOLONCOLON );
consume(); // TODO - whacky way to deal with destructors, please revisit
switch (LT(1)) if (LT(1) == IToken.tCOMPL)
{ consume();
case IToken.tIDENTIFIER : switch (LT(1))
last = consume(IToken.tIDENTIFIER); {
IToken secondMark = mark(); case IToken.tIDENTIFIER :
try last = consume(IToken.tIDENTIFIER);
{ IToken secondMark = null;
last = consumeTemplateParameters(last); try
} catch( BacktrackException bt ) {
{ secondMark = mark();
backup( secondMark ); }
} catch( OffsetLimitReachedException olre )
break; {
default : return new TokenDuple(last, last);
backup(mark); }
throw backtrack; try
{
last = consumeTemplateParameters(last);
} catch( BacktrackException bt )
{
backup( secondMark );
}
break;
default :
backup(mark);
throw backtrack;
}
while (LT(1) == IToken.tCOLONCOLON)
{
last = consume();
if (LT(1) == IToken.t_template)
consume();
if (LT(1) == IToken.tCOMPL)
consume();
switch (LT(1))
{
case IToken.t_operator :
backup(mark);
throw backtrack;
case IToken.tIDENTIFIER :
last = consume();
last = consumeTemplateParameters(last);
}
}
return new TokenDuple(first, last);
} catch( OffsetLimitReachedException olre )
{
backup(mark);
throw backtrack;
} }
while (LT(1) == IToken.tCOLONCOLON)
{
last = consume();
if (LT(1) == IToken.t_template)
consume();
if (LT(1) == IToken.tCOMPL)
consume();
switch (LT(1))
{
case IToken.t_operator :
backup(mark);
throw backtrack;
case IToken.tIDENTIFIER :
last = consume();
last = consumeTemplateParameters(last);
}
}
return new TokenDuple(first, last);
} }
/** /**
* Parse a const-volatile qualifier. * Parse a const-volatile qualifier.
@ -2689,7 +2703,7 @@ public abstract class Parser implements IParser
ITokenDuple duple = null; ITokenDuple duple = null;
setCompletionKind( CompletionKind.USER_SPECIFIED_NAME ); setCompletionKind( CompletionKind.USER_SPECIFIED_NAME );
setCompletionKeywords( KeywordSets.getKeywords( KeywordSets.Key.EMPTY, language ) ); setCompletionKeywords( Key.EMPTY );
// class name // class name
if (LT(1) == IToken.tIDENTIFIER) if (LT(1) == IToken.tIDENTIFIER)
duple = className(); duple = className();
@ -2896,6 +2910,9 @@ public abstract class Parser implements IParser
{ {
setCurrentScope(scope); setCurrentScope(scope);
setCompletionKind( CompletionKind.STATEMENT_START );
setCompletionKeywords( Key.STATEMENT );
switch (LT(1)) switch (LT(1))
{ {
case IToken.t_case : case IToken.t_case :
@ -3007,13 +3024,20 @@ public abstract class Parser implements IParser
default : default :
// can be many things: // can be many things:
// label // label
if (LT(1) == IToken.tIDENTIFIER && LT(2) == IToken.tCOLON)
{ try
consume(IToken.tIDENTIFIER); {
consume(IToken.tCOLON); if (LT(1) == IToken.tIDENTIFIER && LT(2) == IToken.tCOLON)
statement(scope); {
return; consume(IToken.tIDENTIFIER);
} consume(IToken.tCOLON);
statement(scope);
return;
}
}catch( OffsetLimitReachedException olre )
{
// ok
}
// expressionStatement // expressionStatement
// Note: the function style cast ambiguity is handled in expression // Note: the function style cast ambiguity is handled in expression
// Since it only happens when we are in a statement // Since it only happens when we are in a statement
@ -3021,7 +3045,10 @@ public abstract class Parser implements IParser
try try
{ {
IASTExpression thisExpression = expression(scope); IASTExpression thisExpression = expression(scope);
consume(IToken.tSEMI); if( queryLookaheadCapability() )
consume(IToken.tSEMI);
else
throw new EndOfFileException();
thisExpression.acceptElement( requestor ); thisExpression.acceptElement( requestor );
return; return;
} }
@ -3029,14 +3056,15 @@ public abstract class Parser implements IParser
{ {
backup( mark ); backup( mark );
} }
catch( OffsetLimitReachedException olre )
{
backup(mark);
}
// declarationStatement // declarationStatement
declaration(scope, null); declaration(scope, null);
} }
if( scope instanceof IASTScopedElement )
setCurrentScope( ((IASTScopedElement)scope).getOwnerScope() );
else
setCurrentScope( null );
} }
protected void catchHandlerSequence(IASTScope scope) protected void catchHandlerSequence(IASTScope scope)
throws EndOfFileException, BacktrackException throws EndOfFileException, BacktrackException
@ -3136,9 +3164,12 @@ public abstract class Parser implements IParser
newScope.enterScope( requestor ); newScope.enterScope( requestor );
} }
IToken checkToken = null; IToken checkToken = null;
while (LT(1) != IToken.tRBRACE) setCurrentScope(createNewScope ? newScope : scope);
setCompletionKind( CompletionKind.STATEMENT_START );
while (queryLookaheadCapability() && LT(1) != IToken.tRBRACE)
{ {
checkToken = LA(1); checkToken = LA(1);
setCurrentScope(createNewScope ? newScope : scope);
try try
{ {
statement(createNewScope ? newScope : scope ); statement(createNewScope ? newScope : scope );
@ -3149,9 +3180,14 @@ public abstract class Parser implements IParser
if( LA(1) == checkToken ) if( LA(1) == checkToken )
errorHandling(); errorHandling();
} }
setCurrentScope(createNewScope ? newScope : scope);
setCompletionKind( CompletionKind.STATEMENT_START );
setCompletionKeywords( Key.STATEMENT );
} }
consume(IToken.tRBRACE); if( queryLookaheadCapability() ) consume(IToken.tRBRACE);
else throw new EndOfFileException();
if( createNewScope ) if( createNewScope )
newScope.exitScope( requestor ); newScope.exitScope( requestor );
} }
@ -3170,6 +3206,7 @@ public abstract class Parser implements IParser
public IASTExpression expression(IASTScope scope) throws BacktrackException, EndOfFileException public IASTExpression expression(IASTScope scope) throws BacktrackException, EndOfFileException
{ {
IASTExpression assignmentExpression = assignmentExpression(scope); IASTExpression assignmentExpression = assignmentExpression(scope);
if( !queryLookaheadCapability() ) return assignmentExpression;
while (LT(1) == IToken.tCOMMA) while (LT(1) == IToken.tCOMMA)
{ {
consume(); consume();
@ -3211,6 +3248,7 @@ public abstract class Parser implements IParser
&& conditionalExpression.getExpressionKind() && conditionalExpression.getExpressionKind()
== IASTExpression.Kind.CONDITIONALEXPRESSION) == IASTExpression.Kind.CONDITIONALEXPRESSION)
return conditionalExpression; return conditionalExpression;
if( !queryLookaheadCapability() ) return conditionalExpression;
switch (LT(1)) { switch (LT(1)) {
case IToken.tASSIGN : case IToken.tASSIGN :
return assignmentOperatorExpression( return assignmentOperatorExpression(
@ -3341,6 +3379,7 @@ public abstract class Parser implements IParser
throws BacktrackException, EndOfFileException throws BacktrackException, EndOfFileException
{ {
IASTExpression firstExpression = logicalOrExpression(scope); IASTExpression firstExpression = logicalOrExpression(scope);
if( !queryLookaheadCapability() ) return firstExpression;
if (LT(1) == IToken.tQUESTION) if (LT(1) == IToken.tQUESTION)
{ {
consume(); consume();
@ -3377,6 +3416,7 @@ public abstract class Parser implements IParser
throws BacktrackException, EndOfFileException throws BacktrackException, EndOfFileException
{ {
IASTExpression firstExpression = logicalAndExpression(scope); IASTExpression firstExpression = logicalAndExpression(scope);
if( !queryLookaheadCapability() ) return firstExpression;
while (LT(1) == IToken.tOR) while (LT(1) == IToken.tOR)
{ {
consume(); consume();
@ -3412,6 +3452,7 @@ public abstract class Parser implements IParser
throws BacktrackException, EndOfFileException throws BacktrackException, EndOfFileException
{ {
IASTExpression firstExpression = inclusiveOrExpression( scope ); IASTExpression firstExpression = inclusiveOrExpression( scope );
if( !queryLookaheadCapability() ) return firstExpression;
while (LT(1) == IToken.tAND) while (LT(1) == IToken.tAND)
{ {
consume(); consume();
@ -3446,6 +3487,7 @@ public abstract class Parser implements IParser
throws BacktrackException, EndOfFileException throws BacktrackException, EndOfFileException
{ {
IASTExpression firstExpression = exclusiveOrExpression(scope); IASTExpression firstExpression = exclusiveOrExpression(scope);
if( !queryLookaheadCapability() ) return firstExpression;
while (LT(1) == IToken.tBITOR) while (LT(1) == IToken.tBITOR)
{ {
consume(); consume();
@ -3481,6 +3523,7 @@ public abstract class Parser implements IParser
throws BacktrackException, EndOfFileException throws BacktrackException, EndOfFileException
{ {
IASTExpression firstExpression = andExpression( scope ); IASTExpression firstExpression = andExpression( scope );
if( !queryLookaheadCapability() ) return firstExpression;
while (LT(1) == IToken.tXOR) while (LT(1) == IToken.tXOR)
{ {
consume(); consume();
@ -3516,6 +3559,7 @@ public abstract class Parser implements IParser
protected IASTExpression andExpression(IASTScope scope) throws EndOfFileException, BacktrackException protected IASTExpression andExpression(IASTScope scope) throws EndOfFileException, BacktrackException
{ {
IASTExpression firstExpression = equalityExpression(scope); IASTExpression firstExpression = equalityExpression(scope);
if( !queryLookaheadCapability() ) return firstExpression;
while (LT(1) == IToken.tAMPER) while (LT(1) == IToken.tAMPER)
{ {
consume(); consume();
@ -3553,6 +3597,7 @@ public abstract class Parser implements IParser
IASTExpression firstExpression = relationalExpression(scope); IASTExpression firstExpression = relationalExpression(scope);
for (;;) for (;;)
{ {
if( !queryLookaheadCapability() ) return firstExpression;
switch (LT(1)) switch (LT(1))
{ {
case IToken.tEQUAL : case IToken.tEQUAL :
@ -3598,6 +3643,7 @@ public abstract class Parser implements IParser
IASTExpression firstExpression = shiftExpression(scope); IASTExpression firstExpression = shiftExpression(scope);
for (;;) for (;;)
{ {
if( !queryLookaheadCapability() ) return firstExpression;
switch (LT(1)) switch (LT(1))
{ {
case IToken.tGT : case IToken.tGT :
@ -3677,6 +3723,7 @@ public abstract class Parser implements IParser
IASTExpression firstExpression = additiveExpression(scope); IASTExpression firstExpression = additiveExpression(scope);
for (;;) for (;;)
{ {
if( !queryLookaheadCapability() ) return firstExpression;
switch (LT(1)) switch (LT(1))
{ {
case IToken.tSHIFTL : case IToken.tSHIFTL :
@ -3721,6 +3768,7 @@ public abstract class Parser implements IParser
IASTExpression firstExpression = multiplicativeExpression( scope ); IASTExpression firstExpression = multiplicativeExpression( scope );
for (;;) for (;;)
{ {
if( !queryLookaheadCapability() ) return firstExpression;
switch (LT(1)) switch (LT(1))
{ {
case IToken.tPLUS : case IToken.tPLUS :
@ -3765,6 +3813,7 @@ public abstract class Parser implements IParser
IASTExpression firstExpression = pmExpression(scope); IASTExpression firstExpression = pmExpression(scope);
for (;;) for (;;)
{ {
if( !queryLookaheadCapability() ) return firstExpression;
switch (LT(1)) switch (LT(1))
{ {
case IToken.tSTAR : case IToken.tSTAR :
@ -3819,6 +3868,7 @@ public abstract class Parser implements IParser
IASTExpression firstExpression = castExpression(scope); IASTExpression firstExpression = castExpression(scope);
for (;;) for (;;)
{ {
if( ! queryLookaheadCapability() ) return firstExpression;
switch (LT(1)) switch (LT(1))
{ {
case IToken.tDOTSTAR : case IToken.tDOTSTAR :
@ -3861,6 +3911,7 @@ public abstract class Parser implements IParser
protected IASTExpression castExpression( IASTScope scope ) throws EndOfFileException, BacktrackException protected IASTExpression castExpression( IASTScope scope ) throws EndOfFileException, BacktrackException
{ {
// TO DO: we need proper symbol checkint to ensure type name // TO DO: we need proper symbol checkint to ensure type name
if( ! queryLookaheadCapability() ) return unaryExpression(scope);
if (LT(1) == IToken.tLPAREN) if (LT(1) == IToken.tLPAREN)
{ {
IToken mark = mark(); IToken mark = mark();
@ -4091,7 +4142,7 @@ public abstract class Parser implements IParser
*/ */
protected IASTExpression deleteExpression( IASTScope scope ) protected IASTExpression deleteExpression( IASTScope scope )
throws EndOfFileException, BacktrackException throws EndOfFileException, BacktrackException
{ {
if (LT(1) == IToken.tCOLONCOLON) if (LT(1) == IToken.tCOLONCOLON)
{ {
// global scope // global scope
@ -4341,6 +4392,7 @@ public abstract class Parser implements IParser
protected IASTExpression unaryExpression( IASTScope scope ) protected IASTExpression unaryExpression( IASTScope scope )
throws EndOfFileException, BacktrackException throws EndOfFileException, BacktrackException
{ {
if( ! queryLookaheadCapability() ) return postfixExpression( scope );
switch (LT(1)) switch (LT(1))
{ {
case IToken.tSTAR : case IToken.tSTAR :
@ -4465,6 +4517,8 @@ public abstract class Parser implements IParser
{ {
IASTExpression firstExpression = null; IASTExpression firstExpression = null;
boolean isTemplate = false; boolean isTemplate = false;
if( ! queryLookaheadCapability() ) return primaryExpression(scope);
switch (LT(1)) switch (LT(1))
{ {
case IToken.t_typename : case IToken.t_typename :
@ -4625,6 +4679,7 @@ public abstract class Parser implements IParser
IASTExpression secondExpression = null; IASTExpression secondExpression = null;
for (;;) for (;;)
{ {
if( ! queryLookaheadCapability() )return firstExpression;
switch (LT(1)) switch (LT(1))
{ {
case IToken.tLBRACKET : case IToken.tLBRACKET :
@ -4729,12 +4784,18 @@ public abstract class Parser implements IParser
// member access // member access
consume(IToken.tDOT); consume(IToken.tDOT);
if (LT(1) == IToken.t_template) try
{ {
consume(IToken.t_template); if (LT(1) == IToken.t_template)
isTemplate = true; {
} consume(IToken.t_template);
isTemplate = true;
}
} catch( OffsetLimitReachedException olre )
{
setCompletionToken( null );
}
IASTNode context = astFactory.getCompletionContext( (isTemplate IASTNode context = astFactory.getCompletionContext( (isTemplate
? IASTExpression.Kind.POSTFIX_DOT_TEMPL_IDEXPRESS ? IASTExpression.Kind.POSTFIX_DOT_TEMPL_IDEXPRESS
: IASTExpression.Kind.POSTFIX_DOT_IDEXPRESSION), : IASTExpression.Kind.POSTFIX_DOT_IDEXPRESSION),
@ -4760,22 +4821,29 @@ public abstract class Parser implements IParser
catch (ASTSemanticException e5) catch (ASTSemanticException e5)
{ {
failParse(); failParse();
setCompletionContext( null );
throw backtrack; throw backtrack;
} catch (Exception e) } catch (Exception e)
{
throw backtrack;
} finally
{ {
setCompletionContext( null ); setCompletionContext( null );
} throw backtrack;
}
break; break;
case IToken.tARROW : case IToken.tARROW :
// member access // member access
consume(IToken.tARROW); consume(IToken.tARROW);
if (LT(1) == IToken.t_template)
{ try
consume(IToken.t_template); {
isTemplate = true; if (LT(1) == IToken.t_template)
{
consume(IToken.t_template);
isTemplate = true;
}
} catch( OffsetLimitReachedException olre )
{
setCompletionToken( null );
} }
context = astFactory.getCompletionContext( (isTemplate context = astFactory.getCompletionContext( (isTemplate
@ -4803,13 +4871,12 @@ public abstract class Parser implements IParser
catch (ASTSemanticException e) catch (ASTSemanticException e)
{ {
failParse(); failParse();
setCompletionContext( null );
throw backtrack; throw backtrack;
} catch (Exception e) } catch (Exception e)
{
throw backtrack;
}finally
{ {
setCompletionContext( null ); setCompletionContext( null );
throw backtrack;
} }
break; break;
default : default :
@ -4820,7 +4887,24 @@ public abstract class Parser implements IParser
protected IASTExpression specialCastExpression( IASTScope scope, /**
* @return
* @throws EndOfFileException
*/
protected boolean queryLookaheadCapability() throws EndOfFileException {
//make sure we can look ahead one before doing this
boolean result = true;
try
{
LA(1);
}
catch( OffsetLimitReachedException olre )
{
result = false;
}
return result;
}
protected IASTExpression specialCastExpression( IASTScope scope,
IASTExpression.Kind kind) IASTExpression.Kind kind)
throws EndOfFileException, BacktrackException throws EndOfFileException, BacktrackException
{ {
@ -4886,6 +4970,21 @@ public abstract class Parser implements IParser
throws EndOfFileException, BacktrackException throws EndOfFileException, BacktrackException
{ {
IToken t = null; IToken t = null;
IASTExpression emptyExpression = null;
try {
emptyExpression = astFactory.createExpression(
scope,
IASTExpression.Kind.PRIMARY_EMPTY,
null,
null,
null,
null,
null, "", null);
} catch (ASTSemanticException e9) {
// TODO Auto-generated catch block
e9.printStackTrace();
}
if( !queryLookaheadCapability() ) return emptyExpression;
switch (LT(1)) switch (LT(1))
{ {
// TO DO: we need more literals... // TO DO: we need more literals...
@ -5036,7 +5135,7 @@ public abstract class Parser implements IParser
case IToken.t_operator : case IToken.t_operator :
ITokenDuple duple = null; ITokenDuple duple = null;
IToken mark = mark();
try try
{ {
duple = name(); duple = name();
@ -5045,7 +5144,6 @@ public abstract class Parser implements IParser
{ {
Declarator d = new Declarator( new DeclarationWrapper(scope, 0, null) ); Declarator d = new Declarator( new DeclarationWrapper(scope, 0, null) );
IToken mark = mark();
if (LT(1) == IToken.tCOLONCOLON || LT(1) == IToken.tIDENTIFIER) if (LT(1) == IToken.tCOLONCOLON || LT(1) == IToken.tIDENTIFIER)
{ {
IToken start = consume(); IToken start = consume();
@ -5071,6 +5169,11 @@ public abstract class Parser implements IParser
duple = d.getNameDuple(); duple = d.getNameDuple();
} }
catch(OffsetLimitReachedException olre )
{
backup(mark);
throw backtrack;
}
try try
@ -5092,24 +5195,7 @@ public abstract class Parser implements IParser
throw backtrack; throw backtrack;
} }
default : default :
try return emptyExpression;
{
return astFactory.createExpression(
scope,
IASTExpression.Kind.PRIMARY_EMPTY,
null,
null,
null,
null,
null, "", null);
}
catch (ASTSemanticException e)
{
throw backtrack;
} catch (Exception e)
{
throw backtrack;
}
} }
} }
/** /**
@ -5165,6 +5251,7 @@ public abstract class Parser implements IParser
protected IScanner scanner; protected IScanner scanner;
protected IToken currToken, // current token we plan to consume next protected IToken currToken, // current token we plan to consume next
lastToken; // last token we consumed lastToken; // last token we consumed
private boolean limitReached = false;
protected void setCurrentScope( IASTScope scope ) protected void setCurrentScope( IASTScope scope )
{ {
@ -5178,12 +5265,15 @@ public abstract class Parser implements IParser
*/ */
protected IToken fetchToken() throws EndOfFileException protected IToken fetchToken() throws EndOfFileException
{ {
if(limitReached) throw new OffsetLimitReachedException(getCompletionToken());
try try
{ {
return scanner.nextToken(); return scanner.nextToken();
} }
catch( OffsetLimitReachedException olre ) catch( OffsetLimitReachedException olre )
{ {
limitReached = true;
handleOffsetLimitException(olre); handleOffsetLimitException(olre);
return null; return null;
} }
@ -5315,8 +5405,16 @@ public abstract class Parser implements IParser
{ {
} }
protected void setCompletionKeywords( Set keywords ) protected void setCompletionKeywords(KeywordSets.Key key )
{ {
} }
protected void setCompletionToken( IToken token )
{
}
protected IToken getCompletionToken()
{
return null;
}
} }

View file

@ -1,3 +1,6 @@
2004-01-13 John Camelon
Updated CompletionEngine to handle IASTCompletionKind.CompletionKind.STATEMENT_START
2004-01-08 Hoda Amer 2004-01-08 Hoda Amer
Added Content assist log cpabilities Added Content assist log cpabilities

View file

@ -17,7 +17,6 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.ICLogConstants;
import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.parser.IParser; import org.eclipse.cdt.core.parser.IParser;
@ -411,6 +410,24 @@ public class CompletionEngine implements RelevanceConstants{
addToCompletions (result); addToCompletions (result);
} }
private void completionOnStatementStart( IASTCompletionNode completionNode )
{
IASTScope searchNode = completionNode.getCompletionScope();
LookupResult result = null;
// lookup fields and methods with the right visibility
IASTNode.LookupKind[] kinds = new IASTNode.LookupKind[7];
kinds[0] = IASTNode.LookupKind.FIELDS;
kinds[1] = IASTNode.LookupKind.METHODS;
kinds[2] = IASTNode.LookupKind.VARIABLES;
kinds[3] = IASTNode.LookupKind.STRUCTURES;
kinds[4] = IASTNode.LookupKind.ENUMERATIONS;
kinds[5] = IASTNode.LookupKind.NAMESPACES;
kinds[6] = IASTNode.LookupKind.FUNCTIONS;
result = lookup (searchNode, completionNode.getCompletionPrefix(), kinds, completionNode.getCompletionContext());
addToCompletions (result);
}
private void completionOnScopedReference(IASTCompletionNode completionNode){ private void completionOnScopedReference(IASTCompletionNode completionNode){
// 1. Get the search scope node // 1. Get the search scope node
// the search node is the name before the qualification // the search node is the name before the qualification
@ -630,6 +647,10 @@ public class CompletionEngine implements RelevanceConstants{
// CompletionOnKeyword // CompletionOnKeyword
completionOnKeyword(completionNode); completionOnKeyword(completionNode);
} }
else if(kind == IASTCompletionNode.CompletionKind.STATEMENT_START )
{
completionOnStatementStart(completionNode);
}
addKeywordsToCompletions( completionNode.getKeywords()); addKeywordsToCompletions( completionNode.getKeywords());
return completionNode; return completionNode;
@ -704,6 +725,10 @@ public class CompletionEngine implements RelevanceConstants{
case 15: case 15:
kindStr = "USER_SPECIFIED_NAME"; kindStr = "USER_SPECIFIED_NAME";
break; break;
case 16:
kindStr = "STATEMENT_START";
break;
case 200: case 200:
kindStr = "NO_SUCH_KIND"; kindStr = "NO_SUCH_KIND";