1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 22:52:11 +02:00

change CPPSemantics.lookupInParents to use new name caching mechanism

and to support prefix lookup
This commit is contained in:
Andrew Niefer 2005-03-03 23:53:46 +00:00
parent 27c8ac0ac3
commit d7ad9aef13
2 changed files with 119 additions and 60 deletions

View file

@ -191,6 +191,8 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
IASTName [] ns = ((ICPPASTQualifiedName)node).getNames(); IASTName [] ns = ((ICPPASTQualifiedName)node).getNames();
if( ns[ ns.length - 1 ] == name ) if( ns[ ns.length - 1 ] == name )
node = node.getParent(); node = node.getParent();
else
return false;
} }
if( node instanceof IASTDeclSpecifier ){ if( node instanceof IASTDeclSpecifier ){
IASTNode parent = node.getParent(); IASTNode parent = node.getParent();

View file

@ -587,37 +587,56 @@ public class CPPSemantics {
data.foundItems = ArrayUtil.addAll( Object.class, (Object[])data.foundItems, (Object[])results ); data.foundItems = ArrayUtil.addAll( Object.class, (Object[])data.foundItems, (Object[])results );
} }
} else { } else {
Object [] objs = (Object[]) results; data.foundItems = mergePrefixResults( (CharArrayObjectMap) data.foundItems, results, scoped );
CharArrayObjectMap resultMap = (CharArrayObjectMap) data.foundItems; }
if( objs != null ) { }
for( int i = 0; i < objs.length && objs[i] != null; i++ ){
char [] n = null; /**
if( objs[i] instanceof IBinding ) * @param dest
n = ((IBinding)objs[i]).getNameCharArray(); * @param source : either Object[] or CharArrayObjectMap
* @param scoped
* @return
*/
private static Object mergePrefixResults( CharArrayObjectMap dest, Object source, boolean scoped ){
if( source == null ) return dest;
CharArrayObjectMap resultMap = ( dest != null ) ? dest : new CharArrayObjectMap(2);
CharArrayObjectMap map = null;
Object [] objs = null;
if( source instanceof CharArrayObjectMap )
map = (CharArrayObjectMap) source;
else else
n = ((IASTName)objs[i]).toCharArray(); objs = ArrayUtil.trim( Object.class, (Object[]) source );
if( !resultMap.containsKey( n ) ){
resultMap.put( n, objs[i] ); int size = map != null ? map.size() : objs.length;
for( int i = 0; i < size; i ++ ) {
char [] key = ( map != null ) ? map.keyAt(i)
: ( objs[i] instanceof IBinding) ? ((IBinding)objs[i]).getNameCharArray()
: ((IASTName)objs[i]).toCharArray();
if( !resultMap.containsKey( key ) ){
resultMap.put( key, (map != null ) ? map.get( key ) : objs[i] );
} else if( !scoped ) { } else if( !scoped ) {
Object obj = resultMap.get( n ); Object obj = resultMap.get( key );
Object so = ( map != null ) ? map.get(key) : objs[i];
if( obj instanceof Object [] ) { if( obj instanceof Object [] ) {
if( objs[i] instanceof IBinding ) if( so instanceof IBinding )
obj = ArrayUtil.append( Object.class, (Object[]) obj, objs[i] ); obj = ArrayUtil.append( Object.class, (Object[]) obj, so );
else else
obj = ArrayUtil.addAll( Object.class, (Object[])obj, (Object[]) objs[i] ); obj = ArrayUtil.addAll( Object.class, (Object[])obj, (Object[]) so );
} else { } else {
if( objs[i] instanceof IBinding ) if( so instanceof IBinding )
obj = new Object [] { obj, objs[i] }; obj = new Object [] { obj, so };
else { else {
Object [] temp = new Object [ ((Object[])objs[i]).length + 1 ]; Object [] temp = new Object [ ((Object[])so).length + 1 ];
temp[0] = obj; temp[0] = obj;
obj = ArrayUtil.addAll( Object.class, temp, (Object[]) objs[i] ); obj = ArrayUtil.addAll( Object.class, temp, (Object[]) so );
}
}
} }
} }
} }
} }
return resultMap;
} }
static private void lookup( CPPSemantics.LookupData data, Object start ) throws DOMException{ static private void lookup( CPPSemantics.LookupData data, Object start ) throws DOMException{
IASTNode node = data.astName; IASTNode node = data.astName;
@ -700,12 +719,12 @@ public class CPPSemantics {
} }
} }
private static IASTName[] lookupInParents( CPPSemantics.LookupData data, ICPPClassScope lookIn ) throws DOMException{ private static Object lookupInParents( CPPSemantics.LookupData data, ICPPClassScope lookIn ) throws DOMException{
ICPPASTCompositeTypeSpecifier compositeTypeSpec = (ICPPASTCompositeTypeSpecifier) lookIn.getPhysicalNode(); ICPPASTCompositeTypeSpecifier compositeTypeSpec = (ICPPASTCompositeTypeSpecifier) lookIn.getPhysicalNode();
ICPPASTBaseSpecifier [] bases = compositeTypeSpec.getBaseSpecifiers(); ICPPASTBaseSpecifier [] bases = compositeTypeSpec.getBaseSpecifiers();
IASTName[] inherited = null; Object inherited = null;
IASTName[] result = null; Object result = null;
if( bases.length == 0 ) if( bases.length == 0 )
return null; return null;
@ -719,6 +738,7 @@ public class CPPSemantics {
int size = bases.length; int size = bases.length;
for( int i = 0; i < size; i++ ) for( int i = 0; i < size; i++ )
{ {
inherited = null;
ICPPClassType cls = null; ICPPClassType cls = null;
IBinding binding = bases[i].getName().resolveBinding(); IBinding binding = bases[i].getName().resolveBinding();
while( binding instanceof ITypedef && ((ITypedef)binding).getType() instanceof IBinding ){ while( binding instanceof ITypedef && ((ITypedef)binding).getType() instanceof IBinding ){
@ -744,10 +764,19 @@ public class CPPSemantics {
//is circular inheritance //is circular inheritance
if( ! data.inheritanceChain.containsKey( parent ) ){ if( ! data.inheritanceChain.containsKey( parent ) ){
//is this name define in this scope? //is this name define in this scope?
if( !data.prefixLookup && parent.isFullyCached() )
inherited = parent.getBinding( data.astName, true );
else
inherited = lookupInScope( data, parent, null, null ); inherited = lookupInScope( data, parent, null, null );
if( inherited == null || inherited.length == 0 ){ if( inherited == null || data.prefixLookup ){
inherited = lookupInParents( data, parent ); Object temp = lookupInParents( data, parent );
if( inherited != null ){
inherited = mergePrefixResults( null, inherited, true );
inherited = mergePrefixResults( (CharArrayObjectMap)inherited, (CharArrayObjectMap)temp, true );
} else {
inherited = temp;
}
} else { } else {
visitVirtualBaseClasses( data, cls ); visitVirtualBaseClasses( data, cls );
} }
@ -757,20 +786,40 @@ public class CPPSemantics {
} }
} }
if( inherited != null && inherited.length != 0 ){ if( inherited != null ){
if( result == null || result.length == 0 ){ if( result == null ){
result = inherited; result = inherited;
} else if ( inherited != null && inherited.length != 0 ) { } else if ( inherited != null ) {
for( int j = 0; j < result.length && result[j] != null; j++ ) { if( !data.prefixLookup ) {
IASTName n = result[j]; if( result instanceof Object [] ){
if( checkAmbiguity( n, inherited ) ){ Object [] r = (Object[]) result;
data.problem = new ProblemBinding( IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, n.toCharArray() ); for( int j = 0; j < r.length && r[j] != null; j++ ) {
if( checkForAmbiguity( r[j], inherited ) ){
data.problem = new ProblemBinding( IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.name );
return null; return null;
} }
} }
} else {
if( checkForAmbiguity( result, inherited ) ){
data.problem = new ProblemBinding( IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.name );
return null;
}
} }
} else { } else {
inherited = null; //reset temp for next iteration CharArrayObjectMap temp = (CharArrayObjectMap) inherited;
CharArrayObjectMap r = (CharArrayObjectMap) result;
char[] key = null;
int tempSize = temp.size();
for( int ii = 0; ii < tempSize; ii++ ){
key = temp.keyAt( ii );
if( !r.containsKey( key ) ){
r.put( key, temp.get(key) );
} else {
//TODO: prefixLookup ambiguity checking
}
}
}
}
} }
} }
@ -799,27 +848,35 @@ public class CPPSemantics {
} }
} }
} }
private static boolean checkAmbiguity( IASTName n, IASTName []names ) throws DOMException{ private static boolean checkForAmbiguity( Object n, Object names ) throws DOMException{
names = (IASTName[]) ArrayUtil.trim( IASTName.class, names ); if( names instanceof Object[] ) {
if( names.length == 0 ) names = ArrayUtil.trim( Object.class, (Object[]) names );
if( ((Object[])names).length == 0 )
return false; return false;
}
//it is not ambiguous if they are the same thing and it is static or an enumerator //it is not ambiguous if they are the same thing and it is static or an enumerator
IBinding binding = n.resolveBinding(); IBinding binding = ( n instanceof IBinding) ? (IBinding)n : ((IASTName)n).resolveBinding();
for( int i = 0; i < names.length && names[i] != null; i++ ){ Object [] objs = ( names instanceof Object[] ) ? (Object[])names : null;
int idx = ( objs != null && objs.length > 0 ) ? 0 : -1;
IBinding b = names[i].resolveBinding(); Object o = ( idx != -1 ) ? objs[idx++] : names;
while( o != null ) {
IBinding b = ( o instanceof IBinding ) ? (IBinding) o : ((IASTName)o).resolveBinding();
if( binding != b ) if( binding != b )
return true; return true;
if( binding instanceof IEnumerator ) if( !(binding instanceof IEnumerator) &&
continue; !( (binding instanceof IFunction && ((IFunction)binding).isStatic()) ||
else if( (binding instanceof IFunction && ((IFunction)binding).isStatic()) || (binding instanceof IVariable && ((IVariable)binding).isStatic()) ) )
(binding instanceof IVariable && ((IVariable)binding).isStatic()) ) {
continue;
return true; return true;
} }
if( idx > -1 && idx < objs.length )
o = objs[idx++];
else
o = null;
}
return false; return false;
} }