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:
parent
27c8ac0ac3
commit
d7ad9aef13
2 changed files with 119 additions and 60 deletions
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue