示例#1
0
        /// <summary>
        /// Analyze a method invocation.
        /// </summary>
        /// <param name="invokeMethod">The expression to analyze.</param>
        private void ValidateCoreMethodInvocation(InvokeCoreMethodExpression invokeMethod)
        {
            AnalyzeExpression(invokeMethod.TargetObject);

            foreach (var argument in invokeMethod.Arguments)
            {
                AnalyzeExpression(argument);
            }
        }
示例#2
0
        /// <summary>
        /// Parse a static reference to a property or a static method invocation.
        ///
        /// Corresponding grammar :
        ///     Namespace_Or_Type_Name (Member_Access | Method_Invocation)
        /// </summary>
        /// <returns>Returns a <see cref="PropertyReferenceExpression"/> or <see cref="InvokeCoreMethodExpression"/>. Returns null if it doesn't looks like a valid reference or invocation.</returns>
        private Expression ParseStaticPropertyOrMethod()
        {
            var identifierToken = CurrentToken;

            if (CurrentToken.TokenType != TokenType.Identifier)
            {
                AddIssue(new BaZicParserException(CurrentToken.Line, CurrentToken.Column, CurrentToken.StartOffset, CurrentToken.ParsedLength, L.BaZic.Parser.Expressions.TypeExpected));
            }

            var typeName = ParseNamespaceOrTypeName();

            if (typeName == null)
            {
                AddIssue(new BaZicParserException(identifierToken.Line, identifierToken.Column, identifierToken.StartOffset, identifierToken.ParsedLength, L.BaZic.Optimizer.FormattedUndeclaredName(identifierToken.Value)));
                return(null);
            }

            if (!typeName.Namespace.Contains("."))
            {
                AddIssue(new BaZicParserException(typeName.Line, typeName.Column, typeName.StartOffset, typeName.NodeLength, L.BaZic.Parser.Expressions.FormattedInvalidNamespaceOrVariable(typeName.Namespace)));
                return(null);
            }

            var lastDotIndex         = typeName.Namespace.LastIndexOf('.');
            var propertyOrMethodName = typeName.ClassName;
            var className            = typeName.Namespace.Substring(lastDotIndex + 1);
            var @namespace           = typeName.Namespace.Substring(0, lastDotIndex);

            if (CurrentToken.TokenType == TokenType.LeftParenth)
            {
                var invocationToken = PreviousToken;
                var arguments       = ParseMethodInvocation();
                var methodInvoke    = new InvokeCoreMethodExpression(new ClassReferenceExpression(@namespace, className), propertyOrMethodName.Identifier, false)
                {
                    Line        = invocationToken.Line,
                    Column      = invocationToken.Column,
                    StartOffset = invocationToken.StartOffset,
                    NodeLength  = invocationToken.ParsedLength
                };
                methodInvoke.WithParameters(arguments);

                ValidateCoreMethodInvocation(methodInvoke);
                return(methodInvoke);
            }

            return(new PropertyReferenceExpression(new ClassReferenceExpression(@namespace, className), propertyOrMethodName.Identifier)
            {
                Line = PreviousToken.Line,
                Column = PreviousToken.Column,
                StartOffset = PreviousToken.StartOffset,
                NodeLength = PreviousToken.ParsedLength
            });
        }
示例#3
0
        /// <summary>
        /// Generates the code for an <see cref="InvokeCoreMethodExpression"/>.
        /// </summary>
        /// <param name="expression">The expression</param>
        /// <returns>A BaZic code</returns>
        private string GenerateInvokeCoreMethodExpression(InvokeCoreMethodExpression expression)
        {
            Requires.NotNull(expression.TargetObject, nameof(expression.TargetObject));
            Requires.NotNull(expression.MethodName, nameof(expression.MethodName));

            var targetObject = GenerateReferenceExpression(expression.TargetObject);

            var arguments = new List <string>();

            foreach (var argument in expression.Arguments)
            {
                arguments.Add(GenerateExpression(argument));
            }

            var wait = string.Empty;

            if (expression.Await)
            {
                wait = "AWAIT ";
            }

            return($"{wait}{targetObject}.{expression.MethodName}({string.Join(", ", arguments)})");
        }
示例#4
0
        /// <summary>
        /// Parse a part of an expression that can be a reference or primary value followed by an accesser like array indexer or method invocation.
        ///
        /// Corresponding grammar :
        ///     Primary_Expression_Start Bracket_Expression* ((Member_Access | Method_Invocation) Bracket_Expression* )*
        /// </summary>
        /// <param name="isRequired">Defines whether it is required/expected to parse an expression. If true, throw an exception if no expression is parsed.</param>
        /// <returns>Returns an expression.</returns>
        private Expression ParsePrimaryExpression(bool isRequired)
        {
            Expression[] bracketExpression      = null;
            var          expressionLine         = CurrentToken.Line;
            var          expressionColumn       = CurrentToken.Column;
            var          expressionStartOffset  = CurrentToken.StartOffset;
            var          expressionParsedLength = CurrentToken.ParsedLength;

            // Primary_Expression_Start
            var expression = ParsePrimaryExpressionStart(isRequired);

            // Bracket_Expression *
            do
            {
                var bracketToken = CurrentToken;
                bracketExpression = ParseBracketExpression();
                if (bracketExpression != null)
                {
                    var referenceExpression = expression as ReferenceExpression;

                    if (referenceExpression == null)
                    {
                        AddIssue(new BaZicParserException(expressionLine, expressionColumn, expressionStartOffset, expressionParsedLength, L.BaZic.Parser.Expressions.UnexpectedIndexer));
                    }

                    if (bracketExpression.Length == 0)
                    {
                        AddIssue(new BaZicParserException(bracketToken.Line, bracketToken.Column, expressionStartOffset, expressionParsedLength, L.BaZic.Parser.Expressions.IndexerExpected));
                        return(null);
                    }

                    var arrayIndexer = new ArrayIndexerExpression(referenceExpression, bracketExpression)
                    {
                        Line        = bracketToken.Line,
                        Column      = bracketToken.Column,
                        StartOffset = bracketToken.StartOffset,
                        NodeLength  = bracketToken.ParsedLength
                    };

                    ValidateArrayIndexerExpression(arrayIndexer);
                    expression = arrayIndexer;
                }
            } while (bracketExpression != null);

            // ((Member_Access | Method_Invocation) Bracket_Expression* )*
            while (CurrentToken.TokenType == TokenType.Dot || CurrentToken.TokenType == TokenType.LeftParenth)
            {
                if (CurrentToken.TokenType == TokenType.Dot)
                {
                    // Member_Access
                    var memberNameToken = CurrentToken;
                    var memberAccess    = ParseMemberAccessPart(true);

                    if (!string.IsNullOrEmpty(memberAccess))
                    {
                        var referenceExpression = expression as ReferenceExpression;

                        if (referenceExpression == null)
                        {
                            AddIssue(new BaZicParserException(expressionLine, expressionColumn, expressionStartOffset, expressionParsedLength, L.BaZic.Parser.Expressions.IllegalPropertyAccess));
                        }

                        expression = new PropertyReferenceExpression(referenceExpression, memberAccess)
                        {
                            Line        = memberNameToken.Line,
                            Column      = memberNameToken.Column + 1,      // +1 because we don't want to show a potential error on the dot.
                            StartOffset = memberNameToken.StartOffset + 1, // +1 because we don't want to show a potential error on the dot.
                            NodeLength  = memberNameToken.ParsedLength
                        };
                    }
                }
                else if (CurrentToken.TokenType == TokenType.LeftParenth)
                {
                    // Method_Invocation
                    var methodInvocationParameters  = ParseMethodInvocation();
                    var propertyReferenceExpression = expression as PropertyReferenceExpression;

                    if (expression is VariableReferenceExpression variableReferenceExpression)
                    {
                        var methodInvoke = new InvokeMethodExpression(variableReferenceExpression.Name.ToString(), false)
                        {
                            Line        = variableReferenceExpression.Line,
                            Column      = variableReferenceExpression.Column,
                            StartOffset = variableReferenceExpression.StartOffset,
                            NodeLength  = variableReferenceExpression.NodeLength
                        }
                        .WithParameters(methodInvocationParameters);

                        AddMethodInvocation(methodInvoke);
                        expression = methodInvoke;
                    }
                    else if (propertyReferenceExpression != null)
                    {
                        var methodInvoke = new InvokeCoreMethodExpression(propertyReferenceExpression.TargetObject, propertyReferenceExpression.PropertyName.ToString(), false)
                        {
                            Line        = propertyReferenceExpression.Line,
                            Column      = propertyReferenceExpression.Column,
                            StartOffset = propertyReferenceExpression.StartOffset,
                            NodeLength  = propertyReferenceExpression.NodeLength
                        };
                        methodInvoke.WithParameters(methodInvocationParameters);

                        ValidateCoreMethodInvocation(methodInvoke);
                        expression = methodInvoke;
                    }
                    else
                    {
                        AddIssue(new BaZicParserException(expressionLine, expressionColumn, expressionStartOffset, expressionParsedLength, L.BaZic.Parser.Expressions.MethodNameExpected));
                    }
                }
                else
                {
                    AddIssue(new BaZicParserException(expressionLine, expressionColumn, expressionStartOffset, expressionParsedLength, L.BaZic.Parser.Expressions.MethodNameExpected));
                }

                // Bracket_Expression*
                do
                {
                    var bracketToken = CurrentToken;
                    bracketExpression = ParseBracketExpression();
                    if (bracketExpression != null)
                    {
                        var referenceExpression = expression as ReferenceExpression;

                        if (referenceExpression == null)
                        {
                            AddIssue(new BaZicParserException(expressionLine, expressionColumn, expressionStartOffset, expressionParsedLength, L.BaZic.Parser.Expressions.UnexpectedIndexer));
                        }

                        if (bracketExpression.Length == 0)
                        {
                            AddIssue(new BaZicParserException(bracketToken.Line, bracketToken.Column, expressionStartOffset, expressionParsedLength, L.BaZic.Parser.Expressions.IndexerExpected));
                        }

                        var arrayIndexer = new ArrayIndexerExpression(referenceExpression, bracketExpression)
                        {
                            Line        = bracketToken.Line,
                            Column      = bracketToken.Column,
                            StartOffset = bracketToken.StartOffset,
                            NodeLength  = bracketToken.ParsedLength
                        };

                        ValidateArrayIndexerExpression(arrayIndexer);
                        expression = arrayIndexer;
                    }
                } while (bracketExpression != null);
            }

            return(expression);
        }