Class Parser


  • public class Parser
    extends java.lang.Object
    This class implements the JavaScript parser.

    It is based on the SpiderMonkey C source files jsparse.c and jsparse.h in the jsref package.

    The parser generates an AstRoot parse tree representing the source code. No tree rewriting is permitted at this stage, so that the parse tree is a faithful representation of the source for frontend processing tools and IDEs.

    This parser implementation is not intended to be reused after a parse finishes, and will throw an IllegalStateException() if invoked again.

    See Also:
    TokenStream
    • Field Detail

      • ARGC_LIMIT

        public static final int ARGC_LIMIT
        Maximum number of allowed function or constructor arguments, to follow SpiderMonkey.
        See Also:
        Constant Field Values
      • sourceURI

        private java.lang.String sourceURI
      • sourceChars

        private char[] sourceChars
      • calledByCompileFunction

        boolean calledByCompileFunction
      • parseFinished

        private boolean parseFinished
      • currentFlaggedToken

        private int currentFlaggedToken
      • currentToken

        private int currentToken
      • syntaxErrorCount

        private int syntaxErrorCount
      • scannedComments

        private java.util.List<Comment> scannedComments
      • currentJsDocComment

        private Comment currentJsDocComment
      • nestingOfFunction

        protected int nestingOfFunction
      • inDestructuringAssignment

        private boolean inDestructuringAssignment
      • inUseStrictDirective

        protected boolean inUseStrictDirective
      • currentScope

        Scope currentScope
      • endFlags

        private int endFlags
      • inForInit

        private boolean inForInit
      • labelSet

        private java.util.Map<java.lang.String,​LabeledStatement> labelSet
      • loopSet

        private java.util.List<Loop> loopSet
      • loopAndSwitchSet

        private java.util.List<Jump> loopAndSwitchSet
      • prevNameTokenStart

        private int prevNameTokenStart
      • prevNameTokenString

        private java.lang.String prevNameTokenString
      • prevNameTokenLineno

        private int prevNameTokenLineno
      • defaultUseStrictDirective

        private boolean defaultUseStrictDirective
    • Method Detail

      • addStrictWarning

        void addStrictWarning​(java.lang.String messageId,
                              java.lang.String messageArg)
      • addStrictWarning

        void addStrictWarning​(java.lang.String messageId,
                              java.lang.String messageArg,
                              int position,
                              int length)
      • addWarning

        void addWarning​(java.lang.String messageId,
                        java.lang.String messageArg)
      • addWarning

        void addWarning​(java.lang.String messageId,
                        int position,
                        int length)
      • addWarning

        void addWarning​(java.lang.String messageId,
                        java.lang.String messageArg,
                        int position,
                        int length)
      • addError

        void addError​(java.lang.String messageId)
      • addError

        void addError​(java.lang.String messageId,
                      int position,
                      int length)
      • addError

        void addError​(java.lang.String messageId,
                      java.lang.String messageArg)
      • addError

        void addError​(java.lang.String messageId,
                      int c)
      • addError

        void addError​(java.lang.String messageId,
                      java.lang.String messageArg,
                      int position,
                      int length)
      • addStrictWarning

        private void addStrictWarning​(java.lang.String messageId,
                                      java.lang.String messageArg,
                                      int position,
                                      int length,
                                      int line,
                                      java.lang.String lineSource,
                                      int lineOffset)
      • addWarning

        private void addWarning​(java.lang.String messageId,
                                java.lang.String messageArg,
                                int position,
                                int length,
                                int line,
                                java.lang.String lineSource,
                                int lineOffset)
      • addError

        private void addError​(java.lang.String messageId,
                              java.lang.String messageArg,
                              int position,
                              int length,
                              int line,
                              java.lang.String lineSource,
                              int lineOffset)
      • lookupMessage

        java.lang.String lookupMessage​(java.lang.String messageId)
      • lookupMessage

        java.lang.String lookupMessage​(java.lang.String messageId,
                                       java.lang.String messageArg)
      • reportError

        void reportError​(java.lang.String messageId)
      • reportError

        void reportError​(java.lang.String messageId,
                         java.lang.String messageArg)
      • reportError

        void reportError​(java.lang.String messageId,
                         int position,
                         int length)
      • reportError

        void reportError​(java.lang.String messageId,
                         java.lang.String messageArg,
                         int position,
                         int length)
      • getNodeEnd

        private static int getNodeEnd​(AstNode n)
      • recordComment

        private void recordComment​(int lineno,
                                   java.lang.String comment)
      • getAndResetJsDoc

        private Comment getAndResetJsDoc()
      • peekToken

        private int peekToken()
                       throws java.io.IOException
        Throws:
        java.io.IOException
      • peekFlaggedToken

        private int peekFlaggedToken()
                              throws java.io.IOException
        Throws:
        java.io.IOException
      • consumeToken

        private void consumeToken()
      • nextToken

        private int nextToken()
                       throws java.io.IOException
        Throws:
        java.io.IOException
      • matchToken

        private boolean matchToken​(int toMatch,
                                   boolean ignoreComment)
                            throws java.io.IOException
        Throws:
        java.io.IOException
      • peekTokenOrEOL

        private int peekTokenOrEOL()
                            throws java.io.IOException
        Throws:
        java.io.IOException
      • mustMatchToken

        private boolean mustMatchToken​(int toMatch,
                                       java.lang.String messageId,
                                       boolean ignoreComment)
                                throws java.io.IOException
        Throws:
        java.io.IOException
      • mustMatchToken

        private boolean mustMatchToken​(int toMatch,
                                       java.lang.String msgId,
                                       int pos,
                                       int len,
                                       boolean ignoreComment)
                                throws java.io.IOException
        Throws:
        java.io.IOException
      • mustHaveXML

        private void mustHaveXML()
      • eof

        public boolean eof()
      • insideFunction

        boolean insideFunction()
      • pushScope

        void pushScope​(Scope scope)
      • popScope

        void popScope()
      • enterLoop

        private void enterLoop​(Loop loop)
      • exitLoop

        private void exitLoop()
      • restoreRelativeLoopPosition

        private void restoreRelativeLoopPosition​(Loop loop)
      • exitSwitch

        private void exitSwitch()
      • parse

        public AstRoot parse​(java.lang.String sourceString,
                             java.lang.String sourceURI,
                             int lineno)
        Builds a parse tree from the given source string.
        Returns:
        an AstRoot object representing the parsed program. If the parse fails, null will be returned. (The parse failure will result in a call to the ErrorReporter from CompilerEnvirons.)
      • parse

        @Deprecated
        public AstRoot parse​(java.io.Reader sourceReader,
                             java.lang.String sourceURI,
                             int lineno)
                      throws java.io.IOException
        Deprecated.
        use parse(String, String, int) instead
        Builds a parse tree from the given sourcereader.
        Throws:
        java.io.IOException - if the Reader encounters an error
        See Also:
        parse(String,String,int)
      • parse

        private AstRoot parse()
                       throws java.io.IOException
        Throws:
        java.io.IOException
      • parseFunctionBody

        private AstNode parseFunctionBody​(int type,
                                          FunctionNode fnNode)
                                   throws java.io.IOException
        Throws:
        java.io.IOException
      • getDirective

        private static java.lang.String getDirective​(AstNode n)
      • parseFunctionParams

        private void parseFunctionParams​(FunctionNode fnNode)
                                  throws java.io.IOException
        Throws:
        java.io.IOException
      • function

        private FunctionNode function​(int type)
                               throws java.io.IOException
        Throws:
        java.io.IOException
      • function

        private FunctionNode function​(int type,
                                      boolean isGenerator)
                               throws java.io.IOException
        Throws:
        java.io.IOException
      • arrowFunction

        private AstNode arrowFunction​(AstNode params)
                               throws java.io.IOException
        Throws:
        java.io.IOException
      • arrowFunctionParams

        private void arrowFunctionParams​(FunctionNode fnNode,
                                         AstNode params,
                                         java.util.Map<java.lang.String,​Node> destructuring,
                                         java.util.Set<java.lang.String> paramNames)
      • statements

        private AstNode statements​(AstNode parent)
                            throws java.io.IOException
        Throws:
        java.io.IOException
      • statements

        private AstNode statements()
                            throws java.io.IOException
        Throws:
        java.io.IOException
      • condition

        private Parser.ConditionData condition()
                                        throws java.io.IOException
        Throws:
        java.io.IOException
      • statement

        private AstNode statement()
                           throws java.io.IOException
        Throws:
        java.io.IOException
      • statementHelper

        private AstNode statementHelper()
                                 throws java.io.IOException
        Throws:
        java.io.IOException
      • autoInsertSemicolon

        private void autoInsertSemicolon​(AstNode pn)
                                  throws java.io.IOException
        Throws:
        java.io.IOException
      • ifStatement

        private IfStatement ifStatement()
                                 throws java.io.IOException
        Throws:
        java.io.IOException
      • switchStatement

        private SwitchStatement switchStatement()
                                         throws java.io.IOException
        Throws:
        java.io.IOException
      • whileLoop

        private WhileLoop whileLoop()
                             throws java.io.IOException
        Throws:
        java.io.IOException
      • doLoop

        private DoLoop doLoop()
                       throws java.io.IOException
        Throws:
        java.io.IOException
      • peekUntilNonComment

        private int peekUntilNonComment​(int tt)
                                 throws java.io.IOException
        Throws:
        java.io.IOException
      • getNextStatementAfterInlineComments

        private AstNode getNextStatementAfterInlineComments​(AstNode pn)
                                                     throws java.io.IOException
        Throws:
        java.io.IOException
      • forLoop

        private Loop forLoop()
                      throws java.io.IOException
        Throws:
        java.io.IOException
      • forLoopInit

        private AstNode forLoopInit​(int tt)
                             throws java.io.IOException
        Throws:
        java.io.IOException
      • tryStatement

        private TryStatement tryStatement()
                                   throws java.io.IOException
        Throws:
        java.io.IOException
      • throwStatement

        private ThrowStatement throwStatement()
                                       throws java.io.IOException
        Throws:
        java.io.IOException
      • matchJumpLabelName

        private LabeledStatement matchJumpLabelName()
                                             throws java.io.IOException
        Throws:
        java.io.IOException
      • breakStatement

        private BreakStatement breakStatement()
                                       throws java.io.IOException
        Throws:
        java.io.IOException
      • continueStatement

        private ContinueStatement continueStatement()
                                             throws java.io.IOException
        Throws:
        java.io.IOException
      • withStatement

        private WithStatement withStatement()
                                     throws java.io.IOException
        Throws:
        java.io.IOException
      • letStatement

        private AstNode letStatement()
                              throws java.io.IOException
        Throws:
        java.io.IOException
      • nowAllSet

        private static final boolean nowAllSet​(int before,
                                               int after,
                                               int mask)
        Returns whether or not the bits in the mask have changed to all set.
        Parameters:
        before - bits before change
        after - bits after change
        mask - mask for bits
        Returns:
        true if all the bits in the mask are set in "after" but not in "before"
      • returnOrYield

        private AstNode returnOrYield​(int tt,
                                      boolean exprContext)
                               throws java.io.IOException
        Throws:
        java.io.IOException
      • block

        private AstNode block()
                       throws java.io.IOException
        Throws:
        java.io.IOException
      • defaultXmlNamespace

        private AstNode defaultXmlNamespace()
                                     throws java.io.IOException
        Throws:
        java.io.IOException
      • recordLabel

        private void recordLabel​(Label label,
                                 LabeledStatement bundle)
                          throws java.io.IOException
        Throws:
        java.io.IOException
      • nameOrLabel

        private AstNode nameOrLabel()
                             throws java.io.IOException
        Found a name in a statement context. If it's a label, we gather up any following labels and the next non-label statement into a LabeledStatement "bundle" and return that. Otherwise we parse an expression and return it wrapped in an ExpressionStatement.
        Throws:
        java.io.IOException
      • variables

        private VariableDeclaration variables​(int declType,
                                              int pos,
                                              boolean isStatement)
                                       throws java.io.IOException
        Parse a 'var' or 'const' statement, or a 'var' init list in a for statement.
        Parameters:
        declType - A token value: either VAR, CONST, or LET depending on context.
        pos - the position where the node should start. It's sometimes the var/const/let keyword, and other times the beginning of the first token in the first variable declaration.
        Returns:
        the parsed variable list
        Throws:
        java.io.IOException
      • let

        private AstNode let​(boolean isStatement,
                            int pos)
                     throws java.io.IOException
        Throws:
        java.io.IOException
      • defineSymbol

        void defineSymbol​(int declType,
                          java.lang.String name)
      • defineSymbol

        void defineSymbol​(int declType,
                          java.lang.String name,
                          boolean ignoreNotInBlock)
      • expr

        private AstNode expr​(boolean allowTrailingComma)
                      throws java.io.IOException
        Throws:
        java.io.IOException
      • assignExpr

        private AstNode assignExpr()
                            throws java.io.IOException
        Throws:
        java.io.IOException
      • condExpr

        private AstNode condExpr()
                          throws java.io.IOException
        Throws:
        java.io.IOException
      • orExpr

        private AstNode orExpr()
                        throws java.io.IOException
        Throws:
        java.io.IOException
      • andExpr

        private AstNode andExpr()
                         throws java.io.IOException
        Throws:
        java.io.IOException
      • bitOrExpr

        private AstNode bitOrExpr()
                           throws java.io.IOException
        Throws:
        java.io.IOException
      • bitXorExpr

        private AstNode bitXorExpr()
                            throws java.io.IOException
        Throws:
        java.io.IOException
      • bitAndExpr

        private AstNode bitAndExpr()
                            throws java.io.IOException
        Throws:
        java.io.IOException
      • eqExpr

        private AstNode eqExpr()
                        throws java.io.IOException
        Throws:
        java.io.IOException
      • relExpr

        private AstNode relExpr()
                         throws java.io.IOException
        Throws:
        java.io.IOException
      • shiftExpr

        private AstNode shiftExpr()
                           throws java.io.IOException
        Throws:
        java.io.IOException
      • addExpr

        private AstNode addExpr()
                         throws java.io.IOException
        Throws:
        java.io.IOException
      • mulExpr

        private AstNode mulExpr()
                         throws java.io.IOException
        Throws:
        java.io.IOException
      • expExpr

        private AstNode expExpr()
                         throws java.io.IOException
        Throws:
        java.io.IOException
      • unaryExpr

        private AstNode unaryExpr()
                           throws java.io.IOException
        Throws:
        java.io.IOException
      • xmlInitializer

        private AstNode xmlInitializer()
                                throws java.io.IOException
        Throws:
        java.io.IOException
      • argumentList

        private java.util.List<AstNode> argumentList()
                                              throws java.io.IOException
        Throws:
        java.io.IOException
      • memberExprTail

        private AstNode memberExprTail​(boolean allowCallSyntax,
                                       AstNode pn)
                                throws java.io.IOException
        Parse any number of "(expr)", "[expr]" ".expr", "..expr", or ".(expr)" constructs trailing the passed expression.
        Parameters:
        pn - the non-null parent node
        Returns:
        the outermost (lexically last occurring) expression, which will have the passed parent node as a descendant
        Throws:
        java.io.IOException
      • taggedTemplateLiteral

        private AstNode taggedTemplateLiteral​(AstNode pn)
                                       throws java.io.IOException
        Throws:
        java.io.IOException
      • propertyAccess

        private AstNode propertyAccess​(int tt,
                                       AstNode pn)
                                throws java.io.IOException
        Handles any construct following a "." or ".." operator.
        Parameters:
        pn - the left-hand side (target) of the operator. Never null.
        Returns:
        a PropertyGet, XmlMemberGet, or ErrorNode
        Throws:
        java.io.IOException
      • attributeAccess

        private AstNode attributeAccess()
                                 throws java.io.IOException
        Xml attribute expression:

        @attr, @ns::attr, @ns::*, @ns::*, @*, @*::attr, @*::*, @ns::[expr], @*::[expr], @[expr]

        Called if we peeked an '@' token.

        Throws:
        java.io.IOException
      • propertyName

        private AstNode propertyName​(int atPos,
                                     int memberTypeFlags)
                              throws java.io.IOException
        Check if :: follows name in which case it becomes a qualified name.
        Parameters:
        atPos - a natural number if we just read an '@' token, else -1
        s - the name or string that was matched (an identifier, "throw" or "*").
        memberTypeFlags - flags tracking whether we're a '.' or '..' child
        Returns:
        an XmlRef node if it's an attribute access, a child of a '..' operator, or the name is followed by ::. For a plain name, returns a Name node. Returns an ErrorNode for malformed XML expressions. (For now - might change to return a partial XmlRef.)
        Throws:
        java.io.IOException
      • xmlElemRef

        private XmlElemRef xmlElemRef​(int atPos,
                                      Name namespace,
                                      int colonPos)
                               throws java.io.IOException
        Parse the [expr] portion of an xml element reference, e.g. @[expr], @*::[expr], or ns::[expr].
        Throws:
        java.io.IOException
      • primaryExpr

        private AstNode primaryExpr()
                             throws java.io.IOException
        Throws:
        java.io.IOException
      • parenExpr

        private AstNode parenExpr()
                           throws java.io.IOException
        Throws:
        java.io.IOException
      • name

        private AstNode name​(int ttFlagged,
                             int tt)
                      throws java.io.IOException
        Throws:
        java.io.IOException
      • arrayComprehension

        private AstNode arrayComprehension​(AstNode result,
                                           int pos)
                                    throws java.io.IOException
        Parse a JavaScript 1.7 Array comprehension.
        Parameters:
        result - the first expression after the opening left-bracket
        pos - start of LB token that begins the array comprehension
        Returns:
        the array comprehension or an error node
        Throws:
        java.io.IOException
      • arrayComprehensionLoop

        private ArrayComprehensionLoop arrayComprehensionLoop()
                                                       throws java.io.IOException
        Throws:
        java.io.IOException
      • generatorExpression

        private AstNode generatorExpression​(AstNode result,
                                            int pos)
                                     throws java.io.IOException
        Throws:
        java.io.IOException
      • generatorExpression

        private AstNode generatorExpression​(AstNode result,
                                            int pos,
                                            boolean inFunctionParams)
                                     throws java.io.IOException
        Throws:
        java.io.IOException
      • generatorExpressionLoop

        private GeneratorExpressionLoop generatorExpressionLoop()
                                                         throws java.io.IOException
        Throws:
        java.io.IOException
      • objectLiteral

        private ObjectLiteral objectLiteral()
                                     throws java.io.IOException
        Throws:
        java.io.IOException
      • objliteralProperty

        private AstNode objliteralProperty()
                                    throws java.io.IOException
        Throws:
        java.io.IOException
      • plainProperty

        private ObjectProperty plainProperty​(AstNode property,
                                             int ptt)
                                      throws java.io.IOException
        Throws:
        java.io.IOException
      • methodDefinition

        private ObjectProperty methodDefinition​(int pos,
                                                AstNode propName,
                                                int entryKind)
                                         throws java.io.IOException
        Throws:
        java.io.IOException
      • createNameNode

        private Name createNameNode()
      • createNameNode

        private Name createNameNode​(boolean checkActivation,
                                    int token)
        Create a Name node using the token info from the last scanned name. In some cases we need to either synthesize a name node, or we lost the name token information by peeking. If the token parameter is not Token.NAME, then we use token info saved in instance vars.
      • createStringLiteral

        private StringLiteral createStringLiteral()
      • templateLiteral

        private AstNode templateLiteral​(boolean isTaggedLiteral)
                                 throws java.io.IOException
        Throws:
        java.io.IOException
      • createTemplateLiteralCharacters

        private TemplateCharacters createTemplateLiteralCharacters​(int pos)
      • createNumericLiteral

        private AstNode createNumericLiteral​(int tt,
                                             boolean isProperty)
      • checkActivationName

        protected void checkActivationName​(java.lang.String name,
                                           int token)
      • setRequiresActivation

        protected void setRequiresActivation()
      • checkCallRequiresActivation

        private void checkCallRequiresActivation​(AstNode pn)
      • setIsGenerator

        protected void setIsGenerator()
      • makeErrorNode

        private ErrorNode makeErrorNode()
      • nodeEnd

        private static int nodeEnd​(AstNode node)
      • saveNameTokenData

        private void saveNameTokenData​(int pos,
                                       java.lang.String name,
                                       int lineno)
      • lineBeginningFor

        private int lineBeginningFor​(int pos)
        Return the file offset of the beginning of the input source line containing the passed position.
        Parameters:
        pos - an offset into the input source stream. If the offset is negative, it's converted to 0, and if it's beyond the end of the source buffer, the last source position is used.
        Returns:
        the offset of the beginning of the line containing pos (i.e. 1+ the offset of the first preceding newline). Returns -1 if the CompilerEnvirons is not set to ide-mode, and parse(java.io.Reader,String,int) was used.
      • warnMissingSemi

        private void warnMissingSemi​(int pos,
                                     int end)
      • warnTrailingComma

        private void warnTrailingComma​(int pos,
                                       java.util.List<?> elems,
                                       int commaPos)
      • createDestructuringAssignment

        Node createDestructuringAssignment​(int type,
                                           Node left,
                                           Node right)
        Given a destructuring assignment with a left hand side parsed as an array or object literal and a right hand side expression, rewrite as a series of assignments to the variables defined in left from property accesses to the expression on the right.
        Parameters:
        type - declaration type: Token.VAR or Token.LET or -1
        left - array or object literal containing NAME nodes for variables to assign
        right - expression to assign from
        Returns:
        expression that performs a series of assignments to the variables defined in left
      • destructuringAssignmentHelper

        Node destructuringAssignmentHelper​(int variableType,
                                           Node left,
                                           Node right,
                                           java.lang.String tempName)
      • destructuringArray

        boolean destructuringArray​(ArrayLiteral array,
                                   int variableType,
                                   java.lang.String tempName,
                                   Node parent,
                                   java.util.List<java.lang.String> destructuringNames)
      • destructuringObject

        boolean destructuringObject​(ObjectLiteral node,
                                    int variableType,
                                    java.lang.String tempName,
                                    Node parent,
                                    java.util.List<java.lang.String> destructuringNames)
      • createName

        protected Node createName​(java.lang.String name)
      • createName

        protected Node createName​(int type,
                                  java.lang.String name,
                                  Node child)
      • createNumber

        protected Node createNumber​(double number)
      • createScopeNode

        protected Scope createScopeNode​(int token,
                                        int lineno)
        Create a node that can be used to hold lexically scoped variable definitions (via let declarations).
        Parameters:
        token - the token of the node to create
        lineno - line number of source
        Returns:
        the created node
      • simpleAssignment

        protected Node simpleAssignment​(Node left,
                                        Node right)
      • checkMutableReference

        protected void checkMutableReference​(Node n)
      • markDestructuring

        void markDestructuring​(AstNode node)
      • codeBug

        private java.lang.RuntimeException codeBug()
                                            throws java.lang.RuntimeException
        Throws:
        java.lang.RuntimeException
      • setDefaultUseStrictDirective

        public void setDefaultUseStrictDirective​(boolean useStrict)
      • inUseStrictDirective

        public boolean inUseStrictDirective()