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(); }