src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java
author erikj
Tue, 12 Sep 2017 19:03:39 +0200
changeset 47216 71c04702a3d5
parent 47038 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java@f57fa7f112a0
child 47262 bbbf1b1e36e9
permissions -rw-r--r--
8187443: Forest Consolidation: Move files to unified layout Reviewed-by: darcy, ihse
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);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1475
        if (isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1476
            final TokenType tokenType = TokenLookup.lookupKeyword(ident.getName().toCharArray(), 0, ident.getName().length());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1477
            if (tokenType != IDENT && tokenType.getKind() != TokenKind.FUTURESTRICT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1478
                throw error(expectMessage(IDENT));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1479
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1480
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1481
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1482
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1483
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1484
     * Make sure that in strict mode, the identifier name used is allowed.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1485
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1486
     * @param ident         Identifier that is verified
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1487
     * @param contextString String used in error message to give context to the user
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1488
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1489
    private void verifyStrictIdent(final IdentNode ident, final String contextString) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1490
        if (isStrictMode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1491
            switch (ident.getName()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1492
            case "eval":
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1493
            case "arguments":
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1494
                throw error(AbstractParser.message("strict.name", ident.getName(), contextString), ident.getToken());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1495
            default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1496
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1497
            }
20571
f52b0abf5d88 8026039: future strict names are allowed as function name and argument name of a strict function
sundar
parents: 20559
diff changeset
  1498
f52b0abf5d88 8026039: future strict names are allowed as function name and argument name of a strict function
sundar
parents: 20559
diff changeset
  1499
            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
  1500
                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
  1501
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1502
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1503
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1504
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1505
    /*
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1506
     * VariableStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1507
     *      var VariableDeclarationList ;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1508
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1509
     * VariableDeclarationList :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1510
     *      VariableDeclaration
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1511
     *      VariableDeclarationList , VariableDeclaration
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1512
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1513
     * VariableDeclaration :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1514
     *      Identifier Initializer?
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1515
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1516
     * Initializer :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1517
     *      = AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1518
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1519
     * See 12.2
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1520
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1521
     * Parse a VAR statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1522
     * @param isStatement True if a statement (not used in a FOR.)
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1523
     */
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1524
    private void variableStatement(final TokenType varType) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1525
        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
  1526
    }
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
  1527
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1528
    private static final class ForVariableDeclarationListResult {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1529
        /** First missing const or binding pattern initializer. */
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1530
        Expression missingAssignment;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1531
        /** First declaration with an initializer. */
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1532
        long declarationWithInitializerToken;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1533
        /** Destructuring assignments. */
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1534
        Expression init;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1535
        Expression firstBinding;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1536
        Expression secondBinding;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1537
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1538
        void recordMissingAssignment(final Expression binding) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1539
            if (missingAssignment == null) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1540
                missingAssignment = binding;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1541
            }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1542
        }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1543
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1544
        void recordDeclarationWithInitializer(final long token) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1545
            if (declarationWithInitializerToken == 0L) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1546
                declarationWithInitializerToken = token;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1547
            }
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
        void addBinding(final Expression binding) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1551
            if (firstBinding == null) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1552
                firstBinding = binding;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1553
            } else if (secondBinding == null)  {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1554
                secondBinding = binding;
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
            // ignore the rest
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1557
        }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1558
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1559
        void addAssignment(final Expression assignment) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1560
            if (init == null) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1561
                init = assignment;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1562
            } else {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1563
                init = new BinaryNode(Token.recast(init.getToken(), COMMARIGHT), init, assignment);
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
    }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1567
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1568
    /**
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1569
     * @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
  1570
     */
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1571
    private ForVariableDeclarationListResult variableDeclarationList(final TokenType varType, final boolean isStatement, final int sourceOrder) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1572
        // VAR tested in caller.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1573
        assert varType == VAR || varType == LET || varType == CONST;
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  1574
        final int varLine = line;
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  1575
        final long varToken = token;
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  1576
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1577
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1578
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  1579
        int varFlags = 0;
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1580
        if (varType == LET) {
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1581
            varFlags |= VarNode.IS_LET;
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1582
        } else if (varType == CONST) {
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1583
            varFlags |= VarNode.IS_CONST;
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1584
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1585
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1586
        final ForVariableDeclarationListResult forResult = isStatement ? null : new ForVariableDeclarationListResult();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1587
        while (true) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1588
            // Get name of var.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1589
            if (type == YIELD && inGeneratorFunction()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1590
                expect(IDENT);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1591
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1592
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1593
            final String contextString = "variable name";
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1594
            final Expression binding = bindingIdentifierOrPattern(contextString);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1595
            final boolean isDestructuring = !(binding instanceof IdentNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1596
            if (isDestructuring) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1597
                final int finalVarFlags = varFlags;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1598
                verifyDestructuringBindingPattern(binding, new Consumer<IdentNode>() {
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  1599
                    @Override
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1600
                    public void accept(final IdentNode identNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1601
                        verifyIdent(identNode, contextString);
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  1602
                        if (!env._parse_only) {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  1603
                            // 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
  1604
                            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
  1605
                            appendStatement(var);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  1606
                        }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1607
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1608
                });
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1609
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1610
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1611
            // Assume no init.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1612
            Expression init = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1613
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1614
            // Look for initializer assignment.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1615
            if (type == ASSIGN) {
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1616
                if (!isStatement) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1617
                    forResult.recordDeclarationWithInitializer(varToken);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1618
                }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1619
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1620
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1621
                // Get initializer expression. Suppress IN if not statement.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1622
                if (!isDestructuring) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1623
                    defaultNames.push(binding);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1624
                }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1625
                try {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1626
                    init = assignmentExpression(!isStatement);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1627
                } finally {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1628
                    if (!isDestructuring) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1629
                        defaultNames.pop();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1630
                    }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1631
                }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1632
            } else if (isStatement) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1633
                if (isDestructuring) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1634
                    throw error(AbstractParser.message("missing.destructuring.assignment"), token);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1635
                } else if (varType == CONST) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1636
                    throw error(AbstractParser.message("missing.const.assignment", ((IdentNode)binding).getName()));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1637
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1638
                // 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
  1639
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1640
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1641
            if (!isDestructuring) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1642
                assert init != null || varType != CONST || !isStatement;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1643
                final IdentNode ident = (IdentNode)binding;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1644
                if (!isStatement && ident.getName().equals("let")) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1645
                    throw error(AbstractParser.message("let.binding.for")); //ES6 13.7.5.1
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1646
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1647
                // 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
  1648
                final IdentNode name = varType == LET || varType == CONST ? ident.setIsDeclaredHere() : ident;
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1649
                if (!isStatement) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1650
                    if (init == null && varType == CONST) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1651
                        forResult.recordMissingAssignment(name);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1652
                    }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1653
                    forResult.addBinding(new IdentNode(name));
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1654
                }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1655
                final VarNode var = new VarNode(varLine, varToken, sourceOrder, finish, name, init, varFlags);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1656
                appendStatement(var);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1657
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1658
                assert init != null || !isStatement;
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1659
                if (init != null) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1660
                    final Expression assignment = verifyAssignment(Token.recast(varToken, ASSIGN), binding, init);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1661
                    if (isStatement) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1662
                        appendStatement(new ExpressionStatement(varLine, assignment.getToken(), finish, assignment, varType));
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1663
                    } else {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1664
                        forResult.addAssignment(assignment);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1665
                        forResult.addBinding(assignment);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1666
                    }
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1667
                } else if (!isStatement) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1668
                    forResult.recordMissingAssignment(binding);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1669
                    forResult.addBinding(binding);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1670
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1671
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1672
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1673
            if (type != COMMARIGHT) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1674
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1675
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1676
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1677
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1678
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1679
        // If is a statement then handle end of line.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1680
        if (isStatement) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1681
            endOfLine();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1682
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1683
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1684
        return forResult;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1685
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1686
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1687
    private boolean isBindingIdentifier() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1688
        return type == IDENT || isNonStrictModeIdent();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1689
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1690
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1691
    private IdentNode bindingIdentifier(final String contextString) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1692
        final IdentNode name = getIdent();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1693
        verifyIdent(name, contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1694
        return name;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1695
    }
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
    private Expression bindingPattern() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1698
        if (type == LBRACKET) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1699
            return arrayLiteral();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1700
        } else if (type == LBRACE) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1701
            return objectLiteral();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1702
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1703
            throw error(AbstractParser.message("expected.binding"));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1704
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1705
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1706
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1707
    private Expression bindingIdentifierOrPattern(final String contextString) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1708
        if (isBindingIdentifier() || !isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1709
            return bindingIdentifier(contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1710
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1711
            return bindingPattern();
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
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1715
    private abstract class VerifyDestructuringPatternNodeVisitor extends NodeVisitor<LexicalContext> {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1716
        VerifyDestructuringPatternNodeVisitor(final LexicalContext lc) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1717
            super(lc);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1718
        }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1719
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1720
        @Override
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1721
        public boolean enterLiteralNode(final LiteralNode<?> literalNode) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1722
            if (literalNode.isArray()) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1723
                if (((LiteralNode.ArrayLiteralNode)literalNode).hasSpread() && ((LiteralNode.ArrayLiteralNode)literalNode).hasTrailingComma()) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1724
                    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
  1725
                }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1726
                boolean restElement = false;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1727
                for (final Expression element : literalNode.getElementExpressions()) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1728
                    if (element != null) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1729
                        if (restElement) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1730
                            throw error("Unexpected element after rest element", element.getToken());
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1731
                        }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1732
                        if (element.isTokenType(SPREAD_ARRAY)) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1733
                            restElement = true;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1734
                            final Expression lvalue = ((UnaryNode) element).getExpression();
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1735
                            verifySpreadElement(lvalue);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1736
                        }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1737
                        element.accept(this);
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
                }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1740
                return false;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1741
            } else {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1742
                return enterDefault(literalNode);
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
        }
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
        protected abstract void verifySpreadElement(Expression lvalue);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1747
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1748
        @Override
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1749
        public boolean enterObjectNode(final ObjectNode objectNode) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1750
            return true;
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
        @Override
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1754
        public boolean enterPropertyNode(final PropertyNode propertyNode) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1755
            if (propertyNode.getValue() != null) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1756
                propertyNode.getValue().accept(this);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1757
                return false;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1758
            } else {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1759
                return enterDefault(propertyNode);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1760
            }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1761
        }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1762
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1763
        @Override
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1764
        public boolean enterBinaryNode(final BinaryNode binaryNode) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1765
            if (binaryNode.isTokenType(ASSIGN)) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1766
                binaryNode.lhs().accept(this);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1767
                // Initializer(rhs) can be any AssignmentExpression
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1768
                return false;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1769
            } else {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1770
                return enterDefault(binaryNode);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1771
            }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1772
        }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1773
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1774
        @Override
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1775
        public boolean enterUnaryNode(final UnaryNode unaryNode) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1776
            if (unaryNode.isTokenType(SPREAD_ARRAY)) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1777
                // rest element
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1778
                return true;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1779
            } else {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1780
                return enterDefault(unaryNode);
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1781
            }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1782
        }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1783
    }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1784
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1785
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1786
     * Verify destructuring variable declaration binding pattern and extract bound variable declarations.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1787
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1788
    private void verifyDestructuringBindingPattern(final Expression pattern, final Consumer<IdentNode> identifierCallback) {
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1789
        assert (pattern instanceof BinaryNode && pattern.isTokenType(ASSIGN)) ||
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  1790
                pattern instanceof ObjectNode || pattern instanceof LiteralNode.ArrayLiteralNode;
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1791
        pattern.accept(new VerifyDestructuringPatternNodeVisitor(new LexicalContext()) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1792
            @Override
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1793
            protected void verifySpreadElement(final Expression lvalue) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1794
                if (lvalue instanceof IdentNode) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1795
                    // checked in identifierCallback
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1796
                } else if (isDestructuringLhs(lvalue)) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1797
                    verifyDestructuringBindingPattern(lvalue, identifierCallback);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1798
                } else {
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1799
                    throw error("Expected a valid binding identifier", lvalue.getToken());
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1800
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1801
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1802
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1803
            @Override
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1804
            public boolean enterIdentNode(final IdentNode identNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1805
                identifierCallback.accept(identNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1806
                return false;
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
            @Override
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1810
            protected boolean enterDefault(final Node node) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1811
                throw error(String.format("unexpected node in BindingPattern: %s", node));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1812
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1813
        });
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1814
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1815
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1816
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1817
     * EmptyStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1818
     *      ;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1819
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1820
     * See 12.3
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1821
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1822
     * Parse an empty statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1823
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1824
    private void emptyStatement() {
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
  1825
        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
  1826
            appendStatement(new EmptyNode(line, token, Token.descPosition(token) + Token.descLength(token)));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1827
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1828
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1829
        // SEMICOLON checked in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1830
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1831
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1832
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1833
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1834
     * ExpressionStatement :
37924
a78497edf9fb 8156714: Parsing issue with automatic semicolon insertion
hannesw
parents: 37923
diff changeset
  1835
     *      Expression ; // [lookahead ~({ or  function )]
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1836
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1837
     * See 12.4
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1838
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1839
     * Parse an expression used in a statement block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1840
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1841
    private void expressionStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1842
        // 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
  1843
        final int  expressionLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1844
        final long expressionToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1845
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1846
        // Get expression and add as statement.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1847
        final Expression expression = expression();
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1848
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1849
        if (expression != null) {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  1850
            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
  1851
            appendStatement(expressionStatement);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1852
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1853
            expect(null);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1854
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1855
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1856
        endOfLine();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1857
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1858
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1859
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1860
     * IfStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1861
     *      if ( Expression ) Statement else Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1862
     *      if ( Expression ) Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1863
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1864
     * See 12.5
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1865
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1866
     * Parse an IF statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1867
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1868
    private void ifStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1869
        // 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
  1870
        final int  ifLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1871
        final long ifToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1872
         // IF tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1873
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1874
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1875
        expect(LPAREN);
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1876
        final Expression test = expression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1877
        expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1878
        final Block pass = getStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1879
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1880
        Block fail = null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1881
        if (type == ELSE) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1882
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1883
            fail = getStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1884
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1885
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
  1886
        appendStatement(new IfNode(ifLine, ifToken, fail != null ? fail.getFinish() : pass.getFinish(), test, pass, fail));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1887
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1888
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1889
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1890
     * ... IterationStatement:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1891
     *           ...
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1892
     *           for ( Expression[NoIn]?; Expression? ; Expression? ) Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1893
     *           for ( var VariableDeclarationList[NoIn]; Expression? ; Expression? ) Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1894
     *           for ( LeftHandSideExpression in Expression ) Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1895
     *           for ( var VariableDeclaration[NoIn] in Expression ) Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1896
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1897
     * See 12.6
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1898
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1899
     * Parse a FOR statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1900
     */
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1901
    @SuppressWarnings("fallthrough")
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1902
    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
  1903
        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
  1904
        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
  1905
        // 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
  1906
        // 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
  1907
        // 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
  1908
        final int forStart = Token.descPosition(forToken);
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1909
        // 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
  1910
        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
  1911
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1912
        // 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
  1913
        final ParserContextLoopNode forNode = new ParserContextLoopNode();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1914
        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
  1915
        Block body = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  1916
        Expression init = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  1917
        JoinPredecessorExpression test = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  1918
        JoinPredecessorExpression modify = null;
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1919
        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
  1920
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  1921
        int flags = 0;
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1922
        boolean isForOf = false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1923
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1924
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1925
            // FOR tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1926
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1927
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1928
            // Nashorn extension: for each expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1929
            // 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
  1930
            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
  1931
                flags |= ForNode.IS_FOR_EACH;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1932
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1933
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1934
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1935
            expect(LPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1936
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1937
            TokenType varType = null;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1938
            switch (type) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1939
            case VAR:
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  1940
                // Var declaration captured in for outer block.
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1941
                varDeclList = variableDeclarationList(varType = type, false, forStart);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1942
                break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1943
            case SEMICOLON:
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1944
                break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1945
            default:
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1946
                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
  1947
                    flags |= ForNode.PER_ITERATION_SCOPE;
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  1948
                    // LET/CONST declaration captured in container block created above.
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1949
                    varDeclList = variableDeclarationList(varType = type, false, forStart);
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1950
                    break;
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1951
                }
24279
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
  1952
                if (env._const_as_var && type == CONST) {
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  1953
                    // Var declaration captured in for outer block.
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  1954
                    varDeclList = variableDeclarationList(varType = TokenType.VAR, false, forStart);
24279
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
  1955
                    break;
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
  1956
                }
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
  1957
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  1958
                init = expression(unaryExpression(), COMMARIGHT.getPrecedence(), true);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1959
                break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1960
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1961
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1962
            switch (type) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1963
            case SEMICOLON:
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1964
                // for (init; test; modify)
41924
d55f24e8953e 8156619: Unimplemented ES6 features should result in clear Error being thrown
hannesw
parents: 41425
diff changeset
  1965
                if (varDeclList != null) {
d55f24e8953e 8156619: Unimplemented ES6 features should result in clear Error being thrown
hannesw
parents: 41425
diff changeset
  1966
                    assert init == null;
d55f24e8953e 8156619: Unimplemented ES6 features should result in clear Error being thrown
hannesw
parents: 41425
diff changeset
  1967
                    init = varDeclList.init;
d55f24e8953e 8156619: Unimplemented ES6 features should result in clear Error being thrown
hannesw
parents: 41425
diff changeset
  1968
                    // 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
  1969
                    if (varDeclList.missingAssignment != null) {
d55f24e8953e 8156619: Unimplemented ES6 features should result in clear Error being thrown
hannesw
parents: 41425
diff changeset
  1970
                        if (varDeclList.missingAssignment instanceof IdentNode) {
d55f24e8953e 8156619: Unimplemented ES6 features should result in clear Error being thrown
hannesw
parents: 41425
diff changeset
  1971
                            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
  1972
                        } else {
d55f24e8953e 8156619: Unimplemented ES6 features should result in clear Error being thrown
hannesw
parents: 41425
diff changeset
  1973
                            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
  1974
                        }
d55f24e8953e 8156619: Unimplemented ES6 features should result in clear Error being thrown
hannesw
parents: 41425
diff changeset
  1975
                    }
d55f24e8953e 8156619: Unimplemented ES6 features should result in clear Error being thrown
hannesw
parents: 41425
diff changeset
  1976
                }
18843
eea6d1b8263e 8019805: for each (init; test; modify) is invalid
sundar
parents: 18632
diff changeset
  1977
eea6d1b8263e 8019805: for each (init; test; modify) is invalid
sundar
parents: 18632
diff changeset
  1978
                // 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
  1979
                if ((flags & ForNode.IS_FOR_EACH) != 0) {
18843
eea6d1b8263e 8019805: for each (init; test; modify) is invalid
sundar
parents: 18632
diff changeset
  1980
                    throw error(AbstractParser.message("for.each.without.in"), token);
eea6d1b8263e 8019805: for each (init; test; modify) is invalid
sundar
parents: 18632
diff changeset
  1981
                }
eea6d1b8263e 8019805: for each (init; test; modify) is invalid
sundar
parents: 18632
diff changeset
  1982
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1983
                expect(SEMICOLON);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1984
                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
  1985
                    test = joinPredecessorExpression();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1986
                }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1987
                expect(SEMICOLON);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1988
                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
  1989
                    modify = joinPredecessorExpression();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1990
                }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1991
                break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1992
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1993
            case IDENT:
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1994
                if (env._es6 && "of".equals(getValue())) {
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1995
                    isForOf = true;
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1996
                    // fall through
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1997
                } else {
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1998
                    expect(SEMICOLON); // fail with expected message
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1999
                    break;
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  2000
                }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2001
            case IN:
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  2002
                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
  2003
                test = new JoinPredecessorExpression();
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2004
                if (varDeclList != null) {
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2005
                    // for (var|let|const ForBinding in|of expression)
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2006
                    if (varDeclList.secondBinding != null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2007
                        // for (var i, j in obj) is invalid
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2008
                        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
  2009
                    }
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2010
                    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
  2011
                        // ES5 legacy: for (var i = AssignmentExpressionNoIn in Expression)
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2012
                        // 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
  2013
                        // i.e., error if strict, for-of, let/const, or destructuring
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2014
                        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
  2015
                    }
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2016
                    init = varDeclList.firstBinding;
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2017
                    assert init instanceof IdentNode || isDestructuringLhs(init);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2018
                } else {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2019
                    // for (expr in obj)
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  2020
                    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
  2021
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2022
                    // check if initial expression is a valid L-value
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2023
                    if (!checkValidLValue(init, isForOf ? "for-of iterator" : "for-in iterator")) {
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  2024
                        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
  2025
                    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2026
                }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2027
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2028
                next();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2029
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  2030
                // For-of only allows AssignmentExpression.
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  2031
                modify = isForOf ? new JoinPredecessorExpression(assignmentExpression(false)) : joinPredecessorExpression();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2032
                break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2033
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2034
            default:
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2035
                expect(SEMICOLON);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2036
                break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2037
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2038
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2039
            expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2040
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2041
            // 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
  2042
            body = getStatement();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2043
        } finally {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2044
            lc.pop(forNode);
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2045
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2046
            for (final Statement var : forNode.getStatements()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2047
                assert var instanceof VarNode;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2048
                appendStatement(var);
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2049
            }
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2050
            if (body != null) {
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2051
                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
  2052
            }
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2053
            if (outer != null) {
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2054
                restoreBlock(outer);
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2055
                if (body != null) {
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2056
                    appendStatement(new BlockStatement(forLine, new Block(
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2057
                                    outer.getToken(),
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2058
                                    body.getFinish(),
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2059
                                    outer.getStatements())));
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2060
                }
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2061
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2062
        }
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  2063
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2064
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2065
    private boolean checkValidLValue(final Expression init, final String contextString) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2066
        if (init instanceof IdentNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2067
            if (!checkIdentLValue((IdentNode)init)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2068
                return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2069
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2070
            verifyIdent((IdentNode)init, contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2071
            return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2072
        } else if (init instanceof AccessNode || init instanceof IndexNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2073
            return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2074
        } else if (isDestructuringLhs(init)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2075
            verifyDestructuringAssignmentPattern(init, contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2076
            return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2077
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2078
            return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2079
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2080
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2081
38485
8c55199bc96b 8157241: Remove javac warnings of Nashorn "ant clean test"
sundar
parents: 37924
diff changeset
  2082
    @SuppressWarnings("fallthrough")
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2083
    private boolean lookaheadIsLetDeclaration(final boolean ofContextualKeyword) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2084
        assert type == LET;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2085
        for (int i = 1;; i++) {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  2086
            final TokenType t = T(k + i);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2087
            switch (t) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2088
            case EOL:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2089
            case COMMENT:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2090
                continue;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2091
            case IDENT:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2092
                if (ofContextualKeyword && isES6() && "of".equals(getValue(getToken(k + i)))) {
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
                // fall through
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2096
            case LBRACKET:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2097
            case LBRACE:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2098
                return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2099
            default:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2100
                // accept future strict tokens in non-strict mode (including LET)
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2101
                if (!isStrictMode && t.getKind() == TokenKind.FUTURESTRICT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2102
                    return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2103
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2104
                return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2105
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2106
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2107
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2108
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2109
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2110
     * ...IterationStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2111
     *           ...
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2112
     *           while ( Expression ) Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2113
     *           ...
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2114
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2115
     * See 12.6
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2116
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2117
     * Parse while statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2118
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2119
    private void whileStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2120
        // Capture WHILE token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2121
        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
  2122
        final int whileLine = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2123
        // WHILE tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2124
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2125
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2126
        final ParserContextLoopNode whileNode = new ParserContextLoopNode();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2127
        lc.push(whileNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2128
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2129
        JoinPredecessorExpression test = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2130
        Block body = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2131
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2132
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2133
            expect(LPAREN);
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2134
            test = joinPredecessorExpression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2135
            expect(RPAREN);
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2136
            body = getStatement();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2137
        } finally {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2138
            lc.pop(whileNode);
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2139
        }
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2140
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2141
        if (body != null) {
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2142
            appendStatement(new WhileNode(whileLine, whileToken, body.getFinish(), false, test, body));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2143
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2144
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2145
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2146
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2147
     * ...IterationStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2148
     *           ...
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2149
     *           do Statement while( Expression ) ;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2150
     *           ...
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2151
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2152
     * See 12.6
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2153
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2154
     * Parse DO WHILE statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2155
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2156
    private void doStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2157
        // Capture DO token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2158
        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
  2159
        int doLine = 0;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2160
        // DO tested in the caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2161
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2162
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2163
        final ParserContextLoopNode doWhileNode = new ParserContextLoopNode();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2164
        lc.push(doWhileNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2165
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2166
        Block body = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2167
        JoinPredecessorExpression test = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2168
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2169
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2170
           // 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
  2171
            body = getStatement();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2172
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2173
            expect(WHILE);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2174
            expect(LPAREN);
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2175
            doLine = line;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2176
            test = joinPredecessorExpression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2177
            expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2178
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2179
            if (type == SEMICOLON) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2180
                endOfLine();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2181
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2182
        } finally {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2183
            lc.pop(doWhileNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2184
        }
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2185
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2186
        appendStatement(new WhileNode(doLine, doToken, finish, true, test, body));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2187
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2188
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2189
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2190
     * ContinueStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2191
     *      continue Identifier? ; // [no LineTerminator here]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2192
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2193
     * See 12.7
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2194
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2195
     * Parse CONTINUE statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2196
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2197
    private void continueStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2198
        // 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
  2199
        final int  continueLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2200
        final long continueToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2201
        // CONTINUE tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2202
        nextOrEOL();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2203
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2204
        ParserContextLabelNode labelNode = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2205
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2206
        // SEMICOLON or label.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2207
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2208
        case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2209
        case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2210
        case EOL:
18625
13558072545a 8019473: Parser issues related to functions and blocks
sundar
parents: 18335
diff changeset
  2211
        case EOF:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2212
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2213
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2214
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2215
            final IdentNode ident = getIdent();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2216
            labelNode = lc.findLabel(ident.getName());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2217
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2218
            if (labelNode == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2219
                throw error(AbstractParser.message("undefined.label", ident.getName()), ident.getToken());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2220
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2221
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2222
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2223
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2224
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2225
        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
  2226
        final ParserContextLoopNode targetNode = lc.getContinueTo(labelName);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2227
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2228
        if (targetNode == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2229
            throw error(AbstractParser.message("illegal.continue.stmt"), continueToken);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2230
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2231
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2232
        endOfLine();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2233
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2234
        // Construct and add CONTINUE node.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2235
        appendStatement(new ContinueNode(continueLine, continueToken, finish, labelName));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2236
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2237
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2238
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2239
     * BreakStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2240
     *      break Identifier? ; // [no LineTerminator here]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2241
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2242
     * See 12.8
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2243
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2244
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2245
    private void breakStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2246
        // 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
  2247
        final int  breakLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2248
        final long breakToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2249
        // BREAK tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2250
        nextOrEOL();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2251
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2252
        ParserContextLabelNode labelNode = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2253
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2254
        // SEMICOLON or label.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2255
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2256
        case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2257
        case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2258
        case EOL:
18625
13558072545a 8019473: Parser issues related to functions and blocks
sundar
parents: 18335
diff changeset
  2259
        case EOF:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2260
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2261
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2262
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2263
            final IdentNode ident = getIdent();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2264
            labelNode = lc.findLabel(ident.getName());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2265
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2266
            if (labelNode == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2267
                throw error(AbstractParser.message("undefined.label", ident.getName()), ident.getToken());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2268
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2269
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2270
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2271
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2272
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2273
        //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
  2274
        //targetNode is what we are breaking out from.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2275
        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
  2276
        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
  2277
f57fa7f112a0 8177691: Labeled break in catch and finally works wrongly, when invoked through nashorn
sdama
parents: 46169
diff changeset
  2278
        if( targetNode instanceof ParserContextBlockNode) {
f57fa7f112a0 8177691: Labeled break in catch and finally works wrongly, when invoked through nashorn
sdama
parents: 46169
diff changeset
  2279
            targetNode.setFlag(Block.IS_BREAKABLE);
f57fa7f112a0 8177691: Labeled break in catch and finally works wrongly, when invoked through nashorn
sdama
parents: 46169
diff changeset
  2280
        }
f57fa7f112a0 8177691: Labeled break in catch and finally works wrongly, when invoked through nashorn
sdama
parents: 46169
diff changeset
  2281
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2282
        if (targetNode == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2283
            throw error(AbstractParser.message("illegal.break.stmt"), breakToken);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2284
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2285
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2286
        endOfLine();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2287
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2288
        // Construct and add BREAK node.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2289
        appendStatement(new BreakNode(breakLine, breakToken, finish, labelName));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2290
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2291
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2292
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2293
     * ReturnStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2294
     *      return Expression? ; // [no LineTerminator here]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2295
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2296
     * See 12.9
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2297
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2298
     * Parse RETURN statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2299
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2300
    private void returnStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2301
        // check for return outside function
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2302
        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
  2303
            throw error(AbstractParser.message("invalid.return"));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2304
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2305
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2306
        // 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
  2307
        final int  returnLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2308
        final long returnToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2309
        // RETURN tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2310
        nextOrEOL();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2311
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2312
        Expression expression = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2313
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2314
        // SEMICOLON or expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2315
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2316
        case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2317
        case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2318
        case EOL:
18625
13558072545a 8019473: Parser issues related to functions and blocks
sundar
parents: 18335
diff changeset
  2319
        case EOF:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2320
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2321
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2322
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2323
            expression = expression();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2324
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2325
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2326
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2327
        endOfLine();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2328
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2329
        // 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
  2330
        appendStatement(new ReturnNode(returnLine, returnToken, finish, expression));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2331
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2332
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2333
    /**
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2334
     * Parse YieldExpression.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2335
     *
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2336
     * YieldExpression[In] :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2337
     *   yield
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2338
     *   yield [no LineTerminator here] AssignmentExpression[?In, Yield]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2339
     *   yield [no LineTerminator here] * AssignmentExpression[?In, Yield]
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2340
     */
38485
8c55199bc96b 8157241: Remove javac warnings of Nashorn "ant clean test"
sundar
parents: 37924
diff changeset
  2341
    @SuppressWarnings("fallthrough")
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2342
    private Expression yieldExpression(final boolean noIn) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2343
        assert inGeneratorFunction();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2344
        // Capture YIELD token.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2345
        long yieldToken = token;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2346
        // YIELD tested in caller.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2347
        assert type == YIELD;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2348
        nextOrEOL();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2349
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2350
        Expression expression = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2351
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2352
        boolean yieldAsterisk = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2353
        if (type == MUL) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2354
            yieldAsterisk = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2355
            yieldToken = Token.recast(yieldToken, YIELD_STAR);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2356
            next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2357
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2358
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2359
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2360
        case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2361
        case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2362
        case EOL:
18625
13558072545a 8019473: Parser issues related to functions and blocks
sundar
parents: 18335
diff changeset
  2363
        case EOF:
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2364
        case COMMARIGHT:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2365
        case RPAREN:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2366
        case RBRACKET:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2367
        case COLON:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2368
            if (!yieldAsterisk) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2369
                // treat (yield) as (yield void 0)
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2370
                expression = newUndefinedLiteral(yieldToken, finish);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2371
                if (type == EOL) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2372
                    next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2373
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2374
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2375
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2376
                // AssignmentExpression required, fall through
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2377
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2378
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2379
        default:
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2380
            expression = assignmentExpression(noIn);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2381
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2382
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2383
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2384
        // Construct and add YIELD node.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2385
        return new UnaryNode(yieldToken, expression);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2386
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2387
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2388
    private static UnaryNode newUndefinedLiteral(final long token, final int finish) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2389
        return new UnaryNode(Token.recast(token, VOID), LiteralNode.newInstance(token, finish, 0));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2390
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2391
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2392
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2393
     * WithStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2394
     *      with ( Expression ) Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2395
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2396
     * See 12.10
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2397
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2398
     * Parse WITH statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2399
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2400
    private void withStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2401
        // 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
  2402
        final int  withLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2403
        final long withToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2404
        // WITH tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2405
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2406
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2407
        // ECMA 12.10.1 strict mode restrictions
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2408
        if (isStrictMode) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2409
            throw error(AbstractParser.message("strict.no.with"), withToken);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2410
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2411
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2412
        expect(LPAREN);
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2413
        final Expression expression = expression();
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2414
        expect(RPAREN);
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2415
        final Block body = getStatement();
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2416
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2417
        appendStatement(new WithNode(withLine, withToken, finish, expression, body));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2418
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2419
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2420
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2421
     * SwitchStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2422
     *      switch ( Expression ) CaseBlock
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2423
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2424
     * CaseBlock :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2425
     *      { CaseClauses? }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2426
     *      { CaseClauses? DefaultClause CaseClauses }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2427
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2428
     * CaseClauses :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2429
     *      CaseClause
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2430
     *      CaseClauses CaseClause
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2431
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2432
     * CaseClause :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2433
     *      case Expression : StatementList?
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2434
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2435
     * DefaultClause :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2436
     *      default : StatementList?
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2437
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2438
     * See 12.11
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2439
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2440
     * Parse SWITCH statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2441
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2442
    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
  2443
        final int  switchLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2444
        final long switchToken = token;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2445
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2446
        // Block to capture variables declared inside the switch statement.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2447
        final ParserContextBlockNode switchBlock = newBlock();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2448
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2449
        // SWITCH tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2450
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2451
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2452
        // Create and add switch statement.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2453
        final ParserContextSwitchNode switchNode = new ParserContextSwitchNode();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2454
        lc.push(switchNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2455
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2456
        CaseNode defaultCase = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2457
        // 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
  2458
        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
  2459
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2460
        Expression expression = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2461
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2462
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2463
            expect(LPAREN);
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2464
            expression = expression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2465
            expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2466
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2467
            expect(LBRACE);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2468
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2469
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2470
            while (type != RBRACE) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2471
                // Prepare for next case.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2472
                Expression caseExpression = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2473
                final long caseToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2474
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2475
                switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2476
                case CASE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2477
                    next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2478
                    caseExpression = expression();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2479
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2480
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2481
                case DEFAULT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2482
                    if (defaultCase != null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2483
                        throw error(AbstractParser.message("duplicate.default.in.switch"));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2484
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2485
                    next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2486
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2487
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2488
                default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2489
                    // Force an error.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2490
                    expect(CASE);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2491
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2492
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2493
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2494
                expect(COLON);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2495
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2496
                // Get CASE body.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2497
                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
  2498
                final CaseNode caseNode = new CaseNode(caseToken, finish, caseExpression, statements);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2499
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2500
                if (caseExpression == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2501
                    defaultCase = caseNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2502
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2503
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2504
                cases.add(caseNode);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2505
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2506
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2507
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2508
        } finally {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2509
            lc.pop(switchNode);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2510
            restoreBlock(switchBlock);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2511
        }
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2512
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2513
        final SwitchNode switchStatement = new SwitchNode(switchLine, switchToken, finish, expression, cases, defaultCase);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2514
        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
  2515
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2516
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2517
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2518
     * LabelledStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2519
     *      Identifier : Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2520
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2521
     * See 12.12
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2522
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2523
     * Parse label statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2524
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2525
    private void labelStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2526
        // Capture label token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2527
        final long labelToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2528
        // Get label ident.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2529
        final IdentNode ident = getIdent();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2530
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2531
        expect(COLON);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2532
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2533
        if (lc.findLabel(ident.getName()) != null) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2534
            throw error(AbstractParser.message("duplicate.label", ident.getName()), labelToken);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2535
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2536
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2537
        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
  2538
        Block body = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2539
        try {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2540
            lc.push(labelNode);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2541
            body = getStatement(true);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2542
        } finally {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2543
            assert lc.peek() instanceof ParserContextLabelNode;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2544
            lc.pop(labelNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2545
        }
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2546
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2547
        appendStatement(new LabelNode(line, labelToken, finish, ident.getName(), body));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2548
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2549
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  2550
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2551
     * ThrowStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2552
     *      throw Expression ; // [no LineTerminator here]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2553
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2554
     * See 12.13
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2555
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2556
     * Parse throw statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2557
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2558
    private void throwStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2559
        // 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
  2560
        final int  throwLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2561
        final long throwToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2562
        // THROW tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2563
        nextOrEOL();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2564
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2565
        Expression expression = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2566
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2567
        // SEMICOLON or expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2568
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2569
        case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2570
        case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2571
        case EOL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2572
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2573
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2574
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2575
            expression = expression();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2576
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2577
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2578
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2579
        if (expression == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2580
            throw error(AbstractParser.message("expected.operand", type.getNameOrType()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2581
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2582
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2583
        endOfLine();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2584
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2585
        appendStatement(new ThrowNode(throwLine, throwToken, finish, expression, false));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2586
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2587
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2588
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2589
     * TryStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2590
     *      try Block Catch
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2591
     *      try Block Finally
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2592
     *      try Block Catch Finally
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2593
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2594
     * Catch :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2595
     *      catch( Identifier if Expression ) Block
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2596
     *      catch( Identifier ) Block
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2597
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2598
     * Finally :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2599
     *      finally Block
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2600
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2601
     * See 12.14
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2602
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2603
     * Parse TRY statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2604
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2605
    private void tryStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2606
        // 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
  2607
        final int  tryLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2608
        final long tryToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2609
        // TRY tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2610
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2611
16239
fbae49f786c6 8008215: break in catch clause causes java.lang.VerifyError: Inconsistent stackmap
hannesw
parents: 16237
diff changeset
  2612
        // 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
  2613
        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
  2614
        final ParserContextBlockNode outer = newBlock();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2615
        // Create try.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2616
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2617
        try {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2618
            final Block       tryBody     = getBlock(true);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2619
            final List<Block> catchBlocks = new ArrayList<>();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2620
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2621
            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
  2622
                final int  catchLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2623
                final long catchToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2624
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2625
                expect(LPAREN);
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  2626
41983
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2627
                // 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
  2628
                // 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
  2629
                final String contextString = "catch argument";
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2630
                final Expression exception = bindingIdentifierOrPattern(contextString);
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2631
                final boolean isDestructuring = !(exception instanceof IdentNode);
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2632
                if (isDestructuring) {
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2633
                    verifyDestructuringBindingPattern(exception, new Consumer<IdentNode>() {
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2634
                        @Override
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2635
                        public void accept(final IdentNode identNode) {
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2636
                            verifyIdent(identNode, contextString);
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2637
                        }
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2638
                    });
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2639
                } else {
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2640
                    // ECMA 12.4.1 strict mode restrictions
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2641
                    verifyStrictIdent((IdentNode) exception, "catch argument");
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2642
                }
eb674141ab03 8156615: Catch parameter can be a BindingPattern in ES6 mode
sdama
parents: 41924
diff changeset
  2643
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2644
23766
a3ef17770bab 8039047: Parser accepts conditional catch clauses even when --no-syntax-extensions / -nse option is passed
sundar
parents: 23372
diff changeset
  2645
                // 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
  2646
                // 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
  2647
                // 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
  2648
                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
  2649
                if (!env._no_syntax_extensions && type == IF) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2650
                    next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2651
                    // Get the exception condition.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2652
                    ifExpression = expression();
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2653
                } else {
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2654
                    ifExpression = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2655
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2656
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2657
                expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2658
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2659
                final ParserContextBlockNode catchBlock = newBlock();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2660
                try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2661
                    // Get CATCH body.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2662
                    final Block catchBody = getBlock(true);
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2663
                    final CatchNode catchNode = new CatchNode(catchLine, catchToken, finish, exception, ifExpression, catchBody, false);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2664
                    appendStatement(catchNode);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2665
                } finally {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2666
                    restoreBlock(catchBlock);
29407
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
  2667
                    catchBlocks.add(new Block(catchBlock.getToken(), finish, catchBlock.getFlags() | Block.IS_SYNTHETIC, catchBlock.getStatements()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2668
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2669
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2670
                // If unconditional catch then should to be the end.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2671
                if (ifExpression == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2672
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2673
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2674
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2675
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2676
            // Prepare to capture finally statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2677
            Block finallyStatements = null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2678
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2679
            if (type == FINALLY) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2680
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2681
                finallyStatements = getBlock(true);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2682
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2683
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2684
            // Need at least one catch or a finally.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2685
            if (catchBlocks.isEmpty() && finallyStatements == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2686
                throw error(AbstractParser.message("missing.catch.or.finally"), tryToken);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2687
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2688
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2689
            final TryNode tryNode = new TryNode(tryLine, tryToken, finish, tryBody, catchBlocks, finallyStatements);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2690
            // Add try.
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2691
            assert lc.peek() == outer;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2692
            appendStatement(tryNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2693
        } finally {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2694
            restoreBlock(outer);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2695
        }
16239
fbae49f786c6 8008215: break in catch clause causes java.lang.VerifyError: Inconsistent stackmap
hannesw
parents: 16237
diff changeset
  2696
29407
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
  2697
        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
  2698
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2699
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2700
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2701
     * DebuggerStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2702
     *      debugger ;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2703
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2704
     * See 12.15
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2705
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2706
     * Parse debugger statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2707
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2708
    private void  debuggerStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2709
        // 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
  2710
        final int  debuggerLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2711
        final long debuggerToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2712
        // DEBUGGER tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2713
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2714
        endOfLine();
29407
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
  2715
        appendStatement(new DebuggerNode(debuggerLine, debuggerToken, finish));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2716
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2717
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2718
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2719
     * PrimaryExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2720
     *      this
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2721
     *      IdentifierReference
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2722
     *      Literal
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2723
     *      ArrayLiteral
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2724
     *      ObjectLiteral
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  2725
     *      RegularExpressionLiteral
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  2726
     *      TemplateLiteral
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2727
     *      CoverParenthesizedExpressionAndArrowParameterList
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2728
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2729
     * CoverParenthesizedExpressionAndArrowParameterList :
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2730
     *      ( Expression )
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2731
     *      ( )
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2732
     *      ( ... BindingIdentifier )
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2733
     *      ( Expression , ... BindingIdentifier )
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2734
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2735
     * Parse primary expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2736
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2737
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2738
    @SuppressWarnings("fallthrough")
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2739
    private Expression primaryExpression() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2740
        // 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
  2741
        final int  primaryLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2742
        final long primaryToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2743
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2744
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2745
        case THIS:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2746
            final String name = type.getName();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2747
            next();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2748
            markThis(lc);
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  2749
            return new IdentNode(primaryToken, finish, name);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2750
        case IDENT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2751
            final IdentNode ident = getIdent();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2752
            if (ident == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2753
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2754
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2755
            detectSpecialProperty(ident);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2756
            return ident;
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
  2757
        case OCTAL_LEGACY:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2758
            if (isStrictMode) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2759
               throw error(AbstractParser.message("strict.no.octal"), token);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2760
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2761
        case STRING:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2762
        case ESCSTRING:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2763
        case DECIMAL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2764
        case HEXADECIMAL:
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
  2765
        case OCTAL:
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
  2766
        case BINARY_NUMBER:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2767
        case FLOATING:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2768
        case REGEX:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2769
        case XML:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2770
            return getLiteral();
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2771
        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
  2772
            return execString(primaryLine, primaryToken);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2773
        case FALSE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2774
            next();
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  2775
            return LiteralNode.newInstance(primaryToken, finish, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2776
        case TRUE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2777
            next();
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  2778
            return LiteralNode.newInstance(primaryToken, finish, true);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2779
        case NULL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2780
            next();
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  2781
            return LiteralNode.newInstance(primaryToken, finish);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2782
        case LBRACKET:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2783
            return arrayLiteral();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2784
        case LBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2785
            return objectLiteral();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2786
        case LPAREN:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2787
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2788
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2789
            if (isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2790
                if (type == RPAREN) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2791
                    // ()
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2792
                    nextOrEOL();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2793
                    expectDontAdvance(ARROW);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2794
                    return new ExpressionList(primaryToken, finish, Collections.emptyList());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2795
                } else if (type == ELLIPSIS) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2796
                    // (...rest)
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2797
                    final IdentNode restParam = formalParameterList(false).get(0);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2798
                    expectDontAdvance(RPAREN);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2799
                    nextOrEOL();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2800
                    expectDontAdvance(ARROW);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2801
                    return new ExpressionList(primaryToken, finish, Collections.singletonList(restParam));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2802
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2803
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2804
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2805
            final Expression expression = expression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2806
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2807
            expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2808
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2809
            return expression;
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  2810
        case TEMPLATE:
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  2811
        case TEMPLATE_HEAD:
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  2812
            return templateLiteral();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2813
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2814
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2815
            // 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
  2816
            if (lexer.scanLiteral(primaryToken, type, lineInfoReceiver)) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2817
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2818
                return getLiteral();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2819
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2820
            if (isNonStrictModeIdent()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2821
                return getIdent();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2822
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2823
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2824
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2825
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2826
        return null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2827
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2828
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2829
    /**
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2830
     * Convert execString to a call to $EXEC.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2831
     *
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2832
     * @param primaryToken Original string token.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2833
     * @return callNode to $EXEC.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2834
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2835
    CallNode execString(final int primaryLine, final long primaryToken) {
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2836
        // 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
  2837
        final IdentNode execIdent = new IdentNode(primaryToken, finish, ScriptingFunctions.EXEC_NAME);
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2838
        // Skip over EXECSTRING.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2839
        next();
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2840
        // Set up argument list for call.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2841
        // Skip beginning of edit string expression.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2842
        expect(LBRACE);
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2843
        // Add the following expression to arguments.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2844
        final List<Expression> arguments = Collections.singletonList(expression());
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2845
        // Skip ending of edit string expression.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2846
        expect(RBRACE);
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2847
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2848
        return new CallNode(primaryLine, primaryToken, finish, execIdent, arguments, false);
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2849
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2850
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2851
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2852
     * ArrayLiteral :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2853
     *      [ Elision? ]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2854
     *      [ ElementList ]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2855
     *      [ ElementList , Elision? ]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2856
     *      [ expression for (LeftHandExpression in expression) ( (if ( Expression ) )? ]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2857
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2858
     * ElementList : Elision? AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2859
     *      ElementList , Elision? AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2860
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2861
     * Elision :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2862
     *      ,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2863
     *      Elision ,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2864
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2865
     * See 12.1.4
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2866
     * JavaScript 1.8
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2867
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2868
     * Parse array literal.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2869
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2870
     */
38485
8c55199bc96b 8157241: Remove javac warnings of Nashorn "ant clean test"
sundar
parents: 37924
diff changeset
  2871
    @SuppressWarnings("fallthrough")
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2872
    private LiteralNode<Expression[]> arrayLiteral() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2873
        // Capture LBRACKET token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2874
        final long arrayToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2875
        // LBRACKET tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2876
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2877
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2878
        // Prepare to accumulate elements.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2879
        final List<Expression> elements = new ArrayList<>();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2880
        // Track elisions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2881
        boolean elision = true;
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2882
        boolean hasSpread = false;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2883
        loop:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2884
        while (true) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2885
            long spreadToken = 0;
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2886
            switch (type) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2887
            case RBRACKET:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2888
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2889
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2890
                break loop;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2891
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2892
            case COMMARIGHT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2893
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2894
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2895
                // If no prior expression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2896
                if (elision) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2897
                    elements.add(null);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2898
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2899
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2900
                elision = true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2901
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2902
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2903
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2904
            case ELLIPSIS:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2905
                if (isES6()) {
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2906
                    hasSpread = true;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2907
                    spreadToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2908
                    next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2909
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2910
                // fall through
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2911
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2912
            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
  2913
                if (!elision) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2914
                    throw error(AbstractParser.message("expected.comma", type.getNameOrType()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2915
                }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2916
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2917
                // Add expression element.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2918
                Expression expression = assignmentExpression(false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2919
                if (expression != null) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2920
                    if (spreadToken != 0) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2921
                        expression = new UnaryNode(Token.recast(spreadToken, SPREAD_ARRAY), expression);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2922
                    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2923
                    elements.add(expression);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2924
                } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2925
                    expect(RBRACKET);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2926
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2927
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2928
                elision = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2929
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2930
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2931
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2932
41425
86226c782b1a 8167289: Backport ES6 updates from Graal.js
hannesw
parents: 41422
diff changeset
  2933
        return LiteralNode.newInstance(arrayToken, finish, elements, hasSpread, elision);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2934
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2935
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2936
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2937
     * ObjectLiteral :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2938
     *      { }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2939
     *      { PropertyNameAndValueList } { PropertyNameAndValueList , }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2940
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2941
     * PropertyNameAndValueList :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2942
     *      PropertyAssignment
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2943
     *      PropertyNameAndValueList , PropertyAssignment
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2944
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2945
     * See 11.1.5
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2946
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2947
     * Parse an object literal.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2948
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2949
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2950
    private ObjectNode objectLiteral() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2951
        // Capture LBRACE token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2952
        final long objectToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2953
        // LBRACE tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2954
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2955
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2956
        // Object context.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2957
        // Prepare to accumulate elements.
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2958
        final List<PropertyNode> elements = new ArrayList<>();
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2959
        final Map<String, Integer> map = new HashMap<>();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2960
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
  2961
        // 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
  2962
        boolean commaSeen = true;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2963
        loop:
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2964
        while (true) {
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2965
            switch (type) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2966
                case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2967
                    next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2968
                    break loop;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2969
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2970
                case COMMARIGHT:
18629
6b0b6aab4280 8019508: Comma handling in object literal parsing is wrong
sundar
parents: 18625
diff changeset
  2971
                    if (commaSeen) {
6b0b6aab4280 8019508: Comma handling in object literal parsing is wrong
sundar
parents: 18625
diff changeset
  2972
                        throw error(AbstractParser.message("expected.property.id", type.getNameOrType()));
6b0b6aab4280 8019508: Comma handling in object literal parsing is wrong
sundar
parents: 18625
diff changeset
  2973
                    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2974
                    next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2975
                    commaSeen = true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2976
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2977
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2978
                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
  2979
                    if (!commaSeen) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2980
                        throw error(AbstractParser.message("expected.comma", type.getNameOrType()));
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2981
                    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2982
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2983
                    commaSeen = false;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2984
                    // Get and add the next property.
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2985
                    final PropertyNode property = propertyAssignment();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2986
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2987
                    if (property.isComputed()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2988
                        elements.add(property);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2989
                        break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2990
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2991
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2992
                    final String key = property.getKeyName();
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2993
                    final Integer existing = map.get(key);
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2994
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2995
                    if (existing == null) {
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2996
                        map.put(key, elements.size());
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2997
                        elements.add(property);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2998
                        break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2999
                    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3000
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  3001
                    final PropertyNode existingProperty = elements.get(existing);
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  3002
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
  3003
                    // 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
  3004
                    // point # 4 on property assignment production
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3005
                    final Expression   value  = property.getValue();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3006
                    final FunctionNode getter = property.getGetter();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3007
                    final FunctionNode setter = property.getSetter();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3008
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3009
                    final Expression   prevValue  = existingProperty.getValue();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3010
                    final FunctionNode prevGetter = existingProperty.getGetter();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3011
                    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
  3012
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3013
                    if (!isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3014
                        checkPropertyRedefinition(property, value, getter, setter, prevValue, prevGetter, prevSetter);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3015
                    } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3016
                        if (property.getKey() instanceof IdentNode && ((IdentNode)property.getKey()).isProtoPropertyName() &&
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3017
                                        existingProperty.getKey() instanceof IdentNode && ((IdentNode)existingProperty.getKey()).isProtoPropertyName()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3018
                            throw error(AbstractParser.message("multiple.proto.key"), property.getToken());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3019
                        }
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
  3020
                    }
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
  3021
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3022
                    if (value != null || prevValue != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3023
                        map.put(key, elements.size());
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  3024
                        elements.add(property);
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  3025
                    } else if (getter != null) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3026
                        assert prevGetter != null || prevSetter != null;
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  3027
                        elements.set(existing, existingProperty.setGetter(getter));
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  3028
                    } else if (setter != null) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3029
                        assert prevGetter != null || prevSetter != null;
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  3030
                        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
  3031
                    }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3032
                    break;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3033
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3034
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3035
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  3036
        return new ObjectNode(objectToken, finish, elements);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3037
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3038
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3039
    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
  3040
        // ECMA 11.1.5 strict mode restrictions
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3041
        if (isStrictMode && value != null && prevValue != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3042
            throw error(AbstractParser.message("property.redefinition", property.getKeyName()), property.getToken());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3043
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3044
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3045
        final boolean isPrevAccessor = prevGetter != null || prevSetter != null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3046
        final boolean isAccessor     = getter != null     || setter != null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3047
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3048
        // data property redefined as accessor property
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3049
        if (prevValue != null && isAccessor) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3050
            throw error(AbstractParser.message("property.redefinition", property.getKeyName()), property.getToken());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3051
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3052
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3053
        // accessor property redefined as data
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3054
        if (isPrevAccessor && value != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3055
            throw error(AbstractParser.message("property.redefinition", property.getKeyName()), property.getToken());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3056
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3057
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3058
        if (isAccessor && isPrevAccessor) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3059
            if (getter != null && prevGetter != null ||
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3060
                    setter != null && prevSetter != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3061
                throw error(AbstractParser.message("property.redefinition", property.getKeyName()), property.getToken());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3062
            }
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
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3065
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3066
    /**
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3067
     * LiteralPropertyName :
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3068
     *      IdentifierName
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3069
     *      StringLiteral
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3070
     *      NumericLiteral
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3071
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3072
     * @return PropertyName node
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3073
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3074
    @SuppressWarnings("fallthrough")
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3075
    private PropertyKey literalPropertyName() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3076
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3077
        case IDENT:
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3078
            return getIdent().setIsPropertyName();
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
  3079
        case OCTAL_LEGACY:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3080
            if (isStrictMode) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3081
                throw error(AbstractParser.message("strict.no.octal"), token);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3082
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3083
        case STRING:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3084
        case ESCSTRING:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3085
        case DECIMAL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3086
        case HEXADECIMAL:
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
  3087
        case OCTAL:
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
  3088
        case BINARY_NUMBER:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3089
        case FLOATING:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3090
            return getLiteral();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3091
        default:
19883
aae0838ac6ee 8024255: When a keyword is used as object property name, the property can not be deleted
sundar
parents: 19472
diff changeset
  3092
            return getIdentifierName().setIsPropertyName();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3093
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3094
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3095
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3096
    /**
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3097
     * ComputedPropertyName :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3098
     *      AssignmentExpression
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3099
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3100
     * @return PropertyName node
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3101
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3102
    private Expression computedPropertyName() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3103
        expect(LBRACKET);
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  3104
        final Expression expression = assignmentExpression(false);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3105
        expect(RBRACKET);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3106
        return expression;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3107
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3108
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3109
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3110
     * PropertyName :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3111
     *      LiteralPropertyName
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3112
     *      ComputedPropertyName
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3113
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3114
     * @return PropertyName node
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
    private Expression propertyName() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3117
        if (type == LBRACKET && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3118
            return computedPropertyName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3119
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3120
            return (Expression)literalPropertyName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3121
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3122
    }
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
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3125
     * PropertyAssignment :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3126
     *      PropertyName : AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3127
     *      get PropertyName ( ) { FunctionBody }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3128
     *      set PropertyName ( PropertySetParameterList ) { FunctionBody }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3129
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3130
     * PropertySetParameterList :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3131
     *      Identifier
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3132
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3133
     * PropertyName :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3134
     *      IdentifierName
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3135
     *      StringLiteral
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3136
     *      NumericLiteral
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3137
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3138
     * See 11.1.5
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3139
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3140
     * Parse an object literal property.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3141
     * @return Property or reference node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3142
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3143
    private PropertyNode propertyAssignment() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3144
        // Capture firstToken.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3145
        final long propertyToken = token;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3146
        final int  functionLine  = line;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3147
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3148
        final Expression propertyName;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3149
        final boolean isIdentifier;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3150
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3151
        boolean generator = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3152
        if (type == MUL && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3153
            generator = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3154
            next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3155
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3156
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3157
        final boolean computed = type == LBRACKET;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3158
        if (type == IDENT) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3159
            // Get IDENT.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3160
            final String ident = (String)expectValue(IDENT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3161
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3162
            if (type != COLON && (type != LPAREN || !isES6())) {
20938
e92d8249f60c 8026302: source representation of getter and setter methods is wrong
sundar
parents: 20934
diff changeset
  3163
                final long getSetToken = propertyToken;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3164
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3165
                switch (ident) {
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
  3166
                case GET_NAME:
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3167
                    final PropertyFunction getter = propertyGetterFunction(getSetToken, functionLine);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3168
                    return new PropertyNode(propertyToken, finish, getter.key, null, getter.functionNode, null, false, getter.computed);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3169
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
  3170
                case SET_NAME:
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3171
                    final PropertyFunction setter = propertySetterFunction(getSetToken, functionLine);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3172
                    return new PropertyNode(propertyToken, finish, setter.key, null, null, setter.functionNode, false, setter.computed);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3173
                default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3174
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3175
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3176
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3177
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3178
            isIdentifier = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3179
            IdentNode identNode = createIdentNode(propertyToken, finish, ident).setIsPropertyName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3180
            if (type == COLON && ident.equals("__proto__")) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3181
                identNode = identNode.setIsProtoPropertyName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3182
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3183
            propertyName = identNode;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3184
        } else {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3185
            isIdentifier = isNonStrictModeIdent();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3186
            propertyName = propertyName();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3187
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3188
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3189
        Expression propertyValue;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3190
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3191
        if (generator) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3192
            expectDontAdvance(LPAREN);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3193
        }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3194
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3195
        if (type == LPAREN && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3196
            propertyValue = propertyMethodFunction(propertyName, propertyToken, functionLine, generator, FunctionNode.ES6_IS_METHOD, computed).functionNode;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3197
        } else if (isIdentifier && (type == COMMARIGHT || type == RBRACE || type == ASSIGN) && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3198
            propertyValue = createIdentNode(propertyToken, finish, ((IdentNode) propertyName).getPropertyName());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3199
            if (type == ASSIGN && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3200
                // TODO if not destructuring, this is a SyntaxError
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3201
                final long assignToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3202
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3203
                final Expression rhs = assignmentExpression(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3204
                propertyValue = verifyAssignment(assignToken, propertyValue, rhs);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3205
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3206
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3207
            expect(COLON);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3208
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3209
            defaultNames.push(propertyName);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3210
            try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3211
                propertyValue = assignmentExpression(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3212
            } finally {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3213
                defaultNames.pop();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3214
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3215
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3216
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3217
        return new PropertyNode(propertyToken, finish, propertyName, propertyValue, null, null, false, computed);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3218
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3219
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3220
    private PropertyFunction propertyGetterFunction(final long getSetToken, final int functionLine) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3221
        return propertyGetterFunction(getSetToken, functionLine, FunctionNode.ES6_IS_METHOD);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3222
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3223
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3224
    private PropertyFunction propertyGetterFunction(final long getSetToken, final int functionLine, final int flags) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3225
        final boolean computed = type == LBRACKET;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3226
        final Expression propertyName = propertyName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3227
        final String getterName = propertyName instanceof PropertyKey ? ((PropertyKey) propertyName).getPropertyName() : getDefaultValidFunctionName(functionLine, false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3228
        final IdentNode getNameNode = createIdentNode((propertyName).getToken(), finish, NameCodec.encode("get " + getterName));
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3229
        expect(LPAREN);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3230
        expect(RPAREN);
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3231
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3232
        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
  3233
        functionNode.setFlag(flags);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3234
        if (computed) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3235
            functionNode.setFlag(FunctionNode.IS_ANONYMOUS);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3236
        }
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3237
        lc.push(functionNode);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3238
27819
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3239
        Block functionBody;
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3240
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3241
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3242
        try {
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3243
            functionBody = functionBody(functionNode);
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3244
        } finally {
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3245
            lc.pop(functionNode);
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3246
        }
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 FunctionNode  function = createFunctionNode(
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3249
                functionNode,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3250
                getSetToken,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3251
                getNameNode,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3252
                Collections.<IdentNode>emptyList(),
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3253
                FunctionNode.Kind.GETTER,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3254
                functionLine,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3255
                functionBody);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3256
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3257
        return new PropertyFunction(propertyName, function, computed);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3258
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3259
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3260
    private PropertyFunction propertySetterFunction(final long getSetToken, final int functionLine) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3261
        return propertySetterFunction(getSetToken, functionLine, FunctionNode.ES6_IS_METHOD);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3262
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3263
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3264
    private PropertyFunction propertySetterFunction(final long getSetToken, final int functionLine, final int flags) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3265
        final boolean computed = type == LBRACKET;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3266
        final Expression propertyName = propertyName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3267
        final String setterName = propertyName instanceof PropertyKey ? ((PropertyKey) propertyName).getPropertyName() : getDefaultValidFunctionName(functionLine, false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3268
        final IdentNode setNameNode = createIdentNode((propertyName).getToken(), finish, NameCodec.encode("set " + setterName));
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3269
        expect(LPAREN);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3270
        // be sloppy and allow missing setter parameter even though
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3271
        // spec does not permit it!
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3272
        final IdentNode argIdent;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3273
        if (isBindingIdentifier()) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3274
            argIdent = getIdent();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3275
            verifyIdent(argIdent, "setter argument");
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3276
        } else {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3277
            argIdent = null;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3278
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3279
        expect(RPAREN);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3280
        final List<IdentNode> parameters = new ArrayList<>();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3281
        if (argIdent != null) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3282
            parameters.add(argIdent);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3283
        }
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3284
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3285
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3286
        final ParserContextFunctionNode functionNode = createParserContextFunctionNode(setNameNode, getSetToken, FunctionNode.Kind.SETTER, functionLine, parameters);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3287
        functionNode.setFlag(flags);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3288
        if (computed) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3289
            functionNode.setFlag(FunctionNode.IS_ANONYMOUS);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3290
        }
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3291
        lc.push(functionNode);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3292
27819
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3293
        Block functionBody;
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3294
        try {
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3295
            functionBody = functionBody(functionNode);
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3296
        } finally {
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3297
            lc.pop(functionNode);
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3298
        }
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
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
        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
  3302
                functionNode,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3303
                getSetToken,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3304
                setNameNode,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3305
                parameters,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3306
                FunctionNode.Kind.SETTER,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3307
                functionLine,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3308
                functionBody);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3309
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3310
        return new PropertyFunction(propertyName, function, computed);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3311
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3312
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  3313
    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
  3314
        final String methodName = key instanceof PropertyKey ? ((PropertyKey) key).getPropertyName() : getDefaultValidFunctionName(methodLine, false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3315
        final IdentNode methodNameNode = createIdentNode(((Node)key).getToken(), finish, methodName);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3316
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  3317
        final FunctionNode.Kind functionKind = generator ? FunctionNode.Kind.GENERATOR : FunctionNode.Kind.NORMAL;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3318
        final ParserContextFunctionNode functionNode = createParserContextFunctionNode(methodNameNode, methodToken, functionKind, methodLine, null);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3319
        functionNode.setFlag(flags);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3320
        if (computed) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3321
            functionNode.setFlag(FunctionNode.IS_ANONYMOUS);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3322
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3323
        lc.push(functionNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3324
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3325
        try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3326
            final ParserContextBlockNode parameterBlock = newBlock();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3327
            final List<IdentNode> parameters;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3328
            try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3329
                expect(LPAREN);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3330
                parameters = formalParameterList(generator);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3331
                functionNode.setParameters(parameters);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3332
                expect(RPAREN);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3333
            } finally {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3334
                restoreBlock(parameterBlock);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3335
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3336
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3337
            Block functionBody = functionBody(functionNode);
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
            functionBody = maybeWrapBodyInParameterBlock(functionBody, parameterBlock);
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
            final FunctionNode  function = createFunctionNode(
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3342
                            functionNode,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3343
                            methodToken,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3344
                            methodNameNode,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3345
                            parameters,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3346
                            functionKind,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3347
                            methodLine,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3348
                            functionBody);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3349
            return new PropertyFunction(key, function, computed);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3350
        } finally {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3351
            lc.pop(functionNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3352
        }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3353
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3354
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3355
    private static class PropertyFunction {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3356
        final Expression key;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3357
        final FunctionNode functionNode;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3358
        final boolean computed;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3359
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3360
        PropertyFunction(final Expression key, final FunctionNode function, final boolean computed) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3361
            this.key = key;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3362
            this.functionNode = function;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3363
            this.computed = computed;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3364
        }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3365
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3366
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3367
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3368
     * LeftHandSideExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3369
     *      NewExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3370
     *      CallExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3371
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3372
     * CallExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3373
     *      MemberExpression Arguments
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3374
     *      SuperCall
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3375
     *      CallExpression Arguments
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3376
     *      CallExpression [ Expression ]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3377
     *      CallExpression . IdentifierName
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3378
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3379
     * SuperCall :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3380
     *      super Arguments
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3381
     *
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3382
     * See 11.2
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3383
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3384
     * Parse left hand side expression.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3385
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3386
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3387
    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
  3388
        int  callLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3389
        long callToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3390
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3391
        Expression lhs = memberExpression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3392
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3393
        if (type == LPAREN) {
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3394
            final List<Expression> arguments = optimizeList(argumentList());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3395
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3396
            // Catch special functions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3397
            if (lhs instanceof IdentNode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3398
                detectSpecialFunction((IdentNode)lhs);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3399
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3400
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3401
            lhs = new CallNode(callLine, callToken, finish, lhs, arguments, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3402
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3403
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3404
        loop:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3405
        while (true) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3406
            // 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
  3407
            callLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3408
            callToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3409
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3410
            switch (type) {
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3411
            case LPAREN: {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3412
                // Get NEW or FUNCTION arguments.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3413
                final List<Expression> arguments = optimizeList(argumentList());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3414
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3415
                // Create call node.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3416
                lhs = new CallNode(callLine, callToken, finish, lhs, arguments, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3417
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3418
                break;
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3419
            }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3420
            case LBRACKET: {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3421
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3422
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3423
                // Get array index.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3424
                final Expression rhs = expression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3425
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3426
                expect(RBRACKET);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3427
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3428
                // Create indexing node.
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  3429
                lhs = new IndexNode(callToken, finish, lhs, rhs);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3430
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3431
                break;
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3432
            }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3433
            case PERIOD: {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3434
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3435
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3436
                final IdentNode property = getIdentifierName();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3437
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3438
                // Create property access node.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3439
                lhs = new AccessNode(callToken, finish, lhs, property.getName());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3440
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3441
                break;
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3442
            }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3443
            case TEMPLATE:
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3444
            case TEMPLATE_HEAD: {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3445
                // tagged template literal
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3446
                final List<Expression> arguments = templateLiteralArgumentList();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3447
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3448
                // Create call node.
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3449
                lhs = new CallNode(callLine, callToken, finish, lhs, arguments, false);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3450
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3451
                break;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3452
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3453
            default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3454
                break loop;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3455
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3456
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3457
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3458
        return lhs;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3459
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3460
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3461
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3462
     * NewExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3463
     *      MemberExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3464
     *      new NewExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3465
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3466
     * See 11.2
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3467
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3468
     * Parse new expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3469
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3470
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3471
    private Expression newExpression() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3472
        final long newToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3473
        // NEW is tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3474
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3475
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3476
        if (type == PERIOD && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3477
            next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3478
            if (type == IDENT && "target".equals(getValue())) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3479
                if (lc.getCurrentFunction().isProgram()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3480
                    throw error(AbstractParser.message("new.target.in.function"), token);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3481
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3482
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3483
                markNewTarget(lc);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3484
                return new IdentNode(newToken, finish, "new.target");
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3485
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3486
                throw error(AbstractParser.message("expected.target"), token);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3487
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3488
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3489
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3490
        // 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
  3491
        final int  callLine    = line;
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3492
        final Expression constructor = memberExpression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3493
        if (constructor == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3494
            return null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3495
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3496
        // Get arguments.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3497
        ArrayList<Expression> arguments;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3498
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3499
        // Allow for missing arguments.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3500
        if (type == LPAREN) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3501
            arguments = argumentList();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3502
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3503
            arguments = new ArrayList<>();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3504
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3505
16196
58f6f046bb5e 8006983: Introduce a command line option to switch off syntactic extensions of nashorn
sundar
parents: 16191
diff changeset
  3506
        // 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
  3507
        // syntax:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3508
        //
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3509
        //     var r = new java.lang.Runnable() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3510
        //         run: function() { println("run"); }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3511
        //     };
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3512
        //
32534
b3ec7f3b3c2a 8136349: Typos patch for nashorn sources submitted on Sep 10, 2015
sundar
parents: 32444
diff changeset
  3513
        // The object literal following the "new Constructor()" expression
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3514
        // 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
  3515
        if (!env._no_syntax_extensions && type == LBRACE) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3516
            arguments.add(objectLiteral());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3517
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3518
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3519
        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
  3520
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  3521
        return new UnaryNode(newToken, callNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3522
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3523
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3524
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3525
     * MemberExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3526
     *      PrimaryExpression
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3527
     *        FunctionExpression
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3528
     *        ClassExpression
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3529
     *        GeneratorExpression
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3530
     *      MemberExpression [ Expression ]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3531
     *      MemberExpression . IdentifierName
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3532
     *      MemberExpression TemplateLiteral
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3533
     *      SuperProperty
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3534
     *      MetaProperty
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3535
     *      new MemberExpression Arguments
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3536
     *
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3537
     * SuperProperty :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3538
     *      super [ Expression ]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3539
     *      super . IdentifierName
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3540
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3541
     * MetaProperty :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3542
     *      NewTarget
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3543
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3544
     * Parse member expression.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3545
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3546
     */
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3547
    @SuppressWarnings("fallthrough")
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3548
    private Expression memberExpression() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3549
        // Prepare to build operation.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3550
        Expression lhs;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3551
        boolean isSuper = false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3552
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3553
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3554
        case NEW:
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3555
            // Get new expression.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3556
            lhs = newExpression();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3557
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3558
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3559
        case FUNCTION:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3560
            // Get function expression.
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  3561
            lhs = functionExpression(false, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3562
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3563
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3564
        case CLASS:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3565
            if (isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3566
                lhs = classExpression(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3567
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3568
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3569
                // fall through
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3570
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3571
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3572
        case SUPER:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3573
            if (isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3574
                final ParserContextFunctionNode currentFunction = getCurrentNonArrowFunction();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3575
                if (currentFunction.isMethod()) {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  3576
                    final long identToken = Token.recast(token, IDENT);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3577
                    next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3578
                    lhs = createIdentNode(identToken, finish, SUPER.getName());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3579
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3580
                    switch (type) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3581
                        case LBRACKET:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3582
                        case PERIOD:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3583
                            getCurrentNonArrowFunction().setFlag(FunctionNode.ES6_USES_SUPER);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3584
                            isSuper = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3585
                            break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3586
                        case LPAREN:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3587
                            if (currentFunction.isSubclassConstructor()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3588
                                lhs = ((IdentNode)lhs).setIsDirectSuper();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3589
                                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3590
                            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3591
                                // fall through to throw error
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3592
                            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3593
                        default:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3594
                            throw error(AbstractParser.message("invalid.super"), identToken);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3595
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3596
                    break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3597
                } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3598
                    // fall through
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3599
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3600
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3601
                // fall through
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3602
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3603
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3604
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3605
            // Get primary expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3606
            lhs = primaryExpression();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3607
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3608
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3609
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3610
        loop:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3611
        while (true) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3612
            // Capture token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3613
            final long callToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3614
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3615
            switch (type) {
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  3616
            case LBRACKET: {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3617
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3618
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3619
                // Get array index.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3620
                final Expression index = expression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3621
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3622
                expect(RBRACKET);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3623
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3624
                // Create indexing node.
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  3625
                lhs = new IndexNode(callToken, finish, lhs, index);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3626
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3627
                if (isSuper) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3628
                    isSuper = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3629
                    lhs = ((BaseNode) lhs).setIsSuper();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3630
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3631
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3632
                break;
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  3633
            }
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  3634
            case PERIOD: {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3635
                if (lhs == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3636
                    throw error(AbstractParser.message("expected.operand", type.getNameOrType()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3637
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3638
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3639
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3640
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3641
                final IdentNode property = getIdentifierName();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3642
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3643
                // Create property access node.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3644
                lhs = new AccessNode(callToken, finish, lhs, property.getName());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3645
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3646
                if (isSuper) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3647
                    isSuper = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3648
                    lhs = ((BaseNode) lhs).setIsSuper();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3649
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3650
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3651
                break;
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  3652
            }
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3653
            case TEMPLATE:
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3654
            case TEMPLATE_HEAD: {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3655
                // tagged template literal
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3656
                final int callLine = line;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3657
                final List<Expression> arguments = templateLiteralArgumentList();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3658
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3659
                lhs = new CallNode(callLine, callToken, finish, lhs, arguments, false);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3660
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3661
                break;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3662
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3663
            default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3664
                break loop;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3665
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3666
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3667
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3668
        return lhs;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3669
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3670
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3671
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3672
     * Arguments :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3673
     *      ( )
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3674
     *      ( ArgumentList )
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3675
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3676
     * ArgumentList :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3677
     *      AssignmentExpression
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3678
     *      ... AssignmentExpression
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3679
     *      ArgumentList , AssignmentExpression
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3680
     *      ArgumentList , ... AssignmentExpression
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3681
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3682
     * See 11.2
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3683
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3684
     * Parse function call arguments.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3685
     * @return Argument list.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3686
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3687
    private ArrayList<Expression> argumentList() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3688
        // Prepare to accumulate list of arguments.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3689
        final ArrayList<Expression> nodeList = new ArrayList<>();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3690
        // LPAREN tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3691
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3692
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3693
        // Track commas.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3694
        boolean first = true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3695
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3696
        while (type != RPAREN) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3697
            // Comma prior to every argument except the first.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3698
            if (!first) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3699
                expect(COMMARIGHT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3700
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3701
                first = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3702
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3703
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3704
            long spreadToken = 0;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3705
            if (type == ELLIPSIS && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3706
                spreadToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3707
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3708
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3709
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3710
            // Get argument expression.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3711
            Expression expression = assignmentExpression(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3712
            if (spreadToken != 0) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3713
                expression = new UnaryNode(Token.recast(spreadToken, TokenType.SPREAD_ARGUMENT), expression);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3714
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3715
            nodeList.add(expression);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3716
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3717
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3718
        expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3719
        return nodeList;
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3720
    }
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3721
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
  3722
    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
  3723
        switch(list.size()) {
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3724
            case 0: {
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3725
                return Collections.emptyList();
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3726
            }
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3727
            case 1: {
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3728
                return Collections.singletonList(list.get(0));
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3729
            }
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3730
            default: {
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3731
                list.trimToSize();
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3732
                return list;
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3733
            }
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3734
        }
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3735
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3736
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3737
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3738
     * FunctionDeclaration :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3739
     *      function Identifier ( FormalParameterList? ) { FunctionBody }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3740
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3741
     * FunctionExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3742
     *      function Identifier? ( FormalParameterList? ) { FunctionBody }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3743
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3744
     * See 13
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3745
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3746
     * Parse function declaration.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3747
     * @param isStatement True if for is a statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3748
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3749
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3750
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3751
    private Expression functionExpression(final boolean isStatement, final boolean topLevel) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3752
        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
  3753
        final int  functionLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3754
        // FUNCTION is tested in caller.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3755
        assert type == FUNCTION;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3756
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3757
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3758
        boolean generator = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3759
        if (type == MUL && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3760
            generator = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3761
            next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3762
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3763
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3764
        IdentNode name = null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3765
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3766
        if (isBindingIdentifier()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3767
            if (type == YIELD && ((!isStatement && generator) || (isStatement && inGeneratorFunction()))) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3768
                // 12.1.1 Early SyntaxError if:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3769
                // GeneratorExpression with BindingIdentifier yield
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3770
                // HoistableDeclaration with BindingIdentifier yield in generator function body
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3771
                expect(IDENT);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3772
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3773
            name = getIdent();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3774
            verifyStrictIdent(name, "function name");
16196
58f6f046bb5e 8006983: Introduce a command line option to switch off syntactic extensions of nashorn
sundar
parents: 16191
diff changeset
  3775
        } else if (isStatement) {
31095
790fc3d576f9 8085802: Nashorn -nse option causes parse error on anonymous function definition
sundar
parents: 30392
diff changeset
  3776
            // Nashorn extension: anonymous function statements.
790fc3d576f9 8085802: Nashorn -nse option causes parse error on anonymous function definition
sundar
parents: 30392
diff changeset
  3777
            // 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
  3778
            // 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
  3779
            // 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
  3780
            // expression in surrounding code.
790fc3d576f9 8085802: Nashorn -nse option causes parse error on anonymous function definition
sundar
parents: 30392
diff changeset
  3781
            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
  3782
                expect(IDENT);
58f6f046bb5e 8006983: Introduce a command line option to switch off syntactic extensions of nashorn
sundar
parents: 16191
diff changeset
  3783
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3784
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3785
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3786
        // name is null, generate anonymous name
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3787
        boolean isAnonymous = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3788
        if (name == null) {
27974
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3789
            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
  3790
            name = new IdentNode(functionToken, Token.descPosition(functionToken), tmpName);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3791
            isAnonymous = true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3792
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3793
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  3794
        final FunctionNode.Kind functionKind = generator ? FunctionNode.Kind.GENERATOR : FunctionNode.Kind.NORMAL;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3795
        List<IdentNode> parameters = Collections.emptyList();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3796
        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
  3797
        lc.push(functionNode);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3798
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3799
        Block functionBody = null;
27974
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3800
        // 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
  3801
        // 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
  3802
        hideDefaultName();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3803
        try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3804
            final ParserContextBlockNode parameterBlock = newBlock();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3805
            try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3806
                expect(LPAREN);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3807
                parameters = formalParameterList(generator);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3808
                functionNode.setParameters(parameters);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3809
                expect(RPAREN);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3810
            } finally {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3811
                restoreBlock(parameterBlock);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3812
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3813
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3814
            functionBody = functionBody(functionNode);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3815
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3816
            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
  3817
        } finally {
27974
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3818
            defaultNames.pop();
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3819
            lc.pop(functionNode);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3820
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3821
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  3822
        if (isStatement) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3823
            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
  3824
                functionNode.setFlag(FunctionNode.IS_DECLARED);
17257
a2232050cd8f 8008814: Configurable ignore/warning/error behavior for function declaration as statement
attila
parents: 17255
diff changeset
  3825
            } else if (isStrictMode) {
a2232050cd8f 8008814: Configurable ignore/warning/error behavior for function declaration as statement
attila
parents: 17255
diff changeset
  3826
                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
  3827
            } 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
  3828
                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
  3829
            } 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
  3830
                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
  3831
            }
19898
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
  3832
            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
  3833
               lc.getCurrentFunction().setFlag(FunctionNode.DEFINES_ARGUMENTS);
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
  3834
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3835
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3836
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3837
        if (isAnonymous) {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3838
            functionNode.setFlag(FunctionNode.IS_ANONYMOUS);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3839
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3840
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3841
        verifyParameterList(parameters, functionNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3842
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3843
        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
  3844
                functionNode,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3845
                functionToken,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3846
                name,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3847
                parameters,
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3848
                functionKind,
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3849
                functionLine,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3850
                functionBody);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3851
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3852
        if (isStatement) {
31485
be1acaee8e9e 8114838: Anonymous functions escape to surrounding scope when defined under "with" statement
sundar
parents: 31095
diff changeset
  3853
            if (isAnonymous) {
be1acaee8e9e 8114838: Anonymous functions escape to surrounding scope when defined under "with" statement
sundar
parents: 31095
diff changeset
  3854
                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
  3855
                return function;
be1acaee8e9e 8114838: Anonymous functions escape to surrounding scope when defined under "with" statement
sundar
parents: 31095
diff changeset
  3856
            }
be1acaee8e9e 8114838: Anonymous functions escape to surrounding scope when defined under "with" statement
sundar
parents: 31095
diff changeset
  3857
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  3858
            // mark ES6 block functions as lexically scoped
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  3859
            final int     varFlags = (topLevel || !useBlockScope()) ? 0 : VarNode.IS_LET;
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  3860
            final VarNode varNode  = new VarNode(functionLine, functionToken, finish, name, function, varFlags);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3861
            if (topLevel) {
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  3862
                functionDeclarations.add(varNode);
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  3863
            } else if (useBlockScope()) {
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  3864
                prependStatement(varNode); // Hoist to beginning of current block
16191
7dd981da8e11 8006755: Functions inside with statements dont get correct scope
sundar
parents: 16187
diff changeset
  3865
            } else {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3866
                appendStatement(varNode);
16191
7dd981da8e11 8006755: Functions inside with statements dont get correct scope
sundar
parents: 16187
diff changeset
  3867
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3868
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3869
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3870
        return function;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3871
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3872
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3873
    private void verifyParameterList(final List<IdentNode> parameters, final ParserContextFunctionNode functionNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3874
        final IdentNode duplicateParameter = functionNode.getDuplicateParameterBinding();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3875
        if (duplicateParameter != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3876
            if (functionNode.isStrict() || functionNode.getKind() == FunctionNode.Kind.ARROW || !functionNode.isSimpleParameterList()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3877
                throw error(AbstractParser.message("strict.param.redefinition", duplicateParameter.getName()), duplicateParameter.getToken());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3878
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3879
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3880
            final int arity = parameters.size();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3881
            final HashSet<String> parametersSet = new HashSet<>(arity);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3882
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3883
            for (int i = arity - 1; i >= 0; i--) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3884
                final IdentNode parameter = parameters.get(i);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3885
                String parameterName = parameter.getName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3886
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3887
                if (parametersSet.contains(parameterName)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3888
                    // redefinition of parameter name, rename in non-strict mode
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3889
                    parameterName = functionNode.uniqueName(parameterName);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3890
                    final long parameterToken = parameter.getToken();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3891
                    parameters.set(i, new IdentNode(parameterToken, Token.descPosition(parameterToken), functionNode.uniqueName(parameterName)));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3892
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3893
                parametersSet.add(parameterName);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3894
            }
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
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  3898
    private static Block maybeWrapBodyInParameterBlock(final Block functionBody, final ParserContextBlockNode parameterBlock) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3899
        assert functionBody.isFunctionBody();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3900
        if (!parameterBlock.getStatements().isEmpty()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3901
            parameterBlock.appendStatement(new BlockStatement(functionBody));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3902
            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
  3903
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3904
        return functionBody;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3905
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3906
27974
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3907
    private String getDefaultValidFunctionName(final int functionLine, final boolean isStatement) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3908
        final String defaultFunctionName = getDefaultFunctionName();
27974
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3909
        if (isValidIdentifier(defaultFunctionName)) {
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3910
            if (isStatement) {
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3911
                // 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
  3912
                // 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
  3913
                return ANON_FUNCTION_PREFIX.symbolName() + defaultFunctionName;
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3914
            }
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3915
            return defaultFunctionName;
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3916
        }
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3917
        return ANON_FUNCTION_PREFIX.symbolName() + functionLine;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3918
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3919
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
  3920
    private static boolean isValidIdentifier(final String name) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3921
        if (name == null || name.isEmpty()) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3922
            return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3923
        }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3924
        if (!Character.isJavaIdentifierStart(name.charAt(0))) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3925
            return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3926
        }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3927
        for (int i = 1; i < name.length(); ++i) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3928
            if (!Character.isJavaIdentifierPart(name.charAt(i))) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3929
                return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3930
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3931
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3932
        return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3933
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3934
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3935
    private String getDefaultFunctionName() {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3936
        if (!defaultNames.isEmpty()) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3937
            final Object nameExpr = defaultNames.peek();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3938
            if (nameExpr instanceof PropertyKey) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3939
                markDefaultNameUsed();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3940
                return ((PropertyKey)nameExpr).getPropertyName();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3941
            } else if (nameExpr instanceof AccessNode) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3942
                markDefaultNameUsed();
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3943
                return ((AccessNode)nameExpr).getProperty();
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3944
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3945
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3946
        return null;
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
    private void markDefaultNameUsed() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3950
        defaultNames.pop();
27974
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3951
        hideDefaultName();
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3952
    }
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3953
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3954
    private void hideDefaultName() {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3955
        // 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
  3956
        // from. Can't be null
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3957
        defaultNames.push("");
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3958
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3959
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3960
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3961
     * FormalParameterList :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3962
     *      Identifier
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3963
     *      FormalParameterList , Identifier
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3964
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3965
     * See 13
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3966
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3967
     * Parse function parameter list.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3968
     * @return List of parameter nodes.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3969
     */
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3970
    private List<IdentNode> formalParameterList(final boolean yield) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3971
        return formalParameterList(RPAREN, yield);
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3972
    }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3974
    /**
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3975
     * 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
  3976
     * token type expected is passed as argument to this method.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3977
     *
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3978
     * FormalParameterList :
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3979
     *      Identifier
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3980
     *      FormalParameterList , Identifier
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3981
     *
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3982
     * See 13
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3983
     *
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3984
     * Parse function parameter list.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3985
     * @return List of parameter nodes.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3986
     */
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3987
    private List<IdentNode> formalParameterList(final TokenType endType, final boolean yield) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3988
        // Prepare to gather parameters.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3989
        final ArrayList<IdentNode> parameters = new ArrayList<>();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3990
        // Track commas.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3991
        boolean first = true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3992
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3993
        while (type != endType) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3994
            // Comma prior to every argument except the first.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3995
            if (!first) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3996
                expect(COMMARIGHT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3997
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3998
                first = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3999
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4000
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4001
            boolean restParameter = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4002
            if (type == ELLIPSIS && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4003
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4004
                restParameter = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4005
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4006
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4007
            if (type == YIELD && yield) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4008
                expect(IDENT);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4009
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4010
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4011
            final long paramToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4012
            final int paramLine = line;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4013
            final String contextString = "function parameter";
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4014
            IdentNode ident;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4015
            if (isBindingIdentifier() || restParameter || !isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4016
                ident = bindingIdentifier(contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4017
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4018
                if (restParameter) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4019
                    ident = ident.setIsRestParameter();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4020
                    // rest parameter must be last
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4021
                    expectDontAdvance(endType);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4022
                    parameters.add(ident);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4023
                    break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4024
                } else if (type == ASSIGN && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4025
                    next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4026
                    ident = ident.setIsDefaultParameter();
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
                    if (type == YIELD && yield) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4029
                        // error: yield in default expression
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4030
                        expect(IDENT);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4031
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4032
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4033
                    // default parameter
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4034
                    final Expression initializer = assignmentExpression(false);
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4035
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4036
                    final ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4037
                    if (currentFunction != null) {
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4038
                        if (env._parse_only) {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4039
                            // 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
  4040
                            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
  4041
                            currentFunction.addParameterExpression(ident, assignment);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4042
                        } else {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4043
                            // desugar to: param = (param === undefined) ? initializer : param;
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4044
                            // possible alternative: if (param === undefined) param = initializer;
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4045
                            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
  4046
                            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
  4047
                            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
  4048
                            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
  4049
                        }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4050
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4051
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4052
41422
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) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4055
                    currentFunction.addParameterBinding(ident);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4056
                    if (ident.isRestParameter() || ident.isDefaultParameter()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4057
                        currentFunction.setSimpleParameterList(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4058
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4059
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4060
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4061
                final Expression pattern = bindingPattern();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4062
                // Introduce synthetic temporary parameter to capture the object to be destructured.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4063
                ident = createIdentNode(paramToken, pattern.getFinish(), String.format("arguments[%d]", parameters.size())).setIsDestructuredParameter();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4064
                verifyDestructuringParameterBindingPattern(pattern, paramToken, paramLine, contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4065
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4066
                Expression value = ident;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4067
                if (type == ASSIGN) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4068
                    next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4069
                    ident = ident.setIsDefaultParameter();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4070
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4071
                    // binding pattern with initializer. desugar to: (param === undefined) ? initializer : param
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4072
                    final Expression initializer = assignmentExpression(false);
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4073
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4074
                    if (env._parse_only) {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4075
                        // 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
  4076
                        value = initializer;
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4077
                    } else {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4078
                        // 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
  4079
                        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
  4080
                        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
  4081
                    }
37732
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
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4084
                final ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4085
                if (currentFunction != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4086
                    // destructuring assignment
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4087
                    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
  4088
                    if (env._parse_only) {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4089
                        // 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
  4090
                        if (ident.isDefaultParameter()) {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4091
                            currentFunction.addParameterExpression(ident, assignment);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4092
                        } else {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4093
                            currentFunction.addParameterExpression(ident, pattern);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4094
                        }
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4095
                    } else {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4096
                        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
  4097
                    }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4098
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4099
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4100
            parameters.add(ident);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4101
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4102
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  4103
        parameters.trimToSize();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4104
        return parameters;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4105
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4106
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4107
    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
  4108
        verifyDestructuringBindingPattern(pattern, new Consumer<IdentNode>() {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4109
            public void accept(final IdentNode identNode) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4110
                verifyIdent(identNode, contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4111
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4112
                final ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4113
                if (currentFunction != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4114
                    // declare function-scope variables for destructuring bindings
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4115
                    if (!env._parse_only) {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4116
                        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
  4117
                    }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4118
                    // detect duplicate bounds names in parameter list
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4119
                    currentFunction.addParameterBinding(identNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4120
                    currentFunction.setSimpleParameterList(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4121
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4122
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4123
        });
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4124
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4125
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4126
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4127
     * FunctionBody :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4128
     *      SourceElements?
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4129
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4130
     * See 13
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4131
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4132
     * Parse function body.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4133
     * @return function node (body.)
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4134
     */
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4135
    private Block functionBody(final ParserContextFunctionNode functionNode) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4136
        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
  4137
        ParserContextBlockNode body = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4138
        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
  4139
        Block functionBody;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4140
        int bodyFinish = 0;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4141
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4142
        final boolean parseBody;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4143
        Object endParserState = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4144
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4145
            // 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
  4146
            body = newBlock();
33888
0c7b0ab328e0 8131929: Add option for debuggable scopes
hannesw
parents: 33533
diff changeset
  4147
            if (env._debug_scopes) {
0c7b0ab328e0 8131929: Add option for debuggable scopes
hannesw
parents: 33533
diff changeset
  4148
                // debug scope options forces everything to be in scope
0c7b0ab328e0 8131929: Add option for debuggable scopes
hannesw
parents: 33533
diff changeset
  4149
                markEval(lc);
0c7b0ab328e0 8131929: Add option for debuggable scopes
hannesw
parents: 33533
diff changeset
  4150
            }
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4151
            assert functionNode != null;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4152
            final int functionId = functionNode.getId();
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4153
            parseBody = reparsedFunction == null || functionId <= reparsedFunction.getFunctionNodeId();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4154
            // Nashorn extension: expression closures
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4155
            if ((!env._no_syntax_extensions || functionNode.getKind() == FunctionNode.Kind.ARROW) && type != LBRACE) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4156
                /*
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4157
                 * Example:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4158
                 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4159
                 * function square(x) x * x;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4160
                 * print(square(3));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4161
                 */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4162
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4163
                // just expression as function body
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4164
                final Expression expr = assignmentExpression(false);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4165
                lastToken = previousToken;
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4166
                functionNode.setLastToken(previousToken);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4167
                assert lc.getCurrentBlock() == lc.getFunctionBody(functionNode);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4168
                // EOL uses length field to store the line number
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4169
                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
  4170
                // 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
  4171
                // 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
  4172
                // 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
  4173
                // 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
  4174
                // details).
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4175
                if (parseBody) {
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4176
                    functionNode.setFlag(FunctionNode.HAS_EXPRESSION_BODY);
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4177
                    final ReturnNode returnNode = new ReturnNode(functionNode.getLineNumber(), expr.getToken(), lastFinish, expr);
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4178
                    appendStatement(returnNode);
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4179
                }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4180
                // bodyFinish = finish;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4181
            } else {
26505
d29bf8787b43 8057931: Instead of not skipping small functions in parser, make lexer avoid them instead
attila
parents: 26503
diff changeset
  4182
                expectDontAdvance(LBRACE);
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4183
                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
  4184
                    next();
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4185
                    // Gather the function elements.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4186
                    final List<Statement> prevFunctionDecls = functionDeclarations;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4187
                    functionDeclarations = new ArrayList<>();
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4188
                    try {
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
  4189
                        sourceElements(0);
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4190
                        addFunctionDeclarations(functionNode);
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4191
                    } finally {
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4192
                        functionDeclarations = prevFunctionDecls;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4193
                    }
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4194
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4195
                    lastToken = token;
26505
d29bf8787b43 8057931: Instead of not skipping small functions in parser, make lexer avoid them instead
attila
parents: 26503
diff changeset
  4196
                    if (parseBody) {
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4197
                        // 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
  4198
                        // 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
  4199
                        // 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
  4200
                        // ahead) state.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4201
                        endParserState = new ParserState(Token.descPosition(token), line, linePosition);
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4202
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4203
                        // 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
  4204
                        // 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
  4205
                        // 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
  4206
                        // 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
  4207
                        // point. Typical example of a weird lexer state after RBRACE would be:
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4208
                        //     function this_is_skipped() { ... } "use strict";
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4209
                        // 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
  4210
                        // 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
  4211
                        // 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
  4212
                    }
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  4213
                }
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4214
                bodyFinish = finish;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4215
                functionNode.setLastToken(token);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4216
                expect(RBRACE);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4217
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4218
        } finally {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4219
            restoreBlock(body);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4220
        }
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4221
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4222
        // NOTE: we can only do alterations to the function node after restoreFunctionNode.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4223
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4224
        if (parseBody) {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4225
            functionNode.setEndParserState(endParserState);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4226
        } else if (!body.getStatements().isEmpty()){
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4227
            // 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
  4228
            // 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
  4229
            // 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
  4230
            // 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
  4231
            // 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
  4232
            body.setStatements(Collections.<Statement>emptyList());
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4233
        }
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4234
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4235
        if (reparsedFunction != null) {
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4236
            // 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
  4237
            // 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
  4238
            // 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
  4239
            // skipped during an on-demand compilation.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4240
            final RecompilableScriptFunctionData data = reparsedFunction.getScriptFunctionData(functionNode.getId());
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4241
            if (data != null) {
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4242
                // 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
  4243
                // 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
  4244
                functionNode.setFlag(data.getFunctionFlags());
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4245
                // 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
  4246
                // 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
  4247
                if (functionNode.hasNestedEval()) {
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4248
                    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
  4249
                    body.setFlag(Block.NEEDS_SCOPE);
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
        }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4253
        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
  4254
        return functionBody;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4255
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4256
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4257
    private boolean skipFunctionBody(final ParserContextFunctionNode functionNode) {
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4258
        if (reparsedFunction == null) {
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4259
            // Not reparsing, so don't skip any function body.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4260
            return false;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4261
        }
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4262
        // Skip to the RBRACE of this function, and continue parsing from there.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4263
        final RecompilableScriptFunctionData data = reparsedFunction.getScriptFunctionData(functionNode.getId());
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4264
        if (data == null) {
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4265
            // 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
  4266
            // 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
  4267
            // FunctionNode was dropped before a RecompilableScriptFunctionData could've been created for it.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4268
            return false;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4269
        }
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4270
        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
  4271
        assert parserState != null;
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4272
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4273
        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
  4274
            // RBRACE is already in the token stream, so fast forward to it
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4275
            for (; k < stream.last(); k++) {
34447
ec4c069f9436 8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents: 33888
diff changeset
  4276
                final long nextToken = stream.get(k + 1);
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4277
                if (Token.descPosition(nextToken) == parserState.position && Token.descType(nextToken) == RBRACE) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4278
                    token = stream.get(k);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4279
                    type = Token.descType(token);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4280
                    next();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4281
                    assert type == RBRACE && start == parserState.position;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4282
                    return true;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4283
                }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4284
            }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4285
        }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4286
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4287
        stream.reset();
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
  4288
        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
  4289
        line = parserState.line;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4290
        linePosition = parserState.linePosition;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4291
        // 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
  4292
        // the RBRACE.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4293
        type = SEMICOLON;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4294
        scanFirstToken();
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4295
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4296
        return true;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4297
    }
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4298
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4299
    /**
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4300
     * 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
  4301
     * for resuming parsing after skipping a function body.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4302
     */
26646
332e9901f0ed 8058304: Non-serializable fields in serializable classes
hannesw
parents: 26505
diff changeset
  4303
    private static class ParserState implements Serializable {
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4304
        private final int position;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4305
        private final int line;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4306
        private final int linePosition;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4307
26646
332e9901f0ed 8058304: Non-serializable fields in serializable classes
hannesw
parents: 26505
diff changeset
  4308
        private static final long serialVersionUID = -2382565130754093694L;
332e9901f0ed 8058304: Non-serializable fields in serializable classes
hannesw
parents: 26505
diff changeset
  4309
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4310
        ParserState(final int position, final int line, final int linePosition) {
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4311
            this.position = position;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4312
            this.line = line;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4313
            this.linePosition = linePosition;
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
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
  4316
        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
  4317
            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
  4318
            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
  4319
            return newLexer;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4320
        }
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4321
    }
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4322
26065
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  4323
    private void printAST(final FunctionNode functionNode) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4324
        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
  4325
            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
  4326
        }
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  4327
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4328
        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
  4329
            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
  4330
        }
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  4331
    }
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  4332
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4333
    private void addFunctionDeclarations(final ParserContextFunctionNode functionNode) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4334
        VarNode lastDecl = null;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4335
        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
  4336
            Statement decl = functionDeclarations.get(i);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4337
            if (lastDecl == null && decl instanceof VarNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4338
                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
  4339
                functionNode.setFlag(FunctionNode.HAS_FUNCTION_DECLARATIONS);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4340
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4341
            prependStatement(decl);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4342
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4343
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4344
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4345
    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
  4346
        if (env._parse_only || earlyError) {
18632
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  4347
            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
  4348
        }
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4349
        final ArrayList<Expression> args = new ArrayList<>();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4350
        args.add(lhs);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4351
        if (rhs == null) {
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  4352
            args.add(LiteralNode.newInstance(lhs.getToken(), lhs.getFinish()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4353
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4354
            args.add(rhs);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4355
        }
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  4356
        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
  4357
        return new RuntimeNode(lhs.getToken(), lhs.getFinish(), RuntimeNode.Request.REFERENCE_ERROR, args);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4358
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4359
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4360
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4361
     * PostfixExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4362
     *      LeftHandSideExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4363
     *      LeftHandSideExpression ++ // [no LineTerminator here]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4364
     *      LeftHandSideExpression -- // [no LineTerminator here]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4365
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4366
     * See 11.3
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4367
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4368
     * UnaryExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4369
     *      PostfixExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4370
     *      delete UnaryExpression
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  4371
     *      void UnaryExpression
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4372
     *      typeof UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4373
     *      ++ UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4374
     *      -- UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4375
     *      + UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4376
     *      - UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4377
     *      ~ UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4378
     *      ! UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4379
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4380
     * See 11.4
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4381
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4382
     * Parse unary expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4383
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4384
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4385
    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
  4386
        final int  unaryLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4387
        final long unaryToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4388
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4389
        switch (type) {
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
  4390
        case DELETE: {
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
  4391
            next();
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4392
            final Expression expr = 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
  4393
            if (expr instanceof BaseNode || expr instanceof IdentNode) {
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
  4394
                return new UnaryNode(unaryToken, expr);
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
  4395
            }
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4396
            appendStatement(new ExpressionStatement(unaryLine, unaryToken, finish, expr));
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
  4397
            return LiteralNode.newInstance(unaryToken, finish, true);
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
  4398
        }
46169
b385216af0ed 8185252: Unary minus and plus use wrong node Kind
hannesw
parents: 41983
diff changeset
  4399
        case ADD:
b385216af0ed 8185252: Unary minus and plus use wrong node Kind
hannesw
parents: 41983
diff changeset
  4400
        case SUB: {
b385216af0ed 8185252: Unary minus and plus use wrong node Kind
hannesw
parents: 41983
diff changeset
  4401
            final TokenType opType = type;
b385216af0ed 8185252: Unary minus and plus use wrong node Kind
hannesw
parents: 41983
diff changeset
  4402
            next();
b385216af0ed 8185252: Unary minus and plus use wrong node Kind
hannesw
parents: 41983
diff changeset
  4403
            final Expression expr = unaryExpression();
b385216af0ed 8185252: Unary minus and plus use wrong node Kind
hannesw
parents: 41983
diff changeset
  4404
            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
  4405
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4406
        case VOID:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4407
        case TYPEOF:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4408
        case BIT_NOT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4409
        case NOT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4410
            next();
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4411
            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
  4412
            return new UnaryNode(unaryToken, expr);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4413
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4414
        case INCPREFIX:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4415
        case DECPREFIX:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4416
            final TokenType opType = type;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4417
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4418
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4419
            final Expression lhs = leftHandSideExpression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4420
            // ++, -- without operand..
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4421
            if (lhs == null) {
18632
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  4422
                throw error(AbstractParser.message("expected.lvalue", type.getNameOrType()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4423
            }
18632
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  4424
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4425
            return verifyIncDecExpression(unaryToken, opType, lhs, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4426
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4427
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4428
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4429
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4430
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4431
        final Expression expression = leftHandSideExpression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4432
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4433
        if (last != EOL) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4434
            switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4435
            case INCPREFIX:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4436
            case DECPREFIX:
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4437
                final long opToken = token;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4438
                final TokenType opType = type;
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4439
                final Expression lhs = expression;
18632
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  4440
                // ++, -- without operand..
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  4441
                if (lhs == null) {
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  4442
                    throw error(AbstractParser.message("expected.lvalue", type.getNameOrType()));
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  4443
                }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4444
                next();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4445
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4446
                return verifyIncDecExpression(opToken, opType, lhs, true);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4447
            default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4448
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4449
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4450
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4451
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4452
        if (expression == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4453
            throw error(AbstractParser.message("expected.operand", type.getNameOrType()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4454
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4455
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4456
        return expression;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4457
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4458
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4459
    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
  4460
        assert lhs != null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4461
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4462
        if (!(lhs instanceof AccessNode ||
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4463
              lhs instanceof IndexNode ||
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4464
              lhs instanceof IdentNode)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4465
            return referenceError(lhs, null, env._early_lvalue_error);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4466
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4467
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4468
        if (lhs instanceof IdentNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4469
            if (!checkIdentLValue((IdentNode)lhs)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4470
                return referenceError(lhs, null, false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4471
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4472
            verifyIdent((IdentNode)lhs, "operand for " + opType.getName() + " operator");
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4473
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4474
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4475
        return incDecExpression(unaryToken, opType, lhs, isPostfix);
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
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4478
    /**
32245
80164edf8a10 8133872: Expression completion should work on contexts where an expression is accepted
sundar
parents: 31485
diff changeset
  4479
     * {@code
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4480
     * MultiplicativeExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4481
     *      UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4482
     *      MultiplicativeExpression * UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4483
     *      MultiplicativeExpression / UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4484
     *      MultiplicativeExpression % UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4485
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4486
     * See 11.5
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4487
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4488
     * AdditiveExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4489
     *      MultiplicativeExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4490
     *      AdditiveExpression + MultiplicativeExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4491
     *      AdditiveExpression - MultiplicativeExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4492
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4493
     * See 11.6
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4494
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4495
     * ShiftExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4496
     *      AdditiveExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4497
     *      ShiftExpression << AdditiveExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4498
     *      ShiftExpression >> AdditiveExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4499
     *      ShiftExpression >>> AdditiveExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4500
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4501
     * See 11.7
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4502
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4503
     * RelationalExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4504
     *      ShiftExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4505
     *      RelationalExpression < ShiftExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4506
     *      RelationalExpression > ShiftExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4507
     *      RelationalExpression <= ShiftExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4508
     *      RelationalExpression >= ShiftExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4509
     *      RelationalExpression instanceof ShiftExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4510
     *      RelationalExpression in ShiftExpression // if !noIf
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4511
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4512
     * See 11.8
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4513
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4514
     *      RelationalExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4515
     *      EqualityExpression == RelationalExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4516
     *      EqualityExpression != RelationalExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4517
     *      EqualityExpression === RelationalExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4518
     *      EqualityExpression !== RelationalExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4519
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4520
     * See 11.9
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4521
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4522
     * BitwiseANDExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4523
     *      EqualityExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4524
     *      BitwiseANDExpression & EqualityExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4525
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4526
     * BitwiseXORExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4527
     *      BitwiseANDExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4528
     *      BitwiseXORExpression ^ BitwiseANDExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4529
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4530
     * BitwiseORExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4531
     *      BitwiseXORExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4532
     *      BitwiseORExpression | BitwiseXORExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4533
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4534
     * See 11.10
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4535
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4536
     * LogicalANDExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4537
     *      BitwiseORExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4538
     *      LogicalANDExpression && BitwiseORExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4539
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4540
     * LogicalORExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4541
     *      LogicalANDExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4542
     *      LogicalORExpression || LogicalANDExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4543
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4544
     * See 11.11
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4545
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4546
     * ConditionalExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4547
     *      LogicalORExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4548
     *      LogicalORExpression ? AssignmentExpression : AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4549
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4550
     * See 11.12
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4551
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4552
     * AssignmentExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4553
     *      ConditionalExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4554
     *      LeftHandSideExpression AssignmentOperator AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4555
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4556
     * AssignmentOperator :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4557
     *      = *= /= %= += -= <<= >>= >>>= &= ^= |=
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4558
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4559
     * See 11.13
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4560
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4561
     * Expression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4562
     *      AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4563
     *      Expression , AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4564
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4565
     * See 11.14
32245
80164edf8a10 8133872: Expression completion should work on contexts where an expression is accepted
sundar
parents: 31485
diff changeset
  4566
     * }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4567
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4568
     * Parse expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4569
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4570
     */
32245
80164edf8a10 8133872: Expression completion should work on contexts where an expression is accepted
sundar
parents: 31485
diff changeset
  4571
    protected Expression expression() {
80164edf8a10 8133872: Expression completion should work on contexts where an expression is accepted
sundar
parents: 31485
diff changeset
  4572
        // 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
  4573
        // at expression start point!
80164edf8a10 8133872: Expression completion should work on contexts where an expression is accepted
sundar
parents: 31485
diff changeset
  4574
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4575
        // Include commas in expression parsing.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4576
        return expression(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4577
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4578
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4579
    private Expression expression(final boolean noIn) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4580
        Expression assignmentExpression = assignmentExpression(noIn);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4581
        while (type == COMMARIGHT) {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4582
            final long commaToken = token;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4583
            next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4584
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4585
            boolean rhsRestParameter = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4586
            if (type == ELLIPSIS && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4587
                // (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
  4588
                // 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
  4589
                if (isRestParameterEndOfArrowFunctionParameterList()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4590
                    next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4591
                    rhsRestParameter = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4592
                }
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
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4595
            Expression rhs = assignmentExpression(noIn);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4596
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4597
            if (rhsRestParameter) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4598
                rhs = ((IdentNode)rhs).setIsRestParameter();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4599
                // 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
  4600
                // 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
  4601
                // 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
  4602
                assert type == RPAREN;
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
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4605
            assignmentExpression = new BinaryNode(commaToken, assignmentExpression, rhs);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4606
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4607
        return assignmentExpression;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4608
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4609
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4610
    private Expression expression(final int minPrecedence, final boolean noIn) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4611
        return expression(unaryExpression(), minPrecedence, noIn);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4612
    }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4613
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  4614
    private JoinPredecessorExpression joinPredecessorExpression() {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  4615
        return new JoinPredecessorExpression(expression());
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  4616
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  4617
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4618
    private Expression expression(final Expression exprLhs, final int minPrecedence, final boolean noIn) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4619
        // Get the precedence of the next operator.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4620
        int precedence = type.getPrecedence();
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4621
        Expression lhs = exprLhs;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4622
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4623
        // While greater precedence.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4624
        while (type.isOperator(noIn) && precedence >= minPrecedence) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4625
            // Capture the operator token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4626
            final long op = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4627
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4628
            if (type == TERNARY) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4629
                // Skip operator.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4630
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4631
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4632
                // Pass expression. Middle expression of a conditional expression can be a "in"
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4633
                // expression - even in the contexts where "in" is not permitted.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  4634
                final Expression trueExpr = expression(unaryExpression(), ASSIGN.getPrecedence(), false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4635
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4636
                expect(COLON);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4637
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4638
                // Fail expression.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  4639
                final Expression falseExpr = expression(unaryExpression(), ASSIGN.getPrecedence(), noIn);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4640
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4641
                // Build up node.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  4642
                lhs = new TernaryNode(op, lhs, new JoinPredecessorExpression(trueExpr), new JoinPredecessorExpression(falseExpr));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4643
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4644
                // Skip operator.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4645
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4646
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4647
                 // Get the next primary expression.
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4648
                Expression rhs;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4649
                final boolean isAssign = Token.descType(op) == ASSIGN;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4650
                if(isAssign) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4651
                    defaultNames.push(lhs);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4652
                }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4653
                try {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4654
                    rhs = unaryExpression();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4655
                    // Get precedence of next operator.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4656
                    int nextPrecedence = type.getPrecedence();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4657
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4658
                    // Subtask greater precedence.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4659
                    while (type.isOperator(noIn) &&
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4660
                           (nextPrecedence > precedence ||
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4661
                           nextPrecedence == precedence && !type.isLeftAssociative())) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4662
                        rhs = expression(rhs, nextPrecedence, noIn);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4663
                        nextPrecedence = type.getPrecedence();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4664
                    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4665
                } finally {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4666
                    if(isAssign) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4667
                        defaultNames.pop();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4668
                    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4669
                }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4670
                lhs = verifyAssignment(op, lhs, rhs);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4671
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4672
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4673
            precedence = type.getPrecedence();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4674
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4675
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4676
        return lhs;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4677
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4678
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4679
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4680
     * AssignmentExpression.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4681
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4682
     * AssignmentExpression[In, Yield] :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4683
     *   ConditionalExpression[?In, ?Yield]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4684
     *   [+Yield] YieldExpression[?In]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4685
     *   ArrowFunction[?In, ?Yield]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4686
     *   LeftHandSideExpression[?Yield] = AssignmentExpression[?In, ?Yield]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4687
     *   LeftHandSideExpression[?Yield] AssignmentOperator AssignmentExpression[?In, ?Yield]
38807
79e9bf5bb792 8158250: nashorn ant javadoc targets are broken
sundar
parents: 38485
diff changeset
  4688
     *
79e9bf5bb792 8158250: nashorn ant javadoc targets are broken
sundar
parents: 38485
diff changeset
  4689
     * @param noIn {@code true} if IN operator should be ignored.
79e9bf5bb792 8158250: nashorn ant javadoc targets are broken
sundar
parents: 38485
diff changeset
  4690
     * @return the assignment expression
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4691
     */
32245
80164edf8a10 8133872: Expression completion should work on contexts where an expression is accepted
sundar
parents: 31485
diff changeset
  4692
    protected Expression assignmentExpression(final boolean noIn) {
80164edf8a10 8133872: Expression completion should work on contexts where an expression is accepted
sundar
parents: 31485
diff changeset
  4693
        // 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
  4694
        // at assignment expression start point!
80164edf8a10 8133872: Expression completion should work on contexts where an expression is accepted
sundar
parents: 31485
diff changeset
  4695
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4696
        if (type == YIELD && inGeneratorFunction() && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4697
            return yieldExpression(noIn);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4698
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4699
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4700
        final long startToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4701
        final int startLine = line;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4702
        final Expression exprLhs = conditionalExpression(noIn);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4703
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4704
        if (type == ARROW && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4705
            if (checkNoLineTerminator()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4706
                final Expression paramListExpr;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4707
                if (exprLhs instanceof ExpressionList) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4708
                    paramListExpr = (((ExpressionList)exprLhs).getExpressions().isEmpty() ? null : ((ExpressionList)exprLhs).getExpressions().get(0));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4709
                } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4710
                    paramListExpr = exprLhs;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4711
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4712
                return arrowFunction(startToken, startLine, paramListExpr);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4713
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4714
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4715
        assert !(exprLhs instanceof ExpressionList);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4716
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4717
        if (isAssignmentOperator(type)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4718
            final boolean isAssign = type == ASSIGN;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4719
            if (isAssign) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4720
                defaultNames.push(exprLhs);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4721
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4722
            try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4723
                final long assignToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4724
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4725
                final Expression exprRhs = assignmentExpression(noIn);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4726
                return verifyAssignment(assignToken, exprLhs, exprRhs);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4727
            } finally {
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.pop();
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
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4732
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4733
            return exprLhs;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4734
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4735
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4736
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4737
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4738
     * Is type one of {@code = *= /= %= += -= <<= >>= >>>= &= ^= |=}?
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4739
     */
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4740
    private static boolean isAssignmentOperator(final TokenType type) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4741
        switch (type) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4742
        case ASSIGN:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4743
        case ASSIGN_ADD:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4744
        case ASSIGN_BIT_AND:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4745
        case ASSIGN_BIT_OR:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4746
        case ASSIGN_BIT_XOR:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4747
        case ASSIGN_DIV:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4748
        case ASSIGN_MOD:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4749
        case ASSIGN_MUL:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4750
        case ASSIGN_SAR:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4751
        case ASSIGN_SHL:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4752
        case ASSIGN_SHR:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4753
        case ASSIGN_SUB:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4754
            return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4755
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4756
        return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4757
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4758
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4759
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4760
     * ConditionalExpression.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4761
     */
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4762
    private Expression conditionalExpression(final boolean noIn) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4763
        return expression(TERNARY.getPrecedence(), noIn);
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
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
     * ArrowFunction.
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
     * @param startToken start token of the ArrowParameters expression
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4770
     * @param functionLine start line of the arrow function
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4771
     * @param paramListExpr ArrowParameters expression or {@code null} for {@code ()} (empty list)
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4772
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4773
    private Expression arrowFunction(final long startToken, final int functionLine, final Expression paramListExpr) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4774
        // 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
  4775
        assert type != ARROW || checkNoLineTerminator();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4776
        expect(ARROW);
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
        final long functionToken = Token.recast(startToken, ARROW);
37835
78bffb8c47c3 8156492: ClassFormatError thrown when arrow function is used
sundar
parents: 37732
diff changeset
  4779
        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
  4780
        final ParserContextFunctionNode functionNode = createParserContextFunctionNode(name, functionToken, FunctionNode.Kind.ARROW, functionLine, null);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4781
        functionNode.setFlag(FunctionNode.IS_ANONYMOUS);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4782
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4783
        lc.push(functionNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4784
        try {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4785
            final ParserContextBlockNode parameterBlock = newBlock();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4786
            final List<IdentNode> parameters;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4787
            try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4788
                parameters = convertArrowFunctionParameterList(paramListExpr, functionLine);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4789
                functionNode.setParameters(parameters);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4790
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4791
                if (!functionNode.isSimpleParameterList()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4792
                    markEvalInArrowParameterList(parameterBlock);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4793
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4794
            } finally {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4795
                restoreBlock(parameterBlock);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4796
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4797
            Block functionBody = functionBody(functionNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4798
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4799
            functionBody = maybeWrapBodyInParameterBlock(functionBody, parameterBlock);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4800
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4801
            verifyParameterList(parameters, functionNode);
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
            final FunctionNode function = createFunctionNode(
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4804
                            functionNode,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4805
                            functionToken,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4806
                            name,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4807
                            parameters,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4808
                            FunctionNode.Kind.ARROW,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4809
                            functionLine,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4810
                            functionBody);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4811
            return function;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4812
        } finally {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4813
            lc.pop(functionNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4814
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4815
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4816
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4817
    private void markEvalInArrowParameterList(final ParserContextBlockNode parameterBlock) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4818
        final Iterator<ParserContextFunctionNode> iter = lc.getFunctions();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4819
        final ParserContextFunctionNode current = iter.next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4820
        final ParserContextFunctionNode parent = iter.next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4821
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4822
        if (parent.getFlag(FunctionNode.HAS_EVAL) != 0) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4823
            // 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
  4824
            // 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
  4825
            for (final Statement st : parameterBlock.getStatements()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4826
                st.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4827
                    @Override
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4828
                    public boolean enterCallNode(final CallNode callNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4829
                        if (callNode.getFunction() instanceof IdentNode && ((IdentNode) callNode.getFunction()).getName().equals("eval")) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4830
                            current.setFlag(FunctionNode.HAS_EVAL);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4831
                        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4832
                        return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4833
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4834
                });
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4835
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4836
            // TODO: function containing the arrow function should not be flagged has-eval
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4837
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4838
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4839
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4840
    private List<IdentNode> convertArrowFunctionParameterList(final Expression paramListExpr, final int functionLine) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4841
        final List<IdentNode> parameters;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4842
        if (paramListExpr == null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4843
            // empty parameter list, i.e. () =>
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4844
            parameters = Collections.emptyList();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4845
        } else if (paramListExpr instanceof IdentNode || paramListExpr.isTokenType(ASSIGN) || isDestructuringLhs(paramListExpr)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4846
            parameters = Collections.singletonList(verifyArrowParameter(paramListExpr, 0, functionLine));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4847
        } else if (paramListExpr instanceof BinaryNode && Token.descType(paramListExpr.getToken()) == COMMARIGHT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4848
            parameters = new ArrayList<>();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4849
            Expression car = paramListExpr;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4850
            do {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4851
                final Expression cdr = ((BinaryNode) car).rhs();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4852
                parameters.add(0, verifyArrowParameter(cdr, parameters.size(), functionLine));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4853
                car = ((BinaryNode) car).lhs();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4854
            } while (car instanceof BinaryNode && Token.descType(car.getToken()) == COMMARIGHT);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4855
            parameters.add(0, verifyArrowParameter(car, parameters.size(), functionLine));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4856
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4857
            throw error(AbstractParser.message("expected.arrow.parameter"), paramListExpr.getToken());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4858
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4859
        return parameters;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4860
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4861
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4862
    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
  4863
        final String contextString = "function parameter";
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4864
        if (param instanceof IdentNode) {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4865
            final IdentNode ident = (IdentNode)param;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4866
            verifyStrictIdent(ident, contextString);
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4867
            final ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4868
            if (currentFunction != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4869
                currentFunction.addParameterBinding(ident);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4870
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4871
            return ident;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4872
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4873
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4874
        if (param.isTokenType(ASSIGN)) {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4875
            final Expression lhs = ((BinaryNode) param).lhs();
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4876
            final long paramToken = lhs.getToken();
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4877
            final Expression initializer = ((BinaryNode) param).rhs();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4878
            if (lhs instanceof IdentNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4879
                // default parameter
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4880
                final IdentNode ident = (IdentNode) lhs;
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4881
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4882
                final ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4883
                if (currentFunction != null) {
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4884
                    if (env._parse_only) {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4885
                        currentFunction.addParameterExpression(ident, param);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4886
                    } else {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4887
                        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
  4888
                        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
  4889
                        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
  4890
                        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
  4891
                    }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4892
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4893
                    currentFunction.addParameterBinding(ident);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4894
                    currentFunction.setSimpleParameterList(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4895
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4896
                return ident;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4897
            } else if (isDestructuringLhs(lhs)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4898
                // binding pattern with initializer
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4899
                // Introduce synthetic temporary parameter to capture the object to be destructured.
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4900
                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
  4901
                verifyDestructuringParameterBindingPattern(param, paramToken, paramLine, contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4902
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4903
                final ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4904
                if (currentFunction != null) {
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4905
                    if (env._parse_only) {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4906
                        currentFunction.addParameterExpression(ident, param);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4907
                    } else {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4908
                        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
  4909
                        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
  4910
                        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
  4911
                        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
  4912
                    }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4913
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4914
                return ident;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4915
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4916
        } else if (isDestructuringLhs(param)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4917
            // binding pattern
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4918
            final long paramToken = param.getToken();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4919
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4920
            // Introduce synthetic temporary parameter to capture the object to be destructured.
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4921
            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
  4922
            verifyDestructuringParameterBindingPattern(param, paramToken, paramLine, contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4923
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4924
            final ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4925
            if (currentFunction != null) {
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4926
                if (env._parse_only) {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4927
                    currentFunction.addParameterExpression(ident, param);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  4928
                } else {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4929
                    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
  4930
                    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
  4931
                }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4932
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4933
            return ident;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4934
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4935
        throw error(AbstractParser.message("invalid.arrow.parameter"), param.getToken());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4936
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4937
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4938
    private boolean checkNoLineTerminator() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4939
        assert type == ARROW;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4940
        if (last == RPAREN) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4941
            return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4942
        } else if (last == IDENT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4943
            return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4944
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4945
        for (int i = k - 1; i >= 0; i--) {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4946
            final TokenType t = T(i);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4947
            switch (t) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4948
            case RPAREN:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4949
            case IDENT:
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
            case EOL:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4952
                return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4953
            case COMMENT:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4954
                continue;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4955
            default:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4956
                if (t.getKind() == TokenKind.FUTURESTRICT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4957
                    return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4958
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4959
                return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4960
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4961
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4962
        return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4963
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4964
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4965
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4966
     * 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
  4967
     * at the end of an arrow function parameter list.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4968
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4969
    private boolean isRestParameterEndOfArrowFunctionParameterList() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4970
        assert type == ELLIPSIS;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4971
        // 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
  4972
        int i = 1;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4973
        for (;;) {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4974
            final TokenType t = T(k + i++);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4975
            if (t == IDENT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4976
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4977
            } else if (t == EOL || t == COMMENT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4978
                continue;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4979
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4980
                return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4981
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4982
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4983
        for (;;) {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4984
            final TokenType t = T(k + i++);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4985
            if (t == RPAREN) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4986
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4987
            } else if (t == EOL || t == COMMENT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4988
                continue;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4989
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4990
                return false;
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
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4993
        for (;;) {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  4994
            final TokenType t = T(k + i++);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4995
            if (t == ARROW) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4996
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4997
            } else if (t == COMMENT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4998
                continue;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4999
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5000
                return false;
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
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5003
        return true;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5004
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5005
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5006
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5007
     * Parse an end of line.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5008
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5009
    private void endOfLine() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5010
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5011
        case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5012
        case EOL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5013
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5014
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5015
        case RPAREN:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5016
        case RBRACKET:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5017
        case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5018
        case EOF:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5019
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5020
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5021
            if (last != EOL) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5022
                expect(SEMICOLON);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5023
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5024
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5025
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5026
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5027
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5028
    /**
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5029
     * Parse untagged template literal as string concatenation.
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5030
     */
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5031
    private Expression templateLiteral() {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5032
        assert type == TEMPLATE || type == TEMPLATE_HEAD;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5033
        final boolean noSubstitutionTemplate = type == TEMPLATE;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5034
        long lastLiteralToken = token;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5035
        LiteralNode<?> literal = getLiteral();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5036
        if (noSubstitutionTemplate) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5037
            return literal;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5038
        }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5039
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5040
        if (env._parse_only) {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  5041
            final List<Expression> exprs = new ArrayList<>();
39662
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5042
            exprs.add(literal);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5043
            TokenType lastLiteralType;
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5044
            do {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5045
                final Expression expression = expression();
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5046
                if (type != TEMPLATE_MIDDLE && type != TEMPLATE_TAIL) {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5047
                    throw error(AbstractParser.message("unterminated.template.expression"), token);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5048
                }
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5049
                exprs.add(expression);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5050
                lastLiteralType = type;
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5051
                literal = getLiteral();
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5052
                exprs.add(literal);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5053
            } while (lastLiteralType == TEMPLATE_MIDDLE);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5054
            return new TemplateLiteral(exprs);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5055
        } else {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5056
            Expression concat = literal;
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5057
            TokenType lastLiteralType;
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5058
            do {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5059
                final Expression expression = expression();
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5060
                if (type != TEMPLATE_MIDDLE && type != TEMPLATE_TAIL) {
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5061
                    throw error(AbstractParser.message("unterminated.template.expression"), token);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5062
                }
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5063
                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
  5064
                lastLiteralType = type;
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5065
                lastLiteralToken = token;
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5066
                literal = getLiteral();
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5067
                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
  5068
            } while (lastLiteralType == TEMPLATE_MIDDLE);
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5069
            return concat;
e2b36a3779b9 8149929: Nashorn Parser API needs to be updated for ES6
sundar
parents: 39077
diff changeset
  5070
        }
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5071
    }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5072
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5073
    /**
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5074
     * Parse tagged template literal as argument list.
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5075
     * @return argument list for a tag function call (template object, ...substitutions)
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5076
     */
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5077
    private List<Expression> templateLiteralArgumentList() {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5078
        assert type == TEMPLATE || type == TEMPLATE_HEAD;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5079
        final ArrayList<Expression> argumentList = new ArrayList<>();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5080
        final ArrayList<Expression> rawStrings = new ArrayList<>();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5081
        final ArrayList<Expression> cookedStrings = new ArrayList<>();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5082
        argumentList.add(null); // filled at the end
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5083
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5084
        final long templateToken = token;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5085
        final boolean hasSubstitutions = type == TEMPLATE_HEAD;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5086
        addTemplateLiteralString(rawStrings, cookedStrings);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5087
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5088
        if (hasSubstitutions) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5089
            TokenType lastLiteralType;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5090
            do {
34447
ec4c069f9436 8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents: 33888
diff changeset
  5091
                final Expression expression = expression();
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5092
                if (type != TEMPLATE_MIDDLE && type != TEMPLATE_TAIL) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5093
                    throw error(AbstractParser.message("unterminated.template.expression"), token);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5094
                }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5095
                argumentList.add(expression);
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
                lastLiteralType = type;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5098
                addTemplateLiteralString(rawStrings, cookedStrings);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5099
            } while (lastLiteralType == TEMPLATE_MIDDLE);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5100
        }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5101
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5102
        final LiteralNode<Expression[]> rawStringArray = LiteralNode.newInstance(templateToken, finish, rawStrings);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5103
        final LiteralNode<Expression[]> cookedStringArray = LiteralNode.newInstance(templateToken, finish, cookedStrings);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5104
        final RuntimeNode templateObject = new RuntimeNode(templateToken, finish, RuntimeNode.Request.GET_TEMPLATE_OBJECT, rawStringArray, cookedStringArray);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5105
        argumentList.set(0, templateObject);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5106
        return optimizeList(argumentList);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5107
    }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5108
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5109
    private void addTemplateLiteralString(final ArrayList<Expression> rawStrings, final ArrayList<Expression> cookedStrings) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5110
        final long stringToken = token;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5111
        final String rawString = lexer.valueOfRawString(stringToken);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5112
        final String cookedString = (String) getValue();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5113
        next();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5114
        rawStrings.add(LiteralNode.newInstance(stringToken, finish, rawString));
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5115
        cookedStrings.add(LiteralNode.newInstance(stringToken, finish, cookedString));
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5116
    }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5117
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5118
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5119
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5120
     * Parse a module.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5121
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5122
     * Module :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5123
     *      ModuleBody?
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5124
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5125
     * ModuleBody :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5126
     *      ModuleItemList
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5127
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5128
    private FunctionNode module(final String moduleName) {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  5129
        final boolean oldStrictMode = isStrictMode;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5130
        try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5131
            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
  5132
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5133
            // Make a pseudo-token for the script holding its start and length.
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  5134
            final int functionStart = Math.min(Token.descPosition(Token.withDelimiter(token)), finish);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5135
            final long functionToken = Token.toDesc(FUNCTION, functionStart, source.getLength() - functionStart);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5136
            final int  functionLine  = line;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5137
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5138
            final IdentNode ident = new IdentNode(functionToken, Token.descPosition(functionToken), moduleName);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5139
            final ParserContextFunctionNode script = createParserContextFunctionNode(
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5140
                            ident,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5141
                            functionToken,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5142
                            FunctionNode.Kind.MODULE,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5143
                            functionLine,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5144
                            Collections.<IdentNode>emptyList());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5145
            lc.push(script);
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
            final ParserContextModuleNode module = new ParserContextModuleNode(moduleName);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5148
            lc.push(module);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5149
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5150
            final ParserContextBlockNode body = newBlock();
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
            functionDeclarations = new ArrayList<>();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5153
            moduleBody();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5154
            addFunctionDeclarations(script);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5155
            functionDeclarations = null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5156
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5157
            restoreBlock(body);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5158
            body.setFlag(Block.NEEDS_SCOPE);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5159
            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
  5160
            lc.pop(module);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5161
            lc.pop(script);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5162
            script.setLastToken(token);
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
            expect(EOF);
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
            script.setModule(module.createModule());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5167
            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
  5168
        } finally {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5169
            isStrictMode = oldStrictMode;
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
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5172
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5173
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5174
     * Parse module body.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5175
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5176
     * ModuleBody :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5177
     *      ModuleItemList
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5178
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5179
     * ModuleItemList :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5180
     *      ModuleItem
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5181
     *      ModuleItemList ModuleItem
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5182
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5183
     * ModuleItem :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5184
     *      ImportDeclaration
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5185
     *      ExportDeclaration
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5186
     *      StatementListItem
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
    private void moduleBody() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5189
        loop:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5190
        while (type != EOF) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5191
            switch (type) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5192
            case EOF:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5193
                break loop;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5194
            case IMPORT:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5195
                importDeclaration();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5196
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5197
            case EXPORT:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5198
                exportDeclaration();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5199
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5200
            default:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5201
                // StatementListItem
39077
c549268fe94c 8156614: Lazy parsing of ES6 shorthand method syntax is broken
hannesw
parents: 38901
diff changeset
  5202
                statement(true, 0, false, false);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5203
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5204
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5205
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5206
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5207
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5208
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5209
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5210
     * Parse import declaration.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5211
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5212
     * ImportDeclaration :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5213
     *     import ImportClause FromClause ;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5214
     *     import ModuleSpecifier ;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5215
     * ImportClause :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5216
     *     ImportedDefaultBinding
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5217
     *     NameSpaceImport
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5218
     *     NamedImports
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5219
     *     ImportedDefaultBinding , NameSpaceImport
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5220
     *     ImportedDefaultBinding , NamedImports
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5221
     * ImportedDefaultBinding :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5222
     *     ImportedBinding
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5223
     * ModuleSpecifier :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5224
     *     StringLiteral
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5225
     * ImportedBinding :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5226
     *     BindingIdentifier
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5227
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5228
    private void importDeclaration() {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5229
        final int startPosition = start;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5230
        expect(IMPORT);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5231
        final ParserContextModuleNode module = lc.getCurrentModule();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5232
        if (type == STRING || type == ESCSTRING) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5233
            // import ModuleSpecifier ;
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5234
            final IdentNode moduleSpecifier = createIdentNode(token, finish, (String) getValue());
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5235
            next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5236
            module.addModuleRequest(moduleSpecifier);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5237
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5238
            // import ImportClause FromClause ;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5239
            List<Module.ImportEntry> importEntries;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5240
            if (type == MUL) {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5241
                importEntries = Collections.singletonList(nameSpaceImport(startPosition));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5242
            } else if (type == LBRACE) {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5243
                importEntries = namedImports(startPosition);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5244
            } else if (isBindingIdentifier()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5245
                // ImportedDefaultBinding
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5246
                final IdentNode importedDefaultBinding = bindingIdentifier("ImportedBinding");
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  5247
                final Module.ImportEntry defaultImport = Module.ImportEntry.importSpecifier(importedDefaultBinding, startPosition, finish);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5248
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5249
                if (type == COMMARIGHT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5250
                    next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5251
                    importEntries = new ArrayList<>();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5252
                    if (type == MUL) {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5253
                        importEntries.add(nameSpaceImport(startPosition));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5254
                    } else if (type == LBRACE) {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5255
                        importEntries.addAll(namedImports(startPosition));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5256
                    } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5257
                        throw error(AbstractParser.message("expected.named.import"));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5258
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5259
                } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5260
                    importEntries = Collections.singletonList(defaultImport);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5261
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5262
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5263
                throw error(AbstractParser.message("expected.import"));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5264
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5265
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5266
            final IdentNode moduleSpecifier = fromClause();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5267
            module.addModuleRequest(moduleSpecifier);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5268
            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
  5269
                module.addImportEntry(importEntries.get(i).withFrom(moduleSpecifier, finish));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5270
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5271
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5272
        expect(SEMICOLON);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5273
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5274
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
     * NameSpaceImport :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5277
     *     * as ImportedBinding
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5278
     *
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5279
     * @param startPosition the start of the import declaration
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5280
     * @return imported binding identifier
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5281
     */
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5282
    private Module.ImportEntry nameSpaceImport(final int startPosition) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5283
        assert type == MUL;
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5284
        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
  5285
        next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5286
        final long asToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5287
        final String as = (String) expectValue(IDENT);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5288
        if (!"as".equals(as)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5289
            throw error(AbstractParser.message("expected.as"), asToken);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5290
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5291
        final IdentNode localNameSpace = bindingIdentifier("ImportedBinding");
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5292
        return Module.ImportEntry.importSpecifier(starName, localNameSpace, startPosition, finish);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5293
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5294
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5295
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5296
     * NamedImports :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5297
     *     { }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5298
     *     { ImportsList }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5299
     *     { ImportsList , }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5300
     * ImportsList :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5301
     *     ImportSpecifier
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5302
     *     ImportsList , ImportSpecifier
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5303
     * ImportSpecifier :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5304
     *     ImportedBinding
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5305
     *     IdentifierName as ImportedBinding
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5306
     * ImportedBinding :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5307
     *     BindingIdentifier
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5308
     */
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5309
    private List<Module.ImportEntry> namedImports(final int startPosition) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5310
        assert type == LBRACE;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5311
        next();
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  5312
        final List<Module.ImportEntry> importEntries = new ArrayList<>();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5313
        while (type != RBRACE) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5314
            final boolean bindingIdentifier = isBindingIdentifier();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5315
            final long nameToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5316
            final IdentNode importName = getIdentifierName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5317
            if (type == IDENT && "as".equals(getValue())) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5318
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5319
                final IdentNode localName = bindingIdentifier("ImportedBinding");
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5320
                importEntries.add(Module.ImportEntry.importSpecifier(importName, localName, startPosition, finish));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5321
            } else if (!bindingIdentifier) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5322
                throw error(AbstractParser.message("expected.binding.identifier"), nameToken);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5323
            } else {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5324
                importEntries.add(Module.ImportEntry.importSpecifier(importName, startPosition, finish));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5325
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5326
            if (type == COMMARIGHT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5327
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5328
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5329
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5330
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5331
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5332
        expect(RBRACE);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5333
        return importEntries;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5334
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5335
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5336
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5337
     * FromClause :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5338
     *     from ModuleSpecifier
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5339
     */
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5340
    private IdentNode fromClause() {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5341
        final long fromToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5342
        final String name = (String) expectValue(IDENT);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5343
        if (!"from".equals(name)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5344
            throw error(AbstractParser.message("expected.from"), fromToken);
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
        if (type == STRING || type == ESCSTRING) {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5347
            final IdentNode moduleSpecifier = createIdentNode(Token.recast(token, IDENT), finish, (String) getValue());
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5348
            next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5349
            return moduleSpecifier;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5350
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5351
            throw error(expectMessage(STRING));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5352
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5353
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5354
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5355
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5356
     * Parse export declaration.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5357
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5358
     * ExportDeclaration :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5359
     *     export * FromClause ;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5360
     *     export ExportClause FromClause ;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5361
     *     export ExportClause ;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5362
     *     export VariableStatement
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5363
     *     export Declaration
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5364
     *     export default HoistableDeclaration[Default]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5365
     *     export default ClassDeclaration[Default]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5366
     *     export default [lookahead !in {function, class}] AssignmentExpression[In] ;
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
    private void exportDeclaration() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5369
        expect(EXPORT);
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5370
        final int startPosition = start;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5371
        final ParserContextModuleNode module = lc.getCurrentModule();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5372
        switch (type) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5373
            case MUL: {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5374
                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
  5375
                next();
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5376
                final IdentNode moduleRequest = fromClause();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5377
                expect(SEMICOLON);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5378
                module.addModuleRequest(moduleRequest);
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5379
                module.addStarExportEntry(Module.ExportEntry.exportStarFrom(starName, moduleRequest, startPosition, finish));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5380
                break;
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
            case LBRACE: {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5383
                final List<Module.ExportEntry> exportEntries = exportClause(startPosition);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5384
                if (type == IDENT && "from".equals(getValue())) {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5385
                    final IdentNode moduleRequest = fromClause();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5386
                    module.addModuleRequest(moduleRequest);
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  5387
                    for (final Module.ExportEntry exportEntry : exportEntries) {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5388
                        module.addIndirectExportEntry(exportEntry.withFrom(moduleRequest, finish));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5389
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5390
                } else {
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  5391
                    for (final Module.ExportEntry exportEntry : exportEntries) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5392
                        module.addLocalExportEntry(exportEntry);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5393
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5394
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5395
                expect(SEMICOLON);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5396
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5397
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5398
            case DEFAULT:
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5399
                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
  5400
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5401
                final Expression assignmentExpression;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5402
                IdentNode ident;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5403
                final int lineNumber = line;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5404
                final long rhsToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5405
                final boolean declaration;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5406
                switch (type) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5407
                    case FUNCTION:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5408
                        assignmentExpression = functionExpression(false, true);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5409
                        ident = ((FunctionNode) assignmentExpression).getIdent();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5410
                        declaration = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5411
                        break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5412
                    case CLASS:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5413
                        assignmentExpression = classDeclaration(true);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5414
                        ident = ((ClassNode) assignmentExpression).getIdent();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5415
                        declaration = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5416
                        break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5417
                    default:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5418
                        assignmentExpression = assignmentExpression(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5419
                        ident = null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5420
                        declaration = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5421
                        break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5422
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5423
                if (ident != null) {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5424
                    module.addLocalExportEntry(Module.ExportEntry.exportDefault(defaultName, ident, startPosition, finish));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5425
                } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5426
                    ident = createIdentNode(Token.recast(rhsToken, IDENT), finish, Module.DEFAULT_EXPORT_BINDING_NAME);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5427
                    lc.appendStatementToCurrentNode(new VarNode(lineNumber, Token.recast(rhsToken, LET), finish, ident, assignmentExpression));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5428
                    if (!declaration) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5429
                        expect(SEMICOLON);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5430
                    }
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5431
                    module.addLocalExportEntry(Module.ExportEntry.exportDefault(defaultName, ident, startPosition, finish));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5432
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5433
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5434
            case VAR:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5435
            case LET:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5436
            case CONST:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5437
                final List<Statement> statements = lc.getCurrentBlock().getStatements();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5438
                final int previousEnd = statements.size();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5439
                variableStatement(type);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5440
                for (final Statement statement : statements.subList(previousEnd, statements.size())) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5441
                    if (statement instanceof VarNode) {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5442
                        module.addLocalExportEntry(Module.ExportEntry.exportSpecifier(((VarNode) statement).getName(), startPosition, finish));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5443
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5444
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5445
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5446
            case CLASS: {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5447
                final ClassNode classDeclaration = classDeclaration(false);
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5448
                module.addLocalExportEntry(Module.ExportEntry.exportSpecifier(classDeclaration.getIdent(), startPosition, finish));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5449
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5450
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5451
            case FUNCTION: {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5452
                final FunctionNode functionDeclaration = (FunctionNode) functionExpression(true, true);
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5453
                module.addLocalExportEntry(Module.ExportEntry.exportSpecifier(functionDeclaration.getIdent(), startPosition, finish));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5454
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5455
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5456
            default:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5457
                throw error(AbstractParser.message("invalid.export"), token);
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
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5460
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5461
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5462
     * ExportClause :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5463
     *     { }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5464
     *     { ExportsList }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5465
     *     { ExportsList , }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5466
     * ExportsList :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5467
     *     ExportSpecifier
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5468
     *     ExportsList , ExportSpecifier
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5469
     * ExportSpecifier :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5470
     *     IdentifierName
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5471
     *     IdentifierName as IdentifierName
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
     * @return a list of ExportSpecifiers
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5474
     */
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5475
    private List<Module.ExportEntry> exportClause(final int startPosition) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5476
        assert type == LBRACE;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5477
        next();
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 41145
diff changeset
  5478
        final List<Module.ExportEntry> exports = new ArrayList<>();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5479
        while (type != RBRACE) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5480
            final IdentNode localName = getIdentifierName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5481
            if (type == IDENT && "as".equals(getValue())) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5482
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5483
                final IdentNode exportName = getIdentifierName();
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5484
                exports.add(Module.ExportEntry.exportSpecifier(exportName, localName, startPosition, finish));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5485
            } else {
38901
28e775c6e08e 8159220: Preserve position info in module import and export entries
hannesw
parents: 38807
diff changeset
  5486
                exports.add(Module.ExportEntry.exportSpecifier(localName, startPosition, finish));
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5487
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5488
            if (type == COMMARIGHT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5489
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5490
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5491
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5492
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5493
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5494
        expect(RBRACE);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5495
        return exports;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5496
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5497
16252
3bfe9b68a0fa 8008648: Lazy JIT scope and callee semantics bugfixes. Broke out wallclock timer.
lagergren
parents: 16245
diff changeset
  5498
    @Override
3bfe9b68a0fa 8008648: Lazy JIT scope and callee semantics bugfixes. Broke out wallclock timer.
lagergren
parents: 16245
diff changeset
  5499
    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
  5500
        return "'JavaScript Parsing'";
16252
3bfe9b68a0fa 8008648: Lazy JIT scope and callee semantics bugfixes. Broke out wallclock timer.
lagergren
parents: 16245
diff changeset
  5501
    }
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  5502
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  5503
    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
  5504
        final Iterator<ParserContextFunctionNode> iter = lc.getFunctions();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  5505
        boolean flaggedCurrentFn = false;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  5506
        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
  5507
            final ParserContextFunctionNode fn = iter.next();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  5508
            if (!flaggedCurrentFn) {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  5509
                fn.setFlag(FunctionNode.HAS_EVAL);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  5510
                flaggedCurrentFn = true;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5511
                if (fn.getKind() == FunctionNode.Kind.ARROW) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5512
                    // 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
  5513
                    // function fun(){ return (() => eval("this"))(); };
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5514
                    markThis(lc);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5515
                    markNewTarget(lc);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5516
                }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  5517
            } else {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  5518
                fn.setFlag(FunctionNode.HAS_NESTED_EVAL);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  5519
            }
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  5520
            final ParserContextBlockNode body = lc.getFunctionBody(fn);
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  5521
            // 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
  5522
            // 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
  5523
            // 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
  5524
            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
  5525
            fn.setFlag(FunctionNode.HAS_SCOPE_BLOCK);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  5526
        }
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  5527
    }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  5528
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
  5529
    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
  5530
        lc.prependStatementToCurrentNode(statement);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  5531
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  5532
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
  5533
    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
  5534
        lc.appendStatementToCurrentNode(statement);
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  5535
    }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5536
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5537
    private static void markSuperCall(final ParserContext lc) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5538
        final Iterator<ParserContextFunctionNode> iter = lc.getFunctions();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5539
        while (iter.hasNext()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5540
            final ParserContextFunctionNode fn = iter.next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5541
            if (fn.getKind() != FunctionNode.Kind.ARROW) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5542
                assert fn.isSubclassConstructor();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5543
                fn.setFlag(FunctionNode.ES6_HAS_DIRECT_SUPER);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5544
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5545
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5546
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5547
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5548
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5549
    private ParserContextFunctionNode getCurrentNonArrowFunction() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5550
        final Iterator<ParserContextFunctionNode> iter = lc.getFunctions();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5551
        while (iter.hasNext()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5552
            final ParserContextFunctionNode fn = iter.next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5553
            if (fn.getKind() != FunctionNode.Kind.ARROW) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5554
                return fn;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5555
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5556
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5557
        return null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5558
    }
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
    private static void markThis(final ParserContext lc) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5561
        final Iterator<ParserContextFunctionNode> iter = lc.getFunctions();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5562
        while (iter.hasNext()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5563
            final ParserContextFunctionNode fn = iter.next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5564
            fn.setFlag(FunctionNode.USES_THIS);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5565
            if (fn.getKind() != FunctionNode.Kind.ARROW) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5566
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5567
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5568
        }
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
    private static void markNewTarget(final ParserContext lc) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5572
        final Iterator<ParserContextFunctionNode> iter = lc.getFunctions();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5573
        while (iter.hasNext()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5574
            final ParserContextFunctionNode fn = iter.next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5575
            if (fn.getKind() != FunctionNode.Kind.ARROW) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5576
                if (!fn.isProgram()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5577
                    fn.setFlag(FunctionNode.ES6_USES_NEW_TARGET);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5578
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5579
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5580
            }
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
    private boolean inGeneratorFunction() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5585
        return lc.getCurrentFunction().getKind() == FunctionNode.Kind.GENERATOR;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5586
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5587
}