Example #1
0
    public override AstNode ShallowClone()
    {
        var res = new AstConst(Source, Start, End);

        res.Definitions.AddRange(Definitions.AsReadOnlySpan());
        return(res);
    }
Example #2
0
        AstNode ParseForStatement(Position nodeStart)
        {
            Next();
            EnterLexicalScope();
            Expect(TokenType.ParenL);
            if (Type == TokenType.Semi)
            {
                return(ParseFor(nodeStart, null));
            }
            var isLet = IsLet();

            if (Type == TokenType.Var || Type == TokenType.Const || isLet)
            {
                var startLoc = Start;
                var kind     = isLet ? VariableKind.Let : ToVariableKind((string)Value);
                Next();
                var declarations = new StructList <AstVarDef>();
                ParseVar(ref declarations, true, kind);
                AstDefinitions init;
                if (kind == VariableKind.Let)
                {
                    init = new AstLet(this, startLoc, _lastTokEnd, ref declarations);
                }
                else if (kind == VariableKind.Const)
                {
                    init = new AstConst(this, startLoc, _lastTokEnd, ref declarations);
                }
                else
                {
                    init = new AstVar(this, startLoc, _lastTokEnd, ref declarations);
                }

                if ((Type == TokenType.In || Options.EcmaVersion >= 6 && IsContextual("of")) &&
                    init.Definitions.Count == 1 &&
                    !(kind != VariableKind.Var && init.Definitions[0].Value != null))
                {
                    return(ParseForIn(nodeStart, init));
                }
                return(ParseFor(nodeStart, init));
            }
            else
            {
                var refDestructuringErrors = new DestructuringErrors();
                var init = ParseExpression(true, refDestructuringErrors);
                if (Type == TokenType.In || Options.EcmaVersion >= 6 && IsContextual("of"))
                {
                    init = ToAssignable(init);
                    CheckLVal(init, false, null);
                    CheckPatternErrors(refDestructuringErrors, true);
                    return(ParseForIn(nodeStart, init));
                }

                CheckExpressionErrors(refDestructuringErrors, true);
                return(ParseFor(nodeStart, init));
            }
        }
Example #3
0
    // Disambiguating between a `for` and a `for`/`in` or `for`/`of`
    // loop is non-trivial. Basically, we have to parse the init `var`
    // statement or expression, disallowing the `in` operator (see
    // the second parameter to `parseExpression`), and then check
    // whether the next token is `in` or `of`. When there is no init
    // part (semicolon immediately after the opening parenthesis), it
    // is a regular `for` loop.
    AstIterationStatement ParseForStatement(Position nodeStart)
    {
        Next();
        var isAwait = EatContextual("await");

        EnterLexicalScope();
        Expect(TokenType.ParenL);
        if (Type == TokenType.Semi)
        {
            return(ParseFor(nodeStart, null, isAwait));
        }

        var isLet = IsLet();

        if (Type is TokenType.Var or TokenType.Const || isLet)
        {
            var startLoc = Start;
            var kind     = isLet ? VariableKind.Let : ToVariableKind((string)GetValue());
            Next();
            var declarations = new StructList <AstVarDef>();
            ParseVar(ref declarations, true, kind);
            AstDefinitions init;
            if (kind == VariableKind.Let)
            {
                init = new AstLet(SourceFile, startLoc, _lastTokEnd, ref declarations);
            }
            else if (kind == VariableKind.Const)
            {
                init = new AstConst(SourceFile, startLoc, _lastTokEnd, ref declarations);
            }
            else
            {
                init = new AstVar(SourceFile, startLoc, _lastTokEnd, ref declarations);
            }

            if ((Type == TokenType.In || IsContextual("of")) &&
                init.Definitions.Count == 1 &&
                !(kind != VariableKind.Var && init.Definitions[0].Value != null))
            {
                return(ParseForIn(nodeStart, init, isAwait));
            }
            return(ParseFor(nodeStart, init, isAwait));
        }