blob: 1c86f687e380d647e30470ac550711f642568be2 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM Corp. - Rational Software - initial implementation
******************************************************************************/
package org.eclipse.cdt.internal.core.parser.ast.complete;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import org.eclipse.cdt.core.parser.ast.IASTNode;
import org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol;
import org.eclipse.cdt.internal.core.parser.pst.ISymbol;
import org.eclipse.cdt.internal.core.parser.pst.ISymbolASTExtension;
import org.eclipse.cdt.internal.core.parser.pst.ISymbolOwner;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTableException;
import org.eclipse.cdt.internal.core.parser.pst.TypeFilter;
/**
* @author aniefer
*/
public class ASTNode implements IASTNode {
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTNode#lookup(java.lang.String, org.eclipse.cdt.core.parser.ast.IASTNode.LookupKind, org.eclipse.cdt.core.parser.ast.IASTNode)
*/
public LookupResult lookup(String prefix, LookupKind[] kind, IASTNode context) throws LookupException {
if( ! ( this instanceof ISymbolOwner ) || ( context != null && !(context instanceof ISymbolOwner) ) ){
return null;
}
IContainerSymbol thisContainer = (IContainerSymbol) ((ISymbolOwner)this).getSymbol();
IContainerSymbol qualification = null;
if( context != null ){
ISymbol sym = (IContainerSymbol) ((ISymbolOwner)context).getSymbol();
if( sym == null || !(sym instanceof IContainerSymbol) ){
throw new LookupException();
}
qualification = (IContainerSymbol) sym;
}
ISymbolOwner owner = (ISymbolOwner) this;
ISymbol symbol = owner.getSymbol();
if( symbol == null || !(symbol instanceof IContainerSymbol) ){
throw new LookupException();
}
boolean lookInThis = false;
TypeFilter filter = new TypeFilter();
if( kind != null ){
for( int i = 0; i < kind.length; i++ ){
filter.addAcceptedType( kind[i] );
if( kind[i] == LookupKind.THIS ){
lookInThis = true;
if( kind.length == 1 ){
filter.addAcceptedType( LookupKind.ALL );
}
} else {
filter.addAcceptedType( kind[i] );
}
}
} else {
filter.addAcceptedType( LookupKind.ALL );
}
List lookupResults = null;
try {
if( lookInThis ){
ISymbol thisPointer = thisContainer.lookup( ParserSymbolTable.THIS );
ISymbol thisClass = ( thisPointer != null ) ? thisPointer.getTypeSymbol() : null;
if( thisClass != null && thisClass instanceof IContainerSymbol ){
lookupResults = ((IContainerSymbol) thisClass).prefixLookup( filter, prefix, true );
}
} else if( qualification != null ){
lookupResults = qualification.prefixLookup( filter, prefix, true );
} else {
lookupResults = thisContainer.prefixLookup( filter, prefix, false );
}
} catch (ParserSymbolTableException e) {
throw new LookupException();
}
if(lookupResults == null)
return null;
ListIterator iter = lookupResults.listIterator();
while( iter.hasNext() ){
ISymbol s = (ISymbol) iter.next();
if( !thisContainer.isVisible( s, qualification ) ){
iter.remove();
}
}
SymbolIterator iterator = new SymbolIterator( lookupResults.iterator() );
return new Result( prefix, iterator, lookupResults.size() );
}
private class Result implements LookupResult{
private String prefix;
private Iterator iterator;
private int resultsNumber;
public Result( String pref, Iterator iter, int resultsSize ){
prefix = pref;
iterator = iter;
resultsNumber = resultsSize;
}
public String getPrefix() { return prefix; }
public Iterator getNodes() { return iterator; }
public int getResultsSize() { return resultsNumber; }
}
private class SymbolIterator implements Iterator{
Iterator interalIterator;
public SymbolIterator( Iterator iter ){
interalIterator = iter;
}
public boolean hasNext() {
return interalIterator.hasNext();
}
public Object next() {
ISymbol nextSymbol = (ISymbol) interalIterator.next();
ISymbolASTExtension extension = (nextSymbol != null ) ? nextSymbol.getASTExtension() : null;
return (extension != null ) ? extension.getPrimaryDeclaration() : null;
}
public void remove() {
interalIterator.remove();
}
}
}