Example #1
0
        public override void VisitFunctionCallSyntax(FunctionCallSyntax syntax)
        {
            FunctionFlags currentFlags = allowedFlags;

            this.Visit(syntax.Name);
            this.Visit(syntax.OpenParen);
            allowedFlags = allowedFlags.HasDecoratorFlag() ? FunctionFlags.Default : allowedFlags;
            this.VisitNodes(syntax.Arguments);
            this.Visit(syntax.CloseParen);
            allowedFlags = currentFlags;

            var symbol = this.LookupSymbolByName(syntax.Name, true);

            // bind what we got - the type checker will validate if it fits
            this.bindings.Add(syntax, symbol);
        }
Example #2
0
        public override void VisitInstanceFunctionCallSyntax(InstanceFunctionCallSyntax syntax)
        {
            FunctionFlags currentFlags = allowedFlags;

            this.Visit(syntax.BaseExpression);
            this.Visit(syntax.Dot);
            this.Visit(syntax.Name);
            this.Visit(syntax.OpenParen);
            allowedFlags = allowedFlags.HasDecoratorFlag() ? FunctionFlags.Default : allowedFlags;
            this.VisitNodes(syntax.Arguments);
            this.Visit(syntax.CloseParen);
            allowedFlags = currentFlags;

            if (!syntax.Name.IsValid)
            {
                // the parser produced an instance function calls with an invalid name
                // all instance function calls must be bound to a symbol, so let's
                // bind to a symbol without any errors (there's already a parse error)
                this.bindings.Add(syntax, new ErrorSymbol());
                return;
            }

            if (bindings.TryGetValue(syntax.BaseExpression, out var baseSymbol) && baseSymbol is NamespaceSymbol namespaceSymbol)
            {
                var functionSymbol = allowedFlags.HasDecoratorFlag()
                                     // Decorator functions are only valid when HasDecoratorFlag() is true which means
                                     // the instance function call is the top level expression of a DecoratorSyntax node.
                    ? namespaceSymbol.Type.MethodResolver.TryGetSymbol(syntax.Name) ?? namespaceSymbol.Type.DecoratorResolver.TryGetSymbol(syntax.Name)
                    : namespaceSymbol.Type.MethodResolver.TryGetSymbol(syntax.Name);

                var foundSymbol = SymbolValidator.ResolveNamespaceQualifiedFunction(allowedFlags, functionSymbol, syntax.Name, namespaceSymbol);

                this.bindings.Add(syntax, foundSymbol);
            }
        }
Example #3
0
        public static Symbol ResolveNamespaceQualifiedFunction(FunctionFlags allowedFlags, Symbol?foundSymbol, IdentifierSyntax identifierSyntax, NamespaceSymbol namespaceSymbol)
        => ResolveSymbolInternal(
            allowedFlags,
            foundSymbol,
            identifierSyntax,
            getNameSuggestions: () =>
        {
            var knowFunctionNames = namespaceSymbol.Type.MethodResolver.GetKnownFunctions().Keys;

            return(allowedFlags.HasDecoratorFlag()
                        ? knowFunctionNames.Concat(namespaceSymbol.Type.DecoratorResolver.GetKnownDecoratorFunctions().Keys)
                        : knowFunctionNames);
        },
            getMissingNameError: (builder, suggestedName) => suggestedName switch {
            null => builder.FunctionDoesNotExistInNamespace(namespaceSymbol, identifierSyntax.IdentifierName),