private void ResolveDeclarations(VBComponent component, IParseTree tree)
{
var qualifiedModuleName = new QualifiedModuleName(component);
var obsoleteCallStatementListener = new ObsoleteCallStatementListener();
var obsoleteLetStatementListener = new ObsoleteLetStatementListener();
var emptyStringLiteralListener = new EmptyStringLiteralListener();
var argListWithOneByRefParamListener = new ArgListWithOneByRefParamListener();
try
{
ParseTreeWalker.Default.Walk(new CombinedParseTreeListener(new IParseTreeListener[]{
obsoleteCallStatementListener,
obsoleteLetStatementListener,
emptyStringLiteralListener,
argListWithOneByRefParamListener,
}), tree);
// TODO: these are actually (almost) isnpection results.. we should handle them as such
_state.ArgListsWithOneByRefParam = argListWithOneByRefParamListener.Contexts.Select(context => new QualifiedContext(qualifiedModuleName, context));
_state.EmptyStringLiterals = emptyStringLiteralListener.Contexts.Select(context => new QualifiedContext(qualifiedModuleName, context));
_state.ObsoleteLetContexts = obsoleteLetStatementListener.Contexts.Select(context => new QualifiedContext(qualifiedModuleName, context));
_state.ObsoleteCallContexts = obsoleteCallStatementListener.Contexts.Select(context => new QualifiedContext(qualifiedModuleName, context));
// cannot locate declarations in one pass *the way it's currently implemented*,
// because the context in EnterSubStmt() doesn't *yet* have child nodes when the context enters.
// so we need to EnterAmbiguousIdentifier() and evaluate the parent instead - this *might* work.
var declarationsListener = new DeclarationSymbolsListener(qualifiedModuleName, Accessibility.Implicit, component.Type, _state.GetModuleComments(component), _state.GetModuleAnnotations(component),_state.GetModuleAttributes(component), _references);
// TODO: should we unify the API? consider working like the other listeners instead of event-based
declarationsListener.NewDeclaration += (sender, e) => _state.AddDeclaration(e.Declaration);
declarationsListener.CreateModuleDeclarations();
// rewalk parse tree for second declaration level
ParseTreeWalker.Default.Walk(declarationsListener, tree);
} catch (Exception exception)
{
Debug.Print("Exception thrown resolving '{0}' (thread {2}): {1}", component.Name, exception, Thread.CurrentThread.ManagedThreadId);
_state.SetModuleState(component, ParserState.ResolverError);
}
}