nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java
changeset 33414 2e284c36d51f
parent 32692 8f60bd284bf4
child 33533 43400f0f2b47
equal deleted inserted replaced
33373:4a0312f2894b 33414:2e284c36d51f
     1 /*
     1 /*
     2  * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    49 import static jdk.nashorn.internal.parser.TokenType.LPAREN;
    49 import static jdk.nashorn.internal.parser.TokenType.LPAREN;
    50 import static jdk.nashorn.internal.parser.TokenType.RBRACE;
    50 import static jdk.nashorn.internal.parser.TokenType.RBRACE;
    51 import static jdk.nashorn.internal.parser.TokenType.RBRACKET;
    51 import static jdk.nashorn.internal.parser.TokenType.RBRACKET;
    52 import static jdk.nashorn.internal.parser.TokenType.RPAREN;
    52 import static jdk.nashorn.internal.parser.TokenType.RPAREN;
    53 import static jdk.nashorn.internal.parser.TokenType.SEMICOLON;
    53 import static jdk.nashorn.internal.parser.TokenType.SEMICOLON;
       
    54 import static jdk.nashorn.internal.parser.TokenType.TEMPLATE;
       
    55 import static jdk.nashorn.internal.parser.TokenType.TEMPLATE_HEAD;
       
    56 import static jdk.nashorn.internal.parser.TokenType.TEMPLATE_MIDDLE;
       
    57 import static jdk.nashorn.internal.parser.TokenType.TEMPLATE_TAIL;
    54 import static jdk.nashorn.internal.parser.TokenType.TERNARY;
    58 import static jdk.nashorn.internal.parser.TokenType.TERNARY;
    55 import static jdk.nashorn.internal.parser.TokenType.WHILE;
    59 import static jdk.nashorn.internal.parser.TokenType.WHILE;
    56 
    60 
    57 import java.io.Serializable;
    61 import java.io.Serializable;
    58 import java.util.ArrayDeque;
    62 import java.util.ArrayDeque;
    62 import java.util.HashMap;
    66 import java.util.HashMap;
    63 import java.util.HashSet;
    67 import java.util.HashSet;
    64 import java.util.Iterator;
    68 import java.util.Iterator;
    65 import java.util.List;
    69 import java.util.List;
    66 import java.util.Map;
    70 import java.util.Map;
       
    71 
    67 import jdk.internal.dynalink.support.NameCodec;
    72 import jdk.internal.dynalink.support.NameCodec;
    68 import jdk.nashorn.internal.codegen.CompilerConstants;
    73 import jdk.nashorn.internal.codegen.CompilerConstants;
    69 import jdk.nashorn.internal.codegen.Namespace;
    74 import jdk.nashorn.internal.codegen.Namespace;
    70 import jdk.nashorn.internal.ir.AccessNode;
    75 import jdk.nashorn.internal.ir.AccessNode;
    71 import jdk.nashorn.internal.ir.BaseNode;
    76 import jdk.nashorn.internal.ir.BaseNode;
  1924      *      this
  1929      *      this
  1925      *      Identifier
  1930      *      Identifier
  1926      *      Literal
  1931      *      Literal
  1927      *      ArrayLiteral
  1932      *      ArrayLiteral
  1928      *      ObjectLiteral
  1933      *      ObjectLiteral
       
  1934      *      RegularExpressionLiteral
       
  1935      *      TemplateLiteral
  1929      *      ( Expression )
  1936      *      ( Expression )
  1930      *
       
  1931      *  See 11.1
       
  1932      *
  1937      *
  1933      * Parse primary expression.
  1938      * Parse primary expression.
  1934      * @return Expression node.
  1939      * @return Expression node.
  1935      */
  1940      */
  1936     @SuppressWarnings("fallthrough")
  1941     @SuppressWarnings("fallthrough")
  1987             final Expression expression = expression();
  1992             final Expression expression = expression();
  1988 
  1993 
  1989             expect(RPAREN);
  1994             expect(RPAREN);
  1990 
  1995 
  1991             return expression;
  1996             return expression;
       
  1997         case TEMPLATE:
       
  1998         case TEMPLATE_HEAD:
       
  1999             return templateLiteral();
  1992 
  2000 
  1993         default:
  2001         default:
  1994             // In this context some operator tokens mark the start of a literal.
  2002             // In this context some operator tokens mark the start of a literal.
  1995             if (lexer.scanLiteral(primaryToken, type, lineInfoReceiver)) {
  2003             if (lexer.scanLiteral(primaryToken, type, lineInfoReceiver)) {
  1996                 next();
  2004                 next();
  2385             this.functionNode = function;
  2393             this.functionNode = function;
  2386         }
  2394         }
  2387     }
  2395     }
  2388 
  2396 
  2389     /**
  2397     /**
       
  2398      * Parse left hand side expression.
       
  2399      *
  2390      * LeftHandSideExpression :
  2400      * LeftHandSideExpression :
  2391      *      NewExpression
  2401      *      NewExpression
  2392      *      CallExpression
  2402      *      CallExpression
  2393      *
  2403      *
  2394      * CallExpression :
  2404      * CallExpression :
  2395      *      MemberExpression Arguments
  2405      *      MemberExpression Arguments
  2396      *      CallExpression Arguments
  2406      *      CallExpression Arguments
  2397      *      CallExpression [ Expression ]
  2407      *      CallExpression [ Expression ]
  2398      *      CallExpression . IdentifierName
  2408      *      CallExpression . IdentifierName
  2399      *
  2409      *      CallExpression TemplateLiteral
  2400      * See 11.2
  2410      *
  2401      *
       
  2402      * Parse left hand side expression.
       
  2403      * @return Expression node.
  2411      * @return Expression node.
  2404      */
  2412      */
  2405     private Expression leftHandSideExpression() {
  2413     private Expression leftHandSideExpression() {
  2406         int  callLine  = line;
  2414         int  callLine  = line;
  2407         long callToken = token;
  2415         long callToken = token;
  2424             // Capture token.
  2432             // Capture token.
  2425             callLine  = line;
  2433             callLine  = line;
  2426             callToken = token;
  2434             callToken = token;
  2427 
  2435 
  2428             switch (type) {
  2436             switch (type) {
  2429             case LPAREN:
  2437             case LPAREN: {
  2430                 // Get NEW or FUNCTION arguments.
  2438                 // Get NEW or FUNCTION arguments.
  2431                 final List<Expression> arguments = optimizeList(argumentList());
  2439                 final List<Expression> arguments = optimizeList(argumentList());
  2432 
  2440 
  2433                 // Create call node.
  2441                 // Create call node.
  2434                 lhs = new CallNode(callLine, callToken, finish, lhs, arguments, false);
  2442                 lhs = new CallNode(callLine, callToken, finish, lhs, arguments, false);
  2435 
  2443 
  2436                 break;
  2444                 break;
  2437 
  2445             }
  2438             case LBRACKET:
  2446             case LBRACKET: {
  2439                 next();
  2447                 next();
  2440 
  2448 
  2441                 // Get array index.
  2449                 // Get array index.
  2442                 final Expression rhs = expression();
  2450                 final Expression rhs = expression();
  2443 
  2451 
  2445 
  2453 
  2446                 // Create indexing node.
  2454                 // Create indexing node.
  2447                 lhs = new IndexNode(callToken, finish, lhs, rhs);
  2455                 lhs = new IndexNode(callToken, finish, lhs, rhs);
  2448 
  2456 
  2449                 break;
  2457                 break;
  2450 
  2458             }
  2451             case PERIOD:
  2459             case PERIOD: {
  2452                 next();
  2460                 next();
  2453 
  2461 
  2454                 final IdentNode property = getIdentifierName();
  2462                 final IdentNode property = getIdentifierName();
  2455 
  2463 
  2456                 // Create property access node.
  2464                 // Create property access node.
  2457                 lhs = new AccessNode(callToken, finish, lhs, property.getName());
  2465                 lhs = new AccessNode(callToken, finish, lhs, property.getName());
  2458 
  2466 
  2459                 break;
  2467                 break;
  2460 
  2468             }
       
  2469             case TEMPLATE:
       
  2470             case TEMPLATE_HEAD: {
       
  2471                 // tagged template literal
       
  2472                 final List<Expression> arguments = templateLiteralArgumentList();
       
  2473 
       
  2474                 lhs = new CallNode(callLine, callToken, finish, lhs, arguments, false);
       
  2475 
       
  2476                 break;
       
  2477             }
  2461             default:
  2478             default:
  2462                 break loop;
  2479                 break loop;
  2463             }
  2480             }
  2464         }
  2481         }
  2465 
  2482 
  2514 
  2531 
  2515         return new UnaryNode(newToken, callNode);
  2532         return new UnaryNode(newToken, callNode);
  2516     }
  2533     }
  2517 
  2534 
  2518     /**
  2535     /**
       
  2536      * Parse member expression.
       
  2537      *
  2519      * MemberExpression :
  2538      * MemberExpression :
  2520      *      PrimaryExpression
  2539      *      PrimaryExpression
  2521      *      FunctionExpression
  2540      *      FunctionExpression
  2522      *      MemberExpression [ Expression ]
  2541      *      MemberExpression [ Expression ]
  2523      *      MemberExpression . IdentifierName
  2542      *      MemberExpression . IdentifierName
       
  2543      *      MemberExpression TemplateLiteral
  2524      *      new MemberExpression Arguments
  2544      *      new MemberExpression Arguments
  2525      *
  2545      *
  2526      * See 11.2
       
  2527      *
       
  2528      * Parse member expression.
       
  2529      * @return Expression node.
  2546      * @return Expression node.
  2530      */
  2547      */
  2531     private Expression memberExpression() {
  2548     private Expression memberExpression() {
  2532         // Prepare to build operation.
  2549         // Prepare to build operation.
  2533         Expression lhs;
  2550         Expression lhs;
  2577 
  2594 
  2578                 final IdentNode property = getIdentifierName();
  2595                 final IdentNode property = getIdentifierName();
  2579 
  2596 
  2580                 // Create property access node.
  2597                 // Create property access node.
  2581                 lhs = new AccessNode(callToken, finish, lhs, property.getName());
  2598                 lhs = new AccessNode(callToken, finish, lhs, property.getName());
       
  2599 
       
  2600                 break;
       
  2601             }
       
  2602             case TEMPLATE:
       
  2603             case TEMPLATE_HEAD: {
       
  2604                 // tagged template literal
       
  2605                 final int callLine = line;
       
  2606                 final List<Expression> arguments = templateLiteralArgumentList();
       
  2607 
       
  2608                 lhs = new CallNode(callLine, callToken, finish, lhs, arguments, false);
  2582 
  2609 
  2583                 break;
  2610                 break;
  2584             }
  2611             }
  2585             default:
  2612             default:
  2586                 break loop;
  2613                 break loop;
  3033             return false;
  3060             return false;
  3034         }
  3061         }
  3035         final ParserState parserState = (ParserState)data.getEndParserState();
  3062         final ParserState parserState = (ParserState)data.getEndParserState();
  3036         assert parserState != null;
  3063         assert parserState != null;
  3037 
  3064 
       
  3065         if (k < stream.last() && start < parserState.position && parserState.position <= Token.descPosition(stream.get(stream.last()))) {
       
  3066             // RBRACE is already in the token stream, so fast forward to it
       
  3067             for (; k < stream.last(); k++) {
       
  3068                 long nextToken = stream.get(k + 1);
       
  3069                 if (Token.descPosition(nextToken) == parserState.position && Token.descType(nextToken) == RBRACE) {
       
  3070                     token = stream.get(k);
       
  3071                     type = Token.descType(token);
       
  3072                     next();
       
  3073                     assert type == RBRACE && start == parserState.position;
       
  3074                     return true;
       
  3075                 }
       
  3076             }
       
  3077         }
       
  3078 
  3038         stream.reset();
  3079         stream.reset();
  3039         lexer = parserState.createLexer(source, lexer, stream, scripting && !env._no_syntax_extensions, env._es6);
  3080         lexer = parserState.createLexer(source, lexer, stream, scripting && !env._no_syntax_extensions, env._es6);
  3040         line = parserState.line;
  3081         line = parserState.line;
  3041         linePosition = parserState.linePosition;
  3082         linePosition = parserState.linePosition;
  3042         // Doesn't really matter, but it's safe to treat it as if there were a semicolon before
  3083         // Doesn't really matter, but it's safe to treat it as if there were a semicolon before
  3423             }
  3464             }
  3424             break;
  3465             break;
  3425         }
  3466         }
  3426     }
  3467     }
  3427 
  3468 
       
  3469     /**
       
  3470      * Parse untagged template literal as string concatenation.
       
  3471      */
       
  3472     private Expression templateLiteral() {
       
  3473         assert type == TEMPLATE || type == TEMPLATE_HEAD;
       
  3474         final boolean noSubstitutionTemplate = type == TEMPLATE;
       
  3475         long lastLiteralToken = token;
       
  3476         LiteralNode<?> literal = getLiteral();
       
  3477         if (noSubstitutionTemplate) {
       
  3478             return literal;
       
  3479         }
       
  3480 
       
  3481         Expression concat = literal;
       
  3482         TokenType lastLiteralType;
       
  3483         do {
       
  3484             Expression expression = expression();
       
  3485             if (type != TEMPLATE_MIDDLE && type != TEMPLATE_TAIL) {
       
  3486                 throw error(AbstractParser.message("unterminated.template.expression"), token);
       
  3487             }
       
  3488             concat = new BinaryNode(Token.recast(lastLiteralToken, TokenType.ADD), concat, expression);
       
  3489             lastLiteralType = type;
       
  3490             lastLiteralToken = token;
       
  3491             literal = getLiteral();
       
  3492             concat = new BinaryNode(Token.recast(lastLiteralToken, TokenType.ADD), concat, literal);
       
  3493         } while (lastLiteralType == TEMPLATE_MIDDLE);
       
  3494         return concat;
       
  3495     }
       
  3496 
       
  3497     /**
       
  3498      * Parse tagged template literal as argument list.
       
  3499      * @return argument list for a tag function call (template object, ...substitutions)
       
  3500      */
       
  3501     private List<Expression> templateLiteralArgumentList() {
       
  3502         assert type == TEMPLATE || type == TEMPLATE_HEAD;
       
  3503         final ArrayList<Expression> argumentList = new ArrayList<>();
       
  3504         final ArrayList<Expression> rawStrings = new ArrayList<>();
       
  3505         final ArrayList<Expression> cookedStrings = new ArrayList<>();
       
  3506         argumentList.add(null); // filled at the end
       
  3507 
       
  3508         final long templateToken = token;
       
  3509         final boolean hasSubstitutions = type == TEMPLATE_HEAD;
       
  3510         addTemplateLiteralString(rawStrings, cookedStrings);
       
  3511 
       
  3512         if (hasSubstitutions) {
       
  3513             TokenType lastLiteralType;
       
  3514             do {
       
  3515                 Expression expression = expression();
       
  3516                 if (type != TEMPLATE_MIDDLE && type != TEMPLATE_TAIL) {
       
  3517                     throw error(AbstractParser.message("unterminated.template.expression"), token);
       
  3518                 }
       
  3519                 argumentList.add(expression);
       
  3520 
       
  3521                 lastLiteralType = type;
       
  3522                 addTemplateLiteralString(rawStrings, cookedStrings);
       
  3523             } while (lastLiteralType == TEMPLATE_MIDDLE);
       
  3524         }
       
  3525 
       
  3526         final LiteralNode<Expression[]> rawStringArray = LiteralNode.newInstance(templateToken, finish, rawStrings);
       
  3527         final LiteralNode<Expression[]> cookedStringArray = LiteralNode.newInstance(templateToken, finish, cookedStrings);
       
  3528         final RuntimeNode templateObject = new RuntimeNode(templateToken, finish, RuntimeNode.Request.GET_TEMPLATE_OBJECT, rawStringArray, cookedStringArray);
       
  3529         argumentList.set(0, templateObject);
       
  3530         return optimizeList(argumentList);
       
  3531     }
       
  3532 
       
  3533     private void addTemplateLiteralString(final ArrayList<Expression> rawStrings, final ArrayList<Expression> cookedStrings) {
       
  3534         final long stringToken = token;
       
  3535         final String rawString = lexer.valueOfRawString(stringToken);
       
  3536         final String cookedString = (String) getValue();
       
  3537         next();
       
  3538         rawStrings.add(LiteralNode.newInstance(stringToken, finish, rawString));
       
  3539         cookedStrings.add(LiteralNode.newInstance(stringToken, finish, cookedString));
       
  3540     }
       
  3541 
  3428     @Override
  3542     @Override
  3429     public String toString() {
  3543     public String toString() {
  3430         return "'JavaScript Parsing'";
  3544         return "'JavaScript Parsing'";
  3431     }
  3545     }
  3432 
  3546