From fc34ca8ab5dbc1372d6e3c86b82bfce2a222654a Mon Sep 17 00:00:00 2001 From: Andrew Niefer Date: Thu, 27 May 2004 22:26:56 +0000 Subject: [PATCH] reduce the size of the base LookupData from 72 to 40 bytes. Use abstract classes instead. This reduces the memory used by LookupData by 3 meg during a parse of iostream and windows.h --- .../core/parser/pst/ContainerSymbol.java | 146 +++++++++++------ .../parser/pst/DerivableContainerSymbol.java | 38 +++-- .../core/parser/pst/ParserSymbolTable.java | 150 ++++++++---------- 3 files changed, 189 insertions(+), 145 deletions(-) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java index c3de201a360..6624cfd40aa 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java @@ -364,7 +364,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#addUsingDeclaration(java.lang.String, org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol) */ public IUsingDeclarationSymbol addUsingDeclaration( String name, IContainerSymbol declContext ) throws ParserSymbolTableException{ - LookupData data = new LookupData( name, TypeInfo.t_any ); + LookupData data = new LookupData( name ); if( declContext != null ){ data.qualified = true; @@ -450,8 +450,18 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#elaboratedLookup(org.eclipse.cdt.internal.core.parser.pst.TypeInfo.eType, java.lang.String) */ - public ISymbol elaboratedLookup( TypeInfo.eType type, String name ) throws ParserSymbolTableException{ - LookupData data = new LookupData( name, type ); + public ISymbol elaboratedLookup( final TypeInfo.eType type, String name ) throws ParserSymbolTableException{ + LookupData data = new LookupData( name ){ + public TypeFilter getFilter() { + if( t == TypeInfo.t_any ) return ANY_FILTER; + else { + if( filter == null ) filter = new TypeFilter( t ); + return filter; + } + }; + private TypeFilter filter = null; + private final TypeInfo.eType t = type; + }; ParserSymbolTable.lookup( data, this ); @@ -478,7 +488,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#lookup(java.lang.String) */ public ISymbol lookup( String name ) throws ParserSymbolTableException { - LookupData data = new LookupData( name, TypeInfo.t_any ); + LookupData data = new LookupData( name ); ParserSymbolTable.lookup( data, this ); @@ -523,7 +533,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { * for a definition. */ public ISymbol lookupMemberForDefinition( String name ) throws ParserSymbolTableException{ - LookupData data = new LookupData( name, TypeInfo.t_any ); + LookupData data = new LookupData( name ); data.qualified = true; IContainerSymbol container = this; @@ -542,10 +552,12 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { return null; } - public IParameterizedSymbol lookupMethodForDefinition( String name, List parameters ) throws ParserSymbolTableException{ - LookupData data = new LookupData( name, TypeInfo.t_any ); + public IParameterizedSymbol lookupMethodForDefinition( String name, final List parameters ) throws ParserSymbolTableException{ + LookupData data = new LookupData( name ){ + public List getParameters() { return params; }; + final private List params = ( parameters == null ) ? Collections.EMPTY_LIST : parameters; + }; data.qualified = true; - data.parameters = ( parameters == null ) ? Collections.EMPTY_LIST : parameters; data.exactFunctionsOnly = true; IContainerSymbol container = this; @@ -586,10 +598,15 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { private IContainerSymbol lookupNestedNameSpecifier(String name, IContainerSymbol inSymbol ) throws ParserSymbolTableException{ ISymbol foundSymbol = null; - LookupData data = new LookupData( name, TypeInfo.t_namespace ); - data.filter.addAcceptedType( TypeInfo.t_class ); - data.filter.addAcceptedType( TypeInfo.t_struct ); - data.filter.addAcceptedType( TypeInfo.t_union ); + final TypeFilter filter = new TypeFilter( TypeInfo.t_namespace ); + filter.addAcceptedType( TypeInfo.t_class ); + filter.addAcceptedType( TypeInfo.t_struct ); + filter.addAcceptedType( TypeInfo.t_union ); + + LookupData data = new LookupData( name ){ + public TypeFilter getFilter() { return typeFilter; } + final private TypeFilter typeFilter = filter; + }; data.foundItems = ParserSymbolTable.lookupInContained( data, inSymbol ); @@ -611,15 +628,29 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#qualifiedLookup(java.lang.String) */ public ISymbol qualifiedLookup( String name ) throws ParserSymbolTableException{ + LookupData data = new LookupData( name ); + data.qualified = true; + ParserSymbolTable.lookup( data, this ); - return qualifiedLookup(name, TypeInfo.t_any); + return ParserSymbolTable.resolveAmbiguities( data ); } /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#qualifiedLookup(java.lang.String, org.eclipse.cdt.internal.core.parser.pst.TypeInfo.eType) */ - public ISymbol qualifiedLookup( String name, TypeInfo.eType t ) throws ParserSymbolTableException{ - LookupData data = new LookupData( name, t ); + public ISymbol qualifiedLookup( String name, final TypeInfo.eType t ) throws ParserSymbolTableException{ + LookupData data = new LookupData( name ){ + public TypeFilter getFilter() { + if( t == TypeInfo.t_any ) return ANY_FILTER; + else { + if( filter == null ) + filter = new TypeFilter( t ); + return filter; + } + } + private TypeFilter filter = null; + private final TypeInfo.eType type = t; + }; data.qualified = true; ParserSymbolTable.lookup( data, this ); @@ -651,10 +682,10 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { * ordinary unqualified lookup and the set of declarations found in the * namespaces and classes associated with the argument types. */ - public IParameterizedSymbol unqualifiedFunctionLookup( String name, List parameters ) throws ParserSymbolTableException{ + public IParameterizedSymbol unqualifiedFunctionLookup( String name, final List parameters ) throws ParserSymbolTableException{ //figure out the set of associated scopes first, so we can remove those that are searched //during the normal lookup to avoid doing them twice - HashSet associated = new HashSet(); + final HashSet associated = new HashSet(); //collect associated namespaces & classes. int size = ( parameters == null ) ? 0 : parameters.size(); @@ -684,12 +715,15 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { } } - LookupData data = new LookupData( name, TypeInfo.t_function ); - //if parameters == null, thats no parameters, but we need to distinguish that from - //no parameter information at all, so make an empty list. - data.parameters = ( parameters == null ) ? Collections.EMPTY_LIST : parameters; - data.associated = associated; - + LookupData data = new LookupData( name ){ + public HashSet getAssociated() { return assoc; } + public List getParameters() { return params; } + public TypeFilter getFilter() { return FUNCTION_FILTER; } + + final private HashSet assoc = associated; + final private List params = ( parameters == null ) ? Collections.EMPTY_LIST : parameters; + }; + ParserSymbolTable.lookup( data, this ); ISymbol found = ParserSymbolTable.resolveAmbiguities( data ); @@ -740,12 +774,12 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { * Member lookup really proceeds as an unqualified lookup, but doesn't * include argument dependant scopes */ - public IParameterizedSymbol memberFunctionLookup( String name, List parameters ) throws ParserSymbolTableException{ - LookupData data = new LookupData( name, TypeInfo.t_function ); - //if parameters == null, thats no parameters, but we need to distinguish that from - //no parameter information at all, so make an empty list. - data.parameters = ( parameters == null ) ? Collections.EMPTY_LIST : parameters; - + public IParameterizedSymbol memberFunctionLookup( String name, final List parameters ) throws ParserSymbolTableException{ + LookupData data = new LookupData( name ){ + public List getParameters() { return params; }; + final private List params = ( parameters == null ) ? Collections.EMPTY_LIST : parameters; + public TypeFilter getFilter() { return FUNCTION_FILTER; } + }; ParserSymbolTable.lookup( data, this ); return (IParameterizedSymbol) ParserSymbolTable.resolveAmbiguities( data ); } @@ -753,12 +787,13 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#qualifiedFunctionLookup(java.lang.String, java.util.List) */ - public IParameterizedSymbol qualifiedFunctionLookup( String name, List parameters ) throws ParserSymbolTableException{ - LookupData data = new LookupData( name, TypeInfo.t_function ); + public IParameterizedSymbol qualifiedFunctionLookup( String name, final List parameters ) throws ParserSymbolTableException{ + LookupData data = new LookupData( name ){ + public List getParameters() { return params; }; + final private List params = ( parameters == null ) ? Collections.EMPTY_LIST : parameters; + public TypeFilter getFilter() { return FUNCTION_FILTER; } + }; data.qualified = true; - //if parameters == null, thats no parameters, but we need to distinguish that from - //no parameter information at all, so make an empty list. - data.parameters = ( parameters == null ) ? Collections.EMPTY_LIST : parameters; ParserSymbolTable.lookup( data, this ); @@ -770,7 +805,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { */ public ISymbol lookupTemplateId( String name, List arguments ) throws ParserSymbolTableException { - LookupData data = new LookupData( name, TypeInfo.t_any ); + LookupData data = new LookupData( name ); ParserSymbolTable.lookup( data, this ); ISymbol found = ParserSymbolTable.resolveAmbiguities( data ); @@ -790,11 +825,15 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#lookupFunctionTemplateId(java.lang.String, java.util.List, java.util.List) */ - public ISymbol lookupFunctionTemplateId(String name, List parameters, List arguments, boolean forDefinition) throws ParserSymbolTableException { - LookupData data = new LookupData( name, TypeInfo.t_function ); + public ISymbol lookupFunctionTemplateId(String name, final List parameters, final List arguments, boolean forDefinition) throws ParserSymbolTableException { + LookupData data = new LookupData( name ){ + public List getParameters() { return params; } + public List getTemplateParameters() { return templateParams; } + public TypeFilter getFilter() { return FUNCTION_FILTER; } + final private List params = ( parameters == null ) ? Collections.EMPTY_LIST : parameters; + final private List templateParams = arguments; + }; data.exactFunctionsOnly = forDefinition; - data.parameters = parameters; - data.templateParameters = arguments; ParserSymbolTable.lookup( data, this ); ISymbol found = ParserSymbolTable.resolveAmbiguities( data ); @@ -806,16 +845,31 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#lookupTemplateIdForDefinition(java.lang.String, java.util.List) */ - public IContainerSymbol lookupTemplateIdForDefinition(String name, List arguments) throws ParserSymbolTableException { + public IContainerSymbol lookupTemplateIdForDefinition(String name, List arguments){ // TODO Auto-generated method stub return null; } - public List prefixLookup( TypeFilter filter, String prefix, boolean qualified, List paramList ) throws ParserSymbolTableException{ - LookupData data = new LookupData( prefix, filter ); + public List prefixLookup( final TypeFilter filter, String prefix, boolean qualified, final List paramList ) throws ParserSymbolTableException{ + LookupData data = new LookupData( prefix ){ + public List getParameters() { return params; } + public boolean isPrefixLookup(){ return true; } + public Set getAmbiguities(){ return ambiguities; } + public TypeFilter getFilter() { return typeFilter; } + + public void addAmbiguity( String name ){ + if( ambiguities == Collections.EMPTY_SET ){ + ambiguities = new HashSet(); + } + ambiguities.add( name ); + } + + final private List params = paramList; + private Set ambiguities = Collections.EMPTY_SET; + final private TypeFilter typeFilter = filter; + }; + data.qualified = qualified; - data.mode = ParserSymbolTable.LookupMode.PREFIX; - data.parameters = paramList; ParserSymbolTable.lookup( data, this ); @@ -841,8 +895,8 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { return null; } //remove any ambiguous symbols - if( data.ambiguities != null && !data.ambiguities.isEmpty() ){ - Iterator iter = data.ambiguities.iterator(); + if( data.getAmbiguities() != null && !data.getAmbiguities().isEmpty() ){ + Iterator iter = data.getAmbiguities().iterator(); while( iter.hasNext() ){ data.foundItems.remove( iter.next() ); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/DerivableContainerSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/DerivableContainerSymbol.java index c5096a40125..419cbb42ad8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/DerivableContainerSymbol.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/DerivableContainerSymbol.java @@ -205,10 +205,13 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol#lookupConstructor(java.util.List) */ - public IParameterizedSymbol lookupConstructor( List parameters ) throws ParserSymbolTableException + public IParameterizedSymbol lookupConstructor( final List parameters ) throws ParserSymbolTableException { - LookupData data = new LookupData( ParserSymbolTable.EMPTY_NAME, TypeInfo.t_constructor ); - data.parameters = parameters; + LookupData data = new LookupData( ParserSymbolTable.EMPTY_NAME ){ + public List getParameters() { return params; } + public TypeFilter getFilter() { return CONSTRUCTOR_FILTER; } + final private List params = parameters; + }; List constructors = null; if( !getConstructors().isEmpty() ){ @@ -256,7 +259,7 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva //of function will have them from the original declaration boolean foundThis = false; - LookupData data = new LookupData( ParserSymbolTable.THIS, TypeInfo.t_any ); + LookupData data = new LookupData( ParserSymbolTable.THIS ); try { Map map = ParserSymbolTable.lookupInContained( data, obj ); foundThis = ( map != null ) ? map.containsKey( data.name ) : false; @@ -339,8 +342,6 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva * class scope. */ public ISymbol lookupForFriendship( String name ) throws ParserSymbolTableException{ - LookupData data = new LookupData( name, TypeInfo.t_any ); - IContainerSymbol enclosing = getContainingSymbol(); if( enclosing != null && enclosing.isType( TypeInfo.t_namespace, TypeInfo.t_union ) ){ while( enclosing != null && ( enclosing.getType() != TypeInfo.t_namespace) ) @@ -348,17 +349,20 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva enclosing = enclosing.getContainingSymbol(); } } - data.stopAt = enclosing; - data.returnInvisibleSymbols = true; - + + final ISymbol finalEnc = enclosing; + LookupData data = new LookupData( name ){ + public ISymbol getStopAt() { return stopAt; } + public boolean shouldReturnInvisibleSymbols() { return true; } + final private ISymbol stopAt = finalEnc; + }; + ParserSymbolTable.lookup( data, this ); return ParserSymbolTable.resolveAmbiguities( data ); } - public IParameterizedSymbol lookupFunctionForFriendship( String name, List parameters ) throws ParserSymbolTableException{ - LookupData data = new LookupData( name, TypeInfo.t_any ); - - data.parameters = parameters; + public IParameterizedSymbol lookupFunctionForFriendship( String name, final List parameters ) throws ParserSymbolTableException{ + IContainerSymbol enclosing = getContainingSymbol(); if( enclosing != null && enclosing.isType( TypeInfo.t_namespace, TypeInfo.t_union ) ){ @@ -367,7 +371,13 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva enclosing = enclosing.getContainingSymbol(); } } - data.stopAt = enclosing; + final ISymbol finalEnc = enclosing; + LookupData data = new LookupData( name ){ + public List getParameters() { return params; } + public ISymbol getStopAt() { return stopAt; } + final private List params = parameters; + final ISymbol stopAt = finalEnc; + }; ParserSymbolTable.lookup( data, this ); return (IParameterizedSymbol) ParserSymbolTable.resolveAmbiguities( data ); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java index 2e4416a7a25..6dfd8af9006 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java @@ -25,7 +25,6 @@ import java.util.Map; import java.util.Set; import java.util.SortedMap; -import org.eclipse.cdt.core.parser.Enum; import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ParserMode; import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility; @@ -169,7 +168,7 @@ public class ParserSymbolTable { } } - if( data.mode == LookupMode.NORMAL && ( ( data.foundItems != null && !data.foundItems.isEmpty()) || data.stopAt == inSymbol ) ){ + if( !data.isPrefixLookup() && ( ( data.foundItems != null && !data.foundItems.isEmpty()) || data.getStopAt() == inSymbol ) ){ return; } @@ -186,7 +185,7 @@ public class ParserSymbolTable { } //if still not found, check our containing scope. - if( ( data.foundItems == null || data.foundItems.isEmpty() || data.mode == LookupMode.PREFIX ) + if( ( data.foundItems == null || data.foundItems.isEmpty() || data.isPrefixLookup() ) && inSymbol.getContainingSymbol() != null ) { if( data.qualified ){ @@ -261,7 +260,7 @@ public class ParserSymbolTable { //only consider the transitive using directives if we are an unqualified //lookup, or we didn't find the name in decl - if( (!data.qualified || !foundSomething || data.mode == LookupMode.PREFIX ) && temp.hasUsingDirectives() ){ + if( (!data.qualified || !foundSomething || data.isPrefixLookup() ) && temp.hasUsingDirectives() ){ //name wasn't found, add transitive using directives for later consideration if( transitiveDirectives == null ) transitiveDirectives = new ArrayList(4); @@ -317,15 +316,15 @@ public class ParserSymbolTable { Object obj = null; - if( data.associated != null ){ + if( data.getAssociated() != null ){ //we are looking in lookIn, remove it from the associated scopes list - data.associated.remove( lookIn ); + data.getAssociated().remove( lookIn ); } Map declarations = lookIn.getContainedSymbols(); Iterator iterator = null; - if( data.mode == LookupMode.PREFIX && declarations != Collections.EMPTY_MAP ){ + if( data.isPrefixLookup() && declarations != Collections.EMPTY_MAP ){ if( declarations instanceof SortedMap ){ iterator = ((SortedMap)declarations).tailMap( data.name.toLowerCase() ).keySet().iterator(); } else { @@ -358,7 +357,7 @@ public class ParserSymbolTable { } } - if( found != null && data.mode == LookupMode.NORMAL ){ + if( found != null && !data.isPrefixLookup() ){ return found; } @@ -413,7 +412,7 @@ public class ParserSymbolTable { Map parameters = ((IParameterizedSymbol)lookIn).getParameterMap(); if( parameters != Collections.EMPTY_MAP ){ iterator = null; - if( data.mode == LookupMode.PREFIX ){ + if( data.isPrefixLookup() ){ if( parameters instanceof SortedMap ){ iterator = ((SortedMap) parameters).tailMap( data.name.toLowerCase() ).keySet().iterator(); } else { @@ -446,18 +445,18 @@ public class ParserSymbolTable { } private static boolean nameMatches( LookupData data, String name ){ - if( data.mode == LookupMode.PREFIX ){ + if( data.isPrefixLookup() ){ return name.regionMatches( true, 0, data.name, 0, data.name.length() ); } return name.equals( data.name ); } private static boolean checkType( LookupData data, ISymbol symbol ) { //, TypeInfo.eType type, TypeInfo.eType upperType ){ - if( data.filter == null ){ + if( data.getFilter() == null ){ return true; } TypeInfo typeInfo = ParserSymbolTable.getFlatTypeInfo( symbol.getTypeInfo() ); - return data.filter.shouldAccept( symbol, typeInfo ) || data.filter.shouldAccept( symbol ); + return data.getFilter().shouldAccept( symbol, typeInfo ) || data.getFilter().shouldAccept( symbol ); } private static Object collectSymbol(LookupData data, Object object ) throws ParserSymbolTableException { @@ -510,11 +509,8 @@ public class ParserSymbolTable { } else if( foundSymbol.getTypeInfo().isForwardDeclaration() && foundSymbol.getTypeSymbol() == cls ){ //decl is a forward declaration of cls, we already have what we want (cls) } else { - if( data.mode == LookupMode.PREFIX ){ - if( data.ambiguities == null ){ - data.ambiguities = new HashSet(); - } - data.ambiguities.add( foundSymbol.getName() ); + if( data.isPrefixLookup() ){ + data.addAmbiguity( foundSymbol.getName() ); } else { throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous ); } @@ -525,11 +521,8 @@ public class ParserSymbolTable { if( obj == null ){ obj = foundSymbol; } else { - if( data.mode == LookupMode.PREFIX ){ - if( data.ambiguities == null ){ - data.ambiguities = new HashSet(); - } - data.ambiguities.add( foundSymbol.getName() ); + if( data.isPrefixLookup() ){ + data.addAmbiguity( foundSymbol.getName() ); } else { throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous ); } @@ -583,8 +576,8 @@ public class ParserSymbolTable { } if( numTemplateFunctions > 0 ){ - if( data.parameters != null && ( !data.exactFunctionsOnly || data.templateParameters != null ) ){ - List fns = TemplateEngine.selectTemplateFunctions( templateFunctionSet, data.parameters, data.templateParameters ); + if( data.getParameters() != null && ( !data.exactFunctionsOnly || data.getTemplateParameters() != null ) ){ + List fns = TemplateEngine.selectTemplateFunctions( templateFunctionSet, data.getParameters(), data.getTemplateParameters() ); if( fns != null ) functionSet.addAll( fns ); numFunctions = functionSet.size(); @@ -605,11 +598,8 @@ public class ParserSymbolTable { } if( ambiguous ){ - if( data.mode == LookupMode.PREFIX ){ - if( data.ambiguities == null ){ - data.ambiguities = new HashSet(); - } - data.ambiguities.add( foundSymbol.getName() ); + if( data.isPrefixLookup() ){ + data.addAmbiguity( foundSymbol.getName() ); } else { throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous ); } @@ -678,7 +668,7 @@ public class ParserSymbolTable { throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTypeInfo ); } - if( (temp == null || temp.isEmpty()) || data.mode == LookupMode.PREFIX ){ + if( (temp == null || temp.isEmpty()) || data.isPrefixLookup() ){ inherited = lookupInParents( data, parent ); if( temp == null ) temp = inherited; @@ -705,11 +695,8 @@ public class ParserSymbolTable { ISymbol sym = (ISymbol) (( objList != null && objListSize > 0 ) ? objList.get(0) : obj); while( sym != null ){ if( !checkAmbiguity( sym, temp.get( key ) ) ){ - if( data.mode == LookupMode.PREFIX ){ - if( data.ambiguities == null ){ - data.ambiguities = new HashSet(); - } - data.ambiguities.add( sym.getName() ); + if( data.isPrefixLookup() ){ + data.addAmbiguity( sym.getName() ); } else { throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous ); } @@ -932,7 +919,7 @@ public class ParserSymbolTable { static protected ISymbol resolveAmbiguities( LookupData data ) throws ParserSymbolTableException{ ISymbol resolvedSymbol = null; - if( data.foundItems == null || data.foundItems.isEmpty() || data.mode == LookupMode.PREFIX ){ + if( data.foundItems == null || data.foundItems.isEmpty() || data.isPrefixLookup() ){ return null; } @@ -961,7 +948,7 @@ public class ParserSymbolTable { } if( resolvedSymbol == null ){ - if( data.parameters == null ){ + if( data.getParameters() == null ){ //we have no parameter information, if we only have one function, return //that, otherwise we can't decide between them if( functionList.size() == 1){ @@ -984,7 +971,7 @@ public class ParserSymbolTable { //reduce our set of candidate functions to only those who have the right number of parameters reduceToViable( data, functions ); - if( data.exactFunctionsOnly && data.templateParameters == null ){ + if( data.exactFunctionsOnly && data.getTemplateParameters() == null ){ if( functions.size() == 1 ){ return (IParameterizedSymbol) functions.get( 0 ); } else if( functions.size() == 0 ){ @@ -994,7 +981,7 @@ public class ParserSymbolTable { } } - int numSourceParams = ( data.parameters == null ) ? 0 : data.parameters.size(); + int numSourceParams = ( data.getParameters() == null ) ? 0 : data.getParameters().size(); int numFns = functions.size(); if( numSourceParams == 0 ){ @@ -1015,7 +1002,7 @@ public class ParserSymbolTable { } } - if( data.parameters == null ) + if( data.getParameters() == null ) throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous ); } @@ -1046,7 +1033,7 @@ public class ParserSymbolTable { sourceParameters.add( new TypeInfo( TypeInfo.t_void, 0, null ) ); numSourceParams = 1; } else { - sourceParameters = data.parameters; + sourceParameters = data.getParameters(); } for( int fnIdx = 0; fnIdx < numFns; fnIdx++ ){ @@ -1125,7 +1112,7 @@ public class ParserSymbolTable { hasWorse = true; hasBetter = false; - if( data.mode == LookupMode.PREFIX ){ + if( data.isPrefixLookup() ){ //for prefix lookup, just remove from the function list those functions //that don't fit the parameters functions.remove( fnIdx-- ); @@ -1148,7 +1135,7 @@ public class ParserSymbolTable { } //during a prefix lookup, we don't need to rank the functions - if( data.mode == LookupMode.PREFIX ) + if( data.isPrefixLookup() ) continue; //If function has a parameter match that is better than the current best, @@ -1174,12 +1161,12 @@ public class ParserSymbolTable { } //we prefer normal functions over template functions, unless we specified template arguments else if( bestIsTemplate && !currIsTemplate ){ - if( data.templateParameters == null ) + if( data.getTemplateParameters() == null ) hasBetter = true; else ambiguous = false; } else if( !bestIsTemplate && currIsTemplate ){ - if( data.templateParameters == null ) + if( data.getTemplateParameters() == null ) ambiguous = false; else hasBetter = true; @@ -1221,10 +1208,10 @@ public class ParserSymbolTable { } static private void reduceToViable( LookupData data, List functions ){ - int numParameters = ( data.parameters == null ) ? 0 : data.parameters.size(); + int numParameters = ( data.getParameters() == null ) ? 0 : data.getParameters().size(); int num; - if( data.mode == LookupMode.PREFIX ) + if( data.isPrefixLookup() ) { if( numParameters >= 1 ) numParameters++; @@ -1255,7 +1242,7 @@ public class ParserSymbolTable { //if there are m arguments in the list, all candidate functions having m parameters //are viable if( num == numParameters ){ - if( data.exactFunctionsOnly && !functionHasParameters( function, data.parameters ) ){ + if( data.exactFunctionsOnly && !functionHasParameters( function, data.getParameters() ) ){ functions.remove( i-- ); size--; } @@ -1268,7 +1255,7 @@ public class ParserSymbolTable { continue; } else if( numParameters == 1 && num == 0 ){ - TypeInfo paramType = (TypeInfo) data.parameters.iterator().next(); + TypeInfo paramType = (TypeInfo) data.getParameters().iterator().next(); if( paramType.isType( TypeInfo.t_void ) ) continue; } @@ -1286,7 +1273,7 @@ public class ParserSymbolTable { //a candidate function having more than m parameters is viable only if the (m+1)-st //parameter has a default argument else { - if( data.mode == LookupMode.PREFIX ){ + if( data.isPrefixLookup() ){ //during prefix lookup, having more parameters than what is provided is ok continue; } @@ -1871,10 +1858,13 @@ public class ParserSymbolTable { throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTypeInfo ); } if( targetDecl.isType( TypeInfo.t_class, TypeInfo.t_union ) ){ - LookupData data = new LookupData( EMPTY_NAME, TypeInfo.t_constructor); - data.parameters = new ArrayList(1); - data.parameters.add( source ); + LookupData data = new LookupData( EMPTY_NAME){ + public List getParameters() { return parameters; }; + public TypeFilter getFilter() { return CONSTRUCTOR_FILTER; } + private List parameters = new ArrayList( 1 ); + }; data.forUserDefinedConversion = true; + data.getParameters().add( source ); if( targetDecl instanceof IDeferredTemplateInstance ){ targetDecl = ((IDeferredTemplateInstance)targetDecl).getTemplate().getTemplatedSymbol(); @@ -1901,10 +1891,11 @@ public class ParserSymbolTable { String name = target.toString(); if( !name.equals(EMPTY_NAME) ){ - LookupData data = new LookupData( "operator " + name, TypeInfo.t_function ); //$NON-NLS-1$ - data.parameters = Collections.EMPTY_LIST; + LookupData data = new LookupData( "operator " + name ){ //$NON-NLS-1$ + public List getParameters() { return Collections.EMPTY_LIST; }; + public TypeFilter getFilter() { return FUNCTION_FILTER; } + }; data.forUserDefinedConversion = true; - data.foundItems = lookupInContained( data, (IContainerSymbol) sourceDecl ); conversion = (data.foundItems != null ) ? (IParameterizedSymbol)resolveAmbiguities( data ) : null; } @@ -2112,33 +2103,18 @@ public class ParserSymbolTable { // } - static public class LookupMode extends Enum{ - public static final LookupMode PREFIX = new LookupMode( 1 ); - public static final LookupMode NORMAL = new LookupMode( 2 ); - - private LookupMode( int constant) - { - super( constant ); - } - } - static protected class LookupData { protected static final TypeFilter ANY_FILTER = new TypeFilter( TypeInfo.t_any ); - public Set ambiguities; + protected static final TypeFilter CONSTRUCTOR_FILTER = new TypeFilter( TypeInfo.t_constructor ); + protected static final TypeFilter FUNCTION_FILTER = new TypeFilter( TypeInfo.t_function ); + public String name; public Map usingDirectives; public Set visited = new HashSet(); //used to ensure we don't visit things more than once - - public HashSet inheritanceChain; //used to detect circular inheritance - - public List parameters; //parameter info for resolving functions - public List templateParameters; //template parameters - public HashSet associated; //associated namespaces for argument dependant lookup - public ISymbol stopAt; //stop looking along the stack once we hit this declaration - public TypeFilter filter = null; - public ISymbol templateMember; //to assit with template member defs + public HashSet inheritanceChain; //used to detect circular inheritance + public ISymbol templateMember; //to assit with template member defs public boolean qualified = false; public boolean ignoreUsingDirectives = false; @@ -2149,18 +2125,22 @@ public class ParserSymbolTable { public Map foundItems = null; - public LookupMode mode = LookupMode.NORMAL; - - public LookupData( String n, TypeInfo.eType t ){ + public LookupData( String n ){ name = n; - if( t == TypeInfo.t_any ) filter = ANY_FILTER; - else filter = new TypeFilter( t ); - } - public LookupData( String n, TypeFilter f ) { - name = n; - filter = ( f != null ) ? f : ANY_FILTER; } + + //the following function are optionally overloaded by anonymous classes deriving from + //this LookupData + public boolean isPrefixLookup(){ return false;} //prefix lookup + public Set getAmbiguities() { return null; } + public void addAmbiguity(String name) { } + public List getParameters() { return null; } //parameter info for resolving functions + public HashSet getAssociated() { return null; } //associated namespaces for argument dependant lookup + public ISymbol getStopAt() { return null; } //stop looking along the stack once we hit this declaration + public List getTemplateParameters() { return null; } //template parameters + public TypeFilter getFilter() { return ANY_FILTER; } } + static protected class Cost {