Пример #1
0
        public Node parse(string code, Options options)
        {
            // Program program, toString;

            //toString = String;
            //if (typeof code !== "string" && !(code instanceof String)) {
            //    code = toString(code);
            //}

            source = code;
            index = 0;
            lineNumber = (source.Length > 0) ? 1 : 0;
            lineStart = 0;
            startIndex = index;
            startLineNumber = lineNumber;
            startLineStart = lineStart;
            length = source.Length;
            lookahead = null;
            state = new State()
            {
                allowIn = true,
                allowYield = true,
                labelSet = new List<string>(),
                inFunctionBody = false,
                inIteration = false,
                inSwitch = false,
                lastCommentStart = -1,
                curlyStack = new Stack<string>(),
                sourceType = "script"
            };
            strict = false;

            extra = new Extra();
            if (options != null)
            {
                extra.range = options.range;
                extra.loc = options.loc;
                extra.attachComment = options.attachComment;

                //if (extra.loc && options.source != null && options.source != undefined) {
                //    extra.source = toString(options.source);
                //}

                if (options.tokens)
                {
                    extra.tokens = new List<Token>();
                }
                if (options.comment)
                {
                    extra.comments = new List<Comment>();
                }
                if (options.tolerant)
                {
                    extra.errors = new List<Error>();
                }
                if (extra.attachComment)
                {
                    extra.range = true;
                    extra.comments = new List<Comment>();
                    extra.bottomRightStack = new List<Token>();
                    extra.trailingComments = new List<Comment>();
                    extra.leadingComments = new List<Comment>();
                }
                if (options.sourceType == "module")
                {
                    // very restrictive condition for now
                    state.sourceType = options.sourceType;
                    strict = true;
                }
            }

            //try
            //{
            var program = parseProgram();
            //if (typeof extra.comments !== "undefined") {
            //    program.comments = extra.comments;
            //}
            //if (typeof extra.tokens !== "undefined") {
            //    filterTokenLocation();
            //    program.tokens = extra.tokens;
            //}
            //if (typeof extra.errors !== "undefined") {
            //    program.errors = extra.errors;
            //}
            //}
            //catch (Exception e)
            //{


            //    throw e;
            //}
            //finally
            //{
            //    extra = new Extra();
            //}

            return program;
        }
Пример #2
0
        public Options parseParams(Token firstRestricted = null)
        {
            Options options;

            options = new Options
            {
                @params = new List<Node>(),
                defaultCount = 0,
                defaults = new List<Node>(),
                firstRestricted = firstRestricted
            };

            expect("(");

            if (!match(")"))
            {
                //options.paramSet =
                //{
                //}
                //;
                while (startIndex < length)
                {
                    if (!parseParam(options))
                    {
                        break;
                    }
                    expect(",");
                }
            }

            expect(")");

            if (options.defaultCount == 0)
            {
                options.defaults = new List<Node>();
            }

            return new Options()
            {
                @params = options.@params,
                defaults = options.defaults,
                stricted = options.stricted,
                firstRestricted = options.firstRestricted,
                message = options.message
            };
        }
Пример #3
0
        public List<Token> tokenize(string code, Options options)
        {
            //var toString;
            List<Token> tokens;

            //toString = String;
            //if (typeof code !== "string" && !(code instanceof String)) {
            //    code = toString(code);
            //}

            source = code;
            index = 0;
            lineNumber = (source.Length > 0) ? 1 : 0;
            lineStart = 0;
            startIndex = index;
            startLineNumber = lineNumber;
            startLineStart = lineStart;
            length = source.Length;
            lookahead = null;
            state = new State()
            {
                allowIn = true,
                allowYield = true,
                labelSet = new List<string>(),
                inFunctionBody = false,
                inIteration = false,
                inSwitch = false,
                lastCommentStart = -1,
                curlyStack = new Stack<string>()
            };

            extra = new Extra();

            // Options matching.
            options = options ?? new Options();

            // Of course we collect tokens here.
            options.tokens = true;
            extra.tokens = new List<Token>();
            extra.tokenize = true;
            // The following two fields are necessary to compute the Regex tokens.
            extra.openParenToken = -1;
            extra.openCurlyToken = -1;

            extra.range = options.range;
            extra.loc = options.loc;

            if (options.comment)
            {
                extra.comments = new List<Comment>();
            }
            if (options.tolerant)
            {
                extra.errors = new List<Error>();
            }

            //try
            //{
            peek();
            if (lookahead.type == TokenType.EOF)
            {
                return extra.tokens;
            }

            lex();
            while (lookahead.type != TokenType.EOF)
            {
                try
                {
                    lex();
                }
                catch (Error lexError)
                {
                    if (extra.errors != null)
                    {
                        recordError(lexError);
                        // We have to break on the first error
                        // to avoid infinite loops.
                        break;
                    }
                    else
                    {
                        throw lexError;
                    }
                }
            }

            filterTokenLocation();
            tokens = extra.tokens;
            //tokens.comments = extra.comments;
            //tokens.errors = extra.errors;

            //}
            //catch (Exception e)
            //{
            //    throw e;
            //}
            //finally
            //{
            //    extra = new Extra();
            //}
            return tokens;
        }
Пример #4
0
 public void validateParam(Options options, Node param, string name)
 {
     //var key = "$" + name;
     //if (strict)
     //{
     //    if (isRestrictedWord(name))
     //    {
     //        options.stricted = param;
     //        options.message = Messages.StrictParamName;
     //    }
     //    //if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) {
     //    //    options.stricted = param;
     //    //    options.message = Messages.StrictParamDupe;
     //    //}
     //}
     //else if (!options.firstRestricted)
     //{
     //    if (isRestrictedWord(name))
     //    {
     //        options.firstRestricted = param;
     //        options.message = Messages.StrictParamName;
     //    }
     //    else if (isStrictModeReservedWord(name))
     //    {
     //        options.firstRestricted = param;
     //        options.message = Messages.StrictReservedWord;
     //    }
     //    //} else if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) {
     //    //    options.stricted = param;
     //    //    options.message = Messages.StrictParamDupe;
     //    //}
     //}
     //options.paramSet[key] = true;
 }
Пример #5
0
        public bool parseParam(Options options)
        {
            Token token;
            Node param;
            List<Token> @params = new List<Token>();
            int i;
            Node def = null;

            token = lookahead;
            if (token.value == "...")
            {
                param = parseRestElement(@params);
                validateParam(options, param.argument, param.argument.name);
                [email protected](param);
                options.defaults.Add(null);
                return false;
            }

            param = parsePatternWithDefault(@params, "");
            for (i = 0; i < @params.Count; i++)
            {
                //validateParam(options, @params[i], "");//, @params[i].value);
            }

            if (param.type == Syntax.AssignmentPattern)
            {
                def = param.right;
                param = param.left;
                ++options.defaultCount;
            }

            [email protected](param);
            options.defaults.Add(def);

            return !match(")");
        }
Пример #6
0
        public List<Node> parseBindingList(string kind, Options options)
        {
            List<Node> list = new List<Node>();

            do
            {
                list.Add(parseLexicalBinding(kind, options));
                if (!match(","))
                {
                    break;
                }
                lex();
            } while (startIndex < length);

            return list;
        }
Пример #7
0
        public Node parseLexicalDeclaration(Options options)
        {
            string kind;
            List<Node> declarations;
            Node node = new Node();

            kind = lex().value;
            assert(kind == "let" || kind == "const", "Lexical declaration must be either let or const");

            declarations = parseBindingList(kind, options);

            consumeSemicolon();

            return node.finishLexicalDeclaration(declarations, kind);
        }
Пример #8
0
        public List<Node> parseVariableDeclarationList(Options options)
        {
            List<Node> list = new List<Node>();

            do
            {
                list.Add(parseVariableDeclaration(new Options() { inFor = options.inFor }));
                if (!match(","))
                {
                    break;
                }
                lex();
            } while (startIndex < length);

            return list;
        }
Пример #9
0
        // ECMA-262 13.3.1 Let and Const Declarations

        public Node parseLexicalBinding(string kind, Options options)
        {
            Node init = null;
            Node id;
            Node node = new Node();
            List<Token> @params = new List<Token>();

            id = parsePattern(@params, kind);

            // ECMA-262 12.2.1
            if (strict && id.type == Syntax.Identifier && isRestrictedWord(id.name))
            {
                tolerateError(Messages.StrictVarName);
            }

            if (kind == "const")
            {
                if (!matchKeyword("in") && !matchContextualKeyword("of"))
                {
                    expect("=");
                    init = isolateCoverGrammar(parseAssignmentExpression);
                }
            }
            else if ((!options.inFor && id.type != Syntax.Identifier) || match("="))
            {
                expect("=");
                init = isolateCoverGrammar(parseAssignmentExpression);
            }

            return node.finishVariableDeclarator(id, init);
        }
Пример #10
0
        public Node parseArrowFunctionExpression(Options options, Node node)
        {
            bool previousStrict;
            bool previousAllowYield;
            List<Node> body;

            if (hasLineTerminator)
            {
                tolerateUnexpectedToken(lookahead);
            }
            expect("=>");

            previousStrict = strict;
            previousAllowYield = state.allowYield;
            state.allowYield = true;

            body = new List<Node>() { parseConciseBody() };

            if (strict && options.firstRestricted != null)
            {
                throwUnexpectedToken(options.firstRestricted, options.message);
            }
            if (strict && options.stricted != null)
            {
                tolerateUnexpectedToken(options.stricted, options.message);
            }

            strict = previousStrict;
            state.allowYield = previousAllowYield;

            return node.finishArrowFunctionExpression(options.@params, options.defaults, body, null);
            //body.type != Syntax.BlockStatement);
        }
Пример #11
0
        public Node parseVariableDeclaration(Options options)
        {
            Node init = null;
            Node id, node = new Node();
            List<Token> @params = new List<Token>();

            id = parsePattern(@params, "var");

            // ECMA-262 12.2.1
            if (strict && isRestrictedWord(id.name))
            {
                tolerateError(Messages.StrictVarName);
            }

            if (match("="))
            {
                lex();
                init = isolateCoverGrammar(parseAssignmentExpression);
            }
            else if (id.type != Syntax.Identifier && !options.inFor)
            {
                expect("=");
            }

            return node.finishVariableDeclarator(id, init);
        }
Пример #12
0
        public Options reinterpretAsCoverFormalsList(Node expr)
        {
            int i, len;
            Node param;
            List<Node> @params;
            List<Node> defaults;
            int defaultCount;
            Options options;

            Token token;

            defaults = new List<Node>();
            defaultCount = 0;
            @params = new List<Node>() { expr };

            switch (expr.type)
            {
                case Syntax.Identifier:
                    break;
                case PlaceHolders.ArrowParameterPlaceHolder:
                    @params = expr.@params;
                    break;
                default:
                    return null;
            }

            options = new Options()
            {
                // paramSet= {}
            };

            for (i = 0, len = @params.Count; i < len; i += 1)
            {
                param = @params[i];
                switch (param.type)
                {
                    case Syntax.AssignmentPattern:
                        @params[i] = param.left;
                        if (param.right.type == Syntax.YieldExpression)
                        {
                            if (param.right.argument != null)
                            {
                                throwUnexpectedToken(lookahead);
                            }
                            param.right.type = Syntax.Identifier;
                            param.right.name = "yield";
                            param.right.argument = null;
                            param.right.@delegate = null;
                        }
                        defaults.Add(param.right);
                        ++defaultCount;
                        checkPatternParam(options, param.left);
                        break;
                    default:
                        checkPatternParam(options, param);
                        @params[i] = param;
                        defaults.Add(null);
                        break;
                }
            }

            if (strict || !state.allowYield)
            {
                for (i = 0, len = @params.Count; i < len; i += 1)
                {
                    param = @params[i];
                    if (param.type == Syntax.YieldExpression)
                    {
                        throwUnexpectedToken(lookahead);
                    }
                }
            }

            if (options.message == Messages.StrictParamDupe)
            {
                token = strict ? options.stricted : options.firstRestricted;
                throwUnexpectedToken(token, options.message);
            }

            if (defaultCount == 0)
            {
                defaults = new List<Node>();
            }

            return new Options()
            {
                @params = @params,
                defaults = defaults,
                stricted = options.stricted,
                firstRestricted = options.firstRestricted,
                message = options.message
            };
        }
Пример #13
0
 public void checkPatternParam(Options options, Node @param)
 {
     int i;
     switch (@param.type)
     {
         case Syntax.Identifier:
             validateParam(options, @param, @param.name);
             break;
         case Syntax.RestElement:
             checkPatternParam(options, @param.argument);
             break;
         case Syntax.AssignmentPattern:
             checkPatternParam(options, @param.left);
             break;
         case Syntax.ArrayPattern:
             for (i = 0; i < @param.elements.Count; i++)
             {
                 if (@param.elements[i] != null)
                 {
                     checkPatternParam(options, param.elements[i]);
                 }
             }
             break;
         case Syntax.YieldExpression:
             break;
         default:
             assert(param.type == Syntax.ObjectPattern, "Invalid type");
             for (i = 0; i < param.properties.Count; i++)
             {
                 checkPatternParam(options, param.properties[i].value);
             }
             break;
     }
 }
Пример #14
0
        // ECMA-262 12.2.9 Template Literals

        public Node parseTemplateElement(Options option)
        {
            Node node;
            Token token;

            if (lookahead.type != TokenType.Template || (option.head && !lookahead.head))
            {
                throwUnexpectedToken();
            }

            node = new Node();
            token = lex();

            return node.finishTemplateElement(new Node() { raw = token.value }, token.tail);
            //.raw, cooked= token.value.cooked }
        }
Пример #15
0
        // This function is to try to parse a MethodDefinition as defined in 14.3. But in the case of object literals,
        // it might be called at a position where there is in fact a short hand identifier pattern or a data property.
        // This can only be determined after we consumed up to the left parentheses.
        //
        // In order to avoid back tracking, it returns `null` if the position is not a MethodDefinition and the caller
        // is responsible to visit other options.
        public Node tryParseMethodDefinition(Token token, Node key, bool computed, Node node)
        {
            Node value;
            Options options;
            Node methodNode;
            Options @params;
            bool previousAllowYield = state.allowYield;

            if (token.type == TokenType.Identifier)
            {
                // check for `get` and `set`;

                if (token.value == "get" && lookaheadPropertyName())
                {
                    computed = match("[");
                    key = parseObjectPropertyKey();
                    methodNode = new Node();
                    expect("(");
                    expect(")");

                    state.allowYield = false;
                    value = parsePropertyFunction(methodNode, new Options()
                    {
                        @params = new List<Node>(),
                        defaults = new List<Node>(),
                        stricted = null,
                        firstRestricted = null,
                        message = null
                    }, false);
                    state.allowYield = previousAllowYield;

                    return node.finishProperty("get", key, computed, value, false, false);
                }
                else if (token.value == "set" && lookaheadPropertyName())
                {
                    computed = match("[");
                    key = parseObjectPropertyKey();
                    methodNode = new Node();
                    expect("(");

                    options = new Options()
                    {
                        @params = new List<Node>(),
                        defaultCount = 0,
                        defaults = new List<Node>(),
                        firstRestricted = null,
                        // paramSet = {}
                    };
                    if (match(")"))
                    {
                        tolerateUnexpectedToken(lookahead);
                    }
                    else
                    {
                        state.allowYield = false;
                        parseParam(options);
                        state.allowYield = previousAllowYield;
                        if (options.defaultCount == 0)
                        {
                            options.defaults = new List<Node>();
                        }
                    }
                    expect(")");

                    state.allowYield = false;
                    value = parsePropertyFunction(methodNode, options, false);
                    state.allowYield = previousAllowYield;

                    return node.finishProperty("set", key, computed, value, false, false);
                }
            }
            else if (token.type == TokenType.Punctuator && token.value == "*" && lookaheadPropertyName())
            {
                computed = match("[");
                key = parseObjectPropertyKey();
                methodNode = new Node();

                state.allowYield = true;
                @params = parseParams();
                state.allowYield = previousAllowYield;

                state.allowYield = false;
                value = parsePropertyFunction(methodNode, @params, true);
                state.allowYield = previousAllowYield;

                return node.finishProperty("init", key, computed, value, true, false);
            }

            if (key != null && match("("))
            {
                value = parsePropertyMethodFunction();
                return node.finishProperty("init", key, computed, value, true, false);
            }

            // Not a MethodDefinition.
            return null;
        }
Пример #16
0
        // ECMA-262 12.2.6 Object Initializer

        public Node parsePropertyFunction(Node node, Options paramInfo, bool isGenerator)
        {
            bool previousStrict;
            List<Node> body;

            isAssignmentTarget = isBindingElement = false;

            previousStrict = strict;
            body = new List<Node>() { isolateCoverGrammar(parseFunctionSourceElements) };

            if (strict && paramInfo.firstRestricted != null)
            {
                tolerateUnexpectedToken(paramInfo.firstRestricted, paramInfo.message);
            }
            if (strict && paramInfo.stricted != null)
            {
                tolerateUnexpectedToken(paramInfo.stricted, paramInfo.message);
            }

            strict = previousStrict;
            return node.finishFunctionExpression(null, paramInfo.@params, paramInfo.defaults, body, isGenerator);
        }