src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java

Print this page




  60 import java.util.Collections;
  61 import java.util.Deque;
  62 import java.util.HashMap;
  63 import java.util.HashSet;
  64 import java.util.Iterator;
  65 import java.util.List;
  66 import java.util.Map;
  67 import jdk.internal.dynalink.support.NameCodec;
  68 import jdk.nashorn.internal.codegen.CompilerConstants;
  69 import jdk.nashorn.internal.codegen.Namespace;
  70 import jdk.nashorn.internal.ir.AccessNode;
  71 import jdk.nashorn.internal.ir.BaseNode;
  72 import jdk.nashorn.internal.ir.BinaryNode;
  73 import jdk.nashorn.internal.ir.Block;
  74 import jdk.nashorn.internal.ir.BlockStatement;
  75 import jdk.nashorn.internal.ir.BreakNode;
  76 import jdk.nashorn.internal.ir.CallNode;
  77 import jdk.nashorn.internal.ir.CaseNode;
  78 import jdk.nashorn.internal.ir.CatchNode;
  79 import jdk.nashorn.internal.ir.ContinueNode;

  80 import jdk.nashorn.internal.ir.EmptyNode;

  81 import jdk.nashorn.internal.ir.Expression;
  82 import jdk.nashorn.internal.ir.ExpressionStatement;
  83 import jdk.nashorn.internal.ir.ForNode;
  84 import jdk.nashorn.internal.ir.FunctionNode;
  85 import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
  86 import jdk.nashorn.internal.ir.IdentNode;
  87 import jdk.nashorn.internal.ir.IfNode;
  88 import jdk.nashorn.internal.ir.IndexNode;
  89 import jdk.nashorn.internal.ir.JoinPredecessorExpression;
  90 import jdk.nashorn.internal.ir.LabelNode;
  91 import jdk.nashorn.internal.ir.LiteralNode;
  92 import jdk.nashorn.internal.ir.Node;
  93 import jdk.nashorn.internal.ir.ObjectNode;
  94 import jdk.nashorn.internal.ir.PropertyKey;
  95 import jdk.nashorn.internal.ir.PropertyNode;
  96 import jdk.nashorn.internal.ir.ReturnNode;
  97 import jdk.nashorn.internal.ir.RuntimeNode;
  98 import jdk.nashorn.internal.ir.Statement;
  99 import jdk.nashorn.internal.ir.SwitchNode;
 100 import jdk.nashorn.internal.ir.TernaryNode;


 339             next();
 340 
 341             // Make a fake token for the function.
 342             final long functionToken = Token.toDesc(FUNCTION, 0, source.getLength());
 343             // Set up the function to append elements.
 344 
 345             final IdentNode ident = new IdentNode(functionToken, Token.descPosition(functionToken), PROGRAM.symbolName());
 346             final ParserContextFunctionNode function = createParserContextFunctionNode(ident, functionToken, FunctionNode.Kind.NORMAL, functionLine, Collections.<IdentNode>emptyList());
 347             lc.push(function);
 348 
 349             final ParserContextBlockNode body = newBlock();
 350 
 351             functionDeclarations = new ArrayList<>();
 352             sourceElements(false);
 353             addFunctionDeclarations(function);
 354             functionDeclarations = null;
 355 
 356             restoreBlock(body);
 357             body.setFlag(Block.NEEDS_SCOPE);
 358 
 359             final Block functionBody = new Block(functionToken, source.getLength() - 1, body.getFlags(), body.getStatements());

 360             lc.pop(function);
 361 
 362             expect(EOF);
 363 
 364             final FunctionNode functionNode = createFunctionNode(
 365                     function,
 366                     functionToken,
 367                     ident,
 368                     Collections.<IdentNode>emptyList(),
 369                     FunctionNode.Kind.NORMAL,
 370                     functionLine,
 371                     functionBody);
 372             printAST(functionNode);
 373             return functionNode;
 374         } catch (final Exception e) {
 375             handleParseException(e);
 376             return null;
 377         }
 378     }
 379 


 523     private Block getBlock(final boolean needsBraces) {
 524         final long blockToken = token;
 525         final ParserContextBlockNode newBlock = newBlock();
 526         try {
 527             // Block opening brace.
 528             if (needsBraces) {
 529                 expect(LBRACE);
 530             }
 531             // Accumulate block statements.
 532             statementList();
 533 
 534         } finally {
 535             restoreBlock(newBlock);
 536         }
 537 
 538         // Block closing brace.
 539         if (needsBraces) {
 540             expect(RBRACE);
 541         }
 542 
 543         return new Block(blockToken, finish, newBlock.getFlags(), newBlock.getStatements());

 544     }
 545 
 546 
 547     /**
 548      * Get all the statements generated by a single statement.
 549      * @return Statements.
 550      */
 551     private Block getStatement() {
 552         if (type == LBRACE) {
 553             return getBlock(true);
 554         }
 555         // Set up new block. Captures first token.
 556         final ParserContextBlockNode newBlock = newBlock();
 557         try {
 558             statement(false, false, true);
 559         } finally {
 560             restoreBlock(newBlock);
 561         }
 562         return new Block(newBlock.getToken(), finish, newBlock.getFlags(), newBlock.getStatements());
 563     }
 564 
 565     /**
 566      * Detect calls to special functions.
 567      * @param ident Called function.
 568      */
 569     private void detectSpecialFunction(final IdentNode ident) {
 570         final String name = ident.getName();
 571 
 572         if (EVAL.symbolName().equals(name)) {
 573             markEval(lc);
 574         }
 575     }
 576 
 577     /**
 578      * Detect use of special properties.
 579      * @param ident Referenced property.
 580      */
 581     private void detectSpecialProperty(final IdentNode ident) {
 582         if (isArguments(ident)) {


 695         final long functionToken = Token.toDesc(FUNCTION, Token.descPosition(Token.withDelimiter(token)), source.getLength());
 696         final int  functionLine  = line;
 697 
 698         final IdentNode ident = new IdentNode(functionToken, Token.descPosition(functionToken), scriptName);
 699         final ParserContextFunctionNode script = createParserContextFunctionNode(
 700                 ident,
 701                 functionToken,
 702                 FunctionNode.Kind.SCRIPT,
 703                 functionLine,
 704                 Collections.<IdentNode>emptyList());
 705         lc.push(script);
 706         final ParserContextBlockNode body = newBlock();
 707 
 708         functionDeclarations = new ArrayList<>();
 709         sourceElements(allowPropertyFunction);
 710         addFunctionDeclarations(script);
 711         functionDeclarations = null;
 712 
 713         restoreBlock(body);
 714         body.setFlag(Block.NEEDS_SCOPE);
 715         final Block programBody = new Block(functionToken, functionLine, body.getFlags(), body.getStatements());
 716         lc.pop(script);
 717         script.setLastToken(token);
 718 
 719         expect(EOF);
 720 
 721         return createFunctionNode(script, functionToken, ident, Collections.<IdentNode>emptyList(), FunctionNode.Kind.SCRIPT, functionLine, programBody);
 722     }
 723 
 724     /**
 725      * Directive value or null if statement is not a directive.
 726      *
 727      * @param stmt Statement to be checked
 728      * @return Directive value if the given statement is a directive
 729      */
 730     private String getDirective(final Node stmt) {
 731         if (stmt instanceof ExpressionStatement) {
 732             final Node expr = ((ExpressionStatement)stmt).getExpression();
 733             if (expr instanceof LiteralNode) {
 734                 final LiteralNode<?> lit = (LiteralNode<?>)expr;
 735                 final long litToken = lit.getToken();


 809                                         getValue(statement.getToken());
 810                                     }
 811 
 812                                     // verify that function name as well as parameter names
 813                                     // satisfy strict mode restrictions.
 814                                     verifyStrictIdent(function.getIdent(), "function name");
 815                                     for (final IdentNode param : function.getParameters()) {
 816                                         verifyStrictIdent(param, "function parameter");
 817                                     }
 818                                 }
 819                             } else if (Context.DEBUG) {
 820                                 final int flag = FunctionNode.getDirectiveFlag(directive);
 821                                 if (flag != 0) {
 822                                     final ParserContextFunctionNode function = lc.getCurrentFunction();
 823                                     function.setFlag(flag);
 824                                 }
 825                             }
 826                         }
 827                     }
 828                 } catch (final Exception e) {


 829                     //recover parsing
 830                     recover(e);



 831                 }
 832 
 833                 // No backtracking from here on.
 834                 stream.commit(k);
 835             }
 836         } finally {
 837             isStrictMode = oldStrictMode;
 838         }
 839     }
 840 
 841     /**
 842      * Statement :
 843      *      Block
 844      *      VariableStatement
 845      *      EmptyStatement
 846      *      ExpressionStatement
 847      *      IfStatement
 848      *      IterationStatement
 849      *      ContinueStatement
 850      *      BreakStatement


1836                 // catch clause each with it's own condition.
1837                 final Expression ifExpression;
1838                 if (!env._no_syntax_extensions && type == IF) {
1839                     next();
1840                     // Get the exception condition.
1841                     ifExpression = expression();
1842                 } else {
1843                     ifExpression = null;
1844                 }
1845 
1846                 expect(RPAREN);
1847 
1848                 final ParserContextBlockNode catchBlock = newBlock();
1849                 try {
1850                     // Get CATCH body.
1851                     final Block catchBody = getBlock(true);
1852                     final CatchNode catchNode = new CatchNode(catchLine, catchToken, finish, exception, ifExpression, catchBody, false);
1853                     appendStatement(catchNode);
1854                 } finally {
1855                     restoreBlock(catchBlock);
1856                     catchBlocks.add(new Block(catchBlock.getToken(), finish, catchBlock.getFlags(), catchBlock.getStatements()));
1857                 }
1858 
1859                 // If unconditional catch then should to be the end.
1860                 if (ifExpression == null) {
1861                     break;
1862                 }
1863             }
1864 
1865             // Prepare to capture finally statement.
1866             Block finallyStatements = null;
1867 
1868             if (type == FINALLY) {
1869                 next();
1870                 finallyStatements = getBlock(true);
1871             }
1872 
1873             // Need at least one catch or a finally.
1874             if (catchBlocks.isEmpty() && finallyStatements == null) {
1875                 throw error(AbstractParser.message("missing.catch.or.finally"), tryToken);
1876             }
1877 
1878             final TryNode tryNode = new TryNode(tryLine, tryToken, finish, tryBody, catchBlocks, finallyStatements);
1879             // Add try.
1880             assert lc.peek() == outer;
1881             appendStatement(tryNode);
1882         } finally {
1883             restoreBlock(outer);
1884         }
1885 
1886         appendStatement(new BlockStatement(startLine, new Block(tryToken, finish, outer.getFlags(), outer.getStatements())));
1887     }
1888 
1889     /**
1890      * DebuggerStatement :
1891      *      debugger ;
1892      *
1893      * See 12.15
1894      *
1895      * Parse debugger statement.
1896      */
1897     private void  debuggerStatement() {
1898         // Capture DEBUGGER token.
1899         final int  debuggerLine  = line;
1900         final long debuggerToken = token;
1901         // DEBUGGER tested in caller.
1902         next();
1903         endOfLine();
1904         appendStatement(new ExpressionStatement(debuggerLine, debuggerToken, finish, new RuntimeNode(debuggerToken, finish, RuntimeNode.Request.DEBUGGER, Collections.<Expression>emptyList())));
1905     }
1906 
1907     /**
1908      * PrimaryExpression :
1909      *      this
1910      *      Identifier
1911      *      Literal
1912      *      ArrayLiteral
1913      *      ObjectLiteral
1914      *      ( Expression )
1915      *
1916      *  See 11.1
1917      *
1918      * Parse primary expression.
1919      * @return Expression node.
1920      */
1921     @SuppressWarnings("fallthrough")
1922     private Expression primaryExpression() {
1923         // Capture first token.
1924         final int  primaryLine  = line;


2864 
2865         parameters.trimToSize();
2866         return parameters;
2867     }
2868 
2869     /**
2870      * FunctionBody :
2871      *      SourceElements?
2872      *
2873      * See 13
2874      *
2875      * Parse function body.
2876      * @return function node (body.)
2877      */
2878     private Block functionBody(final ParserContextFunctionNode functionNode) {
2879         long lastToken = 0L;
2880         ParserContextBlockNode body = null;
2881         final long bodyToken = token;
2882         Block functionBody;
2883         int bodyFinish = 0;
2884 
2885 
2886         final boolean parseBody;
2887         Object endParserState = null;
2888         try {
2889             // Create a new function block.
2890             body = newBlock();
2891             assert functionNode != null;
2892             final int functionId = functionNode.getId();
2893             parseBody = reparsedFunction == null || functionId <= reparsedFunction.getFunctionNodeId();
2894             // Nashorn extension: expression closures
2895             if (!env._no_syntax_extensions && type != LBRACE) {
2896                 /*
2897                  * Example:
2898                  *
2899                  * function square(x) x * x;
2900                  * print(square(3));
2901                  */
2902 
2903                 // just expression as function body
2904                 final Expression expr = assignmentExpression(true);




  60 import java.util.Collections;
  61 import java.util.Deque;
  62 import java.util.HashMap;
  63 import java.util.HashSet;
  64 import java.util.Iterator;
  65 import java.util.List;
  66 import java.util.Map;
  67 import jdk.internal.dynalink.support.NameCodec;
  68 import jdk.nashorn.internal.codegen.CompilerConstants;
  69 import jdk.nashorn.internal.codegen.Namespace;
  70 import jdk.nashorn.internal.ir.AccessNode;
  71 import jdk.nashorn.internal.ir.BaseNode;
  72 import jdk.nashorn.internal.ir.BinaryNode;
  73 import jdk.nashorn.internal.ir.Block;
  74 import jdk.nashorn.internal.ir.BlockStatement;
  75 import jdk.nashorn.internal.ir.BreakNode;
  76 import jdk.nashorn.internal.ir.CallNode;
  77 import jdk.nashorn.internal.ir.CaseNode;
  78 import jdk.nashorn.internal.ir.CatchNode;
  79 import jdk.nashorn.internal.ir.ContinueNode;
  80 import jdk.nashorn.internal.ir.DebuggerNode;
  81 import jdk.nashorn.internal.ir.EmptyNode;
  82 import jdk.nashorn.internal.ir.ErrorNode;
  83 import jdk.nashorn.internal.ir.Expression;
  84 import jdk.nashorn.internal.ir.ExpressionStatement;
  85 import jdk.nashorn.internal.ir.ForNode;
  86 import jdk.nashorn.internal.ir.FunctionNode;
  87 import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
  88 import jdk.nashorn.internal.ir.IdentNode;
  89 import jdk.nashorn.internal.ir.IfNode;
  90 import jdk.nashorn.internal.ir.IndexNode;
  91 import jdk.nashorn.internal.ir.JoinPredecessorExpression;
  92 import jdk.nashorn.internal.ir.LabelNode;
  93 import jdk.nashorn.internal.ir.LiteralNode;
  94 import jdk.nashorn.internal.ir.Node;
  95 import jdk.nashorn.internal.ir.ObjectNode;
  96 import jdk.nashorn.internal.ir.PropertyKey;
  97 import jdk.nashorn.internal.ir.PropertyNode;
  98 import jdk.nashorn.internal.ir.ReturnNode;
  99 import jdk.nashorn.internal.ir.RuntimeNode;
 100 import jdk.nashorn.internal.ir.Statement;
 101 import jdk.nashorn.internal.ir.SwitchNode;
 102 import jdk.nashorn.internal.ir.TernaryNode;


 341             next();
 342 
 343             // Make a fake token for the function.
 344             final long functionToken = Token.toDesc(FUNCTION, 0, source.getLength());
 345             // Set up the function to append elements.
 346 
 347             final IdentNode ident = new IdentNode(functionToken, Token.descPosition(functionToken), PROGRAM.symbolName());
 348             final ParserContextFunctionNode function = createParserContextFunctionNode(ident, functionToken, FunctionNode.Kind.NORMAL, functionLine, Collections.<IdentNode>emptyList());
 349             lc.push(function);
 350 
 351             final ParserContextBlockNode body = newBlock();
 352 
 353             functionDeclarations = new ArrayList<>();
 354             sourceElements(false);
 355             addFunctionDeclarations(function);
 356             functionDeclarations = null;
 357 
 358             restoreBlock(body);
 359             body.setFlag(Block.NEEDS_SCOPE);
 360 
 361             final Block functionBody = new Block(functionToken, source.getLength() - 1, 
 362                 body.getFlags() | Block.IS_SYNTHETIC, body.getStatements());
 363             lc.pop(function);
 364 
 365             expect(EOF);
 366 
 367             final FunctionNode functionNode = createFunctionNode(
 368                     function,
 369                     functionToken,
 370                     ident,
 371                     Collections.<IdentNode>emptyList(),
 372                     FunctionNode.Kind.NORMAL,
 373                     functionLine,
 374                     functionBody);
 375             printAST(functionNode);
 376             return functionNode;
 377         } catch (final Exception e) {
 378             handleParseException(e);
 379             return null;
 380         }
 381     }
 382 


 526     private Block getBlock(final boolean needsBraces) {
 527         final long blockToken = token;
 528         final ParserContextBlockNode newBlock = newBlock();
 529         try {
 530             // Block opening brace.
 531             if (needsBraces) {
 532                 expect(LBRACE);
 533             }
 534             // Accumulate block statements.
 535             statementList();
 536 
 537         } finally {
 538             restoreBlock(newBlock);
 539         }
 540 
 541         // Block closing brace.
 542         if (needsBraces) {
 543             expect(RBRACE);
 544         }
 545 
 546         final int flags = newBlock.getFlags() | (needsBraces? 0 : Block.IS_SYNTHETIC);
 547         return new Block(blockToken, finish, flags, newBlock.getStatements());
 548     }
 549 
 550 
 551     /**
 552      * Get all the statements generated by a single statement.
 553      * @return Statements.
 554      */
 555     private Block getStatement() {
 556         if (type == LBRACE) {
 557             return getBlock(true);
 558         }
 559         // Set up new block. Captures first token.
 560         final ParserContextBlockNode newBlock = newBlock();
 561         try {
 562             statement(false, false, true);
 563         } finally {
 564             restoreBlock(newBlock);
 565         }
 566         return new Block(newBlock.getToken(), finish, newBlock.getFlags() | Block.IS_SYNTHETIC, newBlock.getStatements());
 567     }
 568 
 569     /**
 570      * Detect calls to special functions.
 571      * @param ident Called function.
 572      */
 573     private void detectSpecialFunction(final IdentNode ident) {
 574         final String name = ident.getName();
 575 
 576         if (EVAL.symbolName().equals(name)) {
 577             markEval(lc);
 578         }
 579     }
 580 
 581     /**
 582      * Detect use of special properties.
 583      * @param ident Referenced property.
 584      */
 585     private void detectSpecialProperty(final IdentNode ident) {
 586         if (isArguments(ident)) {


 699         final long functionToken = Token.toDesc(FUNCTION, Token.descPosition(Token.withDelimiter(token)), source.getLength());
 700         final int  functionLine  = line;
 701 
 702         final IdentNode ident = new IdentNode(functionToken, Token.descPosition(functionToken), scriptName);
 703         final ParserContextFunctionNode script = createParserContextFunctionNode(
 704                 ident,
 705                 functionToken,
 706                 FunctionNode.Kind.SCRIPT,
 707                 functionLine,
 708                 Collections.<IdentNode>emptyList());
 709         lc.push(script);
 710         final ParserContextBlockNode body = newBlock();
 711 
 712         functionDeclarations = new ArrayList<>();
 713         sourceElements(allowPropertyFunction);
 714         addFunctionDeclarations(script);
 715         functionDeclarations = null;
 716 
 717         restoreBlock(body);
 718         body.setFlag(Block.NEEDS_SCOPE);
 719         final Block programBody = new Block(functionToken, functionLine, body.getFlags() | Block.IS_SYNTHETIC, body.getStatements());
 720         lc.pop(script);
 721         script.setLastToken(token);
 722 
 723         expect(EOF);
 724 
 725         return createFunctionNode(script, functionToken, ident, Collections.<IdentNode>emptyList(), FunctionNode.Kind.SCRIPT, functionLine, programBody);
 726     }
 727 
 728     /**
 729      * Directive value or null if statement is not a directive.
 730      *
 731      * @param stmt Statement to be checked
 732      * @return Directive value if the given statement is a directive
 733      */
 734     private String getDirective(final Node stmt) {
 735         if (stmt instanceof ExpressionStatement) {
 736             final Node expr = ((ExpressionStatement)stmt).getExpression();
 737             if (expr instanceof LiteralNode) {
 738                 final LiteralNode<?> lit = (LiteralNode<?>)expr;
 739                 final long litToken = lit.getToken();


 813                                         getValue(statement.getToken());
 814                                     }
 815 
 816                                     // verify that function name as well as parameter names
 817                                     // satisfy strict mode restrictions.
 818                                     verifyStrictIdent(function.getIdent(), "function name");
 819                                     for (final IdentNode param : function.getParameters()) {
 820                                         verifyStrictIdent(param, "function parameter");
 821                                     }
 822                                 }
 823                             } else if (Context.DEBUG) {
 824                                 final int flag = FunctionNode.getDirectiveFlag(directive);
 825                                 if (flag != 0) {
 826                                     final ParserContextFunctionNode function = lc.getCurrentFunction();
 827                                     function.setFlag(flag);
 828                                 }
 829                             }
 830                         }
 831                     }
 832                 } catch (final Exception e) {
 833                     final int errorLine = line;
 834                     final long errorToken = token;
 835                     //recover parsing
 836                     recover(e);
 837                     final ErrorNode errorExpr = new ErrorNode(errorToken, finish);
 838                     final ExpressionStatement expressionStatement = new ExpressionStatement(errorLine, errorToken, finish, errorExpr);
 839                     appendStatement(expressionStatement);
 840                 }
 841 
 842                 // No backtracking from here on.
 843                 stream.commit(k);
 844             }
 845         } finally {
 846             isStrictMode = oldStrictMode;
 847         }
 848     }
 849 
 850     /**
 851      * Statement :
 852      *      Block
 853      *      VariableStatement
 854      *      EmptyStatement
 855      *      ExpressionStatement
 856      *      IfStatement
 857      *      IterationStatement
 858      *      ContinueStatement
 859      *      BreakStatement


1845                 // catch clause each with it's own condition.
1846                 final Expression ifExpression;
1847                 if (!env._no_syntax_extensions && type == IF) {
1848                     next();
1849                     // Get the exception condition.
1850                     ifExpression = expression();
1851                 } else {
1852                     ifExpression = null;
1853                 }
1854 
1855                 expect(RPAREN);
1856 
1857                 final ParserContextBlockNode catchBlock = newBlock();
1858                 try {
1859                     // Get CATCH body.
1860                     final Block catchBody = getBlock(true);
1861                     final CatchNode catchNode = new CatchNode(catchLine, catchToken, finish, exception, ifExpression, catchBody, false);
1862                     appendStatement(catchNode);
1863                 } finally {
1864                     restoreBlock(catchBlock);
1865                     catchBlocks.add(new Block(catchBlock.getToken(), finish, catchBlock.getFlags() | Block.IS_SYNTHETIC, catchBlock.getStatements()));
1866                 }
1867 
1868                 // If unconditional catch then should to be the end.
1869                 if (ifExpression == null) {
1870                     break;
1871                 }
1872             }
1873 
1874             // Prepare to capture finally statement.
1875             Block finallyStatements = null;
1876 
1877             if (type == FINALLY) {
1878                 next();
1879                 finallyStatements = getBlock(true);
1880             }
1881 
1882             // Need at least one catch or a finally.
1883             if (catchBlocks.isEmpty() && finallyStatements == null) {
1884                 throw error(AbstractParser.message("missing.catch.or.finally"), tryToken);
1885             }
1886 
1887             final TryNode tryNode = new TryNode(tryLine, tryToken, finish, tryBody, catchBlocks, finallyStatements);
1888             // Add try.
1889             assert lc.peek() == outer;
1890             appendStatement(tryNode);
1891         } finally {
1892             restoreBlock(outer);
1893         }
1894 
1895         appendStatement(new BlockStatement(startLine, new Block(tryToken, finish, outer.getFlags() | Block.IS_SYNTHETIC, outer.getStatements())));
1896     }
1897 
1898     /**
1899      * DebuggerStatement :
1900      *      debugger ;
1901      *
1902      * See 12.15
1903      *
1904      * Parse debugger statement.
1905      */
1906     private void  debuggerStatement() {
1907         // Capture DEBUGGER token.
1908         final int  debuggerLine  = line;
1909         final long debuggerToken = token;
1910         // DEBUGGER tested in caller.
1911         next();
1912         endOfLine();
1913         appendStatement(new DebuggerNode(debuggerLine, debuggerToken, finish));
1914     }
1915 
1916     /**
1917      * PrimaryExpression :
1918      *      this
1919      *      Identifier
1920      *      Literal
1921      *      ArrayLiteral
1922      *      ObjectLiteral
1923      *      ( Expression )
1924      *
1925      *  See 11.1
1926      *
1927      * Parse primary expression.
1928      * @return Expression node.
1929      */
1930     @SuppressWarnings("fallthrough")
1931     private Expression primaryExpression() {
1932         // Capture first token.
1933         final int  primaryLine  = line;


2873 
2874         parameters.trimToSize();
2875         return parameters;
2876     }
2877 
2878     /**
2879      * FunctionBody :
2880      *      SourceElements?
2881      *
2882      * See 13
2883      *
2884      * Parse function body.
2885      * @return function node (body.)
2886      */
2887     private Block functionBody(final ParserContextFunctionNode functionNode) {
2888         long lastToken = 0L;
2889         ParserContextBlockNode body = null;
2890         final long bodyToken = token;
2891         Block functionBody;
2892         int bodyFinish = 0;

2893 
2894         final boolean parseBody;
2895         Object endParserState = null;
2896         try {
2897             // Create a new function block.
2898             body = newBlock();
2899             assert functionNode != null;
2900             final int functionId = functionNode.getId();
2901             parseBody = reparsedFunction == null || functionId <= reparsedFunction.getFunctionNodeId();
2902             // Nashorn extension: expression closures
2903             if (!env._no_syntax_extensions && type != LBRACE) {
2904                 /*
2905                  * Example:
2906                  *
2907                  * function square(x) x * x;
2908                  * print(square(3));
2909                  */
2910 
2911                 // just expression as function body
2912                 final Expression expr = assignmentExpression(true);