diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java index 7abf5452052..462518b8974 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java @@ -14,7 +14,6 @@ package org.eclipse.cdt.core.parser.tests; import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import java.util.Map; import junit.framework.TestCase; @@ -44,6 +43,7 @@ import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTableException; import org.eclipse.cdt.internal.core.parser.pst.StandardSymbolExtension; import org.eclipse.cdt.internal.core.parser.pst.TypeFilter; import org.eclipse.cdt.internal.core.parser.pst.TypeInfoProvider; +import org.eclipse.cdt.internal.core.parser.scanner2.ObjectMap; @@ -89,13 +89,12 @@ public class ParserSymbolTableTest extends TestCase { IContainerSymbol compUnit = table.getCompilationUnit(); compUnit.addSymbol( x ); - Map declarations = compUnit.getContainedSymbols(); + ObjectMap declarations = compUnit.getContainedSymbols(); assertEquals( 1, declarations.size() ); - Iterator iter = declarations.values().iterator(); - ISymbol contained = (ISymbol) iter.next(); + ISymbol contained = (ISymbol) declarations.getAt( 0 ); - assertEquals( false, iter.hasNext() ); + assertEquals( declarations.size(), 1 ); assertEquals( x, contained ); assertEquals( contained.getName(), "x" ); //$NON-NLS-1$ assertEquals( table.getTypeInfoProvider().numAllocated(), 0 ); @@ -3445,74 +3444,74 @@ public class ParserSymbolTableTest extends TestCase { assertEquals( table.getTypeInfoProvider().numAllocated(), 0 ); } - public void testBug52111RemoveSymbol() throws Exception{ - newTable(); - - IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", ITypeInfo.t_class ); //$NON-NLS-1$ - table.getCompilationUnit().addSymbol( A ); - - ISymbol i = table.newSymbol( "i", ITypeInfo.t_int ); //$NON-NLS-1$ - A.addSymbol( i ); - - IParameterizedSymbol f1 = table.newParameterizedSymbol( "f", ITypeInfo.t_function ); //$NON-NLS-1$ - A.addSymbol( f1 ); - - IParameterizedSymbol f2 = table.newParameterizedSymbol( "f", ITypeInfo.t_function ); //$NON-NLS-1$ - f2.addParameter( ITypeInfo.t_int, 0, null, false ); - - A.addSymbol( f2 ); - - IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B", ITypeInfo.t_class ); //$NON-NLS-1$ - B.addParent( A ); - - table.getCompilationUnit().addSymbol( B ); - - ISymbol look = B.qualifiedLookup( "i" ); //$NON-NLS-1$ - assertEquals( look, i ); - - Iterator iter = A.getContentsIterator(); - assertEquals( iter.next(), i ); - assertEquals( iter.next(), f1 ); - assertEquals( iter.next(), f2 ); - assertFalse( iter.hasNext() ); - - assertTrue( A.removeSymbol( i ) ); - - iter = A.getContentsIterator(); - assertEquals( iter.next(), f1 ); - assertEquals( iter.next(), f2 ); - assertFalse( iter.hasNext() ); - - look = B.qualifiedLookup( "i" ); //$NON-NLS-1$ - assertNull( look ); - - List params = new ArrayList(); - - look = B.qualifiedFunctionLookup( "f", params ); //$NON-NLS-1$ - assertEquals( look, f1 ); - - assertTrue( A.removeSymbol( f1 ) ); - iter = A.getContentsIterator(); - assertEquals( iter.next(), f2 ); - assertFalse( iter.hasNext() ); - - look = B.qualifiedFunctionLookup( "f", params ); //$NON-NLS-1$ - assertNull( look ); - - params.add( TypeInfoProvider.newTypeInfo( ITypeInfo.t_int, 0, null ) ); - look = B.qualifiedFunctionLookup( "f", params ); //$NON-NLS-1$ - - assertEquals( look, f2 ); - assertTrue( A.removeSymbol( f2 ) ); - - iter = A.getContentsIterator(); - assertFalse( iter.hasNext() ); - - look = B.qualifiedFunctionLookup( "f", params ); //$NON-NLS-1$ - assertNull( look ); - - assertEquals( A.getContainedSymbols().size(), 0 ); - assertEquals( table.getTypeInfoProvider().numAllocated(), 0 ); - } +// public void testBug52111RemoveSymbol() throws Exception{ +// newTable(); +// +// IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", ITypeInfo.t_class ); //$NON-NLS-1$ +// table.getCompilationUnit().addSymbol( A ); +// +// ISymbol i = table.newSymbol( "i", ITypeInfo.t_int ); //$NON-NLS-1$ +// A.addSymbol( i ); +// +// IParameterizedSymbol f1 = table.newParameterizedSymbol( "f", ITypeInfo.t_function ); //$NON-NLS-1$ +// A.addSymbol( f1 ); +// +// IParameterizedSymbol f2 = table.newParameterizedSymbol( "f", ITypeInfo.t_function ); //$NON-NLS-1$ +// f2.addParameter( ITypeInfo.t_int, 0, null, false ); +// +// A.addSymbol( f2 ); +// +// IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B", ITypeInfo.t_class ); //$NON-NLS-1$ +// B.addParent( A ); +// +// table.getCompilationUnit().addSymbol( B ); +// +// ISymbol look = B.qualifiedLookup( "i" ); //$NON-NLS-1$ +// assertEquals( look, i ); +// +// Iterator iter = A.getContentsIterator(); +// assertEquals( iter.next(), i ); +// assertEquals( iter.next(), f1 ); +// assertEquals( iter.next(), f2 ); +// assertFalse( iter.hasNext() ); +// +// assertTrue( A.removeSymbol( i ) ); +// +// iter = A.getContentsIterator(); +// assertEquals( iter.next(), f1 ); +// assertEquals( iter.next(), f2 ); +// assertFalse( iter.hasNext() ); +// +// look = B.qualifiedLookup( "i" ); //$NON-NLS-1$ +// assertNull( look ); +// +// List params = new ArrayList(); +// +// look = B.qualifiedFunctionLookup( "f", params ); //$NON-NLS-1$ +// assertEquals( look, f1 ); +// +// assertTrue( A.removeSymbol( f1 ) ); +// iter = A.getContentsIterator(); +// assertEquals( iter.next(), f2 ); +// assertFalse( iter.hasNext() ); +// +// look = B.qualifiedFunctionLookup( "f", params ); //$NON-NLS-1$ +// assertNull( look ); +// +// params.add( TypeInfoProvider.newTypeInfo( ITypeInfo.t_int, 0, null ) ); +// look = B.qualifiedFunctionLookup( "f", params ); //$NON-NLS-1$ +// +// assertEquals( look, f2 ); +// assertTrue( A.removeSymbol( f2 ) ); +// +// iter = A.getContentsIterator(); +// assertFalse( iter.hasNext() ); +// +// look = B.qualifiedFunctionLookup( "f", params ); //$NON-NLS-1$ +// assertNull( look ); +// +// assertEquals( A.getContainedSymbols().size(), 0 ); +// assertEquals( table.getTypeInfoProvider().numAllocated(), 0 ); +// } } 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 b2fed035e38..3ffe56b26c1 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 @@ -22,7 +22,6 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; -import java.util.ListIterator; import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; @@ -32,6 +31,8 @@ import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility; import org.eclipse.cdt.core.parser.ast.IASTMember; import org.eclipse.cdt.core.parser.ast.IASTNode; import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.LookupData; +import org.eclipse.cdt.internal.core.parser.scanner2.ObjectMap; +import org.eclipse.cdt.internal.core.parser.scanner2.ObjectSet; /** * @author aniefer @@ -53,7 +54,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { ContainerSymbol copy = (ContainerSymbol)super.clone(); copy._usingDirectives = (_usingDirectives != Collections.EMPTY_LIST) ? (List) ((ArrayList)_usingDirectives).clone() : _usingDirectives; - copy._containedSymbols = ( _containedSymbols != Collections.EMPTY_MAP )? (Map)((HashMap) _containedSymbols).clone() : _containedSymbols; + copy._containedSymbols = (ObjectMap) ( ( _containedSymbols != ObjectMap.EMPTY_MAP )? _containedSymbols.clone() : _containedSymbols ); copy._contents = (_contents != Collections.EMPTY_LIST) ? (List) ((ArrayList)_contents).clone() : _contents; return copy; @@ -242,41 +243,41 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { // getSymbolTable().pushCommand( command ); } - public boolean removeSymbol( ISymbol symbol ){ - boolean removed = false; - - Map contained = getContainedSymbols(); - - if( symbol != null && contained.containsKey( symbol.getName() ) ){ - Object obj = contained.get( symbol.getName() ); - if( obj instanceof ISymbol ){ - if( obj == symbol ){ - contained.remove( symbol.getName() ); - removed = true; - } - } else if ( obj instanceof List ){ - List list = (List) obj; - if( list.remove( symbol ) ){ - if( list.size() == 1 ){ - contained.put( symbol.getName(), list.get( 0 ) ); - } - removed = true; - } - } - } - - if( removed ){ - ListIterator iter = getContents().listIterator( getContents().size() ); - while( iter.hasPrevious() ){ - if( iter.previous() == symbol ){ - iter.remove(); - break; - } - } - } - - return removed; - } +// public boolean removeSymbol( ISymbol symbol ){ +// boolean removed = false; +// +// StringObjectMap contained = getContainedSymbols(); +// +// if( symbol != null && contained.containsKey( symbol.getName() ) ){ +// Object obj = contained.get( symbol.getName() ); +// if( obj instanceof ISymbol ){ +// if( obj == symbol ){ +// contained.remove( symbol.getName() ); +// removed = true; +// } +// } else if ( obj instanceof List ){ +// List list = (List) obj; +// if( list.remove( symbol ) ){ +// if( list.size() == 1 ){ +// contained.put( symbol.getName(), list.get( 0 ) ); +// } +// removed = true; +// } +// } +// } +// +// if( removed ){ +// ListIterator iter = getContents().listIterator( getContents().size() ); +// while( iter.hasPrevious() ){ +// if( iter.previous() == symbol ){ +// iter.remove(); +// break; +// } +// } +// } +// +// return removed; +// } /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#hasUsingDirectives() @@ -422,13 +423,13 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#getContainedSymbols() */ - public Map getContainedSymbols(){ + public ObjectMap getContainedSymbols(){ return _containedSymbols; } protected void putInContainedSymbols( String key, Object obj ){ - if( _containedSymbols == Collections.EMPTY_MAP ){ - _containedSymbols = new HashMap( ); + if( _containedSymbols == ObjectMap.EMPTY_MAP ){ + _containedSymbols = new ObjectMap( 4 ); } _containedSymbols.put( key, obj ); } @@ -667,7 +668,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { 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 - final HashSet associated = new HashSet(); + final ObjectSet associated = new ObjectSet(0); //collect associated namespaces & classes. int size = ( parameters == null ) ? 0 : parameters.size(); @@ -699,11 +700,11 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { } LookupData data = new LookupData( name ){ - public HashSet getAssociated() { return assoc; } - public List getParameters() { return params; } - public TypeFilter getFilter() { return FUNCTION_FILTER; } + public ObjectSet getAssociated() { return assoc; } + public List getParameters() { return params; } + public TypeFilter getFilter() { return FUNCTION_FILTER; } - final private HashSet assoc = associated; + final private ObjectSet assoc = associated; final private List params = ( parameters == null ) ? Collections.EMPTY_LIST : parameters; }; @@ -722,13 +723,13 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { //dump the hash to an array and iterate over the array because we //could be removing items from the collection as we go and we don't //want to get ConcurrentModificationExceptions - Object [] scopes = associated.toArray(); + Object [] scopes = associated.keyArray(); size = associated.size(); for( int i = 0; i < size; i++ ){ associatedScope = (IContainerSymbol) scopes[ i ]; - if( associated.contains( associatedScope ) ){ + if( associated.containsKey( associatedScope ) ){ data.qualified = true; data.ignoreUsingDirectives = true; data.usingDirectivesOnly = false; @@ -1191,7 +1192,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { private List _contents = Collections.EMPTY_LIST; //ordered list of all contents of this symbol private List _usingDirectives = Collections.EMPTY_LIST; //collection of nominated namespaces - private Map _containedSymbols = Collections.EMPTY_MAP; //declarations contained by us. + private ObjectMap _containedSymbols = ObjectMap.EMPTY_MAP; //declarations contained by us. /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#addTemplateId(org.eclipse.cdt.internal.core.parser.pst.ISymbol, java.util.List) */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IContainerSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IContainerSymbol.java index 3b7395d2674..5c0b8830618 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IContainerSymbol.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IContainerSymbol.java @@ -15,8 +15,8 @@ package org.eclipse.cdt.internal.core.parser.pst; import java.util.Iterator; import java.util.List; -import java.util.Map; +import org.eclipse.cdt.internal.core.parser.scanner2.ObjectMap; /** * @author aniefer @@ -40,7 +40,7 @@ public interface IContainerSymbol extends ISymbol { public void addTemplateId( ISymbol symbol, List args ) throws ParserSymbolTableException; - public boolean removeSymbol( ISymbol symbol ); +// public boolean removeSymbol( ISymbol symbol ); public boolean hasUsingDirectives(); public List getUsingDirectives(); @@ -73,7 +73,7 @@ public interface IContainerSymbol extends ISymbol { public IUsingDeclarationSymbol addUsingDeclaration( String name ) throws ParserSymbolTableException; public IUsingDeclarationSymbol addUsingDeclaration( String name, IContainerSymbol declContext ) throws ParserSymbolTableException; - public Map getContainedSymbols(); + public ObjectMap getContainedSymbols(); /** * Lookup symbols matching the given prefix 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 8988d6b1a11..134f9159e32 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 @@ -16,7 +16,6 @@ package org.eclipse.cdt.internal.core.parser.pst; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; @@ -31,6 +30,8 @@ import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility; import org.eclipse.cdt.core.parser.ast.IASTMember; import org.eclipse.cdt.core.parser.ast.IASTNode; import org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol.IParentSymbol; +import org.eclipse.cdt.internal.core.parser.scanner2.ObjectSet; +import org.eclipse.cdt.internal.core.parser.scanner2.ObjectMap; /** * @author aniefer @@ -247,8 +248,8 @@ public class ParserSymbolTable { temp = (IContainerSymbol) directives.get(i); //namespaces are searched at most once - if( !data.visited.contains( temp ) ){ - data.visited.add( temp ); + if( !data.visited.containsKey( temp ) ){ + data.visited.put( temp ); Map map = lookupInContained( data, temp ); foundSomething = ( map != null && !map.isEmpty() ); @@ -322,18 +323,19 @@ public class ParserSymbolTable { data.getAssociated().remove( lookIn ); } - Map declarations = lookIn.getContainedSymbols(); + ObjectMap declarations = lookIn.getContainedSymbols(); - Iterator iterator = null; + int numKeys = -1; + int idx = 0; if( data.isPrefixLookup() && declarations != Collections.EMPTY_MAP ){ - iterator = declarations.keySet().iterator(); + numKeys = declarations.size();//iterator = declarations.keySet().iterator(); } - String name = ( iterator != null && iterator.hasNext() ) ? (String) iterator.next() : data.name; + String name = ( numKeys > 0 ) ? (String) declarations.keyAt( idx++ ) : data.name; while( name != null ) { if( nameMatches( data, name ) ){ - obj = ( !declarations.isEmpty() ) ? declarations.get( name ) : null; + obj = ( declarations.size() > 0 ) ? declarations.get( name ) : null; if( obj != null ){ obj = collectSymbol( data, obj ); @@ -348,12 +350,10 @@ public class ParserSymbolTable { } } } - - if( iterator != null && iterator.hasNext() ){ - name = (String) iterator.next(); - } else { - name = null; - } + if( idx < numKeys ) + name = (String) declarations.keyAt( idx++ ); + else + name = null; } if( found != null && data.isPrefixLookup() ) found = new LinkedHashMap( found ); @@ -478,8 +478,8 @@ public class ParserSymbolTable { int objListSize = ( objList != null ) ? objList.size() : 0; ISymbol symbol = ( objList != null ) ? (ISymbol) objList.get( 0 ) : (ISymbol) object; - Set functionSet = new HashSet(); - Set templateFunctionSet = new HashSet(); + ObjectSet functionSet = ObjectSet.EMPTY_SET; + ObjectSet templateFunctionSet = ObjectSet.EMPTY_SET; ISymbol obj = null; IContainerSymbol cls = null; @@ -500,9 +500,13 @@ public class ParserSymbolTable { foundSymbol = foundSymbol.getForwardSymbol(); } if( foundSymbol.getContainingSymbol().isType( ITypeInfo.t_template ) ){ - templateFunctionSet.add( foundSymbol ); + if( templateFunctionSet == ObjectSet.EMPTY_SET ) + templateFunctionSet = new ObjectSet( 2 ); + templateFunctionSet.put( foundSymbol ); } else { - functionSet.add( foundSymbol ); + if( functionSet == ObjectSet.EMPTY_SET ) + functionSet = new ObjectSet( 2 ); + functionSet.put( foundSymbol ); } } else { @@ -561,24 +565,19 @@ public class ParserSymbolTable { ambiguous = true; } - Iterator fnIter = null; IParameterizedSymbol fn = null; - if( !templateFunctionSet.isEmpty() ){ - fnIter = templateFunctionSet.iterator(); - - for( int i = numTemplateFunctions; i > 0; i-- ){ - fn = (IParameterizedSymbol) fnIter.next(); + if( numTemplateFunctions > 0 ){ + for( int i = 0; i < numTemplateFunctions; i++ ){ + fn = (IParameterizedSymbol) templateFunctionSet.keyAt( i ); if( cls.getContainingSymbol()!= fn.getContainingSymbol()){ ambiguous = true; break; } } } - if( !functionSet.isEmpty() ){ - fnIter = functionSet.iterator(); - - for( int i = numFunctions; i > 0; i-- ){ - fn = (IParameterizedSymbol) fnIter.next(); + if( numFunctions > 0 ){ + for( int i = 0; i < numFunctions; i++ ){ + fn = (IParameterizedSymbol) functionSet.keyAt( i ); if( cls.getContainingSymbol()!= fn.getContainingSymbol()){ ambiguous = true; break; @@ -590,10 +589,15 @@ public class ParserSymbolTable { if( numTemplateFunctions > 0 ){ if( data.getParameters() != null && ( !data.exactFunctionsOnly || data.getTemplateParameters() != null ) ){ List fns = TemplateEngine.selectTemplateFunctions( templateFunctionSet, data.getParameters(), data.getTemplateParameters() ); - if( fns != null ) + if( fns != null ){ + if( functionSet == ObjectSet.EMPTY_SET ) + functionSet = new ObjectSet( fns.size() ); functionSet.addAll( fns ); + } numFunctions = functionSet.size(); } else { + if( functionSet == ObjectSet.EMPTY_SET ) + functionSet = new ObjectSet( templateFunctionSet.size() ); functionSet.addAll( templateFunctionSet ); numFunctions += numTemplateFunctions; } @@ -606,7 +610,7 @@ public class ParserSymbolTable { return obj; } } else if( numFunctions > 0 ) { - return new ArrayList( functionSet ); + return functionSet.toList(); } if( ambiguous ){ @@ -648,9 +652,9 @@ public class ParserSymbolTable { //use data to detect circular inheritance if( data.inheritanceChain == null ) - data.inheritanceChain = new HashSet(); + data.inheritanceChain = new ObjectSet( 2 ); - data.inheritanceChain.add( container ); + data.inheritanceChain.put( container ); int size = scopes.size(); for( int i = 0; i < size; i++ ) @@ -660,9 +664,9 @@ public class ParserSymbolTable { if( parent == null ) continue; - if( !wrapper.isVirtual() || !data.visited.contains( parent ) ){ + if( !wrapper.isVirtual() || !data.visited.containsKey( parent ) ){ if( wrapper.isVirtual() ){ - data.visited.add( parent ); + data.visited.put( parent ); } if( parent instanceof IDeferredTemplateInstance ){ @@ -673,7 +677,7 @@ public class ParserSymbolTable { //if the inheritanceChain already contains the parent, then that //is circular inheritance - if( ! data.inheritanceChain.contains( parent ) ){ + if( ! data.inheritanceChain.containsKey( parent ) ){ //is this name define in this scope? if( parent instanceof IDerivableContainerSymbol ){ temp = lookupInContained( data, (IDerivableContainerSymbol) parent ); @@ -1383,7 +1387,7 @@ public class ParserSymbolTable { temp = ((IUsingDirectiveSymbol) directives.get(i)).getNamespace(); //namespaces are searched at most once - if( !data.visited.contains( temp ) ){ + if( !data.visited.containsKey( temp ) ){ enclosing = getClosestEnclosingDeclaration( symbol, temp ); //the data.usingDirectives is a map from enclosing declaration to @@ -1494,7 +1498,7 @@ public class ParserSymbolTable { return -1; } - static protected void getAssociatedScopes( ISymbol symbol, HashSet associated ){ + static protected void getAssociatedScopes( ISymbol symbol, ObjectSet associated ){ if( symbol == null ){ return; } @@ -1503,19 +1507,19 @@ public class ParserSymbolTable { //namespaces in which its associated classes are defined //if( symbol.getType() == TypeInfo.t_class ){ if( symbol instanceof IDerivableContainerSymbol ){ - associated.add( symbol ); - associated.add( symbol.getContainingSymbol() ); + associated.put( symbol ); + associated.put( symbol.getContainingSymbol() ); getBaseClassesAndContainingNamespaces( (IDerivableContainerSymbol) symbol, associated ); } //if T is a union or enumeration type, its associated namespace is the namespace in //which it is defined. if it is a class member, its associated class is the member's //class else if( symbol.getType() == ITypeInfo.t_union || symbol.getType() == ITypeInfo.t_enumeration ){ - associated.add( symbol.getContainingSymbol() ); + associated.put( symbol.getContainingSymbol() ); } } - static private void getBaseClassesAndContainingNamespaces( IDerivableContainerSymbol obj, HashSet classes ){ + static private void getBaseClassesAndContainingNamespaces( IDerivableContainerSymbol obj, ObjectSet classes ){ if( obj.getParents() != null ){ if( classes == null ){ return; @@ -1531,9 +1535,9 @@ public class ParserSymbolTable { base = wrapper.getParent(); //TODO: what about IDeferredTemplateInstance parents? if( base instanceof IDerivableContainerSymbol ){ - classes.add( base ); + classes.put( base ); if( base.getContainingSymbol().getType() == ITypeInfo.t_namespace ){ - classes.add( base.getContainingSymbol()); + classes.put( base.getContainingSymbol()); } getBaseClassesAndContainingNamespaces( (IDerivableContainerSymbol) base, classes ); @@ -2221,8 +2225,8 @@ public class ParserSymbolTable { 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 ObjectSet visited = new ObjectSet(0); //used to ensure we don't visit things more than once + public ObjectSet inheritanceChain; //used to detect circular inheritance public ISymbol templateMember; //to assit with template member defs public boolean qualified = false; @@ -2244,7 +2248,7 @@ public class ParserSymbolTable { public Set getAmbiguities() { return null; } public void addAmbiguity(String n ) { /*nothing*/ } public List getParameters() { return null; } //parameter info for resolving functions - public HashSet getAssociated() { return null; } //associated namespaces for argument dependant lookup + public ObjectSet 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; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/SpecializedSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/SpecializedSymbol.java index 32828a2553d..fc0f7a832e6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/SpecializedSymbol.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/SpecializedSymbol.java @@ -16,7 +16,6 @@ package org.eclipse.cdt.internal.core.parser.pst; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; @@ -101,8 +100,7 @@ public class SpecializedSymbol extends TemplateSymbol implements ISpecializedSym IContainerSymbol symbol = null; if( getContainedSymbols().size() == 1 ){ - Iterator iter = getContainedSymbols().keySet().iterator(); - symbol = (IContainerSymbol)getContainedSymbols().get( iter.next() ); + symbol = (IContainerSymbol)getContainedSymbols().getAt( 0 ); } instance = (IContainerSymbol) symbol.instantiate( this, argMap ); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateEngine.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateEngine.java index 330350b798c..86bf63baf92 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateEngine.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateEngine.java @@ -20,6 +20,7 @@ import java.util.Set; import org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol.IParentSymbol; import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.Cost; +import org.eclipse.cdt.internal.core.parser.scanner2.ObjectSet; /** * @author aniefer @@ -891,16 +892,17 @@ public final class TemplateEngine { return info; } - static protected List selectTemplateFunctions( Set templates, List functionArguments, List templateArguments ) throws ParserSymbolTableException{ + static protected List selectTemplateFunctions( ObjectSet templates, List functionArguments, List templateArguments ) throws ParserSymbolTableException{ if( templates == null || templates.size() == 0 ) return null; List instances = null; - Iterator iter = templates.iterator(); + //Iterator iter = templates.iterator(); + int size = templates.size(); - outer: while( iter.hasNext() ){ - IParameterizedSymbol fn = (IParameterizedSymbol) iter.next(); + outer: for( int idx = 0; idx < size; idx++ ){ + IParameterizedSymbol fn = (IParameterizedSymbol) templates.keyAt( idx ); ITemplateSymbol template = (ITemplateSymbol) fn.getContainingSymbol(); Map map = deduceTemplateArguments( template, functionArguments ); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateFactory.java index 974078ca1be..b01c2f733b2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateFactory.java @@ -21,6 +21,7 @@ import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility; import org.eclipse.cdt.internal.core.parser.ast.complete.ASTTemplateDeclaration; import org.eclipse.cdt.internal.core.parser.ast.complete.ASTTemplateInstantiation; import org.eclipse.cdt.internal.core.parser.ast.complete.ASTTemplateSpecialization; +import org.eclipse.cdt.internal.core.parser.scanner2.ObjectMap; /** * @author aniefer @@ -575,7 +576,7 @@ public class TemplateFactory extends ExtensibleSymbol implements ITemplateFactor /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#getContainedSymbols() */ - public Map getContainedSymbols() { + public ObjectMap getContainedSymbols() { return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/CharArrayMap.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/CharArrayMap.java index 1459b2ab5e2..ab3a4ad5d47 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/CharArrayMap.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/CharArrayMap.java @@ -35,7 +35,7 @@ public abstract class CharArrayMap { } private int hash(char[] buffer, int start, int len) { - return CharArrayUtils.hash(buffer, start, len) & (keyTable.length - 1); + return CharArrayUtils.hash(buffer, start, len) & (hashTable.length - 1); } private int hash(char[] buffer) { @@ -80,8 +80,12 @@ public abstract class CharArrayMap { int hash = hash(buffer, start, len); if (hashTable[hash] == 0) { - if (++currEntry >= keyTable.length) + if( (currEntry + 1) >= keyTable.length){ + //need to recompute hash for this add, recurse. resize(); + return add( buffer, start, len ); + } + currEntry++; keyTable[currEntry] = CharArrayUtils.extract(buffer, start, len); insert(currEntry, hash); return currEntry; @@ -102,8 +106,12 @@ public abstract class CharArrayMap { } // nope, add it in - if (++currEntry >= keyTable.length) + if (++currEntry >= keyTable.length){ + //need to recompute hash for this add, recurse resize(); + return add( buffer, start, len ); + } + currEntry++; keyTable[currEntry] = CharArrayUtils.extract(buffer, start, len); nextTable[last] = currEntry + 1; return currEntry; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/HashTable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/HashTable.java new file mode 100644 index 00000000000..c81c9520a28 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/HashTable.java @@ -0,0 +1,228 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +/* + * For use by the Parser Symbol Table + * Created on Jul 15, 2004 + */ +package org.eclipse.cdt.internal.core.parser.scanner2; + + +/** + * @author aniefer + */ +public abstract class HashTable implements Cloneable{ + + private Object[] keyTable; + private int[] hashTable; + private int[] nextTable; + + + protected int currEntry = -1; + + public HashTable(int initialSize) { + int size = 1; + while (size < initialSize) + size <<= 1; + + keyTable = new Object[size]; + hashTable = new int[size * 2]; + nextTable = new int[size]; + } + + public Object clone(){ + HashTable newTable = null; + try { + newTable = (HashTable) super.clone(); + } catch ( CloneNotSupportedException e ) { + //shouldn't happen because object supports clone. + return null; + } + + int size = capacity(); + newTable.keyTable = new Object[ size ]; + newTable.hashTable = new int[ size*2 ]; + newTable.nextTable = new int[ size ]; + + System.arraycopy(keyTable, 0, newTable.keyTable, 0, keyTable.length); + System.arraycopy(hashTable, 0, newTable.hashTable, 0, hashTable.length); + System.arraycopy(nextTable, 0, newTable.nextTable, 0, nextTable.length); + + newTable.currEntry = currEntry; + return newTable; + } + + public int size(){ + return currEntry + 1; + } + + public Object keyAt( int i ){ + if( i < 0 || i > currEntry ) + return null; + + return keyTable[ i ]; + } + + public void clear(){ + for( int i = 0; i < keyTable.length; i++ ){ + keyTable[i] = null; + hashTable[ 2*i ] = 0; + hashTable[ 2*i + 1 ] = 0; + nextTable[i] = 0; + } + currEntry = -1; + } + + protected int capacity() { + return keyTable.length; + } + + private int hash(Object obj) { + return obj.hashCode() & (hashTable.length - 1); + } + + private void insert(int i) { + insert(i, hash(keyTable[i])); + } + + private void insert(int i, int hash) { + + if (hashTable[hash] == 0) { + hashTable[hash] = i + 1; + } else { + // need to link + int j = hashTable[hash] - 1; + while (nextTable[j] != 0) + j = nextTable[j] - 1; + nextTable[j] = i + 1; + } + } + + protected void resize(int size) { + Object[] oldKeyTable = keyTable; + keyTable = new Object[size]; + System.arraycopy(oldKeyTable, 0, keyTable, 0, oldKeyTable.length); + + // Need to rehash everything + hashTable = new int[size * 2]; + nextTable = new int[size]; + for (int i = 0; i < oldKeyTable.length; ++i) { + insert(i); + } + } + + private void resize() { + resize(keyTable.length << 1); + } + + protected final int add(Object obj) { + int hash = hash(obj); + + if (hashTable[hash] == 0) { + if ( (currEntry + 1) >= keyTable.length){ + resize(); + //hash code needs to be recomputed, just recurse. + return add( obj ); + } + currEntry++; + keyTable[currEntry] = obj; + insert(currEntry, hash); + return currEntry; + } + // is the key already registered? + int i = hashTable[hash] - 1; + if ( obj.equals( keyTable[i] ) ) + // yup + return i; + + // follow the next chain + int last = i; + for (i = nextTable[i] - 1; i >= 0; i = nextTable[i] - 1) { + if (obj.equals( keyTable[i] ) ) + // yup this time + return i; + last = i; + } + + // nope, add it in + if ( (currEntry + 1) >= keyTable.length){ + resize(); + //hash code needs to be recomputed, just recurse. + return add( obj ); + } + currEntry++; + keyTable[currEntry] = obj; + nextTable[last] = currEntry + 1; + return currEntry; + } + + protected void removeEntry(int i) { + // Remove the hash entry + int hash = hash(keyTable[i]); + if (hashTable[hash] == i + 1) + hashTable[hash] = nextTable[i]; + else { + // find entry pointing to me + int j = hashTable[hash] - 1; + while (nextTable[j] != 0 && nextTable[j] != i + 1) + j = nextTable[j] - 1; + nextTable[j] = nextTable[i]; + } + + if (i < currEntry) { + // shift everything over + System.arraycopy(keyTable, i + 1, keyTable, i, currEntry - i); + System.arraycopy(nextTable, i + 1, nextTable, i, currEntry - i); + + // adjust hash and next entries for things that moved + for (int j = 0; j < hashTable.length; ++j) + if (hashTable[j] > i) + --hashTable[j]; + + for (int j = 0; j < nextTable.length; ++j) + if (nextTable[j] > i) + --nextTable[j]; + } + + // last entry is now free + keyTable[currEntry] = null; + nextTable[currEntry] = 0; + --currEntry; + } + + protected final int lookup(Object buffer ){ + int hash = hash(buffer); + + if (hashTable[hash] == 0) + return -1; + + int i = hashTable[hash] - 1; + if (buffer.equals( keyTable[i] ) ) + return i; + + // Follow the next chain + for (i = nextTable[i] - 1; i >= 0; i = nextTable[i] - 1) + if ( buffer.equals( keyTable[i] )) + return i; + + return -1; + } + + public boolean containsKey( Object key ){ + return lookup( key ) != -1; + } + + public Object [] keyArray(){ + Object [] keys = new Object[ size() ]; + System.arraycopy( keyTable, 0, keys, 0, keys.length ); + return keys; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ObjectMap.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ObjectMap.java new file mode 100644 index 00000000000..8d568b5478b --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ObjectMap.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +/* + * cloned from CharArrayMap & CharArrayObjectMap + * Created on Jul 14, 2004 + */ +package org.eclipse.cdt.internal.core.parser.scanner2; + + +/** + * @author aniefer + */ +public class ObjectMap extends HashTable{ + public static final ObjectMap EMPTY_MAP = new ObjectMap( 0 ){ + public Object clone() { return this; } + public Object put( Object key, Object value ) { throw new UnsupportedOperationException(); } + }; + + private Object[] valueTable; + + public ObjectMap(int initialSize) { + super( initialSize ); + + valueTable = new Object[ capacity() ]; + } + + public Object clone(){ + ObjectMap newMap = (ObjectMap) super.clone(); + + newMap.valueTable = new Object[ capacity() ]; + + System.arraycopy(valueTable, 0, newMap.valueTable, 0, valueTable.length); + return newMap; + } + + public void clear(){ + super.clear(); + for( int i = 0; i < valueTable.length; i++ ){ + valueTable[i] = null; + } + } + + protected void resize(int size) { + Object[] oldValueTable = valueTable; + valueTable = new Object[size]; + System.arraycopy(oldValueTable, 0, valueTable, 0, oldValueTable.length); + + super.resize( size ); + } + + public Object put(Object key, Object value) { + int i = add(key); + Object oldvalue = valueTable[i]; + valueTable[i] = value; + return oldvalue; + } + + public Object get(Object key) { + int i = lookup(key); + if (i >= 0) + return valueTable[i]; + return null; + } + + public Object getAt( int i ){ + if( i < 0 || i > currEntry ) + return null; + + return get( keyAt( i ) ); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ObjectSet.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ObjectSet.java new file mode 100644 index 00000000000..e7eb2c3b50e --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ObjectSet.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +/* + * Created on Jul 15, 2004 + */ +package org.eclipse.cdt.internal.core.parser.scanner2; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @author aniefer + */ +public class ObjectSet extends HashTable{ + public static final ObjectSet EMPTY_SET = new ObjectSet( 0 ){ + public Object clone() { return this; } + public List toList() { return Collections.EMPTY_LIST; } + public void put( Object key ) { throw new UnsupportedOperationException(); } + public void addAll( List list ) { throw new UnsupportedOperationException(); } + public void addAll( ObjectSet set ) { throw new UnsupportedOperationException(); } + }; + + public ObjectSet(int initialSize) { + super( initialSize ); + } + + public void put(Object key ){ + add(key); + } + + public void addAll( List list ){ + if( list == null ) + return; + + int size = list.size(); + for( int i = 0; i < size; i++ ){ + add( list.get( i ) ); + } + } + + public void addAll( ObjectSet set ){ + if( set == null ) + return; + int size = set.size(); + for( int i = 0; i < size; i++ ){ + add( set.keyAt( i ) ); + } + } + + public List toList(){ + List list = new ArrayList( size() ); + int size = size(); + for( int i = 0; i < size; i++ ){ + list.add( keyAt( i ) ); + } + return list; + } + + public boolean remove( Object key ) { + int i = lookup(key); + if (i < 0) + return false; + + removeEntry(i); + return true; + } +}