1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Patch for Andrew Niefer.

For normal lookups in the symbol table, a HashMap is faster than the tree 
map, but for prefix lookups the TreeMap is faster.  So we are now using 
the HashMap for normal parses, and we use the TreeMap in the parse mode 
used by content assist.

Note that with these changes the results returned by the IASTNode.lookup 
function used by content assist are now in predictable order:  they are 
first sorted in the order of the scopes visited during the lookup and then 
they are sorted alphabetically

Core:
Modified symbol table constructor to take a ParseMode as a parameter.
Modified symbol table to use a TreeMap instead of HashMap when ParseMode is COMPLETION_PARSE.
Modified ASTNode.lookup to throw ASTNotImplementedException if called when ParseMode is not CONTEXTUAL_PARSE.

Core.tests:
Moved testBug48307_FriendFunction_1 & testBug48307_FriendFunction_2 to ContextualParseTest.
Updated ContextualParseTest now that the order of prefix lookup results is predictable.

UI:
Updated CompletionEngine to catch ASTNotImplementedException from IASTNode.lookup.
This commit is contained in:
John Camelon 2004-01-15 23:06:58 +00:00
parent 020ee8aeea
commit 57d668240a
15 changed files with 170 additions and 89 deletions

View file

@ -1,3 +1,7 @@
2004-01-15 Andrew Niefer
Moved testBug48307_FriendFunction_1 & testBug48307_FriendFunction_2 to ContextualParseTest
Updated ContextualParseTest now that the order of prefix lookup results is predictable.
2004-01-15 Hoda Amer 2004-01-15 Hoda Amer
Moved Content Assist testing to the UI.tests plugin Moved Content Assist testing to the UI.tests plugin

View file

@ -32,7 +32,6 @@ import org.eclipse.cdt.core.parser.ast.IASTFunction;
import org.eclipse.cdt.core.parser.ast.IASTLinkageSpecification; import org.eclipse.cdt.core.parser.ast.IASTLinkageSpecification;
import org.eclipse.cdt.core.parser.ast.IASTMethod; import org.eclipse.cdt.core.parser.ast.IASTMethod;
import org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition; import org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition;
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.IASTReference; import org.eclipse.cdt.core.parser.ast.IASTReference;
import org.eclipse.cdt.core.parser.ast.IASTScope; import org.eclipse.cdt.core.parser.ast.IASTScope;
@ -42,7 +41,6 @@ import org.eclipse.cdt.core.parser.ast.IASTUsingDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTUsingDirective; import org.eclipse.cdt.core.parser.ast.IASTUsingDirective;
import org.eclipse.cdt.core.parser.ast.IASTVariable; import org.eclipse.cdt.core.parser.ast.IASTVariable;
import org.eclipse.cdt.core.parser.ast.IASTVariableReference; import org.eclipse.cdt.core.parser.ast.IASTVariableReference;
import org.eclipse.cdt.core.parser.ast.IASTNode.ILookupResult;
import org.eclipse.cdt.internal.core.parser.ParserException; import org.eclipse.cdt.internal.core.parser.ParserException;
@ -1160,48 +1158,4 @@ public class CompleteParseASTTest extends CompleteParseBaseTest
assertTrue( foo.takesVarArgs() ); assertTrue( foo.takesVarArgs() );
assertAllReferences( 1, createTaskList( new Task( foo ) ) ); assertAllReferences( 1, createTaskList( new Task( foo ) ) );
} }
public void testBug48307_FriendFunction_1() throws Exception {
StringWriter writer = new StringWriter();
writer.write( "class A{ public : void foo(); }; " );
writer.write( "class B{ ");
writer.write( " private : int aPrivate;" );
writer.write( " friend void A::foo(); ");
writer.write( "};" );
writer.write( "void A::foo(){}" );
Iterator i = parse( writer.toString() ).getDeclarations();
IASTClassSpecifier classA = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier();
IASTClassSpecifier classB = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier();
IASTMethod method = (IASTMethod) i.next();
ILookupResult result = method.lookup( "a", new IASTNode.LookupKind[] { IASTNode.LookupKind.ALL }, classB );
assertEquals( result.getResultsSize(), 1 );
IASTField field = (IASTField) result.getNodes().next();
assertEquals( field.getName(), "aPrivate" );
}
public void testBug48307_FriendFunction_2() throws Exception {
StringWriter writer = new StringWriter();
writer.write( "void global();" );
writer.write( "class B{ ");
writer.write( " private : int aPrivate;" );
writer.write( " friend void global(); ");
writer.write( "};" );
writer.write( "void global(){}" );
Iterator i = parse( writer.toString() ).getDeclarations();
IASTFunction functionDecl = (IASTFunction) i.next();
IASTClassSpecifier classB = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier();
IASTFunction functionDef = (IASTFunction) i.next();
ILookupResult result = functionDef.lookup( "a", new IASTNode.LookupKind[] { IASTNode.LookupKind.ALL }, classB );
assertEquals( result.getResultsSize(), 1 );
IASTField field = (IASTField) result.getNodes().next();
assertEquals( field.getName(), "aPrivate" );
}
} }

View file

@ -26,8 +26,8 @@ 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.ILookupResult; import org.eclipse.cdt.core.parser.ast.IASTNode.ILookupResult;
import org.eclipse.cdt.core.parser.ast.IASTNode.LookupKind;
import org.eclipse.cdt.internal.core.parser.ParserLogService; import org.eclipse.cdt.internal.core.parser.ParserLogService;
/** /**
@ -150,12 +150,14 @@ public class ContextualParseTest extends CompleteParseBaseTest {
Iterator iter = result.getNodes(); Iterator iter = result.getNodes();
IASTVariable anotherVar = (IASTVariable) iter.next(); IASTVariable anotherVar = (IASTVariable) iter.next();
IASTVariable aVar = (IASTVariable) iter.next();
if( i != 0 ) if( i != 0 )
{ {
IASTFunction foo = (IASTFunction) iter.next(); IASTFunction foo = (IASTFunction) iter.next();
assertEquals( foo.getName(), "foo"); assertEquals( foo.getName(), "foo");
} }
IASTVariable aVar = (IASTVariable) iter.next();
assertFalse( iter.hasNext() ); assertFalse( iter.hasNext() );
assertEquals( anotherVar.getName(), "anotherVar" ); assertEquals( anotherVar.getName(), "anotherVar" );
@ -198,18 +200,8 @@ public class ContextualParseTest extends CompleteParseBaseTest {
Iterator iter = result.getNodes(); Iterator iter = result.getNodes();
IASTMethod aMethod = null; IASTField aField = (IASTField) iter.next();
IASTField aField = null; IASTMethod aMethod = (IASTMethod) iter.next();
//we can't currently predict the order in this case
for( int i = 1; i <= 2; i++ ){
IASTNode astNode = (IASTNode) iter.next();
if( astNode instanceof IASTMethod ){
aMethod = (IASTMethod) astNode;
} else{
aField = (IASTField) astNode;
}
}
assertFalse( iter.hasNext() ); assertFalse( iter.hasNext() );
@ -562,4 +554,52 @@ public class ContextualParseTest extends CompleteParseBaseTest {
ILookupResult result = inquestion.lookup( "a", kinds, null ); ILookupResult result = inquestion.lookup( "a", kinds, null );
assertEquals(result.getResultsSize(), 3 ); assertEquals(result.getResultsSize(), 3 );
} }
public void testBug48307_FriendFunction_1() throws Exception {
StringWriter writer = new StringWriter();
writer.write( "class A{ public : void foo(); }; " );
writer.write( "class B{ ");
writer.write( " private : int aPrivate;" );
writer.write( " friend void A::foo(); ");
writer.write( "};" );
writer.write( "void A::foo(){" );
writer.write( " B b;");
writer.write( " b.aP" );
String code = writer.toString();
int index = code.indexOf( "b.aP" );
IASTCompletionNode node = parse( code, index + 4 );
ILookupResult result = node.getCompletionScope().lookup( node.getCompletionPrefix(),
new IASTNode.LookupKind[] { IASTNode.LookupKind.ALL },
node.getCompletionContext() );
assertEquals( result.getResultsSize(), 1 );
IASTField field = (IASTField) result.getNodes().next();
assertEquals( field.getName(), "aPrivate" );
}
public void testBug48307_FriendFunction_2() throws Exception {
StringWriter writer = new StringWriter();
writer.write( "void global();" );
writer.write( "class B{ ");
writer.write( " private : int aPrivate;" );
writer.write( " friend void global(); ");
writer.write( "};" );
writer.write( "void global(){" );
writer.write( " B b;");
writer.write( " b.aP" );
String code = writer.toString();
int index = code.indexOf( "b.aP" );
IASTCompletionNode node = parse( code, index + 4 );
ILookupResult result = node.getCompletionScope().lookup( node.getCompletionPrefix(),
new IASTNode.LookupKind[] { IASTNode.LookupKind.ALL },
node.getCompletionContext() );
assertEquals( result.getResultsSize(), 1 );
IASTField field = (IASTField) result.getNodes().next();
assertEquals( field.getName(), "aPrivate" );
}
} }

View file

@ -20,6 +20,7 @@ import java.util.Map;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility; import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility;
import org.eclipse.cdt.core.parser.ast.ASTClassKind; import org.eclipse.cdt.core.parser.ast.ASTClassKind;
import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier; import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier;
@ -66,11 +67,11 @@ public class ParserSymbolTableTest extends TestCase {
} }
public ParserSymbolTable newTable(){ public ParserSymbolTable newTable(){
return newTable( ParserLanguage.CPP ); return newTable( ParserLanguage.CPP, ParserMode.COMPLETE_PARSE );
} }
public ParserSymbolTable newTable( ParserLanguage language ){ public ParserSymbolTable newTable( ParserLanguage language, ParserMode mode ){
table = new ParserSymbolTable( language ); table = new ParserSymbolTable( language, mode );
return table; return table;
} }
/** /**
@ -3011,7 +3012,7 @@ public class ParserSymbolTableTest extends TestCase {
* } * }
*/ */
public void testPrefixLookup_Unqualified() throws Exception { public void testPrefixLookup_Unqualified() throws Exception {
newTable(); newTable( ParserLanguage.CPP, ParserMode.COMPLETION_PARSE );
ISymbol aVar = table.newSymbol( "aVar", TypeInfo.t_int ); ISymbol aVar = table.newSymbol( "aVar", TypeInfo.t_int );
table.getCompilationUnit().addSymbol( aVar ); table.getCompilationUnit().addSymbol( aVar );
@ -3042,7 +3043,7 @@ public class ParserSymbolTableTest extends TestCase {
* d.a(CTRL+SPACE) * d.a(CTRL+SPACE)
*/ */
public void testPrefixLookup_Qualified() throws Exception { public void testPrefixLookup_Qualified() throws Exception {
newTable(); newTable( ParserLanguage.CPP, ParserMode.COMPLETION_PARSE );
ISymbol aVar = table.newSymbol( "aVar", TypeInfo.t_int ); ISymbol aVar = table.newSymbol( "aVar", TypeInfo.t_int );
table.getCompilationUnit().addSymbol( aVar ); table.getCompilationUnit().addSymbol( aVar );
@ -3082,7 +3083,7 @@ public class ParserSymbolTableTest extends TestCase {
* @throws Exception * @throws Exception
*/ */
public void testPrefixLookup_Inheritance() throws Exception { public void testPrefixLookup_Inheritance() throws Exception {
newTable(); newTable( ParserLanguage.CPP, ParserMode.COMPLETION_PARSE );
IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_class ); IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
table.getCompilationUnit().addSymbol( A ); table.getCompilationUnit().addSymbol( A );
@ -3143,7 +3144,7 @@ public class ParserSymbolTableTest extends TestCase {
* @throws Exception * @throws Exception
*/ */
public void testPrefixLookup_Ambiguities() throws Exception{ public void testPrefixLookup_Ambiguities() throws Exception{
newTable(); newTable( ParserLanguage.CPP, ParserMode.COMPLETION_PARSE );
ISymbol aa = table.newSymbol( "aa", TypeInfo.t_int ); ISymbol aa = table.newSymbol( "aa", TypeInfo.t_int );
table.getCompilationUnit().addSymbol( aa ); table.getCompilationUnit().addSymbol( aa );
@ -3288,7 +3289,7 @@ public class ParserSymbolTableTest extends TestCase {
* @throws Exception * @throws Exception
*/ */
public void testPrefixFiltering() throws Exception{ public void testPrefixFiltering() throws Exception{
newTable(); newTable( ParserLanguage.CPP, ParserMode.COMPLETION_PARSE );
IDerivableContainerSymbol a1 = table.newDerivableContainerSymbol( "a1", TypeInfo.t_struct ); IDerivableContainerSymbol a1 = table.newDerivableContainerSymbol( "a1", TypeInfo.t_struct );
table.getCompilationUnit().addSymbol( a1 ); table.getCompilationUnit().addSymbol( a1 );

View file

@ -1,3 +1,8 @@
2004-01-15 Andrew Niefer
Modified symbol table constructor to take a ParseMode as a parameter.
Modified symbol table to use a TreeMap instead of HashMap when ParseMode is CONTEXTUAL_PARSE
Modified ASTNode.lookup to throw ASTNotImplementedException if called when ParseMode is not CONTEXTUAL_PARSE
2004-01-15 Hoda Amer 2004-01-15 Hoda Amer
2004-01-15 John Camelon 2004-01-15 John Camelon

View file

@ -37,7 +37,7 @@ public class ParserFactory {
if( mode == ParserMode.QUICK_PARSE ) if( mode == ParserMode.QUICK_PARSE )
return new QuickParseASTFactory(); return new QuickParseASTFactory();
else else
return new CompleteParseASTFactory( language ); return new CompleteParseASTFactory( language, mode );
} }
public static IParser createParser( IScanner scanner, ISourceElementRequestor callback, ParserMode mode, ParserLanguage language, IParserLogService log ) throws ParserFactoryError public static IParser createParser( IScanner scanner, ISourceElementRequestor callback, ParserMode mode, ParserLanguage language, IParserLogService log ) throws ParserFactoryError

View file

@ -66,6 +66,6 @@ public interface IASTNode {
* @return * @return
* @throws LookupException * @throws LookupException
*/ */
public ILookupResult lookup( String prefix, LookupKind[] kind, IASTNode context) throws LookupException; public ILookupResult lookup( String prefix, LookupKind[] kind, IASTNode context) throws LookupException, ASTNotImplementedException;
} }

View file

@ -51,7 +51,7 @@ public class ContextualParser extends Parser implements IParser {
*/ */
public ContextualParser(IScanner scanner, ISourceElementRequestor callback, ParserLanguage language, IParserLogService log) { public ContextualParser(IScanner scanner, ISourceElementRequestor callback, ParserLanguage language, IParserLogService log) {
super(scanner, callback, language, log); super(scanner, callback, language, log);
astFactory = ParserFactory.createASTFactory( ParserMode.COMPLETE_PARSE, language); astFactory = ParserFactory.createASTFactory( ParserMode.COMPLETION_PARSE, language);
scanner.setASTFactory(astFactory); scanner.setASTFactory(astFactory);
} }

View file

@ -14,6 +14,8 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.ListIterator; import java.util.ListIterator;
import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.ast.ASTNotImplementedException;
import org.eclipse.cdt.core.parser.ast.IASTNode; import org.eclipse.cdt.core.parser.ast.IASTNode;
import org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol; import org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol;
import org.eclipse.cdt.internal.core.parser.pst.ISymbol; import org.eclipse.cdt.internal.core.parser.pst.ISymbol;
@ -31,7 +33,8 @@ public class ASTNode implements IASTNode {
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTNode#lookup(java.lang.String, org.eclipse.cdt.core.parser.ast.IASTNode.LookupKind, org.eclipse.cdt.core.parser.ast.IASTNode) * @see org.eclipse.cdt.core.parser.ast.IASTNode#lookup(java.lang.String, org.eclipse.cdt.core.parser.ast.IASTNode.LookupKind, org.eclipse.cdt.core.parser.ast.IASTNode)
*/ */
public ILookupResult lookup(String prefix, LookupKind[] kind, IASTNode context) throws LookupException { public ILookupResult lookup(String prefix, LookupKind[] kind, IASTNode context) throws LookupException, ASTNotImplementedException {
if( ! ( this instanceof ISymbolOwner ) || ( context != null && !(context instanceof ISymbolOwner) ) ){ if( ! ( this instanceof ISymbolOwner ) || ( context != null && !(context instanceof ISymbolOwner) ) ){
return null; return null;
} }
@ -39,6 +42,10 @@ public class ASTNode implements IASTNode {
IContainerSymbol thisContainer = (IContainerSymbol) ((ISymbolOwner)this).getSymbol(); IContainerSymbol thisContainer = (IContainerSymbol) ((ISymbolOwner)this).getSymbol();
IContainerSymbol qualification = null; IContainerSymbol qualification = null;
if( thisContainer.getSymbolTable().getParserMode() != ParserMode.COMPLETION_PARSE ){
throw new ASTNotImplementedException();
}
if( context != null ){ if( context != null ){
ISymbol sym = (IContainerSymbol) ((ISymbolOwner)context).getSymbol(); ISymbol sym = (IContainerSymbol) ((ISymbolOwner)context).getSymbol();
if( sym == null || !(sym instanceof IContainerSymbol) ){ if( sym == null || !(sym instanceof IContainerSymbol) ){

View file

@ -20,6 +20,7 @@ import org.eclipse.cdt.core.parser.Enum;
import org.eclipse.cdt.core.parser.IToken; import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.core.parser.ITokenDuple; import org.eclipse.cdt.core.parser.ITokenDuple;
import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility; import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility;
import org.eclipse.cdt.core.parser.ast.ASTClassKind; import org.eclipse.cdt.core.parser.ast.ASTClassKind;
import org.eclipse.cdt.core.parser.ast.ASTNotImplementedException; import org.eclipse.cdt.core.parser.ast.ASTNotImplementedException;
@ -115,11 +116,11 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
} }
} }
public CompleteParseASTFactory( ParserLanguage language ) public CompleteParseASTFactory( ParserLanguage language, ParserMode mode )
{ {
super(); super();
pst = new ParserSymbolTable( language ); pst = new ParserSymbolTable( language, mode );
} }
/* /*

View file

@ -14,6 +14,7 @@
package org.eclipse.cdt.internal.core.parser.pst; package org.eclipse.cdt.internal.core.parser.pst;
import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
@ -21,7 +22,9 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.ListIterator; import java.util.ListIterator;
import java.util.Map; import java.util.Map;
import java.util.TreeMap;
import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility; import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility;
import org.eclipse.cdt.core.parser.ast.IASTMember; import org.eclipse.cdt.core.parser.ast.IASTMember;
import org.eclipse.cdt.core.parser.ast.IASTNode; import org.eclipse.cdt.core.parser.ast.IASTNode;
@ -52,7 +55,11 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
ContainerSymbol copy = (ContainerSymbol)super.clone(); ContainerSymbol copy = (ContainerSymbol)super.clone();
copy._usingDirectives = ( _usingDirectives != null ) ? (LinkedList) _usingDirectives.clone() : null; copy._usingDirectives = ( _usingDirectives != null ) ? (LinkedList) _usingDirectives.clone() : null;
copy._containedSymbols = ( _containedSymbols != null )? (HashMap) _containedSymbols.clone() : null;
if( getSymbolTable().getParserMode() == ParserMode.COMPLETION_PARSE )
copy._containedSymbols = ( _containedSymbols != null )? (Map)((TreeMap) _containedSymbols).clone() : null;
else
copy._containedSymbols = ( _containedSymbols != null )? (Map)((HashMap) _containedSymbols).clone() : null;
return copy; return copy;
} }
@ -118,7 +125,6 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
origList.add( origDecl ); origList.add( origDecl );
origList.add( obj ); origList.add( obj );
declarations.remove( origDecl );
declarations.put( obj.getName(), origList ); declarations.put( obj.getName(), origList );
} else { } else {
origList.add( obj ); origList.add( obj );
@ -264,7 +270,12 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
*/ */
public Map getContainedSymbols(){ public Map getContainedSymbols(){
if( _containedSymbols == null ){ if( _containedSymbols == null ){
_containedSymbols = new HashMap(); if( getSymbolTable().getParserMode() == ParserMode.COMPLETION_PARSE ){
_containedSymbols = new TreeMap( new SymbolTableComparator() );
} else {
_containedSymbols = new HashMap( );
}
} }
return _containedSymbols; return _containedSymbols;
} }
@ -760,7 +771,6 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
} }
} }
if( list.size() == 1 ){ if( list.size() == 1 ){
_context.getContainedSymbols().remove( _symbol.getName() );
_context.getContainedSymbols().put( _symbol.getName(), list.getFirst() ); _context.getContainedSymbols().put( _symbol.getName(), list.getFirst() );
} }
} else if( obj instanceof BasicSymbol ){ } else if( obj instanceof BasicSymbol ){
@ -787,7 +797,21 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
private IContainerSymbol _namespace; private IContainerSymbol _namespace;
} }
static protected class SymbolTableComparator implements Comparator{
public int compare( Object o1, Object o2 ){
int result = ((String) o1).compareToIgnoreCase( (String) o2 );
if( result == 0 ){
return ((String) o1).compareTo( (String) o2 );
}
return result;
}
public boolean equals( Object obj ){
return ( obj instanceof SymbolTableComparator );
}
}
private LinkedList _usingDirectives; //collection of nominated namespaces private LinkedList _usingDirectives; //collection of nominated namespaces
private HashMap _containedSymbols; //declarations contained by us. private Map _containedSymbols; //declarations contained by us.
} }

View file

@ -18,7 +18,9 @@ import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.TreeMap;
import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.Command; import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.Command;
/** /**
@ -45,7 +47,11 @@ public class ParameterizedSymbol extends ContainerSymbol implements IParameteriz
ParameterizedSymbol copy = (ParameterizedSymbol)super.clone(); ParameterizedSymbol copy = (ParameterizedSymbol)super.clone();
copy._parameterList = ( _parameterList != null ) ? (LinkedList) _parameterList.clone() : null; copy._parameterList = ( _parameterList != null ) ? (LinkedList) _parameterList.clone() : null;
copy._parameterMap = ( _parameterMap != null ) ? (HashMap) _parameterMap.clone() : null;
if( getSymbolTable().getParserMode() == ParserMode.COMPLETION_PARSE )
copy._parameterMap = ( _parameterMap != null ) ? (Map) ((TreeMap) _parameterMap).clone() : null;
else
copy._parameterMap = ( _parameterMap != null ) ? (Map) ((HashMap) _parameterMap).clone() : null;
copy._argumentList = ( _argumentList != null ) ? (LinkedList) _argumentList.clone() : null; copy._argumentList = ( _argumentList != null ) ? (LinkedList) _argumentList.clone() : null;
copy._specializations = ( _specializations != null ) ? (LinkedList) _specializations.clone() : null; copy._specializations = ( _specializations != null ) ? (LinkedList) _specializations.clone() : null;
@ -142,7 +148,10 @@ public class ParameterizedSymbol extends ContainerSymbol implements IParameteriz
*/ */
public Map getParameterMap(){ public Map getParameterMap(){
if( _parameterMap == null ){ if( _parameterMap == null ){
_parameterMap = new HashMap(); if( getSymbolTable().getParserMode() == ParserMode.COMPLETION_PARSE )
_parameterMap = new TreeMap( new SymbolTableComparator() );
else
_parameterMap = new HashMap( );
} }
return _parameterMap; return _parameterMap;
} }
@ -282,7 +291,7 @@ public class ParameterizedSymbol extends ContainerSymbol implements IParameteriz
} }
private LinkedList _parameterList; //have my cake private LinkedList _parameterList; //have my cake
private HashMap _parameterMap; //and eat it too private Map _parameterMap; //and eat it too
private LinkedList _specializations; //template specializations private LinkedList _specializations; //template specializations
private LinkedList _argumentList; //template specialization arguments private LinkedList _argumentList; //template specialization arguments
private ISymbol _returnType; private ISymbol _returnType;

View file

@ -22,9 +22,11 @@ import java.util.List;
import java.util.ListIterator; import java.util.ListIterator;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.SortedMap;
import org.eclipse.cdt.core.parser.Enum; import org.eclipse.cdt.core.parser.Enum;
import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility; import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility;
import org.eclipse.cdt.core.parser.ast.IASTMember; import org.eclipse.cdt.core.parser.ast.IASTMember;
import org.eclipse.cdt.core.parser.ast.IASTNode; import org.eclipse.cdt.core.parser.ast.IASTNode;
@ -43,10 +45,11 @@ public class ParserSymbolTable {
/** /**
* Constructor for ParserSymbolTable. * Constructor for ParserSymbolTable.
*/ */
public ParserSymbolTable( ParserLanguage language ) { public ParserSymbolTable( ParserLanguage language, ParserMode mode ) {
super(); super();
_compilationUnit = newContainerSymbol( EMPTY_NAME, TypeInfo.t_namespace ); _compilationUnit = newContainerSymbol( EMPTY_NAME, TypeInfo.t_namespace );
_language = language; _language = language;
_mode = mode;
} }
public IContainerSymbol getCompilationUnit(){ public IContainerSymbol getCompilationUnit(){
@ -301,7 +304,15 @@ public class ParserSymbolTable {
Map declarations = lookIn.getContainedSymbols(); Map declarations = lookIn.getContainedSymbols();
Iterator iterator = ( data.mode == LookupMode.PREFIX ) ? declarations.keySet().iterator() : null; Iterator iterator = null;
if( data.mode == LookupMode.PREFIX ){
if( declarations instanceof SortedMap ){
iterator = ((SortedMap)declarations).tailMap( data.name.toLowerCase() ).keySet().iterator();
} else {
throw new ParserSymbolTableException( ParserSymbolTableException.r_InternalError );
}
}
String name = ( iterator != null && iterator.hasNext() ) ? (String) iterator.next() : data.name; String name = ( iterator != null && iterator.hasNext() ) ? (String) iterator.next() : data.name;
while( name != null ) { while( name != null ) {
@ -312,6 +323,8 @@ public class ParserSymbolTable {
if( obj != null ) if( obj != null )
found.put( name, obj ); found.put( name, obj );
} else {
break;
} }
if( iterator != null && iterator.hasNext() ){ if( iterator != null && iterator.hasNext() ){
@ -328,7 +341,14 @@ public class ParserSymbolTable {
if( lookIn instanceof IParameterizedSymbol ){ if( lookIn instanceof IParameterizedSymbol ){
Map parameters = ((IParameterizedSymbol)lookIn).getParameterMap(); Map parameters = ((IParameterizedSymbol)lookIn).getParameterMap();
if( parameters != null ){ if( parameters != null ){
iterator = ( data.mode == LookupMode.PREFIX ) ? parameters.keySet().iterator() : null; iterator = null;
if( data.mode == LookupMode.PREFIX ){
if( parameters instanceof SortedMap ){
iterator = ((SortedMap) parameters).tailMap( data.name.toLowerCase() ).keySet().iterator();
} else {
throw new ParserSymbolTableException( ParserSymbolTableException.r_InternalError );
}
}
name = ( iterator != null && iterator.hasNext() ) ? (String) iterator.next() : data.name; name = ( iterator != null && iterator.hasNext() ) ? (String) iterator.next() : data.name;
while( name != null ){ while( name != null ){
if( nameMatches( data, name ) ){ if( nameMatches( data, name ) ){
@ -337,7 +357,10 @@ public class ParserSymbolTable {
if( obj != null ){ if( obj != null ){
found.put( name, obj ); found.put( name, obj );
} }
} else {
break;
} }
if( iterator != null && iterator.hasNext() ){ if( iterator != null && iterator.hasNext() ){
name = (String) iterator.next(); name = (String) iterator.next();
} else { } else {
@ -2184,7 +2207,8 @@ public class ParserSymbolTable {
//private Stack _contextStack = new Stack(); //private Stack _contextStack = new Stack();
private IContainerSymbol _compilationUnit; private IContainerSymbol _compilationUnit;
private ParserLanguage _language; private ParserLanguage _language;
private ParserMode _mode;
private LinkedList undoList = new LinkedList(); private LinkedList undoList = new LinkedList();
private HashSet markSet = new HashSet(); private HashSet markSet = new HashSet();
@ -2196,6 +2220,10 @@ public class ParserSymbolTable {
return _language; return _language;
} }
public ParserMode getParserMode(){
return _mode;
}
protected void pushCommand( Command command ){ protected void pushCommand( Command command ){
undoList.addFirst( command ); undoList.addFirst( command );
} }

View file

@ -1,3 +1,6 @@
2004-01-13 Andrew Niefer
Updated CompletionEngine to catch ASTNotImplementedException from IASTNode.lookup
2004-01-15 Hoda Amer 2004-01-15 Hoda Amer
Moved Content Assist log to the UI plugin Moved Content Assist log to the UI plugin

View file

@ -32,6 +32,7 @@ import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.ParserUtil; import org.eclipse.cdt.core.parser.ParserUtil;
import org.eclipse.cdt.core.parser.ScannerInfo; import org.eclipse.cdt.core.parser.ScannerInfo;
import org.eclipse.cdt.core.parser.ast.ASTClassKind; import org.eclipse.cdt.core.parser.ast.ASTClassKind;
import org.eclipse.cdt.core.parser.ast.ASTNotImplementedException;
import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier; import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTCodeScope; import org.eclipse.cdt.core.parser.ast.IASTCodeScope;
import org.eclipse.cdt.core.parser.ast.IASTCompilationUnit; import org.eclipse.cdt.core.parser.ast.IASTCompilationUnit;
@ -401,6 +402,10 @@ public class CompletionEngine implements RelevanceConstants{
// do we want to do something here? // do we want to do something here?
ilk.printStackTrace(); ilk.printStackTrace();
return null; return null;
} catch (ASTNotImplementedException e) {
// shouldn't happen
e.printStackTrace();
return null;
} }
} }
private void completionOnMemberReference(IASTCompletionNode completionNode){ private void completionOnMemberReference(IASTCompletionNode completionNode){