public static StringSegment ParseJsExpression(this StringSegment literal, out JsToken token, bool filterExpression) { var peekLiteral = literal.ParseJsToken(out var node, filterExpression: filterExpression); peekLiteral = peekLiteral.AdvancePastWhitespace(); var peekChar = peekLiteral.SafeGetChar(0); if (literal.IsNullOrEmpty() || peekChar.IsExpressionTerminatorChar()) { token = node; return(peekLiteral); } if (peekChar == ConditionalExpressionTestChar && peekLiteral.SafeGetChar(1) != ConditionalExpressionTestChar) // not ?? { literal = peekLiteral.ParseJsConditionalExpression(node, out var expression); token = expression; return(literal); } peekLiteral = peekLiteral.AdvancePastWhitespace(); if (!peekLiteral.IsNullOrEmpty()) { if (filterExpression && peekLiteral.Length > 2) { var char1 = peekLiteral.GetChar(0); var char2 = peekLiteral.GetChar(1); if ((char1 == '|' && char2 != '|') || (char1 == '}' && char2 == '}')) { token = node; return(peekLiteral); } } } peekLiteral = peekLiteral.ParseJsBinaryOperator(out var op); if (op != null) { literal = literal.ParseBinaryExpression(out var expr, filterExpression); token = expr; literal = literal.AdvancePastWhitespace(); if (literal.FirstCharEquals(ConditionalExpressionTestChar)) { literal = literal.ParseJsConditionalExpression(expr, out var conditionalExpr); token = conditionalExpr; return(literal); } return(literal); } literal = peekLiteral.ParseJsMemberExpression(ref node, filterExpression); token = node; return(literal); }
public static StringSegment ParseJsCallExpression(this StringSegment 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); }
private static StringSegment ParseJsConditionalExpression(this StringSegment 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); }