src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java
author attila
Thu, 14 Dec 2017 13:42:59 +0100
changeset 48334 fdefa410d655
parent 47337 079a87f87518
permissions -rw-r--r--
8193296: Parser should not eagerly transform delete expressions Reviewed-by: hannesw, sundar
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     1
/*
47038
f57fa7f112a0 8177691: Labeled break in catch and finally works wrongly, when invoked through nashorn
sdama
parents: 46169
diff changeset
     2
 * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     4
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    10
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    15
 * accompanied this code).
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    16
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    20
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    23
 * questions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    24
 */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    25
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    26
package jdk.nashorn.internal.parser;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    27
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
    28
import static jdk.nashorn.internal.codegen.CompilerConstants.ANON_FUNCTION_PREFIX;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    29
import static jdk.nashorn.internal.codegen.CompilerConstants.EVAL;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
    30
import static jdk.nashorn.internal.codegen.CompilerConstants.PROGRAM;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
    31
import static jdk.nashorn.internal.parser.TokenType.ARROW;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    32
import static jdk.nashorn.internal.parser.TokenType.ASSIGN;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    33
import static jdk.nashorn.internal.parser.TokenType.CASE;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    34
import static jdk.nashorn.internal.parser.TokenType.CATCH;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
    35
import static jdk.nashorn.internal.parser.TokenType.CLASS;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    36
import static jdk.nashorn.internal.parser.TokenType.COLON;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    37
import static jdk.nashorn.internal.parser.TokenType.COMMARIGHT;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
    38
import static jdk.nashorn.internal.parser.TokenType.COMMENT;
24279
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
    39
import static jdk.nashorn.internal.parser.TokenType.CONST;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    40
import static jdk.nashorn.internal.parser.TokenType.DECPOSTFIX;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    41
import static jdk.nashorn.internal.parser.TokenType.DECPREFIX;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
    42
import static jdk.nashorn.internal.parser.TokenType.ELLIPSIS;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    43
import static jdk.nashorn.internal.parser.TokenType.ELSE;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    44
import static jdk.nashorn.internal.parser.TokenType.EOF;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    45
import static jdk.nashorn.internal.parser.TokenType.EOL;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
    46
import static jdk.nashorn.internal.parser.TokenType.EQ_STRICT;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
    47
import static jdk.nashorn.internal.parser.TokenType.ESCSTRING;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
    48
import static jdk.nashorn.internal.parser.TokenType.EXPORT;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
    49
import static jdk.nashorn.internal.parser.TokenType.EXTENDS;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    50
import static jdk.nashorn.internal.parser.TokenType.FINALLY;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    51
import static jdk.nashorn.internal.parser.TokenType.FUNCTION;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    52
import static jdk.nashorn.internal.parser.TokenType.IDENT;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    53
import static jdk.nashorn.internal.parser.TokenType.IF;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
    54
import static jdk.nashorn.internal.parser.TokenType.IMPORT;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    55
import static jdk.nashorn.internal.parser.TokenType.INCPOSTFIX;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    56
import static jdk.nashorn.internal.parser.TokenType.LBRACE;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
    57
import static jdk.nashorn.internal.parser.TokenType.LBRACKET;
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
    58
import static jdk.nashorn.internal.parser.TokenType.LET;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    59
import static jdk.nashorn.internal.parser.TokenType.LPAREN;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
    60
import static jdk.nashorn.internal.parser.TokenType.MUL;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
    61
import static jdk.nashorn.internal.parser.TokenType.PERIOD;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    62
import static jdk.nashorn.internal.parser.TokenType.RBRACE;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    63
import static jdk.nashorn.internal.parser.TokenType.RBRACKET;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    64
import static jdk.nashorn.internal.parser.TokenType.RPAREN;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    65
import static jdk.nashorn.internal.parser.TokenType.SEMICOLON;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
    66
import static jdk.nashorn.internal.parser.TokenType.SPREAD_ARRAY;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
    67
import static jdk.nashorn.internal.parser.TokenType.STATIC;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
    68
import static jdk.nashorn.internal.parser.TokenType.STRING;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
    69
import static jdk.nashorn.internal.parser.TokenType.SUPER;
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
    70
import static jdk.nashorn.internal.parser.TokenType.TEMPLATE;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
    71
import static jdk.nashorn.internal.parser.TokenType.TEMPLATE_HEAD;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
    72
import static jdk.nashorn.internal.parser.TokenType.TEMPLATE_MIDDLE;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
    73
import static jdk.nashorn.internal.parser.TokenType.TEMPLATE_TAIL;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    74
import static jdk.nashorn.internal.parser.TokenType.TERNARY;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
    75
import static jdk.nashorn.internal.parser.TokenType.VAR;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
    76
import static jdk.nashorn.internal.parser.TokenType.VOID;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    77
import static jdk.nashorn.internal.parser.TokenType.WHILE;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
    78
import static jdk.nashorn.internal.parser.TokenType.YIELD;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
    79
import static jdk.nashorn.internal.parser.TokenType.YIELD_STAR;
27974
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
    80
26646
332e9901f0ed 8058304: Non-serializable fields in serializable classes
hannesw
parents: 26505
diff changeset
    81
import java.io.Serializable;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
    82
import java.util.ArrayDeque;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    83
import java.util.ArrayList;
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
    84
import java.util.Collections;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
    85
import java.util.Deque;
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
    86
import java.util.HashMap;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    87
import java.util.HashSet;
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
    88
import java.util.Iterator;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    89
import java.util.List;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    90
import java.util.Map;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
    91
import java.util.Objects;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
    92
import java.util.function.Consumer;
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
    93
import jdk.nashorn.internal.codegen.CompilerConstants;
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
    94
import jdk.nashorn.internal.codegen.Namespace;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    95
import jdk.nashorn.internal.ir.AccessNode;
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
    96
import jdk.nashorn.internal.ir.BaseNode;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    97
import jdk.nashorn.internal.ir.BinaryNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    98
import jdk.nashorn.internal.ir.Block;
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
    99
import jdk.nashorn.internal.ir.BlockStatement;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   100
import jdk.nashorn.internal.ir.BreakNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   101
import jdk.nashorn.internal.ir.CallNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   102
import jdk.nashorn.internal.ir.CaseNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   103
import jdk.nashorn.internal.ir.CatchNode;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   104
import jdk.nashorn.internal.ir.ClassNode;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   105
import jdk.nashorn.internal.ir.ContinueNode;
29407
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
   106
import jdk.nashorn.internal.ir.DebuggerNode;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   107
import jdk.nashorn.internal.ir.EmptyNode;
29407
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
   108
import jdk.nashorn.internal.ir.ErrorNode;
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
   109
import jdk.nashorn.internal.ir.Expression;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   110
import jdk.nashorn.internal.ir.ExpressionList;
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
   111
import jdk.nashorn.internal.ir.ExpressionStatement;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   112
import jdk.nashorn.internal.ir.ForNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   113
import jdk.nashorn.internal.ir.FunctionNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   114
import jdk.nashorn.internal.ir.IdentNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   115
import jdk.nashorn.internal.ir.IfNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   116
import jdk.nashorn.internal.ir.IndexNode;
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   117
import jdk.nashorn.internal.ir.JoinPredecessorExpression;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   118
import jdk.nashorn.internal.ir.LabelNode;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   119
import jdk.nashorn.internal.ir.LexicalContext;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   120
import jdk.nashorn.internal.ir.LiteralNode;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   121
import jdk.nashorn.internal.ir.Module;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   122
import jdk.nashorn.internal.ir.Node;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   123
import jdk.nashorn.internal.ir.ObjectNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   124
import jdk.nashorn.internal.ir.PropertyKey;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   125
import jdk.nashorn.internal.ir.PropertyNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   126
import jdk.nashorn.internal.ir.ReturnNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   127
import jdk.nashorn.internal.ir.RuntimeNode;
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   128
import jdk.nashorn.internal.ir.Statement;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   129
import jdk.nashorn.internal.ir.SwitchNode;
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
   130
import jdk.nashorn.internal.ir.TemplateLiteral;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   131
import jdk.nashorn.internal.ir.TernaryNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   132
import jdk.nashorn.internal.ir.ThrowNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   133
import jdk.nashorn.internal.ir.TryNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   134
import jdk.nashorn.internal.ir.UnaryNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   135
import jdk.nashorn.internal.ir.VarNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   136
import jdk.nashorn.internal.ir.WhileNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   137
import jdk.nashorn.internal.ir.WithNode;
26065
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
   138
import jdk.nashorn.internal.ir.debug.ASTWriter;
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
   139
import jdk.nashorn.internal.ir.debug.PrintVisitor;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   140
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   141
import jdk.nashorn.internal.runtime.Context;
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   142
import jdk.nashorn.internal.runtime.ErrorManager;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   143
import jdk.nashorn.internal.runtime.JSErrorType;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   144
import jdk.nashorn.internal.runtime.ParserException;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   145
import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
   146
import jdk.nashorn.internal.runtime.ScriptEnvironment;
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
   147
import jdk.nashorn.internal.runtime.ScriptFunctionData;
16245
6a1c6c8bc113 8008371: Fix Dynalink compiler warnings and whitespace
attila
parents: 16239
diff changeset
   148
import jdk.nashorn.internal.runtime.ScriptingFunctions;
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   149
import jdk.nashorn.internal.runtime.Source;
26246
66c7c54fe70c 8055923: collect timings using System.nanoTime
attila
parents: 26243
diff changeset
   150
import jdk.nashorn.internal.runtime.Timing;
33533
43400f0f2b47 8141144: Move NameCodec to jdk.nashorn.internal space
attila
parents: 33414
diff changeset
   151
import jdk.nashorn.internal.runtime.linker.NameCodec;
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   152
import jdk.nashorn.internal.runtime.logging.DebugLogger;
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   153
import jdk.nashorn.internal.runtime.logging.Loggable;
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   154
import jdk.nashorn.internal.runtime.logging.Logger;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   155
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   156
/**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   157
 * Builds the IR.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   158
 */
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   159
@Logger(name="parser")
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   160
public class Parser extends AbstractParser implements Loggable {
19898
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   161
    private static final String ARGUMENTS_NAME = CompilerConstants.ARGUMENTS_VAR.symbolName();
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
   162
    private static final String CONSTRUCTOR_NAME = "constructor";
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
   163
    private static final String GET_NAME = "get";
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
   164
    private static final String SET_NAME = "set";
19898
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   165
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   166
    /** Current env. */
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
   167
    private final ScriptEnvironment env;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   168
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
   169
    /** Is scripting mode. */
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
   170
    private final boolean scripting;
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
   171
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   172
    private List<Statement> functionDeclarations;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   173
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   174
    private final ParserContext lc;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   175
    private final Deque<Object> defaultNames;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   176
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   177
    /** Namespace for function names where not explicitly given */
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   178
    private final Namespace namespace;
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   179
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   180
    private final DebugLogger log;
16252
3bfe9b68a0fa 8008648: Lazy JIT scope and callee semantics bugfixes. Broke out wallclock timer.
lagergren
parents: 16245
diff changeset
   181
18870
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   182
    /** to receive line information from Lexer when scanning multine literals. */
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   183
    protected final Lexer.LineInfoReceiver lineInfoReceiver;
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   184
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
   185
    private RecompilableScriptFunctionData reparsedFunction;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   186
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   187
    /**
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   188
     * Constructor
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   189
     *
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
   190
     * @param env     script environment
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   191
     * @param source  source to parse
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   192
     * @param errors  error manager
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   193
     */
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
   194
    public Parser(final ScriptEnvironment env, final Source source, final ErrorManager errors) {
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   195
        this(env, source, errors, env._strict, null);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   196
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   197
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   198
    /**
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   199
     * Constructor
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   200
     *
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   201
     * @param env     script environment
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   202
     * @param source  source to parse
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   203
     * @param errors  error manager
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   204
     * @param strict  strict
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   205
     * @param log debug logger if one is needed
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   206
     */
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   207
    public Parser(final ScriptEnvironment env, final Source source, final ErrorManager errors, final boolean strict, final DebugLogger log) {
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
   208
        this(env, source, errors, strict, 0, log);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   209
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   210
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   211
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   212
     * Construct a parser.
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   213
     *
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
   214
     * @param env     script environment
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   215
     * @param source  source to parse
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   216
     * @param errors  error manager
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   217
     * @param strict  parser created with strict mode enabled.
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   218
     * @param lineOffset line offset to start counting lines from
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   219
     * @param log debug logger if one is needed
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   220
     */
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
   221
    public Parser(final ScriptEnvironment env, final Source source, final ErrorManager errors, final boolean strict, final int lineOffset, final DebugLogger log) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   222
        super(source, errors, strict, lineOffset);
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   223
        this.lc = new ParserContext();
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   224
        this.defaultNames = new ArrayDeque<>();
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   225
        this.env = env;
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
   226
        this.namespace = new Namespace(env.getNamespace());
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
   227
        this.scripting = env._scripting;
18870
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   228
        if (this.scripting) {
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   229
            this.lineInfoReceiver = new Lexer.LineInfoReceiver() {
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   230
                @Override
19472
9476460521b3 8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents: 18877
diff changeset
   231
                public void lineInfo(final int receiverLine, final int receiverLinePosition) {
18870
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   232
                    // update the parser maintained line information
19472
9476460521b3 8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents: 18877
diff changeset
   233
                    Parser.this.line = receiverLine;
9476460521b3 8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents: 18877
diff changeset
   234
                    Parser.this.linePosition = receiverLinePosition;
18870
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   235
                }
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   236
            };
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   237
        } else {
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   238
            // non-scripting mode script can't have multi-line literals
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   239
            this.lineInfoReceiver = null;
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   240
        }
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   241
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   242
        this.log = log == null ? DebugLogger.DISABLED_LOGGER : log;
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   243
    }
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   244
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   245
    @Override
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   246
    public DebugLogger getLogger() {
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   247
        return log;
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   248
    }
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   249
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   250
    @Override
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   251
    public DebugLogger initLogger(final Context context) {
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   252
        return context.getLogger(this.getClass());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   253
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   254
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   255
    /**
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   256
     * Sets the name for the first function. This is only used when reparsing anonymous functions to ensure they can
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   257
     * preserve their already assigned name, as that name doesn't appear in their source text.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   258
     * @param name the name for the first parsed function.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   259
     */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   260
    public void setFunctionName(final String name) {
26243
438aba09d465 8055911: Don't use String.intern for IdentNode
attila
parents: 26068
diff changeset
   261
        defaultNames.push(createIdentNode(0, 0, name));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   262
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   263
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   264
    /**
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
   265
     * Sets the {@link RecompilableScriptFunctionData} representing the function being reparsed (when this
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
   266
     * parser instance is used to reparse a previously parsed function, as part of its on-demand compilation).
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
   267
     * This will trigger various special behaviors, such as skipping nested function bodies.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
   268
     * @param reparsedFunction the function being reparsed.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
   269
     */
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
   270
    public void setReparsedFunction(final RecompilableScriptFunctionData reparsedFunction) {
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
   271
        this.reparsedFunction = reparsedFunction;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
   272
    }
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
   273
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
   274
    /**
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   275
     * Execute parse and return the resulting function node.
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   276
     * Errors will be thrown and the error manager will contain information
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   277
     * if parsing should fail
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   278
     *
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   279
     * This is the default parse call, which will name the function node
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   280
     * {code :program} {@link CompilerConstants#PROGRAM}
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   281
     *
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   282
     * @return function node resulting from successful parse
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   283
     */
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   284
    public FunctionNode parse() {
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
   285
        return parse(PROGRAM.symbolName(), 0, source.getLength(), 0);
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   286
    }
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   287
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   288
    /**
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   289
     * Set up first token. Skips opening EOL.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   290
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   291
    private void scanFirstToken() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   292
        k = -1;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   293
        next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   294
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   295
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   296
    /**
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   297
     * Execute parse and return the resulting function node.
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   298
     * Errors will be thrown and the error manager will contain information
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   299
     * if parsing should fail
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   300
     *
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   301
     * This should be used to create one and only one function node
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   302
     *
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   303
     * @param scriptName name for the script, given to the parsed FunctionNode
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   304
     * @param startPos start position in source
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   305
     * @param len length of parse
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
   306
     * @param reparseFlags flags provided by {@link RecompilableScriptFunctionData} as context for
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
   307
     * the code being reparsed. This allows us to recognize special forms of functions such
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
   308
     * as property getters and setters or instances of ES6 method shorthand in object literals.
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   309
     *
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   310
     * @return function node resulting from successful parse
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   311
     */
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
   312
    public FunctionNode parse(final String scriptName, final int startPos, final int len, final int reparseFlags) {
24764
722a9603b237 8043633: In order to remove global state outside of contexts, make sure Timing class is an instance and not a static global collection of data. Move into Context. Move -Dnashorn.timing to an official logging option.
lagergren
parents: 24759
diff changeset
   313
        final boolean isTimingEnabled = env.isTimingEnabled();
26246
66c7c54fe70c 8055923: collect timings using System.nanoTime
attila
parents: 26243
diff changeset
   314
        final long t0 = isTimingEnabled ? System.nanoTime() : 0L;
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   315
        log.info(this, " begin for '", scriptName, "'");
16252
3bfe9b68a0fa 8008648: Lazy JIT scope and callee semantics bugfixes. Broke out wallclock timer.
lagergren
parents: 16245
diff changeset
   316
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   317
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   318
            stream = new TokenStream();
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
   319
            lexer  = new Lexer(source, startPos, len, stream, scripting && !env._no_syntax_extensions, env._es6, reparsedFunction != null);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   320
            lexer.line = lexer.pendingLine = lineOffset + 1;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   321
            line = lineOffset;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   322
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   323
            scanFirstToken();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   324
            // Begin parse.
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
   325
            return program(scriptName, reparseFlags);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   326
        } catch (final Exception e) {
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   327
            handleParseException(e);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   328
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   329
            return null;
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   330
        } finally {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   331
            final String end = this + " end '" + scriptName + "'";
24764
722a9603b237 8043633: In order to remove global state outside of contexts, make sure Timing class is an instance and not a static global collection of data. Move into Context. Move -Dnashorn.timing to an official logging option.
lagergren
parents: 24759
diff changeset
   332
            if (isTimingEnabled) {
26246
66c7c54fe70c 8055923: collect timings using System.nanoTime
attila
parents: 26243
diff changeset
   333
                env._timing.accumulateTime(toString(), System.nanoTime() - t0);
66c7c54fe70c 8055923: collect timings using System.nanoTime
attila
parents: 26243
diff changeset
   334
                log.info(end, "' in ", Timing.toMillisPrint(System.nanoTime() - t0), " ms");
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   335
            } else {
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   336
                log.info(end);
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   337
            }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   338
        }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   339
    }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   340
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   341
    /**
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   342
     * Parse and return the resulting module.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   343
     * Errors will be thrown and the error manager will contain information
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   344
     * if parsing should fail
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   345
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   346
     * @param moduleName name for the module, given to the parsed FunctionNode
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   347
     * @param startPos start position in source
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   348
     * @param len length of parse
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   349
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   350
     * @return function node resulting from successful parse
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   351
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   352
    public FunctionNode parseModule(final String moduleName, final int startPos, final int len) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   353
        try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   354
            stream = new TokenStream();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   355
            lexer  = new Lexer(source, startPos, len, stream, scripting && !env._no_syntax_extensions, env._es6, reparsedFunction != null);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   356
            lexer.line = lexer.pendingLine = lineOffset + 1;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   357
            line = lineOffset;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   358
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   359
            scanFirstToken();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   360
            // Begin parse.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   361
            return module(moduleName);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   362
        } catch (final Exception e) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   363
            handleParseException(e);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   364
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   365
            return null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   366
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   367
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   368
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   369
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   370
     * Entry point for parsing a module.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   371
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   372
     * @param moduleName the module name
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   373
     * @return the parsed module
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   374
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   375
    public FunctionNode parseModule(final String moduleName) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   376
        return parseModule(moduleName, 0, source.getLength());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   377
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   378
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   379
    /**
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   380
     * Parse and return the list of function parameter list. A comma
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   381
     * separated list of function parameter identifiers is expected to be parsed.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   382
     * Errors will be thrown and the error manager will contain information
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   383
     * if parsing should fail. This method is used to check if parameter Strings
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   384
     * passed to "Function" constructor is a valid or not.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   385
     *
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   386
     * @return the list of IdentNodes representing the formal parameter list
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   387
     */
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   388
    public List<IdentNode> parseFormalParameterList() {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   389
        try {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   390
            stream = new TokenStream();
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
   391
            lexer  = new Lexer(source, stream, scripting && !env._no_syntax_extensions, env._es6);
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   392
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   393
            scanFirstToken();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   394
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   395
            return formalParameterList(TokenType.EOF, false);
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   396
        } catch (final Exception e) {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   397
            handleParseException(e);
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   398
            return null;
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   399
        }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   400
    }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   401
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   402
    /**
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   403
     * Execute parse and return the resulting function node.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   404
     * Errors will be thrown and the error manager will contain information
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   405
     * if parsing should fail. This method is used to check if code String
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   406
     * passed to "Function" constructor is a valid function body or not.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   407
     *
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   408
     * @return function node resulting from successful parse
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   409
     */
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   410
    public FunctionNode parseFunctionBody() {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   411
        try {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   412
            stream = new TokenStream();
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
   413
            lexer  = new Lexer(source, stream, scripting && !env._no_syntax_extensions, env._es6);
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24719
diff changeset
   414
            final int functionLine = line;
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   415
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   416
            scanFirstToken();
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   417
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   418
            // Make a fake token for the function.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   419
            final long functionToken = Token.toDesc(FUNCTION, 0, source.getLength());
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   420
            // Set up the function to append elements.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   421
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   422
            final IdentNode ident = new IdentNode(functionToken, Token.descPosition(functionToken), PROGRAM.symbolName());
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   423
            final ParserContextFunctionNode function = createParserContextFunctionNode(ident, functionToken, FunctionNode.Kind.NORMAL, functionLine, Collections.<IdentNode>emptyList());
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   424
            lc.push(function);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   425
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   426
            final ParserContextBlockNode body = newBlock();
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   427
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   428
            functionDeclarations = new ArrayList<>();
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
   429
            sourceElements(0);
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   430
            addFunctionDeclarations(function);
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   431
            functionDeclarations = null;
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   432
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   433
            restoreBlock(body);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   434
            body.setFlag(Block.NEEDS_SCOPE);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   435
29407
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
   436
            final Block functionBody = new Block(functionToken, source.getLength() - 1,
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
   437
                body.getFlags() | Block.IS_SYNTHETIC, body.getStatements());
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   438
            lc.pop(function);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   439
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   440
            expect(EOF);
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   441
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   442
            final FunctionNode functionNode = createFunctionNode(
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   443
                    function,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   444
                    functionToken,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   445
                    ident,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   446
                    Collections.<IdentNode>emptyList(),
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   447
                    FunctionNode.Kind.NORMAL,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   448
                    functionLine,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   449
                    functionBody);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   450
            printAST(functionNode);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   451
            return functionNode;
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   452
        } catch (final Exception e) {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   453
            handleParseException(e);
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   454
            return null;
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   455
        }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   456
    }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   457
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   458
    private void handleParseException(final Exception e) {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   459
        // Extract message from exception.  The message will be in error
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   460
        // message format.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   461
        String message = e.getMessage();
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   462
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   463
        // If empty message.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   464
        if (message == null) {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   465
            message = e.toString();
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   466
        }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   467
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   468
        // Issue message.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   469
        if (e instanceof ParserException) {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   470
            errors.error((ParserException)e);
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   471
        } else {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   472
            errors.error(message);
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   473
        }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   474
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   475
        if (env._dump_on_error) {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   476
            e.printStackTrace(env.getErr());
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   477
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   478
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   479
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   480
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   481
     * Skip to a good parsing recovery point.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   482
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   483
    private void recover(final Exception e) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   484
        if (e != null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   485
            // Extract message from exception.  The message will be in error
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   486
            // message format.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   487
            String message = e.getMessage();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   488
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   489
            // If empty message.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   490
            if (message == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   491
                message = e.toString();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   492
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   493
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   494
            // Issue message.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   495
            if (e instanceof ParserException) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   496
                errors.error((ParserException)e);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   497
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   498
                errors.error(message);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   499
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   500
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
   501
            if (env._dump_on_error) {
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
   502
                e.printStackTrace(env.getErr());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   503
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   504
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   505
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   506
        // Skip to a recovery point.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   507
        loop:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   508
        while (true) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   509
            switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   510
            case EOF:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   511
                // Can not go any further.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   512
                break loop;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   513
            case EOL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   514
            case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   515
            case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   516
                // Good recovery points.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   517
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   518
                break loop;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   519
            default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   520
                // So we can recover after EOL.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   521
                nextOrEOL();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   522
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   523
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   524
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   525
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   526
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   527
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   528
     * Set up a new block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   529
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   530
     * @return New block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   531
     */
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   532
    private ParserContextBlockNode newBlock() {
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   533
        return lc.push(new ParserContextBlockNode(token));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   534
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   535
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   536
    private ParserContextFunctionNode createParserContextFunctionNode(final IdentNode ident, final long functionToken, final FunctionNode.Kind kind, final int functionLine, final List<IdentNode> parameters) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   537
        // Build function name.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   538
        final StringBuilder sb = new StringBuilder();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   539
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   540
        final ParserContextFunctionNode parentFunction = lc.getCurrentFunction();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   541
        if (parentFunction != null && !parentFunction.isProgram()) {
37923
be223c7da1b8 8156896: Script stack trace should display function names
hannesw
parents: 37835
diff changeset
   542
            sb.append(parentFunction.getName()).append(CompilerConstants.NESTED_FUNCTION_SEPARATOR.symbolName());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   543
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   544
22374
5231ab59e740 8030809: Anonymous functions should not be shown with internal names in script stack trace
sundar
parents: 21868
diff changeset
   545
        assert ident.getName() != null;
5231ab59e740 8030809: Anonymous functions should not be shown with internal names in script stack trace
sundar
parents: 21868
diff changeset
   546
        sb.append(ident.getName());
5231ab59e740 8030809: Anonymous functions should not be shown with internal names in script stack trace
sundar
parents: 21868
diff changeset
   547
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   548
        final String name = namespace.uniqueName(sb.toString());
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
   549
        assert parentFunction != null || kind == FunctionNode.Kind.MODULE || name.equals(PROGRAM.symbolName()) : "name = " + name;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   550
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   551
        int flags = 0;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   552
        if (isStrictMode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   553
            flags |= FunctionNode.IS_STRICT;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   554
        }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   555
        if (parentFunction == null) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   556
            flags |= FunctionNode.IS_PROGRAM;
17518
2225a4f929c0 8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents: 17257
diff changeset
   557
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   558
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   559
        final ParserContextFunctionNode functionNode = new ParserContextFunctionNode(functionToken, ident, name, namespace, functionLine, kind, parameters);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   560
        functionNode.setFlag(flags);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   561
        return functionNode;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   562
    }
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   563
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   564
    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) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   565
        // assert body.isFunctionBody() || body.getFlag(Block.IS_PARAMETER_BLOCK) && ((BlockStatement) body.getLastStatement()).getBlock().isFunctionBody();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   566
        // Start new block.
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   567
        final FunctionNode functionNode =
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   568
            new FunctionNode(
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   569
                source,
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   570
                functionLine,
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   571
                body.getToken(),
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   572
                Token.descPosition(body.getToken()),
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   573
                startToken,
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   574
                function.getLastToken(),
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   575
                namespace,
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   576
                ident,
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   577
                function.getName(),
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   578
                parameters,
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
   579
                function.getParameterExpressions(),
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   580
                kind,
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   581
                function.getFlags(),
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   582
                body,
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   583
                function.getEndParserState(),
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   584
                function.getModule(),
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   585
                function.getDebugFlags());
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   586
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   587
        printAST(functionNode);
17518
2225a4f929c0 8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents: 17257
diff changeset
   588
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   589
        return functionNode;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   590
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   591
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   592
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   593
     * Restore the current block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   594
     */
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   595
    private ParserContextBlockNode restoreBlock(final ParserContextBlockNode block) {
17518
2225a4f929c0 8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents: 17257
diff changeset
   596
        return lc.pop(block);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   597
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   598
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   599
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   600
     * Get the statements in a block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   601
     * @return Block statements.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   602
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   603
    private Block getBlock(final boolean needsBraces) {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   604
        final long blockToken = token;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   605
        final ParserContextBlockNode newBlock = newBlock();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   606
        try {
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   607
            // Block opening brace.
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   608
            if (needsBraces) {
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   609
                expect(LBRACE);
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   610
            }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   611
            // Accumulate block statements.
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   612
            statementList();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   613
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   614
        } finally {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   615
            restoreBlock(newBlock);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   616
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   617
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   618
        // Block closing brace.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   619
        if (needsBraces) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   620
            expect(RBRACE);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   621
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   622
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   623
        final int flags = newBlock.getFlags() | (needsBraces ? 0 : Block.IS_SYNTHETIC);
29407
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
   624
        return new Block(blockToken, finish, flags, newBlock.getStatements());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   625
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   626
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   627
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   628
     * Get all the statements generated by a single statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   629
     * @return Statements.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   630
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   631
    private Block getStatement() {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   632
        return getStatement(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   633
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   634
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
   635
    private Block getStatement(final boolean labelledStatement) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   636
        if (type == LBRACE) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   637
            return getBlock(true);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   638
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   639
        // Set up new block. Captures first token.
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   640
        final ParserContextBlockNode newBlock = newBlock();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   641
        try {
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
   642
            statement(false, 0, true, labelledStatement);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   643
        } finally {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   644
            restoreBlock(newBlock);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   645
        }
29407
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
   646
        return new Block(newBlock.getToken(), finish, newBlock.getFlags() | Block.IS_SYNTHETIC, newBlock.getStatements());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   647
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   648
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   649
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   650
     * Detect calls to special functions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   651
     * @param ident Called function.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   652
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   653
    private void detectSpecialFunction(final IdentNode ident) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   654
        final String name = ident.getName();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   655
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   656
        if (EVAL.symbolName().equals(name)) {
17255
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17249
diff changeset
   657
            markEval(lc);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   658
        } else if (SUPER.getName().equals(name)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   659
            assert ident.isDirectSuper();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   660
            markSuperCall(lc);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   661
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   662
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   663
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   664
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   665
     * Detect use of special properties.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   666
     * @param ident Referenced property.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   667
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   668
    private void detectSpecialProperty(final IdentNode ident) {
19898
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   669
        if (isArguments(ident)) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   670
            // skip over arrow functions, e.g. function f() { return (() => arguments.length)(); }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   671
            getCurrentNonArrowFunction().setFlag(FunctionNode.USES_ARGUMENTS);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   672
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   673
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   674
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   675
    private boolean useBlockScope() {
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   676
        return env._es6;
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   677
    }
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   678
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   679
    private boolean isES6() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   680
        return env._es6;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   681
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   682
19898
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   683
    private static boolean isArguments(final String name) {
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   684
        return ARGUMENTS_NAME.equals(name);
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   685
    }
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   686
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   687
    static boolean isArguments(final IdentNode ident) {
19898
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   688
        return isArguments(ident.getName());
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   689
    }
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   690
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   691
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   692
     * Tells whether a IdentNode can be used as L-value of an assignment
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   693
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   694
     * @param ident IdentNode to be checked
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   695
     * @return whether the ident can be used as L-value
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   696
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   697
    private static boolean checkIdentLValue(final IdentNode ident) {
30392
dc4a419b2982 8079362: Enforce best practices for Node token API usage
attila
parents: 29539
diff changeset
   698
        return ident.tokenType().getKind() != TokenKind.KEYWORD;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   699
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   700
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   701
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   702
     * Verify an assignment expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   703
     * @param op  Operation token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   704
     * @param lhs Left hand side expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   705
     * @param rhs Right hand side expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   706
     * @return Verified expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   707
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
   708
    private Expression verifyAssignment(final long op, final Expression lhs, final Expression rhs) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   709
        final TokenType opType = Token.descType(op);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   710
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   711
        switch (opType) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   712
        case ASSIGN:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   713
        case ASSIGN_ADD:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   714
        case ASSIGN_BIT_AND:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   715
        case ASSIGN_BIT_OR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   716
        case ASSIGN_BIT_XOR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   717
        case ASSIGN_DIV:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   718
        case ASSIGN_MOD:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   719
        case ASSIGN_MUL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   720
        case ASSIGN_SAR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   721
        case ASSIGN_SHL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   722
        case ASSIGN_SHR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   723
        case ASSIGN_SUB:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   724
            if (lhs instanceof IdentNode) {
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
   725
                if (!checkIdentLValue((IdentNode)lhs)) {
18632
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
   726
                    return referenceError(lhs, rhs, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   727
                }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   728
                verifyIdent((IdentNode)lhs, "assignment");
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   729
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   730
            } else if (lhs instanceof AccessNode || lhs instanceof IndexNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   731
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   732
            } else if (opType == ASSIGN && isDestructuringLhs(lhs)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   733
                verifyDestructuringAssignmentPattern(lhs, "assignment");
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   734
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   735
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   736
                return referenceError(lhs, rhs, env._early_lvalue_error);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   737
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   738
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   739
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   740
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   741
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   742
        // Build up node.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   743
        if(BinaryNode.isLogical(opType)) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   744
            return new BinaryNode(op, new JoinPredecessorExpression(lhs), new JoinPredecessorExpression(rhs));
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   745
        }
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
   746
        return new BinaryNode(op, lhs, rhs);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   747
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   748
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
   749
    private boolean isDestructuringLhs(final Expression lhs) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   750
        if (lhs instanceof ObjectNode || lhs instanceof LiteralNode.ArrayLiteralNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   751
            return isES6();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   752
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   753
        return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   754
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   755
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
   756
    private void verifyDestructuringAssignmentPattern(final Expression pattern, final String contextString) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   757
        assert pattern instanceof ObjectNode || pattern instanceof LiteralNode.ArrayLiteralNode;
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
   758
        pattern.accept(new VerifyDestructuringPatternNodeVisitor(new LexicalContext()) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   759
            @Override
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
   760
            protected void verifySpreadElement(final Expression lvalue) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
   761
                if (!checkValidLValue(lvalue, contextString)) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
   762
                    throw error(AbstractParser.message("invalid.lvalue"), lvalue.getToken());
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   763
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   764
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   765
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   766
            @Override
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
   767
            public boolean enterIdentNode(final IdentNode identNode) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   768
                verifyIdent(identNode, contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   769
                if (!checkIdentLValue(identNode)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   770
                    referenceError(identNode, null, true);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   771
                    return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   772
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   773
                return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   774
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   775
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   776
            @Override
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
   777
            public boolean enterAccessNode(final AccessNode accessNode) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   778
                return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   779
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   780
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   781
            @Override
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
   782
            public boolean enterIndexNode(final IndexNode indexNode) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   783
                return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   784
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   785
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   786
            @Override
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
   787
            protected boolean enterDefault(final Node node) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   788
                throw error(String.format("unexpected node in AssignmentPattern: %s", node));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   789
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   790
        });
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   791
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   792
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   793
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   794
     * Reduce increment/decrement to simpler operations.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   795
     * @param firstToken First token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   796
     * @param tokenType  Operation token (INCPREFIX/DEC.)
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   797
     * @param expression Left hand side expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   798
     * @param isPostfix  Prefix or postfix.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   799
     * @return           Reduced expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   800
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
   801
    private static UnaryNode incDecExpression(final long firstToken, final TokenType tokenType, final Expression expression, final boolean isPostfix) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   802
        if (isPostfix) {
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
   803
            return new UnaryNode(Token.recast(firstToken, tokenType == DECPREFIX ? DECPOSTFIX : INCPOSTFIX), expression.getStart(), Token.descPosition(firstToken) + Token.descLength(firstToken), expression);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   804
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   805
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
   806
        return new UnaryNode(firstToken, expression);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   807
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   808
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   809
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   810
     * -----------------------------------------------------------------------
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   811
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   812
     * Grammar based on
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   813
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   814
     *      ECMAScript Language Specification
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   815
     *      ECMA-262 5th Edition / December 2009
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   816
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   817
     * -----------------------------------------------------------------------
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   818
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   819
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   820
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   821
     * Program :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   822
     *      SourceElements?
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   823
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   824
     * See 14
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   825
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   826
     * Parse the top level script.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   827
     */
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
   828
    private FunctionNode program(final String scriptName, final int reparseFlags) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   829
        // Make a pseudo-token for the script holding its start and length.
24994
92a19723a5ac 8047035: (function() "hello")() crashes in Lexer with jdk9
sundar
parents: 24769
diff changeset
   830
        final long functionToken = Token.toDesc(FUNCTION, Token.descPosition(Token.withDelimiter(token)), source.getLength());
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   831
        final int  functionLine  = line;
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   832
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   833
        final IdentNode ident = new IdentNode(functionToken, Token.descPosition(functionToken), scriptName);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   834
        final ParserContextFunctionNode script = createParserContextFunctionNode(
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   835
                ident,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   836
                functionToken,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   837
                FunctionNode.Kind.SCRIPT,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   838
                functionLine,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   839
                Collections.<IdentNode>emptyList());
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   840
        lc.push(script);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   841
        final ParserContextBlockNode body = newBlock();
27814
96427359f4fe 8057691: Nashorn: let & const declarations are not shared between scripts
hannesw
parents: 27102
diff changeset
   842
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   843
        functionDeclarations = new ArrayList<>();
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
   844
        sourceElements(reparseFlags);
27814
96427359f4fe 8057691: Nashorn: let & const declarations are not shared between scripts
hannesw
parents: 27102
diff changeset
   845
        addFunctionDeclarations(script);
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   846
        functionDeclarations = null;
27814
96427359f4fe 8057691: Nashorn: let & const declarations are not shared between scripts
hannesw
parents: 27102
diff changeset
   847
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   848
        restoreBlock(body);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   849
        body.setFlag(Block.NEEDS_SCOPE);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   850
        final Block programBody = new Block(functionToken, finish, body.getFlags() | Block.IS_SYNTHETIC | Block.IS_BODY, body.getStatements());
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   851
        lc.pop(script);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   852
        script.setLastToken(token);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   853
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   854
        expect(EOF);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   855
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   856
        return createFunctionNode(script, functionToken, ident, Collections.<IdentNode>emptyList(), FunctionNode.Kind.SCRIPT, functionLine, programBody);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   857
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   858
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   859
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   860
     * Directive value or null if statement is not a directive.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   861
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   862
     * @param stmt Statement to be checked
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   863
     * @return Directive value if the given statement is a directive
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   864
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   865
    private String getDirective(final Node stmt) {
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
   866
        if (stmt instanceof ExpressionStatement) {
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
   867
            final Node expr = ((ExpressionStatement)stmt).getExpression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   868
            if (expr instanceof LiteralNode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   869
                final LiteralNode<?> lit = (LiteralNode<?>)expr;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   870
                final long litToken = lit.getToken();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   871
                final TokenType tt = Token.descType(litToken);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   872
                // A directive is either a string or an escape string
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   873
                if (tt == TokenType.STRING || tt == TokenType.ESCSTRING) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   874
                    // Make sure that we don't unescape anything. Return as seen in source!
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   875
                    return source.getString(lit.getStart(), Token.descLength(litToken));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   876
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   877
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   878
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   879
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   880
        return null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   881
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   882
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   883
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   884
     * SourceElements :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   885
     *      SourceElement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   886
     *      SourceElements SourceElement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   887
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   888
     * See 14
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   889
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   890
     * Parse the elements of the script or function.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   891
     */
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
   892
    private void sourceElements(final int reparseFlags) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   893
        List<Node>    directiveStmts        = null;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   894
        boolean       checkDirective        = true;
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
   895
        int           functionFlags          = reparseFlags;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   896
        final boolean oldStrictMode         = isStrictMode;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   897
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   898
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   899
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   900
            // If is a script, then process until the end of the script.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   901
            while (type != EOF) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   902
                // Break if the end of a code block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   903
                if (type == RBRACE) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   904
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   905
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   906
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   907
                try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   908
                    // Get the next element.
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
   909
                    statement(true, functionFlags, false, false);
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
   910
                    functionFlags = 0;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   911
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   912
                    // check for directive prologues
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   913
                    if (checkDirective) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   914
                        // skip any debug statement like line number to get actual first line
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   915
                        final Statement lastStatement = lc.getLastStatement();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   916
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   917
                        // get directive prologue, if any
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   918
                        final String directive = getDirective(lastStatement);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   919
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   920
                        // If we have seen first non-directive statement,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   921
                        // no more directive statements!!
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   922
                        checkDirective = directive != null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   923
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   924
                        if (checkDirective) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   925
                            if (!oldStrictMode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   926
                                if (directiveStmts == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   927
                                    directiveStmts = new ArrayList<>();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   928
                                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   929
                                directiveStmts.add(lastStatement);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   930
                            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   931
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   932
                            // handle use strict directive
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   933
                            if ("use strict".equals(directive)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   934
                                isStrictMode = true;
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   935
                                final ParserContextFunctionNode function = lc.getCurrentFunction();
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   936
                                function.setFlag(FunctionNode.IS_STRICT);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   937
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   938
                                // We don't need to check these, if lexical environment is already strict
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   939
                                if (!oldStrictMode && directiveStmts != null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   940
                                    // check that directives preceding this one do not violate strictness
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   941
                                    for (final Node statement : directiveStmts) {
32534
b3ec7f3b3c2a 8136349: Typos patch for nashorn sources submitted on Sep 10, 2015
sundar
parents: 32444
diff changeset
   942
                                        // the get value will force unescape of preceding
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   943
                                        // escaped string directives
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   944
                                        getValue(statement.getToken());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   945
                                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   946
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   947
                                    // verify that function name as well as parameter names
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16196
diff changeset
   948
                                    // satisfy strict mode restrictions.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   949
                                    verifyIdent(function.getIdent(), "function name");
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   950
                                    for (final IdentNode param : function.getParameters()) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   951
                                        verifyIdent(param, "function parameter");
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   952
                                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   953
                                }
26065
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
   954
                            } else if (Context.DEBUG) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   955
                                final int debugFlag = FunctionNode.getDirectiveFlag(directive);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   956
                                if (debugFlag != 0) {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   957
                                    final ParserContextFunctionNode function = lc.getCurrentFunction();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   958
                                    function.setDebugFlag(debugFlag);
26065
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
   959
                                }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   960
                            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   961
                        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   962
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   963
                } catch (final Exception e) {
29407
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
   964
                    final int errorLine = line;
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
   965
                    final long errorToken = token;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   966
                    //recover parsing
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   967
                    recover(e);
29407
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
   968
                    final ErrorNode errorExpr = new ErrorNode(errorToken, finish);
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
   969
                    final ExpressionStatement expressionStatement = new ExpressionStatement(errorLine, errorToken, finish, errorExpr);
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
   970
                    appendStatement(expressionStatement);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   971
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   972
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   973
                // No backtracking from here on.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   974
                stream.commit(k);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   975
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   976
        } finally {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   977
            isStrictMode = oldStrictMode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   978
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   979
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   980
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   981
    /**
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   982
     * Parse any of the basic statement types.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   983
     *
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   984
     * Statement :
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   985
     *      BlockStatement
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   986
     *      VariableStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   987
     *      EmptyStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   988
     *      ExpressionStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   989
     *      IfStatement
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   990
     *      BreakableStatement
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   991
     *      ContinueStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   992
     *      BreakStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   993
     *      ReturnStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   994
     *      WithStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   995
     *      LabelledStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   996
     *      ThrowStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   997
     *      TryStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   998
     *      DebuggerStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   999
     *
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1000
     * BreakableStatement :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1001
     *      IterationStatement
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1002
     *      SwitchStatement
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1003
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1004
     * BlockStatement :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1005
     *      Block
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1006
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1007
     * Block :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1008
     *      { StatementList opt }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1009
     *
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1010
     * StatementList :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1011
     *      StatementListItem
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1012
     *      StatementList StatementListItem
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1013
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1014
     * StatementItem :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1015
     *      Statement
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1016
     *      Declaration
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1017
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1018
     * Declaration :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1019
     *     HoistableDeclaration
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1020
     *     ClassDeclaration
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1021
     *     LexicalDeclaration
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1022
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1023
     * HoistableDeclaration :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1024
     *     FunctionDeclaration
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1025
     *     GeneratorDeclaration
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1026
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1027
    private void statement() {
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
  1028
        statement(false, 0, false, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1029
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1030
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1031
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1032
     * @param topLevel does this statement occur at the "top level" of a script or a function?
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
  1033
     * @param reparseFlags reparse flags to decide whether to allow property "get" and "set" functions or ES6 methods.
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  1034
     * @param singleStatement are we in a single statement context?
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1035
     */
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
  1036
    private void statement(final boolean topLevel, final int reparseFlags, final boolean singleStatement, final boolean labelledStatement) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1037
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1038
        case LBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1039
            block();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1040
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1041
        case VAR:
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1042
            variableStatement(type);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1043
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1044
        case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1045
            emptyStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1046
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1047
        case IF:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1048
            ifStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1049
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1050
        case FOR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1051
            forStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1052
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1053
        case WHILE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1054
            whileStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1055
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1056
        case DO:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1057
            doStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1058
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1059
        case CONTINUE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1060
            continueStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1061
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1062
        case BREAK:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1063
            breakStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1064
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1065
        case RETURN:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1066
            returnStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1067
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1068
        case WITH:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1069
            withStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1070
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1071
        case SWITCH:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1072
            switchStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1073
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1074
        case THROW:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1075
            throwStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1076
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1077
        case TRY:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1078
            tryStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1079
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1080
        case DEBUGGER:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1081
            debuggerStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1082
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1083
        case RPAREN:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1084
        case RBRACKET:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1085
        case EOF:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1086
            expect(SEMICOLON);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1087
            break;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1088
        case FUNCTION:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1089
            // As per spec (ECMA section 12), function declarations as arbitrary statement
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1090
            // is not "portable". Implementation can issue a warning or disallow the same.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1091
            if (singleStatement) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1092
                // ES6 B.3.2 Labelled Function Declarations
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1093
                // It is a Syntax Error if any strict mode source code matches this rule:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1094
                // LabelledItem : FunctionDeclaration.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1095
                if (!labelledStatement || isStrictMode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1096
                    throw error(AbstractParser.message("expected.stmt", "function declaration"), token);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1097
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1098
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1099
            functionExpression(true, topLevel || labelledStatement);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1100
            return;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1101
        default:
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1102
            if (useBlockScope() && (type == LET && lookaheadIsLetDeclaration(false) || type == CONST)) {
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  1103
                if (singleStatement) {
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  1104
                    throw error(AbstractParser.message("expected.stmt", type.getName() + " declaration"), token);
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  1105
                }
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1106
                variableStatement(type);
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1107
                break;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1108
            } else if (type == CLASS && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1109
                if (singleStatement) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1110
                    throw error(AbstractParser.message("expected.stmt", "class declaration"), token);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1111
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1112
                classDeclaration(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1113
                break;
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1114
            }
24279
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
  1115
            if (env._const_as_var && type == CONST) {
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1116
                variableStatement(TokenType.VAR);
24279
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
  1117
                break;
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
  1118
            }
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
  1119
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1120
            if (type == IDENT || isNonStrictModeIdent()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1121
                if (T(k + 1) == COLON) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1122
                    labelStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1123
                    return;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1124
                }
41145
b9a1cb9ed1d3 8164467: ES6 computed properties are implemented wrongly
hannesw
parents: 39662
diff changeset
  1125
b9a1cb9ed1d3 8164467: ES6 computed properties are implemented wrongly
hannesw
parents: 39662
diff changeset
  1126
                if ((reparseFlags & ScriptFunctionData.IS_PROPERTY_ACCESSOR) != 0) {
b9a1cb9ed1d3 8164467: ES6 computed properties are implemented wrongly
hannesw
parents: 39662
diff changeset
  1127
                    final String ident = (String) getValue();
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1128
                    final long propertyToken = token;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1129
                    final int propertyLine = line;
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
  1130
                    if (GET_NAME.equals(ident)) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1131
                        next();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1132
                        addPropertyFunctionStatement(propertyGetterFunction(propertyToken, propertyLine));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1133
                        return;
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
  1134
                    } else if (SET_NAME.equals(ident)) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1135
                        next();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1136
                        addPropertyFunctionStatement(propertySetterFunction(propertyToken, propertyLine));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1137
                        return;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1138
                    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1139
                }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1140
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1141
41145
b9a1cb9ed1d3 8164467: ES6 computed properties are implemented wrongly
hannesw
parents: 39662
diff changeset
  1142
            if ((reparseFlags & ScriptFunctionData.IS_ES6_METHOD) != 0
b9a1cb9ed1d3 8164467: ES6 computed properties are implemented wrongly
hannesw
parents: 39662
diff changeset
  1143
                    && (type == IDENT || type == LBRACKET || isNonStrictModeIdent())) {
b9a1cb9ed1d3 8164467: ES6 computed properties are implemented wrongly
hannesw
parents: 39662
diff changeset
  1144
                final String ident = (String)getValue();
b9a1cb9ed1d3 8164467: ES6 computed properties are implemented wrongly
hannesw
parents: 39662
diff changeset
  1145
                final long propertyToken = token;
b9a1cb9ed1d3 8164467: ES6 computed properties are implemented wrongly
hannesw
parents: 39662
diff changeset
  1146
                final int propertyLine = line;
b9a1cb9ed1d3 8164467: ES6 computed properties are implemented wrongly
hannesw
parents: 39662
diff changeset
  1147
                final Expression propertyKey = propertyName();
b9a1cb9ed1d3 8164467: ES6 computed properties are implemented wrongly
hannesw
parents: 39662
diff changeset
  1148
b9a1cb9ed1d3 8164467: ES6 computed properties are implemented wrongly
hannesw
parents: 39662
diff changeset
  1149
                // Code below will need refinement once we fully support ES6 class syntax
b9a1cb9ed1d3 8164467: ES6 computed properties are implemented wrongly
hannesw
parents: 39662
diff changeset
  1150
                final int flags = CONSTRUCTOR_NAME.equals(ident) ? FunctionNode.ES6_IS_CLASS_CONSTRUCTOR : FunctionNode.ES6_IS_METHOD;
b9a1cb9ed1d3 8164467: ES6 computed properties are implemented wrongly
hannesw
parents: 39662
diff changeset
  1151
                addPropertyFunctionStatement(propertyMethodFunction(propertyKey, propertyToken, propertyLine, false, flags, false));
b9a1cb9ed1d3 8164467: ES6 computed properties are implemented wrongly
hannesw
parents: 39662
diff changeset
  1152
                return;
b9a1cb9ed1d3 8164467: ES6 computed properties are implemented wrongly
hannesw
parents: 39662
diff changeset
  1153
            }
b9a1cb9ed1d3 8164467: ES6 computed properties are implemented wrongly
hannesw
parents: 39662
diff changeset
  1154
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1155
            expressionStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1156
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1157
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1158
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1159
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1160
    private void addPropertyFunctionStatement(final PropertyFunction propertyFunction) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1161
        final FunctionNode fn = propertyFunction.functionNode;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1162
        functionDeclarations.add(new ExpressionStatement(fn.getLineNumber(), fn.getToken(), finish, fn));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1163
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1164
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1165
    /**
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1166
     * ClassDeclaration[Yield, Default] :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1167
     *   class BindingIdentifier[?Yield] ClassTail[?Yield]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1168
     *   [+Default] class ClassTail[?Yield]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1169
     */
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  1170
    private ClassNode classDeclaration(final boolean isDefault) {
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  1171
        final int classLineNumber = line;
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  1172
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  1173
        final ClassNode classExpression = classExpression(!isDefault);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1174
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1175
        if (!isDefault) {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  1176
            final VarNode classVar = new VarNode(classLineNumber, classExpression.getToken(), classExpression.getIdent().getFinish(), classExpression.getIdent(), classExpression, VarNode.IS_CONST);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1177
            appendStatement(classVar);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1178
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1179
        return classExpression;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1180
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1181
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1182
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1183
     * ClassExpression[Yield] :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1184
     *   class BindingIdentifier[?Yield]opt ClassTail[?Yield]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1185
     */
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  1186
    private ClassNode classExpression(final boolean isStatement) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1187
        assert type == CLASS;
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  1188
        final int classLineNumber = line;
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  1189
        final long classToken = token;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1190
        next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1191
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1192
        IdentNode className = null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1193
        if (isStatement || type == IDENT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1194
            className = getIdent();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1195
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1196
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  1197
        return classTail(classLineNumber, classToken, className, isStatement);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1198
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1199
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1200
    private static final class ClassElementKey {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1201
        private final boolean isStatic;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1202
        private final String propertyName;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1203
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  1204
        private ClassElementKey(final boolean isStatic, final String propertyName) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1205
            this.isStatic = isStatic;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1206
            this.propertyName = propertyName;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1207
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1208
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1209
        @Override
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1210
        public int hashCode() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1211
            final int prime = 31;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1212
            int result = 1;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1213
            result = prime * result + (isStatic ? 1231 : 1237);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1214
            result = prime * result + ((propertyName == null) ? 0 : propertyName.hashCode());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1215
            return result;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1216
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1217
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1218
        @Override
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  1219
        public boolean equals(final Object obj) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1220
            if (obj instanceof ClassElementKey) {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  1221
                final ClassElementKey other = (ClassElementKey) obj;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1222
                return this.isStatic == other.isStatic && Objects.equals(this.propertyName, other.propertyName);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1223
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1224
            return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1225
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1226
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1227
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1228
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1229
     * Parse ClassTail and ClassBody.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1230
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1231
     * ClassTail[Yield] :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1232
     *   ClassHeritage[?Yield]opt { ClassBody[?Yield]opt }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1233
     * ClassHeritage[Yield] :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1234
     *   extends LeftHandSideExpression[?Yield]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1235
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1236
     * ClassBody[Yield] :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1237
     *   ClassElementList[?Yield]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1238
     * ClassElementList[Yield] :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1239
     *   ClassElement[?Yield]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1240
     *   ClassElementList[?Yield] ClassElement[?Yield]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1241
     * ClassElement[Yield] :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1242
     *   MethodDefinition[?Yield]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1243
     *   static MethodDefinition[?Yield]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1244
     *   ;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1245
     */
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  1246
    private ClassNode classTail(final int classLineNumber, final long classToken,
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  1247
            final IdentNode className, final boolean isStatement) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1248
        final boolean oldStrictMode = isStrictMode;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1249
        isStrictMode = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1250
        try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1251
            Expression classHeritage = null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1252
            if (type == EXTENDS) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1253
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1254
                classHeritage = leftHandSideExpression();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1255
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1256
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1257
            expect(LBRACE);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1258
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1259
            PropertyNode constructor = null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1260
            final ArrayList<PropertyNode> classElements = new ArrayList<>();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1261
            final Map<ClassElementKey, Integer> keyToIndexMap = new HashMap<>();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1262
            for (;;) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1263
                if (type == SEMICOLON) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1264
                    next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1265
                    continue;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1266
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1267
                if (type == RBRACE) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1268
                    break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1269
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1270
                final long classElementToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1271
                boolean isStatic = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1272
                if (type == STATIC) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1273
                    isStatic = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1274
                    next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1275
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1276
                boolean generator = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1277
                if (isES6() && type == MUL) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1278
                    generator = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1279
                    next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1280
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1281
                final PropertyNode classElement = methodDefinition(isStatic, classHeritage != null, generator);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1282
                if (classElement.isComputed()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1283
                    classElements.add(classElement);
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
  1284
                } else if (!classElement.isStatic() && classElement.getKeyName().equals(CONSTRUCTOR_NAME)) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1285
                    if (constructor == null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1286
                        constructor = classElement;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1287
                    } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1288
                        throw error(AbstractParser.message("multiple.constructors"), classElementToken);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1289
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1290
                } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1291
                    // Check for duplicate method definitions and combine accessor methods.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1292
                    // In ES6, a duplicate is never an error regardless of strict mode (in consequence of computed property names).
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1293
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1294
                    final ClassElementKey key = new ClassElementKey(classElement.isStatic(), classElement.getKeyName());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1295
                    final Integer existing = keyToIndexMap.get(key);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1296
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1297
                    if (existing == null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1298
                        keyToIndexMap.put(key, classElements.size());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1299
                        classElements.add(classElement);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1300
                    } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1301
                        final PropertyNode existingProperty = classElements.get(existing);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1302
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1303
                        final Expression   value  = classElement.getValue();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1304
                        final FunctionNode getter = classElement.getGetter();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1305
                        final FunctionNode setter = classElement.getSetter();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1306
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1307
                        if (value != null || existingProperty.getValue() != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1308
                            keyToIndexMap.put(key, classElements.size());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1309
                            classElements.add(classElement);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1310
                        } else if (getter != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1311
                            assert existingProperty.getGetter() != null || existingProperty.getSetter() != null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1312
                            classElements.set(existing, existingProperty.setGetter(getter));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1313
                        } else if (setter != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1314
                            assert existingProperty.getGetter() != null || existingProperty.getSetter() != null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1315
                            classElements.set(existing, existingProperty.setSetter(setter));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1316
                        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1317
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1318
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1319
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1320
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1321
            final long lastToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1322
            expect(RBRACE);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1323
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1324
            if (constructor == null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1325
                constructor = createDefaultClassConstructor(classLineNumber, classToken, lastToken, className, classHeritage != null);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1326
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1327
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1328
            classElements.trimToSize();
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  1329
            return new ClassNode(classLineNumber, classToken, finish, className, classHeritage, constructor, classElements, isStatement);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1330
        } finally {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1331
            isStrictMode = oldStrictMode;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1332
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1333
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1334
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  1335
    private PropertyNode createDefaultClassConstructor(final int classLineNumber, final long classToken, final long lastToken, final IdentNode className, final boolean subclass) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1336
        final int ctorFinish = finish;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1337
        final List<Statement> statements;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1338
        final List<IdentNode> parameters;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1339
        final long identToken = Token.recast(classToken, TokenType.IDENT);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1340
        if (subclass) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1341
            final IdentNode superIdent = createIdentNode(identToken, ctorFinish, SUPER.getName()).setIsDirectSuper();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1342
            final IdentNode argsIdent = createIdentNode(identToken, ctorFinish, "args").setIsRestParameter();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1343
            final Expression spreadArgs = new UnaryNode(Token.recast(classToken, TokenType.SPREAD_ARGUMENT), argsIdent);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1344
            final CallNode superCall = new CallNode(classLineNumber, classToken, ctorFinish, superIdent, Collections.singletonList(spreadArgs), false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1345
            statements = Collections.singletonList(new ExpressionStatement(classLineNumber, classToken, ctorFinish, superCall));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1346
            parameters = Collections.singletonList(argsIdent);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1347
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1348
            statements = Collections.emptyList();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1349
            parameters = Collections.emptyList();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1350
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1351
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1352
        final Block body = new Block(classToken, ctorFinish, Block.IS_BODY, statements);
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
  1353
        final IdentNode ctorName = className != null ? className : createIdentNode(identToken, ctorFinish, CONSTRUCTOR_NAME);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1354
        final ParserContextFunctionNode function = createParserContextFunctionNode(ctorName, classToken, FunctionNode.Kind.NORMAL, classLineNumber, parameters);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1355
        function.setLastToken(lastToken);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1356
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1357
        function.setFlag(FunctionNode.ES6_IS_METHOD);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1358
        function.setFlag(FunctionNode.ES6_IS_CLASS_CONSTRUCTOR);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1359
        if (subclass) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1360
            function.setFlag(FunctionNode.ES6_IS_SUBCLASS_CONSTRUCTOR);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1361
            function.setFlag(FunctionNode.ES6_HAS_DIRECT_SUPER);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1362
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1363
        if (className == null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1364
            function.setFlag(FunctionNode.IS_ANONYMOUS);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1365
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1366
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1367
        final PropertyNode constructor = new PropertyNode(classToken, ctorFinish, ctorName, createFunctionNode(
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1368
                        function,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1369
                        classToken,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1370
                        ctorName,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1371
                        parameters,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1372
                        FunctionNode.Kind.NORMAL,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1373
                        classLineNumber,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1374
                        body
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1375
                        ), null, null, false, false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1376
        return constructor;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1377
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1378
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1379
    private PropertyNode methodDefinition(final boolean isStatic, final boolean subclass, final boolean generator) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1380
        final long methodToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1381
        final int methodLine = line;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1382
        final boolean computed = type == LBRACKET;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1383
        final boolean isIdent = type == IDENT;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1384
        final Expression propertyName = propertyName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1385
        int flags = FunctionNode.ES6_IS_METHOD;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1386
        if (!computed) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1387
            final String name = ((PropertyKey)propertyName).getPropertyName();
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
  1388
            if (!generator && isIdent && type != LPAREN && name.equals(GET_NAME)) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1389
                final PropertyFunction methodDefinition = propertyGetterFunction(methodToken, methodLine, flags);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1390
                verifyAllowedMethodName(methodDefinition.key, isStatic, methodDefinition.computed, generator, true);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1391
                return new PropertyNode(methodToken, finish, methodDefinition.key, null, methodDefinition.functionNode, null, isStatic, methodDefinition.computed);
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
  1392
            } else if (!generator && isIdent && type != LPAREN && name.equals(SET_NAME)) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1393
                final PropertyFunction methodDefinition = propertySetterFunction(methodToken, methodLine, flags);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1394
                verifyAllowedMethodName(methodDefinition.key, isStatic, methodDefinition.computed, generator, true);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1395
                return new PropertyNode(methodToken, finish, methodDefinition.key, null, null, methodDefinition.functionNode, isStatic, methodDefinition.computed);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1396
            } else {
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
  1397
                if (!isStatic && !generator && name.equals(CONSTRUCTOR_NAME)) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1398
                    flags |= FunctionNode.ES6_IS_CLASS_CONSTRUCTOR;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1399
                    if (subclass) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1400
                        flags |= FunctionNode.ES6_IS_SUBCLASS_CONSTRUCTOR;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1401
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1402
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1403
                verifyAllowedMethodName(propertyName, isStatic, computed, generator, false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1404
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1405
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1406
        final PropertyFunction methodDefinition = propertyMethodFunction(propertyName, methodToken, methodLine, generator, flags, computed);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1407
        return new PropertyNode(methodToken, finish, methodDefinition.key, methodDefinition.functionNode, null, null, isStatic, computed);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1408
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1409
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1410
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1411
     * ES6 14.5.1 Static Semantics: Early Errors.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1412
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1413
    private void verifyAllowedMethodName(final Expression key, final boolean isStatic, final boolean computed, final boolean generator, final boolean accessor) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1414
        if (!computed) {
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
  1415
            if (!isStatic && generator && ((PropertyKey) key).getPropertyName().equals(CONSTRUCTOR_NAME)) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1416
                throw error(AbstractParser.message("generator.constructor"), key.getToken());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1417
            }
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
  1418
            if (!isStatic && accessor && ((PropertyKey) key).getPropertyName().equals(CONSTRUCTOR_NAME)) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1419
                throw error(AbstractParser.message("accessor.constructor"), key.getToken());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1420
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1421
            if (isStatic && ((PropertyKey) key).getPropertyName().equals("prototype")) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1422
                throw error(AbstractParser.message("static.prototype.method"), key.getToken());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1423
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1424
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1425
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1426
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1427
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1428
     * block :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1429
     *      { StatementList? }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1430
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1431
     * see 12.1
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1432
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1433
     * Parse a statement block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1434
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1435
    private void block() {
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1436
        appendStatement(new BlockStatement(line, getBlock(true)));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1437
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1438
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1439
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1440
     * StatementList :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1441
     *      Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1442
     *      StatementList Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1443
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1444
     * See 12.1
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1445
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1446
     * Parse a list of statements.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1447
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1448
    private void statementList() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1449
        // Accumulate statements until end of list. */
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1450
        loop:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1451
        while (type != EOF) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1452
            switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1453
            case EOF:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1454
            case CASE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1455
            case DEFAULT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1456
            case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1457
                break loop;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1458
            default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1459
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1460
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1461
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1462
            // Get next statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1463
            statement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1464
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1465
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1466
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1467
    /**
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1468
     * Make sure that the identifier name used is allowed.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1469
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1470
     * @param ident         Identifier that is verified
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1471
     * @param contextString String used in error message to give context to the user
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1472
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1473
    private void verifyIdent(final IdentNode ident, final String contextString) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1474
        verifyStrictIdent(ident, contextString);
47337
079a87f87518 8027302: Identifiers containing unicode escapes are not recognized as reserved words
hannesw
parents: 47287
diff changeset
  1475
        checkEscapedKeyword(ident);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1476
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1477
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1478
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1479
     * Make sure that in strict mode, the identifier name used is allowed.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1480
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1481
     * @param ident         Identifier that is verified
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1482
     * @param contextString String used in error message to give context to the user
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1483
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1484
    private void verifyStrictIdent(final IdentNode ident, final String contextString) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1485
        if (isStrictMode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1486
            switch (ident.getName()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1487
            case "eval":
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1488
            case "arguments":
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1489
                throw error(AbstractParser.message("strict.name", ident.getName(), contextString), ident.getToken());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1490
            default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1491
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1492
            }
20571
f52b0abf5d88 8026039: future strict names are allowed as function name and argument name of a strict function
sundar
parents: 20559
diff changeset
  1493
f52b0abf5d88 8026039: future strict names are allowed as function name and argument name of a strict function
sundar
parents: 20559
diff changeset
  1494
            if (ident.isFutureStrictName()) {
f52b0abf5d88 8026039: future strict names are allowed as function name and argument name of a strict function
sundar
parents: 20559
diff changeset
  1495
                throw error(AbstractParser.message("strict.name", ident.getName(), contextString), ident.getToken());
f52b0abf5d88 8026039: future strict names are allowed as function name and argument name of a strict function
sundar
parents: 20559
diff changeset
  1496
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1497
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1498
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1499
47337
079a87f87518 8027302: Identifiers containing unicode escapes are not recognized as reserved words
hannesw
parents: 47287
diff changeset
  1500
    /**
079a87f87518 8027302: Identifiers containing unicode escapes are not recognized as reserved words
hannesw
parents: 47287
diff changeset
  1501
     * ES6 11.6.2: A code point in a ReservedWord cannot be expressed by a | UnicodeEscapeSequence.
079a87f87518 8027302: Identifiers containing unicode escapes are not recognized as reserved words
hannesw
parents: 47287
diff changeset
  1502
     */
079a87f87518 8027302: Identifiers containing unicode escapes are not recognized as reserved words
hannesw
parents: 47287
diff changeset
  1503
    private void checkEscapedKeyword(final IdentNode ident) {
079a87f87518 8027302: Identifiers containing unicode escapes are not recognized as reserved words
hannesw
parents: 47287
diff changeset
  1504
        if (isES6() && ident.containsEscapes()) {
079a87f87518 8027302: Identifiers containing unicode escapes are not recognized as reserved words
hannesw
parents: 47287
diff changeset
  1505
            final TokenType tokenType = TokenLookup.lookupKeyword(ident.getName().toCharArray(), 0, ident.getName().length());
079a87f87518 8027302: Identifiers containing unicode escapes are not recognized as reserved words
hannesw
parents: 47287
diff changeset
  1506
            if (tokenType != IDENT && !(tokenType.getKind() == TokenKind.FUTURESTRICT && !isStrictMode)) {
079a87f87518 8027302: Identifiers containing unicode escapes are not recognized as reserved words
hannesw
parents: 47287
diff changeset
  1507
                throw error(AbstractParser.message("keyword.escaped.character"), ident.getToken());
079a87f87518 8027302: Identifiers containing unicode escapes are not recognized as reserved words
hannesw
parents: 47287
diff changeset
  1508
            }
079a87f87518 8027302: Identifiers containing unicode escapes are not recognized as reserved words
hannesw
parents: 47287
diff changeset
  1509
        }
079a87f87518 8027302: Identifiers containing unicode escapes are not recognized as reserved words
hannesw
parents: 47287
diff changeset
  1510
    }
079a87f87518 8027302: Identifiers containing unicode escapes are not recognized as reserved words
hannesw
parents: 47287
diff changeset
  1511
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1512
    /*
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1513
     * VariableStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1514
     *      var VariableDeclarationList ;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1515
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1516
     * VariableDeclarationList :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1517
     *      VariableDeclaration
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1518
     *      VariableDeclarationList , VariableDeclaration
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1519
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1520
     * VariableDeclaration :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1521
     *      Identifier Initializer?
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1522
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1523
     * Initializer :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1524
     *      = AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1525
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1526
     * See 12.2
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1527
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1528
     * Parse a VAR statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1529
     * @param isStatement True if a statement (not used in a FOR.)
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1530
     */
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1531
    private void variableStatement(final TokenType varType) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1532
        variableDeclarationList(varType, true, -1);
29539
b2a8fb583979 8075448: nashorn parser API returns init variable tree object of a for loop after for loop statement tree object
sundar
parents: 29407
diff changeset
  1533
    }
b2a8fb583979 8075448: nashorn parser API returns init variable tree object of a for loop after for loop statement tree object
sundar
parents: 29407
diff changeset
  1534
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1535
    private static final class ForVariableDeclarationListResult {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1536
        /** First missing const or binding pattern initializer. */
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1537
        Expression missingAssignment;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1538
        /** First declaration with an initializer. */
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1539
        long declarationWithInitializerToken;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1540
        /** Destructuring assignments. */
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1541
        Expression init;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1542
        Expression firstBinding;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1543
        Expression secondBinding;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1544
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1545
        void recordMissingAssignment(final Expression binding) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1546
            if (missingAssignment == null) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1547
                missingAssignment = binding;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1548
            }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1549
        }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1550
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1551
        void recordDeclarationWithInitializer(final long token) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1552
            if (declarationWithInitializerToken == 0L) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1553
                declarationWithInitializerToken = token;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1554
            }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1555
        }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1556
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1557
        void addBinding(final Expression binding) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1558
            if (firstBinding == null) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1559
                firstBinding = binding;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1560
            } else if (secondBinding == null)  {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1561
                secondBinding = binding;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1562
            }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1563
            // ignore the rest
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1564
        }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1565
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1566
        void addAssignment(final Expression assignment) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1567
            if (init == null) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1568
                init = assignment;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1569
            } else {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1570
                init = new BinaryNode(Token.recast(init.getToken(), COMMARIGHT), init, assignment);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1571
            }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1572
        }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1573
    }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1574
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1575
    /**
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1576
     * @param isStatement {@code true} if a VariableStatement, {@code false} if a {@code for} loop VariableDeclarationList
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1577
     */
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1578
    private ForVariableDeclarationListResult variableDeclarationList(final TokenType varType, final boolean isStatement, final int sourceOrder) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1579
        // VAR tested in caller.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1580
        assert varType == VAR || varType == LET || varType == CONST;
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  1581
        final int varLine = line;
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  1582
        final long varToken = token;
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  1583
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1584
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1585
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  1586
        int varFlags = 0;
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1587
        if (varType == LET) {
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1588
            varFlags |= VarNode.IS_LET;
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1589
        } else if (varType == CONST) {
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1590
            varFlags |= VarNode.IS_CONST;
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1591
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1592
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1593
        final ForVariableDeclarationListResult forResult = isStatement ? null : new ForVariableDeclarationListResult();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1594
        while (true) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1595
            // Get name of var.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1596
            if (type == YIELD && inGeneratorFunction()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1597
                expect(IDENT);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1598
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1599
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1600
            final String contextString = "variable name";
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1601
            final Expression binding = bindingIdentifierOrPattern(contextString);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1602
            final boolean isDestructuring = !(binding instanceof IdentNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1603
            if (isDestructuring) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1604
                final int finalVarFlags = varFlags;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1605
                verifyDestructuringBindingPattern(binding, new Consumer<IdentNode>() {
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  1606
                    @Override
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1607
                    public void accept(final IdentNode identNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1608
                        verifyIdent(identNode, contextString);
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  1609
                        if (!env._parse_only) {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  1610
                            // don't bother adding a variable if we are just parsing!
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  1611
                            final VarNode var = new VarNode(varLine, varToken, sourceOrder, identNode.getFinish(), identNode.setIsDeclaredHere(), null, finalVarFlags);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  1612
                            appendStatement(var);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  1613
                        }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1614
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1615
                });
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1616
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1617
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1618
            // Assume no init.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1619
            Expression init = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1620
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1621
            // Look for initializer assignment.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1622
            if (type == ASSIGN) {
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1623
                if (!isStatement) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1624
                    forResult.recordDeclarationWithInitializer(varToken);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1625
                }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1626
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1627
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1628
                // Get initializer expression. Suppress IN if not statement.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1629
                if (!isDestructuring) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1630
                    defaultNames.push(binding);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1631
                }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1632
                try {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1633
                    init = assignmentExpression(!isStatement);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1634
                } finally {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1635
                    if (!isDestructuring) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1636
                        defaultNames.pop();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1637
                    }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1638
                }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1639
            } else if (isStatement) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1640
                if (isDestructuring) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1641
                    throw error(AbstractParser.message("missing.destructuring.assignment"), token);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1642
                } else if (varType == CONST) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1643
                    throw error(AbstractParser.message("missing.const.assignment", ((IdentNode)binding).getName()));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1644
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1645
                // else, if we are in a for loop, delay checking until we know the kind of loop
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1646
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1647
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1648
            if (!isDestructuring) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1649
                assert init != null || varType != CONST || !isStatement;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1650
                final IdentNode ident = (IdentNode)binding;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1651
                if (!isStatement && ident.getName().equals("let")) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1652
                    throw error(AbstractParser.message("let.binding.for")); //ES6 13.7.5.1
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1653
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1654
                // Only set declaration flag on lexically scoped let/const as it adds runtime overhead.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1655
                final IdentNode name = varType == LET || varType == CONST ? ident.setIsDeclaredHere() : ident;
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1656
                if (!isStatement) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1657
                    if (init == null && varType == CONST) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1658
                        forResult.recordMissingAssignment(name);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1659
                    }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1660
                    forResult.addBinding(new IdentNode(name));
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1661
                }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1662
                final VarNode var = new VarNode(varLine, varToken, sourceOrder, finish, name, init, varFlags);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1663
                appendStatement(var);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1664
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1665
                assert init != null || !isStatement;
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1666
                if (init != null) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1667
                    final Expression assignment = verifyAssignment(Token.recast(varToken, ASSIGN), binding, init);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1668
                    if (isStatement) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1669
                        appendStatement(new ExpressionStatement(varLine, assignment.getToken(), finish, assignment, varType));
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1670
                    } else {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1671
                        forResult.addAssignment(assignment);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1672
                        forResult.addBinding(assignment);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1673
                    }
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1674
                } else if (!isStatement) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1675
                    forResult.recordMissingAssignment(binding);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1676
                    forResult.addBinding(binding);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1677
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1678
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1679
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1680
            if (type != COMMARIGHT) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1681
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1682
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1683
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1684
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1685
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1686
        // If is a statement then handle end of line.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1687
        if (isStatement) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1688
            endOfLine();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1689
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1690
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1691
        return forResult;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1692
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1693
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1694
    private boolean isBindingIdentifier() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1695
        return type == IDENT || isNonStrictModeIdent();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1696
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1697
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1698
    private IdentNode bindingIdentifier(final String contextString) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1699
        final IdentNode name = getIdent();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1700
        verifyIdent(name, contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1701
        return name;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1702
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1703
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1704
    private Expression bindingPattern() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1705
        if (type == LBRACKET) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1706
            return arrayLiteral();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1707
        } else if (type == LBRACE) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1708
            return objectLiteral();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1709
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1710
            throw error(AbstractParser.message("expected.binding"));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1711
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1712
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1713
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1714
    private Expression bindingIdentifierOrPattern(final String contextString) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1715
        if (isBindingIdentifier() || !isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1716
            return bindingIdentifier(contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1717
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1718
            return bindingPattern();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1719
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1720
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1721
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1722
    private abstract class VerifyDestructuringPatternNodeVisitor extends NodeVisitor<LexicalContext> {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1723
        VerifyDestructuringPatternNodeVisitor(final LexicalContext lc) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1724
            super(lc);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1725
        }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1726
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1727
        @Override
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1728
        public boolean enterLiteralNode(final LiteralNode<?> literalNode) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1729
            if (literalNode.isArray()) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1730
                if (((LiteralNode.ArrayLiteralNode)literalNode).hasSpread() && ((LiteralNode.ArrayLiteralNode)literalNode).hasTrailingComma()) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1731
                    throw error("Rest element must be last", literalNode.getElementExpressions().get(literalNode.getElementExpressions().size() - 1).getToken());
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1732
                }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1733
                boolean restElement = false;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1734
                for (final Expression element : literalNode.getElementExpressions()) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1735
                    if (element != null) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1736
                        if (restElement) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1737
                            throw error("Unexpected element after rest element", element.getToken());
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1738
                        }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1739
                        if (element.isTokenType(SPREAD_ARRAY)) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1740
                            restElement = true;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1741
                            final Expression lvalue = ((UnaryNode) element).getExpression();
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1742
                            verifySpreadElement(lvalue);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1743
                        }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1744
                        element.accept(this);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1745
                    }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1746
                }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1747
                return false;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1748
            } else {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1749
                return enterDefault(literalNode);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1750
            }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1751
        }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1752
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1753
        protected abstract void verifySpreadElement(Expression lvalue);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1754
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1755
        @Override
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1756
        public boolean enterObjectNode(final ObjectNode objectNode) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1757
            return true;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1758
        }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1759
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1760
        @Override
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1761
        public boolean enterPropertyNode(final PropertyNode propertyNode) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1762
            if (propertyNode.getValue() != null) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1763
                propertyNode.getValue().accept(this);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1764
                return false;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1765
            } else {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1766
                return enterDefault(propertyNode);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1767
            }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1768
        }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1769
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1770
        @Override
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1771
        public boolean enterBinaryNode(final BinaryNode binaryNode) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1772
            if (binaryNode.isTokenType(ASSIGN)) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1773
                binaryNode.lhs().accept(this);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1774
                // Initializer(rhs) can be any AssignmentExpression
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1775
                return false;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1776
            } else {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1777
                return enterDefault(binaryNode);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1778
            }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1779
        }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1780
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1781
        @Override
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1782
        public boolean enterUnaryNode(final UnaryNode unaryNode) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1783
            if (unaryNode.isTokenType(SPREAD_ARRAY)) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1784
                // rest element
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1785
                return true;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1786
            } else {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1787
                return enterDefault(unaryNode);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1788
            }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1789
        }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1790
    }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1791
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1792
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1793
     * Verify destructuring variable declaration binding pattern and extract bound variable declarations.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1794
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1795
    private void verifyDestructuringBindingPattern(final Expression pattern, final Consumer<IdentNode> identifierCallback) {
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1796
        assert (pattern instanceof BinaryNode && pattern.isTokenType(ASSIGN)) ||
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  1797
                pattern instanceof ObjectNode || pattern instanceof LiteralNode.ArrayLiteralNode;
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1798
        pattern.accept(new VerifyDestructuringPatternNodeVisitor(new LexicalContext()) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1799
            @Override
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1800
            protected void verifySpreadElement(final Expression lvalue) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1801
                if (lvalue instanceof IdentNode) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1802
                    // checked in identifierCallback
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1803
                } else if (isDestructuringLhs(lvalue)) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1804
                    verifyDestructuringBindingPattern(lvalue, identifierCallback);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1805
                } else {
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1806
                    throw error("Expected a valid binding identifier", lvalue.getToken());
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1807
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1808
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1809
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1810
            @Override
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1811
            public boolean enterIdentNode(final IdentNode identNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1812
                identifierCallback.accept(identNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1813
                return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1814
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1815
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1816
            @Override
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1817
            protected boolean enterDefault(final Node node) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1818
                throw error(String.format("unexpected node in BindingPattern: %s", node));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1819
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1820
        });
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1821
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1822
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1823
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1824
     * EmptyStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1825
     *      ;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1826
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1827
     * See 12.3
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1828
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1829
     * Parse an empty statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1830
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1831
    private void emptyStatement() {
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
  1832
        if (env._empty_statements) {
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  1833
            appendStatement(new EmptyNode(line, token, Token.descPosition(token) + Token.descLength(token)));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1834
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1835
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1836
        // SEMICOLON checked in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1837
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1838
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1839
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1840
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1841
     * ExpressionStatement :
37924
a78497edf9fb 8156714: Parsing issue with automatic semicolon insertion
hannesw
parents: 37923
diff changeset
  1842
     *      Expression ; // [lookahead ~({ or  function )]
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1843
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1844
     * See 12.4
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1845
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1846
     * Parse an expression used in a statement block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1847
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1848
    private void expressionStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1849
        // Lookahead checked in caller.
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  1850
        final int  expressionLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1851
        final long expressionToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1852
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1853
        // Get expression and add as statement.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1854
        final Expression expression = expression();
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1855
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1856
        if (expression != null) {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  1857
            final ExpressionStatement expressionStatement = new ExpressionStatement(expressionLine, expressionToken, finish, expression);
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1858
            appendStatement(expressionStatement);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1859
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1860
            expect(null);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1861
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1862
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1863
        endOfLine();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1864
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1865
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1866
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1867
     * IfStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1868
     *      if ( Expression ) Statement else Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1869
     *      if ( Expression ) Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1870
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1871
     * See 12.5
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1872
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1873
     * Parse an IF statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1874
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1875
    private void ifStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1876
        // Capture IF token.
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  1877
        final int  ifLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1878
        final long ifToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1879
         // IF tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1880
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1881
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1882
        expect(LPAREN);
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1883
        final Expression test = expression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1884
        expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1885
        final Block pass = getStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1886
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1887
        Block fail = null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1888
        if (type == ELSE) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1889
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1890
            fail = getStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1891
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1892
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  1893
        appendStatement(new IfNode(ifLine, ifToken, fail != null ? fail.getFinish() : pass.getFinish(), test, pass, fail));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1894
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1895
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1896
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1897
     * ... IterationStatement:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1898
     *           ...
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1899
     *           for ( Expression[NoIn]?; Expression? ; Expression? ) Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1900
     *           for ( var VariableDeclarationList[NoIn]; Expression? ; Expression? ) Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1901
     *           for ( LeftHandSideExpression in Expression ) Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1902
     *           for ( var VariableDeclaration[NoIn] in Expression ) Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1903
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1904
     * See 12.6
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1905
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1906
     * Parse a FOR statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1907
     */
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1908
    @SuppressWarnings("fallthrough")
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1909
    private void forStatement() {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  1910
        final long forToken = token;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  1911
        final int forLine = line;
29539
b2a8fb583979 8075448: nashorn parser API returns init variable tree object of a for loop after for loop statement tree object
sundar
parents: 29407
diff changeset
  1912
        // start position of this for statement. This is used
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  1913
        // for sort order for variables declared in the initializer
29539
b2a8fb583979 8075448: nashorn parser API returns init variable tree object of a for loop after for loop statement tree object
sundar
parents: 29407
diff changeset
  1914
        // part of this 'for' statement (if any).
b2a8fb583979 8075448: nashorn parser API returns init variable tree object of a for loop after for loop statement tree object
sundar
parents: 29407
diff changeset
  1915
        final int forStart = Token.descPosition(forToken);
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1916
        // When ES6 for-let is enabled we create a container block to capture the LET.
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  1917
        final ParserContextBlockNode outer = useBlockScope() ? newBlock() : null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  1918
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1919
        // Create FOR node, capturing FOR token.
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  1920
        final ParserContextLoopNode forNode = new ParserContextLoopNode();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1921
        lc.push(forNode);
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  1922
        Block body = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  1923
        Expression init = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  1924
        JoinPredecessorExpression test = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  1925
        JoinPredecessorExpression modify = null;
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1926
        ForVariableDeclarationListResult varDeclList = null;
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  1927
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  1928
        int flags = 0;
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1929
        boolean isForOf = false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1930
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1931
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1932
            // FOR tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1933
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1934
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1935
            // Nashorn extension: for each expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1936
            // iterate property values rather than property names.
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
  1937
            if (!env._no_syntax_extensions && type == IDENT && "each".equals(getValue())) {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  1938
                flags |= ForNode.IS_FOR_EACH;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1939
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1940
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1941
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1942
            expect(LPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1943
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1944
            TokenType varType = null;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1945
            switch (type) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1946
            case VAR:
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  1947
                // Var declaration captured in for outer block.
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1948
                varDeclList = variableDeclarationList(varType = type, false, forStart);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1949
                break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1950
            case SEMICOLON:
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1951
                break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1952
            default:
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1953
                if (useBlockScope() && (type == LET && lookaheadIsLetDeclaration(true) || type == CONST)) {
36691
56a7257458e7 8151811: Const declarations do not work in for..in loops
hannesw
parents: 36690
diff changeset
  1954
                    flags |= ForNode.PER_ITERATION_SCOPE;
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  1955
                    // LET/CONST declaration captured in container block created above.
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1956
                    varDeclList = variableDeclarationList(varType = type, false, forStart);
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1957
                    break;
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1958
                }
24279
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
  1959
                if (env._const_as_var && type == CONST) {
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  1960
                    // Var declaration captured in for outer block.
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1961
                    varDeclList = variableDeclarationList(varType = TokenType.VAR, false, forStart);
24279
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
  1962
                    break;
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
  1963
                }
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
  1964
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  1965
                init = expression(unaryExpression(), COMMARIGHT.getPrecedence(), true);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1966
                break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1967
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1968
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1969
            switch (type) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1970
            case SEMICOLON:
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1971
                // for (init; test; modify)
41924
d55f24e8953e 8156619: Unimplemented ES6 features should result in clear Error being thrown
hannesw
parents: 41425
diff changeset
  1972
                if (varDeclList != null) {
d55f24e8953e 8156619: Unimplemented ES6 features should result in clear Error being thrown
hannesw
parents: 41425
diff changeset
  1973
                    assert init == null;
d55f24e8953e 8156619: Unimplemented ES6 features should result in clear Error being thrown
hannesw
parents: 41425
diff changeset
  1974
                    init = varDeclList.init;
d55f24e8953e 8156619: Unimplemented ES6 features should result in clear Error being thrown
hannesw
parents: 41425
diff changeset
  1975
                    // late check for missing assignment, now we know it's a for (init; test; modify) loop
d55f24e8953e 8156619: Unimplemented ES6 features should result in clear Error being thrown
hannesw
parents: 41425
diff changeset
  1976
                    if (varDeclList.missingAssignment != null) {
d55f24e8953e 8156619: Unimplemented ES6 features should result in clear Error being thrown
hannesw
parents: 41425
diff changeset
  1977
                        if (varDeclList.missingAssignment instanceof IdentNode) {
d55f24e8953e 8156619: Unimplemented ES6 features should result in clear Error being thrown
hannesw
parents: 41425
diff changeset
  1978
                            throw error(AbstractParser.message("missing.const.assignment", ((IdentNode)varDeclList.missingAssignment).getName()));
d55f24e8953e 8156619: Unimplemented ES6 features should result in clear Error being thrown
hannesw
parents: 41425
diff changeset
  1979
                        } else {
d55f24e8953e 8156619: Unimplemented ES6 features should result in clear Error being thrown
hannesw
parents: 41425
diff changeset
  1980
                            throw error(AbstractParser.message("missing.destructuring.assignment"), varDeclList.missingAssignment.getToken());
d55f24e8953e 8156619: Unimplemented ES6 features should result in clear Error being thrown
hannesw
parents: 41425
diff changeset
  1981
                        }
d55f24e8953e 8156619: Unimplemented ES6 features should result in clear Error being thrown
hannesw
parents: 41425
diff changeset
  1982
                    }
d55f24e8953e 8156619: Unimplemented ES6 features should result in clear Error being thrown
hannesw
parents: 41425
diff changeset
  1983
                }
18843
eea6d1b8263e 8019805: for each (init; test; modify) is invalid
sundar
parents: 18632
diff changeset
  1984
eea6d1b8263e 8019805: for each (init; test; modify) is invalid
sundar
parents: 18632
diff changeset
  1985
                // for each (init; test; modify) is invalid
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  1986
                if ((flags & ForNode.IS_FOR_EACH) != 0) {
18843
eea6d1b8263e 8019805: for each (init; test; modify) is invalid
sundar
parents: 18632
diff changeset
  1987
                    throw error(AbstractParser.message("for.each.without.in"), token);
eea6d1b8263e 8019805: for each (init; test; modify) is invalid
sundar
parents: 18632
diff changeset
  1988
                }
eea6d1b8263e 8019805: for each (init; test; modify) is invalid
sundar
parents: 18632
diff changeset
  1989
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1990
                expect(SEMICOLON);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1991
                if (type != SEMICOLON) {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  1992
                    test = joinPredecessorExpression();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1993
                }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1994
                expect(SEMICOLON);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1995
                if (type != RPAREN) {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  1996
                    modify = joinPredecessorExpression();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1997
                }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1998
                break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1999
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  2000
            case IDENT:
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  2001
                if (env._es6 && "of".equals(getValue())) {
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  2002
                    isForOf = true;
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  2003
                    // fall through
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  2004
                } else {
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  2005
                    expect(SEMICOLON); // fail with expected message
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  2006
                    break;
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  2007
                }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2008
            case IN:
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  2009
                flags |= isForOf ? ForNode.IS_FOR_OF : ForNode.IS_FOR_IN;
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2010
                test = new JoinPredecessorExpression();
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2011
                if (varDeclList != null) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2012
                    // for (var|let|const ForBinding in|of expression)
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2013
                    if (varDeclList.secondBinding != null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2014
                        // for (var i, j in obj) is invalid
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2015
                        throw error(AbstractParser.message("many.vars.in.for.in.loop", isForOf ? "of" : "in"), varDeclList.secondBinding.getToken());
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2016
                    }
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2017
                    if (varDeclList.declarationWithInitializerToken != 0 && (isStrictMode || type != TokenType.IN || varType != VAR || varDeclList.init != null)) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2018
                        // ES5 legacy: for (var i = AssignmentExpressionNoIn in Expression)
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2019
                        // Invalid in ES6, but allow it in non-strict mode if no ES6 features used,
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2020
                        // i.e., error if strict, for-of, let/const, or destructuring
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2021
                        throw error(AbstractParser.message("for.in.loop.initializer", isForOf ? "of" : "in"), varDeclList.declarationWithInitializerToken);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2022
                    }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2023
                    init = varDeclList.firstBinding;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2024
                    assert init instanceof IdentNode || isDestructuringLhs(init);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2025
                } else {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2026
                    // for (expr in obj)
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  2027
                    assert init != null : "for..in/of init expression can not be null here";
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2028
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2029
                    // check if initial expression is a valid L-value
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2030
                    if (!checkValidLValue(init, isForOf ? "for-of iterator" : "for-in iterator")) {
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  2031
                        throw error(AbstractParser.message("not.lvalue.for.in.loop", isForOf ? "of" : "in"), init.getToken());
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2032
                    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2033
                }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2034
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2035
                next();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2036
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  2037
                // For-of only allows AssignmentExpression.
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  2038
                modify = isForOf ? new JoinPredecessorExpression(assignmentExpression(false)) : joinPredecessorExpression();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2039
                break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2040
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2041
            default:
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2042
                expect(SEMICOLON);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2043
                break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2044
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2045
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2046
            expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2047
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2048
            // Set the for body.
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2049
            body = getStatement();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2050
        } finally {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2051
            lc.pop(forNode);
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2052
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2053
            for (final Statement var : forNode.getStatements()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2054
                assert var instanceof VarNode;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2055
                appendStatement(var);
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2056
            }
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2057
            if (body != null) {
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2058
                appendStatement(new ForNode(forLine, forToken, body.getFinish(), body, (forNode.getFlags() | flags), init, test, modify));
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2059
            }
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2060
            if (outer != null) {
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2061
                restoreBlock(outer);
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2062
                if (body != null) {
47262
bbbf1b1e36e9 8185257: Nashorn AST is missing nodes when a for-loop contains a VariableDeclarationList
sdama
parents: 47216
diff changeset
  2063
                    List<Statement> statements = new ArrayList<>();
bbbf1b1e36e9 8185257: Nashorn AST is missing nodes when a for-loop contains a VariableDeclarationList
sdama
parents: 47216
diff changeset
  2064
                    for (final Statement var : outer.getStatements()) {
bbbf1b1e36e9 8185257: Nashorn AST is missing nodes when a for-loop contains a VariableDeclarationList
sdama
parents: 47216
diff changeset
  2065
                        if(var instanceof VarNode && !((VarNode)var).isBlockScoped()) {
bbbf1b1e36e9 8185257: Nashorn AST is missing nodes when a for-loop contains a VariableDeclarationList
sdama
parents: 47216
diff changeset
  2066
                            appendStatement(var);
bbbf1b1e36e9 8185257: Nashorn AST is missing nodes when a for-loop contains a VariableDeclarationList
sdama
parents: 47216
diff changeset
  2067
                        }else {
bbbf1b1e36e9 8185257: Nashorn AST is missing nodes when a for-loop contains a VariableDeclarationList
sdama
parents: 47216
diff changeset
  2068
                            statements.add(var);
bbbf1b1e36e9 8185257: Nashorn AST is missing nodes when a for-loop contains a VariableDeclarationList
sdama
parents: 47216
diff changeset
  2069
                        }
bbbf1b1e36e9 8185257: Nashorn AST is missing nodes when a for-loop contains a VariableDeclarationList
sdama
parents: 47216
diff changeset
  2070
                    }
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2071
                    appendStatement(new BlockStatement(forLine, new Block(
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2072
                                    outer.getToken(),
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2073
                                    body.getFinish(),
47262
bbbf1b1e36e9 8185257: Nashorn AST is missing nodes when a for-loop contains a VariableDeclarationList
sdama
parents: 47216
diff changeset
  2074
                                    statements)));
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2075
                }
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2076
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2077
        }
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  2078
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2079
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2080
    private boolean checkValidLValue(final Expression init, final String contextString) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2081
        if (init instanceof IdentNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2082
            if (!checkIdentLValue((IdentNode)init)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2083
                return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2084
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2085
            verifyIdent((IdentNode)init, contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2086
            return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2087
        } else if (init instanceof AccessNode || init instanceof IndexNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2088
            return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2089
        } else if (isDestructuringLhs(init)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2090
            verifyDestructuringAssignmentPattern(init, contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2091
            return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2092
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2093
            return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2094
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2095
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2096
38485
8c55199bc96b 8157241: Remove javac warnings of Nashorn "ant clean test"
sundar
parents: 37924
diff changeset
  2097
    @SuppressWarnings("fallthrough")
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2098
    private boolean lookaheadIsLetDeclaration(final boolean ofContextualKeyword) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2099
        assert type == LET;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2100
        for (int i = 1;; i++) {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  2101
            final TokenType t = T(k + i);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2102
            switch (t) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2103
            case EOL:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2104
            case COMMENT:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2105
                continue;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2106
            case IDENT:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2107
                if (ofContextualKeyword && isES6() && "of".equals(getValue(getToken(k + i)))) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2108
                    return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2109
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2110
                // fall through
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2111
            case LBRACKET:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2112
            case LBRACE:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2113
                return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2114
            default:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2115
                // accept future strict tokens in non-strict mode (including LET)
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2116
                if (!isStrictMode && t.getKind() == TokenKind.FUTURESTRICT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2117
                    return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2118
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2119
                return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2120
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2121
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2122
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2123
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2124
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2125
     * ...IterationStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2126
     *           ...
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2127
     *           while ( Expression ) Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2128
     *           ...
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2129
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2130
     * See 12.6
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2131
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2132
     * Parse while statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2133
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2134
    private void whileStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2135
        // Capture WHILE token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2136
        final long whileToken = token;
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2137
        final int whileLine = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2138
        // WHILE tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2139
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2140
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2141
        final ParserContextLoopNode whileNode = new ParserContextLoopNode();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2142
        lc.push(whileNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2143
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2144
        JoinPredecessorExpression test = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2145
        Block body = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2146
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2147
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2148
            expect(LPAREN);
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2149
            test = joinPredecessorExpression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2150
            expect(RPAREN);
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2151
            body = getStatement();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2152
        } finally {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2153
            lc.pop(whileNode);
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2154
        }
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2155
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2156
        if (body != null) {
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2157
            appendStatement(new WhileNode(whileLine, whileToken, body.getFinish(), false, test, body));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2158
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2159
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2160
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2161
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2162
     * ...IterationStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2163
     *           ...
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2164
     *           do Statement while( Expression ) ;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2165
     *           ...
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2166
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2167
     * See 12.6
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2168
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2169
     * Parse DO WHILE statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2170
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2171
    private void doStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2172
        // Capture DO token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2173
        final long doToken = token;
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2174
        int doLine = 0;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2175
        // DO tested in the caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2176
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2177
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2178
        final ParserContextLoopNode doWhileNode = new ParserContextLoopNode();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2179
        lc.push(doWhileNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2180
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2181
        Block body = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2182
        JoinPredecessorExpression test = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2183
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2184
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2185
           // Get DO body.
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2186
            body = getStatement();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2187
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2188
            expect(WHILE);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2189
            expect(LPAREN);
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2190
            doLine = line;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2191
            test = joinPredecessorExpression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2192
            expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2193
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2194
            if (type == SEMICOLON) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2195
                endOfLine();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2196
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2197
        } finally {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2198
            lc.pop(doWhileNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2199
        }
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2200
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2201
        appendStatement(new WhileNode(doLine, doToken, finish, true, test, body));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2202
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2203
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2204
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2205
     * ContinueStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2206
     *      continue Identifier? ; // [no LineTerminator here]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2207
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2208
     * See 12.7
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2209
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2210
     * Parse CONTINUE statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2211
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2212
    private void continueStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2213
        // Capture CONTINUE token.
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  2214
        final int  continueLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2215
        final long continueToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2216
        // CONTINUE tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2217
        nextOrEOL();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2218
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2219
        ParserContextLabelNode labelNode = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2220
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2221
        // SEMICOLON or label.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2222
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2223
        case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2224
        case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2225
        case EOL:
18625
13558072545a 8019473: Parser issues related to functions and blocks
sundar
parents: 18335
diff changeset
  2226
        case EOF:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2227
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2228
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2229
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2230
            final IdentNode ident = getIdent();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2231
            labelNode = lc.findLabel(ident.getName());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2232
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2233
            if (labelNode == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2234
                throw error(AbstractParser.message("undefined.label", ident.getName()), ident.getToken());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2235
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2236
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2237
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2238
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2239
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2240
        final String labelName = labelNode == null ? null : labelNode.getLabelName();
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2241
        final ParserContextLoopNode targetNode = lc.getContinueTo(labelName);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2242
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2243
        if (targetNode == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2244
            throw error(AbstractParser.message("illegal.continue.stmt"), continueToken);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2245
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2246
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2247
        endOfLine();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2248
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2249
        // Construct and add CONTINUE node.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2250
        appendStatement(new ContinueNode(continueLine, continueToken, finish, labelName));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2251
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2252
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2253
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2254
     * BreakStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2255
     *      break Identifier? ; // [no LineTerminator here]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2256
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2257
     * See 12.8
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2258
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2259
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2260
    private void breakStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2261
        // Capture BREAK token.
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  2262
        final int  breakLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2263
        final long breakToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2264
        // BREAK tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2265
        nextOrEOL();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2266
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2267
        ParserContextLabelNode labelNode = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2268
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2269
        // SEMICOLON or label.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2270
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2271
        case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2272
        case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2273
        case EOL:
18625
13558072545a 8019473: Parser issues related to functions and blocks
sundar
parents: 18335
diff changeset
  2274
        case EOF:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2275
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2276
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2277
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2278
            final IdentNode ident = getIdent();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2279
            labelNode = lc.findLabel(ident.getName());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2280
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2281
            if (labelNode == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2282
                throw error(AbstractParser.message("undefined.label", ident.getName()), ident.getToken());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2283
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2284
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2285
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2286
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2287
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2288
        //either an explicit label - then get its node or just a "break" - get first breakable
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2289
        //targetNode is what we are breaking out from.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2290
        final String labelName = labelNode == null ? null : labelNode.getLabelName();
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2291
        final ParserContextBreakableNode targetNode = lc.getBreakable(labelName);
47038
f57fa7f112a0 8177691: Labeled break in catch and finally works wrongly, when invoked through nashorn
sdama
parents: 46169
diff changeset
  2292
f57fa7f112a0 8177691: Labeled break in catch and finally works wrongly, when invoked through nashorn
sdama
parents: 46169
diff changeset
  2293
        if( targetNode instanceof ParserContextBlockNode) {
f57fa7f112a0 8177691: Labeled break in catch and finally works wrongly, when invoked through nashorn
sdama
parents: 46169
diff changeset
  2294
            targetNode.setFlag(Block.IS_BREAKABLE);
f57fa7f112a0 8177691: Labeled break in catch and finally works wrongly, when invoked through nashorn
sdama
parents: 46169
diff changeset
  2295
        }
f57fa7f112a0 8177691: Labeled break in catch and finally works wrongly, when invoked through nashorn
sdama
parents: 46169
diff changeset
  2296
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2297
        if (targetNode == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2298
            throw error(AbstractParser.message("illegal.break.stmt"), breakToken);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2299
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2300
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2301
        endOfLine();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2302
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2303
        // Construct and add BREAK node.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2304
        appendStatement(new BreakNode(breakLine, breakToken, finish, labelName));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2305
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2306
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2307
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2308
     * ReturnStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2309
     *      return Expression? ; // [no LineTerminator here]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2310
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2311
     * See 12.9
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2312
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2313
     * Parse RETURN statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2314
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2315
    private void returnStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2316
        // check for return outside function
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2317
        if (lc.getCurrentFunction().getKind() == FunctionNode.Kind.SCRIPT || lc.getCurrentFunction().getKind() == FunctionNode.Kind.MODULE) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2318
            throw error(AbstractParser.message("invalid.return"));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2319
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2320
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2321
        // Capture RETURN token.
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  2322
        final int  returnLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2323
        final long returnToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2324
        // RETURN tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2325
        nextOrEOL();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2326
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2327
        Expression expression = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2328
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2329
        // SEMICOLON or expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2330
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2331
        case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2332
        case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2333
        case EOL:
18625
13558072545a 8019473: Parser issues related to functions and blocks
sundar
parents: 18335
diff changeset
  2334
        case EOF:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2335
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2336
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2337
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2338
            expression = expression();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2339
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2340
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2341
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2342
        endOfLine();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2343
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2344
        // Construct and add RETURN node.
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  2345
        appendStatement(new ReturnNode(returnLine, returnToken, finish, expression));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2346
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2347
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2348
    /**
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2349
     * Parse YieldExpression.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2350
     *
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2351
     * YieldExpression[In] :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2352
     *   yield
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2353
     *   yield [no LineTerminator here] AssignmentExpression[?In, Yield]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2354
     *   yield [no LineTerminator here] * AssignmentExpression[?In, Yield]
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2355
     */
38485
8c55199bc96b 8157241: Remove javac warnings of Nashorn "ant clean test"
sundar
parents: 37924
diff changeset
  2356
    @SuppressWarnings("fallthrough")
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2357
    private Expression yieldExpression(final boolean noIn) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2358
        assert inGeneratorFunction();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2359
        // Capture YIELD token.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2360
        long yieldToken = token;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2361
        // YIELD tested in caller.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2362
        assert type == YIELD;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2363
        nextOrEOL();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2364
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2365
        Expression expression = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2366
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2367
        boolean yieldAsterisk = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2368
        if (type == MUL) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2369
            yieldAsterisk = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2370
            yieldToken = Token.recast(yieldToken, YIELD_STAR);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2371
            next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2372
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2373
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2374
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2375
        case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2376
        case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2377
        case EOL:
18625
13558072545a 8019473: Parser issues related to functions and blocks
sundar
parents: 18335
diff changeset
  2378
        case EOF:
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2379
        case COMMARIGHT:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2380
        case RPAREN:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2381
        case RBRACKET:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2382
        case COLON:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2383
            if (!yieldAsterisk) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2384
                // treat (yield) as (yield void 0)
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2385
                expression = newUndefinedLiteral(yieldToken, finish);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2386
                if (type == EOL) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2387
                    next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2388
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2389
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2390
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2391
                // AssignmentExpression required, fall through
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2392
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2393
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2394
        default:
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2395
            expression = assignmentExpression(noIn);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2396
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2397
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2398
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2399
        // Construct and add YIELD node.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2400
        return new UnaryNode(yieldToken, expression);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2401
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2402
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2403
    private static UnaryNode newUndefinedLiteral(final long token, final int finish) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2404
        return new UnaryNode(Token.recast(token, VOID), LiteralNode.newInstance(token, finish, 0));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2405
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2406
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2407
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2408
     * WithStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2409
     *      with ( Expression ) Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2410
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2411
     * See 12.10
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2412
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2413
     * Parse WITH statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2414
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2415
    private void withStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2416
        // Capture WITH token.
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  2417
        final int  withLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2418
        final long withToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2419
        // WITH tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2420
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2421
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2422
        // ECMA 12.10.1 strict mode restrictions
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2423
        if (isStrictMode) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2424
            throw error(AbstractParser.message("strict.no.with"), withToken);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2425
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2426
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2427
        expect(LPAREN);
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2428
        final Expression expression = expression();
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2429
        expect(RPAREN);
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2430
        final Block body = getStatement();
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2431
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2432
        appendStatement(new WithNode(withLine, withToken, finish, expression, body));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2433
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2434
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2435
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2436
     * SwitchStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2437
     *      switch ( Expression ) CaseBlock
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2438
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2439
     * CaseBlock :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2440
     *      { CaseClauses? }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2441
     *      { CaseClauses? DefaultClause CaseClauses }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2442
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2443
     * CaseClauses :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2444
     *      CaseClause
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2445
     *      CaseClauses CaseClause
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2446
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2447
     * CaseClause :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2448
     *      case Expression : StatementList?
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2449
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2450
     * DefaultClause :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2451
     *      default : StatementList?
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2452
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2453
     * See 12.11
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2454
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2455
     * Parse SWITCH statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2456
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2457
    private void switchStatement() {
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  2458
        final int  switchLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2459
        final long switchToken = token;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2460
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2461
        // Block to capture variables declared inside the switch statement.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2462
        final ParserContextBlockNode switchBlock = newBlock();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2463
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2464
        // SWITCH tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2465
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2466
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2467
        // Create and add switch statement.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2468
        final ParserContextSwitchNode switchNode = new ParserContextSwitchNode();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2469
        lc.push(switchNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2470
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2471
        CaseNode defaultCase = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2472
        // Prepare to accumulate cases.
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2473
        final List<CaseNode> cases = new ArrayList<>();
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2474
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2475
        Expression expression = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2476
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2477
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2478
            expect(LPAREN);
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2479
            expression = expression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2480
            expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2481
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2482
            expect(LBRACE);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2483
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2484
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2485
            while (type != RBRACE) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2486
                // Prepare for next case.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2487
                Expression caseExpression = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2488
                final long caseToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2489
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2490
                switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2491
                case CASE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2492
                    next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2493
                    caseExpression = expression();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2494
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2495
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2496
                case DEFAULT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2497
                    if (defaultCase != null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2498
                        throw error(AbstractParser.message("duplicate.default.in.switch"));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2499
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2500
                    next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2501
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2502
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2503
                default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2504
                    // Force an error.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2505
                    expect(CASE);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2506
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2507
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2508
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2509
                expect(COLON);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2510
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2511
                // Get CASE body.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2512
                final Block statements = getBlock(false); // TODO: List<Statement> statements = caseStatementList();
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  2513
                final CaseNode caseNode = new CaseNode(caseToken, finish, caseExpression, statements);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2514
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2515
                if (caseExpression == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2516
                    defaultCase = caseNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2517
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2518
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2519
                cases.add(caseNode);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2520
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2521
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2522
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2523
        } finally {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2524
            lc.pop(switchNode);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2525
            restoreBlock(switchBlock);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2526
        }
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2527
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2528
        final SwitchNode switchStatement = new SwitchNode(switchLine, switchToken, finish, expression, cases, defaultCase);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2529
        appendStatement(new BlockStatement(switchLine, new Block(switchToken, finish, switchBlock.getFlags() | Block.IS_SYNTHETIC | Block.IS_SWITCH_BLOCK, switchStatement)));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2530
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2531
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2532
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2533
     * LabelledStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2534
     *      Identifier : Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2535
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2536
     * See 12.12
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2537
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2538
     * Parse label statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2539
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2540
    private void labelStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2541
        // Capture label token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2542
        final long labelToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2543
        // Get label ident.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2544
        final IdentNode ident = getIdent();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2545
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2546
        expect(COLON);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2547
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2548
        if (lc.findLabel(ident.getName()) != null) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2549
            throw error(AbstractParser.message("duplicate.label", ident.getName()), labelToken);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2550
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2551
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2552
        final ParserContextLabelNode labelNode = new ParserContextLabelNode(ident.getName());
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2553
        Block body = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2554
        try {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2555
            lc.push(labelNode);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2556
            body = getStatement(true);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2557
        } finally {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2558
            assert lc.peek() instanceof ParserContextLabelNode;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2559
            lc.pop(labelNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2560
        }
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2561
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2562
        appendStatement(new LabelNode(line, labelToken, finish, ident.getName(), body));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2563
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2564
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  2565
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2566
     * ThrowStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2567
     *      throw Expression ; // [no LineTerminator here]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2568
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2569
     * See 12.13
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2570
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2571
     * Parse throw statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2572
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2573
    private void throwStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2574
        // Capture THROW token.
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  2575
        final int  throwLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2576
        final long throwToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2577
        // THROW tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2578
        nextOrEOL();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2579
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2580
        Expression expression = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2581
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2582
        // SEMICOLON or expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2583
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2584
        case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2585
        case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2586
        case EOL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2587
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2588
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2589
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2590
            expression = expression();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2591
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2592
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2593
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2594
        if (expression == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2595
            throw error(AbstractParser.message("expected.operand", type.getNameOrType()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2596
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2597
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2598
        endOfLine();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2599
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2600
        appendStatement(new ThrowNode(throwLine, throwToken, finish, expression, false));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2601
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2602
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2603
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2604
     * TryStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2605
     *      try Block Catch
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2606
     *      try Block Finally
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2607
     *      try Block Catch Finally
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2608
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2609
     * Catch :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2610
     *      catch( Identifier if Expression ) Block
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2611
     *      catch( Identifier ) Block
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2612
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2613
     * Finally :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2614
     *      finally Block
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2615
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2616
     * See 12.14
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2617
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2618
     * Parse TRY statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2619
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2620
    private void tryStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2621
        // Capture TRY token.
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  2622
        final int  tryLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2623
        final long tryToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2624
        // TRY tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2625
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2626
16239
fbae49f786c6 8008215: break in catch clause causes java.lang.VerifyError: Inconsistent stackmap
hannesw
parents: 16237
diff changeset
  2627
        // Container block needed to act as target for labeled break statements
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2628
        final int startLine = line;
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2629
        final ParserContextBlockNode outer = newBlock();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2630
        // Create try.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2631
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2632
        try {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2633
            final Block       tryBody     = getBlock(true);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2634
            final List<Block> catchBlocks = new ArrayList<>();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2635
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2636
            while (type == CATCH) {
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  2637
                final int  catchLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2638
                final long catchToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2639
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2640
                expect(LPAREN);
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  2641
41983
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2642
                // ES6 catch parameter can be a BindingIdentifier or a BindingPattern
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  2643
                // http://www.ecma-international.org/ecma-262/6.0/
41983
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2644
                final String contextString = "catch argument";
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2645
                final Expression exception = bindingIdentifierOrPattern(contextString);
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2646
                final boolean isDestructuring = !(exception instanceof IdentNode);
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2647
                if (isDestructuring) {
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2648
                    verifyDestructuringBindingPattern(exception, new Consumer<IdentNode>() {
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2649
                        @Override
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2650
                        public void accept(final IdentNode identNode) {
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2651
                            verifyIdent(identNode, contextString);
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2652
                        }
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2653
                    });
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2654
                } else {
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2655
                    // ECMA 12.4.1 strict mode restrictions
47337
079a87f87518 8027302: Identifiers containing unicode escapes are not recognized as reserved words
hannesw
parents: 47287
diff changeset
  2656
                    verifyIdent((IdentNode) exception, "catch argument");
41983
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2657
                }
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2658
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2659
23766
a3ef17770bab 8039047: Parser accepts conditional catch clauses even when --no-syntax-extensions / -nse option is passed
sundar
parents: 23372
diff changeset
  2660
                // Nashorn extension: catch clause can have optional
a3ef17770bab 8039047: Parser accepts conditional catch clauses even when --no-syntax-extensions / -nse option is passed
sundar
parents: 23372
diff changeset
  2661
                // condition. So, a single try can have more than one
a3ef17770bab 8039047: Parser accepts conditional catch clauses even when --no-syntax-extensions / -nse option is passed
sundar
parents: 23372
diff changeset
  2662
                // catch clause each with it's own condition.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2663
                final Expression ifExpression;
23766
a3ef17770bab 8039047: Parser accepts conditional catch clauses even when --no-syntax-extensions / -nse option is passed
sundar
parents: 23372
diff changeset
  2664
                if (!env._no_syntax_extensions && type == IF) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2665
                    next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2666
                    // Get the exception condition.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2667
                    ifExpression = expression();
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2668
                } else {
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2669
                    ifExpression = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2670
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2671
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2672
                expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2673
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2674
                final ParserContextBlockNode catchBlock = newBlock();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2675
                try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2676
                    // Get CATCH body.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2677
                    final Block catchBody = getBlock(true);
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2678
                    final CatchNode catchNode = new CatchNode(catchLine, catchToken, finish, exception, ifExpression, catchBody, false);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2679
                    appendStatement(catchNode);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2680
                } finally {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2681
                    restoreBlock(catchBlock);
29407
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
  2682
                    catchBlocks.add(new Block(catchBlock.getToken(), finish, catchBlock.getFlags() | Block.IS_SYNTHETIC, catchBlock.getStatements()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2683
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2684
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2685
                // If unconditional catch then should to be the end.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2686
                if (ifExpression == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2687
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2688
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2689
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2690
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2691
            // Prepare to capture finally statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2692
            Block finallyStatements = null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2693
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2694
            if (type == FINALLY) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2695
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2696
                finallyStatements = getBlock(true);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2697
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2698
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2699
            // Need at least one catch or a finally.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2700
            if (catchBlocks.isEmpty() && finallyStatements == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2701
                throw error(AbstractParser.message("missing.catch.or.finally"), tryToken);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2702
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2703
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2704
            final TryNode tryNode = new TryNode(tryLine, tryToken, finish, tryBody, catchBlocks, finallyStatements);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2705
            // Add try.
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2706
            assert lc.peek() == outer;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2707
            appendStatement(tryNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2708
        } finally {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2709
            restoreBlock(outer);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2710
        }
16239
fbae49f786c6 8008215: break in catch clause causes java.lang.VerifyError: Inconsistent stackmap
hannesw
parents: 16237
diff changeset
  2711
29407
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
  2712
        appendStatement(new BlockStatement(startLine, new Block(tryToken, finish, outer.getFlags() | Block.IS_SYNTHETIC, outer.getStatements())));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2713
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2714
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2715
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2716
     * DebuggerStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2717
     *      debugger ;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2718
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2719
     * See 12.15
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2720
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2721
     * Parse debugger statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2722
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2723
    private void  debuggerStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2724
        // Capture DEBUGGER token.
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  2725
        final int  debuggerLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2726
        final long debuggerToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2727
        // DEBUGGER tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2728
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2729
        endOfLine();
29407
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
  2730
        appendStatement(new DebuggerNode(debuggerLine, debuggerToken, finish));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2731
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2732
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2733
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2734
     * PrimaryExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2735
     *      this
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2736
     *      IdentifierReference
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2737
     *      Literal
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2738
     *      ArrayLiteral
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2739
     *      ObjectLiteral
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  2740
     *      RegularExpressionLiteral
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  2741
     *      TemplateLiteral
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2742
     *      CoverParenthesizedExpressionAndArrowParameterList
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2743
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2744
     * CoverParenthesizedExpressionAndArrowParameterList :
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2745
     *      ( Expression )
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2746
     *      ( )
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2747
     *      ( ... BindingIdentifier )
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2748
     *      ( Expression , ... BindingIdentifier )
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2749
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2750
     * Parse primary expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2751
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2752
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2753
    @SuppressWarnings("fallthrough")
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2754
    private Expression primaryExpression() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2755
        // Capture first token.
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  2756
        final int  primaryLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2757
        final long primaryToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2758
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2759
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2760
        case THIS:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2761
            final String name = type.getName();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2762
            next();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2763
            markThis(lc);
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  2764
            return new IdentNode(primaryToken, finish, name);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2765
        case IDENT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2766
            final IdentNode ident = getIdent();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2767
            if (ident == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2768
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2769
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2770
            detectSpecialProperty(ident);
47337
079a87f87518 8027302: Identifiers containing unicode escapes are not recognized as reserved words
hannesw
parents: 47287
diff changeset
  2771
            checkEscapedKeyword(ident);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2772
            return ident;
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
  2773
        case OCTAL_LEGACY:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2774
            if (isStrictMode) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2775
               throw error(AbstractParser.message("strict.no.octal"), token);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2776
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2777
        case STRING:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2778
        case ESCSTRING:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2779
        case DECIMAL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2780
        case HEXADECIMAL:
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
  2781
        case OCTAL:
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
  2782
        case BINARY_NUMBER:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2783
        case FLOATING:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2784
        case REGEX:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2785
        case XML:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2786
            return getLiteral();
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2787
        case EXECSTRING:
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  2788
            return execString(primaryLine, primaryToken);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2789
        case FALSE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2790
            next();
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  2791
            return LiteralNode.newInstance(primaryToken, finish, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2792
        case TRUE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2793
            next();
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  2794
            return LiteralNode.newInstance(primaryToken, finish, true);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2795
        case NULL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2796
            next();
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  2797
            return LiteralNode.newInstance(primaryToken, finish);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2798
        case LBRACKET:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2799
            return arrayLiteral();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2800
        case LBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2801
            return objectLiteral();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2802
        case LPAREN:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2803
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2804
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2805
            if (isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2806
                if (type == RPAREN) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2807
                    // ()
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2808
                    nextOrEOL();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2809
                    expectDontAdvance(ARROW);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2810
                    return new ExpressionList(primaryToken, finish, Collections.emptyList());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2811
                } else if (type == ELLIPSIS) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2812
                    // (...rest)
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2813
                    final IdentNode restParam = formalParameterList(false).get(0);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2814
                    expectDontAdvance(RPAREN);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2815
                    nextOrEOL();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2816
                    expectDontAdvance(ARROW);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2817
                    return new ExpressionList(primaryToken, finish, Collections.singletonList(restParam));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2818
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2819
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2820
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2821
            final Expression expression = expression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2822
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2823
            expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2824
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2825
            return expression;
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  2826
        case TEMPLATE:
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  2827
        case TEMPLATE_HEAD:
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  2828
            return templateLiteral();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2829
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2830
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2831
            // In this context some operator tokens mark the start of a literal.
18870
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
  2832
            if (lexer.scanLiteral(primaryToken, type, lineInfoReceiver)) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2833
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2834
                return getLiteral();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2835
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2836
            if (isNonStrictModeIdent()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2837
                return getIdent();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2838
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2839
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2840
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2841
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2842
        return null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2843
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2844
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2845
    /**
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2846
     * Convert execString to a call to $EXEC.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2847
     *
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2848
     * @param primaryToken Original string token.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2849
     * @return callNode to $EXEC.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2850
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2851
    CallNode execString(final int primaryLine, final long primaryToken) {
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2852
        // Synthesize an ident to call $EXEC.
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  2853
        final IdentNode execIdent = new IdentNode(primaryToken, finish, ScriptingFunctions.EXEC_NAME);
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2854
        // Skip over EXECSTRING.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2855
        next();
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2856
        // Set up argument list for call.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2857
        // Skip beginning of edit string expression.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2858
        expect(LBRACE);
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2859
        // Add the following expression to arguments.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2860
        final List<Expression> arguments = Collections.singletonList(expression());
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2861
        // Skip ending of edit string expression.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2862
        expect(RBRACE);
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2863
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2864
        return new CallNode(primaryLine, primaryToken, finish, execIdent, arguments, false);
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2865
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2866
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2867
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2868
     * ArrayLiteral :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2869
     *      [ Elision? ]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2870
     *      [ ElementList ]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2871
     *      [ ElementList , Elision? ]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2872
     *      [ expression for (LeftHandExpression in expression) ( (if ( Expression ) )? ]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2873
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2874
     * ElementList : Elision? AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2875
     *      ElementList , Elision? AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2876
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2877
     * Elision :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2878
     *      ,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2879
     *      Elision ,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2880
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2881
     * See 12.1.4
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2882
     * JavaScript 1.8
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2883
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2884
     * Parse array literal.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2885
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2886
     */
38485
8c55199bc96b 8157241: Remove javac warnings of Nashorn "ant clean test"
sundar
parents: 37924
diff changeset
  2887
    @SuppressWarnings("fallthrough")
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2888
    private LiteralNode<Expression[]> arrayLiteral() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2889
        // Capture LBRACKET token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2890
        final long arrayToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2891
        // LBRACKET tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2892
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2893
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2894
        // Prepare to accumulate elements.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2895
        final List<Expression> elements = new ArrayList<>();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2896
        // Track elisions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2897
        boolean elision = true;
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2898
        boolean hasSpread = false;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2899
        loop:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2900
        while (true) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2901
            long spreadToken = 0;
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2902
            switch (type) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2903
            case RBRACKET:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2904
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2905
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2906
                break loop;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2907
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2908
            case COMMARIGHT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2909
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2910
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2911
                // If no prior expression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2912
                if (elision) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2913
                    elements.add(null);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2914
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2915
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2916
                elision = true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2917
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2918
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2919
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2920
            case ELLIPSIS:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2921
                if (isES6()) {
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2922
                    hasSpread = true;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2923
                    spreadToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2924
                    next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2925
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2926
                // fall through
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2927
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2928
            default:
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2929
                if (!elision) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2930
                    throw error(AbstractParser.message("expected.comma", type.getNameOrType()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2931
                }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2932
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2933
                // Add expression element.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2934
                Expression expression = assignmentExpression(false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2935
                if (expression != null) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2936
                    if (spreadToken != 0) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2937
                        expression = new UnaryNode(Token.recast(spreadToken, SPREAD_ARRAY), expression);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2938
                    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2939
                    elements.add(expression);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2940
                } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2941
                    expect(RBRACKET);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2942
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2943
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2944
                elision = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2945
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2946
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2947
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2948
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2949
        return LiteralNode.newInstance(arrayToken, finish, elements, hasSpread, elision);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2950
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2951
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2952
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2953
     * ObjectLiteral :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2954
     *      { }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2955
     *      { PropertyNameAndValueList } { PropertyNameAndValueList , }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2956
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2957
     * PropertyNameAndValueList :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2958
     *      PropertyAssignment
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2959
     *      PropertyNameAndValueList , PropertyAssignment
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2960
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2961
     * See 11.1.5
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2962
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2963
     * Parse an object literal.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2964
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2965
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2966
    private ObjectNode objectLiteral() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2967
        // Capture LBRACE token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2968
        final long objectToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2969
        // LBRACE tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2970
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2971
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2972
        // Object context.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2973
        // Prepare to accumulate elements.
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2974
        final List<PropertyNode> elements = new ArrayList<>();
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2975
        final Map<String, Integer> map = new HashMap<>();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2976
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2977
        // Create a block for the object literal.
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2978
        boolean commaSeen = true;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2979
        loop:
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2980
        while (true) {
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2981
            switch (type) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2982
                case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2983
                    next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2984
                    break loop;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2985
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2986
                case COMMARIGHT:
18629
6b0b6aab4280 8019508: Comma handling in object literal parsing is wrong
sundar
parents: 18625
diff changeset
  2987
                    if (commaSeen) {
6b0b6aab4280 8019508: Comma handling in object literal parsing is wrong
sundar
parents: 18625
diff changeset
  2988
                        throw error(AbstractParser.message("expected.property.id", type.getNameOrType()));
6b0b6aab4280 8019508: Comma handling in object literal parsing is wrong
sundar
parents: 18625
diff changeset
  2989
                    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2990
                    next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2991
                    commaSeen = true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2992
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2993
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2994
                default:
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2995
                    if (!commaSeen) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2996
                        throw error(AbstractParser.message("expected.comma", type.getNameOrType()));
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2997
                    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2998
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2999
                    commaSeen = false;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3000
                    // Get and add the next property.
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3001
                    final PropertyNode property = propertyAssignment();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3002
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3003
                    if (property.isComputed()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3004
                        elements.add(property);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3005
                        break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3006
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3007
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3008
                    final String key = property.getKeyName();
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  3009
                    final Integer existing = map.get(key);
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  3010
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  3011
                    if (existing == null) {
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  3012
                        map.put(key, elements.size());
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  3013
                        elements.add(property);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3014
                        break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3015
                    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3016
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  3017
                    final PropertyNode existingProperty = elements.get(existing);
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  3018
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  3019
                    // ECMA section 11.1.5 Object Initialiser
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  3020
                    // point # 4 on property assignment production
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3021
                    final Expression   value  = property.getValue();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3022
                    final FunctionNode getter = property.getGetter();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3023
                    final FunctionNode setter = property.getSetter();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3024
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3025
                    final Expression   prevValue  = existingProperty.getValue();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3026
                    final FunctionNode prevGetter = existingProperty.getGetter();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3027
                    final FunctionNode prevSetter = existingProperty.getSetter();
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  3028
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3029
                    if (!isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3030
                        checkPropertyRedefinition(property, value, getter, setter, prevValue, prevGetter, prevSetter);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3031
                    } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3032
                        if (property.getKey() instanceof IdentNode && ((IdentNode)property.getKey()).isProtoPropertyName() &&
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3033
                                        existingProperty.getKey() instanceof IdentNode && ((IdentNode)existingProperty.getKey()).isProtoPropertyName()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3034
                            throw error(AbstractParser.message("multiple.proto.key"), property.getToken());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3035
                        }
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  3036
                    }
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  3037
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3038
                    if (value != null || prevValue != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3039
                        map.put(key, elements.size());
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  3040
                        elements.add(property);
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  3041
                    } else if (getter != null) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3042
                        assert prevGetter != null || prevSetter != null;
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  3043
                        elements.set(existing, existingProperty.setGetter(getter));
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  3044
                    } else if (setter != null) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3045
                        assert prevGetter != null || prevSetter != null;
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  3046
                        elements.set(existing, existingProperty.setSetter(setter));
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  3047
                    }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3048
                    break;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3049
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3050
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3051
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  3052
        return new ObjectNode(objectToken, finish, elements);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3053
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3054
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3055
    private void checkPropertyRedefinition(final PropertyNode property, final Expression value, final FunctionNode getter, final FunctionNode setter, final Expression prevValue, final FunctionNode prevGetter, final FunctionNode prevSetter) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3056
        // ECMA 11.1.5 strict mode restrictions
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3057
        if (isStrictMode && value != null && prevValue != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3058
            throw error(AbstractParser.message("property.redefinition", property.getKeyName()), property.getToken());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3059
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3060
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3061
        final boolean isPrevAccessor = prevGetter != null || prevSetter != null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3062
        final boolean isAccessor     = getter != null     || setter != null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3063
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3064
        // data property redefined as accessor property
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3065
        if (prevValue != null && isAccessor) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3066
            throw error(AbstractParser.message("property.redefinition", property.getKeyName()), property.getToken());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3067
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3068
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3069
        // accessor property redefined as data
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3070
        if (isPrevAccessor && value != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3071
            throw error(AbstractParser.message("property.redefinition", property.getKeyName()), property.getToken());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3072
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3073
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3074
        if (isAccessor && isPrevAccessor) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3075
            if (getter != null && prevGetter != null ||
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3076
                    setter != null && prevSetter != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3077
                throw error(AbstractParser.message("property.redefinition", property.getKeyName()), property.getToken());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3078
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3079
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3080
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3081
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3082
    /**
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3083
     * LiteralPropertyName :
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3084
     *      IdentifierName
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3085
     *      StringLiteral
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3086
     *      NumericLiteral
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3087
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3088
     * @return PropertyName node
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3089
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3090
    @SuppressWarnings("fallthrough")
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3091
    private PropertyKey literalPropertyName() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3092
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3093
        case IDENT:
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3094
            return getIdent().setIsPropertyName();
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
  3095
        case OCTAL_LEGACY:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3096
            if (isStrictMode) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3097
                throw error(AbstractParser.message("strict.no.octal"), token);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3098
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3099
        case STRING:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3100
        case ESCSTRING:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3101
        case DECIMAL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3102
        case HEXADECIMAL:
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
  3103
        case OCTAL:
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
  3104
        case BINARY_NUMBER:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3105
        case FLOATING:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3106
            return getLiteral();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3107
        default:
19883
aae0838ac6ee 8024255: When a keyword is used as object property name, the property can not be deleted
sundar
parents: 19472
diff changeset
  3108
            return getIdentifierName().setIsPropertyName();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3109
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3110
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3111
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3112
    /**
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3113
     * ComputedPropertyName :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3114
     *      AssignmentExpression
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3115
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3116
     * @return PropertyName node
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3117
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3118
    private Expression computedPropertyName() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3119
        expect(LBRACKET);
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  3120
        final Expression expression = assignmentExpression(false);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3121
        expect(RBRACKET);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3122
        return expression;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3123
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3124
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3125
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3126
     * PropertyName :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3127
     *      LiteralPropertyName
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3128
     *      ComputedPropertyName
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3129
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3130
     * @return PropertyName node
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3131
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3132
    private Expression propertyName() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3133
        if (type == LBRACKET && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3134
            return computedPropertyName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3135
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3136
            return (Expression)literalPropertyName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3137
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3138
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3139
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3140
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3141
     * PropertyAssignment :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3142
     *      PropertyName : AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3143
     *      get PropertyName ( ) { FunctionBody }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3144
     *      set PropertyName ( PropertySetParameterList ) { FunctionBody }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3145
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3146
     * PropertySetParameterList :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3147
     *      Identifier
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3148
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3149
     * PropertyName :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3150
     *      IdentifierName
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3151
     *      StringLiteral
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3152
     *      NumericLiteral
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3153
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3154
     * See 11.1.5
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3155
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3156
     * Parse an object literal property.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3157
     * @return Property or reference node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3158
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3159
    private PropertyNode propertyAssignment() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3160
        // Capture firstToken.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3161
        final long propertyToken = token;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3162
        final int  functionLine  = line;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3163
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3164
        final Expression propertyName;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3165
        final boolean isIdentifier;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3166
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3167
        boolean generator = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3168
        if (type == MUL && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3169
            generator = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3170
            next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3171
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3172
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3173
        final boolean computed = type == LBRACKET;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3174
        if (type == IDENT) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3175
            // Get IDENT.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3176
            final String ident = (String)expectValue(IDENT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3177
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3178
            if (type != COLON && (type != LPAREN || !isES6())) {
20938
e92d8249f60c 8026302: source representation of getter and setter methods is wrong
sundar
parents: 20934
diff changeset
  3179
                final long getSetToken = propertyToken;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3180
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3181
                switch (ident) {
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
  3182
                case GET_NAME:
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3183
                    final PropertyFunction getter = propertyGetterFunction(getSetToken, functionLine);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3184
                    return new PropertyNode(propertyToken, finish, getter.key, null, getter.functionNode, null, false, getter.computed);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3185
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
  3186
                case SET_NAME:
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3187
                    final PropertyFunction setter = propertySetterFunction(getSetToken, functionLine);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3188
                    return new PropertyNode(propertyToken, finish, setter.key, null, null, setter.functionNode, false, setter.computed);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3189
                default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3190
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3191
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3192
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3193
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3194
            isIdentifier = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3195
            IdentNode identNode = createIdentNode(propertyToken, finish, ident).setIsPropertyName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3196
            if (type == COLON && ident.equals("__proto__")) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3197
                identNode = identNode.setIsProtoPropertyName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3198
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3199
            propertyName = identNode;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3200
        } else {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3201
            isIdentifier = isNonStrictModeIdent();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3202
            propertyName = propertyName();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3203
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3204
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3205
        Expression propertyValue;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3206
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3207
        if (generator) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3208
            expectDontAdvance(LPAREN);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3209
        }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3210
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3211
        if (type == LPAREN && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3212
            propertyValue = propertyMethodFunction(propertyName, propertyToken, functionLine, generator, FunctionNode.ES6_IS_METHOD, computed).functionNode;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3213
        } else if (isIdentifier && (type == COMMARIGHT || type == RBRACE || type == ASSIGN) && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3214
            propertyValue = createIdentNode(propertyToken, finish, ((IdentNode) propertyName).getPropertyName());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3215
            if (type == ASSIGN && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3216
                // TODO if not destructuring, this is a SyntaxError
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3217
                final long assignToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3218
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3219
                final Expression rhs = assignmentExpression(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3220
                propertyValue = verifyAssignment(assignToken, propertyValue, rhs);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3221
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3222
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3223
            expect(COLON);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3224
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3225
            defaultNames.push(propertyName);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3226
            try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3227
                propertyValue = assignmentExpression(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3228
            } finally {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3229
                defaultNames.pop();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3230
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3231
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3232
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3233
        return new PropertyNode(propertyToken, finish, propertyName, propertyValue, null, null, false, computed);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3234
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3235
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3236
    private PropertyFunction propertyGetterFunction(final long getSetToken, final int functionLine) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3237
        return propertyGetterFunction(getSetToken, functionLine, FunctionNode.ES6_IS_METHOD);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3238
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3239
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3240
    private PropertyFunction propertyGetterFunction(final long getSetToken, final int functionLine, final int flags) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3241
        final boolean computed = type == LBRACKET;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3242
        final Expression propertyName = propertyName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3243
        final String getterName = propertyName instanceof PropertyKey ? ((PropertyKey) propertyName).getPropertyName() : getDefaultValidFunctionName(functionLine, false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3244
        final IdentNode getNameNode = createIdentNode((propertyName).getToken(), finish, NameCodec.encode("get " + getterName));
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3245
        expect(LPAREN);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3246
        expect(RPAREN);
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3247
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3248
        final ParserContextFunctionNode functionNode = createParserContextFunctionNode(getNameNode, getSetToken, FunctionNode.Kind.GETTER, functionLine, Collections.<IdentNode>emptyList());
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3249
        functionNode.setFlag(flags);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3250
        if (computed) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3251
            functionNode.setFlag(FunctionNode.IS_ANONYMOUS);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3252
        }
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3253
        lc.push(functionNode);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3254
27819
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3255
        Block functionBody;
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3256
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3257
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3258
        try {
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3259
            functionBody = functionBody(functionNode);
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3260
        } finally {
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3261
            lc.pop(functionNode);
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3262
        }
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3263
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3264
        final FunctionNode  function = createFunctionNode(
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3265
                functionNode,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3266
                getSetToken,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3267
                getNameNode,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3268
                Collections.<IdentNode>emptyList(),
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3269
                FunctionNode.Kind.GETTER,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3270
                functionLine,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3271
                functionBody);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3272
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3273
        return new PropertyFunction(propertyName, function, computed);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3274
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3275
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3276
    private PropertyFunction propertySetterFunction(final long getSetToken, final int functionLine) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3277
        return propertySetterFunction(getSetToken, functionLine, FunctionNode.ES6_IS_METHOD);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3278
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3279
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3280
    private PropertyFunction propertySetterFunction(final long getSetToken, final int functionLine, final int flags) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3281
        final boolean computed = type == LBRACKET;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3282
        final Expression propertyName = propertyName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3283
        final String setterName = propertyName instanceof PropertyKey ? ((PropertyKey) propertyName).getPropertyName() : getDefaultValidFunctionName(functionLine, false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3284
        final IdentNode setNameNode = createIdentNode((propertyName).getToken(), finish, NameCodec.encode("set " + setterName));
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3285
        expect(LPAREN);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3286
        // be sloppy and allow missing setter parameter even though
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3287
        // spec does not permit it!
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3288
        final IdentNode argIdent;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3289
        if (isBindingIdentifier()) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3290
            argIdent = getIdent();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3291
            verifyIdent(argIdent, "setter argument");
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3292
        } else {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3293
            argIdent = null;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3294
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3295
        expect(RPAREN);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3296
        final List<IdentNode> parameters = new ArrayList<>();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3297
        if (argIdent != null) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3298
            parameters.add(argIdent);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3299
        }
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3300
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3301
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3302
        final ParserContextFunctionNode functionNode = createParserContextFunctionNode(setNameNode, getSetToken, FunctionNode.Kind.SETTER, functionLine, parameters);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3303
        functionNode.setFlag(flags);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3304
        if (computed) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3305
            functionNode.setFlag(FunctionNode.IS_ANONYMOUS);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3306
        }
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3307
        lc.push(functionNode);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3308
27819
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3309
        Block functionBody;
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3310
        try {
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3311
            functionBody = functionBody(functionNode);
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3312
        } finally {
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3313
            lc.pop(functionNode);
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3314
        }
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3315
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3316
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3317
        final FunctionNode  function = createFunctionNode(
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3318
                functionNode,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3319
                getSetToken,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3320
                setNameNode,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3321
                parameters,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3322
                FunctionNode.Kind.SETTER,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3323
                functionLine,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3324
                functionBody);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3325
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3326
        return new PropertyFunction(propertyName, function, computed);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3327
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3328
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  3329
    private PropertyFunction propertyMethodFunction(final Expression key, final long methodToken, final int methodLine, final boolean generator, final int flags, final boolean computed) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3330
        final String methodName = key instanceof PropertyKey ? ((PropertyKey) key).getPropertyName() : getDefaultValidFunctionName(methodLine, false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3331
        final IdentNode methodNameNode = createIdentNode(((Node)key).getToken(), finish, methodName);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3332
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  3333
        final FunctionNode.Kind functionKind = generator ? FunctionNode.Kind.GENERATOR : FunctionNode.Kind.NORMAL;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3334
        final ParserContextFunctionNode functionNode = createParserContextFunctionNode(methodNameNode, methodToken, functionKind, methodLine, null);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3335
        functionNode.setFlag(flags);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3336
        if (computed) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3337
            functionNode.setFlag(FunctionNode.IS_ANONYMOUS);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3338
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3339
        lc.push(functionNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3340
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3341
        try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3342
            final ParserContextBlockNode parameterBlock = newBlock();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3343
            final List<IdentNode> parameters;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3344
            try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3345
                expect(LPAREN);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3346
                parameters = formalParameterList(generator);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3347
                functionNode.setParameters(parameters);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3348
                expect(RPAREN);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3349
            } finally {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3350
                restoreBlock(parameterBlock);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3351
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3352
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3353
            Block functionBody = functionBody(functionNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3354
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3355
            functionBody = maybeWrapBodyInParameterBlock(functionBody, parameterBlock);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3356
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3357
            final FunctionNode  function = createFunctionNode(
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3358
                            functionNode,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3359
                            methodToken,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3360
                            methodNameNode,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3361
                            parameters,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3362
                            functionKind,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3363
                            methodLine,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3364
                            functionBody);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3365
            return new PropertyFunction(key, function, computed);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3366
        } finally {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3367
            lc.pop(functionNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3368
        }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3369
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3370
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3371
    private static class PropertyFunction {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3372
        final Expression key;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3373
        final FunctionNode functionNode;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3374
        final boolean computed;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3375
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3376
        PropertyFunction(final Expression key, final FunctionNode function, final boolean computed) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3377
            this.key = key;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3378
            this.functionNode = function;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3379
            this.computed = computed;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3380
        }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3381
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3382
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3383
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3384
     * LeftHandSideExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3385
     *      NewExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3386
     *      CallExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3387
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3388
     * CallExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3389
     *      MemberExpression Arguments
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3390
     *      SuperCall
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3391
     *      CallExpression Arguments
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3392
     *      CallExpression [ Expression ]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3393
     *      CallExpression . IdentifierName
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3394
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3395
     * SuperCall :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3396
     *      super Arguments
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3397
     *
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3398
     * See 11.2
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3399
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3400
     * Parse left hand side expression.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3401
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3402
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3403
    private Expression leftHandSideExpression() {
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  3404
        int  callLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3405
        long callToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3406
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3407
        Expression lhs = memberExpression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3408
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3409
        if (type == LPAREN) {
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3410
            final List<Expression> arguments = optimizeList(argumentList());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3411
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3412
            // Catch special functions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3413
            if (lhs instanceof IdentNode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3414
                detectSpecialFunction((IdentNode)lhs);
47337
079a87f87518 8027302: Identifiers containing unicode escapes are not recognized as reserved words
hannesw
parents: 47287
diff changeset
  3415
                checkEscapedKeyword((IdentNode)lhs);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3416
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3417
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3418
            lhs = new CallNode(callLine, callToken, finish, lhs, arguments, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3419
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3420
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3421
        loop:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3422
        while (true) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3423
            // Capture token.
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  3424
            callLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3425
            callToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3426
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3427
            switch (type) {
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3428
            case LPAREN: {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3429
                // Get NEW or FUNCTION arguments.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3430
                final List<Expression> arguments = optimizeList(argumentList());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3431
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3432
                // Create call node.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3433
                lhs = new CallNode(callLine, callToken, finish, lhs, arguments, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3434
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3435
                break;
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3436
            }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3437
            case LBRACKET: {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3438
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3439
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3440
                // Get array index.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3441
                final Expression rhs = expression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3442
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3443
                expect(RBRACKET);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3444
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3445
                // Create indexing node.
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  3446
                lhs = new IndexNode(callToken, finish, lhs, rhs);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3447
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3448
                break;
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3449
            }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3450
            case PERIOD: {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3451
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3452
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3453
                final IdentNode property = getIdentifierName();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3454
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3455
                // Create property access node.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3456
                lhs = new AccessNode(callToken, finish, lhs, property.getName());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3457
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3458
                break;
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3459
            }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3460
            case TEMPLATE:
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3461
            case TEMPLATE_HEAD: {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3462
                // tagged template literal
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3463
                final List<Expression> arguments = templateLiteralArgumentList();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3464
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3465
                // Create call node.
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3466
                lhs = new CallNode(callLine, callToken, finish, lhs, arguments, false);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3467
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3468
                break;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3469
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3470
            default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3471
                break loop;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3472
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3473
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3474
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3475
        return lhs;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3476
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3477
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3478
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3479
     * NewExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3480
     *      MemberExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3481
     *      new NewExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3482
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3483
     * See 11.2
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3484
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3485
     * Parse new expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3486
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3487
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3488
    private Expression newExpression() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3489
        final long newToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3490
        // NEW is tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3491
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3492
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3493
        if (type == PERIOD && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3494
            next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3495
            if (type == IDENT && "target".equals(getValue())) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3496
                if (lc.getCurrentFunction().isProgram()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3497
                    throw error(AbstractParser.message("new.target.in.function"), token);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3498
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3499
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3500
                markNewTarget(lc);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3501
                return new IdentNode(newToken, finish, "new.target");
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3502
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3503
                throw error(AbstractParser.message("expected.target"), token);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3504
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3505
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3506
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3507
        // Get function base.
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  3508
        final int  callLine    = line;
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3509
        final Expression constructor = memberExpression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3510
        if (constructor == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3511
            return null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3512
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3513
        // Get arguments.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3514
        ArrayList<Expression> arguments;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3515
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3516
        // Allow for missing arguments.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3517
        if (type == LPAREN) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3518
            arguments = argumentList();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3519
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3520
            arguments = new ArrayList<>();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3521
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3522
16196
58f6f046bb5e 8006983: Introduce a command line option to switch off syntactic extensions of nashorn
sundar
parents: 16191
diff changeset
  3523
        // Nashorn extension: This is to support the following interface implementation
58f6f046bb5e 8006983: Introduce a command line option to switch off syntactic extensions of nashorn
sundar
parents: 16191
diff changeset
  3524
        // syntax:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3525
        //
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3526
        //     var r = new java.lang.Runnable() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3527
        //         run: function() { println("run"); }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3528
        //     };
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3529
        //
32534
b3ec7f3b3c2a 8136349: Typos patch for nashorn sources submitted on Sep 10, 2015
sundar
parents: 32444
diff changeset
  3530
        // The object literal following the "new Constructor()" expression
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3531
        // is passed as an additional (last) argument to the constructor.
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
  3532
        if (!env._no_syntax_extensions && type == LBRACE) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3533
            arguments.add(objectLiteral());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3534
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3535
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3536
        final CallNode callNode = new CallNode(callLine, constructor.getToken(), finish, constructor, optimizeList(arguments), true);
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  3537
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  3538
        return new UnaryNode(newToken, callNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3539
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3540
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3541
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3542
     * MemberExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3543
     *      PrimaryExpression
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3544
     *        FunctionExpression
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3545
     *        ClassExpression
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3546
     *        GeneratorExpression
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3547
     *      MemberExpression [ Expression ]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3548
     *      MemberExpression . IdentifierName
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3549
     *      MemberExpression TemplateLiteral
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3550
     *      SuperProperty
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3551
     *      MetaProperty
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3552
     *      new MemberExpression Arguments
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3553
     *
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3554
     * SuperProperty :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3555
     *      super [ Expression ]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3556
     *      super . IdentifierName
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3557
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3558
     * MetaProperty :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3559
     *      NewTarget
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3560
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3561
     * Parse member expression.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3562
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3563
     */
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3564
    @SuppressWarnings("fallthrough")
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3565
    private Expression memberExpression() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3566
        // Prepare to build operation.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3567
        Expression lhs;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3568
        boolean isSuper = false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3569
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3570
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3571
        case NEW:
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3572
            // Get new expression.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3573
            lhs = newExpression();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3574
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3575
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3576
        case FUNCTION:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3577
            // Get function expression.
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  3578
            lhs = functionExpression(false, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3579
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3580
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3581
        case CLASS:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3582
            if (isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3583
                lhs = classExpression(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3584
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3585
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3586
                // fall through
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3587
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3588
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3589
        case SUPER:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3590
            if (isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3591
                final ParserContextFunctionNode currentFunction = getCurrentNonArrowFunction();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3592
                if (currentFunction.isMethod()) {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  3593
                    final long identToken = Token.recast(token, IDENT);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3594
                    next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3595
                    lhs = createIdentNode(identToken, finish, SUPER.getName());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3596
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3597
                    switch (type) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3598
                        case LBRACKET:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3599
                        case PERIOD:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3600
                            getCurrentNonArrowFunction().setFlag(FunctionNode.ES6_USES_SUPER);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3601
                            isSuper = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3602
                            break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3603
                        case LPAREN:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3604
                            if (currentFunction.isSubclassConstructor()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3605
                                lhs = ((IdentNode)lhs).setIsDirectSuper();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3606
                                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3607
                            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3608
                                // fall through to throw error
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3609
                            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3610
                        default:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3611
                            throw error(AbstractParser.message("invalid.super"), identToken);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3612
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3613
                    break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3614
                } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3615
                    // fall through
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3616
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3617
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3618
                // fall through
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3619
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3620
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3621
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3622
            // Get primary expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3623
            lhs = primaryExpression();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3624
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3625
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3626
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3627
        loop:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3628
        while (true) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3629
            // Capture token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3630
            final long callToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3631
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3632
            switch (type) {
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  3633
            case LBRACKET: {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3634
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3635
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3636
                // Get array index.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3637
                final Expression index = expression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3638
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3639
                expect(RBRACKET);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3640
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3641
                // Create indexing node.
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  3642
                lhs = new IndexNode(callToken, finish, lhs, index);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3643
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3644
                if (isSuper) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3645
                    isSuper = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3646
                    lhs = ((BaseNode) lhs).setIsSuper();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3647
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3648
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3649
                break;
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  3650
            }
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  3651
            case PERIOD: {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3652
                if (lhs == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3653
                    throw error(AbstractParser.message("expected.operand", type.getNameOrType()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3654
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3655
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3656
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3657
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3658
                final IdentNode property = getIdentifierName();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3659
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3660
                // Create property access node.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3661
                lhs = new AccessNode(callToken, finish, lhs, property.getName());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3662
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3663
                if (isSuper) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3664
                    isSuper = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3665
                    lhs = ((BaseNode) lhs).setIsSuper();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3666
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3667
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3668
                break;
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  3669
            }
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3670
            case TEMPLATE:
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3671
            case TEMPLATE_HEAD: {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3672
                // tagged template literal
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3673
                final int callLine = line;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3674
                final List<Expression> arguments = templateLiteralArgumentList();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3675
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3676
                lhs = new CallNode(callLine, callToken, finish, lhs, arguments, false);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3677
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3678
                break;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3679
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3680
            default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3681
                break loop;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3682
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3683
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3684
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3685
        return lhs;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3686
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3687
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3688
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3689
     * Arguments :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3690
     *      ( )
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3691
     *      ( ArgumentList )
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3692
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3693
     * ArgumentList :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3694
     *      AssignmentExpression
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3695
     *      ... AssignmentExpression
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3696
     *      ArgumentList , AssignmentExpression
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3697
     *      ArgumentList , ... AssignmentExpression
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3698
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3699
     * See 11.2
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3700
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3701
     * Parse function call arguments.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3702
     * @return Argument list.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3703
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3704
    private ArrayList<Expression> argumentList() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3705
        // Prepare to accumulate list of arguments.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3706
        final ArrayList<Expression> nodeList = new ArrayList<>();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3707
        // LPAREN tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3708
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3709
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3710
        // Track commas.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3711
        boolean first = true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3712
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3713
        while (type != RPAREN) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3714
            // Comma prior to every argument except the first.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3715
            if (!first) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3716
                expect(COMMARIGHT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3717
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3718
                first = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3719
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3720
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3721
            long spreadToken = 0;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3722
            if (type == ELLIPSIS && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3723
                spreadToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3724
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3725
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3726
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3727
            // Get argument expression.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3728
            Expression expression = assignmentExpression(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3729
            if (spreadToken != 0) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3730
                expression = new UnaryNode(Token.recast(spreadToken, TokenType.SPREAD_ARGUMENT), expression);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3731
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3732
            nodeList.add(expression);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3733
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3734
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3735
        expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3736
        return nodeList;
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3737
    }
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3738
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
  3739
    private static <T> List<T> optimizeList(final ArrayList<T> list) {
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3740
        switch(list.size()) {
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3741
            case 0: {
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3742
                return Collections.emptyList();
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3743
            }
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3744
            case 1: {
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3745
                return Collections.singletonList(list.get(0));
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3746
            }
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3747
            default: {
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3748
                list.trimToSize();
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3749
                return list;
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3750
            }
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3751
        }
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3752
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3753
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3754
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3755
     * FunctionDeclaration :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3756
     *      function Identifier ( FormalParameterList? ) { FunctionBody }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3757
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3758
     * FunctionExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3759
     *      function Identifier? ( FormalParameterList? ) { FunctionBody }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3760
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3761
     * See 13
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3762
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3763
     * Parse function declaration.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3764
     * @param isStatement True if for is a statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3765
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3766
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3767
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3768
    private Expression functionExpression(final boolean isStatement, final boolean topLevel) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3769
        final long functionToken = token;
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  3770
        final int  functionLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3771
        // FUNCTION is tested in caller.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3772
        assert type == FUNCTION;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3773
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3774
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3775
        boolean generator = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3776
        if (type == MUL && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3777
            generator = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3778
            next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3779
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3780
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3781
        IdentNode name = null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3782
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3783
        if (isBindingIdentifier()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3784
            if (type == YIELD && ((!isStatement && generator) || (isStatement && inGeneratorFunction()))) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3785
                // 12.1.1 Early SyntaxError if:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3786
                // GeneratorExpression with BindingIdentifier yield
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3787
                // HoistableDeclaration with BindingIdentifier yield in generator function body
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3788
                expect(IDENT);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3789
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3790
            name = getIdent();
47337
079a87f87518 8027302: Identifiers containing unicode escapes are not recognized as reserved words
hannesw
parents: 47287
diff changeset
  3791
            verifyIdent(name, "function name");
16196
58f6f046bb5e 8006983: Introduce a command line option to switch off syntactic extensions of nashorn
sundar
parents: 16191
diff changeset
  3792
        } else if (isStatement) {
31095
790fc3d576f9 8085802: Nashorn -nse option causes parse error on anonymous function definition
sundar
parents: 30392
diff changeset
  3793
            // Nashorn extension: anonymous function statements.
790fc3d576f9 8085802: Nashorn -nse option causes parse error on anonymous function definition
sundar
parents: 30392
diff changeset
  3794
            // Do not allow anonymous function statement if extensions
790fc3d576f9 8085802: Nashorn -nse option causes parse error on anonymous function definition
sundar
parents: 30392
diff changeset
  3795
            // are now allowed. But if we are reparsing then anon function
790fc3d576f9 8085802: Nashorn -nse option causes parse error on anonymous function definition
sundar
parents: 30392
diff changeset
  3796
            // statement is possible - because it was used as function
790fc3d576f9 8085802: Nashorn -nse option causes parse error on anonymous function definition
sundar
parents: 30392
diff changeset
  3797
            // expression in surrounding code.
790fc3d576f9 8085802: Nashorn -nse option causes parse error on anonymous function definition
sundar
parents: 30392
diff changeset
  3798
            if (env._no_syntax_extensions && reparsedFunction == null) {
16196
58f6f046bb5e 8006983: Introduce a command line option to switch off syntactic extensions of nashorn
sundar
parents: 16191
diff changeset
  3799
                expect(IDENT);
58f6f046bb5e 8006983: Introduce a command line option to switch off syntactic extensions of nashorn
sundar
parents: 16191
diff changeset
  3800
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3801
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3802
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3803
        // name is null, generate anonymous name
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3804
        boolean isAnonymous = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3805
        if (name == null) {
27974
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3806
            final String tmpName = getDefaultValidFunctionName(functionLine, isStatement);
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  3807
            name = new IdentNode(functionToken, Token.descPosition(functionToken), tmpName);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3808
            isAnonymous = true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3809
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3810
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  3811
        final FunctionNode.Kind functionKind = generator ? FunctionNode.Kind.GENERATOR : FunctionNode.Kind.NORMAL;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3812
        List<IdentNode> parameters = Collections.emptyList();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3813
        final ParserContextFunctionNode functionNode = createParserContextFunctionNode(name, functionToken, functionKind, functionLine, parameters);
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3814
        lc.push(functionNode);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3815
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3816
        Block functionBody = null;
27974
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3817
        // Hide the current default name across function boundaries. E.g. "x3 = function x1() { function() {}}"
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3818
        // If we didn't hide the current default name, then the innermost anonymous function would receive "x3".
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3819
        hideDefaultName();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3820
        try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3821
            final ParserContextBlockNode parameterBlock = newBlock();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3822
            try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3823
                expect(LPAREN);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3824
                parameters = formalParameterList(generator);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3825
                functionNode.setParameters(parameters);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3826
                expect(RPAREN);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3827
            } finally {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3828
                restoreBlock(parameterBlock);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3829
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3830
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3831
            functionBody = functionBody(functionNode);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3832
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3833
            functionBody = maybeWrapBodyInParameterBlock(functionBody, parameterBlock);
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3834
        } finally {
27974
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3835
            defaultNames.pop();
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3836
            lc.pop(functionNode);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3837
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3838
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  3839
        if (isStatement) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3840
            if (topLevel || useBlockScope() || (!isStrictMode && env._function_statement == ScriptEnvironment.FunctionStatementBehavior.ACCEPT)) {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3841
                functionNode.setFlag(FunctionNode.IS_DECLARED);
17257
a2232050cd8f 8008814: Configurable ignore/warning/error behavior for function declaration as statement
attila
parents: 17255
diff changeset
  3842
            } else if (isStrictMode) {
a2232050cd8f 8008814: Configurable ignore/warning/error behavior for function declaration as statement
attila
parents: 17255
diff changeset
  3843
                throw error(JSErrorType.SYNTAX_ERROR, AbstractParser.message("strict.no.func.decl.here"), functionToken);
a2232050cd8f 8008814: Configurable ignore/warning/error behavior for function declaration as statement
attila
parents: 17255
diff changeset
  3844
            } else if (env._function_statement == ScriptEnvironment.FunctionStatementBehavior.ERROR) {
a2232050cd8f 8008814: Configurable ignore/warning/error behavior for function declaration as statement
attila
parents: 17255
diff changeset
  3845
                throw error(JSErrorType.SYNTAX_ERROR, AbstractParser.message("no.func.decl.here"), functionToken);
a2232050cd8f 8008814: Configurable ignore/warning/error behavior for function declaration as statement
attila
parents: 17255
diff changeset
  3846
            } else if (env._function_statement == ScriptEnvironment.FunctionStatementBehavior.WARNING) {
a2232050cd8f 8008814: Configurable ignore/warning/error behavior for function declaration as statement
attila
parents: 17255
diff changeset
  3847
                warning(JSErrorType.SYNTAX_ERROR, AbstractParser.message("no.func.decl.here.warn"), functionToken);
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  3848
            }
19898
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
  3849
            if (isArguments(name)) {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3850
               lc.getCurrentFunction().setFlag(FunctionNode.DEFINES_ARGUMENTS);
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
  3851
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3852
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3853
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3854
        if (isAnonymous) {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3855
            functionNode.setFlag(FunctionNode.IS_ANONYMOUS);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3856
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3857
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3858
        verifyParameterList(parameters, functionNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3859
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3860
        final FunctionNode function = createFunctionNode(
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3861
                functionNode,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3862
                functionToken,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3863
                name,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3864
                parameters,
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3865
                functionKind,
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3866
                functionLine,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3867
                functionBody);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3868
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3869
        if (isStatement) {
31485
be1acaee8e9e 8114838: Anonymous functions escape to surrounding scope when defined under "with" statement
sundar
parents: 31095
diff changeset
  3870
            if (isAnonymous) {
be1acaee8e9e 8114838: Anonymous functions escape to surrounding scope when defined under "with" statement
sundar
parents: 31095
diff changeset
  3871
                appendStatement(new ExpressionStatement(functionLine, functionToken, finish, function));
be1acaee8e9e 8114838: Anonymous functions escape to surrounding scope when defined under "with" statement
sundar
parents: 31095
diff changeset
  3872
                return function;
be1acaee8e9e 8114838: Anonymous functions escape to surrounding scope when defined under "with" statement
sundar
parents: 31095
diff changeset
  3873
            }
be1acaee8e9e 8114838: Anonymous functions escape to surrounding scope when defined under "with" statement
sundar
parents: 31095
diff changeset
  3874
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  3875
            // mark ES6 block functions as lexically scoped
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  3876
            final int     varFlags = (topLevel || !useBlockScope()) ? 0 : VarNode.IS_LET;
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  3877
            final VarNode varNode  = new VarNode(functionLine, functionToken, finish, name, function, varFlags);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3878
            if (topLevel) {
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  3879
                functionDeclarations.add(varNode);
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  3880
            } else if (useBlockScope()) {
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  3881
                prependStatement(varNode); // Hoist to beginning of current block
16191
7dd981da8e11 8006755: Functions inside with statements dont get correct scope
sundar
parents: 16187
diff changeset
  3882
            } else {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3883
                appendStatement(varNode);
16191
7dd981da8e11 8006755: Functions inside with statements dont get correct scope
sundar
parents: 16187
diff changeset
  3884
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3885
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3886
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3887
        return function;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3888
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3889
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3890
    private void verifyParameterList(final List<IdentNode> parameters, final ParserContextFunctionNode functionNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3891
        final IdentNode duplicateParameter = functionNode.getDuplicateParameterBinding();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3892
        if (duplicateParameter != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3893
            if (functionNode.isStrict() || functionNode.getKind() == FunctionNode.Kind.ARROW || !functionNode.isSimpleParameterList()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3894
                throw error(AbstractParser.message("strict.param.redefinition", duplicateParameter.getName()), duplicateParameter.getToken());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3895
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3896
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3897
            final int arity = parameters.size();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3898
            final HashSet<String> parametersSet = new HashSet<>(arity);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3899
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3900
            for (int i = arity - 1; i >= 0; i--) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3901
                final IdentNode parameter = parameters.get(i);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3902
                String parameterName = parameter.getName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3903
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3904
                if (parametersSet.contains(parameterName)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3905
                    // redefinition of parameter name, rename in non-strict mode
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3906
                    parameterName = functionNode.uniqueName(parameterName);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3907
                    final long parameterToken = parameter.getToken();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3908
                    parameters.set(i, new IdentNode(parameterToken, Token.descPosition(parameterToken), functionNode.uniqueName(parameterName)));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3909
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3910
                parametersSet.add(parameterName);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3911
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3912
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3913
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3914
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  3915
    private static Block maybeWrapBodyInParameterBlock(final Block functionBody, final ParserContextBlockNode parameterBlock) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3916
        assert functionBody.isFunctionBody();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3917
        if (!parameterBlock.getStatements().isEmpty()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3918
            parameterBlock.appendStatement(new BlockStatement(functionBody));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3919
            return new Block(parameterBlock.getToken(), functionBody.getFinish(), (functionBody.getFlags() | Block.IS_PARAMETER_BLOCK) & ~Block.IS_BODY, parameterBlock.getStatements());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3920
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3921
        return functionBody;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3922
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3923
27974
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3924
    private String getDefaultValidFunctionName(final int functionLine, final boolean isStatement) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3925
        final String defaultFunctionName = getDefaultFunctionName();
27974
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3926
        if (isValidIdentifier(defaultFunctionName)) {
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3927
            if (isStatement) {
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3928
                // The name will be used as the LHS of a symbol assignment. We add the anonymous function
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3929
                // prefix to ensure that it can't clash with another variable.
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3930
                return ANON_FUNCTION_PREFIX.symbolName() + defaultFunctionName;
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3931
            }
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3932
            return defaultFunctionName;
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3933
        }
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3934
        return ANON_FUNCTION_PREFIX.symbolName() + functionLine;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3935
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3936
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
  3937
    private static boolean isValidIdentifier(final String name) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3938
        if (name == null || name.isEmpty()) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3939
            return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3940
        }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3941
        if (!Character.isJavaIdentifierStart(name.charAt(0))) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3942
            return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3943
        }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3944
        for (int i = 1; i < name.length(); ++i) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3945
            if (!Character.isJavaIdentifierPart(name.charAt(i))) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3946
                return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3947
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3948
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3949
        return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3950
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3951
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3952
    private String getDefaultFunctionName() {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3953
        if (!defaultNames.isEmpty()) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3954
            final Object nameExpr = defaultNames.peek();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3955
            if (nameExpr instanceof PropertyKey) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3956
                markDefaultNameUsed();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3957
                return ((PropertyKey)nameExpr).getPropertyName();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3958
            } else if (nameExpr instanceof AccessNode) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3959
                markDefaultNameUsed();
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3960
                return ((AccessNode)nameExpr).getProperty();
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3961
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3962
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3963
        return null;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3964
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3965
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3966
    private void markDefaultNameUsed() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3967
        defaultNames.pop();
27974
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3968
        hideDefaultName();
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3969
    }
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3970
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3971
    private void hideDefaultName() {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3972
        // Can be any value as long as getDefaultFunctionName doesn't recognize it as something it can extract a value
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3973
        // from. Can't be null
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3974
        defaultNames.push("");
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3975
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3976
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3977
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3978
     * FormalParameterList :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3979
     *      Identifier
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3980
     *      FormalParameterList , Identifier
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3981
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3982
     * See 13
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3983
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3984
     * Parse function parameter list.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3985
     * @return List of parameter nodes.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3986
     */
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3987
    private List<IdentNode> formalParameterList(final boolean yield) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3988
        return formalParameterList(RPAREN, yield);
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3989
    }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3990
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3991
    /**
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3992
     * Same as the other method of the same name - except that the end
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3993
     * token type expected is passed as argument to this method.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3994
     *
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3995
     * FormalParameterList :
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3996
     *      Identifier
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3997
     *      FormalParameterList , Identifier
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3998
     *
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3999
     * See 13
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  4000
     *
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  4001
     * Parse function parameter list.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  4002
     * @return List of parameter nodes.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  4003
     */
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4004
    private List<IdentNode> formalParameterList(final TokenType endType, final boolean yield) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4005
        // Prepare to gather parameters.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  4006
        final ArrayList<IdentNode> parameters = new ArrayList<>();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4007
        // Track commas.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4008
        boolean first = true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4009
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  4010
        while (type != endType) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4011
            // Comma prior to every argument except the first.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4012
            if (!first) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4013
                expect(COMMARIGHT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4014
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4015
                first = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4016
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4017
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4018
            boolean restParameter = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4019
            if (type == ELLIPSIS && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4020
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4021
                restParameter = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4022
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4023
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4024
            if (type == YIELD && yield) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4025
                expect(IDENT);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4026
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4027
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4028
            final long paramToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4029
            final int paramLine = line;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4030
            final String contextString = "function parameter";
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4031
            IdentNode ident;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4032
            if (isBindingIdentifier() || restParameter || !isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4033
                ident = bindingIdentifier(contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4034
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4035
                if (restParameter) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4036
                    ident = ident.setIsRestParameter();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4037
                    // rest parameter must be last
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4038
                    expectDontAdvance(endType);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4039
                    parameters.add(ident);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4040
                    break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4041
                } else if (type == ASSIGN && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4042
                    next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4043
                    ident = ident.setIsDefaultParameter();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4044
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4045
                    if (type == YIELD && yield) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4046
                        // error: yield in default expression
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4047
                        expect(IDENT);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4048
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4049
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4050
                    // default parameter
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4051
                    final Expression initializer = assignmentExpression(false);
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4052
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4053
                    final ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4054
                    if (currentFunction != null) {
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4055
                        if (env._parse_only) {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4056
                            // keep what is seen in source "as is" and save it as parameter expression
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4057
                            final BinaryNode assignment = new BinaryNode(Token.recast(paramToken, ASSIGN), ident, initializer);
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4058
                            currentFunction.addParameterExpression(ident, assignment);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4059
                        } else {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4060
                            // desugar to: param = (param === undefined) ? initializer : param;
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4061
                            // possible alternative: if (param === undefined) param = initializer;
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4062
                            final BinaryNode test = new BinaryNode(Token.recast(paramToken, EQ_STRICT), ident, newUndefinedLiteral(paramToken, finish));
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4063
                            final TernaryNode value = new TernaryNode(Token.recast(paramToken, TERNARY), test, new JoinPredecessorExpression(initializer), new JoinPredecessorExpression(ident));
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4064
                            final BinaryNode assignment = new BinaryNode(Token.recast(paramToken, ASSIGN), ident, value);
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4065
                            lc.getFunctionBody(currentFunction).appendStatement(new ExpressionStatement(paramLine, assignment.getToken(), assignment.getFinish(), assignment));
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4066
                        }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4067
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4068
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4069
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4070
                final ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4071
                if (currentFunction != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4072
                    currentFunction.addParameterBinding(ident);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4073
                    if (ident.isRestParameter() || ident.isDefaultParameter()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4074
                        currentFunction.setSimpleParameterList(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4075
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4076
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4077
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4078
                final Expression pattern = bindingPattern();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4079
                // Introduce synthetic temporary parameter to capture the object to be destructured.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4080
                ident = createIdentNode(paramToken, pattern.getFinish(), String.format("arguments[%d]", parameters.size())).setIsDestructuredParameter();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4081
                verifyDestructuringParameterBindingPattern(pattern, paramToken, paramLine, contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4082
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4083
                Expression value = ident;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4084
                if (type == ASSIGN) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4085
                    next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4086
                    ident = ident.setIsDefaultParameter();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4087
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4088
                    // binding pattern with initializer. desugar to: (param === undefined) ? initializer : param
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4089
                    final Expression initializer = assignmentExpression(false);
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4090
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4091
                    if (env._parse_only) {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4092
                        // we don't want the synthetic identifier in parse only mode
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4093
                        value = initializer;
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4094
                    } else {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4095
                        // TODO initializer must not contain yield expression if yield=true (i.e. this is generator function's parameter list)
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4096
                        final BinaryNode test = new BinaryNode(Token.recast(paramToken, EQ_STRICT), ident, newUndefinedLiteral(paramToken, finish));
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4097
                        value = new TernaryNode(Token.recast(paramToken, TERNARY), test, new JoinPredecessorExpression(initializer), new JoinPredecessorExpression(ident));
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4098
                    }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4099
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4100
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4101
                final ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4102
                if (currentFunction != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4103
                    // destructuring assignment
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4104
                    final BinaryNode assignment = new BinaryNode(Token.recast(paramToken, ASSIGN), pattern, value);
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4105
                    if (env._parse_only) {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4106
                        // in parse-only mode, represent source tree "as is"
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4107
                        if (ident.isDefaultParameter()) {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4108
                            currentFunction.addParameterExpression(ident, assignment);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4109
                        } else {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4110
                            currentFunction.addParameterExpression(ident, pattern);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4111
                        }
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4112
                    } else {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4113
                        lc.getFunctionBody(currentFunction).appendStatement(new ExpressionStatement(paramLine, assignment.getToken(), assignment.getFinish(), assignment));
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4114
                    }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4115
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4116
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4117
            parameters.add(ident);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4118
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4119
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  4120
        parameters.trimToSize();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4121
        return parameters;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4122
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4123
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4124
    private void verifyDestructuringParameterBindingPattern(final Expression pattern, final long paramToken, final int paramLine, final String contextString) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4125
        verifyDestructuringBindingPattern(pattern, new Consumer<IdentNode>() {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4126
            public void accept(final IdentNode identNode) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4127
                verifyIdent(identNode, contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4128
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4129
                final ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4130
                if (currentFunction != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4131
                    // declare function-scope variables for destructuring bindings
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4132
                    if (!env._parse_only) {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4133
                        lc.getFunctionBody(currentFunction).appendStatement(new VarNode(paramLine, Token.recast(paramToken, VAR), pattern.getFinish(), identNode, null));
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4134
                    }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4135
                    // detect duplicate bounds names in parameter list
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4136
                    currentFunction.addParameterBinding(identNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4137
                    currentFunction.setSimpleParameterList(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4138
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4139
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4140
        });
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4141
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4142
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4143
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4144
     * FunctionBody :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4145
     *      SourceElements?
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4146
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4147
     * See 13
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4148
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4149
     * Parse function body.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4150
     * @return function node (body.)
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4151
     */
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4152
    private Block functionBody(final ParserContextFunctionNode functionNode) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4153
        long lastToken = 0L;
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4154
        ParserContextBlockNode body = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4155
        final long bodyToken = token;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4156
        Block functionBody;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4157
        int bodyFinish = 0;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4158
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4159
        final boolean parseBody;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4160
        Object endParserState = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4161
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4162
            // Create a new function block.
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4163
            body = newBlock();
33888
0c7b0ab328e0 8131929: Add option for debuggable scopes
hannesw
parents: 33533
diff changeset
  4164
            if (env._debug_scopes) {
0c7b0ab328e0 8131929: Add option for debuggable scopes
hannesw
parents: 33533
diff changeset
  4165
                // debug scope options forces everything to be in scope
0c7b0ab328e0 8131929: Add option for debuggable scopes
hannesw
parents: 33533
diff changeset
  4166
                markEval(lc);
0c7b0ab328e0 8131929: Add option for debuggable scopes
hannesw
parents: 33533
diff changeset
  4167
            }
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4168
            assert functionNode != null;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4169
            final int functionId = functionNode.getId();
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4170
            parseBody = reparsedFunction == null || functionId <= reparsedFunction.getFunctionNodeId();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4171
            // Nashorn extension: expression closures
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4172
            if ((!env._no_syntax_extensions || functionNode.getKind() == FunctionNode.Kind.ARROW) && type != LBRACE) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4173
                /*
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4174
                 * Example:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4175
                 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4176
                 * function square(x) x * x;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4177
                 * print(square(3));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4178
                 */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4179
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4180
                // just expression as function body
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4181
                final Expression expr = assignmentExpression(false);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4182
                lastToken = previousToken;
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4183
                functionNode.setLastToken(previousToken);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4184
                assert lc.getCurrentBlock() == lc.getFunctionBody(functionNode);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4185
                // EOL uses length field to store the line number
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4186
                final int lastFinish = Token.descPosition(lastToken) + (Token.descType(lastToken) == EOL ? 0 : Token.descLength(lastToken));
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4187
                // Only create the return node if we aren't skipping nested functions. Note that we aren't
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4188
                // skipping parsing of these extended functions; they're considered to be small anyway. Also,
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4189
                // they don't end with a single well known token, so it'd be very hard to get correctly (see
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4190
                // the note below for reasoning on skipping happening before instead of after RBRACE for
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4191
                // details).
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4192
                if (parseBody) {
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4193
                    functionNode.setFlag(FunctionNode.HAS_EXPRESSION_BODY);
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4194
                    final ReturnNode returnNode = new ReturnNode(functionNode.getLineNumber(), expr.getToken(), lastFinish, expr);
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4195
                    appendStatement(returnNode);
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4196
                }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4197
                // bodyFinish = finish;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4198
            } else {
26505
d29bf8787b43 8057931: Instead of not skipping small functions in parser, make lexer avoid them instead
attila
parents: 26503
diff changeset
  4199
                expectDontAdvance(LBRACE);
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4200
                if (parseBody || !skipFunctionBody(functionNode)) {
26505
d29bf8787b43 8057931: Instead of not skipping small functions in parser, make lexer avoid them instead
attila
parents: 26503
diff changeset
  4201
                    next();
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4202
                    // Gather the function elements.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4203
                    final List<Statement> prevFunctionDecls = functionDeclarations;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4204
                    functionDeclarations = new ArrayList<>();
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4205
                    try {
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
  4206
                        sourceElements(0);
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4207
                        addFunctionDeclarations(functionNode);
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4208
                    } finally {
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4209
                        functionDeclarations = prevFunctionDecls;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4210
                    }
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4211
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4212
                    lastToken = token;
26505
d29bf8787b43 8057931: Instead of not skipping small functions in parser, make lexer avoid them instead
attila
parents: 26503
diff changeset
  4213
                    if (parseBody) {
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4214
                        // Since the lexer can read ahead and lexify some number of tokens in advance and have
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4215
                        // them buffered in the TokenStream, we need to produce a lexer state as it was just
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4216
                        // before it lexified RBRACE, and not whatever is its current (quite possibly well read
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4217
                        // ahead) state.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4218
                        endParserState = new ParserState(Token.descPosition(token), line, linePosition);
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4219
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4220
                        // NOTE: you might wonder why do we capture/restore parser state before RBRACE instead of
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4221
                        // after RBRACE; after all, we could skip the below "expect(RBRACE);" if we captured the
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4222
                        // state after it. The reason is that RBRACE is a well-known token that we can expect and
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4223
                        // will never involve us getting into a weird lexer state, and as such is a great reparse
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4224
                        // point. Typical example of a weird lexer state after RBRACE would be:
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4225
                        //     function this_is_skipped() { ... } "use strict";
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4226
                        // because lexer is doing weird off-by-one maneuvers around string literal quotes. Instead
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4227
                        // of compensating for the possibility of a string literal (or similar) after RBRACE,
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4228
                        // we'll rather just restart parsing from this well-known, friendly token instead.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4229
                    }
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  4230
                }
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4231
                bodyFinish = finish;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4232
                functionNode.setLastToken(token);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4233
                expect(RBRACE);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4234
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4235
        } finally {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4236
            restoreBlock(body);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4237
        }
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4238
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4239
        // NOTE: we can only do alterations to the function node after restoreFunctionNode.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4240
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4241
        if (parseBody) {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4242
            functionNode.setEndParserState(endParserState);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4243
        } else if (!body.getStatements().isEmpty()){
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4244
            // This is to ensure the body is empty when !parseBody but we couldn't skip parsing it (see
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4245
            // skipFunctionBody() for possible reasons). While it is not strictly necessary for correctness to
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4246
            // enforce empty bodies in nested functions that were supposed to be skipped, we do assert it as
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4247
            // an invariant in few places in the compiler pipeline, so for consistency's sake we'll throw away
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4248
            // nested bodies early if we were supposed to skip 'em.
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4249
            body.setStatements(Collections.<Statement>emptyList());
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4250
        }
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4251
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4252
        if (reparsedFunction != null) {
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4253
            // We restore the flags stored in the function's ScriptFunctionData that we got when we first
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4254
            // eagerly parsed the code. We're doing it because some flags would be set based on the
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4255
            // content of the function, or even content of its nested functions, most of which are normally
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4256
            // skipped during an on-demand compilation.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4257
            final RecompilableScriptFunctionData data = reparsedFunction.getScriptFunctionData(functionNode.getId());
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4258
            if (data != null) {
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4259
                // Data can be null if when we originally parsed the file, we removed the function declaration
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4260
                // as it was dead code.
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4261
                functionNode.setFlag(data.getFunctionFlags());
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4262
                // This compensates for missing markEval() in case the function contains an inner function
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4263
                // that contains eval(), that now we didn't discover since we skipped the inner function.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4264
                if (functionNode.hasNestedEval()) {
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4265
                    assert functionNode.hasScopeBlock();
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4266
                    body.setFlag(Block.NEEDS_SCOPE);
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4267
                }
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4268
            }
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4269
        }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4270
        functionBody = new Block(bodyToken, bodyFinish, body.getFlags() | Block.IS_BODY, body.getStatements());
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4271
        return functionBody;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4272
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4273
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4274
    private boolean skipFunctionBody(final ParserContextFunctionNode functionNode) {
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4275
        if (reparsedFunction == null) {
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4276
            // Not reparsing, so don't skip any function body.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4277
            return false;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4278
        }
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4279
        // Skip to the RBRACE of this function, and continue parsing from there.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4280
        final RecompilableScriptFunctionData data = reparsedFunction.getScriptFunctionData(functionNode.getId());
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4281
        if (data == null) {
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4282
            // Nested function is not known to the reparsed function. This can happen if the FunctionNode was
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4283
            // in dead code that was removed. Both FoldConstants and Lower prune dead code. In that case, the
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4284
            // FunctionNode was dropped before a RecompilableScriptFunctionData could've been created for it.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4285
            return false;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4286
        }
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4287
        final ParserState parserState = (ParserState)data.getEndParserState();
26505
d29bf8787b43 8057931: Instead of not skipping small functions in parser, make lexer avoid them instead
attila
parents: 26503
diff changeset
  4288
        assert parserState != null;
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4289
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4290
        if (k < stream.last() && start < parserState.position && parserState.position <= Token.descPosition(stream.get(stream.last()))) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4291
            // RBRACE is already in the token stream, so fast forward to it
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4292
            for (; k < stream.last(); k++) {
34447
ec4c069f9436 8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents: 33888
diff changeset
  4293
                final long nextToken = stream.get(k + 1);
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4294
                if (Token.descPosition(nextToken) == parserState.position && Token.descType(nextToken) == RBRACE) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4295
                    token = stream.get(k);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4296
                    type = Token.descType(token);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4297
                    next();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4298
                    assert type == RBRACE && start == parserState.position;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4299
                    return true;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4300
                }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4301
            }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4302
        }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4303
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4304
        stream.reset();
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
  4305
        lexer = parserState.createLexer(source, lexer, stream, scripting && !env._no_syntax_extensions, env._es6);
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4306
        line = parserState.line;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4307
        linePosition = parserState.linePosition;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4308
        // Doesn't really matter, but it's safe to treat it as if there were a semicolon before
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4309
        // the RBRACE.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4310
        type = SEMICOLON;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4311
        scanFirstToken();
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4312
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4313
        return true;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4314
    }
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4315
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4316
    /**
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4317
     * Encapsulates part of the state of the parser, enough to reconstruct the state of both parser and lexer
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4318
     * for resuming parsing after skipping a function body.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4319
     */
26646
332e9901f0ed 8058304: Non-serializable fields in serializable classes
hannesw
parents: 26505
diff changeset
  4320
    private static class ParserState implements Serializable {
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4321
        private final int position;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4322
        private final int line;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4323
        private final int linePosition;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4324
26646
332e9901f0ed 8058304: Non-serializable fields in serializable classes
hannesw
parents: 26505
diff changeset
  4325
        private static final long serialVersionUID = -2382565130754093694L;
332e9901f0ed 8058304: Non-serializable fields in serializable classes
hannesw
parents: 26505
diff changeset
  4326
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4327
        ParserState(final int position, final int line, final int linePosition) {
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4328
            this.position = position;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4329
            this.line = line;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4330
            this.linePosition = linePosition;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4331
        }
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4332
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
  4333
        Lexer createLexer(final Source source, final Lexer lexer, final TokenStream stream, final boolean scripting, final boolean es6) {
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
  4334
            final Lexer newLexer = new Lexer(source, position, lexer.limit - position, stream, scripting, es6, true);
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4335
            newLexer.restoreState(new Lexer.State(position, Integer.MAX_VALUE, line, -1, linePosition, SEMICOLON));
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4336
            return newLexer;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4337
        }
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4338
    }
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4339
26065
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  4340
    private void printAST(final FunctionNode functionNode) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4341
        if (functionNode.getDebugFlag(FunctionNode.DEBUG_PRINT_AST)) {
26065
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  4342
            env.getErr().println(new ASTWriter(functionNode));
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  4343
        }
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  4344
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4345
        if (functionNode.getDebugFlag(FunctionNode.DEBUG_PRINT_PARSE)) {
26065
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  4346
            env.getErr().println(new PrintVisitor(functionNode, true, false));
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  4347
        }
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  4348
    }
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  4349
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4350
    private void addFunctionDeclarations(final ParserContextFunctionNode functionNode) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4351
        VarNode lastDecl = null;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4352
        for (int i = functionDeclarations.size() - 1; i >= 0; i--) {
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  4353
            Statement decl = functionDeclarations.get(i);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4354
            if (lastDecl == null && decl instanceof VarNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4355
                decl = lastDecl = ((VarNode)decl).setFlag(VarNode.IS_LAST_FUNCTION_DECLARATION);
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4356
                functionNode.setFlag(FunctionNode.HAS_FUNCTION_DECLARATIONS);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4357
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4358
            prependStatement(decl);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4359
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4360
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4361
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4362
    private RuntimeNode referenceError(final Expression lhs, final Expression rhs, final boolean earlyError) {
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4363
        if (env._parse_only || earlyError) {
18632
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  4364
            throw error(JSErrorType.REFERENCE_ERROR, AbstractParser.message("invalid.lvalue"), lhs.getToken());
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  4365
        }
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4366
        final ArrayList<Expression> args = new ArrayList<>();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4367
        args.add(lhs);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4368
        if (rhs == null) {
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  4369
            args.add(LiteralNode.newInstance(lhs.getToken(), lhs.getFinish()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4370
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4371
            args.add(rhs);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4372
        }
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  4373
        args.add(LiteralNode.newInstance(lhs.getToken(), lhs.getFinish(), lhs.toString()));
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  4374
        return new RuntimeNode(lhs.getToken(), lhs.getFinish(), RuntimeNode.Request.REFERENCE_ERROR, args);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4375
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4376
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4377
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4378
     * PostfixExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4379
     *      LeftHandSideExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4380
     *      LeftHandSideExpression ++ // [no LineTerminator here]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4381
     *      LeftHandSideExpression -- // [no LineTerminator here]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4382
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4383
     * See 11.3
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4384
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4385
     * UnaryExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4386
     *      PostfixExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4387
     *      delete UnaryExpression
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  4388
     *      void UnaryExpression
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4389
     *      typeof UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4390
     *      ++ UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4391
     *      -- UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4392
     *      + UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4393
     *      - UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4394
     *      ~ UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4395
     *      ! UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4396
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4397
     * See 11.4
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4398
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4399
     * Parse unary expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4400
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4401
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4402
    private Expression unaryExpression() {
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  4403
        final int  unaryLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4404
        final long unaryToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4405
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4406
        switch (type) {
46169
b385216af0ed 8185252: Unary minus and plus use wrong node Kind
hannesw
parents: 41983
diff changeset
  4407
        case ADD:
b385216af0ed 8185252: Unary minus and plus use wrong node Kind
hannesw
parents: 41983
diff changeset
  4408
        case SUB: {
b385216af0ed 8185252: Unary minus and plus use wrong node Kind
hannesw
parents: 41983
diff changeset
  4409
            final TokenType opType = type;
b385216af0ed 8185252: Unary minus and plus use wrong node Kind
hannesw
parents: 41983
diff changeset
  4410
            next();
b385216af0ed 8185252: Unary minus and plus use wrong node Kind
hannesw
parents: 41983
diff changeset
  4411
            final Expression expr = unaryExpression();
b385216af0ed 8185252: Unary minus and plus use wrong node Kind
hannesw
parents: 41983
diff changeset
  4412
            return new UnaryNode(Token.recast(unaryToken, (opType == TokenType.ADD) ? TokenType.POS : TokenType.NEG), expr);
b385216af0ed 8185252: Unary minus and plus use wrong node Kind
hannesw
parents: 41983
diff changeset
  4413
        }
48334
fdefa410d655 8193296: Parser should not eagerly transform delete expressions
attila
parents: 47337
diff changeset
  4414
        case DELETE:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4415
        case VOID:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4416
        case TYPEOF:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4417
        case BIT_NOT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4418
        case NOT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4419
            next();
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4420
            final Expression expr = unaryExpression();
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  4421
            return new UnaryNode(unaryToken, expr);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4422
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4423
        case INCPREFIX:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4424
        case DECPREFIX:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4425
            final TokenType opType = type;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4426
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4427
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4428
            final Expression lhs = leftHandSideExpression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4429
            // ++, -- without operand..
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4430
            if (lhs == null) {
18632
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  4431
                throw error(AbstractParser.message("expected.lvalue", type.getNameOrType()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4432
            }
18632
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  4433
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4434
            return verifyIncDecExpression(unaryToken, opType, lhs, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4435
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4436
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4437
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4438
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4439
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4440
        final Expression expression = leftHandSideExpression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4441
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4442
        if (last != EOL) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4443
            switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4444
            case INCPREFIX:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4445
            case DECPREFIX:
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4446
                final long opToken = token;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4447
                final TokenType opType = type;
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4448
                final Expression lhs = expression;
18632
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  4449
                // ++, -- without operand..
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  4450
                if (lhs == null) {
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  4451
                    throw error(AbstractParser.message("expected.lvalue", type.getNameOrType()));
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  4452
                }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4453
                next();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4454
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4455
                return verifyIncDecExpression(opToken, opType, lhs, true);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4456
            default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4457
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4458
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4459
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4460
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4461
        if (expression == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4462
            throw error(AbstractParser.message("expected.operand", type.getNameOrType()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4463
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4464
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4465
        return expression;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4466
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4467
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4468
    private Expression verifyIncDecExpression(final long unaryToken, final TokenType opType, final Expression lhs, final boolean isPostfix) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4469
        assert lhs != null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4470
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4471
        if (!(lhs instanceof AccessNode ||
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4472
              lhs instanceof IndexNode ||
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4473
              lhs instanceof IdentNode)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4474
            return referenceError(lhs, null, env._early_lvalue_error);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4475
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4476
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4477
        if (lhs instanceof IdentNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4478
            if (!checkIdentLValue((IdentNode)lhs)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4479
                return referenceError(lhs, null, false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4480
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4481
            verifyIdent((IdentNode)lhs, "operand for " + opType.getName() + " operator");
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4482
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4483
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4484
        return incDecExpression(unaryToken, opType, lhs, isPostfix);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4485
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4486
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4487
    /**
32245
80164edf8a10 8133872: Expression completion should work on contexts where an expression is accepted
sundar
parents: 31485
diff changeset
  4488
     * {@code
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4489
     * MultiplicativeExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4490
     *      UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4491
     *      MultiplicativeExpression * UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4492
     *      MultiplicativeExpression / UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4493
     *      MultiplicativeExpression % UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4494
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4495
     * See 11.5
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4496
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4497
     * AdditiveExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4498
     *      MultiplicativeExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4499
     *      AdditiveExpression + MultiplicativeExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4500
     *      AdditiveExpression - MultiplicativeExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4501
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4502
     * See 11.6
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4503
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4504
     * ShiftExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4505
     *      AdditiveExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4506
     *      ShiftExpression << AdditiveExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4507
     *      ShiftExpression >> AdditiveExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4508
     *      ShiftExpression >>> AdditiveExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4509
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4510
     * See 11.7
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4511
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4512
     * RelationalExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4513
     *      ShiftExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4514
     *      RelationalExpression < ShiftExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4515
     *      RelationalExpression > ShiftExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4516
     *      RelationalExpression <= ShiftExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4517
     *      RelationalExpression >= ShiftExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4518
     *      RelationalExpression instanceof ShiftExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4519
     *      RelationalExpression in ShiftExpression // if !noIf
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4520
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4521
     * See 11.8
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4522
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4523
     *      RelationalExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4524
     *      EqualityExpression == RelationalExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4525
     *      EqualityExpression != RelationalExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4526
     *      EqualityExpression === RelationalExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4527
     *      EqualityExpression !== RelationalExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4528
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4529
     * See 11.9
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4530
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4531
     * BitwiseANDExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4532
     *      EqualityExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4533
     *      BitwiseANDExpression & EqualityExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4534
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4535
     * BitwiseXORExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4536
     *      BitwiseANDExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4537
     *      BitwiseXORExpression ^ BitwiseANDExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4538
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4539
     * BitwiseORExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4540
     *      BitwiseXORExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4541
     *      BitwiseORExpression | BitwiseXORExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4542
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4543
     * See 11.10
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4544
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4545
     * LogicalANDExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4546
     *      BitwiseORExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4547
     *      LogicalANDExpression && BitwiseORExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4548
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4549
     * LogicalORExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4550
     *      LogicalANDExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4551
     *      LogicalORExpression || LogicalANDExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4552
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4553
     * See 11.11
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4554
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4555
     * ConditionalExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4556
     *      LogicalORExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4557
     *      LogicalORExpression ? AssignmentExpression : AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4558
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4559
     * See 11.12
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4560
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4561
     * AssignmentExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4562
     *      ConditionalExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4563
     *      LeftHandSideExpression AssignmentOperator AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4564
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4565
     * AssignmentOperator :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4566
     *      = *= /= %= += -= <<= >>= >>>= &= ^= |=
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4567
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4568
     * See 11.13
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4569
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4570
     * Expression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4571
     *      AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4572
     *      Expression , AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4573
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4574
     * See 11.14
32245
80164edf8a10 8133872: Expression completion should work on contexts where an expression is accepted
sundar
parents: 31485
diff changeset
  4575
     * }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4576
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4577
     * Parse expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4578
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4579
     */
32245
80164edf8a10 8133872: Expression completion should work on contexts where an expression is accepted
sundar
parents: 31485
diff changeset
  4580
    protected Expression expression() {
80164edf8a10 8133872: Expression completion should work on contexts where an expression is accepted
sundar
parents: 31485
diff changeset
  4581
        // This method is protected so that subclass can get details
80164edf8a10 8133872: Expression completion should work on contexts where an expression is accepted
sundar
parents: 31485
diff changeset
  4582
        // at expression start point!
80164edf8a10 8133872: Expression completion should work on contexts where an expression is accepted
sundar
parents: 31485
diff changeset
  4583
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4584
        // Include commas in expression parsing.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4585
        return expression(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4586
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4587
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4588
    private Expression expression(final boolean noIn) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4589
        Expression assignmentExpression = assignmentExpression(noIn);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4590
        while (type == COMMARIGHT) {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4591
            final long commaToken = token;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4592
            next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4593
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4594
            boolean rhsRestParameter = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4595
            if (type == ELLIPSIS && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4596
                // (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).
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4597
                // 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.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4598
                if (isRestParameterEndOfArrowFunctionParameterList()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4599
                    next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4600
                    rhsRestParameter = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4601
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4602
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4603
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4604
            Expression rhs = assignmentExpression(noIn);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4605
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4606
            if (rhsRestParameter) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4607
                rhs = ((IdentNode)rhs).setIsRestParameter();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4608
                // Our only valid move is to end Expression here and continue with ArrowFunction.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4609
                // We've already checked that this is the parameter list of an arrow function (see above).
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4610
                // RPAREN is next, so we'll finish the binary expression and drop out of the loop.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4611
                assert type == RPAREN;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4612
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4613
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4614
            assignmentExpression = new BinaryNode(commaToken, assignmentExpression, rhs);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4615
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4616
        return assignmentExpression;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4617
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4618
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4619
    private Expression expression(final int minPrecedence, final boolean noIn) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4620
        return expression(unaryExpression(), minPrecedence, noIn);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4621
    }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4622
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  4623
    private JoinPredecessorExpression joinPredecessorExpression() {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  4624
        return new JoinPredecessorExpression(expression());
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  4625
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  4626
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4627
    private Expression expression(final Expression exprLhs, final int minPrecedence, final boolean noIn) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4628
        // Get the precedence of the next operator.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4629
        int precedence = type.getPrecedence();
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4630
        Expression lhs = exprLhs;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4631
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4632
        // While greater precedence.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4633
        while (type.isOperator(noIn) && precedence >= minPrecedence) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4634
            // Capture the operator token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4635
            final long op = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4636
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4637
            if (type == TERNARY) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4638
                // Skip operator.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4639
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4640
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4641
                // Pass expression. Middle expression of a conditional expression can be a "in"
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4642
                // expression - even in the contexts where "in" is not permitted.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  4643
                final Expression trueExpr = expression(unaryExpression(), ASSIGN.getPrecedence(), false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4644
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4645
                expect(COLON);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4646
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4647
                // Fail expression.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  4648
                final Expression falseExpr = expression(unaryExpression(), ASSIGN.getPrecedence(), noIn);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4649
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4650
                // Build up node.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  4651
                lhs = new TernaryNode(op, lhs, new JoinPredecessorExpression(trueExpr), new JoinPredecessorExpression(falseExpr));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4652
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4653
                // Skip operator.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4654
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4655
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4656
                 // Get the next primary expression.
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4657
                Expression rhs;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4658
                final boolean isAssign = Token.descType(op) == ASSIGN;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4659
                if(isAssign) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4660
                    defaultNames.push(lhs);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4661
                }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4662
                try {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4663
                    rhs = unaryExpression();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4664
                    // Get precedence of next operator.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4665
                    int nextPrecedence = type.getPrecedence();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4666
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4667
                    // Subtask greater precedence.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4668
                    while (type.isOperator(noIn) &&
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4669
                           (nextPrecedence > precedence ||
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4670
                           nextPrecedence == precedence && !type.isLeftAssociative())) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4671
                        rhs = expression(rhs, nextPrecedence, noIn);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4672
                        nextPrecedence = type.getPrecedence();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4673
                    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4674
                } finally {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4675
                    if(isAssign) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4676
                        defaultNames.pop();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4677
                    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4678
                }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4679
                lhs = verifyAssignment(op, lhs, rhs);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4680
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4681
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4682
            precedence = type.getPrecedence();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4683
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4684
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4685
        return lhs;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4686
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4687
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4688
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4689
     * AssignmentExpression.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4690
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4691
     * AssignmentExpression[In, Yield] :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4692
     *   ConditionalExpression[?In, ?Yield]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4693
     *   [+Yield] YieldExpression[?In]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4694
     *   ArrowFunction[?In, ?Yield]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4695
     *   LeftHandSideExpression[?Yield] = AssignmentExpression[?In, ?Yield]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4696
     *   LeftHandSideExpression[?Yield] AssignmentOperator AssignmentExpression[?In, ?Yield]
38807
79e9bf5bb792 8158250: nashorn ant javadoc targets are broken
sundar
parents: 38485
diff changeset
  4697
     *
79e9bf5bb792 8158250: nashorn ant javadoc targets are broken
sundar
parents: 38485
diff changeset
  4698
     * @param noIn {@code true} if IN operator should be ignored.
79e9bf5bb792 8158250: nashorn ant javadoc targets are broken
sundar
parents: 38485
diff changeset
  4699
     * @return the assignment expression
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4700
     */
32245
80164edf8a10 8133872: Expression completion should work on contexts where an expression is accepted
sundar
parents: 31485
diff changeset
  4701
    protected Expression assignmentExpression(final boolean noIn) {
80164edf8a10 8133872: Expression completion should work on contexts where an expression is accepted
sundar
parents: 31485
diff changeset
  4702
        // This method is protected so that subclass can get details
80164edf8a10 8133872: Expression completion should work on contexts where an expression is accepted
sundar
parents: 31485
diff changeset
  4703
        // at assignment expression start point!
80164edf8a10 8133872: Expression completion should work on contexts where an expression is accepted
sundar
parents: 31485
diff changeset
  4704
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4705
        if (type == YIELD && inGeneratorFunction() && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4706
            return yieldExpression(noIn);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4707
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4708
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4709
        final long startToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4710
        final int startLine = line;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4711
        final Expression exprLhs = conditionalExpression(noIn);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4712
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4713
        if (type == ARROW && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4714
            if (checkNoLineTerminator()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4715
                final Expression paramListExpr;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4716
                if (exprLhs instanceof ExpressionList) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4717
                    paramListExpr = (((ExpressionList)exprLhs).getExpressions().isEmpty() ? null : ((ExpressionList)exprLhs).getExpressions().get(0));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4718
                } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4719
                    paramListExpr = exprLhs;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4720
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4721
                return arrowFunction(startToken, startLine, paramListExpr);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4722
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4723
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4724
        assert !(exprLhs instanceof ExpressionList);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4725
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4726
        if (isAssignmentOperator(type)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4727
            final boolean isAssign = type == ASSIGN;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4728
            if (isAssign) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4729
                defaultNames.push(exprLhs);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4730
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4731
            try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4732
                final long assignToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4733
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4734
                final Expression exprRhs = assignmentExpression(noIn);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4735
                return verifyAssignment(assignToken, exprLhs, exprRhs);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4736
            } finally {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4737
                if (isAssign) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4738
                    defaultNames.pop();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4739
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4740
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4741
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4742
            return exprLhs;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4743
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4744
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4745
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4746
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4747
     * Is type one of {@code = *= /= %= += -= <<= >>= >>>= &= ^= |=}?
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4748
     */
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4749
    private static boolean isAssignmentOperator(final TokenType type) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4750
        switch (type) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4751
        case ASSIGN:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4752
        case ASSIGN_ADD:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4753
        case ASSIGN_BIT_AND:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4754
        case ASSIGN_BIT_OR:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4755
        case ASSIGN_BIT_XOR:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4756
        case ASSIGN_DIV:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4757
        case ASSIGN_MOD:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4758
        case ASSIGN_MUL:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4759
        case ASSIGN_SAR:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4760
        case ASSIGN_SHL:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4761
        case ASSIGN_SHR:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4762
        case ASSIGN_SUB:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4763
            return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4764
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4765
        return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4766
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4767
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4768
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4769
     * ConditionalExpression.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4770
     */
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4771
    private Expression conditionalExpression(final boolean noIn) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4772
        return expression(TERNARY.getPrecedence(), noIn);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4773
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4774
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4775
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4776
     * ArrowFunction.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4777
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4778
     * @param startToken start token of the ArrowParameters expression
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4779
     * @param functionLine start line of the arrow function
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4780
     * @param paramListExpr ArrowParameters expression or {@code null} for {@code ()} (empty list)
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4781
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4782
    private Expression arrowFunction(final long startToken, final int functionLine, final Expression paramListExpr) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4783
        // caller needs to check that there's no LineTerminator between parameter list and arrow
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4784
        assert type != ARROW || checkNoLineTerminator();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4785
        expect(ARROW);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4786
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4787
        final long functionToken = Token.recast(startToken, ARROW);
37835
78bffb8c47c3 8156492: ClassFormatError thrown when arrow function is used
sundar
parents: 37732
diff changeset
  4788
        final IdentNode name = new IdentNode(functionToken, Token.descPosition(functionToken), NameCodec.encode("=>:") + functionLine);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4789
        final ParserContextFunctionNode functionNode = createParserContextFunctionNode(name, functionToken, FunctionNode.Kind.ARROW, functionLine, null);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4790
        functionNode.setFlag(FunctionNode.IS_ANONYMOUS);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4791
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4792
        lc.push(functionNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4793
        try {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4794
            final ParserContextBlockNode parameterBlock = newBlock();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4795
            final List<IdentNode> parameters;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4796
            try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4797
                parameters = convertArrowFunctionParameterList(paramListExpr, functionLine);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4798
                functionNode.setParameters(parameters);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4799
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4800
                if (!functionNode.isSimpleParameterList()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4801
                    markEvalInArrowParameterList(parameterBlock);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4802
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4803
            } finally {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4804
                restoreBlock(parameterBlock);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4805
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4806
            Block functionBody = functionBody(functionNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4807
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4808
            functionBody = maybeWrapBodyInParameterBlock(functionBody, parameterBlock);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4809
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4810
            verifyParameterList(parameters, functionNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4811
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4812
            final FunctionNode function = createFunctionNode(
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4813
                            functionNode,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4814
                            functionToken,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4815
                            name,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4816
                            parameters,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4817
                            FunctionNode.Kind.ARROW,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4818
                            functionLine,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4819
                            functionBody);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4820
            return function;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4821
        } finally {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4822
            lc.pop(functionNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4823
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4824
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4825
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4826
    private void markEvalInArrowParameterList(final ParserContextBlockNode parameterBlock) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4827
        final Iterator<ParserContextFunctionNode> iter = lc.getFunctions();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4828
        final ParserContextFunctionNode current = iter.next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4829
        final ParserContextFunctionNode parent = iter.next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4830
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4831
        if (parent.getFlag(FunctionNode.HAS_EVAL) != 0) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4832
            // we might have flagged has-eval in the parent function during parsing the parameter list,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4833
            // if the parameter list contains eval; must tag arrow function as has-eval.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4834
            for (final Statement st : parameterBlock.getStatements()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4835
                st.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4836
                    @Override
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4837
                    public boolean enterCallNode(final CallNode callNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4838
                        if (callNode.getFunction() instanceof IdentNode && ((IdentNode) callNode.getFunction()).getName().equals("eval")) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4839
                            current.setFlag(FunctionNode.HAS_EVAL);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4840
                        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4841
                        return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4842
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4843
                });
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4844
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4845
            // TODO: function containing the arrow function should not be flagged has-eval
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4846
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4847
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4848
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4849
    private List<IdentNode> convertArrowFunctionParameterList(final Expression paramListExpr, final int functionLine) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4850
        final List<IdentNode> parameters;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4851
        if (paramListExpr == null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4852
            // empty parameter list, i.e. () =>
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4853
            parameters = Collections.emptyList();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4854
        } else if (paramListExpr instanceof IdentNode || paramListExpr.isTokenType(ASSIGN) || isDestructuringLhs(paramListExpr)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4855
            parameters = Collections.singletonList(verifyArrowParameter(paramListExpr, 0, functionLine));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4856
        } else if (paramListExpr instanceof BinaryNode && Token.descType(paramListExpr.getToken()) == COMMARIGHT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4857
            parameters = new ArrayList<>();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4858
            Expression car = paramListExpr;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4859
            do {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4860
                final Expression cdr = ((BinaryNode) car).rhs();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4861
                parameters.add(0, verifyArrowParameter(cdr, parameters.size(), functionLine));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4862
                car = ((BinaryNode) car).lhs();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4863
            } while (car instanceof BinaryNode && Token.descType(car.getToken()) == COMMARIGHT);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4864
            parameters.add(0, verifyArrowParameter(car, parameters.size(), functionLine));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4865
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4866
            throw error(AbstractParser.message("expected.arrow.parameter"), paramListExpr.getToken());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4867
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4868
        return parameters;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4869
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4870
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4871
    private IdentNode verifyArrowParameter(final Expression param, final int index, final int paramLine) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4872
        final String contextString = "function parameter";
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4873
        if (param instanceof IdentNode) {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4874
            final IdentNode ident = (IdentNode)param;
47337
079a87f87518 8027302: Identifiers containing unicode escapes are not recognized as reserved words
hannesw
parents: 47287
diff changeset
  4875
            verifyIdent(ident, contextString);
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4876
            final ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4877
            if (currentFunction != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4878
                currentFunction.addParameterBinding(ident);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4879
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4880
            return ident;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4881
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4882
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4883
        if (param.isTokenType(ASSIGN)) {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4884
            final Expression lhs = ((BinaryNode) param).lhs();
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4885
            final long paramToken = lhs.getToken();
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4886
            final Expression initializer = ((BinaryNode) param).rhs();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4887
            if (lhs instanceof IdentNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4888
                // default parameter
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4889
                final IdentNode ident = (IdentNode) lhs;
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4890
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4891
                final ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4892
                if (currentFunction != null) {
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4893
                    if (env._parse_only) {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4894
                        currentFunction.addParameterExpression(ident, param);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4895
                    } else {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4896
                        final BinaryNode test = new BinaryNode(Token.recast(paramToken, EQ_STRICT), ident, newUndefinedLiteral(paramToken, finish));
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4897
                        final TernaryNode value = new TernaryNode(Token.recast(paramToken, TERNARY), test, new JoinPredecessorExpression(initializer), new JoinPredecessorExpression(ident));
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4898
                        final BinaryNode assignment = new BinaryNode(Token.recast(paramToken, ASSIGN), ident, value);
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4899
                        lc.getFunctionBody(currentFunction).appendStatement(new ExpressionStatement(paramLine, assignment.getToken(), assignment.getFinish(), assignment));
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4900
                    }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4901
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4902
                    currentFunction.addParameterBinding(ident);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4903
                    currentFunction.setSimpleParameterList(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4904
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4905
                return ident;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4906
            } else if (isDestructuringLhs(lhs)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4907
                // binding pattern with initializer
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4908
                // Introduce synthetic temporary parameter to capture the object to be destructured.
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4909
                final IdentNode ident = createIdentNode(paramToken, param.getFinish(), String.format("arguments[%d]", index)).setIsDestructuredParameter().setIsDefaultParameter();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4910
                verifyDestructuringParameterBindingPattern(param, paramToken, paramLine, contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4911
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4912
                final ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4913
                if (currentFunction != null) {
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4914
                    if (env._parse_only) {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4915
                        currentFunction.addParameterExpression(ident, param);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4916
                    } else {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4917
                        final BinaryNode test = new BinaryNode(Token.recast(paramToken, EQ_STRICT), ident, newUndefinedLiteral(paramToken, finish));
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4918
                        final TernaryNode value = new TernaryNode(Token.recast(paramToken, TERNARY), test, new JoinPredecessorExpression(initializer), new JoinPredecessorExpression(ident));
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4919
                        final BinaryNode assignment = new BinaryNode(Token.recast(paramToken, ASSIGN), param, value);
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4920
                        lc.getFunctionBody(currentFunction).appendStatement(new ExpressionStatement(paramLine, assignment.getToken(), assignment.getFinish(), assignment));
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4921
                    }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4922
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4923
                return ident;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4924
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4925
        } else if (isDestructuringLhs(param)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4926
            // binding pattern
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4927
            final long paramToken = param.getToken();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4928
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4929
            // Introduce synthetic temporary parameter to capture the object to be destructured.
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4930
            final IdentNode ident = createIdentNode(paramToken, param.getFinish(), String.format("arguments[%d]", index)).setIsDestructuredParameter();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4931
            verifyDestructuringParameterBindingPattern(param, paramToken, paramLine, contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4932
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4933
            final ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4934
            if (currentFunction != null) {
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4935
                if (env._parse_only) {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4936
                    currentFunction.addParameterExpression(ident, param);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4937
                } else {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4938
                    final BinaryNode assignment = new BinaryNode(Token.recast(paramToken, ASSIGN), param, ident);
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4939
                    lc.getFunctionBody(currentFunction).appendStatement(new ExpressionStatement(paramLine, assignment.getToken(), assignment.getFinish(), assignment));
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4940
                }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4941
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4942
            return ident;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4943
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4944
        throw error(AbstractParser.message("invalid.arrow.parameter"), param.getToken());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4945
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4946
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4947
    private boolean checkNoLineTerminator() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4948
        assert type == ARROW;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4949
        if (last == RPAREN) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4950
            return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4951
        } else if (last == IDENT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4952
            return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4953
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4954
        for (int i = k - 1; i >= 0; i--) {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4955
            final TokenType t = T(i);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4956
            switch (t) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4957
            case RPAREN:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4958
            case IDENT:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4959
                return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4960
            case EOL:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4961
                return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4962
            case COMMENT:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4963
                continue;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4964
            default:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4965
                if (t.getKind() == TokenKind.FUTURESTRICT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4966
                    return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4967
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4968
                return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4969
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4970
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4971
        return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4972
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4973
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4974
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4975
     * Peek ahead to see if what follows after the ellipsis is a rest parameter
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4976
     * at the end of an arrow function parameter list.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4977
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4978
    private boolean isRestParameterEndOfArrowFunctionParameterList() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4979
        assert type == ELLIPSIS;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4980
        // find IDENT, RPAREN, ARROW, in that order, skipping over EOL (where allowed) and COMMENT
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4981
        int i = 1;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4982
        for (;;) {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4983
            final TokenType t = T(k + i++);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4984
            if (t == IDENT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4985
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4986
            } else if (t == EOL || t == COMMENT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4987
                continue;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4988
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4989
                return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4990
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4991
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4992
        for (;;) {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4993
            final TokenType t = T(k + i++);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4994
            if (t == RPAREN) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4995
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4996
            } else if (t == EOL || t == COMMENT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4997
                continue;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4998
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4999
                return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5000
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5001
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5002
        for (;;) {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  5003
            final TokenType t = T(k + i++);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5004
            if (t == ARROW) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5005
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5006
            } else if (t == COMMENT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5007
                continue;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5008
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5009
                return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5010
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5011
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5012
        return true;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5013
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5014
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5015
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5016
     * Parse an end of line.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5017
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5018
    private void endOfLine() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5019
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5020
        case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5021
        case EOL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5022
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5023
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5024
        case RPAREN:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5025
        case RBRACKET:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5026
        case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5027
        case EOF:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5028
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5029
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5030
            if (last != EOL) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5031
                expect(SEMICOLON);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5032
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5033
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5034
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5035
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5036
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5037
    /**
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5038
     * Parse untagged template literal as string concatenation.
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5039
     */
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5040
    private Expression templateLiteral() {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5041
        assert type == TEMPLATE || type == TEMPLATE_HEAD;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5042
        final boolean noSubstitutionTemplate = type == TEMPLATE;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5043
        long lastLiteralToken = token;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5044
        LiteralNode<?> literal = getLiteral();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5045
        if (noSubstitutionTemplate) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5046
            return literal;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5047
        }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5048
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5049
        if (env._parse_only) {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  5050
            final List<Expression> exprs = new ArrayList<>();
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5051
            exprs.add(literal);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5052
            TokenType lastLiteralType;
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5053
            do {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5054
                final Expression expression = expression();
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5055
                if (type != TEMPLATE_MIDDLE && type != TEMPLATE_TAIL) {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5056
                    throw error(AbstractParser.message("unterminated.template.expression"), token);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5057
                }
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5058
                exprs.add(expression);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5059
                lastLiteralType = type;
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5060
                literal = getLiteral();
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5061
                exprs.add(literal);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5062
            } while (lastLiteralType == TEMPLATE_MIDDLE);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5063
            return new TemplateLiteral(exprs);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5064
        } else {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5065
            Expression concat = literal;
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5066
            TokenType lastLiteralType;
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5067
            do {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5068
                final Expression expression = expression();
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5069
                if (type != TEMPLATE_MIDDLE && type != TEMPLATE_TAIL) {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5070
                    throw error(AbstractParser.message("unterminated.template.expression"), token);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5071
                }
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5072
                concat = new BinaryNode(Token.recast(lastLiteralToken, TokenType.ADD), concat, expression);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5073
                lastLiteralType = type;
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5074
                lastLiteralToken = token;
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5075
                literal = getLiteral();
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5076
                concat = new BinaryNode(Token.recast(lastLiteralToken, TokenType.ADD), concat, literal);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5077
            } while (lastLiteralType == TEMPLATE_MIDDLE);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5078
            return concat;
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5079
        }
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5080
    }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5081
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5082
    /**
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5083
     * Parse tagged template literal as argument list.
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5084
     * @return argument list for a tag function call (template object, ...substitutions)
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5085
     */
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5086
    private List<Expression> templateLiteralArgumentList() {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5087
        assert type == TEMPLATE || type == TEMPLATE_HEAD;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5088
        final ArrayList<Expression> argumentList = new ArrayList<>();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5089
        final ArrayList<Expression> rawStrings = new ArrayList<>();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5090
        final ArrayList<Expression> cookedStrings = new ArrayList<>();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5091
        argumentList.add(null); // filled at the end
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5092
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5093
        final long templateToken = token;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5094
        final boolean hasSubstitutions = type == TEMPLATE_HEAD;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5095
        addTemplateLiteralString(rawStrings, cookedStrings);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5096
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5097
        if (hasSubstitutions) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5098
            TokenType lastLiteralType;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5099
            do {
34447
ec4c069f9436 8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents: 33888
diff changeset
  5100
                final Expression expression = expression();
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5101
                if (type != TEMPLATE_MIDDLE && type != TEMPLATE_TAIL) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5102
                    throw error(AbstractParser.message("unterminated.template.expression"), token);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5103
                }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5104
                argumentList.add(expression);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5105
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5106
                lastLiteralType = type;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5107
                addTemplateLiteralString(rawStrings, cookedStrings);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5108
            } while (lastLiteralType == TEMPLATE_MIDDLE);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5109
        }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5110
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5111
        final LiteralNode<Expression[]> rawStringArray = LiteralNode.newInstance(templateToken, finish, rawStrings);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5112
        final LiteralNode<Expression[]> cookedStringArray = LiteralNode.newInstance(templateToken, finish, cookedStrings);
47287
8eb5e3ccee56 8188098: NPE in SimpleTreeVisitorES6 visitor when parsing a tagged template literal
sundar
parents: 47262
diff changeset
  5113
8eb5e3ccee56 8188098: NPE in SimpleTreeVisitorES6 visitor when parsing a tagged template literal
sundar
parents: 47262
diff changeset
  5114
        if (!env._parse_only) {
8eb5e3ccee56 8188098: NPE in SimpleTreeVisitorES6 visitor when parsing a tagged template literal
sundar
parents: 47262
diff changeset
  5115
            final RuntimeNode templateObject = new RuntimeNode(templateToken, finish, RuntimeNode.Request.GET_TEMPLATE_OBJECT, rawStringArray, cookedStringArray);
8eb5e3ccee56 8188098: NPE in SimpleTreeVisitorES6 visitor when parsing a tagged template literal
sundar
parents: 47262
diff changeset
  5116
            argumentList.set(0, templateObject);
8eb5e3ccee56 8188098: NPE in SimpleTreeVisitorES6 visitor when parsing a tagged template literal
sundar
parents: 47262
diff changeset
  5117
        } else {
8eb5e3ccee56 8188098: NPE in SimpleTreeVisitorES6 visitor when parsing a tagged template literal
sundar
parents: 47262
diff changeset
  5118
            argumentList.set(0, rawStringArray);
8eb5e3ccee56 8188098: NPE in SimpleTreeVisitorES6 visitor when parsing a tagged template literal
sundar
parents: 47262
diff changeset
  5119
        }
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5120
        return optimizeList(argumentList);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5121
    }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5122
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5123
    private void addTemplateLiteralString(final ArrayList<Expression> rawStrings, final ArrayList<Expression> cookedStrings) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5124
        final long stringToken = token;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5125
        final String rawString = lexer.valueOfRawString(stringToken);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5126
        final String cookedString = (String) getValue();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5127
        next();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5128
        rawStrings.add(LiteralNode.newInstance(stringToken, finish, rawString));
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5129
        cookedStrings.add(LiteralNode.newInstance(stringToken, finish, cookedString));
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5130
    }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5131
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5132
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5133
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5134
     * Parse a module.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5135
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5136
     * Module :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5137
     *      ModuleBody?
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5138
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5139
     * ModuleBody :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5140
     *      ModuleItemList
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5141
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5142
    private FunctionNode module(final String moduleName) {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  5143
        final boolean oldStrictMode = isStrictMode;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5144
        try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5145
            isStrictMode = true; // Module code is always strict mode code. (ES6 10.2.1)
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5146
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5147
            // Make a pseudo-token for the script holding its start and length.
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  5148
            final int functionStart = Math.min(Token.descPosition(Token.withDelimiter(token)), finish);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5149
            final long functionToken = Token.toDesc(FUNCTION, functionStart, source.getLength() - functionStart);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5150
            final int  functionLine  = line;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5151
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5152
            final IdentNode ident = new IdentNode(functionToken, Token.descPosition(functionToken), moduleName);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5153
            final ParserContextFunctionNode script = createParserContextFunctionNode(
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5154
                            ident,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5155
                            functionToken,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5156
                            FunctionNode.Kind.MODULE,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5157
                            functionLine,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5158
                            Collections.<IdentNode>emptyList());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5159
            lc.push(script);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5160
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5161
            final ParserContextModuleNode module = new ParserContextModuleNode(moduleName);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5162
            lc.push(module);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5163
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5164
            final ParserContextBlockNode body = newBlock();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5165
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5166
            functionDeclarations = new ArrayList<>();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5167
            moduleBody();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5168
            addFunctionDeclarations(script);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5169
            functionDeclarations = null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5170
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5171
            restoreBlock(body);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5172
            body.setFlag(Block.NEEDS_SCOPE);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5173
            final Block programBody = new Block(functionToken, finish, body.getFlags() | Block.IS_SYNTHETIC | Block.IS_BODY, body.getStatements());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5174
            lc.pop(module);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5175
            lc.pop(script);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5176
            script.setLastToken(token);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5177
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5178
            expect(EOF);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5179
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5180
            script.setModule(module.createModule());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5181
            return createFunctionNode(script, functionToken, ident, Collections.<IdentNode>emptyList(), FunctionNode.Kind.MODULE, functionLine, programBody);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5182
        } finally {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5183
            isStrictMode = oldStrictMode;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5184
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5185
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5186
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5187
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5188
     * Parse module body.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5189
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5190
     * ModuleBody :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5191
     *      ModuleItemList
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5192
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5193
     * ModuleItemList :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5194
     *      ModuleItem
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5195
     *      ModuleItemList ModuleItem
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5196
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5197
     * ModuleItem :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5198
     *      ImportDeclaration
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5199
     *      ExportDeclaration
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5200
     *      StatementListItem
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5201
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5202
    private void moduleBody() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5203
        loop:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5204
        while (type != EOF) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5205
            switch (type) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5206
            case EOF:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5207
                break loop;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5208
            case IMPORT:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5209
                importDeclaration();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5210
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5211
            case EXPORT:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5212
                exportDeclaration();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5213
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5214
            default:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5215
                // StatementListItem
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
  5216
                statement(true, 0, false, false);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5217
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5218
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5219
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5220
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5221
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5222
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5223
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5224
     * Parse import declaration.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5225
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5226
     * ImportDeclaration :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5227
     *     import ImportClause FromClause ;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5228
     *     import ModuleSpecifier ;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5229
     * ImportClause :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5230
     *     ImportedDefaultBinding
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5231
     *     NameSpaceImport
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5232
     *     NamedImports
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5233
     *     ImportedDefaultBinding , NameSpaceImport
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5234
     *     ImportedDefaultBinding , NamedImports
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5235
     * ImportedDefaultBinding :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5236
     *     ImportedBinding
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5237
     * ModuleSpecifier :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5238
     *     StringLiteral
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5239
     * ImportedBinding :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5240
     *     BindingIdentifier
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5241
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5242
    private void importDeclaration() {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5243
        final int startPosition = start;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5244
        expect(IMPORT);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5245
        final ParserContextModuleNode module = lc.getCurrentModule();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5246
        if (type == STRING || type == ESCSTRING) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5247
            // import ModuleSpecifier ;
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5248
            final IdentNode moduleSpecifier = createIdentNode(token, finish, (String) getValue());
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5249
            next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5250
            module.addModuleRequest(moduleSpecifier);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5251
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5252
            // import ImportClause FromClause ;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5253
            List<Module.ImportEntry> importEntries;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5254
            if (type == MUL) {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5255
                importEntries = Collections.singletonList(nameSpaceImport(startPosition));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5256
            } else if (type == LBRACE) {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5257
                importEntries = namedImports(startPosition);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5258
            } else if (isBindingIdentifier()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5259
                // ImportedDefaultBinding
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5260
                final IdentNode importedDefaultBinding = bindingIdentifier("ImportedBinding");
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  5261
                final Module.ImportEntry defaultImport = Module.ImportEntry.importSpecifier(importedDefaultBinding, startPosition, finish);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5262
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5263
                if (type == COMMARIGHT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5264
                    next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5265
                    importEntries = new ArrayList<>();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5266
                    if (type == MUL) {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5267
                        importEntries.add(nameSpaceImport(startPosition));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5268
                    } else if (type == LBRACE) {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5269
                        importEntries.addAll(namedImports(startPosition));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5270
                    } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5271
                        throw error(AbstractParser.message("expected.named.import"));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5272
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5273
                } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5274
                    importEntries = Collections.singletonList(defaultImport);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5275
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5276
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5277
                throw error(AbstractParser.message("expected.import"));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5278
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5279
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5280
            final IdentNode moduleSpecifier = fromClause();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5281
            module.addModuleRequest(moduleSpecifier);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5282
            for (int i = 0; i < importEntries.size(); i++) {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5283
                module.addImportEntry(importEntries.get(i).withFrom(moduleSpecifier, finish));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5284
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5285
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5286
        expect(SEMICOLON);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5287
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5288
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5289
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5290
     * NameSpaceImport :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5291
     *     * as ImportedBinding
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5292
     *
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5293
     * @param startPosition the start of the import declaration
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5294
     * @return imported binding identifier
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5295
     */
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5296
    private Module.ImportEntry nameSpaceImport(final int startPosition) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5297
        assert type == MUL;
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5298
        final IdentNode starName = createIdentNode(Token.recast(token, IDENT), finish, Module.STAR_NAME);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5299
        next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5300
        final long asToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5301
        final String as = (String) expectValue(IDENT);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5302
        if (!"as".equals(as)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5303
            throw error(AbstractParser.message("expected.as"), asToken);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5304
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5305
        final IdentNode localNameSpace = bindingIdentifier("ImportedBinding");
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5306
        return Module.ImportEntry.importSpecifier(starName, localNameSpace, startPosition, finish);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5307
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5308
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5309
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5310
     * NamedImports :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5311
     *     { }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5312
     *     { ImportsList }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5313
     *     { ImportsList , }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5314
     * ImportsList :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5315
     *     ImportSpecifier
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5316
     *     ImportsList , ImportSpecifier
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5317
     * ImportSpecifier :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5318
     *     ImportedBinding
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5319
     *     IdentifierName as ImportedBinding
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5320
     * ImportedBinding :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5321
     *     BindingIdentifier
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5322
     */
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5323
    private List<Module.ImportEntry> namedImports(final int startPosition) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5324
        assert type == LBRACE;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5325
        next();
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  5326
        final List<Module.ImportEntry> importEntries = new ArrayList<>();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5327
        while (type != RBRACE) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5328
            final boolean bindingIdentifier = isBindingIdentifier();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5329
            final long nameToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5330
            final IdentNode importName = getIdentifierName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5331
            if (type == IDENT && "as".equals(getValue())) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5332
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5333
                final IdentNode localName = bindingIdentifier("ImportedBinding");
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5334
                importEntries.add(Module.ImportEntry.importSpecifier(importName, localName, startPosition, finish));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5335
            } else if (!bindingIdentifier) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5336
                throw error(AbstractParser.message("expected.binding.identifier"), nameToken);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5337
            } else {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5338
                importEntries.add(Module.ImportEntry.importSpecifier(importName, startPosition, finish));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5339
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5340
            if (type == COMMARIGHT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5341
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5342
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5343
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5344
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5345
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5346
        expect(RBRACE);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5347
        return importEntries;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5348
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5349
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5350
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5351
     * FromClause :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5352
     *     from ModuleSpecifier
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5353
     */
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5354
    private IdentNode fromClause() {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5355
        final long fromToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5356
        final String name = (String) expectValue(IDENT);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5357
        if (!"from".equals(name)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5358
            throw error(AbstractParser.message("expected.from"), fromToken);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5359
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5360
        if (type == STRING || type == ESCSTRING) {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5361
            final IdentNode moduleSpecifier = createIdentNode(Token.recast(token, IDENT), finish, (String) getValue());
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5362
            next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5363
            return moduleSpecifier;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5364
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5365
            throw error(expectMessage(STRING));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5366
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5367
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5368
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5369
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5370
     * Parse export declaration.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5371
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5372
     * ExportDeclaration :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5373
     *     export * FromClause ;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5374
     *     export ExportClause FromClause ;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5375
     *     export ExportClause ;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5376
     *     export VariableStatement
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5377
     *     export Declaration
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5378
     *     export default HoistableDeclaration[Default]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5379
     *     export default ClassDeclaration[Default]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5380
     *     export default [lookahead !in {function, class}] AssignmentExpression[In] ;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5381
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5382
    private void exportDeclaration() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5383
        expect(EXPORT);
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5384
        final int startPosition = start;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5385
        final ParserContextModuleNode module = lc.getCurrentModule();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5386
        switch (type) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5387
            case MUL: {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5388
                final IdentNode starName = createIdentNode(Token.recast(token, IDENT), finish, Module.STAR_NAME);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5389
                next();
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5390
                final IdentNode moduleRequest = fromClause();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5391
                expect(SEMICOLON);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5392
                module.addModuleRequest(moduleRequest);
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5393
                module.addStarExportEntry(Module.ExportEntry.exportStarFrom(starName, moduleRequest, startPosition, finish));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5394
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5395
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5396
            case LBRACE: {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5397
                final List<Module.ExportEntry> exportEntries = exportClause(startPosition);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5398
                if (type == IDENT && "from".equals(getValue())) {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5399
                    final IdentNode moduleRequest = fromClause();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5400
                    module.addModuleRequest(moduleRequest);
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  5401
                    for (final Module.ExportEntry exportEntry : exportEntries) {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5402
                        module.addIndirectExportEntry(exportEntry.withFrom(moduleRequest, finish));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5403
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5404
                } else {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  5405
                    for (final Module.ExportEntry exportEntry : exportEntries) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5406
                        module.addLocalExportEntry(exportEntry);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5407
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5408
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5409
                expect(SEMICOLON);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5410
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5411
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5412
            case DEFAULT:
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5413
                final IdentNode defaultName = createIdentNode(Token.recast(token, IDENT), finish, Module.DEFAULT_NAME);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5414
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5415
                final Expression assignmentExpression;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5416
                IdentNode ident;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5417
                final int lineNumber = line;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5418
                final long rhsToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5419
                final boolean declaration;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5420
                switch (type) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5421
                    case FUNCTION:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5422
                        assignmentExpression = functionExpression(false, true);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5423
                        ident = ((FunctionNode) assignmentExpression).getIdent();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5424
                        declaration = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5425
                        break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5426
                    case CLASS:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5427
                        assignmentExpression = classDeclaration(true);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5428
                        ident = ((ClassNode) assignmentExpression).getIdent();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5429
                        declaration = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5430
                        break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5431
                    default:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5432
                        assignmentExpression = assignmentExpression(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5433
                        ident = null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5434
                        declaration = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5435
                        break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5436
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5437
                if (ident != null) {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5438
                    module.addLocalExportEntry(Module.ExportEntry.exportDefault(defaultName, ident, startPosition, finish));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5439
                } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5440
                    ident = createIdentNode(Token.recast(rhsToken, IDENT), finish, Module.DEFAULT_EXPORT_BINDING_NAME);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5441
                    lc.appendStatementToCurrentNode(new VarNode(lineNumber, Token.recast(rhsToken, LET), finish, ident, assignmentExpression));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5442
                    if (!declaration) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5443
                        expect(SEMICOLON);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5444
                    }
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5445
                    module.addLocalExportEntry(Module.ExportEntry.exportDefault(defaultName, ident, startPosition, finish));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5446
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5447
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5448
            case VAR:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5449
            case LET:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5450
            case CONST:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5451
                final List<Statement> statements = lc.getCurrentBlock().getStatements();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5452
                final int previousEnd = statements.size();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5453
                variableStatement(type);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5454
                for (final Statement statement : statements.subList(previousEnd, statements.size())) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5455
                    if (statement instanceof VarNode) {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5456
                        module.addLocalExportEntry(Module.ExportEntry.exportSpecifier(((VarNode) statement).getName(), startPosition, finish));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5457
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5458
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5459
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5460
            case CLASS: {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5461
                final ClassNode classDeclaration = classDeclaration(false);
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5462
                module.addLocalExportEntry(Module.ExportEntry.exportSpecifier(classDeclaration.getIdent(), startPosition, finish));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5463
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5464
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5465
            case FUNCTION: {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5466
                final FunctionNode functionDeclaration = (FunctionNode) functionExpression(true, true);
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5467
                module.addLocalExportEntry(Module.ExportEntry.exportSpecifier(functionDeclaration.getIdent(), startPosition, finish));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5468
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5469
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5470
            default:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5471
                throw error(AbstractParser.message("invalid.export"), token);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5472
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5473
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5474
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5475
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5476
     * ExportClause :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5477
     *     { }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5478
     *     { ExportsList }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5479
     *     { ExportsList , }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5480
     * ExportsList :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5481
     *     ExportSpecifier
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5482
     *     ExportsList , ExportSpecifier
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5483
     * ExportSpecifier :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5484
     *     IdentifierName
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5485
     *     IdentifierName as IdentifierName
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5486
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5487
     * @return a list of ExportSpecifiers
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5488
     */
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5489
    private List<Module.ExportEntry> exportClause(final int startPosition) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5490
        assert type == LBRACE;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5491
        next();
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  5492
        final List<Module.ExportEntry> exports = new ArrayList<>();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5493
        while (type != RBRACE) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5494
            final IdentNode localName = getIdentifierName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5495
            if (type == IDENT && "as".equals(getValue())) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5496
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5497
                final IdentNode exportName = getIdentifierName();
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5498
                exports.add(Module.ExportEntry.exportSpecifier(exportName, localName, startPosition, finish));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5499
            } else {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5500
                exports.add(Module.ExportEntry.exportSpecifier(localName, startPosition, finish));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5501
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5502
            if (type == COMMARIGHT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5503
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5504
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5505
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5506
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5507
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5508
        expect(RBRACE);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5509
        return exports;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5510
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5511
16252
3bfe9b68a0fa 8008648: Lazy JIT scope and callee semantics bugfixes. Broke out wallclock timer.
lagergren
parents: 16245
diff changeset
  5512
    @Override
3bfe9b68a0fa 8008648: Lazy JIT scope and callee semantics bugfixes. Broke out wallclock timer.
lagergren
parents: 16245
diff changeset
  5513
    public String toString() {
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
  5514
        return "'JavaScript Parsing'";
16252
3bfe9b68a0fa 8008648: Lazy JIT scope and callee semantics bugfixes. Broke out wallclock timer.
lagergren
parents: 16245
diff changeset
  5515
    }
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  5516
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  5517
    private static void markEval(final ParserContext lc) {
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  5518
        final Iterator<ParserContextFunctionNode> iter = lc.getFunctions();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  5519
        boolean flaggedCurrentFn = false;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  5520
        while (iter.hasNext()) {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  5521
            final ParserContextFunctionNode fn = iter.next();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  5522
            if (!flaggedCurrentFn) {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  5523
                fn.setFlag(FunctionNode.HAS_EVAL);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  5524
                flaggedCurrentFn = true;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5525
                if (fn.getKind() == FunctionNode.Kind.ARROW) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5526
                    // possible use of this in an eval that's nested in an arrow function, e.g.:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5527
                    // function fun(){ return (() => eval("this"))(); };
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5528
                    markThis(lc);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5529
                    markNewTarget(lc);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5530
                }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  5531
            } else {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  5532
                fn.setFlag(FunctionNode.HAS_NESTED_EVAL);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  5533
            }
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  5534
            final ParserContextBlockNode body = lc.getFunctionBody(fn);
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  5535
            // NOTE: it is crucial to mark the body of the outer function as needing scope even when we skip
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  5536
            // parsing a nested function. functionBody() contains code to compensate for the lack of invoking
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  5537
            // this method when the parser skips a nested function.
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  5538
            body.setFlag(Block.NEEDS_SCOPE);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  5539
            fn.setFlag(FunctionNode.HAS_SCOPE_BLOCK);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  5540
        }
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  5541
    }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  5542
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  5543
    private void prependStatement(final Statement statement) {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  5544
        lc.prependStatementToCurrentNode(statement);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  5545
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  5546
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  5547
    private void appendStatement(final Statement statement) {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  5548
        lc.appendStatementToCurrentNode(statement);
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  5549
    }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5550
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5551
    private static void markSuperCall(final ParserContext lc) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5552
        final Iterator<ParserContextFunctionNode> iter = lc.getFunctions();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5553
        while (iter.hasNext()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5554
            final ParserContextFunctionNode fn = iter.next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5555
            if (fn.getKind() != FunctionNode.Kind.ARROW) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5556
                assert fn.isSubclassConstructor();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5557
                fn.setFlag(FunctionNode.ES6_HAS_DIRECT_SUPER);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5558
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5559
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5560
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5561
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5562
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5563
    private ParserContextFunctionNode getCurrentNonArrowFunction() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5564
        final Iterator<ParserContextFunctionNode> iter = lc.getFunctions();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5565
        while (iter.hasNext()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5566
            final ParserContextFunctionNode fn = iter.next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5567
            if (fn.getKind() != FunctionNode.Kind.ARROW) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5568
                return fn;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5569
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5570
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5571
        return null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5572
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5573
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5574
    private static void markThis(final ParserContext lc) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5575
        final Iterator<ParserContextFunctionNode> iter = lc.getFunctions();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5576
        while (iter.hasNext()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5577
            final ParserContextFunctionNode fn = iter.next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5578
            fn.setFlag(FunctionNode.USES_THIS);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5579
            if (fn.getKind() != FunctionNode.Kind.ARROW) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5580
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5581
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5582
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5583
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5584
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5585
    private static void markNewTarget(final ParserContext lc) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5586
        final Iterator<ParserContextFunctionNode> iter = lc.getFunctions();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5587
        while (iter.hasNext()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5588
            final ParserContextFunctionNode fn = iter.next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5589
            if (fn.getKind() != FunctionNode.Kind.ARROW) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5590
                if (!fn.isProgram()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5591
                    fn.setFlag(FunctionNode.ES6_USES_NEW_TARGET);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5592
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5593
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5594
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5595
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5596
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5597
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5598
    private boolean inGeneratorFunction() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5599
        return lc.getCurrentFunction().getKind() == FunctionNode.Kind.GENERATOR;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5600
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5601
}