예제 #1
0
 public ContainedFunctionBinder(SharedBinderState sharedBinderState, Binder parent, Binder containerBinder)
     : base(sharedBinderState, parent)
 {
     if (containerBinder == null)
         throw new ArgumentNullException(nameof(containerBinder));
     _containerBinder = containerBinder;
 }
예제 #2
0
        private BoundNode BindTechniqueDeclaration(TechniqueSyntax declaration)
        {
            var techniqueSymbol = new TechniqueSymbol(declaration.Name.Text);
            AddSymbol(techniqueSymbol, declaration.Name.Span);

            var techniqueBinder = new Binder(_sharedBinderState, this);
            var boundPasses = declaration.Passes.Select(x => techniqueBinder.Bind(x, techniqueBinder.BindPass));
            return new BoundTechnique(techniqueSymbol, boundPasses.ToImmutableArray());
        }
예제 #3
0
        private BoundStatement BindSwitchStatement(SwitchStatementSyntax syntax, Symbol parent)
        {
            BindAttributes(syntax.Attributes);

            var switchBinder = new Binder(_sharedBinderState, this);
            var boundSections = syntax.Sections.Select(x => switchBinder.Bind(x, y => switchBinder.BindSwitchSection(y, parent))).ToImmutableArray();

            return new BoundSwitchStatement(
                Bind(syntax.Expression, BindExpression),
                boundSections);
        }
예제 #4
0
 public ClassMethodBinder(SharedBinderState sharedBinderState, Binder parent, ClassSymbol classSymbol)
     : base(sharedBinderState, parent)
 {
     _classSymbol = classSymbol;
 }
예제 #5
0
 public NamespaceBinder(SharedBinderState sharedBinderState, Binder parent, NamespaceSymbol namespaceSymbol)
     : base(sharedBinderState, parent)
 {
     NamespaceSymbol = namespaceSymbol;
 }
예제 #6
0
 private BoundBlock BindBlock(BlockSyntax syntax, Symbol parent)
 {
     var blockBinder = new Binder(_sharedBinderState, this);
     return new BoundBlock(syntax.Statements.Select(x => blockBinder.Bind(x, y => blockBinder.BindStatement(y, parent))).ToImmutableArray());
 }
예제 #7
0
        private BoundForStatement BindForStatement(ForStatementSyntax syntax, Symbol parent)
        {
            BindAttributes(syntax.Attributes);

            var forStatementBinder = new Binder(_sharedBinderState, this);

            // Note that we bind declarations in the current scope, not the for statement scope.

            return new BoundForStatement(
                syntax.Declaration != null ? Bind(syntax.Declaration, x => BindForStatementDeclaration(x, parent)) : null,
                syntax.Initializer != null ? forStatementBinder.Bind(syntax.Initializer, forStatementBinder.BindExpression) : null,
                forStatementBinder.Bind(syntax.Condition, forStatementBinder.BindExpression),
                syntax.Incrementor != null ? forStatementBinder.Bind(syntax.Incrementor, forStatementBinder.BindExpression) : null,
                forStatementBinder.Bind(syntax.Statement, x => forStatementBinder.BindStatement(x, parent)));
        }
예제 #8
0
        private static IEnumerable<Symbol> LookupSymbols(Binder binder)
        {
            // NOTE: We want to only show the *available* symbols. That means, we need to
            //       hide symbols from the parent binder that have same name as the ones
            //       from a nested binder.
            //
            //       We do this by simply recording which names we've already seen.
            //       Please note that we *do* want to see duplicate names within the
            //       *same* binder.

            var allNames = new HashSet<string>();

            while (binder != null)
            {
                var localNames = new HashSet<string>();
                var localSymbols = binder.LocalSymbols
                    .SelectMany(x => x.Value)
                    .Where(s => !string.IsNullOrEmpty(s.Name));

                foreach (var symbol in localSymbols)
                {
                    if (!allNames.Contains(symbol.Name))
                    {
                        localNames.Add(symbol.Name);
                        yield return symbol;
                    }
                }

                allNames.UnionWith(localNames);
                binder = binder.Parent;
            }
        }
예제 #9
0
        private BoundInterfaceType BindInterfaceDeclaration(InterfaceTypeSyntax declaration, Symbol parent)
        {
            var interfaceSymbol = new InterfaceSymbol(declaration, parent);
            AddSymbol(interfaceSymbol, declaration.Name.Span);

            var methods = new List<BoundFunction>();
            var interfaceBinder = new Binder(_sharedBinderState, this);
            foreach (var memberSyntax in declaration.Methods)
                methods.Add(interfaceBinder.Bind(memberSyntax, x => interfaceBinder.BindFunctionDeclaration(x, interfaceSymbol)));

            foreach (var member in interfaceBinder.LocalSymbols.Values.SelectMany(x => x))
                interfaceSymbol.AddMember(member);

            return new BoundInterfaceType(interfaceSymbol, methods.ToImmutableArray());
        }
예제 #10
0
        private BoundStructType BindStructDeclaration(StructTypeSyntax declaration, Symbol parent)
        {
            var structSymbol = new StructSymbol(declaration, parent);
            AddSymbol(structSymbol, declaration.Name?.Span ?? declaration.GetTextSpanSafe());

            var variables = new List<BoundMultipleVariableDeclarations>();
            var structBinder = new Binder(_sharedBinderState, this);
            foreach (var variableDeclarationStatement in declaration.Fields)
                variables.Add(structBinder.Bind(variableDeclarationStatement, x => structBinder.BindField(x, structSymbol)));

            foreach (var member in structBinder.LocalSymbols.Values.SelectMany(x => x))
                structSymbol.AddMember(member);

            return new BoundStructType(structSymbol, variables.ToImmutableArray());
        }
예제 #11
0
        private BoundClassType BindClassDeclaration(ClassTypeSyntax declaration, Symbol parent)
        {
            ClassSymbol baseClass = null;
            var baseInterfaces = new List<InterfaceSymbol>();

            if (declaration.BaseList != null)
            {
                var baseType = Bind(declaration.BaseList.BaseType, x => BindType(x, parent));
                switch (baseType.TypeSymbol.Kind)
                {
                    case SymbolKind.Class:
                        baseClass = (ClassSymbol) baseType.TypeSymbol;
                        break;
                    case SymbolKind.Interface:
                        baseInterfaces.Add((InterfaceSymbol) baseType.TypeSymbol);
                        break;
                }
            }

            var classBinder = new Binder(_sharedBinderState, this);

            var classSymbol = new ClassSymbol(declaration, parent, baseClass, baseInterfaces.ToImmutableArray(), classBinder);
            AddSymbol(classSymbol, declaration.Name.Span);

            var members = new List<BoundNode>();

            foreach (var memberSyntax in declaration.Members)
            {
                switch (memberSyntax.Kind)
                {
                    case SyntaxKind.VariableDeclarationStatement:
                        members.Add(classBinder.Bind((VariableDeclarationStatementSyntax) memberSyntax, x => classBinder.BindVariableDeclarationStatement(x, classSymbol)));
                        break;
                    case SyntaxKind.FunctionDeclaration:
                        members.Add(classBinder.Bind((FunctionDeclarationSyntax) memberSyntax, x => classBinder.BindFunctionDeclaration(x, classSymbol)));
                        break;
                    case SyntaxKind.FunctionDefinition:
                        members.Add(classBinder.Bind((FunctionDefinitionSyntax) memberSyntax, x => classBinder.BindFunctionDefinition(x, classSymbol)));
                        break;
                }
            }

            foreach (var member in classBinder.LocalSymbols.Values.SelectMany(x => x))
                classSymbol.AddMember(member);

            return new BoundClassType(classSymbol, members.ToImmutableArray());
        }
예제 #12
0
        private ImmutableArray<BoundVariableDeclaration> BindParameters(ParameterListSyntax parameterList, Binder invocableBinder, InvocableSymbol invocableSymbol)
        {
            var boundParameters = new List<BoundVariableDeclaration>();
            foreach (var parameterSyntax in parameterList.Parameters)
            {
                var parameterValueType = Bind(parameterSyntax.Type, x => BindType(x, null));
                var parameterDirection = SyntaxFacts.GetParameterDirection(parameterSyntax.Modifiers);

                boundParameters.Add(invocableBinder.Bind(parameterSyntax.Declarator, x => invocableBinder.BindVariableDeclarator(x, parameterValueType.TypeSymbol, (d, t) =>
                    new SourceParameterSymbol(
                        parameterSyntax,
                        invocableSymbol,
                        t,
                        parameterDirection))));
            }

            invocableSymbol.ClearParameters();
            foreach (var parameter in invocableBinder.LocalSymbols.Values.SelectMany(x => x))
                invocableSymbol.AddParameter((ParameterSymbol) parameter);

            return boundParameters.ToImmutableArray();
        }
예제 #13
0
        private BoundFunctionDeclaration BindFunctionDeclaration(FunctionDeclarationSyntax declaration, Symbol parent)
        {
            BindAttributes(declaration.Attributes);

            var boundReturnType = Bind(declaration.ReturnType, x => BindType(x, parent));

            var functionSymbol = LocalSymbols.OfType<SourceFunctionSymbol>()
                .FirstOrDefault(x => SyntaxFacts.HaveMatchingSignatures(
                    x.DefinitionSyntax as FunctionSyntax ?? x.DeclarationSyntaxes[0],
                    declaration));

            if (functionSymbol != null)
            {
                functionSymbol.DeclarationSyntaxes.Add(declaration);
            }
            else
            {
                functionSymbol = new SourceFunctionSymbol(declaration, parent, boundReturnType.TypeSymbol);
                AddSymbol(functionSymbol, declaration.Name.GetTextSpanSafe(), true);
            }

            if (declaration.Semantic != null)
                Bind(declaration.Semantic, BindVariableQualifier);

            var functionBinder = new Binder(_sharedBinderState, this);

            var boundParameters = BindParameters(declaration.ParameterList, functionBinder, functionSymbol);

            return new BoundFunctionDeclaration(functionSymbol, boundReturnType, boundParameters.ToImmutableArray());
        }