public void Build(DeclarationSyntax declaration, ContainerBinder containingScope) { declaration.Match() .With<NamespaceSyntax>(@namespace => { var imports = @namespace.UsingDirectives.SelectMany(u => GatherImportedSymbols(u, containingScope)); var namesCount = @namespace.Names.Count; for(var i = 0; i < namesCount; i++) { var name = @namespace.Names[i]; var last = i == namesCount - 1; var reference = containingScope.GetMembers(name.ValueText).OfType<NamespaceReference>().Single(); containingScope = new NamespaceBinder(containingScope, reference, last ? imports : Enumerable.Empty<ImportedSymbol>()); // The innermost binder is the one that has the imports and should be associated with the syntax node if(last) binders.Add(@namespace, containingScope); } foreach(var member in @namespace.Members) Build(member, containingScope); }) .With<ClassSyntax>(@class => { var scope = new ClassBinder(containingScope, @class); binders.Add(@class, scope); foreach(var member in @class.Members) Build(member, scope); }) .With<FunctionSyntax>(function => { foreach(var parameter in function.Parameters) Build(parameter.Type.Type, containingScope); // TODO deal with return type Binder scope = new FunctionBinder(containingScope); binders.Add(function, scope); foreach(var statement in function.Body) scope = Build(statement, scope); }) // .With<VariableDeclaration>(global => // { // global.Type.BindNames(scope); // global.InitExpression?.BindNames(scope); // }) .Exhaustive(); }
private void Build(ClassMemberSyntax member, ClassBinder containingScope) { member.Match() .With<FieldSyntax>(field => { Build(field.Type.Type, containingScope); if(field.InitExpression != null) Build(field.InitExpression, containingScope); }) .With<ConstructorSyntax>(constructor => { foreach(var parameter in constructor.Parameters) Build(parameter.Type.Type, containingScope); Binder scope = new FunctionBinder(containingScope); binders.Add(constructor, scope); foreach(var statement in constructor.Body) scope = Build(statement, scope); }) .With<DestructorSyntax>(destructor => { foreach(var parameter in destructor.Parameters) if(parameter.Type != null) Build(parameter.Type.Type, containingScope); Binder scope = new FunctionBinder(containingScope); binders.Add(destructor, scope); foreach(var statement in destructor.Body) scope = Build(statement, scope); }) .With<IndexerMethodSyntax>(indexer => { foreach(var parameter in indexer.Parameters) if(parameter.Type != null) Build(parameter.Type.Type, containingScope); // TODO deal with return type Binder scope = new FunctionBinder(containingScope); binders.Add(indexer, scope); foreach(var statement in indexer.Body) scope = Build(statement, scope); }) .With<MethodSyntax>(method => { foreach(var parameter in method.Parameters) if(parameter.Type != null) Build(parameter.Type.Type, containingScope); // TODO deal with return type Binder scope = new FunctionBinder(containingScope); binders.Add(method, scope); foreach(var statement in method.Body) scope = Build(statement, scope); }) .Exhaustive(); }