예제 #1
0
        private static ReadOnlySpan <char> ParseJsConditionalExpression(this ReadOnlySpan <char> literal, JsToken test, out JsConditionalExpression expression)
        {
            literal = literal.Advance(1);

            literal = literal.ParseJsExpression(out var consequent);
            literal = literal.AdvancePastWhitespace();

            if (!literal.FirstCharEquals(':'))
            {
                throw new SyntaxErrorException($"Expected Conditional ':' but was {literal.DebugFirstChar()}");
            }

            literal = literal.Advance(1);

            literal = literal.ParseJsExpression(out var alternate);

            expression = new JsConditionalExpression(test, consequent, alternate);
            return(literal);
        }
예제 #2
0
        public static ReadOnlySpan <char> ParseJsCallExpression(this ReadOnlySpan <char> literal, out JsCallExpression expression, bool filterExpression = false)
        {
            literal = literal.ParseIdentifier(out var token);

            if (!(token is JsIdentifier identifier))
            {
                throw new SyntaxErrorException($"Expected identifier but instead found {token.DebugToken()}");
            }

            literal = literal.AdvancePastWhitespace();

            if (literal.FirstCharEquals(WhitespaceArgument))
            {
                literal    = literal.Advance(1);
                literal    = literal.ParseWhitespaceArgument(out var argument);
                expression = new JsCallExpression(identifier, argument);
                return(literal);
            }

            if (literal.StartsWith("=>"))
            {
                literal    = literal.ParseArrowExpressionBody(new[] { new JsIdentifier("it") }, out var arrowExpr);
                expression = new JsCallExpression(identifier, arrowExpr);
                return(literal);
            }

            if (!literal.FirstCharEquals('('))
            {
                expression = new JsCallExpression(identifier);
                return(literal);
            }

            literal = literal.Advance(1);

            literal = literal.ParseArguments(out var args, termination: ')');

            expression = new JsCallExpression(identifier, args.ToArray());
            return(literal);
        }
예제 #3
0
        internal static ReadOnlySpan <char> ParseArguments(this ReadOnlySpan <char> literal, out List <JsToken> arguments, char termination)
        {
            arguments = new List <JsToken>();

            while (!literal.IsNullOrEmpty())
            {
                JsToken listValue;

                literal = literal.AdvancePastWhitespace();
                if (literal[0] == termination)
                {
                    literal = literal.Advance(1);
                    break;
                }

                if (literal.StartsWith("..."))
                {
                    literal = literal.Advance(3);
                    literal = literal.ParseJsExpression(out listValue);
                    if (!(listValue is JsIdentifier) && !(listValue is JsArrayExpression))
                    {
                        throw new SyntaxErrorException($"Spread operator expected array but instead found {listValue.DebugToken()}");
                    }

                    listValue = new JsSpreadElement(listValue);
                }
                else
                {
                    literal = literal.ParseJsExpression(out listValue);
                }

                arguments.Add(listValue);

                literal = literal.AdvancePastWhitespace();
                if (literal.IsNullOrEmpty())
                {
                    break;
                }

                if (literal[0] == termination)
                {
                    literal = literal.Advance(1);
                    break;
                }

                literal = literal.AdvancePastWhitespace();
                var c = literal.SafeGetChar(0);
                if (c.IsEnd() || c == termination)
                {
                    literal = literal.Advance(1);
                    break;
                }

                if (c != ',')
                {
                    throw new SyntaxErrorException($"Unterminated arguments expression near: {literal.DebugLiteral()}");
                }

                literal = literal.Advance(1);
                literal = literal.AdvancePastWhitespace();
            }

            literal = literal.AdvancePastWhitespace();

            return(literal);
        }
예제 #4
0
 public static ReadOnlySpan <char> AdvancePastPipeOperator(this ReadOnlySpan <char> literal) =>
 literal.SafeCharEquals(1, '>')
         ? literal.Advance(2) // support new JS |> operator
         : ScriptConfig.AllowUnixPipeSyntax ? literal.Advance(1)
             : throw new SyntaxErrorException("Unix Pipe syntax is disallowed, use JS Pipeline Operator syntax '|>' or set ScriptConfig.AllowUnixPipeSyntax=true; ");