nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java
changeset 37732 3673fec68d16
parent 36696 39ff39c8e396
child 37835 78bffb8c47c3
equal deleted inserted replaced
37646:84aba7335005 37732:3673fec68d16
    26 package jdk.nashorn.internal.parser;
    26 package jdk.nashorn.internal.parser;
    27 
    27 
    28 import static jdk.nashorn.internal.codegen.CompilerConstants.ANON_FUNCTION_PREFIX;
    28 import static jdk.nashorn.internal.codegen.CompilerConstants.ANON_FUNCTION_PREFIX;
    29 import static jdk.nashorn.internal.codegen.CompilerConstants.EVAL;
    29 import static jdk.nashorn.internal.codegen.CompilerConstants.EVAL;
    30 import static jdk.nashorn.internal.codegen.CompilerConstants.PROGRAM;
    30 import static jdk.nashorn.internal.codegen.CompilerConstants.PROGRAM;
       
    31 import static jdk.nashorn.internal.parser.TokenType.ARROW;
    31 import static jdk.nashorn.internal.parser.TokenType.ASSIGN;
    32 import static jdk.nashorn.internal.parser.TokenType.ASSIGN;
    32 import static jdk.nashorn.internal.parser.TokenType.CASE;
    33 import static jdk.nashorn.internal.parser.TokenType.CASE;
    33 import static jdk.nashorn.internal.parser.TokenType.CATCH;
    34 import static jdk.nashorn.internal.parser.TokenType.CATCH;
       
    35 import static jdk.nashorn.internal.parser.TokenType.CLASS;
    34 import static jdk.nashorn.internal.parser.TokenType.COLON;
    36 import static jdk.nashorn.internal.parser.TokenType.COLON;
    35 import static jdk.nashorn.internal.parser.TokenType.COMMARIGHT;
    37 import static jdk.nashorn.internal.parser.TokenType.COMMARIGHT;
       
    38 import static jdk.nashorn.internal.parser.TokenType.COMMENT;
    36 import static jdk.nashorn.internal.parser.TokenType.CONST;
    39 import static jdk.nashorn.internal.parser.TokenType.CONST;
    37 import static jdk.nashorn.internal.parser.TokenType.DECPOSTFIX;
    40 import static jdk.nashorn.internal.parser.TokenType.DECPOSTFIX;
    38 import static jdk.nashorn.internal.parser.TokenType.DECPREFIX;
    41 import static jdk.nashorn.internal.parser.TokenType.DECPREFIX;
       
    42 import static jdk.nashorn.internal.parser.TokenType.ELLIPSIS;
    39 import static jdk.nashorn.internal.parser.TokenType.ELSE;
    43 import static jdk.nashorn.internal.parser.TokenType.ELSE;
    40 import static jdk.nashorn.internal.parser.TokenType.EOF;
    44 import static jdk.nashorn.internal.parser.TokenType.EOF;
    41 import static jdk.nashorn.internal.parser.TokenType.EOL;
    45 import static jdk.nashorn.internal.parser.TokenType.EOL;
       
    46 import static jdk.nashorn.internal.parser.TokenType.EQ_STRICT;
       
    47 import static jdk.nashorn.internal.parser.TokenType.ESCSTRING;
       
    48 import static jdk.nashorn.internal.parser.TokenType.EXPORT;
       
    49 import static jdk.nashorn.internal.parser.TokenType.EXTENDS;
    42 import static jdk.nashorn.internal.parser.TokenType.FINALLY;
    50 import static jdk.nashorn.internal.parser.TokenType.FINALLY;
    43 import static jdk.nashorn.internal.parser.TokenType.FUNCTION;
    51 import static jdk.nashorn.internal.parser.TokenType.FUNCTION;
    44 import static jdk.nashorn.internal.parser.TokenType.IDENT;
    52 import static jdk.nashorn.internal.parser.TokenType.IDENT;
    45 import static jdk.nashorn.internal.parser.TokenType.IF;
    53 import static jdk.nashorn.internal.parser.TokenType.IF;
       
    54 import static jdk.nashorn.internal.parser.TokenType.IMPORT;
    46 import static jdk.nashorn.internal.parser.TokenType.INCPOSTFIX;
    55 import static jdk.nashorn.internal.parser.TokenType.INCPOSTFIX;
    47 import static jdk.nashorn.internal.parser.TokenType.LBRACE;
    56 import static jdk.nashorn.internal.parser.TokenType.LBRACE;
       
    57 import static jdk.nashorn.internal.parser.TokenType.LBRACKET;
    48 import static jdk.nashorn.internal.parser.TokenType.LET;
    58 import static jdk.nashorn.internal.parser.TokenType.LET;
    49 import static jdk.nashorn.internal.parser.TokenType.LPAREN;
    59 import static jdk.nashorn.internal.parser.TokenType.LPAREN;
       
    60 import static jdk.nashorn.internal.parser.TokenType.MUL;
       
    61 import static jdk.nashorn.internal.parser.TokenType.PERIOD;
    50 import static jdk.nashorn.internal.parser.TokenType.RBRACE;
    62 import static jdk.nashorn.internal.parser.TokenType.RBRACE;
    51 import static jdk.nashorn.internal.parser.TokenType.RBRACKET;
    63 import static jdk.nashorn.internal.parser.TokenType.RBRACKET;
    52 import static jdk.nashorn.internal.parser.TokenType.RPAREN;
    64 import static jdk.nashorn.internal.parser.TokenType.RPAREN;
    53 import static jdk.nashorn.internal.parser.TokenType.SEMICOLON;
    65 import static jdk.nashorn.internal.parser.TokenType.SEMICOLON;
       
    66 import static jdk.nashorn.internal.parser.TokenType.SPREAD_ARRAY;
       
    67 import static jdk.nashorn.internal.parser.TokenType.STATIC;
       
    68 import static jdk.nashorn.internal.parser.TokenType.STRING;
       
    69 import static jdk.nashorn.internal.parser.TokenType.SUPER;
    54 import static jdk.nashorn.internal.parser.TokenType.TEMPLATE;
    70 import static jdk.nashorn.internal.parser.TokenType.TEMPLATE;
    55 import static jdk.nashorn.internal.parser.TokenType.TEMPLATE_HEAD;
    71 import static jdk.nashorn.internal.parser.TokenType.TEMPLATE_HEAD;
    56 import static jdk.nashorn.internal.parser.TokenType.TEMPLATE_MIDDLE;
    72 import static jdk.nashorn.internal.parser.TokenType.TEMPLATE_MIDDLE;
    57 import static jdk.nashorn.internal.parser.TokenType.TEMPLATE_TAIL;
    73 import static jdk.nashorn.internal.parser.TokenType.TEMPLATE_TAIL;
    58 import static jdk.nashorn.internal.parser.TokenType.TERNARY;
    74 import static jdk.nashorn.internal.parser.TokenType.TERNARY;
       
    75 import static jdk.nashorn.internal.parser.TokenType.VAR;
       
    76 import static jdk.nashorn.internal.parser.TokenType.VOID;
    59 import static jdk.nashorn.internal.parser.TokenType.WHILE;
    77 import static jdk.nashorn.internal.parser.TokenType.WHILE;
       
    78 import static jdk.nashorn.internal.parser.TokenType.YIELD;
       
    79 import static jdk.nashorn.internal.parser.TokenType.YIELD_STAR;
    60 
    80 
    61 import java.io.Serializable;
    81 import java.io.Serializable;
    62 import java.util.ArrayDeque;
    82 import java.util.ArrayDeque;
    63 import java.util.ArrayList;
    83 import java.util.ArrayList;
    64 import java.util.Collections;
    84 import java.util.Collections;
    66 import java.util.HashMap;
    86 import java.util.HashMap;
    67 import java.util.HashSet;
    87 import java.util.HashSet;
    68 import java.util.Iterator;
    88 import java.util.Iterator;
    69 import java.util.List;
    89 import java.util.List;
    70 import java.util.Map;
    90 import java.util.Map;
       
    91 import java.util.Objects;
       
    92 import java.util.function.Consumer;
    71 import jdk.nashorn.internal.codegen.CompilerConstants;
    93 import jdk.nashorn.internal.codegen.CompilerConstants;
    72 import jdk.nashorn.internal.codegen.Namespace;
    94 import jdk.nashorn.internal.codegen.Namespace;
    73 import jdk.nashorn.internal.ir.AccessNode;
    95 import jdk.nashorn.internal.ir.AccessNode;
    74 import jdk.nashorn.internal.ir.BaseNode;
    96 import jdk.nashorn.internal.ir.BaseNode;
    75 import jdk.nashorn.internal.ir.BinaryNode;
    97 import jdk.nashorn.internal.ir.BinaryNode;
    77 import jdk.nashorn.internal.ir.BlockStatement;
    99 import jdk.nashorn.internal.ir.BlockStatement;
    78 import jdk.nashorn.internal.ir.BreakNode;
   100 import jdk.nashorn.internal.ir.BreakNode;
    79 import jdk.nashorn.internal.ir.CallNode;
   101 import jdk.nashorn.internal.ir.CallNode;
    80 import jdk.nashorn.internal.ir.CaseNode;
   102 import jdk.nashorn.internal.ir.CaseNode;
    81 import jdk.nashorn.internal.ir.CatchNode;
   103 import jdk.nashorn.internal.ir.CatchNode;
       
   104 import jdk.nashorn.internal.ir.ClassNode;
    82 import jdk.nashorn.internal.ir.ContinueNode;
   105 import jdk.nashorn.internal.ir.ContinueNode;
    83 import jdk.nashorn.internal.ir.DebuggerNode;
   106 import jdk.nashorn.internal.ir.DebuggerNode;
    84 import jdk.nashorn.internal.ir.EmptyNode;
   107 import jdk.nashorn.internal.ir.EmptyNode;
    85 import jdk.nashorn.internal.ir.ErrorNode;
   108 import jdk.nashorn.internal.ir.ErrorNode;
    86 import jdk.nashorn.internal.ir.Expression;
   109 import jdk.nashorn.internal.ir.Expression;
       
   110 import jdk.nashorn.internal.ir.ExpressionList;
    87 import jdk.nashorn.internal.ir.ExpressionStatement;
   111 import jdk.nashorn.internal.ir.ExpressionStatement;
    88 import jdk.nashorn.internal.ir.ForNode;
   112 import jdk.nashorn.internal.ir.ForNode;
    89 import jdk.nashorn.internal.ir.FunctionNode;
   113 import jdk.nashorn.internal.ir.FunctionNode;
    90 import jdk.nashorn.internal.ir.IdentNode;
   114 import jdk.nashorn.internal.ir.IdentNode;
    91 import jdk.nashorn.internal.ir.IfNode;
   115 import jdk.nashorn.internal.ir.IfNode;
    92 import jdk.nashorn.internal.ir.IndexNode;
   116 import jdk.nashorn.internal.ir.IndexNode;
    93 import jdk.nashorn.internal.ir.JoinPredecessorExpression;
   117 import jdk.nashorn.internal.ir.JoinPredecessorExpression;
    94 import jdk.nashorn.internal.ir.LabelNode;
   118 import jdk.nashorn.internal.ir.LabelNode;
       
   119 import jdk.nashorn.internal.ir.LexicalContext;
    95 import jdk.nashorn.internal.ir.LiteralNode;
   120 import jdk.nashorn.internal.ir.LiteralNode;
       
   121 import jdk.nashorn.internal.ir.Module;
    96 import jdk.nashorn.internal.ir.Node;
   122 import jdk.nashorn.internal.ir.Node;
    97 import jdk.nashorn.internal.ir.ObjectNode;
   123 import jdk.nashorn.internal.ir.ObjectNode;
    98 import jdk.nashorn.internal.ir.PropertyKey;
   124 import jdk.nashorn.internal.ir.PropertyKey;
    99 import jdk.nashorn.internal.ir.PropertyNode;
   125 import jdk.nashorn.internal.ir.PropertyNode;
   100 import jdk.nashorn.internal.ir.ReturnNode;
   126 import jdk.nashorn.internal.ir.ReturnNode;
   108 import jdk.nashorn.internal.ir.VarNode;
   134 import jdk.nashorn.internal.ir.VarNode;
   109 import jdk.nashorn.internal.ir.WhileNode;
   135 import jdk.nashorn.internal.ir.WhileNode;
   110 import jdk.nashorn.internal.ir.WithNode;
   136 import jdk.nashorn.internal.ir.WithNode;
   111 import jdk.nashorn.internal.ir.debug.ASTWriter;
   137 import jdk.nashorn.internal.ir.debug.ASTWriter;
   112 import jdk.nashorn.internal.ir.debug.PrintVisitor;
   138 import jdk.nashorn.internal.ir.debug.PrintVisitor;
       
   139 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
   113 import jdk.nashorn.internal.runtime.Context;
   140 import jdk.nashorn.internal.runtime.Context;
   114 import jdk.nashorn.internal.runtime.ErrorManager;
   141 import jdk.nashorn.internal.runtime.ErrorManager;
   115 import jdk.nashorn.internal.runtime.JSErrorType;
   142 import jdk.nashorn.internal.runtime.JSErrorType;
   116 import jdk.nashorn.internal.runtime.ParserException;
   143 import jdk.nashorn.internal.runtime.ParserException;
   117 import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
   144 import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
   252     public FunctionNode parse() {
   279     public FunctionNode parse() {
   253         return parse(PROGRAM.symbolName(), 0, source.getLength(), false);
   280         return parse(PROGRAM.symbolName(), 0, source.getLength(), false);
   254     }
   281     }
   255 
   282 
   256     /**
   283     /**
       
   284      * Set up first token. Skips opening EOL.
       
   285      */
       
   286     private void scanFirstToken() {
       
   287         k = -1;
       
   288         next();
       
   289     }
       
   290 
       
   291     /**
   257      * Execute parse and return the resulting function node.
   292      * Execute parse and return the resulting function node.
   258      * Errors will be thrown and the error manager will contain information
   293      * Errors will be thrown and the error manager will contain information
   259      * if parsing should fail
   294      * if parsing should fail
   260      *
   295      *
   261      * This should be used to create one and only one function node
   296      * This should be used to create one and only one function node
   278             stream = new TokenStream();
   313             stream = new TokenStream();
   279             lexer  = new Lexer(source, startPos, len, stream, scripting && !env._no_syntax_extensions, env._es6, reparsedFunction != null);
   314             lexer  = new Lexer(source, startPos, len, stream, scripting && !env._no_syntax_extensions, env._es6, reparsedFunction != null);
   280             lexer.line = lexer.pendingLine = lineOffset + 1;
   315             lexer.line = lexer.pendingLine = lineOffset + 1;
   281             line = lineOffset;
   316             line = lineOffset;
   282 
   317 
   283             // Set up first token (skips opening EOL.)
   318             scanFirstToken();
   284             k = -1;
       
   285             next();
       
   286             // Begin parse.
   319             // Begin parse.
   287             return program(scriptName, allowPropertyFunction);
   320             return program(scriptName, allowPropertyFunction);
   288         } catch (final Exception e) {
   321         } catch (final Exception e) {
   289             handleParseException(e);
   322             handleParseException(e);
   290 
   323 
   299             }
   332             }
   300         }
   333         }
   301     }
   334     }
   302 
   335 
   303     /**
   336     /**
       
   337      * Parse and return the resulting module.
       
   338      * Errors will be thrown and the error manager will contain information
       
   339      * if parsing should fail
       
   340      *
       
   341      * @param moduleName name for the module, given to the parsed FunctionNode
       
   342      * @param startPos start position in source
       
   343      * @param len length of parse
       
   344      *
       
   345      * @return function node resulting from successful parse
       
   346      */
       
   347     public FunctionNode parseModule(final String moduleName, final int startPos, final int len) {
       
   348         try {
       
   349             stream = new TokenStream();
       
   350             lexer  = new Lexer(source, startPos, len, stream, scripting && !env._no_syntax_extensions, env._es6, reparsedFunction != null);
       
   351             lexer.line = lexer.pendingLine = lineOffset + 1;
       
   352             line = lineOffset;
       
   353 
       
   354             scanFirstToken();
       
   355             // Begin parse.
       
   356             return module(moduleName);
       
   357         } catch (final Exception e) {
       
   358             handleParseException(e);
       
   359 
       
   360             return null;
       
   361         }
       
   362     }
       
   363 
       
   364     /**
       
   365      * Entry point for parsing a module.
       
   366      *
       
   367      * @param moduleName the module name
       
   368      * @return the parsed module
       
   369      */
       
   370     public FunctionNode parseModule(final String moduleName) {
       
   371         return parseModule(moduleName, 0, source.getLength());
       
   372     }
       
   373 
       
   374     /**
   304      * Parse and return the list of function parameter list. A comma
   375      * Parse and return the list of function parameter list. A comma
   305      * separated list of function parameter identifiers is expected to be parsed.
   376      * separated list of function parameter identifiers is expected to be parsed.
   306      * Errors will be thrown and the error manager will contain information
   377      * Errors will be thrown and the error manager will contain information
   307      * if parsing should fail. This method is used to check if parameter Strings
   378      * if parsing should fail. This method is used to check if parameter Strings
   308      * passed to "Function" constructor is a valid or not.
   379      * passed to "Function" constructor is a valid or not.
   312     public List<IdentNode> parseFormalParameterList() {
   383     public List<IdentNode> parseFormalParameterList() {
   313         try {
   384         try {
   314             stream = new TokenStream();
   385             stream = new TokenStream();
   315             lexer  = new Lexer(source, stream, scripting && !env._no_syntax_extensions, env._es6);
   386             lexer  = new Lexer(source, stream, scripting && !env._no_syntax_extensions, env._es6);
   316 
   387 
   317             // Set up first token (skips opening EOL.)
   388             scanFirstToken();
   318             k = -1;
   389 
   319             next();
   390             return formalParameterList(TokenType.EOF, false);
   320 
       
   321             return formalParameterList(TokenType.EOF);
       
   322         } catch (final Exception e) {
   391         } catch (final Exception e) {
   323             handleParseException(e);
   392             handleParseException(e);
   324             return null;
   393             return null;
   325         }
   394         }
   326     }
   395     }
   337         try {
   406         try {
   338             stream = new TokenStream();
   407             stream = new TokenStream();
   339             lexer  = new Lexer(source, stream, scripting && !env._no_syntax_extensions, env._es6);
   408             lexer  = new Lexer(source, stream, scripting && !env._no_syntax_extensions, env._es6);
   340             final int functionLine = line;
   409             final int functionLine = line;
   341 
   410 
   342             // Set up first token (skips opening EOL.)
   411             scanFirstToken();
   343             k = -1;
       
   344             next();
       
   345 
   412 
   346             // Make a fake token for the function.
   413             // Make a fake token for the function.
   347             final long functionToken = Token.toDesc(FUNCTION, 0, source.getLength());
   414             final long functionToken = Token.toDesc(FUNCTION, 0, source.getLength());
   348             // Set up the function to append elements.
   415             // Set up the function to append elements.
   349 
   416 
   430                 e.printStackTrace(env.getErr());
   497                 e.printStackTrace(env.getErr());
   431             }
   498             }
   432         }
   499         }
   433 
   500 
   434         // Skip to a recovery point.
   501         // Skip to a recovery point.
   435 loop:
   502         loop:
   436         while (true) {
   503         while (true) {
   437             switch (type) {
   504             switch (type) {
   438             case EOF:
   505             case EOF:
   439                 // Can not go any further.
   506                 // Can not go any further.
   440                 break loop;
   507                 break loop;
   472 
   539 
   473         assert ident.getName() != null;
   540         assert ident.getName() != null;
   474         sb.append(ident.getName());
   541         sb.append(ident.getName());
   475 
   542 
   476         final String name = namespace.uniqueName(sb.toString());
   543         final String name = namespace.uniqueName(sb.toString());
   477         assert parentFunction != null || name.equals(PROGRAM.symbolName()) || name.startsWith(RecompilableScriptFunctionData.RECOMPILATION_PREFIX) : "name = " + name;
   544         assert parentFunction != null || name.equals(PROGRAM.symbolName()) : "name = " + name;
   478 
   545 
   479         int flags = 0;
   546         int flags = 0;
   480         if (isStrictMode) {
   547         if (isStrictMode) {
   481             flags |= FunctionNode.IS_STRICT;
   548             flags |= FunctionNode.IS_STRICT;
   482         }
   549         }
   487         final ParserContextFunctionNode functionNode = new ParserContextFunctionNode(functionToken, ident, name, namespace, functionLine, kind, parameters);
   554         final ParserContextFunctionNode functionNode = new ParserContextFunctionNode(functionToken, ident, name, namespace, functionLine, kind, parameters);
   488         functionNode.setFlag(flags);
   555         functionNode.setFlag(flags);
   489         return functionNode;
   556         return functionNode;
   490     }
   557     }
   491 
   558 
   492     private FunctionNode createFunctionNode(final ParserContextFunctionNode function, final long startToken, final IdentNode ident, final List<IdentNode> parameters, final FunctionNode.Kind kind, final int functionLine, final Block body){
   559     private FunctionNode createFunctionNode(final ParserContextFunctionNode function, final long startToken, final IdentNode ident, final List<IdentNode> parameters, final FunctionNode.Kind kind, final int functionLine, final Block body) {
       
   560         // assert body.isFunctionBody() || body.getFlag(Block.IS_PARAMETER_BLOCK) && ((BlockStatement) body.getLastStatement()).getBlock().isFunctionBody();
   493         // Start new block.
   561         // Start new block.
   494         final FunctionNode functionNode =
   562         final FunctionNode functionNode =
   495             new FunctionNode(
   563             new FunctionNode(
   496                 source,
   564                 source,
   497                 functionLine,
   565                 functionLine,
   504                 function.getName(),
   572                 function.getName(),
   505                 parameters,
   573                 parameters,
   506                 kind,
   574                 kind,
   507                 function.getFlags(),
   575                 function.getFlags(),
   508                 body,
   576                 body,
   509                 function.getEndParserState());
   577                 function.getEndParserState(),
       
   578                 function.getModule(),
       
   579                 function.getDebugFlags());
   510 
   580 
   511         printAST(functionNode);
   581         printAST(functionNode);
   512 
   582 
   513         return functionNode;
   583         return functionNode;
   514     }
   584     }
   542         // Block closing brace.
   612         // Block closing brace.
   543         if (needsBraces) {
   613         if (needsBraces) {
   544             expect(RBRACE);
   614             expect(RBRACE);
   545         }
   615         }
   546 
   616 
   547         final int flags = newBlock.getFlags() | (needsBraces? 0 : Block.IS_SYNTHETIC);
   617         final int flags = newBlock.getFlags() | (needsBraces ? 0 : Block.IS_SYNTHETIC);
   548         return new Block(blockToken, finish, flags, newBlock.getStatements());
   618         return new Block(blockToken, finish, flags, newBlock.getStatements());
   549     }
   619     }
   550 
   620 
       
   621     /**
       
   622      * Get the statements in a case clause.
       
   623      */
       
   624     private List<Statement> caseStatementList() {
       
   625         final ParserContextBlockNode newBlock = newBlock();
       
   626         try {
       
   627             statementList();
       
   628         } finally {
       
   629             restoreBlock(newBlock);
       
   630         }
       
   631         return newBlock.getStatements();
       
   632     }
   551 
   633 
   552     /**
   634     /**
   553      * Get all the statements generated by a single statement.
   635      * Get all the statements generated by a single statement.
   554      * @return Statements.
   636      * @return Statements.
   555      */
   637      */
   556     private Block getStatement() {
   638     private Block getStatement() {
       
   639         return getStatement(false);
       
   640     }
       
   641 
       
   642     private Block getStatement(boolean labelledStatement) {
   557         if (type == LBRACE) {
   643         if (type == LBRACE) {
   558             return getBlock(true);
   644             return getBlock(true);
   559         }
   645         }
   560         // Set up new block. Captures first token.
   646         // Set up new block. Captures first token.
   561         final ParserContextBlockNode newBlock = newBlock();
   647         final ParserContextBlockNode newBlock = newBlock();
   562         try {
   648         try {
   563             statement(false, false, true);
   649             statement(false, false, true, labelledStatement);
   564         } finally {
   650         } finally {
   565             restoreBlock(newBlock);
   651             restoreBlock(newBlock);
   566         }
   652         }
   567         return new Block(newBlock.getToken(), finish, newBlock.getFlags() | Block.IS_SYNTHETIC, newBlock.getStatements());
   653         return new Block(newBlock.getToken(), finish, newBlock.getFlags() | Block.IS_SYNTHETIC, newBlock.getStatements());
   568     }
   654     }
   574     private void detectSpecialFunction(final IdentNode ident) {
   660     private void detectSpecialFunction(final IdentNode ident) {
   575         final String name = ident.getName();
   661         final String name = ident.getName();
   576 
   662 
   577         if (EVAL.symbolName().equals(name)) {
   663         if (EVAL.symbolName().equals(name)) {
   578             markEval(lc);
   664             markEval(lc);
       
   665         } else if (SUPER.getName().equals(name)) {
       
   666             assert ident.isDirectSuper();
       
   667             markSuperCall(lc);
   579         }
   668         }
   580     }
   669     }
   581 
   670 
   582     /**
   671     /**
   583      * Detect use of special properties.
   672      * Detect use of special properties.
   584      * @param ident Referenced property.
   673      * @param ident Referenced property.
   585      */
   674      */
   586     private void detectSpecialProperty(final IdentNode ident) {
   675     private void detectSpecialProperty(final IdentNode ident) {
   587         if (isArguments(ident)) {
   676         if (isArguments(ident)) {
   588             lc.getCurrentFunction().setFlag(FunctionNode.USES_ARGUMENTS);
   677             // skip over arrow functions, e.g. function f() { return (() => arguments.length)(); }
       
   678             getCurrentNonArrowFunction().setFlag(FunctionNode.USES_ARGUMENTS);
   589         }
   679         }
   590     }
   680     }
   591 
   681 
   592     private boolean useBlockScope() {
   682     private boolean useBlockScope() {
   593         return env._es6;
   683         return env._es6;
   594     }
   684     }
   595 
   685 
       
   686     private boolean isES6() {
       
   687         return env._es6;
       
   688     }
       
   689 
   596     private static boolean isArguments(final String name) {
   690     private static boolean isArguments(final String name) {
   597         return ARGUMENTS_NAME.equals(name);
   691         return ARGUMENTS_NAME.equals(name);
   598     }
   692     }
   599 
   693 
   600     private static boolean isArguments(final IdentNode ident) {
   694     static boolean isArguments(final IdentNode ident) {
   601         return isArguments(ident.getName());
   695         return isArguments(ident.getName());
   602     }
   696     }
   603 
   697 
   604     /**
   698     /**
   605      * Tells whether a IdentNode can be used as L-value of an assignment
   699      * Tells whether a IdentNode can be used as L-value of an assignment
   632         case ASSIGN_MUL:
   726         case ASSIGN_MUL:
   633         case ASSIGN_SAR:
   727         case ASSIGN_SAR:
   634         case ASSIGN_SHL:
   728         case ASSIGN_SHL:
   635         case ASSIGN_SHR:
   729         case ASSIGN_SHR:
   636         case ASSIGN_SUB:
   730         case ASSIGN_SUB:
   637             if (!(lhs instanceof AccessNode ||
       
   638                   lhs instanceof IndexNode ||
       
   639                   lhs instanceof IdentNode)) {
       
   640                 return referenceError(lhs, rhs, env._early_lvalue_error);
       
   641             }
       
   642 
       
   643             if (lhs instanceof IdentNode) {
   731             if (lhs instanceof IdentNode) {
   644                 if (!checkIdentLValue((IdentNode)lhs)) {
   732                 if (!checkIdentLValue((IdentNode)lhs)) {
   645                     return referenceError(lhs, rhs, false);
   733                     return referenceError(lhs, rhs, false);
   646                 }
   734                 }
   647                 verifyStrictIdent((IdentNode)lhs, "assignment");
   735                 verifyIdent((IdentNode)lhs, "assignment");
   648             }
   736                 break;
   649             break;
   737             } else if (lhs instanceof AccessNode || lhs instanceof IndexNode) {
   650 
   738                 break;
       
   739             } else if (opType == ASSIGN && isDestructuringLhs(lhs)) {
       
   740                 verifyDestructuringAssignmentPattern(lhs, "assignment");
       
   741                 break;
       
   742             } else {
       
   743                 return referenceError(lhs, rhs, env._early_lvalue_error);
       
   744             }
   651         default:
   745         default:
   652             break;
   746             break;
   653         }
   747         }
   654 
   748 
   655         // Build up node.
   749         // Build up node.
   656         if(BinaryNode.isLogical(opType)) {
   750         if(BinaryNode.isLogical(opType)) {
       
   751             return new BinaryNode(op, new JoinPredecessorExpression(lhs), new JoinPredecessorExpression(rhs));
       
   752         }
       
   753         return new BinaryNode(op, lhs, rhs);
       
   754     }
       
   755 
       
   756     private boolean isDestructuringLhs(Expression lhs) {
       
   757         if (lhs instanceof ObjectNode || lhs instanceof LiteralNode.ArrayLiteralNode) {
       
   758             return isES6();
       
   759         }
       
   760         return false;
       
   761     }
       
   762 
       
   763     private void verifyDestructuringAssignmentPattern(Expression pattern, String contextString) {
       
   764         assert pattern instanceof ObjectNode || pattern instanceof LiteralNode.ArrayLiteralNode;
       
   765         pattern.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
       
   766             @Override
       
   767             public boolean enterLiteralNode(LiteralNode<?> literalNode) {
       
   768                 if (literalNode.isArray()) {
       
   769                     boolean restElement = false;
       
   770                     for (Expression element : literalNode.getElementExpressions()) {
       
   771                         if (element != null) {
       
   772                             if (restElement) {
       
   773                                 throw error(String.format("Unexpected element after rest element"), element.getToken());
       
   774                             }
       
   775                             if (element.isTokenType(SPREAD_ARRAY)) {
       
   776                                 restElement = true;
       
   777                                 Expression lvalue = ((UnaryNode) element).getExpression();
       
   778                                 if (!checkValidLValue(lvalue, contextString)) {
       
   779                                     throw error(AbstractParser.message("invalid.lvalue"), lvalue.getToken());
       
   780                                 }
       
   781                             }
       
   782                             element.accept(this);
       
   783                         }
       
   784                     }
       
   785                     return false;
       
   786                 } else {
       
   787                     return enterDefault(literalNode);
       
   788                 }
       
   789             }
       
   790 
       
   791             @Override
       
   792             public boolean enterObjectNode(ObjectNode objectNode) {
       
   793                 return true;
       
   794             }
       
   795 
       
   796             @Override
       
   797             public boolean enterPropertyNode(PropertyNode propertyNode) {
       
   798                 if (propertyNode.getValue() != null) {
       
   799                     propertyNode.getValue().accept(this);
       
   800                     return false;
       
   801                 } else {
       
   802                     return enterDefault(propertyNode);
       
   803                 }
       
   804             }
       
   805 
       
   806             @Override
       
   807             public boolean enterIdentNode(IdentNode identNode) {
       
   808                 verifyIdent(identNode, contextString);
       
   809                 if (!checkIdentLValue(identNode)) {
       
   810                     referenceError(identNode, null, true);
       
   811                     return false;
       
   812                 }
       
   813                 return false;
       
   814             }
       
   815 
       
   816             @Override
       
   817             public boolean enterAccessNode(AccessNode accessNode) {
       
   818                 return false;
       
   819             }
       
   820 
       
   821             @Override
       
   822             public boolean enterIndexNode(IndexNode indexNode) {
       
   823                 return false;
       
   824             }
       
   825 
       
   826             @Override
       
   827             public boolean enterBinaryNode(BinaryNode binaryNode) {
       
   828                 if (binaryNode.isTokenType(ASSIGN)) {
       
   829                     binaryNode.lhs().accept(this);
       
   830                     // Initializer(rhs) can be any AssignmentExpression
       
   831                     return false;
       
   832                 } else {
       
   833                     return enterDefault(binaryNode);
       
   834                 }
       
   835             }
       
   836 
       
   837             @Override
       
   838             public boolean enterUnaryNode(UnaryNode unaryNode) {
       
   839                 if (unaryNode.isTokenType(SPREAD_ARRAY)) {
       
   840                     // rest element
       
   841                     return true;
       
   842                 } else {
       
   843                     return enterDefault(unaryNode);
       
   844                 }
       
   845             }
       
   846 
       
   847             @Override
       
   848             protected boolean enterDefault(Node node) {
       
   849                 throw error(String.format("unexpected node in AssignmentPattern: %s", node));
       
   850             }
       
   851         });
       
   852     }
       
   853 
       
   854     private static Expression newBinaryExpression(final long op, final Expression lhs, final Expression rhs) {
       
   855         final TokenType opType = Token.descType(op);
       
   856 
       
   857         // Build up node.
       
   858         if (BinaryNode.isLogical(opType)) {
   657             return new BinaryNode(op, new JoinPredecessorExpression(lhs), new JoinPredecessorExpression(rhs));
   859             return new BinaryNode(op, new JoinPredecessorExpression(lhs), new JoinPredecessorExpression(rhs));
   658         }
   860         }
   659         return new BinaryNode(op, lhs, rhs);
   861         return new BinaryNode(op, lhs, rhs);
   660     }
   862     }
   661 
   863 
   715         addFunctionDeclarations(script);
   917         addFunctionDeclarations(script);
   716         functionDeclarations = null;
   918         functionDeclarations = null;
   717 
   919 
   718         restoreBlock(body);
   920         restoreBlock(body);
   719         body.setFlag(Block.NEEDS_SCOPE);
   921         body.setFlag(Block.NEEDS_SCOPE);
   720         final Block programBody = new Block(functionToken, finish, body.getFlags() | Block.IS_SYNTHETIC, body.getStatements());
   922         final Block programBody = new Block(functionToken, finish, body.getFlags() | Block.IS_SYNTHETIC | Block.IS_BODY, body.getStatements());
   721         lc.pop(script);
   923         lc.pop(script);
   722         script.setLastToken(token);
   924         script.setLastToken(token);
   723 
   925 
   724         expect(EOF);
   926         expect(EOF);
   725 
   927 
   774                     break;
   976                     break;
   775                 }
   977                 }
   776 
   978 
   777                 try {
   979                 try {
   778                     // Get the next element.
   980                     // Get the next element.
   779                     statement(true, allowPropertyFunction, false);
   981                     statement(true, allowPropertyFunction, false, false);
   780                     allowPropertyFunction = false;
   982                     allowPropertyFunction = false;
   781 
   983 
   782                     // check for directive prologues
   984                     // check for directive prologues
   783                     if (checkDirective) {
   985                     if (checkDirective) {
   784                         // skip any debug statement like line number to get actual first line
   986                         // skip any debug statement like line number to get actual first line
   814                                         getValue(statement.getToken());
  1016                                         getValue(statement.getToken());
   815                                     }
  1017                                     }
   816 
  1018 
   817                                     // verify that function name as well as parameter names
  1019                                     // verify that function name as well as parameter names
   818                                     // satisfy strict mode restrictions.
  1020                                     // satisfy strict mode restrictions.
   819                                     verifyStrictIdent(function.getIdent(), "function name");
  1021                                     verifyIdent(function.getIdent(), "function name");
   820                                     for (final IdentNode param : function.getParameters()) {
  1022                                     for (final IdentNode param : function.getParameters()) {
   821                                         verifyStrictIdent(param, "function parameter");
  1023                                         verifyIdent(param, "function parameter");
   822                                     }
  1024                                     }
   823                                 }
  1025                                 }
   824                             } else if (Context.DEBUG) {
  1026                             } else if (Context.DEBUG) {
   825                                 final int flag = FunctionNode.getDirectiveFlag(directive);
  1027                                 final int debugFlag = FunctionNode.getDirectiveFlag(directive);
   826                                 if (flag != 0) {
  1028                                 if (debugFlag != 0) {
   827                                     final ParserContextFunctionNode function = lc.getCurrentFunction();
  1029                                     final ParserContextFunctionNode function = lc.getCurrentFunction();
   828                                     function.setFlag(flag);
  1030                                     function.setDebugFlag(debugFlag);
   829                                 }
  1031                                 }
   830                             }
  1032                             }
   831                         }
  1033                         }
   832                     }
  1034                     }
   833                 } catch (final Exception e) {
  1035                 } catch (final Exception e) {
   847             isStrictMode = oldStrictMode;
  1049             isStrictMode = oldStrictMode;
   848         }
  1050         }
   849     }
  1051     }
   850 
  1052 
   851     /**
  1053     /**
       
  1054      * Parse any of the basic statement types.
       
  1055      *
   852      * Statement :
  1056      * Statement :
   853      *      Block
  1057      *      BlockStatement
   854      *      VariableStatement
  1058      *      VariableStatement
   855      *      EmptyStatement
  1059      *      EmptyStatement
   856      *      ExpressionStatement
  1060      *      ExpressionStatement
   857      *      IfStatement
  1061      *      IfStatement
   858      *      IterationStatement
  1062      *      BreakableStatement
   859      *      ContinueStatement
  1063      *      ContinueStatement
   860      *      BreakStatement
  1064      *      BreakStatement
   861      *      ReturnStatement
  1065      *      ReturnStatement
   862      *      WithStatement
  1066      *      WithStatement
   863      *      LabelledStatement
  1067      *      LabelledStatement
   864      *      SwitchStatement
       
   865      *      ThrowStatement
  1068      *      ThrowStatement
   866      *      TryStatement
  1069      *      TryStatement
   867      *      DebuggerStatement
  1070      *      DebuggerStatement
   868      *
  1071      *
   869      * see 12
  1072      * BreakableStatement :
   870      *
  1073      *      IterationStatement
   871      * Parse any of the basic statement types.
  1074      *      SwitchStatement
       
  1075      *
       
  1076      * BlockStatement :
       
  1077      *      Block
       
  1078      *
       
  1079      * Block :
       
  1080      *      { StatementList opt }
       
  1081      *
       
  1082      * StatementList :
       
  1083      *      StatementListItem
       
  1084      *      StatementList StatementListItem
       
  1085      *
       
  1086      * StatementItem :
       
  1087      *      Statement
       
  1088      *      Declaration
       
  1089      *
       
  1090      * Declaration :
       
  1091      *     HoistableDeclaration
       
  1092      *     ClassDeclaration
       
  1093      *     LexicalDeclaration
       
  1094      *
       
  1095      * HoistableDeclaration :
       
  1096      *     FunctionDeclaration
       
  1097      *     GeneratorDeclaration
   872      */
  1098      */
   873     private void statement() {
  1099     private void statement() {
   874         statement(false, false, false);
  1100         statement(false, false, false, false);
   875     }
  1101     }
   876 
  1102 
   877     /**
  1103     /**
   878      * @param topLevel does this statement occur at the "top level" of a script or a function?
  1104      * @param topLevel does this statement occur at the "top level" of a script or a function?
   879      * @param allowPropertyFunction allow property "get" and "set" functions?
  1105      * @param allowPropertyFunction allow property "get" and "set" functions?
   880      * @param singleStatement are we in a single statement context?
  1106      * @param singleStatement are we in a single statement context?
   881      */
  1107      */
   882     private void statement(final boolean topLevel, final boolean allowPropertyFunction, final boolean singleStatement) {
  1108     private void statement(final boolean topLevel, final boolean allowPropertyFunction, final boolean singleStatement, final boolean labelledStatement) {
   883         if (type == FUNCTION) {
       
   884             // As per spec (ECMA section 12), function declarations as arbitrary statement
       
   885             // is not "portable". Implementation can issue a warning or disallow the same.
       
   886             functionExpression(true, topLevel);
       
   887             return;
       
   888         }
       
   889 
       
   890         switch (type) {
  1109         switch (type) {
   891         case LBRACE:
  1110         case LBRACE:
   892             block();
  1111             block();
   893             break;
  1112             break;
   894         case VAR:
  1113         case VAR:
   916             breakStatement();
  1135             breakStatement();
   917             break;
  1136             break;
   918         case RETURN:
  1137         case RETURN:
   919             returnStatement();
  1138             returnStatement();
   920             break;
  1139             break;
   921         case YIELD:
       
   922             yieldStatement();
       
   923             break;
       
   924         case WITH:
  1140         case WITH:
   925             withStatement();
  1141             withStatement();
   926             break;
  1142             break;
   927         case SWITCH:
  1143         case SWITCH:
   928             switchStatement();
  1144             switchStatement();
   939         case RPAREN:
  1155         case RPAREN:
   940         case RBRACKET:
  1156         case RBRACKET:
   941         case EOF:
  1157         case EOF:
   942             expect(SEMICOLON);
  1158             expect(SEMICOLON);
   943             break;
  1159             break;
       
  1160         case FUNCTION:
       
  1161             // As per spec (ECMA section 12), function declarations as arbitrary statement
       
  1162             // is not "portable". Implementation can issue a warning or disallow the same.
       
  1163             if (singleStatement) {
       
  1164                 // ES6 B.3.2 Labelled Function Declarations
       
  1165                 // It is a Syntax Error if any strict mode source code matches this rule:
       
  1166                 // LabelledItem : FunctionDeclaration.
       
  1167                 if (!labelledStatement || isStrictMode) {
       
  1168                     throw error(AbstractParser.message("expected.stmt", "function declaration"), token);
       
  1169                 }
       
  1170             }
       
  1171             functionExpression(true, topLevel || labelledStatement);
       
  1172             return;
   944         default:
  1173         default:
   945             if (useBlockScope() && (type == LET || type == CONST)) {
  1174             if (useBlockScope() && (type == LET && lookaheadIsLetDeclaration(false) || type == CONST)) {
   946                 if (singleStatement) {
  1175                 if (singleStatement) {
   947                     throw error(AbstractParser.message("expected.stmt", type.getName() + " declaration"), token);
  1176                     throw error(AbstractParser.message("expected.stmt", type.getName() + " declaration"), token);
   948                 }
  1177                 }
   949                 variableStatement(type);
  1178                 variableStatement(type);
       
  1179                 break;
       
  1180             } else if (type == CLASS && isES6()) {
       
  1181                 if (singleStatement) {
       
  1182                     throw error(AbstractParser.message("expected.stmt", "class declaration"), token);
       
  1183                 }
       
  1184                 classDeclaration(false);
   950                 break;
  1185                 break;
   951             }
  1186             }
   952             if (env._const_as_var && type == CONST) {
  1187             if (env._const_as_var && type == CONST) {
   953                 variableStatement(TokenType.VAR);
  1188                 variableStatement(TokenType.VAR);
   954                 break;
  1189                 break;
   961                 }
  1196                 }
   962                 if(allowPropertyFunction) {
  1197                 if(allowPropertyFunction) {
   963                     final String ident = (String)getValue();
  1198                     final String ident = (String)getValue();
   964                     final long propertyToken = token;
  1199                     final long propertyToken = token;
   965                     final int propertyLine = line;
  1200                     final int propertyLine = line;
   966                     if("get".equals(ident)) {
  1201                     if ("get".equals(ident)) {
   967                         next();
  1202                         next();
   968                         addPropertyFunctionStatement(propertyGetterFunction(propertyToken, propertyLine));
  1203                         addPropertyFunctionStatement(propertyGetterFunction(propertyToken, propertyLine));
   969                         return;
  1204                         return;
   970                     } else if("set".equals(ident)) {
  1205                     } else if ("set".equals(ident)) {
   971                         next();
  1206                         next();
   972                         addPropertyFunctionStatement(propertySetterFunction(propertyToken, propertyLine));
  1207                         addPropertyFunctionStatement(propertySetterFunction(propertyToken, propertyLine));
   973                         return;
  1208                         return;
   974                     }
  1209                     }
   975                 }
  1210                 }
   984         final FunctionNode fn = propertyFunction.functionNode;
  1219         final FunctionNode fn = propertyFunction.functionNode;
   985         functionDeclarations.add(new ExpressionStatement(fn.getLineNumber(), fn.getToken(), finish, fn));
  1220         functionDeclarations.add(new ExpressionStatement(fn.getLineNumber(), fn.getToken(), finish, fn));
   986     }
  1221     }
   987 
  1222 
   988     /**
  1223     /**
       
  1224      * ClassDeclaration[Yield, Default] :
       
  1225      *   class BindingIdentifier[?Yield] ClassTail[?Yield]
       
  1226      *   [+Default] class ClassTail[?Yield]
       
  1227      */
       
  1228     private ClassNode classDeclaration(boolean isDefault) {
       
  1229         int classLineNumber = line;
       
  1230 
       
  1231         ClassNode classExpression = classExpression(!isDefault);
       
  1232 
       
  1233         if (!isDefault) {
       
  1234             VarNode classVar = new VarNode(classLineNumber, classExpression.getToken(), classExpression.getIdent().getFinish(), classExpression.getIdent(), classExpression, VarNode.IS_CONST);
       
  1235             appendStatement(classVar);
       
  1236         }
       
  1237         return classExpression;
       
  1238     }
       
  1239 
       
  1240     /**
       
  1241      * ClassExpression[Yield] :
       
  1242      *   class BindingIdentifier[?Yield]opt ClassTail[?Yield]
       
  1243      */
       
  1244     private ClassNode classExpression(boolean isStatement) {
       
  1245         assert type == CLASS;
       
  1246         int classLineNumber = line;
       
  1247         long classToken = token;
       
  1248         next();
       
  1249 
       
  1250         IdentNode className = null;
       
  1251         if (isStatement || type == IDENT) {
       
  1252             className = getIdent();
       
  1253         }
       
  1254 
       
  1255         return classTail(classLineNumber, classToken, className);
       
  1256     }
       
  1257 
       
  1258     private static final class ClassElementKey {
       
  1259         private final boolean isStatic;
       
  1260         private final String propertyName;
       
  1261 
       
  1262         private ClassElementKey(boolean isStatic, String propertyName) {
       
  1263             this.isStatic = isStatic;
       
  1264             this.propertyName = propertyName;
       
  1265         }
       
  1266 
       
  1267         @Override
       
  1268         public int hashCode() {
       
  1269             final int prime = 31;
       
  1270             int result = 1;
       
  1271             result = prime * result + (isStatic ? 1231 : 1237);
       
  1272             result = prime * result + ((propertyName == null) ? 0 : propertyName.hashCode());
       
  1273             return result;
       
  1274         }
       
  1275 
       
  1276         @Override
       
  1277         public boolean equals(Object obj) {
       
  1278             if (obj instanceof ClassElementKey) {
       
  1279                 ClassElementKey other = (ClassElementKey) obj;
       
  1280                 return this.isStatic == other.isStatic && Objects.equals(this.propertyName, other.propertyName);
       
  1281             }
       
  1282             return false;
       
  1283         }
       
  1284     }
       
  1285 
       
  1286     /**
       
  1287      * Parse ClassTail and ClassBody.
       
  1288      *
       
  1289      * ClassTail[Yield] :
       
  1290      *   ClassHeritage[?Yield]opt { ClassBody[?Yield]opt }
       
  1291      * ClassHeritage[Yield] :
       
  1292      *   extends LeftHandSideExpression[?Yield]
       
  1293      *
       
  1294      * ClassBody[Yield] :
       
  1295      *   ClassElementList[?Yield]
       
  1296      * ClassElementList[Yield] :
       
  1297      *   ClassElement[?Yield]
       
  1298      *   ClassElementList[?Yield] ClassElement[?Yield]
       
  1299      * ClassElement[Yield] :
       
  1300      *   MethodDefinition[?Yield]
       
  1301      *   static MethodDefinition[?Yield]
       
  1302      *   ;
       
  1303      */
       
  1304     private ClassNode classTail(final int classLineNumber, final long classToken, final IdentNode className) {
       
  1305         final boolean oldStrictMode = isStrictMode;
       
  1306         isStrictMode = true;
       
  1307         try {
       
  1308             Expression classHeritage = null;
       
  1309             if (type == EXTENDS) {
       
  1310                 next();
       
  1311                 classHeritage = leftHandSideExpression();
       
  1312             }
       
  1313 
       
  1314             expect(LBRACE);
       
  1315 
       
  1316             PropertyNode constructor = null;
       
  1317             final ArrayList<PropertyNode> classElements = new ArrayList<>();
       
  1318             final Map<ClassElementKey, Integer> keyToIndexMap = new HashMap<>();
       
  1319             for (;;) {
       
  1320                 if (type == SEMICOLON) {
       
  1321                     next();
       
  1322                     continue;
       
  1323                 }
       
  1324                 if (type == RBRACE) {
       
  1325                     break;
       
  1326                 }
       
  1327                 final long classElementToken = token;
       
  1328                 boolean isStatic = false;
       
  1329                 if (type == STATIC) {
       
  1330                     isStatic = true;
       
  1331                     next();
       
  1332                 }
       
  1333                 boolean generator = false;
       
  1334                 if (isES6() && type == MUL) {
       
  1335                     generator = true;
       
  1336                     next();
       
  1337                 }
       
  1338                 final PropertyNode classElement = methodDefinition(isStatic, classHeritage != null, generator);
       
  1339                 if (classElement.isComputed()) {
       
  1340                     classElements.add(classElement);
       
  1341                 } else if (!classElement.isStatic() && classElement.getKeyName().equals("constructor")) {
       
  1342                     if (constructor == null) {
       
  1343                         constructor = classElement;
       
  1344                     } else {
       
  1345                         throw error(AbstractParser.message("multiple.constructors"), classElementToken);
       
  1346                     }
       
  1347                 } else {
       
  1348                     // Check for duplicate method definitions and combine accessor methods.
       
  1349                     // In ES6, a duplicate is never an error regardless of strict mode (in consequence of computed property names).
       
  1350 
       
  1351                     final ClassElementKey key = new ClassElementKey(classElement.isStatic(), classElement.getKeyName());
       
  1352                     final Integer existing = keyToIndexMap.get(key);
       
  1353 
       
  1354                     if (existing == null) {
       
  1355                         keyToIndexMap.put(key, classElements.size());
       
  1356                         classElements.add(classElement);
       
  1357                     } else {
       
  1358                         final PropertyNode existingProperty = classElements.get(existing);
       
  1359 
       
  1360                         final Expression   value  = classElement.getValue();
       
  1361                         final FunctionNode getter = classElement.getGetter();
       
  1362                         final FunctionNode setter = classElement.getSetter();
       
  1363 
       
  1364                         if (value != null || existingProperty.getValue() != null) {
       
  1365                             keyToIndexMap.put(key, classElements.size());
       
  1366                             classElements.add(classElement);
       
  1367                         } else if (getter != null) {
       
  1368                             assert existingProperty.getGetter() != null || existingProperty.getSetter() != null;
       
  1369                             classElements.set(existing, existingProperty.setGetter(getter));
       
  1370                         } else if (setter != null) {
       
  1371                             assert existingProperty.getGetter() != null || existingProperty.getSetter() != null;
       
  1372                             classElements.set(existing, existingProperty.setSetter(setter));
       
  1373                         }
       
  1374                     }
       
  1375                 }
       
  1376             }
       
  1377 
       
  1378             final long lastToken = token;
       
  1379             expect(RBRACE);
       
  1380 
       
  1381             if (constructor == null) {
       
  1382                 constructor = createDefaultClassConstructor(classLineNumber, classToken, lastToken, className, classHeritage != null);
       
  1383             }
       
  1384 
       
  1385             classElements.trimToSize();
       
  1386             return new ClassNode(classLineNumber, classToken, finish, className, classHeritage, constructor, classElements);
       
  1387         } finally {
       
  1388             isStrictMode = oldStrictMode;
       
  1389         }
       
  1390     }
       
  1391 
       
  1392     private PropertyNode createDefaultClassConstructor(int classLineNumber, long classToken, long lastToken, IdentNode className, boolean subclass) {
       
  1393         final int ctorFinish = finish;
       
  1394         final List<Statement> statements;
       
  1395         final List<IdentNode> parameters;
       
  1396         final long identToken = Token.recast(classToken, TokenType.IDENT);
       
  1397         if (subclass) {
       
  1398             final IdentNode superIdent = createIdentNode(identToken, ctorFinish, SUPER.getName()).setIsDirectSuper();
       
  1399             final IdentNode argsIdent = createIdentNode(identToken, ctorFinish, "args").setIsRestParameter();
       
  1400             final Expression spreadArgs = new UnaryNode(Token.recast(classToken, TokenType.SPREAD_ARGUMENT), argsIdent);
       
  1401             final CallNode superCall = new CallNode(classLineNumber, classToken, ctorFinish, superIdent, Collections.singletonList(spreadArgs), false);
       
  1402             statements = Collections.singletonList(new ExpressionStatement(classLineNumber, classToken, ctorFinish, superCall));
       
  1403             parameters = Collections.singletonList(argsIdent);
       
  1404         } else {
       
  1405             statements = Collections.emptyList();
       
  1406             parameters = Collections.emptyList();
       
  1407         }
       
  1408 
       
  1409         final Block body = new Block(classToken, ctorFinish, Block.IS_BODY, statements);
       
  1410         final IdentNode ctorName = className != null ? className : createIdentNode(identToken, ctorFinish, "constructor");
       
  1411         final ParserContextFunctionNode function = createParserContextFunctionNode(ctorName, classToken, FunctionNode.Kind.NORMAL, classLineNumber, parameters);
       
  1412         function.setLastToken(lastToken);
       
  1413 
       
  1414         function.setFlag(FunctionNode.ES6_IS_METHOD);
       
  1415         function.setFlag(FunctionNode.ES6_IS_CLASS_CONSTRUCTOR);
       
  1416         if (subclass) {
       
  1417             function.setFlag(FunctionNode.ES6_IS_SUBCLASS_CONSTRUCTOR);
       
  1418             function.setFlag(FunctionNode.ES6_HAS_DIRECT_SUPER);
       
  1419         }
       
  1420         if (className == null) {
       
  1421             function.setFlag(FunctionNode.IS_ANONYMOUS);
       
  1422         }
       
  1423 
       
  1424         final PropertyNode constructor = new PropertyNode(classToken, ctorFinish, ctorName, createFunctionNode(
       
  1425                         function,
       
  1426                         classToken,
       
  1427                         ctorName,
       
  1428                         parameters,
       
  1429                         FunctionNode.Kind.NORMAL,
       
  1430                         classLineNumber,
       
  1431                         body
       
  1432                         ), null, null, false, false);
       
  1433         return constructor;
       
  1434     }
       
  1435 
       
  1436     private PropertyNode methodDefinition(final boolean isStatic, final boolean subclass, final boolean generator) {
       
  1437         final long methodToken = token;
       
  1438         final int methodLine = line;
       
  1439         final boolean computed = type == LBRACKET;
       
  1440         final boolean isIdent = type == IDENT;
       
  1441         final Expression propertyName = propertyName();
       
  1442         int flags = FunctionNode.ES6_IS_METHOD;
       
  1443         if (!computed) {
       
  1444             final String name = ((PropertyKey)propertyName).getPropertyName();
       
  1445             if (!generator && isIdent && type != LPAREN && name.equals("get")) {
       
  1446                 final PropertyFunction methodDefinition = propertyGetterFunction(methodToken, methodLine, flags);
       
  1447                 verifyAllowedMethodName(methodDefinition.key, isStatic, methodDefinition.computed, generator, true);
       
  1448                 return new PropertyNode(methodToken, finish, methodDefinition.key, null, methodDefinition.functionNode, null, isStatic, methodDefinition.computed);
       
  1449             } else if (!generator && isIdent && type != LPAREN && name.equals("set")) {
       
  1450                 final PropertyFunction methodDefinition = propertySetterFunction(methodToken, methodLine, flags);
       
  1451                 verifyAllowedMethodName(methodDefinition.key, isStatic, methodDefinition.computed, generator, true);
       
  1452                 return new PropertyNode(methodToken, finish, methodDefinition.key, null, null, methodDefinition.functionNode, isStatic, methodDefinition.computed);
       
  1453             } else {
       
  1454                 if (!isStatic && !generator && name.equals("constructor")) {
       
  1455                     flags |= FunctionNode.ES6_IS_CLASS_CONSTRUCTOR;
       
  1456                     if (subclass) {
       
  1457                         flags |= FunctionNode.ES6_IS_SUBCLASS_CONSTRUCTOR;
       
  1458                     }
       
  1459                 }
       
  1460                 verifyAllowedMethodName(propertyName, isStatic, computed, generator, false);
       
  1461             }
       
  1462         }
       
  1463         final PropertyFunction methodDefinition = propertyMethodFunction(propertyName, methodToken, methodLine, generator, flags, computed);
       
  1464         return new PropertyNode(methodToken, finish, methodDefinition.key, methodDefinition.functionNode, null, null, isStatic, computed);
       
  1465     }
       
  1466 
       
  1467     /**
       
  1468      * ES6 14.5.1 Static Semantics: Early Errors.
       
  1469      */
       
  1470     private void verifyAllowedMethodName(final Expression key, final boolean isStatic, final boolean computed, final boolean generator, final boolean accessor) {
       
  1471         if (!computed) {
       
  1472             if (!isStatic && generator && ((PropertyKey) key).getPropertyName().equals("constructor")) {
       
  1473                 throw error(AbstractParser.message("generator.constructor"), key.getToken());
       
  1474             }
       
  1475             if (!isStatic && accessor && ((PropertyKey) key).getPropertyName().equals("constructor")) {
       
  1476                 throw error(AbstractParser.message("accessor.constructor"), key.getToken());
       
  1477             }
       
  1478             if (isStatic && ((PropertyKey) key).getPropertyName().equals("prototype")) {
       
  1479                 throw error(AbstractParser.message("static.prototype.method"), key.getToken());
       
  1480             }
       
  1481         }
       
  1482     }
       
  1483 
       
  1484     /**
   989      * block :
  1485      * block :
   990      *      { StatementList? }
  1486      *      { StatementList? }
   991      *
  1487      *
   992      * see 12.1
  1488      * see 12.1
   993      *
  1489      *
  1006      *
  1502      *
  1007      * Parse a list of statements.
  1503      * Parse a list of statements.
  1008      */
  1504      */
  1009     private void statementList() {
  1505     private void statementList() {
  1010         // Accumulate statements until end of list. */
  1506         // Accumulate statements until end of list. */
  1011 loop:
  1507         loop:
  1012         while (type != EOF) {
  1508         while (type != EOF) {
  1013             switch (type) {
  1509             switch (type) {
  1014             case EOF:
  1510             case EOF:
  1015             case CASE:
  1511             case CASE:
  1016             case DEFAULT:
  1512             case DEFAULT:
  1024             statement();
  1520             statement();
  1025         }
  1521         }
  1026     }
  1522     }
  1027 
  1523 
  1028     /**
  1524     /**
       
  1525      * Make sure that the identifier name used is allowed.
       
  1526      *
       
  1527      * @param ident         Identifier that is verified
       
  1528      * @param contextString String used in error message to give context to the user
       
  1529      */
       
  1530     private void verifyIdent(final IdentNode ident, final String contextString) {
       
  1531         verifyStrictIdent(ident, contextString);
       
  1532         if (isES6()) {
       
  1533             final TokenType tokenType = TokenLookup.lookupKeyword(ident.getName().toCharArray(), 0, ident.getName().length());
       
  1534             if (tokenType != IDENT && tokenType.getKind() != TokenKind.FUTURESTRICT) {
       
  1535                 throw error(expectMessage(IDENT));
       
  1536             }
       
  1537         }
       
  1538     }
       
  1539 
       
  1540     /**
  1029      * Make sure that in strict mode, the identifier name used is allowed.
  1541      * Make sure that in strict mode, the identifier name used is allowed.
  1030      *
  1542      *
  1031      * @param ident         Identifier that is verified
  1543      * @param ident         Identifier that is verified
  1032      * @param contextString String used in error message to give context to the user
  1544      * @param contextString String used in error message to give context to the user
  1033      */
  1545      */
  1064      * See 12.2
  1576      * See 12.2
  1065      *
  1577      *
  1066      * Parse a VAR statement.
  1578      * Parse a VAR statement.
  1067      * @param isStatement True if a statement (not used in a FOR.)
  1579      * @param isStatement True if a statement (not used in a FOR.)
  1068      */
  1580      */
  1069     private List<VarNode> variableStatement(final TokenType varType) {
  1581     private void variableStatement(final TokenType varType) {
  1070         return variableStatement(varType, true, -1);
  1582         variableDeclarationList(varType, true, -1);
  1071     }
  1583     }
  1072 
  1584 
  1073     private List<VarNode> variableStatement(final TokenType varType, final boolean isStatement, final int sourceOrder) {
  1585     private List<Expression> variableDeclarationList(final TokenType varType, final boolean isStatement, final int sourceOrder) {
  1074         // VAR tested in caller.
  1586         // VAR tested in caller.
       
  1587         assert varType == VAR || varType == LET || varType == CONST;
  1075         next();
  1588         next();
  1076 
  1589 
  1077         final List<VarNode> vars = new ArrayList<>();
  1590         final List<Expression> bindings = new ArrayList<>();
  1078         int varFlags = 0;
  1591         int varFlags = 0;
  1079         if (varType == LET) {
  1592         if (varType == LET) {
  1080             varFlags |= VarNode.IS_LET;
  1593             varFlags |= VarNode.IS_LET;
  1081         } else if (varType == CONST) {
  1594         } else if (varType == CONST) {
  1082             varFlags |= VarNode.IS_CONST;
  1595             varFlags |= VarNode.IS_CONST;
  1083         }
  1596         }
  1084 
  1597 
       
  1598         Expression missingAssignment = null;
  1085         while (true) {
  1599         while (true) {
  1086             // Get starting token.
  1600             // Get starting token.
  1087             final int  varLine  = line;
  1601             final int  varLine  = line;
  1088             final long varToken = token;
  1602             final long varToken = token;
  1089             // Get name of var.
  1603             // Get name of var.
  1090             final IdentNode name = getIdent();
  1604             if (type == YIELD && inGeneratorFunction()) {
  1091             verifyStrictIdent(name, "variable name");
  1605                 expect(IDENT);
       
  1606             }
       
  1607 
       
  1608             final String contextString = "variable name";
       
  1609             Expression binding = bindingIdentifierOrPattern(contextString);
       
  1610             final boolean isDestructuring = !(binding instanceof IdentNode);
       
  1611             if (isDestructuring) {
       
  1612                 final int finalVarFlags = varFlags;
       
  1613                 verifyDestructuringBindingPattern(binding, new Consumer<IdentNode>() {
       
  1614                     public void accept(final IdentNode identNode) {
       
  1615                         verifyIdent(identNode, contextString);
       
  1616                         final VarNode var = new VarNode(varLine, varToken, sourceOrder, identNode.getFinish(), identNode.setIsDeclaredHere(), null, finalVarFlags);
       
  1617                         appendStatement(var);
       
  1618                     }
       
  1619                 });
       
  1620             }
  1092 
  1621 
  1093             // Assume no init.
  1622             // Assume no init.
  1094             Expression init = null;
  1623             Expression init = null;
  1095 
  1624 
  1096             // Look for initializer assignment.
  1625             // Look for initializer assignment.
  1097             if (type == ASSIGN) {
  1626             if (type == ASSIGN) {
  1098                 next();
  1627                 next();
  1099 
  1628 
  1100                 // Get initializer expression. Suppress IN if not statement.
  1629                 // Get initializer expression. Suppress IN if not statement.
  1101                 defaultNames.push(name);
  1630                 if (!isDestructuring) {
       
  1631                     defaultNames.push(binding);
       
  1632                 }
  1102                 try {
  1633                 try {
  1103                     init = assignmentExpression(!isStatement);
  1634                     init = assignmentExpression(!isStatement);
  1104                 } finally {
  1635                 } finally {
  1105                     defaultNames.pop();
  1636                     if (!isDestructuring) {
  1106                 }
  1637                         defaultNames.pop();
  1107             } else if (varType == CONST && isStatement) {
  1638                     }
  1108                 throw error(AbstractParser.message("missing.const.assignment", name.getName()));
  1639                 }
  1109             }
  1640             } else if (isStatement) {
  1110 
  1641                 if (isDestructuring) {
  1111             // Only set declaration flag on lexically scoped let/const as it adds runtime overhead.
  1642                     throw error(AbstractParser.message("missing.destructuring.assignment"), token);
  1112             final IdentNode actualName = varType == LET || varType == CONST ? name.setIsDeclaredHere() : name;
  1643                 } else if (varType == CONST) {
  1113             // Allocate var node.
  1644                     throw error(AbstractParser.message("missing.const.assignment", ((IdentNode)binding).getName()));
  1114             final VarNode var = new VarNode(varLine, varToken, sourceOrder, finish, actualName, init, varFlags);
  1645                 }
  1115             vars.add(var);
  1646                 // else, if we are in a for loop, delay checking until we know the kind of loop
  1116             appendStatement(var);
  1647             }
       
  1648 
       
  1649             if (!isDestructuring) {
       
  1650                 assert init != null || varType != CONST || !isStatement;
       
  1651                 final IdentNode ident = (IdentNode)binding;
       
  1652                 if (!isStatement && ident.getName().equals("let")) {
       
  1653                     throw error(AbstractParser.message("let.binding.for")); //ES6 13.7.5.1
       
  1654                 }
       
  1655                 // Only set declaration flag on lexically scoped let/const as it adds runtime overhead.
       
  1656                 final IdentNode name = varType == LET || varType == CONST ? ident.setIsDeclaredHere() : ident;
       
  1657                 binding = name;
       
  1658                 final VarNode var = new VarNode(varLine, varToken, sourceOrder, finish, name, init, varFlags);
       
  1659                 appendStatement(var);
       
  1660                 if (init == null && varType == CONST) {
       
  1661                     if (missingAssignment == null) {
       
  1662                         missingAssignment = binding;
       
  1663                     }
       
  1664                 }
       
  1665             } else {
       
  1666                 assert init != null || !isStatement;
       
  1667                 binding = init == null ? binding : verifyAssignment(Token.recast(varToken, ASSIGN), binding, init);
       
  1668                 if (isStatement) {
       
  1669                     appendStatement(new ExpressionStatement(varLine, binding.getToken(), finish, binding));
       
  1670                 } else if (init == null) {
       
  1671                     if (missingAssignment == null) {
       
  1672                         missingAssignment = binding;
       
  1673                     }
       
  1674                 }
       
  1675             }
       
  1676             bindings.add(binding);
  1117 
  1677 
  1118             if (type != COMMARIGHT) {
  1678             if (type != COMMARIGHT) {
  1119                 break;
  1679                 break;
  1120             }
  1680             }
  1121             next();
  1681             next();
  1122         }
  1682         }
  1123 
  1683 
  1124         // If is a statement then handle end of line.
  1684         // If is a statement then handle end of line.
  1125         if (isStatement) {
  1685         if (isStatement) {
  1126             endOfLine();
  1686             endOfLine();
  1127         }
  1687         } else {
  1128 
  1688             if (type == SEMICOLON) {
  1129         return vars;
  1689                 // late check for missing assignment, now we know it's a for (init; test; modify) loop
       
  1690                 if (missingAssignment != null) {
       
  1691                     if (missingAssignment instanceof IdentNode) {
       
  1692                         throw error(AbstractParser.message("missing.const.assignment", ((IdentNode)missingAssignment).getName()));
       
  1693                     } else {
       
  1694                         throw error(AbstractParser.message("missing.destructuring.assignment"), missingAssignment.getToken());
       
  1695                     }
       
  1696                 }
       
  1697             }
       
  1698         }
       
  1699 
       
  1700         return bindings;
       
  1701     }
       
  1702 
       
  1703     private boolean isBindingIdentifier() {
       
  1704         return type == IDENT || isNonStrictModeIdent();
       
  1705     }
       
  1706 
       
  1707     private IdentNode bindingIdentifier(final String contextString) {
       
  1708         final IdentNode name = getIdent();
       
  1709         verifyIdent(name, contextString);
       
  1710         return name;
       
  1711     }
       
  1712 
       
  1713     private Expression bindingPattern() {
       
  1714         if (type == LBRACKET) {
       
  1715             return arrayLiteral();
       
  1716         } else if (type == LBRACE) {
       
  1717             return objectLiteral();
       
  1718         } else {
       
  1719             throw error(AbstractParser.message("expected.binding"));
       
  1720         }
       
  1721     }
       
  1722 
       
  1723     private Expression bindingIdentifierOrPattern(final String contextString) {
       
  1724         if (isBindingIdentifier() || !isES6()) {
       
  1725             return bindingIdentifier(contextString);
       
  1726         } else {
       
  1727             return bindingPattern();
       
  1728         }
       
  1729     }
       
  1730 
       
  1731     /**
       
  1732      * Verify destructuring variable declaration binding pattern and extract bound variable declarations.
       
  1733      */
       
  1734     private void verifyDestructuringBindingPattern(final Expression pattern, final Consumer<IdentNode> identifierCallback) {
       
  1735         assert pattern instanceof ObjectNode || pattern instanceof LiteralNode.ArrayLiteralNode;
       
  1736         pattern.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
       
  1737             @Override
       
  1738             public boolean enterLiteralNode(final LiteralNode<?> literalNode) {
       
  1739                 if (literalNode.isArray()) {
       
  1740                     boolean restElement = false;
       
  1741                     for (final Expression element : literalNode.getElementExpressions()) {
       
  1742                         if (restElement) {
       
  1743                             throw error(String.format("Unexpected element after rest element"), element.getToken());
       
  1744                         }
       
  1745                         if (element != null) {
       
  1746                             if (element.isTokenType(SPREAD_ARRAY)) {
       
  1747                                 restElement = true;
       
  1748                                 if (!(((UnaryNode) element).getExpression() instanceof IdentNode)) {
       
  1749                                     throw error(String.format("Expected a valid binding identifier"), element.getToken());
       
  1750 
       
  1751                                 }
       
  1752                             }
       
  1753                             element.accept(this);
       
  1754                         }
       
  1755                     }
       
  1756                     return false;
       
  1757                 } else {
       
  1758                     return enterDefault(literalNode);
       
  1759                 }
       
  1760             }
       
  1761 
       
  1762             @Override
       
  1763             public boolean enterObjectNode(final ObjectNode objectNode) {
       
  1764                 return true;
       
  1765             }
       
  1766 
       
  1767             @Override
       
  1768             public boolean enterPropertyNode(final PropertyNode propertyNode) {
       
  1769                 if (propertyNode.getValue() != null) {
       
  1770                     propertyNode.getValue().accept(this);
       
  1771                     return false;
       
  1772                 } else {
       
  1773                     return enterDefault(propertyNode);
       
  1774                 }
       
  1775             }
       
  1776 
       
  1777             @Override
       
  1778             public boolean enterIdentNode(final IdentNode identNode) {
       
  1779                 identifierCallback.accept(identNode);
       
  1780                 return false;
       
  1781             }
       
  1782 
       
  1783             @Override
       
  1784             public boolean enterBinaryNode(final BinaryNode binaryNode) {
       
  1785                 if (binaryNode.isTokenType(ASSIGN)) {
       
  1786                     binaryNode.lhs().accept(this);
       
  1787                     // Initializer(rhs) can be any AssignmentExpression
       
  1788                     return false;
       
  1789                 } else {
       
  1790                     return enterDefault(binaryNode);
       
  1791                 }
       
  1792             }
       
  1793 
       
  1794             @Override
       
  1795             public boolean enterUnaryNode(final UnaryNode unaryNode) {
       
  1796                 if (unaryNode.isTokenType(SPREAD_ARRAY)) {
       
  1797                     // rest element
       
  1798                     return true;
       
  1799                 } else {
       
  1800                     return enterDefault(unaryNode);
       
  1801                 }
       
  1802             }
       
  1803 
       
  1804             @Override
       
  1805             protected boolean enterDefault(final Node node) {
       
  1806                 throw error(String.format("unexpected node in BindingPattern: %s", node));
       
  1807             }
       
  1808         });
  1130     }
  1809     }
  1131 
  1810 
  1132     /**
  1811     /**
  1133      * EmptyStatement :
  1812      * EmptyStatement :
  1134      *      ;
  1813      *      ;
  1228 
  1907 
  1229         // Create FOR node, capturing FOR token.
  1908         // Create FOR node, capturing FOR token.
  1230         final ParserContextLoopNode forNode = new ParserContextLoopNode();
  1909         final ParserContextLoopNode forNode = new ParserContextLoopNode();
  1231         lc.push(forNode);
  1910         lc.push(forNode);
  1232         Block body = null;
  1911         Block body = null;
  1233         List<VarNode> vars = null;
  1912         List<Expression> vars = null;
  1234         Expression init = null;
  1913         Expression init = null;
  1235         JoinPredecessorExpression test = null;
  1914         JoinPredecessorExpression test = null;
  1236         JoinPredecessorExpression modify = null;
  1915         JoinPredecessorExpression modify = null;
  1237 
  1916 
  1238         int flags = 0;
  1917         int flags = 0;
  1252             expect(LPAREN);
  1931             expect(LPAREN);
  1253 
  1932 
  1254             switch (type) {
  1933             switch (type) {
  1255             case VAR:
  1934             case VAR:
  1256                 // Var declaration captured in for outer block.
  1935                 // Var declaration captured in for outer block.
  1257                 vars = variableStatement(type, false, forStart);
  1936                 vars = variableDeclarationList(type, false, forStart);
  1258                 break;
  1937                 break;
  1259             case SEMICOLON:
  1938             case SEMICOLON:
  1260                 break;
  1939                 break;
  1261             default:
  1940             default:
  1262                 if (useBlockScope() && (type == LET || type == CONST)) {
  1941                 if (useBlockScope() && (type == LET && lookaheadIsLetDeclaration(true) || type == CONST)) {
  1263                     flags |= ForNode.PER_ITERATION_SCOPE;
  1942                     flags |= ForNode.PER_ITERATION_SCOPE;
  1264                     // LET/CONST declaration captured in container block created above.
  1943                     // LET/CONST declaration captured in container block created above.
  1265                     vars = variableStatement(type, false, forStart);
  1944                     vars = variableDeclarationList(type, false, forStart);
  1266                     break;
  1945                     break;
  1267                 }
  1946                 }
  1268                 if (env._const_as_var && type == CONST) {
  1947                 if (env._const_as_var && type == CONST) {
  1269                     // Var declaration captured in for outer block.
  1948                     // Var declaration captured in for outer block.
  1270                     vars = variableStatement(TokenType.VAR, false, forStart);
  1949                     vars = variableDeclarationList(TokenType.VAR, false, forStart);
  1271                     break;
  1950                     break;
  1272                 }
  1951                 }
  1273 
  1952 
  1274                 init = expression(unaryExpression(), COMMARIGHT.getPrecedence(), true);
  1953                 init = expression(unaryExpression(), COMMARIGHT.getPrecedence(), true);
  1275                 break;
  1954                 break;
  1307                 flags |= isForOf ? ForNode.IS_FOR_OF : ForNode.IS_FOR_IN;
  1986                 flags |= isForOf ? ForNode.IS_FOR_OF : ForNode.IS_FOR_IN;
  1308                 test = new JoinPredecessorExpression();
  1987                 test = new JoinPredecessorExpression();
  1309                 if (vars != null) {
  1988                 if (vars != null) {
  1310                     // for (var i in obj)
  1989                     // for (var i in obj)
  1311                     if (vars.size() == 1) {
  1990                     if (vars.size() == 1) {
  1312                         init = new IdentNode(vars.get(0).getName());
  1991                         init = new IdentNode((IdentNode)vars.get(0));
       
  1992                         if (init.isTokenType(ASSIGN)) {
       
  1993                             throw error(AbstractParser.message("for.in.loop.initializer"), init.getToken());
       
  1994                         }
       
  1995                         assert init instanceof IdentNode || isDestructuringLhs(init);
  1313                     } else {
  1996                     } else {
  1314                         // for (var i, j in obj) is invalid
  1997                         // for (var i, j in obj) is invalid
  1315                         throw error(AbstractParser.message("many.vars.in.for.in.loop", isForOf ? "of" : "in"), vars.get(1).getToken());
  1998                         throw error(AbstractParser.message("many.vars.in.for.in.loop", isForOf ? "of" : "in"), vars.get(1).getToken());
  1316                     }
  1999                     }
  1317                 } else {
  2000                 } else {
  1349             // Set the for body.
  2032             // Set the for body.
  1350             body = getStatement();
  2033             body = getStatement();
  1351         } finally {
  2034         } finally {
  1352             lc.pop(forNode);
  2035             lc.pop(forNode);
  1353 
  2036 
  1354             if (vars != null) {
  2037             for (final Statement var : forNode.getStatements()) {
  1355                 for (final VarNode var : vars) {
  2038                 assert var instanceof VarNode;
  1356                     appendStatement(var);
  2039                 appendStatement(var);
  1357                 }
       
  1358             }
  2040             }
  1359             if (body != null) {
  2041             if (body != null) {
  1360                 appendStatement(new ForNode(forLine, forToken, body.getFinish(), body, (forNode.getFlags() | flags), init, test, modify));
  2042                 appendStatement(new ForNode(forLine, forToken, body.getFinish(), body, (forNode.getFlags() | flags), init, test, modify));
  1361             }
  2043             }
  1362             if (outer != null) {
  2044             if (outer != null) {
  1369                 }
  2051                 }
  1370             }
  2052             }
  1371         }
  2053         }
  1372     }
  2054     }
  1373 
  2055 
       
  2056     private boolean checkValidLValue(final Expression init, final String contextString) {
       
  2057         if (init instanceof IdentNode) {
       
  2058             if (!checkIdentLValue((IdentNode)init)) {
       
  2059                 return false;
       
  2060             }
       
  2061             verifyIdent((IdentNode)init, contextString);
       
  2062             return true;
       
  2063         } else if (init instanceof AccessNode || init instanceof IndexNode) {
       
  2064             return true;
       
  2065         } else if (isDestructuringLhs(init)) {
       
  2066             verifyDestructuringAssignmentPattern(init, contextString);
       
  2067             return true;
       
  2068         } else {
       
  2069             return false;
       
  2070         }
       
  2071     }
       
  2072 
       
  2073     private boolean lookaheadIsLetDeclaration(final boolean ofContextualKeyword) {
       
  2074         assert type == LET;
       
  2075         for (int i = 1;; i++) {
       
  2076             TokenType t = T(k + i);
       
  2077             switch (t) {
       
  2078             case EOL:
       
  2079             case COMMENT:
       
  2080                 continue;
       
  2081             case IDENT:
       
  2082                 if (ofContextualKeyword && isES6() && "of".equals(getValue(getToken(k + i)))) {
       
  2083                     return false;
       
  2084                 }
       
  2085                 // fall through
       
  2086             case LBRACKET:
       
  2087             case LBRACE:
       
  2088                 return true;
       
  2089             default:
       
  2090                 // accept future strict tokens in non-strict mode (including LET)
       
  2091                 if (!isStrictMode && t.getKind() == TokenKind.FUTURESTRICT) {
       
  2092                     return true;
       
  2093                 }
       
  2094                 return false;
       
  2095             }
       
  2096         }
       
  2097     }
       
  2098 
  1374     /**
  2099     /**
  1375      * ...IterationStatement :
  2100      * ...IterationStatement :
  1376      *           ...
  2101      *           ...
  1377      *           while ( Expression ) Statement
  2102      *           while ( Expression ) Statement
  1378      *           ...
  2103      *           ...
  1557      *
  2282      *
  1558      * Parse RETURN statement.
  2283      * Parse RETURN statement.
  1559      */
  2284      */
  1560     private void returnStatement() {
  2285     private void returnStatement() {
  1561         // check for return outside function
  2286         // check for return outside function
  1562         if (lc.getCurrentFunction().getKind() == FunctionNode.Kind.SCRIPT) {
  2287         if (lc.getCurrentFunction().getKind() == FunctionNode.Kind.SCRIPT || lc.getCurrentFunction().getKind() == FunctionNode.Kind.MODULE) {
  1563             throw error(AbstractParser.message("invalid.return"));
  2288             throw error(AbstractParser.message("invalid.return"));
  1564         }
  2289         }
  1565 
  2290 
  1566         // Capture RETURN token.
  2291         // Capture RETURN token.
  1567         final int  returnLine  = line;
  2292         final int  returnLine  = line;
  1589         // Construct and add RETURN node.
  2314         // Construct and add RETURN node.
  1590         appendStatement(new ReturnNode(returnLine, returnToken, finish, expression));
  2315         appendStatement(new ReturnNode(returnLine, returnToken, finish, expression));
  1591     }
  2316     }
  1592 
  2317 
  1593     /**
  2318     /**
  1594      * YieldStatement :
  2319      * Parse YieldExpression.
  1595      *      yield Expression? ; // [no LineTerminator here]
  2320      *
  1596      *
  2321      * YieldExpression[In] :
  1597      * JavaScript 1.8
  2322      *   yield
  1598      *
  2323      *   yield [no LineTerminator here] AssignmentExpression[?In, Yield]
  1599      * Parse YIELD statement.
  2324      *   yield [no LineTerminator here] * AssignmentExpression[?In, Yield]
  1600      */
  2325      */
  1601     private void yieldStatement() {
  2326     private Expression yieldExpression(final boolean noIn) {
       
  2327         assert inGeneratorFunction();
  1602         // Capture YIELD token.
  2328         // Capture YIELD token.
  1603         final int  yieldLine  = line;
  2329         long yieldToken = token;
  1604         final long yieldToken = token;
       
  1605         // YIELD tested in caller.
  2330         // YIELD tested in caller.
       
  2331         assert type == YIELD;
  1606         nextOrEOL();
  2332         nextOrEOL();
  1607 
  2333 
  1608         Expression expression = null;
  2334         Expression expression = null;
  1609 
  2335 
  1610         // SEMICOLON or expression.
  2336         boolean yieldAsterisk = false;
       
  2337         if (type == MUL) {
       
  2338             yieldAsterisk = true;
       
  2339             yieldToken = Token.recast(yieldToken, YIELD_STAR);
       
  2340             next();
       
  2341         }
       
  2342 
  1611         switch (type) {
  2343         switch (type) {
  1612         case RBRACE:
  2344         case RBRACE:
  1613         case SEMICOLON:
  2345         case SEMICOLON:
  1614         case EOL:
  2346         case EOL:
  1615         case EOF:
  2347         case EOF:
       
  2348         case COMMARIGHT:
       
  2349         case RPAREN:
       
  2350         case RBRACKET:
       
  2351         case COLON:
       
  2352             if (!yieldAsterisk) {
       
  2353                 // treat (yield) as (yield void 0)
       
  2354                 expression = newUndefinedLiteral(yieldToken, finish);
       
  2355                 if (type == EOL) {
       
  2356                     next();
       
  2357                 }
       
  2358                 break;
       
  2359             } else {
       
  2360                 // AssignmentExpression required, fall through
       
  2361             }
       
  2362 
       
  2363         default:
       
  2364             expression = assignmentExpression(noIn);
  1616             break;
  2365             break;
  1617 
  2366         }
  1618         default:
       
  1619             expression = expression();
       
  1620             break;
       
  1621         }
       
  1622 
       
  1623         endOfLine();
       
  1624 
  2367 
  1625         // Construct and add YIELD node.
  2368         // Construct and add YIELD node.
  1626         appendStatement(new ReturnNode(yieldLine, yieldToken, finish, expression));
  2369         return new UnaryNode(yieldToken, expression);
       
  2370     }
       
  2371 
       
  2372     private static UnaryNode newUndefinedLiteral(final long token, final int finish) {
       
  2373         return new UnaryNode(Token.recast(token, VOID), LiteralNode.newInstance(token, finish, 0));
  1627     }
  2374     }
  1628 
  2375 
  1629     /**
  2376     /**
  1630      * WithStatement :
  2377      * WithStatement :
  1631      *      with ( Expression ) Statement
  2378      *      with ( Expression ) Statement
  1677      * Parse SWITCH statement.
  2424      * Parse SWITCH statement.
  1678      */
  2425      */
  1679     private void switchStatement() {
  2426     private void switchStatement() {
  1680         final int  switchLine  = line;
  2427         final int  switchLine  = line;
  1681         final long switchToken = token;
  2428         final long switchToken = token;
       
  2429 
       
  2430         // Block to capture variables declared inside the switch statement.
       
  2431         final ParserContextBlockNode switchBlock = newBlock();
       
  2432 
  1682         // SWITCH tested in caller.
  2433         // SWITCH tested in caller.
  1683         next();
  2434         next();
  1684 
  2435 
  1685         // Create and add switch statement.
  2436         // Create and add switch statement.
  1686         final ParserContextSwitchNode switchNode= new ParserContextSwitchNode();
  2437         final ParserContextSwitchNode switchNode = new ParserContextSwitchNode();
  1687         lc.push(switchNode);
  2438         lc.push(switchNode);
  1688 
  2439 
  1689         CaseNode defaultCase = null;
  2440         CaseNode defaultCase = null;
  1690         // Prepare to accumulate cases.
  2441         // Prepare to accumulate cases.
  1691         final List<CaseNode> cases = new ArrayList<>();
  2442         final List<CaseNode> cases = new ArrayList<>();
  1725                 }
  2476                 }
  1726 
  2477 
  1727                 expect(COLON);
  2478                 expect(COLON);
  1728 
  2479 
  1729                 // Get CASE body.
  2480                 // Get CASE body.
  1730                 final Block statements = getBlock(false);
  2481                 final Block statements = getBlock(false); // TODO: List<Statement> statements = caseStatementList();
  1731                 final CaseNode caseNode = new CaseNode(caseToken, finish, caseExpression, statements);
  2482                 final CaseNode caseNode = new CaseNode(caseToken, finish, caseExpression, statements);
  1732 
  2483 
  1733                 if (caseExpression == null) {
  2484                 if (caseExpression == null) {
  1734                     defaultCase = caseNode;
  2485                     defaultCase = caseNode;
  1735                 }
  2486                 }
  1738             }
  2489             }
  1739 
  2490 
  1740             next();
  2491             next();
  1741         } finally {
  2492         } finally {
  1742             lc.pop(switchNode);
  2493             lc.pop(switchNode);
  1743         }
  2494             restoreBlock(switchBlock);
  1744 
  2495         }
  1745         appendStatement(new SwitchNode(switchLine, switchToken, finish, expression, cases, defaultCase));
  2496 
       
  2497         final SwitchNode switchStatement = new SwitchNode(switchLine, switchToken, finish, expression, cases, defaultCase);
       
  2498         appendStatement(new BlockStatement(switchLine, new Block(switchToken, finish, switchBlock.getFlags() | Block.IS_SYNTHETIC | Block.IS_SWITCH_BLOCK, switchStatement)));
  1746     }
  2499     }
  1747 
  2500 
  1748     /**
  2501     /**
  1749      * LabelledStatement :
  2502      * LabelledStatement :
  1750      *      Identifier : Statement
  2503      *      Identifier : Statement
  1767 
  2520 
  1768         final ParserContextLabelNode labelNode = new ParserContextLabelNode(ident.getName());
  2521         final ParserContextLabelNode labelNode = new ParserContextLabelNode(ident.getName());
  1769         Block body = null;
  2522         Block body = null;
  1770         try {
  2523         try {
  1771             lc.push(labelNode);
  2524             lc.push(labelNode);
  1772             body = getStatement();
  2525             body = getStatement(true);
  1773         } finally {
  2526         } finally {
  1774             assert lc.peek() instanceof ParserContextLabelNode;
  2527             assert lc.peek() instanceof ParserContextLabelNode;
  1775             lc.pop(labelNode);
  2528             lc.pop(labelNode);
  1776         }
  2529         }
  1777 
  2530 
  1933     }
  2686     }
  1934 
  2687 
  1935     /**
  2688     /**
  1936      * PrimaryExpression :
  2689      * PrimaryExpression :
  1937      *      this
  2690      *      this
  1938      *      Identifier
  2691      *      IdentifierReference
  1939      *      Literal
  2692      *      Literal
  1940      *      ArrayLiteral
  2693      *      ArrayLiteral
  1941      *      ObjectLiteral
  2694      *      ObjectLiteral
  1942      *      RegularExpressionLiteral
  2695      *      RegularExpressionLiteral
  1943      *      TemplateLiteral
  2696      *      TemplateLiteral
       
  2697      *      CoverParenthesizedExpressionAndArrowParameterList
       
  2698      *
       
  2699      * CoverParenthesizedExpressionAndArrowParameterList :
  1944      *      ( Expression )
  2700      *      ( Expression )
       
  2701      *      ( )
       
  2702      *      ( ... BindingIdentifier )
       
  2703      *      ( Expression , ... BindingIdentifier )
  1945      *
  2704      *
  1946      * Parse primary expression.
  2705      * Parse primary expression.
  1947      * @return Expression node.
  2706      * @return Expression node.
  1948      */
  2707      */
  1949     @SuppressWarnings("fallthrough")
  2708     @SuppressWarnings("fallthrough")
  1954 
  2713 
  1955         switch (type) {
  2714         switch (type) {
  1956         case THIS:
  2715         case THIS:
  1957             final String name = type.getName();
  2716             final String name = type.getName();
  1958             next();
  2717             next();
  1959             lc.getCurrentFunction().setFlag(FunctionNode.USES_THIS);
  2718             markThis(lc);
  1960             return new IdentNode(primaryToken, finish, name);
  2719             return new IdentNode(primaryToken, finish, name);
  1961         case IDENT:
  2720         case IDENT:
  1962             final IdentNode ident = getIdent();
  2721             final IdentNode ident = getIdent();
  1963             if (ident == null) {
  2722             if (ident == null) {
  1964                 break;
  2723                 break;
  1995         case LBRACE:
  2754         case LBRACE:
  1996             return objectLiteral();
  2755             return objectLiteral();
  1997         case LPAREN:
  2756         case LPAREN:
  1998             next();
  2757             next();
  1999 
  2758 
       
  2759             if (isES6()) {
       
  2760                 if (type == RPAREN) {
       
  2761                     // ()
       
  2762                     nextOrEOL();
       
  2763                     expectDontAdvance(ARROW);
       
  2764                     return new ExpressionList(primaryToken, finish, Collections.emptyList());
       
  2765                 } else if (type == ELLIPSIS) {
       
  2766                     // (...rest)
       
  2767                     final IdentNode restParam = formalParameterList(false).get(0);
       
  2768                     expectDontAdvance(RPAREN);
       
  2769                     nextOrEOL();
       
  2770                     expectDontAdvance(ARROW);
       
  2771                     return new ExpressionList(primaryToken, finish, Collections.singletonList(restParam));
       
  2772                 }
       
  2773             }
       
  2774 
  2000             final Expression expression = expression();
  2775             final Expression expression = expression();
  2001 
  2776 
  2002             expect(RPAREN);
  2777             expect(RPAREN);
  2003 
  2778 
  2004             return expression;
  2779             return expression;
  2071 
  2846 
  2072         // Prepare to accumulate elements.
  2847         // Prepare to accumulate elements.
  2073         final List<Expression> elements = new ArrayList<>();
  2848         final List<Expression> elements = new ArrayList<>();
  2074         // Track elisions.
  2849         // Track elisions.
  2075         boolean elision = true;
  2850         boolean elision = true;
  2076 loop:
  2851         loop:
  2077         while (true) {
  2852         while (true) {
       
  2853             long spreadToken = 0;
  2078             switch (type) {
  2854             switch (type) {
  2079             case RBRACKET:
  2855             case RBRACKET:
  2080                 next();
  2856                 next();
  2081 
  2857 
  2082                 break loop;
  2858                 break loop;
  2091 
  2867 
  2092                 elision = true;
  2868                 elision = true;
  2093 
  2869 
  2094                 break;
  2870                 break;
  2095 
  2871 
       
  2872             case ELLIPSIS:
       
  2873                 if (isES6()) {
       
  2874                     spreadToken = token;
       
  2875                     next();
       
  2876                 }
       
  2877                 // fall through
       
  2878 
  2096             default:
  2879             default:
  2097                 if (!elision) {
  2880                 if (!elision) {
  2098                     throw error(AbstractParser.message("expected.comma", type.getNameOrType()));
  2881                     throw error(AbstractParser.message("expected.comma", type.getNameOrType()));
  2099                 }
  2882                 }
       
  2883 
  2100                 // Add expression element.
  2884                 // Add expression element.
  2101                 final Expression expression = assignmentExpression(false);
  2885                 Expression expression = assignmentExpression(false);
  2102 
       
  2103                 if (expression != null) {
  2886                 if (expression != null) {
       
  2887                     if (spreadToken != 0) {
       
  2888                         expression = new UnaryNode(Token.recast(spreadToken, SPREAD_ARRAY), expression);
       
  2889                     }
  2104                     elements.add(expression);
  2890                     elements.add(expression);
  2105                 } else {
  2891                 } else {
  2106                     expect(RBRACKET);
  2892                     expect(RBRACKET);
  2107                 }
  2893                 }
  2108 
  2894 
  2139         final List<PropertyNode> elements = new ArrayList<>();
  2925         final List<PropertyNode> elements = new ArrayList<>();
  2140         final Map<String, Integer> map = new HashMap<>();
  2926         final Map<String, Integer> map = new HashMap<>();
  2141 
  2927 
  2142         // Create a block for the object literal.
  2928         // Create a block for the object literal.
  2143         boolean commaSeen = true;
  2929         boolean commaSeen = true;
  2144 loop:
  2930         loop:
  2145         while (true) {
  2931         while (true) {
  2146             switch (type) {
  2932             switch (type) {
  2147                 case RBRACE:
  2933                 case RBRACE:
  2148                     next();
  2934                     next();
  2149                     break loop;
  2935                     break loop;
  2162                     }
  2948                     }
  2163 
  2949 
  2164                     commaSeen = false;
  2950                     commaSeen = false;
  2165                     // Get and add the next property.
  2951                     // Get and add the next property.
  2166                     final PropertyNode property = propertyAssignment();
  2952                     final PropertyNode property = propertyAssignment();
       
  2953 
       
  2954                     if (property.isComputed()) {
       
  2955                         elements.add(property);
       
  2956                         break;
       
  2957                     }
       
  2958 
  2167                     final String key = property.getKeyName();
  2959                     final String key = property.getKeyName();
  2168                     final Integer existing = map.get(key);
  2960                     final Integer existing = map.get(key);
  2169 
  2961 
  2170                     if (existing == null) {
  2962                     if (existing == null) {
  2171                         map.put(key, elements.size());
  2963                         map.put(key, elements.size());
  2183 
  2975 
  2184                     final Expression   prevValue  = existingProperty.getValue();
  2976                     final Expression   prevValue  = existingProperty.getValue();
  2185                     final FunctionNode prevGetter = existingProperty.getGetter();
  2977                     final FunctionNode prevGetter = existingProperty.getGetter();
  2186                     final FunctionNode prevSetter = existingProperty.getSetter();
  2978                     final FunctionNode prevSetter = existingProperty.getSetter();
  2187 
  2979 
  2188                     // ECMA 11.1.5 strict mode restrictions
  2980                     if (!isES6()) {
  2189                     if (isStrictMode && value != null && prevValue != null) {
  2981                         checkPropertyRedefinition(property, value, getter, setter, prevValue, prevGetter, prevSetter);
  2190                         throw error(AbstractParser.message("property.redefinition", key), property.getToken());
  2982                     } else {
  2191                     }
  2983                         if (property.getKey() instanceof IdentNode && ((IdentNode)property.getKey()).isProtoPropertyName() &&
  2192 
  2984                                         existingProperty.getKey() instanceof IdentNode && ((IdentNode)existingProperty.getKey()).isProtoPropertyName()) {
  2193                     final boolean isPrevAccessor = prevGetter != null || prevSetter != null;
  2985                             throw error(AbstractParser.message("multiple.proto.key"), property.getToken());
  2194                     final boolean isAccessor     = getter != null     || setter != null;
       
  2195 
       
  2196                     // data property redefined as accessor property
       
  2197                     if (prevValue != null && isAccessor) {
       
  2198                         throw error(AbstractParser.message("property.redefinition", key), property.getToken());
       
  2199                     }
       
  2200 
       
  2201                     // accessor property redefined as data
       
  2202                     if (isPrevAccessor && value != null) {
       
  2203                         throw error(AbstractParser.message("property.redefinition", key), property.getToken());
       
  2204                     }
       
  2205 
       
  2206                     if (isAccessor && isPrevAccessor) {
       
  2207                         if (getter != null && prevGetter != null ||
       
  2208                                 setter != null && prevSetter != null) {
       
  2209                             throw error(AbstractParser.message("property.redefinition", key), property.getToken());
       
  2210                         }
  2986                         }
  2211                     }
  2987                     }
  2212 
  2988 
  2213                     if (value != null) {
  2989                     if (value != null || prevValue != null) {
       
  2990                         map.put(key, elements.size());
  2214                         elements.add(property);
  2991                         elements.add(property);
  2215                     } else if (getter != null) {
  2992                     } else if (getter != null) {
       
  2993                         assert prevGetter != null || prevSetter != null;
  2216                         elements.set(existing, existingProperty.setGetter(getter));
  2994                         elements.set(existing, existingProperty.setGetter(getter));
  2217                     } else if (setter != null) {
  2995                     } else if (setter != null) {
       
  2996                         assert prevGetter != null || prevSetter != null;
  2218                         elements.set(existing, existingProperty.setSetter(setter));
  2997                         elements.set(existing, existingProperty.setSetter(setter));
  2219                     }
  2998                     }
  2220                     break;
  2999                     break;
  2221             }
  3000             }
  2222         }
  3001         }
  2223 
  3002 
  2224         return new ObjectNode(objectToken, finish, elements);
  3003         return new ObjectNode(objectToken, finish, elements);
  2225     }
  3004     }
  2226 
  3005 
  2227     /**
  3006     private void checkPropertyRedefinition(final PropertyNode property, final Expression value, final FunctionNode getter, final FunctionNode setter, final Expression prevValue, final FunctionNode prevGetter, final FunctionNode prevSetter) {
  2228      * PropertyName :
  3007         // ECMA 11.1.5 strict mode restrictions
       
  3008         if (isStrictMode && value != null && prevValue != null) {
       
  3009             throw error(AbstractParser.message("property.redefinition", property.getKeyName()), property.getToken());
       
  3010         }
       
  3011 
       
  3012         final boolean isPrevAccessor = prevGetter != null || prevSetter != null;
       
  3013         final boolean isAccessor     = getter != null     || setter != null;
       
  3014 
       
  3015         // data property redefined as accessor property
       
  3016         if (prevValue != null && isAccessor) {
       
  3017             throw error(AbstractParser.message("property.redefinition", property.getKeyName()), property.getToken());
       
  3018         }
       
  3019 
       
  3020         // accessor property redefined as data
       
  3021         if (isPrevAccessor && value != null) {
       
  3022             throw error(AbstractParser.message("property.redefinition", property.getKeyName()), property.getToken());
       
  3023         }
       
  3024 
       
  3025         if (isAccessor && isPrevAccessor) {
       
  3026             if (getter != null && prevGetter != null ||
       
  3027                     setter != null && prevSetter != null) {
       
  3028                 throw error(AbstractParser.message("property.redefinition", property.getKeyName()), property.getToken());
       
  3029             }
       
  3030         }
       
  3031     }
       
  3032 
       
  3033     /**
       
  3034      * LiteralPropertyName :
  2229      *      IdentifierName
  3035      *      IdentifierName
  2230      *      StringLiteral
  3036      *      StringLiteral
  2231      *      NumericLiteral
  3037      *      NumericLiteral
  2232      *
  3038      *
  2233      * See 11.1.5
       
  2234      *
       
  2235      * @return PropertyName node
  3039      * @return PropertyName node
  2236      */
  3040      */
  2237     @SuppressWarnings("fallthrough")
  3041     @SuppressWarnings("fallthrough")
  2238     private PropertyKey propertyName() {
  3042     private PropertyKey literalPropertyName() {
  2239         switch (type) {
  3043         switch (type) {
  2240         case IDENT:
  3044         case IDENT:
  2241             return getIdent().setIsPropertyName();
  3045             return getIdent().setIsPropertyName();
  2242         case OCTAL_LEGACY:
  3046         case OCTAL_LEGACY:
  2243             if (isStrictMode) {
  3047             if (isStrictMode) {
  2255             return getIdentifierName().setIsPropertyName();
  3059             return getIdentifierName().setIsPropertyName();
  2256         }
  3060         }
  2257     }
  3061     }
  2258 
  3062 
  2259     /**
  3063     /**
       
  3064      * ComputedPropertyName :
       
  3065      *      AssignmentExpression
       
  3066      *
       
  3067      * @return PropertyName node
       
  3068      */
       
  3069     private Expression computedPropertyName() {
       
  3070         expect(LBRACKET);
       
  3071         Expression expression = assignmentExpression(false);
       
  3072         expect(RBRACKET);
       
  3073         return expression;
       
  3074     }
       
  3075 
       
  3076     /**
       
  3077      * PropertyName :
       
  3078      *      LiteralPropertyName
       
  3079      *      ComputedPropertyName
       
  3080      *
       
  3081      * @return PropertyName node
       
  3082      */
       
  3083     private Expression propertyName() {
       
  3084         if (type == LBRACKET && isES6()) {
       
  3085             return computedPropertyName();
       
  3086         } else {
       
  3087             return (Expression)literalPropertyName();
       
  3088         }
       
  3089     }
       
  3090 
       
  3091     /**
  2260      * PropertyAssignment :
  3092      * PropertyAssignment :
  2261      *      PropertyName : AssignmentExpression
  3093      *      PropertyName : AssignmentExpression
  2262      *      get PropertyName ( ) { FunctionBody }
  3094      *      get PropertyName ( ) { FunctionBody }
  2263      *      set PropertyName ( PropertySetParameterList ) { FunctionBody }
  3095      *      set PropertyName ( PropertySetParameterList ) { FunctionBody }
  2264      *
  3096      *
  2278     private PropertyNode propertyAssignment() {
  3110     private PropertyNode propertyAssignment() {
  2279         // Capture firstToken.
  3111         // Capture firstToken.
  2280         final long propertyToken = token;
  3112         final long propertyToken = token;
  2281         final int  functionLine  = line;
  3113         final int  functionLine  = line;
  2282 
  3114 
  2283         PropertyKey propertyName;
  3115         final Expression propertyName;
  2284 
  3116         final boolean isIdentifier;
       
  3117 
       
  3118         boolean generator = false;
       
  3119         if (type == MUL && isES6()) {
       
  3120             generator = true;
       
  3121             next();
       
  3122         }
       
  3123 
       
  3124         final boolean computed = type == LBRACKET;
  2285         if (type == IDENT) {
  3125         if (type == IDENT) {
  2286             // Get IDENT.
  3126             // Get IDENT.
  2287             final String ident = (String)expectValue(IDENT);
  3127             final String ident = (String)expectValue(IDENT);
  2288 
  3128 
  2289             if (type != COLON) {
  3129             if (type != COLON && (type != LPAREN || !isES6())) {
  2290                 final long getSetToken = propertyToken;
  3130                 final long getSetToken = propertyToken;
  2291 
  3131 
  2292                 switch (ident) {
  3132                 switch (ident) {
  2293                 case "get":
  3133                 case "get":
  2294                     final PropertyFunction getter = propertyGetterFunction(getSetToken, functionLine);
  3134                     final PropertyFunction getter = propertyGetterFunction(getSetToken, functionLine);
  2295                     return new PropertyNode(propertyToken, finish, getter.ident, null, getter.functionNode, null);
  3135                     return new PropertyNode(propertyToken, finish, getter.key, null, getter.functionNode, null, false, getter.computed);
  2296 
  3136 
  2297                 case "set":
  3137                 case "set":
  2298                     final PropertyFunction setter = propertySetterFunction(getSetToken, functionLine);
  3138                     final PropertyFunction setter = propertySetterFunction(getSetToken, functionLine);
  2299                     return new PropertyNode(propertyToken, finish, setter.ident, null, null, setter.functionNode);
  3139                     return new PropertyNode(propertyToken, finish, setter.key, null, null, setter.functionNode, false, setter.computed);
  2300                 default:
  3140                 default:
  2301                     break;
  3141                     break;
  2302                 }
  3142                 }
  2303             }
  3143             }
  2304 
  3144 
  2305             propertyName = createIdentNode(propertyToken, finish, ident).setIsPropertyName();
  3145             isIdentifier = true;
       
  3146             IdentNode identNode = createIdentNode(propertyToken, finish, ident).setIsPropertyName();
       
  3147             if (type == COLON && ident.equals("__proto__")) {
       
  3148                 identNode = identNode.setIsProtoPropertyName();
       
  3149             }
       
  3150             propertyName = identNode;
  2306         } else {
  3151         } else {
       
  3152             isIdentifier = isNonStrictModeIdent();
  2307             propertyName = propertyName();
  3153             propertyName = propertyName();
  2308         }
  3154         }
  2309 
  3155 
  2310         expect(COLON);
  3156         Expression propertyValue;
  2311 
  3157 
  2312         defaultNames.push(propertyName);
  3158         if (generator) {
  2313         try {
  3159             expectDontAdvance(LPAREN);
  2314             return new PropertyNode(propertyToken, finish, propertyName, assignmentExpression(false), null, null);
  3160         }
  2315         } finally {
  3161 
  2316             defaultNames.pop();
  3162         if (type == LPAREN && isES6()) {
  2317         }
  3163             propertyValue = propertyMethodFunction(propertyName, propertyToken, functionLine, generator, FunctionNode.ES6_IS_METHOD, computed).functionNode;
       
  3164         } else if (isIdentifier && (type == COMMARIGHT || type == RBRACE || type == ASSIGN) && isES6()) {
       
  3165             propertyValue = createIdentNode(propertyToken, finish, ((IdentNode) propertyName).getPropertyName());
       
  3166             if (type == ASSIGN && isES6()) {
       
  3167                 // TODO if not destructuring, this is a SyntaxError
       
  3168                 final long assignToken = token;
       
  3169                 next();
       
  3170                 final Expression rhs = assignmentExpression(false);
       
  3171                 propertyValue = verifyAssignment(assignToken, propertyValue, rhs);
       
  3172             }
       
  3173         } else {
       
  3174             expect(COLON);
       
  3175 
       
  3176             defaultNames.push(propertyName);
       
  3177             try {
       
  3178                 propertyValue = assignmentExpression(false);
       
  3179             } finally {
       
  3180                 defaultNames.pop();
       
  3181             }
       
  3182         }
       
  3183 
       
  3184         return new PropertyNode(propertyToken, finish, propertyName, propertyValue, null, null, false, computed);
  2318     }
  3185     }
  2319 
  3186 
  2320     private PropertyFunction propertyGetterFunction(final long getSetToken, final int functionLine) {
  3187     private PropertyFunction propertyGetterFunction(final long getSetToken, final int functionLine) {
  2321         final PropertyKey getIdent = propertyName();
  3188         return propertyGetterFunction(getSetToken, functionLine, FunctionNode.ES6_IS_METHOD);
  2322         final String getterName = getIdent.getPropertyName();
  3189     }
  2323         final IdentNode getNameNode = createIdentNode(((Node)getIdent).getToken(), finish, NameCodec.encode("get " + getterName));
  3190 
       
  3191     private PropertyFunction propertyGetterFunction(final long getSetToken, final int functionLine, final int flags) {
       
  3192         final boolean computed = type == LBRACKET;
       
  3193         final Expression propertyName = propertyName();
       
  3194         final String getterName = propertyName instanceof PropertyKey ? ((PropertyKey) propertyName).getPropertyName() : getDefaultValidFunctionName(functionLine, false);
       
  3195         final IdentNode getNameNode = createIdentNode((propertyName).getToken(), finish, NameCodec.encode("get " + getterName));
  2324         expect(LPAREN);
  3196         expect(LPAREN);
  2325         expect(RPAREN);
  3197         expect(RPAREN);
  2326 
  3198 
  2327         final ParserContextFunctionNode functionNode = createParserContextFunctionNode(getNameNode, getSetToken, FunctionNode.Kind.GETTER, functionLine, Collections.<IdentNode>emptyList());
  3199         final ParserContextFunctionNode functionNode = createParserContextFunctionNode(getNameNode, getSetToken, FunctionNode.Kind.GETTER, functionLine, Collections.<IdentNode>emptyList());
       
  3200         functionNode.setFlag(flags);
       
  3201         if (computed) {
       
  3202             functionNode.setFlag(FunctionNode.IS_ANONYMOUS);
       
  3203         }
  2328         lc.push(functionNode);
  3204         lc.push(functionNode);
  2329 
  3205 
  2330         Block functionBody;
  3206         Block functionBody;
  2331 
  3207 
  2332 
  3208 
  2343                 Collections.<IdentNode>emptyList(),
  3219                 Collections.<IdentNode>emptyList(),
  2344                 FunctionNode.Kind.GETTER,
  3220                 FunctionNode.Kind.GETTER,
  2345                 functionLine,
  3221                 functionLine,
  2346                 functionBody);
  3222                 functionBody);
  2347 
  3223 
  2348         return new PropertyFunction(getIdent, function);
  3224         return new PropertyFunction(propertyName, function, computed);
  2349     }
  3225     }
  2350 
  3226 
  2351     private PropertyFunction propertySetterFunction(final long getSetToken, final int functionLine) {
  3227     private PropertyFunction propertySetterFunction(final long getSetToken, final int functionLine) {
  2352         final PropertyKey setIdent = propertyName();
  3228         return propertySetterFunction(getSetToken, functionLine, FunctionNode.ES6_IS_METHOD);
  2353         final String setterName = setIdent.getPropertyName();
  3229     }
  2354         final IdentNode setNameNode = createIdentNode(((Node)setIdent).getToken(), finish, NameCodec.encode("set " + setterName));
  3230 
       
  3231     private PropertyFunction propertySetterFunction(final long getSetToken, final int functionLine, final int flags) {
       
  3232         final boolean computed = type == LBRACKET;
       
  3233         final Expression propertyName = propertyName();
       
  3234         final String setterName = propertyName instanceof PropertyKey ? ((PropertyKey) propertyName).getPropertyName() : getDefaultValidFunctionName(functionLine, false);
       
  3235         final IdentNode setNameNode = createIdentNode((propertyName).getToken(), finish, NameCodec.encode("set " + setterName));
  2355         expect(LPAREN);
  3236         expect(LPAREN);
  2356         // be sloppy and allow missing setter parameter even though
  3237         // be sloppy and allow missing setter parameter even though
  2357         // spec does not permit it!
  3238         // spec does not permit it!
  2358         final IdentNode argIdent;
  3239         final IdentNode argIdent;
  2359         if (type == IDENT || isNonStrictModeIdent()) {
  3240         if (isBindingIdentifier()) {
  2360             argIdent = getIdent();
  3241             argIdent = getIdent();
  2361             verifyStrictIdent(argIdent, "setter argument");
  3242             verifyIdent(argIdent, "setter argument");
  2362         } else {
  3243         } else {
  2363             argIdent = null;
  3244             argIdent = null;
  2364         }
  3245         }
  2365         expect(RPAREN);
  3246         expect(RPAREN);
  2366         final List<IdentNode> parameters = new ArrayList<>();
  3247         final List<IdentNode> parameters = new ArrayList<>();
  2368             parameters.add(argIdent);
  3249             parameters.add(argIdent);
  2369         }
  3250         }
  2370 
  3251 
  2371 
  3252 
  2372         final ParserContextFunctionNode functionNode = createParserContextFunctionNode(setNameNode, getSetToken, FunctionNode.Kind.SETTER, functionLine, parameters);
  3253         final ParserContextFunctionNode functionNode = createParserContextFunctionNode(setNameNode, getSetToken, FunctionNode.Kind.SETTER, functionLine, parameters);
       
  3254         functionNode.setFlag(flags);
       
  3255         if (computed) {
       
  3256             functionNode.setFlag(FunctionNode.IS_ANONYMOUS);
       
  3257         }
  2373         lc.push(functionNode);
  3258         lc.push(functionNode);
  2374 
  3259 
  2375         Block functionBody;
  3260         Block functionBody;
  2376         try {
  3261         try {
  2377             functionBody = functionBody(functionNode);
  3262             functionBody = functionBody(functionNode);
  2387                 parameters,
  3272                 parameters,
  2388                 FunctionNode.Kind.SETTER,
  3273                 FunctionNode.Kind.SETTER,
  2389                 functionLine,
  3274                 functionLine,
  2390                 functionBody);
  3275                 functionBody);
  2391 
  3276 
  2392         return new PropertyFunction(setIdent, function);
  3277         return new PropertyFunction(propertyName, function, computed);
       
  3278     }
       
  3279 
       
  3280     private PropertyFunction propertyMethodFunction(Expression key, final long methodToken, final int methodLine, final boolean generator, final int flags, boolean computed) {
       
  3281         final String methodName = key instanceof PropertyKey ? ((PropertyKey) key).getPropertyName() : getDefaultValidFunctionName(methodLine, false);
       
  3282         final IdentNode methodNameNode = createIdentNode(((Node)key).getToken(), finish, methodName);
       
  3283 
       
  3284         FunctionNode.Kind functionKind = generator ? FunctionNode.Kind.GENERATOR : FunctionNode.Kind.NORMAL;
       
  3285         final ParserContextFunctionNode functionNode = createParserContextFunctionNode(methodNameNode, methodToken, functionKind, methodLine, null);
       
  3286         functionNode.setFlag(flags);
       
  3287         if (computed) {
       
  3288             functionNode.setFlag(FunctionNode.IS_ANONYMOUS);
       
  3289         }
       
  3290         lc.push(functionNode);
       
  3291 
       
  3292         try {
       
  3293             final ParserContextBlockNode parameterBlock = newBlock();
       
  3294             final List<IdentNode> parameters;
       
  3295             try {
       
  3296                 expect(LPAREN);
       
  3297                 parameters = formalParameterList(generator);
       
  3298                 functionNode.setParameters(parameters);
       
  3299                 expect(RPAREN);
       
  3300             } finally {
       
  3301                 restoreBlock(parameterBlock);
       
  3302             }
       
  3303 
       
  3304             Block functionBody = functionBody(functionNode);
       
  3305 
       
  3306             functionBody = maybeWrapBodyInParameterBlock(functionBody, parameterBlock);
       
  3307 
       
  3308             final FunctionNode  function = createFunctionNode(
       
  3309                             functionNode,
       
  3310                             methodToken,
       
  3311                             methodNameNode,
       
  3312                             parameters,
       
  3313                             functionKind,
       
  3314                             methodLine,
       
  3315                             functionBody);
       
  3316             return new PropertyFunction(key, function, computed);
       
  3317         } finally {
       
  3318             lc.pop(functionNode);
       
  3319         }
  2393     }
  3320     }
  2394 
  3321 
  2395     private static class PropertyFunction {
  3322     private static class PropertyFunction {
  2396         final PropertyKey ident;
  3323         final Expression key;
  2397         final FunctionNode functionNode;
  3324         final FunctionNode functionNode;
  2398 
  3325         final boolean computed;
  2399         PropertyFunction(final PropertyKey ident, final FunctionNode function) {
  3326 
  2400             this.ident = ident;
  3327         PropertyFunction(final Expression key, final FunctionNode function, final boolean computed) {
       
  3328             this.key = key;
  2401             this.functionNode = function;
  3329             this.functionNode = function;
  2402         }
  3330             this.computed = computed;
  2403     }
  3331         }
  2404 
  3332     }
  2405     /**
  3333 
  2406      * Parse left hand side expression.
  3334     /**
  2407      *
       
  2408      * LeftHandSideExpression :
  3335      * LeftHandSideExpression :
  2409      *      NewExpression
  3336      *      NewExpression
  2410      *      CallExpression
  3337      *      CallExpression
  2411      *
  3338      *
  2412      * CallExpression :
  3339      * CallExpression :
  2413      *      MemberExpression Arguments
  3340      *      MemberExpression Arguments
       
  3341      *      SuperCall
  2414      *      CallExpression Arguments
  3342      *      CallExpression Arguments
  2415      *      CallExpression [ Expression ]
  3343      *      CallExpression [ Expression ]
  2416      *      CallExpression . IdentifierName
  3344      *      CallExpression . IdentifierName
  2417      *      CallExpression TemplateLiteral
  3345      *
  2418      *
  3346      * SuperCall :
       
  3347      *      super Arguments
       
  3348      *
       
  3349      * See 11.2
       
  3350      *
       
  3351      * Parse left hand side expression.
  2419      * @return Expression node.
  3352      * @return Expression node.
  2420      */
  3353      */
  2421     private Expression leftHandSideExpression() {
  3354     private Expression leftHandSideExpression() {
  2422         int  callLine  = line;
  3355         int  callLine  = line;
  2423         long callToken = token;
  3356         long callToken = token;
  2433             }
  3366             }
  2434 
  3367 
  2435             lhs = new CallNode(callLine, callToken, finish, lhs, arguments, false);
  3368             lhs = new CallNode(callLine, callToken, finish, lhs, arguments, false);
  2436         }
  3369         }
  2437 
  3370 
  2438 loop:
  3371         loop:
  2439         while (true) {
  3372         while (true) {
  2440             // Capture token.
  3373             // Capture token.
  2441             callLine  = line;
  3374             callLine  = line;
  2442             callToken = token;
  3375             callToken = token;
  2443 
  3376 
  2477             case TEMPLATE:
  3410             case TEMPLATE:
  2478             case TEMPLATE_HEAD: {
  3411             case TEMPLATE_HEAD: {
  2479                 // tagged template literal
  3412                 // tagged template literal
  2480                 final List<Expression> arguments = templateLiteralArgumentList();
  3413                 final List<Expression> arguments = templateLiteralArgumentList();
  2481 
  3414 
       
  3415                 // Create call node.
  2482                 lhs = new CallNode(callLine, callToken, finish, lhs, arguments, false);
  3416                 lhs = new CallNode(callLine, callToken, finish, lhs, arguments, false);
  2483 
  3417 
  2484                 break;
  3418                 break;
  2485             }
  3419             }
  2486             default:
  3420             default:
  2503      */
  3437      */
  2504     private Expression newExpression() {
  3438     private Expression newExpression() {
  2505         final long newToken = token;
  3439         final long newToken = token;
  2506         // NEW is tested in caller.
  3440         // NEW is tested in caller.
  2507         next();
  3441         next();
       
  3442 
       
  3443         if (type == PERIOD && isES6()) {
       
  3444             next();
       
  3445             if (type == IDENT && "target".equals(getValue())) {
       
  3446                 if (lc.getCurrentFunction().isProgram()) {
       
  3447                     throw error(AbstractParser.message("new.target.in.function"), token);
       
  3448                 }
       
  3449                 next();
       
  3450                 markNewTarget(lc);
       
  3451                 return new IdentNode(newToken, finish, "new.target");
       
  3452             } else {
       
  3453                 throw error(AbstractParser.message("expected.target"), token);
       
  3454             }
       
  3455         }
  2508 
  3456 
  2509         // Get function base.
  3457         // Get function base.
  2510         final int  callLine    = line;
  3458         final int  callLine    = line;
  2511         final Expression constructor = memberExpression();
  3459         final Expression constructor = memberExpression();
  2512         if (constructor == null) {
  3460         if (constructor == null) {
  2539 
  3487 
  2540         return new UnaryNode(newToken, callNode);
  3488         return new UnaryNode(newToken, callNode);
  2541     }
  3489     }
  2542 
  3490 
  2543     /**
  3491     /**
  2544      * Parse member expression.
       
  2545      *
       
  2546      * MemberExpression :
  3492      * MemberExpression :
  2547      *      PrimaryExpression
  3493      *      PrimaryExpression
  2548      *      FunctionExpression
  3494      *        FunctionExpression
       
  3495      *        ClassExpression
       
  3496      *        GeneratorExpression
  2549      *      MemberExpression [ Expression ]
  3497      *      MemberExpression [ Expression ]
  2550      *      MemberExpression . IdentifierName
  3498      *      MemberExpression . IdentifierName
  2551      *      MemberExpression TemplateLiteral
  3499      *      MemberExpression TemplateLiteral
       
  3500      *      SuperProperty
       
  3501      *      MetaProperty
  2552      *      new MemberExpression Arguments
  3502      *      new MemberExpression Arguments
  2553      *
  3503      *
       
  3504      * SuperProperty :
       
  3505      *      super [ Expression ]
       
  3506      *      super . IdentifierName
       
  3507      *
       
  3508      * MetaProperty :
       
  3509      *      NewTarget
       
  3510      *
       
  3511      * Parse member expression.
  2554      * @return Expression node.
  3512      * @return Expression node.
  2555      */
  3513      */
       
  3514     @SuppressWarnings("fallthrough")
  2556     private Expression memberExpression() {
  3515     private Expression memberExpression() {
  2557         // Prepare to build operation.
  3516         // Prepare to build operation.
  2558         Expression lhs;
  3517         Expression lhs;
       
  3518         boolean isSuper = false;
  2559 
  3519 
  2560         switch (type) {
  3520         switch (type) {
  2561         case NEW:
  3521         case NEW:
  2562             // Get new expression.
  3522             // Get new expression.
  2563             lhs = newExpression();
  3523             lhs = newExpression();
  2566         case FUNCTION:
  3526         case FUNCTION:
  2567             // Get function expression.
  3527             // Get function expression.
  2568             lhs = functionExpression(false, false);
  3528             lhs = functionExpression(false, false);
  2569             break;
  3529             break;
  2570 
  3530 
       
  3531         case CLASS:
       
  3532             if (isES6()) {
       
  3533                 lhs = classExpression(false);
       
  3534                 break;
       
  3535             } else {
       
  3536                 // fall through
       
  3537             }
       
  3538 
       
  3539         case SUPER:
       
  3540             if (isES6()) {
       
  3541                 final ParserContextFunctionNode currentFunction = getCurrentNonArrowFunction();
       
  3542                 if (currentFunction.isMethod()) {
       
  3543                     long identToken = Token.recast(token, IDENT);
       
  3544                     next();
       
  3545                     lhs = createIdentNode(identToken, finish, SUPER.getName());
       
  3546 
       
  3547                     switch (type) {
       
  3548                         case LBRACKET:
       
  3549                         case PERIOD:
       
  3550                             getCurrentNonArrowFunction().setFlag(FunctionNode.ES6_USES_SUPER);
       
  3551                             isSuper = true;
       
  3552                             break;
       
  3553                         case LPAREN:
       
  3554                             if (currentFunction.isSubclassConstructor()) {
       
  3555                                 lhs = ((IdentNode)lhs).setIsDirectSuper();
       
  3556                                 break;
       
  3557                             } else {
       
  3558                                 // fall through to throw error
       
  3559                             }
       
  3560                         default:
       
  3561                             throw error(AbstractParser.message("invalid.super"), identToken);
       
  3562                     }
       
  3563                     break;
       
  3564                 } else {
       
  3565                     // fall through
       
  3566                 }
       
  3567             } else {
       
  3568                 // fall through
       
  3569             }
       
  3570 
  2571         default:
  3571         default:
  2572             // Get primary expression.
  3572             // Get primary expression.
  2573             lhs = primaryExpression();
  3573             lhs = primaryExpression();
  2574             break;
  3574             break;
  2575         }
  3575         }
  2576 
  3576 
  2577 loop:
  3577         loop:
  2578         while (true) {
  3578         while (true) {
  2579             // Capture token.
  3579             // Capture token.
  2580             final long callToken = token;
  3580             final long callToken = token;
  2581 
  3581 
  2582             switch (type) {
  3582             switch (type) {
  2589                 expect(RBRACKET);
  3589                 expect(RBRACKET);
  2590 
  3590 
  2591                 // Create indexing node.
  3591                 // Create indexing node.
  2592                 lhs = new IndexNode(callToken, finish, lhs, index);
  3592                 lhs = new IndexNode(callToken, finish, lhs, index);
  2593 
  3593 
       
  3594                 if (isSuper) {
       
  3595                     isSuper = false;
       
  3596                     lhs = ((BaseNode) lhs).setIsSuper();
       
  3597                 }
       
  3598 
  2594                 break;
  3599                 break;
  2595             }
  3600             }
  2596             case PERIOD: {
  3601             case PERIOD: {
  2597                 if (lhs == null) {
  3602                 if (lhs == null) {
  2598                     throw error(AbstractParser.message("expected.operand", type.getNameOrType()));
  3603                     throw error(AbstractParser.message("expected.operand", type.getNameOrType()));
  2602 
  3607 
  2603                 final IdentNode property = getIdentifierName();
  3608                 final IdentNode property = getIdentifierName();
  2604 
  3609 
  2605                 // Create property access node.
  3610                 // Create property access node.
  2606                 lhs = new AccessNode(callToken, finish, lhs, property.getName());
  3611                 lhs = new AccessNode(callToken, finish, lhs, property.getName());
       
  3612 
       
  3613                 if (isSuper) {
       
  3614                     isSuper = false;
       
  3615                     lhs = ((BaseNode) lhs).setIsSuper();
       
  3616                 }
  2607 
  3617 
  2608                 break;
  3618                 break;
  2609             }
  3619             }
  2610             case TEMPLATE:
  3620             case TEMPLATE:
  2611             case TEMPLATE_HEAD: {
  3621             case TEMPLATE_HEAD: {
  2630      *      ( )
  3640      *      ( )
  2631      *      ( ArgumentList )
  3641      *      ( ArgumentList )
  2632      *
  3642      *
  2633      * ArgumentList :
  3643      * ArgumentList :
  2634      *      AssignmentExpression
  3644      *      AssignmentExpression
       
  3645      *      ... AssignmentExpression
  2635      *      ArgumentList , AssignmentExpression
  3646      *      ArgumentList , AssignmentExpression
       
  3647      *      ArgumentList , ... AssignmentExpression
  2636      *
  3648      *
  2637      * See 11.2
  3649      * See 11.2
  2638      *
  3650      *
  2639      * Parse function call arguments.
  3651      * Parse function call arguments.
  2640      * @return Argument list.
  3652      * @return Argument list.
  2654                 expect(COMMARIGHT);
  3666                 expect(COMMARIGHT);
  2655             } else {
  3667             } else {
  2656                 first = false;
  3668                 first = false;
  2657             }
  3669             }
  2658 
  3670 
       
  3671             long spreadToken = 0;
       
  3672             if (type == ELLIPSIS && isES6()) {
       
  3673                 spreadToken = token;
       
  3674                 next();
       
  3675             }
       
  3676 
  2659             // Get argument expression.
  3677             // Get argument expression.
  2660             nodeList.add(assignmentExpression(false));
  3678             Expression expression = assignmentExpression(false);
       
  3679             if (spreadToken != 0) {
       
  3680                 expression = new UnaryNode(Token.recast(spreadToken, TokenType.SPREAD_ARGUMENT), expression);
       
  3681             }
       
  3682             nodeList.add(expression);
  2661         }
  3683         }
  2662 
  3684 
  2663         expect(RPAREN);
  3685         expect(RPAREN);
  2664         return nodeList;
  3686         return nodeList;
  2665     }
  3687     }
  2695      */
  3717      */
  2696     private Expression functionExpression(final boolean isStatement, final boolean topLevel) {
  3718     private Expression functionExpression(final boolean isStatement, final boolean topLevel) {
  2697         final long functionToken = token;
  3719         final long functionToken = token;
  2698         final int  functionLine  = line;
  3720         final int  functionLine  = line;
  2699         // FUNCTION is tested in caller.
  3721         // FUNCTION is tested in caller.
       
  3722         assert type == FUNCTION;
  2700         next();
  3723         next();
  2701 
  3724 
       
  3725         boolean generator = false;
       
  3726         if (type == MUL && isES6()) {
       
  3727             generator = true;
       
  3728             next();
       
  3729         }
       
  3730 
  2702         IdentNode name = null;
  3731         IdentNode name = null;
  2703 
  3732 
  2704         if (type == IDENT || isNonStrictModeIdent()) {
  3733         if (isBindingIdentifier()) {
       
  3734             if (type == YIELD && ((!isStatement && generator) || (isStatement && inGeneratorFunction()))) {
       
  3735                 // 12.1.1 Early SyntaxError if:
       
  3736                 // GeneratorExpression with BindingIdentifier yield
       
  3737                 // HoistableDeclaration with BindingIdentifier yield in generator function body
       
  3738                 expect(IDENT);
       
  3739             }
  2705             name = getIdent();
  3740             name = getIdent();
  2706             verifyStrictIdent(name, "function name");
  3741             verifyStrictIdent(name, "function name");
  2707         } else if (isStatement) {
  3742         } else if (isStatement) {
  2708             // Nashorn extension: anonymous function statements.
  3743             // Nashorn extension: anonymous function statements.
  2709             // Do not allow anonymous function statement if extensions
  3744             // Do not allow anonymous function statement if extensions
  2721             final String tmpName = getDefaultValidFunctionName(functionLine, isStatement);
  3756             final String tmpName = getDefaultValidFunctionName(functionLine, isStatement);
  2722             name = new IdentNode(functionToken, Token.descPosition(functionToken), tmpName);
  3757             name = new IdentNode(functionToken, Token.descPosition(functionToken), tmpName);
  2723             isAnonymous = true;
  3758             isAnonymous = true;
  2724         }
  3759         }
  2725 
  3760 
  2726         expect(LPAREN);
  3761         FunctionNode.Kind functionKind = generator ? FunctionNode.Kind.GENERATOR : FunctionNode.Kind.NORMAL;
  2727         final List<IdentNode> parameters = formalParameterList();
  3762         List<IdentNode> parameters = Collections.emptyList();
  2728         expect(RPAREN);
  3763         final ParserContextFunctionNode functionNode = createParserContextFunctionNode(name, functionToken, functionKind, functionLine, parameters);
  2729 
       
  2730         final ParserContextFunctionNode functionNode = createParserContextFunctionNode(name, functionToken, FunctionNode.Kind.NORMAL, functionLine, parameters);
       
  2731         lc.push(functionNode);
  3764         lc.push(functionNode);
       
  3765 
  2732         Block functionBody = null;
  3766         Block functionBody = null;
  2733         // Hide the current default name across function boundaries. E.g. "x3 = function x1() { function() {}}"
  3767         // Hide the current default name across function boundaries. E.g. "x3 = function x1() { function() {}}"
  2734         // If we didn't hide the current default name, then the innermost anonymous function would receive "x3".
  3768         // If we didn't hide the current default name, then the innermost anonymous function would receive "x3".
  2735         hideDefaultName();
  3769         hideDefaultName();
  2736         try{
  3770         try {
       
  3771             final ParserContextBlockNode parameterBlock = newBlock();
       
  3772             try {
       
  3773                 expect(LPAREN);
       
  3774                 parameters = formalParameterList(generator);
       
  3775                 functionNode.setParameters(parameters);
       
  3776                 expect(RPAREN);
       
  3777             } finally {
       
  3778                 restoreBlock(parameterBlock);
       
  3779             }
       
  3780 
  2737             functionBody = functionBody(functionNode);
  3781             functionBody = functionBody(functionNode);
       
  3782 
       
  3783             functionBody = maybeWrapBodyInParameterBlock(functionBody, parameterBlock);
  2738         } finally {
  3784         } finally {
  2739             defaultNames.pop();
  3785             defaultNames.pop();
  2740             lc.pop(functionNode);
  3786             lc.pop(functionNode);
  2741         }
  3787         }
  2742 
  3788 
  2743         if (isStatement) {
  3789         if (isStatement) {
  2744             if (topLevel || useBlockScope()) {
  3790             if (topLevel || useBlockScope() || (!isStrictMode && env._function_statement == ScriptEnvironment.FunctionStatementBehavior.ACCEPT)) {
  2745                 functionNode.setFlag(FunctionNode.IS_DECLARED);
  3791                 functionNode.setFlag(FunctionNode.IS_DECLARED);
  2746             } else if (isStrictMode) {
  3792             } else if (isStrictMode) {
  2747                 throw error(JSErrorType.SYNTAX_ERROR, AbstractParser.message("strict.no.func.decl.here"), functionToken);
  3793                 throw error(JSErrorType.SYNTAX_ERROR, AbstractParser.message("strict.no.func.decl.here"), functionToken);
  2748             } else if (env._function_statement == ScriptEnvironment.FunctionStatementBehavior.ERROR) {
  3794             } else if (env._function_statement == ScriptEnvironment.FunctionStatementBehavior.ERROR) {
  2749                 throw error(JSErrorType.SYNTAX_ERROR, AbstractParser.message("no.func.decl.here"), functionToken);
  3795                 throw error(JSErrorType.SYNTAX_ERROR, AbstractParser.message("no.func.decl.here"), functionToken);
  2757 
  3803 
  2758         if (isAnonymous) {
  3804         if (isAnonymous) {
  2759             functionNode.setFlag(FunctionNode.IS_ANONYMOUS);
  3805             functionNode.setFlag(FunctionNode.IS_ANONYMOUS);
  2760         }
  3806         }
  2761 
  3807 
  2762         final int arity = parameters.size();
  3808         verifyParameterList(parameters, functionNode);
  2763 
       
  2764         final boolean strict = functionNode.isStrict();
       
  2765         if (arity > 1) {
       
  2766             final HashSet<String> parametersSet = new HashSet<>(arity);
       
  2767 
       
  2768             for (int i = arity - 1; i >= 0; i--) {
       
  2769                 final IdentNode parameter = parameters.get(i);
       
  2770                 String parameterName = parameter.getName();
       
  2771 
       
  2772                 if (isArguments(parameterName)) {
       
  2773                     functionNode.setFlag(FunctionNode.DEFINES_ARGUMENTS);
       
  2774                 }
       
  2775 
       
  2776                 if (parametersSet.contains(parameterName)) {
       
  2777                     // redefinition of parameter name
       
  2778                     if (strict) {
       
  2779                         throw error(AbstractParser.message("strict.param.redefinition", parameterName), parameter.getToken());
       
  2780                     }
       
  2781                     // rename in non-strict mode
       
  2782                     parameterName = functionNode.uniqueName(parameterName);
       
  2783                     final long parameterToken = parameter.getToken();
       
  2784                     parameters.set(i, new IdentNode(parameterToken, Token.descPosition(parameterToken), functionNode.uniqueName(parameterName)));
       
  2785                 }
       
  2786 
       
  2787                 parametersSet.add(parameterName);
       
  2788             }
       
  2789         } else if (arity == 1) {
       
  2790             if (isArguments(parameters.get(0))) {
       
  2791                 functionNode.setFlag(FunctionNode.DEFINES_ARGUMENTS);
       
  2792             }
       
  2793         }
       
  2794 
  3809 
  2795         final FunctionNode function = createFunctionNode(
  3810         final FunctionNode function = createFunctionNode(
  2796                 functionNode,
  3811                 functionNode,
  2797                 functionToken,
  3812                 functionToken,
  2798                 name,
  3813                 name,
  2799                 parameters,
  3814                 parameters,
  2800                 FunctionNode.Kind.NORMAL,
  3815                 functionKind,
  2801                 functionLine,
  3816                 functionLine,
  2802                 functionBody);
  3817                 functionBody);
  2803 
  3818 
  2804         if (isStatement) {
  3819         if (isStatement) {
  2805             if (isAnonymous) {
  3820             if (isAnonymous) {
  2820         }
  3835         }
  2821 
  3836 
  2822         return function;
  3837         return function;
  2823     }
  3838     }
  2824 
  3839 
       
  3840     private void verifyParameterList(final List<IdentNode> parameters, final ParserContextFunctionNode functionNode) {
       
  3841         final IdentNode duplicateParameter = functionNode.getDuplicateParameterBinding();
       
  3842         if (duplicateParameter != null) {
       
  3843             if (functionNode.isStrict() || functionNode.getKind() == FunctionNode.Kind.ARROW || !functionNode.isSimpleParameterList()) {
       
  3844                 throw error(AbstractParser.message("strict.param.redefinition", duplicateParameter.getName()), duplicateParameter.getToken());
       
  3845             }
       
  3846 
       
  3847             final int arity = parameters.size();
       
  3848             final HashSet<String> parametersSet = new HashSet<>(arity);
       
  3849 
       
  3850             for (int i = arity - 1; i >= 0; i--) {
       
  3851                 final IdentNode parameter = parameters.get(i);
       
  3852                 String parameterName = parameter.getName();
       
  3853 
       
  3854                 if (parametersSet.contains(parameterName)) {
       
  3855                     // redefinition of parameter name, rename in non-strict mode
       
  3856                     parameterName = functionNode.uniqueName(parameterName);
       
  3857                     final long parameterToken = parameter.getToken();
       
  3858                     parameters.set(i, new IdentNode(parameterToken, Token.descPosition(parameterToken), functionNode.uniqueName(parameterName)));
       
  3859                 }
       
  3860                 parametersSet.add(parameterName);
       
  3861             }
       
  3862         }
       
  3863     }
       
  3864 
       
  3865     private static Block maybeWrapBodyInParameterBlock(Block functionBody, ParserContextBlockNode parameterBlock) {
       
  3866         assert functionBody.isFunctionBody();
       
  3867         if (!parameterBlock.getStatements().isEmpty()) {
       
  3868             parameterBlock.appendStatement(new BlockStatement(functionBody));
       
  3869             return new Block(parameterBlock.getToken(), functionBody.getFinish(), (functionBody.getFlags() | Block.IS_PARAMETER_BLOCK) & ~Block.IS_BODY, parameterBlock.getStatements());
       
  3870         }
       
  3871         return functionBody;
       
  3872     }
       
  3873 
  2825     private String getDefaultValidFunctionName(final int functionLine, final boolean isStatement) {
  3874     private String getDefaultValidFunctionName(final int functionLine, final boolean isStatement) {
  2826         final String defaultFunctionName = getDefaultFunctionName();
  3875         final String defaultFunctionName = getDefaultFunctionName();
  2827         if (isValidIdentifier(defaultFunctionName)) {
  3876         if (isValidIdentifier(defaultFunctionName)) {
  2828             if (isStatement) {
  3877             if (isStatement) {
  2829                 // The name will be used as the LHS of a symbol assignment. We add the anonymous function
  3878                 // The name will be used as the LHS of a symbol assignment. We add the anonymous function
  2834         }
  3883         }
  2835         return ANON_FUNCTION_PREFIX.symbolName() + functionLine;
  3884         return ANON_FUNCTION_PREFIX.symbolName() + functionLine;
  2836     }
  3885     }
  2837 
  3886 
  2838     private static boolean isValidIdentifier(final String name) {
  3887     private static boolean isValidIdentifier(final String name) {
  2839         if(name == null || name.isEmpty()) {
  3888         if (name == null || name.isEmpty()) {
  2840             return false;
  3889             return false;
  2841         }
  3890         }
  2842         if(!Character.isJavaIdentifierStart(name.charAt(0))) {
  3891         if (!Character.isJavaIdentifierStart(name.charAt(0))) {
  2843             return false;
  3892             return false;
  2844         }
  3893         }
  2845         for(int i = 1; i < name.length(); ++i) {
  3894         for (int i = 1; i < name.length(); ++i) {
  2846             if(!Character.isJavaIdentifierPart(name.charAt(i))) {
  3895             if (!Character.isJavaIdentifierPart(name.charAt(i))) {
  2847                 return false;
  3896                 return false;
  2848             }
  3897             }
  2849         }
  3898         }
  2850         return true;
  3899         return true;
  2851     }
  3900     }
  2852 
  3901 
  2853     private String getDefaultFunctionName() {
  3902     private String getDefaultFunctionName() {
  2854         if(!defaultNames.isEmpty()) {
  3903         if (!defaultNames.isEmpty()) {
  2855             final Object nameExpr = defaultNames.peek();
  3904             final Object nameExpr = defaultNames.peek();
  2856             if(nameExpr instanceof PropertyKey) {
  3905             if (nameExpr instanceof PropertyKey) {
  2857                 markDefaultNameUsed();
  3906                 markDefaultNameUsed();
  2858                 return ((PropertyKey)nameExpr).getPropertyName();
  3907                 return ((PropertyKey)nameExpr).getPropertyName();
  2859             } else if(nameExpr instanceof AccessNode) {
  3908             } else if (nameExpr instanceof AccessNode) {
  2860                 markDefaultNameUsed();
  3909                 markDefaultNameUsed();
  2861                 return ((AccessNode)nameExpr).getProperty();
  3910                 return ((AccessNode)nameExpr).getProperty();
  2862             }
  3911             }
  2863         }
  3912         }
  2864         return null;
  3913         return null;
  2883      * See 13
  3932      * See 13
  2884      *
  3933      *
  2885      * Parse function parameter list.
  3934      * Parse function parameter list.
  2886      * @return List of parameter nodes.
  3935      * @return List of parameter nodes.
  2887      */
  3936      */
  2888     private List<IdentNode> formalParameterList() {
  3937     private List<IdentNode> formalParameterList(final boolean yield) {
  2889         return formalParameterList(RPAREN);
  3938         return formalParameterList(RPAREN, yield);
  2890     }
  3939     }
  2891 
  3940 
  2892     /**
  3941     /**
  2893      * Same as the other method of the same name - except that the end
  3942      * Same as the other method of the same name - except that the end
  2894      * token type expected is passed as argument to this method.
  3943      * token type expected is passed as argument to this method.
  2900      * See 13
  3949      * See 13
  2901      *
  3950      *
  2902      * Parse function parameter list.
  3951      * Parse function parameter list.
  2903      * @return List of parameter nodes.
  3952      * @return List of parameter nodes.
  2904      */
  3953      */
  2905     private List<IdentNode> formalParameterList(final TokenType endType) {
  3954     private List<IdentNode> formalParameterList(final TokenType endType, final boolean yield) {
  2906         // Prepare to gather parameters.
  3955         // Prepare to gather parameters.
  2907         final ArrayList<IdentNode> parameters = new ArrayList<>();
  3956         final ArrayList<IdentNode> parameters = new ArrayList<>();
  2908         // Track commas.
  3957         // Track commas.
  2909         boolean first = true;
  3958         boolean first = true;
  2910 
  3959 
  2914                 expect(COMMARIGHT);
  3963                 expect(COMMARIGHT);
  2915             } else {
  3964             } else {
  2916                 first = false;
  3965                 first = false;
  2917             }
  3966             }
  2918 
  3967 
  2919             // Get and add parameter.
  3968             boolean restParameter = false;
  2920             final IdentNode ident = getIdent();
  3969             if (type == ELLIPSIS && isES6()) {
  2921 
  3970                 next();
  2922             // ECMA 13.1 strict mode restrictions
  3971                 restParameter = true;
  2923             verifyStrictIdent(ident, "function parameter");
  3972             }
  2924 
  3973 
       
  3974             if (type == YIELD && yield) {
       
  3975                 expect(IDENT);
       
  3976             }
       
  3977 
       
  3978             final long paramToken = token;
       
  3979             final int paramLine = line;
       
  3980             final String contextString = "function parameter";
       
  3981             IdentNode ident;
       
  3982             if (isBindingIdentifier() || restParameter || !isES6()) {
       
  3983                 ident = bindingIdentifier(contextString);
       
  3984 
       
  3985                 if (restParameter) {
       
  3986                     ident = ident.setIsRestParameter();
       
  3987                     // rest parameter must be last
       
  3988                     expectDontAdvance(endType);
       
  3989                     parameters.add(ident);
       
  3990                     break;
       
  3991                 } else if (type == ASSIGN && isES6()) {
       
  3992                     next();
       
  3993                     ident = ident.setIsDefaultParameter();
       
  3994 
       
  3995                     if (type == YIELD && yield) {
       
  3996                         // error: yield in default expression
       
  3997                         expect(IDENT);
       
  3998                     }
       
  3999 
       
  4000                     // default parameter
       
  4001                     Expression initializer = assignmentExpression(false);
       
  4002 
       
  4003                     ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
       
  4004                     if (currentFunction != null) {
       
  4005                         // desugar to: param = (param === undefined) ? initializer : param;
       
  4006                         // possible alternative: if (param === undefined) param = initializer;
       
  4007                         BinaryNode test = new BinaryNode(Token.recast(paramToken, EQ_STRICT), ident, newUndefinedLiteral(paramToken, finish));
       
  4008                         TernaryNode value = new TernaryNode(Token.recast(paramToken, TERNARY), test, new JoinPredecessorExpression(initializer), new JoinPredecessorExpression(ident));
       
  4009                         BinaryNode assignment = new BinaryNode(Token.recast(paramToken, ASSIGN), ident, value);
       
  4010                         lc.getFunctionBody(currentFunction).appendStatement(new ExpressionStatement(paramLine, assignment.getToken(), assignment.getFinish(), assignment));
       
  4011                     }
       
  4012                 }
       
  4013 
       
  4014                 ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
       
  4015                 if (currentFunction != null) {
       
  4016                     currentFunction.addParameterBinding(ident);
       
  4017                     if (ident.isRestParameter() || ident.isDefaultParameter()) {
       
  4018                         currentFunction.setSimpleParameterList(false);
       
  4019                     }
       
  4020                 }
       
  4021             } else {
       
  4022                 final Expression pattern = bindingPattern();
       
  4023                 // Introduce synthetic temporary parameter to capture the object to be destructured.
       
  4024                 ident = createIdentNode(paramToken, pattern.getFinish(), String.format("arguments[%d]", parameters.size())).setIsDestructuredParameter();
       
  4025                 verifyDestructuringParameterBindingPattern(pattern, paramToken, paramLine, contextString);
       
  4026 
       
  4027                 Expression value = ident;
       
  4028                 if (type == ASSIGN) {
       
  4029                     next();
       
  4030                     ident = ident.setIsDefaultParameter();
       
  4031 
       
  4032                     // binding pattern with initializer. desugar to: (param === undefined) ? initializer : param
       
  4033                     Expression initializer = assignmentExpression(false);
       
  4034                     // TODO initializer must not contain yield expression if yield=true (i.e. this is generator function's parameter list)
       
  4035                     BinaryNode test = new BinaryNode(Token.recast(paramToken, EQ_STRICT), ident, newUndefinedLiteral(paramToken, finish));
       
  4036                     value = new TernaryNode(Token.recast(paramToken, TERNARY), test, new JoinPredecessorExpression(initializer), new JoinPredecessorExpression(ident));
       
  4037                 }
       
  4038 
       
  4039                 ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
       
  4040                 if (currentFunction != null) {
       
  4041                     // destructuring assignment
       
  4042                     BinaryNode assignment = new BinaryNode(Token.recast(paramToken, ASSIGN), pattern, value);
       
  4043                     lc.getFunctionBody(currentFunction).appendStatement(new ExpressionStatement(paramLine, assignment.getToken(), assignment.getFinish(), assignment));
       
  4044                 }
       
  4045             }
  2925             parameters.add(ident);
  4046             parameters.add(ident);
  2926         }
  4047         }
  2927 
  4048 
  2928         parameters.trimToSize();
  4049         parameters.trimToSize();
  2929         return parameters;
  4050         return parameters;
       
  4051     }
       
  4052 
       
  4053     private void verifyDestructuringParameterBindingPattern(final Expression pattern, final long paramToken, final int paramLine, final String contextString) {
       
  4054         verifyDestructuringBindingPattern(pattern, new Consumer<IdentNode>() {
       
  4055             public void accept(IdentNode identNode) {
       
  4056                 verifyIdent(identNode, contextString);
       
  4057 
       
  4058                 ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
       
  4059                 if (currentFunction != null) {
       
  4060                     // declare function-scope variables for destructuring bindings
       
  4061                     lc.getFunctionBody(currentFunction).appendStatement(new VarNode(paramLine, Token.recast(paramToken, VAR), pattern.getFinish(), identNode, null));
       
  4062                     // detect duplicate bounds names in parameter list
       
  4063                     currentFunction.addParameterBinding(identNode);
       
  4064                     currentFunction.setSimpleParameterList(false);
       
  4065                 }
       
  4066             }
       
  4067         });
  2930     }
  4068     }
  2931 
  4069 
  2932     /**
  4070     /**
  2933      * FunctionBody :
  4071      * FunctionBody :
  2934      *      SourceElements?
  4072      *      SourceElements?
  2956             }
  4094             }
  2957             assert functionNode != null;
  4095             assert functionNode != null;
  2958             final int functionId = functionNode.getId();
  4096             final int functionId = functionNode.getId();
  2959             parseBody = reparsedFunction == null || functionId <= reparsedFunction.getFunctionNodeId();
  4097             parseBody = reparsedFunction == null || functionId <= reparsedFunction.getFunctionNodeId();
  2960             // Nashorn extension: expression closures
  4098             // Nashorn extension: expression closures
  2961             if (!env._no_syntax_extensions && type != LBRACE) {
  4099             if ((!env._no_syntax_extensions || functionNode.getKind() == FunctionNode.Kind.ARROW) && type != LBRACE) {
  2962                 /*
  4100                 /*
  2963                  * Example:
  4101                  * Example:
  2964                  *
  4102                  *
  2965                  * function square(x) x * x;
  4103                  * function square(x) x * x;
  2966                  * print(square(3));
  4104                  * print(square(3));
  2967                  */
  4105                  */
  2968 
  4106 
  2969                 // just expression as function body
  4107                 // just expression as function body
  2970                 final Expression expr = assignmentExpression(true);
  4108                 final Expression expr = assignmentExpression(false);
  2971                 lastToken = previousToken;
  4109                 lastToken = previousToken;
  2972                 functionNode.setLastToken(previousToken);
  4110                 functionNode.setLastToken(previousToken);
  2973                 assert lc.getCurrentBlock() == lc.getFunctionBody(functionNode);
  4111                 assert lc.getCurrentBlock() == lc.getFunctionBody(functionNode);
  2974                 // EOL uses length field to store the line number
  4112                 // EOL uses length field to store the line number
  2975                 final int lastFinish = Token.descPosition(lastToken) + (Token.descType(lastToken) == EOL ? 0 : Token.descLength(lastToken));
  4113                 final int lastFinish = Token.descPosition(lastToken) + (Token.descType(lastToken) == EOL ? 0 : Token.descLength(lastToken));
  2980                 // details).
  4118                 // details).
  2981                 if (parseBody) {
  4119                 if (parseBody) {
  2982                     final ReturnNode returnNode = new ReturnNode(functionNode.getLineNumber(), expr.getToken(), lastFinish, expr);
  4120                     final ReturnNode returnNode = new ReturnNode(functionNode.getLineNumber(), expr.getToken(), lastFinish, expr);
  2983                     appendStatement(returnNode);
  4121                     appendStatement(returnNode);
  2984                 }
  4122                 }
       
  4123                 // bodyFinish = finish;
  2985             } else {
  4124             } else {
  2986                 expectDontAdvance(LBRACE);
  4125                 expectDontAdvance(LBRACE);
  2987                 if (parseBody || !skipFunctionBody(functionNode)) {
  4126                 if (parseBody || !skipFunctionBody(functionNode)) {
  2988                     next();
  4127                     next();
  2989                     // Gather the function elements.
  4128                     // Gather the function elements.
  3052                     assert functionNode.hasScopeBlock();
  4191                     assert functionNode.hasScopeBlock();
  3053                     body.setFlag(Block.NEEDS_SCOPE);
  4192                     body.setFlag(Block.NEEDS_SCOPE);
  3054                 }
  4193                 }
  3055             }
  4194             }
  3056         }
  4195         }
  3057         functionBody = new Block(bodyToken, bodyFinish, body.getFlags(), body.getStatements());
  4196         functionBody = new Block(bodyToken, bodyFinish, body.getFlags() | Block.IS_BODY, body.getStatements());
  3058         return functionBody;
  4197         return functionBody;
  3059     }
  4198     }
  3060 
  4199 
  3061     private boolean skipFunctionBody(final ParserContextFunctionNode functionNode) {
  4200     private boolean skipFunctionBody(final ParserContextFunctionNode functionNode) {
  3062         if (reparsedFunction == null) {
  4201         if (reparsedFunction == null) {
  3093         line = parserState.line;
  4232         line = parserState.line;
  3094         linePosition = parserState.linePosition;
  4233         linePosition = parserState.linePosition;
  3095         // Doesn't really matter, but it's safe to treat it as if there were a semicolon before
  4234         // Doesn't really matter, but it's safe to treat it as if there were a semicolon before
  3096         // the RBRACE.
  4235         // the RBRACE.
  3097         type = SEMICOLON;
  4236         type = SEMICOLON;
  3098         k = -1;
  4237         scanFirstToken();
  3099         next();
       
  3100 
  4238 
  3101         return true;
  4239         return true;
  3102     }
  4240     }
  3103 
  4241 
  3104     /**
  4242     /**
  3124             return newLexer;
  4262             return newLexer;
  3125         }
  4263         }
  3126     }
  4264     }
  3127 
  4265 
  3128     private void printAST(final FunctionNode functionNode) {
  4266     private void printAST(final FunctionNode functionNode) {
  3129         if (functionNode.getFlag(FunctionNode.IS_PRINT_AST)) {
  4267         if (functionNode.getDebugFlag(FunctionNode.DEBUG_PRINT_AST)) {
  3130             env.getErr().println(new ASTWriter(functionNode));
  4268             env.getErr().println(new ASTWriter(functionNode));
  3131         }
  4269         }
  3132 
  4270 
  3133         if (functionNode.getFlag(FunctionNode.IS_PRINT_PARSE)) {
  4271         if (functionNode.getDebugFlag(FunctionNode.DEBUG_PRINT_PARSE)) {
  3134             env.getErr().println(new PrintVisitor(functionNode, true, false));
  4272             env.getErr().println(new PrintVisitor(functionNode, true, false));
  3135         }
  4273         }
  3136     }
  4274     }
  3137 
  4275 
  3138     private void addFunctionDeclarations(final ParserContextFunctionNode functionNode) {
  4276     private void addFunctionDeclarations(final ParserContextFunctionNode functionNode) {
  3220             // ++, -- without operand..
  4358             // ++, -- without operand..
  3221             if (lhs == null) {
  4359             if (lhs == null) {
  3222                 throw error(AbstractParser.message("expected.lvalue", type.getNameOrType()));
  4360                 throw error(AbstractParser.message("expected.lvalue", type.getNameOrType()));
  3223             }
  4361             }
  3224 
  4362 
  3225             if (!(lhs instanceof AccessNode ||
  4363             return verifyIncDecExpression(unaryToken, opType, lhs, false);
  3226                   lhs instanceof IndexNode ||
       
  3227                   lhs instanceof IdentNode)) {
       
  3228                 return referenceError(lhs, null, env._early_lvalue_error);
       
  3229             }
       
  3230 
       
  3231             if (lhs instanceof IdentNode) {
       
  3232                 if (!checkIdentLValue((IdentNode)lhs)) {
       
  3233                     return referenceError(lhs, null, false);
       
  3234                 }
       
  3235                 verifyStrictIdent((IdentNode)lhs, "operand for " + opType.getName() + " operator");
       
  3236             }
       
  3237 
       
  3238             return incDecExpression(unaryToken, opType, lhs, false);
       
  3239 
  4364 
  3240         default:
  4365         default:
  3241             break;
  4366             break;
  3242         }
  4367         }
  3243 
  4368 
  3245 
  4370 
  3246         if (last != EOL) {
  4371         if (last != EOL) {
  3247             switch (type) {
  4372             switch (type) {
  3248             case INCPREFIX:
  4373             case INCPREFIX:
  3249             case DECPREFIX:
  4374             case DECPREFIX:
       
  4375                 final long opToken = token;
  3250                 final TokenType opType = type;
  4376                 final TokenType opType = type;
  3251                 final Expression lhs = expression;
  4377                 final Expression lhs = expression;
  3252                 // ++, -- without operand..
  4378                 // ++, -- without operand..
  3253                 if (lhs == null) {
  4379                 if (lhs == null) {
  3254                     throw error(AbstractParser.message("expected.lvalue", type.getNameOrType()));
  4380                     throw error(AbstractParser.message("expected.lvalue", type.getNameOrType()));
  3255                 }
  4381                 }
  3256 
       
  3257                 if (!(lhs instanceof AccessNode ||
       
  3258                    lhs instanceof IndexNode ||
       
  3259                    lhs instanceof IdentNode)) {
       
  3260                     next();
       
  3261                     return referenceError(lhs, null, env._early_lvalue_error);
       
  3262                 }
       
  3263                 if (lhs instanceof IdentNode) {
       
  3264                     if (!checkIdentLValue((IdentNode)lhs)) {
       
  3265                         next();
       
  3266                         return referenceError(lhs, null, false);
       
  3267                     }
       
  3268                     verifyStrictIdent((IdentNode)lhs, "operand for " + opType.getName() + " operator");
       
  3269                 }
       
  3270                 expression = incDecExpression(token, type, expression, true);
       
  3271                 next();
  4382                 next();
  3272                 break;
  4383 
       
  4384                 return verifyIncDecExpression(opToken, opType, lhs, true);
  3273             default:
  4385             default:
  3274                 break;
  4386                 break;
  3275             }
  4387             }
  3276         }
  4388         }
  3277 
  4389 
  3278         if (expression == null) {
  4390         if (expression == null) {
  3279             throw error(AbstractParser.message("expected.operand", type.getNameOrType()));
  4391             throw error(AbstractParser.message("expected.operand", type.getNameOrType()));
  3280         }
  4392         }
  3281 
  4393 
  3282         return expression;
  4394         return expression;
       
  4395     }
       
  4396 
       
  4397     private Expression verifyIncDecExpression(final long unaryToken, final TokenType opType, final Expression lhs, final boolean isPostfix) {
       
  4398         assert lhs != null;
       
  4399 
       
  4400         if (!(lhs instanceof AccessNode ||
       
  4401               lhs instanceof IndexNode ||
       
  4402               lhs instanceof IdentNode)) {
       
  4403             return referenceError(lhs, null, env._early_lvalue_error);
       
  4404         }
       
  4405 
       
  4406         if (lhs instanceof IdentNode) {
       
  4407             if (!checkIdentLValue((IdentNode)lhs)) {
       
  4408                 return referenceError(lhs, null, false);
       
  4409             }
       
  4410             verifyIdent((IdentNode)lhs, "operand for " + opType.getName() + " operator");
       
  4411         }
       
  4412 
       
  4413         return incDecExpression(unaryToken, opType, lhs, isPostfix);
  3283     }
  4414     }
  3284 
  4415 
  3285     /**
  4416     /**
  3286      * {@code
  4417      * {@code
  3287      * MultiplicativeExpression :
  4418      * MultiplicativeExpression :
  3378     protected Expression expression() {
  4509     protected Expression expression() {
  3379         // This method is protected so that subclass can get details
  4510         // This method is protected so that subclass can get details
  3380         // at expression start point!
  4511         // at expression start point!
  3381 
  4512 
  3382         // Include commas in expression parsing.
  4513         // Include commas in expression parsing.
  3383         return expression(unaryExpression(), COMMARIGHT.getPrecedence(), false);
  4514         return expression(false);
       
  4515     }
       
  4516 
       
  4517     private Expression expression(final boolean noIn) {
       
  4518         Expression assignmentExpression = assignmentExpression(noIn);
       
  4519         while (type == COMMARIGHT) {
       
  4520             long commaToken = token;
       
  4521             next();
       
  4522 
       
  4523             boolean rhsRestParameter = false;
       
  4524             if (type == ELLIPSIS && isES6()) {
       
  4525                 // (a, b, ...rest) is not a valid expression, unless we're parsing the parameter list of an arrow function (we need to throw the right error).
       
  4526                 // But since the rest parameter is always last, at least we know that the expression has to end here and be followed by RPAREN and ARROW, so peek ahead.
       
  4527                 if (isRestParameterEndOfArrowFunctionParameterList()) {
       
  4528                     next();
       
  4529                     rhsRestParameter = true;
       
  4530                 }
       
  4531             }
       
  4532 
       
  4533             Expression rhs = assignmentExpression(noIn);
       
  4534 
       
  4535             if (rhsRestParameter) {
       
  4536                 rhs = ((IdentNode)rhs).setIsRestParameter();
       
  4537                 // Our only valid move is to end Expression here and continue with ArrowFunction.
       
  4538                 // We've already checked that this is the parameter list of an arrow function (see above).
       
  4539                 // RPAREN is next, so we'll finish the binary expression and drop out of the loop.
       
  4540                 assert type == RPAREN;
       
  4541             }
       
  4542 
       
  4543             assignmentExpression = new BinaryNode(commaToken, assignmentExpression, rhs);
       
  4544         }
       
  4545         return assignmentExpression;
       
  4546     }
       
  4547 
       
  4548     private Expression expression(final int minPrecedence, final boolean noIn) {
       
  4549         return expression(unaryExpression(), minPrecedence, noIn);
  3384     }
  4550     }
  3385 
  4551 
  3386     private JoinPredecessorExpression joinPredecessorExpression() {
  4552     private JoinPredecessorExpression joinPredecessorExpression() {
  3387         return new JoinPredecessorExpression(expression());
  4553         return new JoinPredecessorExpression(expression());
  3388     }
  4554     }
  3446         }
  4612         }
  3447 
  4613 
  3448         return lhs;
  4614         return lhs;
  3449     }
  4615     }
  3450 
  4616 
       
  4617     /**
       
  4618      * AssignmentExpression.
       
  4619      *
       
  4620      * AssignmentExpression[In, Yield] :
       
  4621      *   ConditionalExpression[?In, ?Yield]
       
  4622      *   [+Yield] YieldExpression[?In]
       
  4623      *   ArrowFunction[?In, ?Yield]
       
  4624      *   LeftHandSideExpression[?Yield] = AssignmentExpression[?In, ?Yield]
       
  4625      *   LeftHandSideExpression[?Yield] AssignmentOperator AssignmentExpression[?In, ?Yield]
       
  4626      */
  3451     protected Expression assignmentExpression(final boolean noIn) {
  4627     protected Expression assignmentExpression(final boolean noIn) {
  3452         // This method is protected so that subclass can get details
  4628         // This method is protected so that subclass can get details
  3453         // at assignment expression start point!
  4629         // at assignment expression start point!
  3454 
  4630 
  3455         // Exclude commas in expression parsing.
  4631         if (type == YIELD && inGeneratorFunction() && isES6()) {
  3456         return expression(unaryExpression(), ASSIGN.getPrecedence(), noIn);
  4632             return yieldExpression(noIn);
       
  4633         }
       
  4634 
       
  4635         final long startToken = token;
       
  4636         final int startLine = line;
       
  4637         final Expression exprLhs = conditionalExpression(noIn);
       
  4638 
       
  4639         if (type == ARROW && isES6()) {
       
  4640             if (checkNoLineTerminator()) {
       
  4641                 final Expression paramListExpr;
       
  4642                 if (exprLhs instanceof ExpressionList) {
       
  4643                     paramListExpr = (((ExpressionList)exprLhs).getExpressions().isEmpty() ? null : ((ExpressionList)exprLhs).getExpressions().get(0));
       
  4644                 } else {
       
  4645                     paramListExpr = exprLhs;
       
  4646                 }
       
  4647                 return arrowFunction(startToken, startLine, paramListExpr);
       
  4648             }
       
  4649         }
       
  4650         assert !(exprLhs instanceof ExpressionList);
       
  4651 
       
  4652         if (isAssignmentOperator(type)) {
       
  4653             final boolean isAssign = type == ASSIGN;
       
  4654             if (isAssign) {
       
  4655                 defaultNames.push(exprLhs);
       
  4656             }
       
  4657             try {
       
  4658                 final long assignToken = token;
       
  4659                 next();
       
  4660                 final Expression exprRhs = assignmentExpression(noIn);
       
  4661                 return verifyAssignment(assignToken, exprLhs, exprRhs);
       
  4662             } finally {
       
  4663                 if (isAssign) {
       
  4664                     defaultNames.pop();
       
  4665                 }
       
  4666             }
       
  4667         } else {
       
  4668             return exprLhs;
       
  4669         }
       
  4670     }
       
  4671 
       
  4672     /**
       
  4673      * Is type one of {@code = *= /= %= += -= <<= >>= >>>= &= ^= |=}?
       
  4674      */
       
  4675     private static boolean isAssignmentOperator(TokenType type) {
       
  4676         switch (type) {
       
  4677         case ASSIGN:
       
  4678         case ASSIGN_ADD:
       
  4679         case ASSIGN_BIT_AND:
       
  4680         case ASSIGN_BIT_OR:
       
  4681         case ASSIGN_BIT_XOR:
       
  4682         case ASSIGN_DIV:
       
  4683         case ASSIGN_MOD:
       
  4684         case ASSIGN_MUL:
       
  4685         case ASSIGN_SAR:
       
  4686         case ASSIGN_SHL:
       
  4687         case ASSIGN_SHR:
       
  4688         case ASSIGN_SUB:
       
  4689             return true;
       
  4690         }
       
  4691         return false;
       
  4692     }
       
  4693 
       
  4694     /**
       
  4695      * ConditionalExpression.
       
  4696      */
       
  4697     private Expression conditionalExpression(boolean noIn) {
       
  4698         return expression(TERNARY.getPrecedence(), noIn);
       
  4699     }
       
  4700 
       
  4701     /**
       
  4702      * ArrowFunction.
       
  4703      *
       
  4704      * @param startToken start token of the ArrowParameters expression
       
  4705      * @param functionLine start line of the arrow function
       
  4706      * @param paramListExpr ArrowParameters expression or {@code null} for {@code ()} (empty list)
       
  4707      */
       
  4708     private Expression arrowFunction(final long startToken, final int functionLine, final Expression paramListExpr) {
       
  4709         // caller needs to check that there's no LineTerminator between parameter list and arrow
       
  4710         assert type != ARROW || checkNoLineTerminator();
       
  4711         expect(ARROW);
       
  4712 
       
  4713         final long functionToken = Token.recast(startToken, ARROW);
       
  4714         final IdentNode name = new IdentNode(functionToken, Token.descPosition(functionToken), "=>:" + functionLine);
       
  4715         final ParserContextFunctionNode functionNode = createParserContextFunctionNode(name, functionToken, FunctionNode.Kind.ARROW, functionLine, null);
       
  4716         functionNode.setFlag(FunctionNode.IS_ANONYMOUS);
       
  4717 
       
  4718         lc.push(functionNode);
       
  4719         try {
       
  4720             ParserContextBlockNode parameterBlock = newBlock();
       
  4721             final List<IdentNode> parameters;
       
  4722             try {
       
  4723                 parameters = convertArrowFunctionParameterList(paramListExpr, functionLine);
       
  4724                 functionNode.setParameters(parameters);
       
  4725 
       
  4726                 if (!functionNode.isSimpleParameterList()) {
       
  4727                     markEvalInArrowParameterList(parameterBlock);
       
  4728                 }
       
  4729             } finally {
       
  4730                 restoreBlock(parameterBlock);
       
  4731             }
       
  4732             Block functionBody = functionBody(functionNode);
       
  4733 
       
  4734             functionBody = maybeWrapBodyInParameterBlock(functionBody, parameterBlock);
       
  4735 
       
  4736             verifyParameterList(parameters, functionNode);
       
  4737 
       
  4738             final FunctionNode function = createFunctionNode(
       
  4739                             functionNode,
       
  4740                             functionToken,
       
  4741                             name,
       
  4742                             parameters,
       
  4743                             FunctionNode.Kind.ARROW,
       
  4744                             functionLine,
       
  4745                             functionBody);
       
  4746             return function;
       
  4747         } finally {
       
  4748             lc.pop(functionNode);
       
  4749         }
       
  4750     }
       
  4751 
       
  4752     private void markEvalInArrowParameterList(final ParserContextBlockNode parameterBlock) {
       
  4753         final Iterator<ParserContextFunctionNode> iter = lc.getFunctions();
       
  4754         final ParserContextFunctionNode current = iter.next();
       
  4755         final ParserContextFunctionNode parent = iter.next();
       
  4756 
       
  4757         if (parent.getFlag(FunctionNode.HAS_EVAL) != 0) {
       
  4758             // we might have flagged has-eval in the parent function during parsing the parameter list,
       
  4759             // if the parameter list contains eval; must tag arrow function as has-eval.
       
  4760             for (final Statement st : parameterBlock.getStatements()) {
       
  4761                 st.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
       
  4762                     @Override
       
  4763                     public boolean enterCallNode(final CallNode callNode) {
       
  4764                         if (callNode.getFunction() instanceof IdentNode && ((IdentNode) callNode.getFunction()).getName().equals("eval")) {
       
  4765                             current.setFlag(FunctionNode.HAS_EVAL);
       
  4766                         }
       
  4767                         return true;
       
  4768                     }
       
  4769                 });
       
  4770             }
       
  4771             // TODO: function containing the arrow function should not be flagged has-eval
       
  4772         }
       
  4773     }
       
  4774 
       
  4775     private List<IdentNode> convertArrowFunctionParameterList(final Expression paramListExpr, final int functionLine) {
       
  4776         final List<IdentNode> parameters;
       
  4777         if (paramListExpr == null) {
       
  4778             // empty parameter list, i.e. () =>
       
  4779             parameters = Collections.emptyList();
       
  4780         } else if (paramListExpr instanceof IdentNode || paramListExpr.isTokenType(ASSIGN) || isDestructuringLhs(paramListExpr)) {
       
  4781             parameters = Collections.singletonList(verifyArrowParameter(paramListExpr, 0, functionLine));
       
  4782         } else if (paramListExpr instanceof BinaryNode && Token.descType(paramListExpr.getToken()) == COMMARIGHT) {
       
  4783             parameters = new ArrayList<>();
       
  4784             Expression car = paramListExpr;
       
  4785             do {
       
  4786                 final Expression cdr = ((BinaryNode) car).rhs();
       
  4787                 parameters.add(0, verifyArrowParameter(cdr, parameters.size(), functionLine));
       
  4788                 car = ((BinaryNode) car).lhs();
       
  4789             } while (car instanceof BinaryNode && Token.descType(car.getToken()) == COMMARIGHT);
       
  4790             parameters.add(0, verifyArrowParameter(car, parameters.size(), functionLine));
       
  4791         } else {
       
  4792             throw error(AbstractParser.message("expected.arrow.parameter"), paramListExpr.getToken());
       
  4793         }
       
  4794         return parameters;
       
  4795     }
       
  4796 
       
  4797     private IdentNode verifyArrowParameter(Expression param, int index, int paramLine) {
       
  4798         final String contextString = "function parameter";
       
  4799         if (param instanceof IdentNode) {
       
  4800             IdentNode ident = (IdentNode)param;
       
  4801             verifyStrictIdent(ident, contextString);
       
  4802             ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
       
  4803             if (currentFunction != null) {
       
  4804                 currentFunction.addParameterBinding(ident);
       
  4805             }
       
  4806             return ident;
       
  4807         }
       
  4808 
       
  4809         if (param.isTokenType(ASSIGN)) {
       
  4810             Expression lhs = ((BinaryNode) param).lhs();
       
  4811             long paramToken = lhs.getToken();
       
  4812             Expression initializer = ((BinaryNode) param).rhs();
       
  4813             if (lhs instanceof IdentNode) {
       
  4814                 // default parameter
       
  4815                 IdentNode ident = (IdentNode) lhs;
       
  4816 
       
  4817                 ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
       
  4818                 if (currentFunction != null) {
       
  4819                     BinaryNode test = new BinaryNode(Token.recast(paramToken, EQ_STRICT), ident, newUndefinedLiteral(paramToken, finish));
       
  4820                     TernaryNode value = new TernaryNode(Token.recast(paramToken, TERNARY), test, new JoinPredecessorExpression(initializer), new JoinPredecessorExpression(ident));
       
  4821                     BinaryNode assignment = new BinaryNode(Token.recast(paramToken, ASSIGN), ident, value);
       
  4822                     lc.getFunctionBody(currentFunction).appendStatement(new ExpressionStatement(paramLine, assignment.getToken(), assignment.getFinish(), assignment));
       
  4823 
       
  4824                     currentFunction.addParameterBinding(ident);
       
  4825                     currentFunction.setSimpleParameterList(false);
       
  4826                 }
       
  4827                 return ident;
       
  4828             } else if (isDestructuringLhs(lhs)) {
       
  4829                 // binding pattern with initializer
       
  4830                 // Introduce synthetic temporary parameter to capture the object to be destructured.
       
  4831                 IdentNode ident = createIdentNode(paramToken, param.getFinish(), String.format("arguments[%d]", index)).setIsDestructuredParameter().setIsDefaultParameter();
       
  4832                 verifyDestructuringParameterBindingPattern(param, paramToken, paramLine, contextString);
       
  4833 
       
  4834                 ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
       
  4835                 if (currentFunction != null) {
       
  4836                     BinaryNode test = new BinaryNode(Token.recast(paramToken, EQ_STRICT), ident, newUndefinedLiteral(paramToken, finish));
       
  4837                     TernaryNode value = new TernaryNode(Token.recast(paramToken, TERNARY), test, new JoinPredecessorExpression(initializer), new JoinPredecessorExpression(ident));
       
  4838                     BinaryNode assignment = new BinaryNode(Token.recast(paramToken, ASSIGN), param, value);
       
  4839                     lc.getFunctionBody(currentFunction).appendStatement(new ExpressionStatement(paramLine, assignment.getToken(), assignment.getFinish(), assignment));
       
  4840                 }
       
  4841                 return ident;
       
  4842             }
       
  4843         } else if (isDestructuringLhs(param)) {
       
  4844             // binding pattern
       
  4845             long paramToken = param.getToken();
       
  4846 
       
  4847             // Introduce synthetic temporary parameter to capture the object to be destructured.
       
  4848             IdentNode ident = createIdentNode(paramToken, param.getFinish(), String.format("arguments[%d]", index)).setIsDestructuredParameter();
       
  4849             verifyDestructuringParameterBindingPattern(param, paramToken, paramLine, contextString);
       
  4850 
       
  4851             ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
       
  4852             if (currentFunction != null) {
       
  4853                 BinaryNode assignment = new BinaryNode(Token.recast(paramToken, ASSIGN), param, ident);
       
  4854                 lc.getFunctionBody(currentFunction).appendStatement(new ExpressionStatement(paramLine, assignment.getToken(), assignment.getFinish(), assignment));
       
  4855             }
       
  4856             return ident;
       
  4857         }
       
  4858         throw error(AbstractParser.message("invalid.arrow.parameter"), param.getToken());
       
  4859     }
       
  4860 
       
  4861     private boolean checkNoLineTerminator() {
       
  4862         assert type == ARROW;
       
  4863         if (last == RPAREN) {
       
  4864             return true;
       
  4865         } else if (last == IDENT) {
       
  4866             return true;
       
  4867         }
       
  4868         for (int i = k - 1; i >= 0; i--) {
       
  4869             TokenType t = T(i);
       
  4870             switch (t) {
       
  4871             case RPAREN:
       
  4872             case IDENT:
       
  4873                 return true;
       
  4874             case EOL:
       
  4875                 return false;
       
  4876             case COMMENT:
       
  4877                 continue;
       
  4878             default:
       
  4879                 if (t.getKind() == TokenKind.FUTURESTRICT) {
       
  4880                     return true;
       
  4881                 }
       
  4882                 return false;
       
  4883             }
       
  4884         }
       
  4885         return false;
       
  4886     }
       
  4887 
       
  4888     /**
       
  4889      * Peek ahead to see if what follows after the ellipsis is a rest parameter
       
  4890      * at the end of an arrow function parameter list.
       
  4891      */
       
  4892     private boolean isRestParameterEndOfArrowFunctionParameterList() {
       
  4893         assert type == ELLIPSIS;
       
  4894         // find IDENT, RPAREN, ARROW, in that order, skipping over EOL (where allowed) and COMMENT
       
  4895         int i = 1;
       
  4896         for (;;) {
       
  4897             TokenType t = T(k + i++);
       
  4898             if (t == IDENT) {
       
  4899                 break;
       
  4900             } else if (t == EOL || t == COMMENT) {
       
  4901                 continue;
       
  4902             } else {
       
  4903                 return false;
       
  4904             }
       
  4905         }
       
  4906         for (;;) {
       
  4907             TokenType t = T(k + i++);
       
  4908             if (t == RPAREN) {
       
  4909                 break;
       
  4910             } else if (t == EOL || t == COMMENT) {
       
  4911                 continue;
       
  4912             } else {
       
  4913                 return false;
       
  4914             }
       
  4915         }
       
  4916         for (;;) {
       
  4917             TokenType t = T(k + i++);
       
  4918             if (t == ARROW) {
       
  4919                 break;
       
  4920             } else if (t == COMMENT) {
       
  4921                 continue;
       
  4922             } else {
       
  4923                 return false;
       
  4924             }
       
  4925         }
       
  4926         return true;
  3457     }
  4927     }
  3458 
  4928 
  3459     /**
  4929     /**
  3460      * Parse an end of line.
  4930      * Parse an end of line.
  3461      */
  4931      */
  3549         next();
  5019         next();
  3550         rawStrings.add(LiteralNode.newInstance(stringToken, finish, rawString));
  5020         rawStrings.add(LiteralNode.newInstance(stringToken, finish, rawString));
  3551         cookedStrings.add(LiteralNode.newInstance(stringToken, finish, cookedString));
  5021         cookedStrings.add(LiteralNode.newInstance(stringToken, finish, cookedString));
  3552     }
  5022     }
  3553 
  5023 
       
  5024 
       
  5025     /**
       
  5026      * Parse a module.
       
  5027      *
       
  5028      * Module :
       
  5029      *      ModuleBody?
       
  5030      *
       
  5031      * ModuleBody :
       
  5032      *      ModuleItemList
       
  5033      */
       
  5034     private FunctionNode module(final String moduleName) {
       
  5035         boolean oldStrictMode = isStrictMode;
       
  5036         try {
       
  5037             isStrictMode = true; // Module code is always strict mode code. (ES6 10.2.1)
       
  5038 
       
  5039             // Make a pseudo-token for the script holding its start and length.
       
  5040             int functionStart = Math.min(Token.descPosition(Token.withDelimiter(token)), finish);
       
  5041             final long functionToken = Token.toDesc(FUNCTION, functionStart, source.getLength() - functionStart);
       
  5042             final int  functionLine  = line;
       
  5043 
       
  5044             final IdentNode ident = new IdentNode(functionToken, Token.descPosition(functionToken), moduleName);
       
  5045             final ParserContextFunctionNode script = createParserContextFunctionNode(
       
  5046                             ident,
       
  5047                             functionToken,
       
  5048                             FunctionNode.Kind.MODULE,
       
  5049                             functionLine,
       
  5050                             Collections.<IdentNode>emptyList());
       
  5051             lc.push(script);
       
  5052 
       
  5053             final ParserContextModuleNode module = new ParserContextModuleNode(moduleName);
       
  5054             lc.push(module);
       
  5055 
       
  5056             final ParserContextBlockNode body = newBlock();
       
  5057 
       
  5058             functionDeclarations = new ArrayList<>();
       
  5059             moduleBody();
       
  5060             addFunctionDeclarations(script);
       
  5061             functionDeclarations = null;
       
  5062 
       
  5063             restoreBlock(body);
       
  5064             body.setFlag(Block.NEEDS_SCOPE);
       
  5065             final Block programBody = new Block(functionToken, finish, body.getFlags() | Block.IS_SYNTHETIC | Block.IS_BODY, body.getStatements());
       
  5066             lc.pop(module);
       
  5067             lc.pop(script);
       
  5068             script.setLastToken(token);
       
  5069 
       
  5070             expect(EOF);
       
  5071 
       
  5072             script.setModule(module.createModule());
       
  5073             return createFunctionNode(script, functionToken, ident, Collections.<IdentNode>emptyList(), FunctionNode.Kind.MODULE, functionLine, programBody);
       
  5074         } finally {
       
  5075             isStrictMode = oldStrictMode;
       
  5076         }
       
  5077     }
       
  5078 
       
  5079     /**
       
  5080      * Parse module body.
       
  5081      *
       
  5082      * ModuleBody :
       
  5083      *      ModuleItemList
       
  5084      *
       
  5085      * ModuleItemList :
       
  5086      *      ModuleItem
       
  5087      *      ModuleItemList ModuleItem
       
  5088      *
       
  5089      * ModuleItem :
       
  5090      *      ImportDeclaration
       
  5091      *      ExportDeclaration
       
  5092      *      StatementListItem
       
  5093      */
       
  5094     private void moduleBody() {
       
  5095         loop:
       
  5096         while (type != EOF) {
       
  5097             switch (type) {
       
  5098             case EOF:
       
  5099                 break loop;
       
  5100             case IMPORT:
       
  5101                 importDeclaration();
       
  5102                 break;
       
  5103             case EXPORT:
       
  5104                 exportDeclaration();
       
  5105                 break;
       
  5106             default:
       
  5107                 // StatementListItem
       
  5108                 statement(true, false, false, false);
       
  5109                 break;
       
  5110             }
       
  5111         }
       
  5112     }
       
  5113 
       
  5114 
       
  5115     /**
       
  5116      * Parse import declaration.
       
  5117      *
       
  5118      * ImportDeclaration :
       
  5119      *     import ImportClause FromClause ;
       
  5120      *     import ModuleSpecifier ;
       
  5121      * ImportClause :
       
  5122      *     ImportedDefaultBinding
       
  5123      *     NameSpaceImport
       
  5124      *     NamedImports
       
  5125      *     ImportedDefaultBinding , NameSpaceImport
       
  5126      *     ImportedDefaultBinding , NamedImports
       
  5127      * ImportedDefaultBinding :
       
  5128      *     ImportedBinding
       
  5129      * ModuleSpecifier :
       
  5130      *     StringLiteral
       
  5131      * ImportedBinding :
       
  5132      *     BindingIdentifier
       
  5133      */
       
  5134     private void importDeclaration() {
       
  5135         expect(IMPORT);
       
  5136         final ParserContextModuleNode module = lc.getCurrentModule();
       
  5137         if (type == STRING || type == ESCSTRING) {
       
  5138             // import ModuleSpecifier ;
       
  5139             final String moduleSpecifier = (String) getValue();
       
  5140             next();
       
  5141             module.addModuleRequest(moduleSpecifier);
       
  5142         } else {
       
  5143             // import ImportClause FromClause ;
       
  5144             List<Module.ImportEntry> importEntries;
       
  5145             if (type == MUL) {
       
  5146                 importEntries = Collections.singletonList(nameSpaceImport());
       
  5147             } else if (type == LBRACE) {
       
  5148                 importEntries = namedImports();
       
  5149             } else if (isBindingIdentifier()) {
       
  5150                 // ImportedDefaultBinding
       
  5151                 final IdentNode importedDefaultBinding = bindingIdentifier("ImportedBinding");
       
  5152                 Module.ImportEntry defaultImport = Module.ImportEntry.importDefault(importedDefaultBinding.getName());
       
  5153 
       
  5154                 if (type == COMMARIGHT) {
       
  5155                     next();
       
  5156                     importEntries = new ArrayList<>();
       
  5157                     if (type == MUL) {
       
  5158                         importEntries.add(nameSpaceImport());
       
  5159                     } else if (type == LBRACE) {
       
  5160                         importEntries.addAll(namedImports());
       
  5161                     } else {
       
  5162                         throw error(AbstractParser.message("expected.named.import"));
       
  5163                     }
       
  5164                 } else {
       
  5165                     importEntries = Collections.singletonList(defaultImport);
       
  5166                 }
       
  5167             } else {
       
  5168                 throw error(AbstractParser.message("expected.import"));
       
  5169             }
       
  5170 
       
  5171             final String moduleSpecifier = fromClause();
       
  5172             module.addModuleRequest(moduleSpecifier);
       
  5173             for (int i = 0; i < importEntries.size(); i++) {
       
  5174                 module.addImportEntry(importEntries.get(i).withFrom(moduleSpecifier));
       
  5175             }
       
  5176         }
       
  5177         expect(SEMICOLON);
       
  5178     }
       
  5179 
       
  5180     /**
       
  5181      * NameSpaceImport :
       
  5182      *     * as ImportedBinding
       
  5183      *
       
  5184      * @return imported binding identifier
       
  5185      */
       
  5186     private Module.ImportEntry nameSpaceImport() {
       
  5187         assert type == MUL;
       
  5188         next();
       
  5189         final long asToken = token;
       
  5190         final String as = (String) expectValue(IDENT);
       
  5191         if (!"as".equals(as)) {
       
  5192             throw error(AbstractParser.message("expected.as"), asToken);
       
  5193         }
       
  5194         final IdentNode localNameSpace = bindingIdentifier("ImportedBinding");
       
  5195         return Module.ImportEntry.importStarAsNameSpaceFrom(localNameSpace.getName());
       
  5196     }
       
  5197 
       
  5198     /**
       
  5199      * NamedImports :
       
  5200      *     { }
       
  5201      *     { ImportsList }
       
  5202      *     { ImportsList , }
       
  5203      * ImportsList :
       
  5204      *     ImportSpecifier
       
  5205      *     ImportsList , ImportSpecifier
       
  5206      * ImportSpecifier :
       
  5207      *     ImportedBinding
       
  5208      *     IdentifierName as ImportedBinding
       
  5209      * ImportedBinding :
       
  5210      *     BindingIdentifier
       
  5211      */
       
  5212     private List<Module.ImportEntry> namedImports() {
       
  5213         assert type == LBRACE;
       
  5214         next();
       
  5215         List<Module.ImportEntry> importEntries = new ArrayList<>();
       
  5216         while (type != RBRACE) {
       
  5217             final boolean bindingIdentifier = isBindingIdentifier();
       
  5218             final long nameToken = token;
       
  5219             final IdentNode importName = getIdentifierName();
       
  5220             if (type == IDENT && "as".equals(getValue())) {
       
  5221                 next();
       
  5222                 final IdentNode localName = bindingIdentifier("ImportedBinding");
       
  5223                 importEntries.add(Module.ImportEntry.importSpecifier(importName.getName(), localName.getName()));
       
  5224             } else if (!bindingIdentifier) {
       
  5225                 throw error(AbstractParser.message("expected.binding.identifier"), nameToken);
       
  5226             } else {
       
  5227                 importEntries.add(Module.ImportEntry.importSpecifier(importName.getName()));
       
  5228             }
       
  5229             if (type == COMMARIGHT) {
       
  5230                 next();
       
  5231             } else {
       
  5232                 break;
       
  5233             }
       
  5234         }
       
  5235         expect(RBRACE);
       
  5236         return importEntries;
       
  5237     }
       
  5238 
       
  5239     /**
       
  5240      * FromClause :
       
  5241      *     from ModuleSpecifier
       
  5242      */
       
  5243     private String fromClause() {
       
  5244         final long fromToken = token;
       
  5245         final String name = (String) expectValue(IDENT);
       
  5246         if (!"from".equals(name)) {
       
  5247             throw error(AbstractParser.message("expected.from"), fromToken);
       
  5248         }
       
  5249         if (type == STRING || type == ESCSTRING) {
       
  5250             final String moduleSpecifier = (String) getValue();
       
  5251             next();
       
  5252             return moduleSpecifier;
       
  5253         } else {
       
  5254             throw error(expectMessage(STRING));
       
  5255         }
       
  5256     }
       
  5257 
       
  5258     /**
       
  5259      * Parse export declaration.
       
  5260      *
       
  5261      * ExportDeclaration :
       
  5262      *     export * FromClause ;
       
  5263      *     export ExportClause FromClause ;
       
  5264      *     export ExportClause ;
       
  5265      *     export VariableStatement
       
  5266      *     export Declaration
       
  5267      *     export default HoistableDeclaration[Default]
       
  5268      *     export default ClassDeclaration[Default]
       
  5269      *     export default [lookahead !in {function, class}] AssignmentExpression[In] ;
       
  5270      */
       
  5271     private void exportDeclaration() {
       
  5272         expect(EXPORT);
       
  5273         final ParserContextModuleNode module = lc.getCurrentModule();
       
  5274         switch (type) {
       
  5275             case MUL: {
       
  5276                 next();
       
  5277                 final String moduleRequest = fromClause();
       
  5278                 expect(SEMICOLON);
       
  5279                 module.addModuleRequest(moduleRequest);
       
  5280                 module.addStarExportEntry(Module.ExportEntry.exportStarFrom(moduleRequest));
       
  5281                 break;
       
  5282             }
       
  5283             case LBRACE: {
       
  5284                 final List<Module.ExportEntry> exportEntries = exportClause();
       
  5285                 if (type == IDENT && "from".equals(getValue())) {
       
  5286                     final String moduleRequest = fromClause();
       
  5287                     module.addModuleRequest(moduleRequest);
       
  5288                     for (Module.ExportEntry exportEntry : exportEntries) {
       
  5289                         module.addIndirectExportEntry(exportEntry.withFrom(moduleRequest));
       
  5290                     }
       
  5291                 } else {
       
  5292                     for (Module.ExportEntry exportEntry : exportEntries) {
       
  5293                         module.addLocalExportEntry(exportEntry);
       
  5294                     }
       
  5295                 }
       
  5296                 expect(SEMICOLON);
       
  5297                 break;
       
  5298             }
       
  5299             case DEFAULT:
       
  5300                 next();
       
  5301                 final Expression assignmentExpression;
       
  5302                 IdentNode ident;
       
  5303                 final int lineNumber = line;
       
  5304                 final long rhsToken = token;
       
  5305                 final boolean declaration;
       
  5306                 switch (type) {
       
  5307                     case FUNCTION:
       
  5308                         assignmentExpression = functionExpression(false, true);
       
  5309                         ident = ((FunctionNode) assignmentExpression).getIdent();
       
  5310                         declaration = true;
       
  5311                         break;
       
  5312                     case CLASS:
       
  5313                         assignmentExpression = classDeclaration(true);
       
  5314                         ident = ((ClassNode) assignmentExpression).getIdent();
       
  5315                         declaration = true;
       
  5316                         break;
       
  5317                     default:
       
  5318                         assignmentExpression = assignmentExpression(false);
       
  5319                         ident = null;
       
  5320                         declaration = false;
       
  5321                         break;
       
  5322                 }
       
  5323                 if (ident != null) {
       
  5324                     module.addLocalExportEntry(Module.ExportEntry.exportDefault(ident.getName()));
       
  5325                 } else {
       
  5326                     ident = createIdentNode(Token.recast(rhsToken, IDENT), finish, Module.DEFAULT_EXPORT_BINDING_NAME);
       
  5327                     lc.appendStatementToCurrentNode(new VarNode(lineNumber, Token.recast(rhsToken, LET), finish, ident, assignmentExpression));
       
  5328                     if (!declaration) {
       
  5329                         expect(SEMICOLON);
       
  5330                     }
       
  5331                     module.addLocalExportEntry(Module.ExportEntry.exportDefault());
       
  5332                 }
       
  5333                 break;
       
  5334             case VAR:
       
  5335             case LET:
       
  5336             case CONST:
       
  5337                 final List<Statement> statements = lc.getCurrentBlock().getStatements();
       
  5338                 final int previousEnd = statements.size();
       
  5339                 variableStatement(type);
       
  5340                 for (final Statement statement : statements.subList(previousEnd, statements.size())) {
       
  5341                     if (statement instanceof VarNode) {
       
  5342                         module.addLocalExportEntry(Module.ExportEntry.exportSpecifier(((VarNode) statement).getName().getName()));
       
  5343                     }
       
  5344                 }
       
  5345                 break;
       
  5346             case CLASS: {
       
  5347                 final ClassNode classDeclaration = classDeclaration(false);
       
  5348                 module.addLocalExportEntry(Module.ExportEntry.exportSpecifier(classDeclaration.getIdent().getName()));
       
  5349                 break;
       
  5350             }
       
  5351             case FUNCTION: {
       
  5352                 final FunctionNode functionDeclaration = (FunctionNode) functionExpression(true, true);
       
  5353                 module.addLocalExportEntry(Module.ExportEntry.exportSpecifier(functionDeclaration.getIdent().getName()));
       
  5354                 break;
       
  5355             }
       
  5356             default:
       
  5357                 throw error(AbstractParser.message("invalid.export"), token);
       
  5358         }
       
  5359     }
       
  5360 
       
  5361     /**
       
  5362      * ExportClause :
       
  5363      *     { }
       
  5364      *     { ExportsList }
       
  5365      *     { ExportsList , }
       
  5366      * ExportsList :
       
  5367      *     ExportSpecifier
       
  5368      *     ExportsList , ExportSpecifier
       
  5369      * ExportSpecifier :
       
  5370      *     IdentifierName
       
  5371      *     IdentifierName as IdentifierName
       
  5372      *
       
  5373      * @return a list of ExportSpecifiers
       
  5374      */
       
  5375     private List<Module.ExportEntry> exportClause() {
       
  5376         assert type == LBRACE;
       
  5377         next();
       
  5378         List<Module.ExportEntry> exports = new ArrayList<>();
       
  5379         while (type != RBRACE) {
       
  5380             final IdentNode localName = getIdentifierName();
       
  5381             if (type == IDENT && "as".equals(getValue())) {
       
  5382                 next();
       
  5383                 final IdentNode exportName = getIdentifierName();
       
  5384                 exports.add(Module.ExportEntry.exportSpecifier(exportName.getName(), localName.getName()));
       
  5385             } else {
       
  5386                 exports.add(Module.ExportEntry.exportSpecifier(localName.getName()));
       
  5387             }
       
  5388             if (type == COMMARIGHT) {
       
  5389                 next();
       
  5390             } else {
       
  5391                 break;
       
  5392             }
       
  5393         }
       
  5394         expect(RBRACE);
       
  5395         return exports;
       
  5396     }
       
  5397 
  3554     @Override
  5398     @Override
  3555     public String toString() {
  5399     public String toString() {
  3556         return "'JavaScript Parsing'";
  5400         return "'JavaScript Parsing'";
  3557     }
  5401     }
  3558 
  5402 
  3562         while (iter.hasNext()) {
  5406         while (iter.hasNext()) {
  3563             final ParserContextFunctionNode fn = iter.next();
  5407             final ParserContextFunctionNode fn = iter.next();
  3564             if (!flaggedCurrentFn) {
  5408             if (!flaggedCurrentFn) {
  3565                 fn.setFlag(FunctionNode.HAS_EVAL);
  5409                 fn.setFlag(FunctionNode.HAS_EVAL);
  3566                 flaggedCurrentFn = true;
  5410                 flaggedCurrentFn = true;
       
  5411                 if (fn.getKind() == FunctionNode.Kind.ARROW) {
       
  5412                     // possible use of this in an eval that's nested in an arrow function, e.g.:
       
  5413                     // function fun(){ return (() => eval("this"))(); };
       
  5414                     markThis(lc);
       
  5415                     markNewTarget(lc);
       
  5416                 }
  3567             } else {
  5417             } else {
  3568                 fn.setFlag(FunctionNode.HAS_NESTED_EVAL);
  5418                 fn.setFlag(FunctionNode.HAS_NESTED_EVAL);
  3569             }
  5419             }
  3570             final ParserContextBlockNode body = lc.getFunctionBody(fn);
  5420             final ParserContextBlockNode body = lc.getFunctionBody(fn);
  3571             // NOTE: it is crucial to mark the body of the outer function as needing scope even when we skip
  5421             // NOTE: it is crucial to mark the body of the outer function as needing scope even when we skip
  3581     }
  5431     }
  3582 
  5432 
  3583     private void appendStatement(final Statement statement) {
  5433     private void appendStatement(final Statement statement) {
  3584         lc.appendStatementToCurrentNode(statement);
  5434         lc.appendStatementToCurrentNode(statement);
  3585     }
  5435     }
       
  5436 
       
  5437     private static void markSuperCall(final ParserContext lc) {
       
  5438         final Iterator<ParserContextFunctionNode> iter = lc.getFunctions();
       
  5439         while (iter.hasNext()) {
       
  5440             final ParserContextFunctionNode fn = iter.next();
       
  5441             if (fn.getKind() != FunctionNode.Kind.ARROW) {
       
  5442                 assert fn.isSubclassConstructor();
       
  5443                 fn.setFlag(FunctionNode.ES6_HAS_DIRECT_SUPER);
       
  5444                 break;
       
  5445             }
       
  5446         }
       
  5447     }
       
  5448 
       
  5449     private ParserContextFunctionNode getCurrentNonArrowFunction() {
       
  5450         final Iterator<ParserContextFunctionNode> iter = lc.getFunctions();
       
  5451         while (iter.hasNext()) {
       
  5452             final ParserContextFunctionNode fn = iter.next();
       
  5453             if (fn.getKind() != FunctionNode.Kind.ARROW) {
       
  5454                 return fn;
       
  5455             }
       
  5456         }
       
  5457         return null;
       
  5458     }
       
  5459 
       
  5460     private static void markThis(final ParserContext lc) {
       
  5461         final Iterator<ParserContextFunctionNode> iter = lc.getFunctions();
       
  5462         while (iter.hasNext()) {
       
  5463             final ParserContextFunctionNode fn = iter.next();
       
  5464             fn.setFlag(FunctionNode.USES_THIS);
       
  5465             if (fn.getKind() != FunctionNode.Kind.ARROW) {
       
  5466                 break;
       
  5467             }
       
  5468         }
       
  5469     }
       
  5470 
       
  5471     private static void markNewTarget(final ParserContext lc) {
       
  5472         final Iterator<ParserContextFunctionNode> iter = lc.getFunctions();
       
  5473         while (iter.hasNext()) {
       
  5474             final ParserContextFunctionNode fn = iter.next();
       
  5475             if (fn.getKind() != FunctionNode.Kind.ARROW) {
       
  5476                 if (!fn.isProgram()) {
       
  5477                     fn.setFlag(FunctionNode.ES6_USES_NEW_TARGET);
       
  5478                 }
       
  5479                 break;
       
  5480             }
       
  5481         }
       
  5482     }
       
  5483 
       
  5484     private boolean inGeneratorFunction() {
       
  5485         return lc.getCurrentFunction().getKind() == FunctionNode.Kind.GENERATOR;
       
  5486     }
  3586 }
  5487 }