nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java
author hannesw
Wed, 27 Apr 2016 15:50:33 +0200
changeset 37732 3673fec68d16
parent 36696 39ff39c8e396
child 37835 78bffb8c47c3
permissions -rw-r--r--
8134503: support ES6 parsing in Nashorn Reviewed-by: jlaskey, sundar, mhaupt Contributed-by: andreas.woess@oracle.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     1
/*
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
     2
 * Copyright (c) 2010, 2015, 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;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   130
import jdk.nashorn.internal.ir.TernaryNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   131
import jdk.nashorn.internal.ir.ThrowNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   132
import jdk.nashorn.internal.ir.TryNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   133
import jdk.nashorn.internal.ir.UnaryNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   134
import jdk.nashorn.internal.ir.VarNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   135
import jdk.nashorn.internal.ir.WhileNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   136
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
   137
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
   138
import jdk.nashorn.internal.ir.debug.PrintVisitor;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   139
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   140
import jdk.nashorn.internal.runtime.Context;
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   141
import jdk.nashorn.internal.runtime.ErrorManager;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   142
import jdk.nashorn.internal.runtime.JSErrorType;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   143
import jdk.nashorn.internal.runtime.ParserException;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   144
import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
   145
import jdk.nashorn.internal.runtime.ScriptEnvironment;
16245
6a1c6c8bc113 8008371: Fix Dynalink compiler warnings and whitespace
attila
parents: 16239
diff changeset
   146
import jdk.nashorn.internal.runtime.ScriptingFunctions;
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   147
import jdk.nashorn.internal.runtime.Source;
26246
66c7c54fe70c 8055923: collect timings using System.nanoTime
attila
parents: 26243
diff changeset
   148
import jdk.nashorn.internal.runtime.Timing;
33533
43400f0f2b47 8141144: Move NameCodec to jdk.nashorn.internal space
attila
parents: 33414
diff changeset
   149
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
   150
import jdk.nashorn.internal.runtime.logging.DebugLogger;
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   151
import jdk.nashorn.internal.runtime.logging.Loggable;
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   152
import jdk.nashorn.internal.runtime.logging.Logger;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   153
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   154
/**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   155
 * Builds the IR.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   156
 */
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   157
@Logger(name="parser")
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   158
public class Parser extends AbstractParser implements Loggable {
19898
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   159
    private static final String ARGUMENTS_NAME = CompilerConstants.ARGUMENTS_VAR.symbolName();
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   160
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   161
    /** Current env. */
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
   162
    private final ScriptEnvironment env;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   163
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
   164
    /** Is scripting mode. */
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
   165
    private final boolean scripting;
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
   166
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
   167
    private List<Statement> functionDeclarations;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   168
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   169
    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
   170
    private final Deque<Object> defaultNames;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   171
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   172
    /** Namespace for function names where not explicitly given */
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   173
    private final Namespace namespace;
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   174
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   175
    private final DebugLogger log;
16252
3bfe9b68a0fa 8008648: Lazy JIT scope and callee semantics bugfixes. Broke out wallclock timer.
lagergren
parents: 16245
diff changeset
   176
18870
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   177
    /** 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
   178
    protected final Lexer.LineInfoReceiver lineInfoReceiver;
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   179
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
   180
    private RecompilableScriptFunctionData reparsedFunction;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   181
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   182
    /**
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   183
     * Constructor
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   184
     *
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
   185
     * @param env     script environment
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   186
     * @param source  source to parse
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   187
     * @param errors  error manager
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   188
     */
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
   189
    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
   190
        this(env, source, errors, env._strict, null);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   191
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   192
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   193
    /**
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   194
     * Constructor
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   195
     *
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   196
     * @param env     script environment
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   197
     * @param source  source to parse
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   198
     * @param errors  error manager
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   199
     * @param strict  strict
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   200
     * @param log debug logger if one is needed
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   201
     */
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   202
    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
   203
        this(env, source, errors, strict, 0, log);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   204
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   205
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   206
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   207
     * Construct a parser.
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   208
     *
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
   209
     * @param env     script environment
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   210
     * @param source  source to parse
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   211
     * @param errors  error manager
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   212
     * @param strict  parser created with strict mode enabled.
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   213
     * @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
   214
     * @param log debug logger if one is needed
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   215
     */
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
   216
    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
   217
        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
   218
        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
   219
        this.defaultNames = new ArrayDeque<>();
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   220
        this.env = env;
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
   221
        this.namespace = new Namespace(env.getNamespace());
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
   222
        this.scripting = env._scripting;
18870
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   223
        if (this.scripting) {
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   224
            this.lineInfoReceiver = new Lexer.LineInfoReceiver() {
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   225
                @Override
19472
9476460521b3 8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents: 18877
diff changeset
   226
                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
   227
                    // update the parser maintained line information
19472
9476460521b3 8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents: 18877
diff changeset
   228
                    Parser.this.line = receiverLine;
9476460521b3 8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents: 18877
diff changeset
   229
                    Parser.this.linePosition = receiverLinePosition;
18870
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   230
                }
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   231
            };
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   232
        } else {
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   233
            // 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
   234
            this.lineInfoReceiver = null;
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   235
        }
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   236
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   237
        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
   238
    }
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   239
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   240
    @Override
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   241
    public DebugLogger getLogger() {
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   242
        return log;
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
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   246
    public DebugLogger initLogger(final Context context) {
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   247
        return context.getLogger(this.getClass());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   248
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   249
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   250
    /**
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   251
     * 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
   252
     * preserve their already assigned name, as that name doesn't appear in their source text.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   253
     * @param name the name for the first parsed function.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   254
     */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   255
    public void setFunctionName(final String name) {
26243
438aba09d465 8055911: Don't use String.intern for IdentNode
attila
parents: 26068
diff changeset
   256
        defaultNames.push(createIdentNode(0, 0, name));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   257
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   258
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   259
    /**
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
   260
     * Sets the {@link RecompilableScriptFunctionData} representing the function being reparsed (when this
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
   261
     * 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
   262
     * This will trigger various special behaviors, such as skipping nested function bodies.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
   263
     * @param reparsedFunction the function being reparsed.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
   264
     */
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
   265
    public void setReparsedFunction(final RecompilableScriptFunctionData reparsedFunction) {
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
   266
        this.reparsedFunction = reparsedFunction;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
   267
    }
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
   268
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
   269
    /**
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   270
     * Execute parse and return the resulting function node.
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   271
     * Errors will be thrown and the error manager will contain information
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   272
     * if parsing should fail
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   273
     *
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   274
     * This is the default parse call, which will name the function node
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   275
     * {code :program} {@link CompilerConstants#PROGRAM}
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   276
     *
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   277
     * @return function node resulting from successful parse
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
    public FunctionNode parse() {
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   280
        return parse(PROGRAM.symbolName(), 0, source.getLength(), false);
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
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   283
    /**
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   284
     * Set up first token. Skips opening EOL.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   285
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   286
    private void scanFirstToken() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   287
        k = -1;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   288
        next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   289
    }
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
    /**
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   292
     * Execute parse and return the resulting function node.
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   293
     * Errors will be thrown and the error manager will contain information
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   294
     * if parsing should fail
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   295
     *
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   296
     * This should be used to create one and only one function node
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   297
     *
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   298
     * @param scriptName name for the script, given to the parsed FunctionNode
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   299
     * @param startPos start position in source
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   300
     * @param len length of parse
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   301
     * @param allowPropertyFunction if true, "get" and "set" are allowed as first tokens of the program, followed by
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   302
     * a property getter or setter function. This is used when reparsing a function that can potentially be defined as a
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   303
     * property getter or setter in an object literal.
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   304
     *
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   305
     * @return function node resulting from successful parse
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   306
     */
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   307
    public FunctionNode parse(final String scriptName, final int startPos, final int len, final boolean allowPropertyFunction) {
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
   308
        final boolean isTimingEnabled = env.isTimingEnabled();
26246
66c7c54fe70c 8055923: collect timings using System.nanoTime
attila
parents: 26243
diff changeset
   309
        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
   310
        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
   311
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   312
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   313
            stream = new TokenStream();
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
   314
            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
   315
            lexer.line = lexer.pendingLine = lineOffset + 1;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   316
            line = lineOffset;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   317
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   318
            scanFirstToken();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   319
            // Begin parse.
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   320
            return program(scriptName, allowPropertyFunction);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   321
        } catch (final Exception e) {
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   322
            handleParseException(e);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   323
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   324
            return null;
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   325
        } finally {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   326
            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
   327
            if (isTimingEnabled) {
26246
66c7c54fe70c 8055923: collect timings using System.nanoTime
attila
parents: 26243
diff changeset
   328
                env._timing.accumulateTime(toString(), System.nanoTime() - t0);
66c7c54fe70c 8055923: collect timings using System.nanoTime
attila
parents: 26243
diff changeset
   329
                log.info(end, "' in ", Timing.toMillisPrint(System.nanoTime() - t0), " ms");
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   330
            } else {
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   331
                log.info(end);
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   332
            }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   333
        }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   334
    }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   335
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   336
    /**
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   337
     * Parse and return the resulting module.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   338
     * Errors will be thrown and the error manager will contain information
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   339
     * if parsing should fail
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   340
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   341
     * @param moduleName name for the module, given to the parsed FunctionNode
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   342
     * @param startPos start position in source
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   343
     * @param len length of parse
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   344
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   345
     * @return function node resulting from successful parse
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   346
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   347
    public FunctionNode parseModule(final String moduleName, final int startPos, final int len) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   348
        try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   349
            stream = new TokenStream();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   350
            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
   351
            lexer.line = lexer.pendingLine = lineOffset + 1;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   352
            line = lineOffset;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   353
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   354
            scanFirstToken();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   355
            // Begin parse.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   356
            return module(moduleName);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   357
        } catch (final Exception e) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   358
            handleParseException(e);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   359
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   360
            return null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   361
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   362
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   363
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
     * Entry point for parsing a module.
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
     * @param moduleName the module name
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   368
     * @return the parsed module
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
    public FunctionNode parseModule(final String moduleName) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   371
        return parseModule(moduleName, 0, source.getLength());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   372
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   373
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   374
    /**
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   375
     * Parse and return the list of function parameter list. A comma
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   376
     * separated list of function parameter identifiers is expected to be parsed.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   377
     * Errors will be thrown and the error manager will contain information
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   378
     * 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
   379
     * passed to "Function" constructor is a valid or not.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   380
     *
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   381
     * @return the list of IdentNodes representing the formal parameter list
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   382
     */
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   383
    public List<IdentNode> parseFormalParameterList() {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   384
        try {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   385
            stream = new TokenStream();
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
   386
            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
   387
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   388
            scanFirstToken();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   389
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   390
            return formalParameterList(TokenType.EOF, false);
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   391
        } catch (final Exception e) {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   392
            handleParseException(e);
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   393
            return null;
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   394
        }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   395
    }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   396
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   397
    /**
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   398
     * Execute parse and return the resulting function node.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   399
     * Errors will be thrown and the error manager will contain information
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   400
     * 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
   401
     * passed to "Function" constructor is a valid function body or not.
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
     * @return function node resulting from successful parse
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   404
     */
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   405
    public FunctionNode parseFunctionBody() {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   406
        try {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   407
            stream = new TokenStream();
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
   408
            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
   409
            final int functionLine = line;
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   410
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   411
            scanFirstToken();
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   412
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   413
            // Make a fake token for the function.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   414
            final long functionToken = Token.toDesc(FUNCTION, 0, source.getLength());
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   415
            // Set up the function to append elements.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   416
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   417
            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
   418
            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
   419
            lc.push(function);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   420
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   421
            final ParserContextBlockNode body = newBlock();
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   422
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   423
            functionDeclarations = new ArrayList<>();
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   424
            sourceElements(false);
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   425
            addFunctionDeclarations(function);
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   426
            functionDeclarations = null;
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   427
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   428
            restoreBlock(body);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   429
            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
   430
29407
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
   431
            final Block functionBody = new Block(functionToken, source.getLength() - 1,
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
   432
                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
   433
            lc.pop(function);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   434
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   435
            expect(EOF);
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   436
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   437
            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
   438
                    function,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   439
                    functionToken,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   440
                    ident,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   441
                    Collections.<IdentNode>emptyList(),
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   442
                    FunctionNode.Kind.NORMAL,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   443
                    functionLine,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   444
                    functionBody);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   445
            printAST(functionNode);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   446
            return functionNode;
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   447
        } catch (final Exception e) {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   448
            handleParseException(e);
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   449
            return null;
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   450
        }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   451
    }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   452
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   453
    private void handleParseException(final Exception e) {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   454
        // Extract message from exception.  The message will be in error
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   455
        // message format.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   456
        String message = e.getMessage();
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
        // If empty message.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   459
        if (message == null) {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   460
            message = e.toString();
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   461
        }
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
        // Issue message.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   464
        if (e instanceof ParserException) {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   465
            errors.error((ParserException)e);
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   466
        } else {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   467
            errors.error(message);
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   468
        }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   469
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   470
        if (env._dump_on_error) {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   471
            e.printStackTrace(env.getErr());
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   472
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   473
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   474
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   475
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   476
     * Skip to a good parsing recovery point.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   477
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   478
    private void recover(final Exception e) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   479
        if (e != null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   480
            // Extract message from exception.  The message will be in error
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   481
            // message format.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   482
            String message = e.getMessage();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   483
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   484
            // If empty message.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   485
            if (message == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   486
                message = e.toString();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   487
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   488
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   489
            // Issue message.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   490
            if (e instanceof ParserException) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   491
                errors.error((ParserException)e);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   492
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   493
                errors.error(message);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   494
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   495
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
   496
            if (env._dump_on_error) {
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
   497
                e.printStackTrace(env.getErr());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   498
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   499
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   500
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   501
        // Skip to a recovery point.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   502
        loop:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   503
        while (true) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   504
            switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   505
            case EOF:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   506
                // Can not go any further.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   507
                break loop;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   508
            case EOL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   509
            case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   510
            case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   511
                // Good recovery points.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   512
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   513
                break loop;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   514
            default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   515
                // So we can recover after EOL.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   516
                nextOrEOL();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   517
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   518
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   519
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   520
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   521
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   522
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   523
     * Set up a new block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   524
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   525
     * @return New block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   526
     */
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   527
    private ParserContextBlockNode newBlock() {
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   528
        return lc.push(new ParserContextBlockNode(token));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   529
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   530
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   531
    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
   532
        // Build function name.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   533
        final StringBuilder sb = new StringBuilder();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   534
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   535
        final ParserContextFunctionNode parentFunction = lc.getCurrentFunction();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   536
        if (parentFunction != null && !parentFunction.isProgram()) {
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   537
            sb.append(parentFunction.getName()).append('$');
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   538
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   539
22374
5231ab59e740 8030809: Anonymous functions should not be shown with internal names in script stack trace
sundar
parents: 21868
diff changeset
   540
        assert ident.getName() != null;
5231ab59e740 8030809: Anonymous functions should not be shown with internal names in script stack trace
sundar
parents: 21868
diff changeset
   541
        sb.append(ident.getName());
5231ab59e740 8030809: Anonymous functions should not be shown with internal names in script stack trace
sundar
parents: 21868
diff changeset
   542
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   543
        final String name = namespace.uniqueName(sb.toString());
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   544
        assert parentFunction != null || name.equals(PROGRAM.symbolName()) : "name = " + name;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   545
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   546
        int flags = 0;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   547
        if (isStrictMode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   548
            flags |= FunctionNode.IS_STRICT;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   549
        }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   550
        if (parentFunction == null) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   551
            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
   552
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   553
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   554
        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
   555
        functionNode.setFlag(flags);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   556
        return functionNode;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   557
    }
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   558
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   559
    private FunctionNode createFunctionNode(final ParserContextFunctionNode function, final long startToken, final IdentNode ident, final List<IdentNode> parameters, final FunctionNode.Kind kind, final int functionLine, final Block body) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   560
        // assert body.isFunctionBody() || body.getFlag(Block.IS_PARAMETER_BLOCK) && ((BlockStatement) body.getLastStatement()).getBlock().isFunctionBody();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   561
        // Start new block.
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   562
        final FunctionNode functionNode =
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   563
            new FunctionNode(
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   564
                source,
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   565
                functionLine,
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   566
                body.getToken(),
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   567
                Token.descPosition(body.getToken()),
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   568
                startToken,
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   569
                function.getLastToken(),
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   570
                namespace,
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   571
                ident,
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   572
                function.getName(),
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   573
                parameters,
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   574
                kind,
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   575
                function.getFlags(),
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   576
                body,
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   577
                function.getEndParserState(),
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   578
                function.getModule(),
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   579
                function.getDebugFlags());
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   580
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   581
        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
   582
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   583
        return functionNode;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   584
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   585
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   586
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   587
     * Restore the current block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   588
     */
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   589
    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
   590
        return lc.pop(block);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   591
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   592
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   593
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   594
     * Get the statements in a block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   595
     * @return Block statements.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   596
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   597
    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
   598
        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
   599
        final ParserContextBlockNode newBlock = newBlock();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   600
        try {
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   601
            // Block opening brace.
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   602
            if (needsBraces) {
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   603
                expect(LBRACE);
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   604
            }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   605
            // Accumulate block statements.
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   606
            statementList();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   607
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   608
        } finally {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   609
            restoreBlock(newBlock);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   610
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   611
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   612
        // Block closing brace.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   613
        if (needsBraces) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   614
            expect(RBRACE);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   615
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   616
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   617
        final int flags = newBlock.getFlags() | (needsBraces ? 0 : Block.IS_SYNTHETIC);
29407
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
   618
        return new Block(blockToken, finish, flags, newBlock.getStatements());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   619
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   620
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   621
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   622
     * Get the statements in a case clause.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   623
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   624
    private List<Statement> caseStatementList() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   625
        final ParserContextBlockNode newBlock = newBlock();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   626
        try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   627
            statementList();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   628
        } finally {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   629
            restoreBlock(newBlock);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   630
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   631
        return newBlock.getStatements();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   632
    }
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   633
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   634
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   635
     * Get all the statements generated by a single statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   636
     * @return Statements.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   637
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   638
    private Block getStatement() {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   639
        return getStatement(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   640
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   641
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   642
    private Block getStatement(boolean labelledStatement) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   643
        if (type == LBRACE) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   644
            return getBlock(true);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   645
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   646
        // 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
   647
        final ParserContextBlockNode newBlock = newBlock();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   648
        try {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   649
            statement(false, false, true, labelledStatement);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   650
        } finally {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   651
            restoreBlock(newBlock);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   652
        }
29407
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
   653
        return new Block(newBlock.getToken(), finish, newBlock.getFlags() | Block.IS_SYNTHETIC, newBlock.getStatements());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   654
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   655
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   656
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   657
     * Detect calls to special functions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   658
     * @param ident Called function.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   659
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   660
    private void detectSpecialFunction(final IdentNode ident) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   661
        final String name = ident.getName();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   662
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   663
        if (EVAL.symbolName().equals(name)) {
17255
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17249
diff changeset
   664
            markEval(lc);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   665
        } else if (SUPER.getName().equals(name)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   666
            assert ident.isDirectSuper();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   667
            markSuperCall(lc);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   668
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   669
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   670
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   671
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   672
     * Detect use of special properties.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   673
     * @param ident Referenced property.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   674
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   675
    private void detectSpecialProperty(final IdentNode ident) {
19898
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   676
        if (isArguments(ident)) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   677
            // skip over arrow functions, e.g. function f() { return (() => arguments.length)(); }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   678
            getCurrentNonArrowFunction().setFlag(FunctionNode.USES_ARGUMENTS);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   679
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   680
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   681
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   682
    private boolean useBlockScope() {
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   683
        return env._es6;
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   684
    }
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   685
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   686
    private boolean isES6() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   687
        return env._es6;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   688
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   689
19898
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   690
    private static boolean isArguments(final String name) {
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   691
        return ARGUMENTS_NAME.equals(name);
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   692
    }
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   693
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   694
    static boolean isArguments(final IdentNode ident) {
19898
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   695
        return isArguments(ident.getName());
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   696
    }
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   697
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   698
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   699
     * Tells whether a IdentNode can be used as L-value of an assignment
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   700
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   701
     * @param ident IdentNode to be checked
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   702
     * @return whether the ident can be used as L-value
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   703
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   704
    private static boolean checkIdentLValue(final IdentNode ident) {
30392
dc4a419b2982 8079362: Enforce best practices for Node token API usage
attila
parents: 29539
diff changeset
   705
        return ident.tokenType().getKind() != TokenKind.KEYWORD;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   706
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   707
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   708
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   709
     * Verify an assignment expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   710
     * @param op  Operation token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   711
     * @param lhs Left hand side expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   712
     * @param rhs Right hand side expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   713
     * @return Verified expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   714
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
   715
    private Expression verifyAssignment(final long op, final Expression lhs, final Expression rhs) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   716
        final TokenType opType = Token.descType(op);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   717
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   718
        switch (opType) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   719
        case ASSIGN:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   720
        case ASSIGN_ADD:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   721
        case ASSIGN_BIT_AND:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   722
        case ASSIGN_BIT_OR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   723
        case ASSIGN_BIT_XOR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   724
        case ASSIGN_DIV:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   725
        case ASSIGN_MOD:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   726
        case ASSIGN_MUL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   727
        case ASSIGN_SAR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   728
        case ASSIGN_SHL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   729
        case ASSIGN_SHR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   730
        case ASSIGN_SUB:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   731
            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
   732
                if (!checkIdentLValue((IdentNode)lhs)) {
18632
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
   733
                    return referenceError(lhs, rhs, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   734
                }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   735
                verifyIdent((IdentNode)lhs, "assignment");
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   736
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   737
            } else if (lhs instanceof AccessNode || lhs instanceof IndexNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   738
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   739
            } else if (opType == ASSIGN && isDestructuringLhs(lhs)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   740
                verifyDestructuringAssignmentPattern(lhs, "assignment");
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   741
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   742
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   743
                return referenceError(lhs, rhs, env._early_lvalue_error);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   744
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   745
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   746
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   747
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   748
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   749
        // Build up node.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   750
        if(BinaryNode.isLogical(opType)) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   751
            return new BinaryNode(op, new JoinPredecessorExpression(lhs), new JoinPredecessorExpression(rhs));
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   752
        }
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
   753
        return new BinaryNode(op, lhs, rhs);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   754
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   755
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   756
    private boolean isDestructuringLhs(Expression lhs) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   757
        if (lhs instanceof ObjectNode || lhs instanceof LiteralNode.ArrayLiteralNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   758
            return isES6();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   759
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   760
        return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   761
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   762
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   763
    private void verifyDestructuringAssignmentPattern(Expression pattern, String contextString) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   764
        assert pattern instanceof ObjectNode || pattern instanceof LiteralNode.ArrayLiteralNode;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   765
        pattern.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   766
            @Override
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   767
            public boolean enterLiteralNode(LiteralNode<?> literalNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   768
                if (literalNode.isArray()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   769
                    boolean restElement = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   770
                    for (Expression element : literalNode.getElementExpressions()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   771
                        if (element != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   772
                            if (restElement) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   773
                                throw error(String.format("Unexpected element after rest element"), element.getToken());
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
                            if (element.isTokenType(SPREAD_ARRAY)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   776
                                restElement = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   777
                                Expression lvalue = ((UnaryNode) element).getExpression();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   778
                                if (!checkValidLValue(lvalue, contextString)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   779
                                    throw error(AbstractParser.message("invalid.lvalue"), lvalue.getToken());
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
                            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   782
                            element.accept(this);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   783
                        }
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
                    return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   786
                } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   787
                    return enterDefault(literalNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   788
                }
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
            @Override
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   792
            public boolean enterObjectNode(ObjectNode objectNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   793
                return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   794
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   795
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   796
            @Override
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   797
            public boolean enterPropertyNode(PropertyNode propertyNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   798
                if (propertyNode.getValue() != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   799
                    propertyNode.getValue().accept(this);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   800
                    return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   801
                } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   802
                    return enterDefault(propertyNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   803
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   804
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   805
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   806
            @Override
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   807
            public boolean enterIdentNode(IdentNode identNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   808
                verifyIdent(identNode, contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   809
                if (!checkIdentLValue(identNode)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   810
                    referenceError(identNode, null, true);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   811
                    return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   812
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   813
                return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   814
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   815
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   816
            @Override
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   817
            public boolean enterAccessNode(AccessNode accessNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   818
                return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   819
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   820
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   821
            @Override
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   822
            public boolean enterIndexNode(IndexNode indexNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   823
                return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   824
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   825
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   826
            @Override
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   827
            public boolean enterBinaryNode(BinaryNode binaryNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   828
                if (binaryNode.isTokenType(ASSIGN)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   829
                    binaryNode.lhs().accept(this);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   830
                    // Initializer(rhs) can be any AssignmentExpression
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   831
                    return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   832
                } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   833
                    return enterDefault(binaryNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   834
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   835
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   836
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   837
            @Override
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   838
            public boolean enterUnaryNode(UnaryNode unaryNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   839
                if (unaryNode.isTokenType(SPREAD_ARRAY)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   840
                    // rest element
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   841
                    return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   842
                } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   843
                    return enterDefault(unaryNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   844
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   845
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   846
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   847
            @Override
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   848
            protected boolean enterDefault(Node node) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   849
                throw error(String.format("unexpected node in AssignmentPattern: %s", node));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   850
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   851
        });
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   852
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   853
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   854
    private static Expression newBinaryExpression(final long op, final Expression lhs, final Expression rhs) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   855
        final TokenType opType = Token.descType(op);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   856
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   857
        // Build up node.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   858
        if (BinaryNode.isLogical(opType)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   859
            return new BinaryNode(op, new JoinPredecessorExpression(lhs), new JoinPredecessorExpression(rhs));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   860
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   861
        return new BinaryNode(op, lhs, rhs);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   862
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   863
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   864
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   865
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   866
     * Reduce increment/decrement to simpler operations.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   867
     * @param firstToken First token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   868
     * @param tokenType  Operation token (INCPREFIX/DEC.)
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   869
     * @param expression Left hand side expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   870
     * @param isPostfix  Prefix or postfix.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   871
     * @return           Reduced expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   872
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
   873
    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
   874
        if (isPostfix) {
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
   875
            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
   876
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   877
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
   878
        return new UnaryNode(firstToken, expression);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   879
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   880
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
     * Grammar based on
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   885
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   886
     *      ECMAScript Language Specification
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   887
     *      ECMA-262 5th Edition / December 2009
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   888
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   889
     * -----------------------------------------------------------------------
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   890
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   891
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   892
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   893
     * Program :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   894
     *      SourceElements?
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   895
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   896
     * See 14
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   897
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   898
     * Parse the top level script.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   899
     */
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   900
    private FunctionNode program(final String scriptName, final boolean allowPropertyFunction) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   901
        // 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
   902
        final long functionToken = Token.toDesc(FUNCTION, Token.descPosition(Token.withDelimiter(token)), source.getLength());
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   903
        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
   904
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   905
        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
   906
        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
   907
                ident,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   908
                functionToken,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   909
                FunctionNode.Kind.SCRIPT,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   910
                functionLine,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   911
                Collections.<IdentNode>emptyList());
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   912
        lc.push(script);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   913
        final ParserContextBlockNode body = newBlock();
27814
96427359f4fe 8057691: Nashorn: let & const declarations are not shared between scripts
hannesw
parents: 27102
diff changeset
   914
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   915
        functionDeclarations = new ArrayList<>();
27814
96427359f4fe 8057691: Nashorn: let & const declarations are not shared between scripts
hannesw
parents: 27102
diff changeset
   916
        sourceElements(allowPropertyFunction);
96427359f4fe 8057691: Nashorn: let & const declarations are not shared between scripts
hannesw
parents: 27102
diff changeset
   917
        addFunctionDeclarations(script);
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   918
        functionDeclarations = null;
27814
96427359f4fe 8057691: Nashorn: let & const declarations are not shared between scripts
hannesw
parents: 27102
diff changeset
   919
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   920
        restoreBlock(body);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   921
        body.setFlag(Block.NEEDS_SCOPE);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   922
        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
   923
        lc.pop(script);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   924
        script.setLastToken(token);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   925
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   926
        expect(EOF);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   927
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
   928
        return createFunctionNode(script, functionToken, ident, Collections.<IdentNode>emptyList(), FunctionNode.Kind.SCRIPT, functionLine, programBody);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   929
    }
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
     * Directive value or null if statement is not a directive.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   933
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   934
     * @param stmt Statement to be checked
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   935
     * @return Directive value if the given statement is a directive
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   936
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   937
    private String getDirective(final Node stmt) {
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
   938
        if (stmt instanceof ExpressionStatement) {
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
   939
            final Node expr = ((ExpressionStatement)stmt).getExpression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   940
            if (expr instanceof LiteralNode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   941
                final LiteralNode<?> lit = (LiteralNode<?>)expr;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   942
                final long litToken = lit.getToken();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   943
                final TokenType tt = Token.descType(litToken);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   944
                // A directive is either a string or an escape string
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   945
                if (tt == TokenType.STRING || tt == TokenType.ESCSTRING) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   946
                    // Make sure that we don't unescape anything. Return as seen in source!
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   947
                    return source.getString(lit.getStart(), Token.descLength(litToken));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   948
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   949
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   950
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   951
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   952
        return null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   953
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   954
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   955
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   956
     * SourceElements :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   957
     *      SourceElement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   958
     *      SourceElements SourceElement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   959
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   960
     * See 14
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   961
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   962
     * Parse the elements of the script or function.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   963
     */
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   964
    private void sourceElements(final boolean shouldAllowPropertyFunction) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   965
        List<Node>    directiveStmts        = null;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   966
        boolean       checkDirective        = true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   967
        boolean       allowPropertyFunction = shouldAllowPropertyFunction;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   968
        final boolean oldStrictMode         = isStrictMode;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   969
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   970
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   971
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   972
            // If is a script, then process until the end of the script.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   973
            while (type != EOF) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   974
                // Break if the end of a code block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   975
                if (type == RBRACE) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   976
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   977
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   978
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   979
                try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   980
                    // Get the next element.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
   981
                    statement(true, allowPropertyFunction, false, false);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   982
                    allowPropertyFunction = false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   983
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   984
                    // check for directive prologues
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   985
                    if (checkDirective) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   986
                        // 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
   987
                        final Statement lastStatement = lc.getLastStatement();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   988
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   989
                        // get directive prologue, if any
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   990
                        final String directive = getDirective(lastStatement);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   991
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   992
                        // If we have seen first non-directive statement,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   993
                        // no more directive statements!!
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   994
                        checkDirective = directive != null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   995
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   996
                        if (checkDirective) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   997
                            if (!oldStrictMode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   998
                                if (directiveStmts == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   999
                                    directiveStmts = new ArrayList<>();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1000
                                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1001
                                directiveStmts.add(lastStatement);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1002
                            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1003
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1004
                            // handle use strict directive
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1005
                            if ("use strict".equals(directive)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1006
                                isStrictMode = true;
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  1007
                                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
  1008
                                function.setFlag(FunctionNode.IS_STRICT);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1009
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1010
                                // We don't need to check these, if lexical environment is already strict
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1011
                                if (!oldStrictMode && directiveStmts != null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1012
                                    // check that directives preceding this one do not violate strictness
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1013
                                    for (final Node statement : directiveStmts) {
32534
b3ec7f3b3c2a 8136349: Typos patch for nashorn sources submitted on Sep 10, 2015
sundar
parents: 32444
diff changeset
  1014
                                        // the get value will force unescape of preceding
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1015
                                        // escaped string directives
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1016
                                        getValue(statement.getToken());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1017
                                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1018
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1019
                                    // 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
  1020
                                    // satisfy strict mode restrictions.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1021
                                    verifyIdent(function.getIdent(), "function name");
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1022
                                    for (final IdentNode param : function.getParameters()) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1023
                                        verifyIdent(param, "function parameter");
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1024
                                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1025
                                }
26065
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  1026
                            } else if (Context.DEBUG) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1027
                                final int debugFlag = FunctionNode.getDirectiveFlag(directive);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1028
                                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
  1029
                                    final ParserContextFunctionNode function = lc.getCurrentFunction();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1030
                                    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
  1031
                                }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1032
                            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1033
                        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1034
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1035
                } catch (final Exception e) {
29407
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
  1036
                    final int errorLine = line;
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
  1037
                    final long errorToken = token;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1038
                    //recover parsing
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1039
                    recover(e);
29407
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
  1040
                    final ErrorNode errorExpr = new ErrorNode(errorToken, finish);
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
  1041
                    final ExpressionStatement expressionStatement = new ExpressionStatement(errorLine, errorToken, finish, errorExpr);
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
  1042
                    appendStatement(expressionStatement);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1043
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1044
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1045
                // No backtracking from here on.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1046
                stream.commit(k);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1047
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1048
        } finally {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1049
            isStrictMode = oldStrictMode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1050
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1051
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1052
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1053
    /**
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1054
     * Parse any of the basic statement types.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1055
     *
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1056
     * Statement :
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1057
     *      BlockStatement
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1058
     *      VariableStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1059
     *      EmptyStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1060
     *      ExpressionStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1061
     *      IfStatement
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1062
     *      BreakableStatement
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1063
     *      ContinueStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1064
     *      BreakStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1065
     *      ReturnStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1066
     *      WithStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1067
     *      LabelledStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1068
     *      ThrowStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1069
     *      TryStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1070
     *      DebuggerStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1071
     *
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1072
     * BreakableStatement :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1073
     *      IterationStatement
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1074
     *      SwitchStatement
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1075
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1076
     * BlockStatement :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1077
     *      Block
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1078
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1079
     * Block :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1080
     *      { StatementList opt }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1081
     *
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1082
     * StatementList :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1083
     *      StatementListItem
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1084
     *      StatementList StatementListItem
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1085
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1086
     * StatementItem :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1087
     *      Statement
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1088
     *      Declaration
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1089
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1090
     * Declaration :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1091
     *     HoistableDeclaration
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1092
     *     ClassDeclaration
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1093
     *     LexicalDeclaration
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1094
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1095
     * HoistableDeclaration :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1096
     *     FunctionDeclaration
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1097
     *     GeneratorDeclaration
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1098
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1099
    private void statement() {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1100
        statement(false, false, false, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1101
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1102
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1103
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1104
     * @param topLevel does this statement occur at the "top level" of a script or a function?
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  1105
     * @param allowPropertyFunction allow property "get" and "set" functions?
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  1106
     * @param singleStatement are we in a single statement context?
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1107
     */
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1108
    private void statement(final boolean topLevel, final boolean allowPropertyFunction, final boolean singleStatement, final boolean labelledStatement) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1109
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1110
        case LBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1111
            block();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1112
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1113
        case VAR:
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1114
            variableStatement(type);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1115
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1116
        case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1117
            emptyStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1118
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1119
        case IF:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1120
            ifStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1121
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1122
        case FOR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1123
            forStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1124
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1125
        case WHILE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1126
            whileStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1127
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1128
        case DO:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1129
            doStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1130
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1131
        case CONTINUE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1132
            continueStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1133
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1134
        case BREAK:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1135
            breakStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1136
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1137
        case RETURN:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1138
            returnStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1139
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1140
        case WITH:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1141
            withStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1142
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1143
        case SWITCH:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1144
            switchStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1145
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1146
        case THROW:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1147
            throwStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1148
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1149
        case TRY:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1150
            tryStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1151
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1152
        case DEBUGGER:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1153
            debuggerStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1154
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1155
        case RPAREN:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1156
        case RBRACKET:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1157
        case EOF:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1158
            expect(SEMICOLON);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1159
            break;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1160
        case FUNCTION:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1161
            // As per spec (ECMA section 12), function declarations as arbitrary statement
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1162
            // is not "portable". Implementation can issue a warning or disallow the same.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1163
            if (singleStatement) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1164
                // ES6 B.3.2 Labelled Function Declarations
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1165
                // 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
  1166
                // LabelledItem : FunctionDeclaration.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1167
                if (!labelledStatement || isStrictMode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1168
                    throw error(AbstractParser.message("expected.stmt", "function declaration"), token);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1169
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1170
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1171
            functionExpression(true, topLevel || labelledStatement);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1172
            return;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1173
        default:
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1174
            if (useBlockScope() && (type == LET && lookaheadIsLetDeclaration(false) || type == CONST)) {
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  1175
                if (singleStatement) {
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  1176
                    throw error(AbstractParser.message("expected.stmt", type.getName() + " declaration"), token);
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  1177
                }
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1178
                variableStatement(type);
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1179
                break;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1180
            } else if (type == CLASS && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1181
                if (singleStatement) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1182
                    throw error(AbstractParser.message("expected.stmt", "class declaration"), token);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1183
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1184
                classDeclaration(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1185
                break;
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1186
            }
24279
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
  1187
            if (env._const_as_var && type == CONST) {
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1188
                variableStatement(TokenType.VAR);
24279
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
  1189
                break;
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
  1190
            }
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
  1191
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1192
            if (type == IDENT || isNonStrictModeIdent()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1193
                if (T(k + 1) == COLON) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1194
                    labelStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1195
                    return;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1196
                }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1197
                if(allowPropertyFunction) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1198
                    final String ident = (String)getValue();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1199
                    final long propertyToken = token;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1200
                    final int propertyLine = line;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1201
                    if ("get".equals(ident)) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1202
                        next();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1203
                        addPropertyFunctionStatement(propertyGetterFunction(propertyToken, propertyLine));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1204
                        return;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1205
                    } else if ("set".equals(ident)) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1206
                        next();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1207
                        addPropertyFunctionStatement(propertySetterFunction(propertyToken, propertyLine));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1208
                        return;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1209
                    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1210
                }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1211
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1212
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1213
            expressionStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1214
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1215
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1216
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1217
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1218
    private void addPropertyFunctionStatement(final PropertyFunction propertyFunction) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1219
        final FunctionNode fn = propertyFunction.functionNode;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1220
        functionDeclarations.add(new ExpressionStatement(fn.getLineNumber(), fn.getToken(), finish, fn));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1221
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1222
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1223
    /**
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1224
     * ClassDeclaration[Yield, Default] :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1225
     *   class BindingIdentifier[?Yield] ClassTail[?Yield]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1226
     *   [+Default] class ClassTail[?Yield]
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
    private ClassNode classDeclaration(boolean isDefault) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1229
        int classLineNumber = line;
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
        ClassNode classExpression = classExpression(!isDefault);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1232
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1233
        if (!isDefault) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1234
            VarNode classVar = new VarNode(classLineNumber, classExpression.getToken(), classExpression.getIdent().getFinish(), classExpression.getIdent(), classExpression, VarNode.IS_CONST);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1235
            appendStatement(classVar);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1236
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1237
        return classExpression;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1238
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1239
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1240
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1241
     * ClassExpression[Yield] :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1242
     *   class BindingIdentifier[?Yield]opt ClassTail[?Yield]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1243
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1244
    private ClassNode classExpression(boolean isStatement) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1245
        assert type == CLASS;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1246
        int classLineNumber = line;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1247
        long classToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1248
        next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1249
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1250
        IdentNode className = null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1251
        if (isStatement || type == IDENT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1252
            className = getIdent();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1253
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1254
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1255
        return classTail(classLineNumber, classToken, className);
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
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1258
    private static final class ClassElementKey {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1259
        private final boolean isStatic;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1260
        private final String propertyName;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1261
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1262
        private ClassElementKey(boolean isStatic, String propertyName) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1263
            this.isStatic = isStatic;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1264
            this.propertyName = propertyName;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1265
        }
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
        @Override
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1268
        public int hashCode() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1269
            final int prime = 31;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1270
            int result = 1;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1271
            result = prime * result + (isStatic ? 1231 : 1237);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1272
            result = prime * result + ((propertyName == null) ? 0 : propertyName.hashCode());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1273
            return result;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1274
        }
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
        @Override
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1277
        public boolean equals(Object obj) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1278
            if (obj instanceof ClassElementKey) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1279
                ClassElementKey other = (ClassElementKey) obj;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1280
                return this.isStatic == other.isStatic && Objects.equals(this.propertyName, other.propertyName);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1281
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1282
            return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1283
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1284
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1285
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1286
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1287
     * Parse ClassTail and ClassBody.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1288
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1289
     * ClassTail[Yield] :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1290
     *   ClassHeritage[?Yield]opt { ClassBody[?Yield]opt }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1291
     * ClassHeritage[Yield] :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1292
     *   extends LeftHandSideExpression[?Yield]
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
     * ClassBody[Yield] :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1295
     *   ClassElementList[?Yield]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1296
     * ClassElementList[Yield] :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1297
     *   ClassElement[?Yield]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1298
     *   ClassElementList[?Yield] ClassElement[?Yield]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1299
     * ClassElement[Yield] :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1300
     *   MethodDefinition[?Yield]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1301
     *   static MethodDefinition[?Yield]
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
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1304
    private ClassNode classTail(final int classLineNumber, final long classToken, final IdentNode className) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1305
        final boolean oldStrictMode = isStrictMode;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1306
        isStrictMode = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1307
        try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1308
            Expression classHeritage = null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1309
            if (type == EXTENDS) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1310
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1311
                classHeritage = leftHandSideExpression();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1312
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1313
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1314
            expect(LBRACE);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1315
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1316
            PropertyNode constructor = null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1317
            final ArrayList<PropertyNode> classElements = new ArrayList<>();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1318
            final Map<ClassElementKey, Integer> keyToIndexMap = new HashMap<>();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1319
            for (;;) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1320
                if (type == SEMICOLON) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1321
                    next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1322
                    continue;
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 (type == RBRACE) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1325
                    break;
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
                final long classElementToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1328
                boolean isStatic = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1329
                if (type == STATIC) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1330
                    isStatic = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1331
                    next();
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
                boolean generator = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1334
                if (isES6() && type == MUL) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1335
                    generator = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1336
                    next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1337
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1338
                final PropertyNode classElement = methodDefinition(isStatic, classHeritage != null, generator);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1339
                if (classElement.isComputed()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1340
                    classElements.add(classElement);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1341
                } else if (!classElement.isStatic() && classElement.getKeyName().equals("constructor")) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1342
                    if (constructor == null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1343
                        constructor = classElement;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1344
                    } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1345
                        throw error(AbstractParser.message("multiple.constructors"), classElementToken);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1346
                    }
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
                    // Check for duplicate method definitions and combine accessor methods.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1349
                    // 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
  1350
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1351
                    final ClassElementKey key = new ClassElementKey(classElement.isStatic(), classElement.getKeyName());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1352
                    final Integer existing = keyToIndexMap.get(key);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1353
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1354
                    if (existing == null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1355
                        keyToIndexMap.put(key, classElements.size());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1356
                        classElements.add(classElement);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1357
                    } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1358
                        final PropertyNode existingProperty = classElements.get(existing);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1359
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1360
                        final Expression   value  = classElement.getValue();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1361
                        final FunctionNode getter = classElement.getGetter();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1362
                        final FunctionNode setter = classElement.getSetter();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1363
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1364
                        if (value != null || existingProperty.getValue() != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1365
                            keyToIndexMap.put(key, classElements.size());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1366
                            classElements.add(classElement);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1367
                        } else if (getter != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1368
                            assert existingProperty.getGetter() != null || existingProperty.getSetter() != null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1369
                            classElements.set(existing, existingProperty.setGetter(getter));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1370
                        } else if (setter != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1371
                            assert existingProperty.getGetter() != null || existingProperty.getSetter() != null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1372
                            classElements.set(existing, existingProperty.setSetter(setter));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1373
                        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1374
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1375
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1376
            }
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
            final long lastToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1379
            expect(RBRACE);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1380
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1381
            if (constructor == null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1382
                constructor = createDefaultClassConstructor(classLineNumber, classToken, lastToken, className, classHeritage != null);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1383
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1384
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1385
            classElements.trimToSize();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1386
            return new ClassNode(classLineNumber, classToken, finish, className, classHeritage, constructor, classElements);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1387
        } finally {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1388
            isStrictMode = oldStrictMode;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1389
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1390
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1391
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1392
    private PropertyNode createDefaultClassConstructor(int classLineNumber, long classToken, long lastToken, IdentNode className, boolean subclass) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1393
        final int ctorFinish = finish;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1394
        final List<Statement> statements;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1395
        final List<IdentNode> parameters;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1396
        final long identToken = Token.recast(classToken, TokenType.IDENT);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1397
        if (subclass) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1398
            final IdentNode superIdent = createIdentNode(identToken, ctorFinish, SUPER.getName()).setIsDirectSuper();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1399
            final IdentNode argsIdent = createIdentNode(identToken, ctorFinish, "args").setIsRestParameter();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1400
            final Expression spreadArgs = new UnaryNode(Token.recast(classToken, TokenType.SPREAD_ARGUMENT), argsIdent);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1401
            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
  1402
            statements = Collections.singletonList(new ExpressionStatement(classLineNumber, classToken, ctorFinish, superCall));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1403
            parameters = Collections.singletonList(argsIdent);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1404
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1405
            statements = Collections.emptyList();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1406
            parameters = Collections.emptyList();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1407
        }
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
        final Block body = new Block(classToken, ctorFinish, Block.IS_BODY, statements);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1410
        final IdentNode ctorName = className != null ? className : createIdentNode(identToken, ctorFinish, "constructor");
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1411
        final ParserContextFunctionNode function = createParserContextFunctionNode(ctorName, classToken, FunctionNode.Kind.NORMAL, classLineNumber, parameters);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1412
        function.setLastToken(lastToken);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1413
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1414
        function.setFlag(FunctionNode.ES6_IS_METHOD);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1415
        function.setFlag(FunctionNode.ES6_IS_CLASS_CONSTRUCTOR);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1416
        if (subclass) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1417
            function.setFlag(FunctionNode.ES6_IS_SUBCLASS_CONSTRUCTOR);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1418
            function.setFlag(FunctionNode.ES6_HAS_DIRECT_SUPER);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1419
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1420
        if (className == null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1421
            function.setFlag(FunctionNode.IS_ANONYMOUS);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1422
        }
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
        final PropertyNode constructor = new PropertyNode(classToken, ctorFinish, ctorName, createFunctionNode(
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1425
                        function,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1426
                        classToken,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1427
                        ctorName,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1428
                        parameters,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1429
                        FunctionNode.Kind.NORMAL,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1430
                        classLineNumber,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1431
                        body
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1432
                        ), null, null, false, false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1433
        return constructor;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1434
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1435
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1436
    private PropertyNode methodDefinition(final boolean isStatic, final boolean subclass, final boolean generator) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1437
        final long methodToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1438
        final int methodLine = line;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1439
        final boolean computed = type == LBRACKET;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1440
        final boolean isIdent = type == IDENT;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1441
        final Expression propertyName = propertyName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1442
        int flags = FunctionNode.ES6_IS_METHOD;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1443
        if (!computed) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1444
            final String name = ((PropertyKey)propertyName).getPropertyName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1445
            if (!generator && isIdent && type != LPAREN && name.equals("get")) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1446
                final PropertyFunction methodDefinition = propertyGetterFunction(methodToken, methodLine, flags);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1447
                verifyAllowedMethodName(methodDefinition.key, isStatic, methodDefinition.computed, generator, true);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1448
                return new PropertyNode(methodToken, finish, methodDefinition.key, null, methodDefinition.functionNode, null, isStatic, methodDefinition.computed);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1449
            } else if (!generator && isIdent && type != LPAREN && name.equals("set")) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1450
                final PropertyFunction methodDefinition = propertySetterFunction(methodToken, methodLine, flags);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1451
                verifyAllowedMethodName(methodDefinition.key, isStatic, methodDefinition.computed, generator, true);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1452
                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
  1453
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1454
                if (!isStatic && !generator && name.equals("constructor")) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1455
                    flags |= FunctionNode.ES6_IS_CLASS_CONSTRUCTOR;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1456
                    if (subclass) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1457
                        flags |= FunctionNode.ES6_IS_SUBCLASS_CONSTRUCTOR;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1458
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1459
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1460
                verifyAllowedMethodName(propertyName, isStatic, computed, generator, false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1461
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1462
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1463
        final PropertyFunction methodDefinition = propertyMethodFunction(propertyName, methodToken, methodLine, generator, flags, computed);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1464
        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
  1465
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1466
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1467
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1468
     * ES6 14.5.1 Static Semantics: Early Errors.
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
    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
  1471
        if (!computed) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1472
            if (!isStatic && generator && ((PropertyKey) key).getPropertyName().equals("constructor")) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1473
                throw error(AbstractParser.message("generator.constructor"), key.getToken());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1474
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1475
            if (!isStatic && accessor && ((PropertyKey) key).getPropertyName().equals("constructor")) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1476
                throw error(AbstractParser.message("accessor.constructor"), key.getToken());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1477
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1478
            if (isStatic && ((PropertyKey) key).getPropertyName().equals("prototype")) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1479
                throw error(AbstractParser.message("static.prototype.method"), key.getToken());
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
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1484
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1485
     * block :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1486
     *      { StatementList? }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1487
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1488
     * see 12.1
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1489
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1490
     * Parse a statement block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1491
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1492
    private void block() {
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1493
        appendStatement(new BlockStatement(line, getBlock(true)));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1494
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1495
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1496
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1497
     * StatementList :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1498
     *      Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1499
     *      StatementList Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1500
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1501
     * See 12.1
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1502
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1503
     * Parse a list of statements.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1504
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1505
    private void statementList() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1506
        // Accumulate statements until end of list. */
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1507
        loop:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1508
        while (type != EOF) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1509
            switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1510
            case EOF:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1511
            case CASE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1512
            case DEFAULT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1513
            case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1514
                break loop;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1515
            default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1516
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1517
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1518
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1519
            // Get next statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1520
            statement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1521
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1522
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1523
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1524
    /**
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1525
     * Make sure that the identifier name used is allowed.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1526
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1527
     * @param ident         Identifier that is verified
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1528
     * @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
  1529
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1530
    private void verifyIdent(final IdentNode ident, final String contextString) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1531
        verifyStrictIdent(ident, contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1532
        if (isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1533
            final TokenType tokenType = TokenLookup.lookupKeyword(ident.getName().toCharArray(), 0, ident.getName().length());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1534
            if (tokenType != IDENT && tokenType.getKind() != TokenKind.FUTURESTRICT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1535
                throw error(expectMessage(IDENT));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1536
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1537
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1538
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1539
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1540
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1541
     * Make sure that in strict mode, the identifier name used is allowed.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1542
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1543
     * @param ident         Identifier that is verified
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1544
     * @param contextString String used in error message to give context to the user
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1545
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1546
    private void verifyStrictIdent(final IdentNode ident, final String contextString) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1547
        if (isStrictMode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1548
            switch (ident.getName()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1549
            case "eval":
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1550
            case "arguments":
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1551
                throw error(AbstractParser.message("strict.name", ident.getName(), contextString), ident.getToken());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1552
            default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1553
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1554
            }
20571
f52b0abf5d88 8026039: future strict names are allowed as function name and argument name of a strict function
sundar
parents: 20559
diff changeset
  1555
f52b0abf5d88 8026039: future strict names are allowed as function name and argument name of a strict function
sundar
parents: 20559
diff changeset
  1556
            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
  1557
                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
  1558
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1559
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1560
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1561
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1562
    /*
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1563
     * VariableStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1564
     *      var VariableDeclarationList ;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1565
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1566
     * VariableDeclarationList :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1567
     *      VariableDeclaration
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1568
     *      VariableDeclarationList , VariableDeclaration
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1569
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1570
     * VariableDeclaration :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1571
     *      Identifier Initializer?
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1572
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1573
     * Initializer :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1574
     *      = AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1575
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1576
     * See 12.2
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1577
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1578
     * Parse a VAR statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1579
     * @param isStatement True if a statement (not used in a FOR.)
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1580
     */
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1581
    private void variableStatement(final TokenType varType) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1582
        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
  1583
    }
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
  1584
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1585
    private List<Expression> variableDeclarationList(final TokenType varType, final boolean isStatement, final int sourceOrder) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1586
        // VAR tested in caller.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1587
        assert varType == VAR || varType == LET || varType == CONST;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1588
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1589
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1590
        final List<Expression> bindings = new ArrayList<>();
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  1591
        int varFlags = 0;
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1592
        if (varType == LET) {
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1593
            varFlags |= VarNode.IS_LET;
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1594
        } else if (varType == CONST) {
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1595
            varFlags |= VarNode.IS_CONST;
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1596
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1597
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1598
        Expression missingAssignment = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1599
        while (true) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1600
            // Get starting 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
  1601
            final int  varLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1602
            final long varToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1603
            // Get name of var.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1604
            if (type == YIELD && inGeneratorFunction()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1605
                expect(IDENT);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1606
            }
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
            final String contextString = "variable name";
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1609
            Expression binding = bindingIdentifierOrPattern(contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1610
            final boolean isDestructuring = !(binding instanceof IdentNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1611
            if (isDestructuring) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1612
                final int finalVarFlags = varFlags;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1613
                verifyDestructuringBindingPattern(binding, new Consumer<IdentNode>() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1614
                    public void accept(final IdentNode identNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1615
                        verifyIdent(identNode, contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1616
                        final VarNode var = new VarNode(varLine, varToken, sourceOrder, identNode.getFinish(), identNode.setIsDeclaredHere(), null, finalVarFlags);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1617
                        appendStatement(var);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1618
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1619
                });
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1620
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1621
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1622
            // Assume no init.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1623
            Expression init = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1624
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1625
            // Look for initializer assignment.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1626
            if (type == ASSIGN) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1627
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1628
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1629
                // Get initializer expression. Suppress IN if not statement.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1630
                if (!isDestructuring) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1631
                    defaultNames.push(binding);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1632
                }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1633
                try {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1634
                    init = assignmentExpression(!isStatement);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1635
                } finally {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1636
                    if (!isDestructuring) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1637
                        defaultNames.pop();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1638
                    }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1639
                }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1640
            } else if (isStatement) {
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
                    throw error(AbstractParser.message("missing.destructuring.assignment"), token);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1643
                } else if (varType == CONST) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1644
                    throw error(AbstractParser.message("missing.const.assignment", ((IdentNode)binding).getName()));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1645
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1646
                // 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
  1647
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1648
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1649
            if (!isDestructuring) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1650
                assert init != null || varType != CONST || !isStatement;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1651
                final IdentNode ident = (IdentNode)binding;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1652
                if (!isStatement && ident.getName().equals("let")) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1653
                    throw error(AbstractParser.message("let.binding.for")); //ES6 13.7.5.1
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1654
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1655
                // 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
  1656
                final IdentNode name = varType == LET || varType == CONST ? ident.setIsDeclaredHere() : ident;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1657
                binding = name;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1658
                final VarNode var = new VarNode(varLine, varToken, sourceOrder, finish, name, init, varFlags);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1659
                appendStatement(var);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1660
                if (init == null && varType == CONST) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1661
                    if (missingAssignment == null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1662
                        missingAssignment = binding;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1663
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1664
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1665
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1666
                assert init != null || !isStatement;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1667
                binding = init == null ? binding : verifyAssignment(Token.recast(varToken, ASSIGN), binding, init);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1668
                if (isStatement) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1669
                    appendStatement(new ExpressionStatement(varLine, binding.getToken(), finish, binding));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1670
                } else if (init == null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1671
                    if (missingAssignment == null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1672
                        missingAssignment = binding;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1673
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1674
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1675
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1676
            bindings.add(binding);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1677
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1678
            if (type != COMMARIGHT) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1679
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1680
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1681
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1682
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1683
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1684
        // If is a statement then handle end of line.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1685
        if (isStatement) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1686
            endOfLine();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1687
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1688
            if (type == SEMICOLON) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1689
                // late check for missing assignment, now we know it's a for (init; test; modify) loop
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1690
                if (missingAssignment != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1691
                    if (missingAssignment instanceof IdentNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1692
                        throw error(AbstractParser.message("missing.const.assignment", ((IdentNode)missingAssignment).getName()));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1693
                    } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1694
                        throw error(AbstractParser.message("missing.destructuring.assignment"), missingAssignment.getToken());
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
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1698
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1699
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1700
        return bindings;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1701
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1702
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1703
    private boolean isBindingIdentifier() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1704
        return type == IDENT || isNonStrictModeIdent();
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 IdentNode bindingIdentifier(final String contextString) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1708
        final IdentNode name = getIdent();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1709
        verifyIdent(name, contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1710
        return name;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1711
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1712
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1713
    private Expression bindingPattern() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1714
        if (type == LBRACKET) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1715
            return arrayLiteral();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1716
        } else if (type == LBRACE) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1717
            return objectLiteral();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1718
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1719
            throw error(AbstractParser.message("expected.binding"));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1720
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1721
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1722
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1723
    private Expression bindingIdentifierOrPattern(final String contextString) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1724
        if (isBindingIdentifier() || !isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1725
            return bindingIdentifier(contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1726
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1727
            return bindingPattern();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1728
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1729
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1730
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1731
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1732
     * Verify destructuring variable declaration binding pattern and extract bound variable declarations.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1733
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1734
    private void verifyDestructuringBindingPattern(final Expression pattern, final Consumer<IdentNode> identifierCallback) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1735
        assert pattern instanceof ObjectNode || pattern instanceof LiteralNode.ArrayLiteralNode;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1736
        pattern.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1737
            @Override
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1738
            public boolean enterLiteralNode(final LiteralNode<?> literalNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1739
                if (literalNode.isArray()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1740
                    boolean restElement = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1741
                    for (final Expression element : literalNode.getElementExpressions()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1742
                        if (restElement) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1743
                            throw error(String.format("Unexpected element after rest element"), element.getToken());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1744
                        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1745
                        if (element != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1746
                            if (element.isTokenType(SPREAD_ARRAY)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1747
                                restElement = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1748
                                if (!(((UnaryNode) element).getExpression() instanceof IdentNode)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1749
                                    throw error(String.format("Expected a valid binding identifier"), element.getToken());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1750
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1751
                                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1752
                            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1753
                            element.accept(this);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1754
                        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1755
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1756
                    return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1757
                } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1758
                    return enterDefault(literalNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1759
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1760
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1761
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1762
            @Override
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1763
            public boolean enterObjectNode(final ObjectNode objectNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1764
                return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1765
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1766
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1767
            @Override
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1768
            public boolean enterPropertyNode(final PropertyNode propertyNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1769
                if (propertyNode.getValue() != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1770
                    propertyNode.getValue().accept(this);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1771
                    return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1772
                } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1773
                    return enterDefault(propertyNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1774
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1775
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1776
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1777
            @Override
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1778
            public boolean enterIdentNode(final IdentNode identNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1779
                identifierCallback.accept(identNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1780
                return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1781
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1782
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1783
            @Override
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1784
            public boolean enterBinaryNode(final BinaryNode binaryNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1785
                if (binaryNode.isTokenType(ASSIGN)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1786
                    binaryNode.lhs().accept(this);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1787
                    // Initializer(rhs) can be any AssignmentExpression
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1788
                    return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1789
                } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1790
                    return enterDefault(binaryNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1791
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1792
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1793
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1794
            @Override
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1795
            public boolean enterUnaryNode(final UnaryNode unaryNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1796
                if (unaryNode.isTokenType(SPREAD_ARRAY)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1797
                    // rest element
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1798
                    return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1799
                } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1800
                    return enterDefault(unaryNode);
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
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1804
            @Override
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1805
            protected boolean enterDefault(final Node node) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1806
                throw error(String.format("unexpected node in BindingPattern: %s", node));
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
        });
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1809
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1810
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1811
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1812
     * EmptyStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1813
     *      ;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1814
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1815
     * See 12.3
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1816
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1817
     * Parse an empty statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1818
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1819
    private void emptyStatement() {
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
  1820
        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
  1821
            appendStatement(new EmptyNode(line, token, Token.descPosition(token) + Token.descLength(token)));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1822
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1823
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1824
        // SEMICOLON checked in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1825
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1826
    }
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
     * ExpressionStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1830
     *      Expression ; // [lookahead ~( or  function )]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1831
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1832
     * See 12.4
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1833
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1834
     * Parse an expression used in a statement block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1835
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1836
    private void expressionStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1837
        // 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
  1838
        final int  expressionLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1839
        final long expressionToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1840
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1841
        // Get expression and add as statement.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1842
        final Expression expression = expression();
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1843
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1844
        ExpressionStatement expressionStatement = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1845
        if (expression != null) {
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1846
            expressionStatement = new ExpressionStatement(expressionLine, expressionToken, finish, expression);
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1847
            appendStatement(expressionStatement);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1848
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1849
            expect(null);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1850
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1851
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1852
        endOfLine();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1853
    }
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
     * IfStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1857
     *      if ( Expression ) Statement else Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1858
     *      if ( Expression ) Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1859
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1860
     * See 12.5
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1861
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1862
     * Parse an IF statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1863
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1864
    private void ifStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1865
        // 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
  1866
        final int  ifLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1867
        final long ifToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1868
         // IF tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1869
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1870
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1871
        expect(LPAREN);
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1872
        final Expression test = expression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1873
        expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1874
        final Block pass = getStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1875
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1876
        Block fail = null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1877
        if (type == ELSE) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1878
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1879
            fail = getStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1880
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1881
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
  1882
        appendStatement(new IfNode(ifLine, ifToken, fail != null ? fail.getFinish() : pass.getFinish(), test, pass, fail));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1883
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1884
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1885
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1886
     * ... IterationStatement:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1887
     *           ...
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1888
     *           for ( Expression[NoIn]?; Expression? ; Expression? ) Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1889
     *           for ( var VariableDeclarationList[NoIn]; Expression? ; Expression? ) Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1890
     *           for ( LeftHandSideExpression in Expression ) Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1891
     *           for ( var VariableDeclaration[NoIn] in Expression ) Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1892
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1893
     * See 12.6
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1894
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1895
     * Parse a FOR statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1896
     */
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1897
    @SuppressWarnings("fallthrough")
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1898
    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
  1899
        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
  1900
        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
  1901
        // 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
  1902
        // 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
  1903
        // 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
  1904
        final int forStart = Token.descPosition(forToken);
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1905
        // 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
  1906
        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
  1907
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1908
        // 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
  1909
        final ParserContextLoopNode forNode = new ParserContextLoopNode();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1910
        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
  1911
        Block body = null;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1912
        List<Expression> vars = null;
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  1913
        Expression init = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  1914
        JoinPredecessorExpression test = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  1915
        JoinPredecessorExpression modify = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  1916
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  1917
        int flags = 0;
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1918
        boolean isForOf = false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1919
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1920
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1921
            // FOR tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1922
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1923
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1924
            // Nashorn extension: for each expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1925
            // 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
  1926
            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
  1927
                flags |= ForNode.IS_FOR_EACH;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1928
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1929
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1930
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1931
            expect(LPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1932
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1933
            switch (type) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1934
            case VAR:
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  1935
                // Var declaration captured in for outer block.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1936
                vars = variableDeclarationList(type, false, forStart);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1937
                break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1938
            case SEMICOLON:
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1939
                break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1940
            default:
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1941
                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
  1942
                    flags |= ForNode.PER_ITERATION_SCOPE;
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  1943
                    // LET/CONST declaration captured in container block created above.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1944
                    vars = variableDeclarationList(type, false, forStart);
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1945
                    break;
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1946
                }
24279
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
  1947
                if (env._const_as_var && type == CONST) {
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  1948
                    // Var declaration captured in for outer block.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1949
                    vars = variableDeclarationList(TokenType.VAR, false, forStart);
24279
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
  1950
                    break;
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
  1951
                }
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
  1952
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  1953
                init = expression(unaryExpression(), COMMARIGHT.getPrecedence(), true);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1954
                break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1955
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1956
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1957
            switch (type) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1958
            case SEMICOLON:
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1959
                // for (init; test; modify)
18843
eea6d1b8263e 8019805: for each (init; test; modify) is invalid
sundar
parents: 18632
diff changeset
  1960
eea6d1b8263e 8019805: for each (init; test; modify) is invalid
sundar
parents: 18632
diff changeset
  1961
                // 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
  1962
                if ((flags & ForNode.IS_FOR_EACH) != 0) {
18843
eea6d1b8263e 8019805: for each (init; test; modify) is invalid
sundar
parents: 18632
diff changeset
  1963
                    throw error(AbstractParser.message("for.each.without.in"), token);
eea6d1b8263e 8019805: for each (init; test; modify) is invalid
sundar
parents: 18632
diff changeset
  1964
                }
eea6d1b8263e 8019805: for each (init; test; modify) is invalid
sundar
parents: 18632
diff changeset
  1965
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1966
                expect(SEMICOLON);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1967
                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
  1968
                    test = joinPredecessorExpression();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1969
                }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1970
                expect(SEMICOLON);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1971
                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
  1972
                    modify = joinPredecessorExpression();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1973
                }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1974
                break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1975
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1976
            case IDENT:
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1977
                if (env._es6 && "of".equals(getValue())) {
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1978
                    isForOf = true;
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1979
                    // fall through
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1980
                } else {
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1981
                    expect(SEMICOLON); // fail with expected message
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1982
                    break;
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1983
                }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1984
            case IN:
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1985
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1986
                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
  1987
                test = new JoinPredecessorExpression();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1988
                if (vars != null) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1989
                    // for (var i in obj)
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1990
                    if (vars.size() == 1) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1991
                        init = new IdentNode((IdentNode)vars.get(0));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1992
                        if (init.isTokenType(ASSIGN)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1993
                            throw error(AbstractParser.message("for.in.loop.initializer"), init.getToken());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1994
                        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  1995
                        assert init instanceof IdentNode || isDestructuringLhs(init);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1996
                    } else {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1997
                        // for (var i, j in obj) is invalid
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  1998
                        throw error(AbstractParser.message("many.vars.in.for.in.loop", isForOf ? "of" : "in"), vars.get(1).getToken());
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1999
                    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2000
                } else {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2001
                    // for (expr in obj)
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  2002
                    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
  2003
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2004
                    // check if initial expression is a valid L-value
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2005
                    if (!(init instanceof AccessNode ||
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2006
                          init instanceof IndexNode ||
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2007
                          init instanceof IdentNode)) {
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  2008
                        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
  2009
                    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2010
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2011
                    if (init instanceof IdentNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2012
                        if (!checkIdentLValue((IdentNode)init)) {
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  2013
                            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
  2014
                        }
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  2015
                        verifyStrictIdent((IdentNode)init, isForOf ? "for-of iterator" : "for-in iterator");
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2016
                    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2017
                }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2018
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2019
                next();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2020
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  2021
                // For-of only allows AssignmentExpression.
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 36691
diff changeset
  2022
                modify = isForOf ? new JoinPredecessorExpression(assignmentExpression(false)) : joinPredecessorExpression();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2023
                break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2024
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2025
            default:
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2026
                expect(SEMICOLON);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2027
                break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2028
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2029
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2030
            expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2031
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2032
            // 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
  2033
            body = getStatement();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2034
        } finally {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2035
            lc.pop(forNode);
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2036
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2037
            for (final Statement var : forNode.getStatements()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2038
                assert var instanceof VarNode;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2039
                appendStatement(var);
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2040
            }
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2041
            if (body != null) {
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2042
                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
  2043
            }
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2044
            if (outer != null) {
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2045
                restoreBlock(outer);
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2046
                if (body != null) {
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2047
                    appendStatement(new BlockStatement(forLine, new Block(
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2048
                                    outer.getToken(),
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2049
                                    body.getFinish(),
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2050
                                    outer.getStatements())));
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2051
                }
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2052
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2053
        }
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  2054
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2055
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2056
    private boolean checkValidLValue(final Expression init, final String contextString) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2057
        if (init instanceof IdentNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2058
            if (!checkIdentLValue((IdentNode)init)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2059
                return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2060
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2061
            verifyIdent((IdentNode)init, contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2062
            return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2063
        } else if (init instanceof AccessNode || init instanceof IndexNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2064
            return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2065
        } else if (isDestructuringLhs(init)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2066
            verifyDestructuringAssignmentPattern(init, contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2067
            return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2068
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2069
            return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2070
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2071
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2072
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2073
    private boolean lookaheadIsLetDeclaration(final boolean ofContextualKeyword) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2074
        assert type == LET;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2075
        for (int i = 1;; i++) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2076
            TokenType t = T(k + i);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2077
            switch (t) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2078
            case EOL:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2079
            case COMMENT:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2080
                continue;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2081
            case IDENT:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2082
                if (ofContextualKeyword && isES6() && "of".equals(getValue(getToken(k + i)))) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2083
                    return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2084
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2085
                // fall through
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2086
            case LBRACKET:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2087
            case LBRACE:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2088
                return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2089
            default:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2090
                // accept future strict tokens in non-strict mode (including LET)
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2091
                if (!isStrictMode && t.getKind() == TokenKind.FUTURESTRICT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2092
                    return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2093
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2094
                return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2095
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2096
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2097
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2098
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2099
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2100
     * ...IterationStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2101
     *           ...
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2102
     *           while ( Expression ) Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2103
     *           ...
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2104
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2105
     * See 12.6
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2106
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2107
     * Parse while statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2108
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2109
    private void whileStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2110
        // Capture WHILE token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2111
        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
  2112
        final int whileLine = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2113
        // WHILE tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2114
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2115
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2116
        final ParserContextLoopNode whileNode = new ParserContextLoopNode();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2117
        lc.push(whileNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2118
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2119
        JoinPredecessorExpression test = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2120
        Block body = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2121
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2122
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2123
            expect(LPAREN);
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2124
            test = joinPredecessorExpression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2125
            expect(RPAREN);
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2126
            body = getStatement();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2127
        } finally {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2128
            lc.pop(whileNode);
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2129
        }
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2130
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2131
        if (body != null) {
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2132
            appendStatement(new WhileNode(whileLine, whileToken, body.getFinish(), false, test, body));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2133
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2134
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2135
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2136
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2137
     * ...IterationStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2138
     *           ...
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2139
     *           do Statement while( Expression ) ;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2140
     *           ...
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2141
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2142
     * See 12.6
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2143
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2144
     * Parse DO WHILE statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2145
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2146
    private void doStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2147
        // Capture DO token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2148
        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
  2149
        int doLine = 0;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2150
        // DO tested in the caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2151
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2152
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2153
        final ParserContextLoopNode doWhileNode = new ParserContextLoopNode();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2154
        lc.push(doWhileNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2155
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2156
        Block body = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2157
        JoinPredecessorExpression test = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2158
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2159
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2160
           // 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
  2161
            body = getStatement();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2162
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2163
            expect(WHILE);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2164
            expect(LPAREN);
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2165
            doLine = line;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2166
            test = joinPredecessorExpression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2167
            expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2168
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2169
            if (type == SEMICOLON) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2170
                endOfLine();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2171
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2172
        } finally {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2173
            lc.pop(doWhileNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2174
        }
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2175
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2176
        appendStatement(new WhileNode(doLine, doToken, finish, true, test, body));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2177
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2178
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2179
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2180
     * ContinueStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2181
     *      continue Identifier? ; // [no LineTerminator here]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2182
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2183
     * See 12.7
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2184
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2185
     * Parse CONTINUE statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2186
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2187
    private void continueStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2188
        // 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
  2189
        final int  continueLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2190
        final long continueToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2191
        // CONTINUE tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2192
        nextOrEOL();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2193
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2194
        ParserContextLabelNode labelNode = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2195
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2196
        // SEMICOLON or label.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2197
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2198
        case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2199
        case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2200
        case EOL:
18625
13558072545a 8019473: Parser issues related to functions and blocks
sundar
parents: 18335
diff changeset
  2201
        case EOF:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2202
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2203
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2204
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2205
            final IdentNode ident = getIdent();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2206
            labelNode = lc.findLabel(ident.getName());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2207
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2208
            if (labelNode == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2209
                throw error(AbstractParser.message("undefined.label", ident.getName()), ident.getToken());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2210
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2211
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
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2215
        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
  2216
        final ParserContextLoopNode targetNode = lc.getContinueTo(labelName);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2217
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2218
        if (targetNode == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2219
            throw error(AbstractParser.message("illegal.continue.stmt"), continueToken);
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
        endOfLine();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2223
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2224
        // Construct and add CONTINUE node.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2225
        appendStatement(new ContinueNode(continueLine, continueToken, finish, labelName));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2226
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2227
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2228
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2229
     * BreakStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2230
     *      break Identifier? ; // [no LineTerminator here]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2231
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2232
     * See 12.8
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2233
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2234
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2235
    private void breakStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2236
        // 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
  2237
        final int  breakLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2238
        final long breakToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2239
        // BREAK tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2240
        nextOrEOL();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2241
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2242
        ParserContextLabelNode labelNode = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2243
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2244
        // SEMICOLON or label.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2245
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2246
        case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2247
        case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2248
        case EOL:
18625
13558072545a 8019473: Parser issues related to functions and blocks
sundar
parents: 18335
diff changeset
  2249
        case EOF:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2250
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2251
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2252
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2253
            final IdentNode ident = getIdent();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2254
            labelNode = lc.findLabel(ident.getName());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2255
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2256
            if (labelNode == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2257
                throw error(AbstractParser.message("undefined.label", ident.getName()), ident.getToken());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2258
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2259
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2260
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2261
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2262
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2263
        //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
  2264
        //targetNode is what we are breaking out from.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2265
        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
  2266
        final ParserContextBreakableNode targetNode = lc.getBreakable(labelName);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2267
        if (targetNode == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2268
            throw error(AbstractParser.message("illegal.break.stmt"), breakToken);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2269
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2270
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2271
        endOfLine();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2272
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2273
        // Construct and add BREAK node.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2274
        appendStatement(new BreakNode(breakLine, breakToken, finish, labelName));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2275
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2276
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2277
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2278
     * ReturnStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2279
     *      return Expression? ; // [no LineTerminator here]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2280
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2281
     * See 12.9
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2282
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2283
     * Parse RETURN statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2284
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2285
    private void returnStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2286
        // check for return outside function
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2287
        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
  2288
            throw error(AbstractParser.message("invalid.return"));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2289
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2290
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2291
        // 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
  2292
        final int  returnLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2293
        final long returnToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2294
        // RETURN tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2295
        nextOrEOL();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2296
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2297
        Expression expression = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2298
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2299
        // SEMICOLON or expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2300
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2301
        case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2302
        case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2303
        case EOL:
18625
13558072545a 8019473: Parser issues related to functions and blocks
sundar
parents: 18335
diff changeset
  2304
        case EOF:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2305
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2306
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2307
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2308
            expression = expression();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2309
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2310
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2311
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2312
        endOfLine();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2313
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2314
        // 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
  2315
        appendStatement(new ReturnNode(returnLine, returnToken, finish, expression));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2316
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2317
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2318
    /**
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2319
     * Parse YieldExpression.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2320
     *
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2321
     * YieldExpression[In] :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2322
     *   yield
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2323
     *   yield [no LineTerminator here] AssignmentExpression[?In, Yield]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2324
     *   yield [no LineTerminator here] * AssignmentExpression[?In, Yield]
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2325
     */
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2326
    private Expression yieldExpression(final boolean noIn) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2327
        assert inGeneratorFunction();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2328
        // Capture YIELD token.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2329
        long yieldToken = token;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2330
        // YIELD tested in caller.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2331
        assert type == YIELD;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2332
        nextOrEOL();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2333
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2334
        Expression expression = null;
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
        boolean yieldAsterisk = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2337
        if (type == MUL) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2338
            yieldAsterisk = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2339
            yieldToken = Token.recast(yieldToken, YIELD_STAR);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2340
            next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2341
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2342
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2343
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2344
        case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2345
        case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2346
        case EOL:
18625
13558072545a 8019473: Parser issues related to functions and blocks
sundar
parents: 18335
diff changeset
  2347
        case EOF:
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2348
        case COMMARIGHT:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2349
        case RPAREN:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2350
        case RBRACKET:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2351
        case COLON:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2352
            if (!yieldAsterisk) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2353
                // treat (yield) as (yield void 0)
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2354
                expression = newUndefinedLiteral(yieldToken, finish);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2355
                if (type == EOL) {
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
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2359
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2360
                // AssignmentExpression required, fall through
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2361
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2362
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2363
        default:
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2364
            expression = assignmentExpression(noIn);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2365
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2366
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2367
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2368
        // Construct and add YIELD node.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2369
        return new UnaryNode(yieldToken, expression);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2370
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2371
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2372
    private static UnaryNode newUndefinedLiteral(final long token, final int finish) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2373
        return new UnaryNode(Token.recast(token, VOID), LiteralNode.newInstance(token, finish, 0));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2374
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2375
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2376
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2377
     * WithStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2378
     *      with ( Expression ) Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2379
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2380
     * See 12.10
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2381
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2382
     * Parse WITH statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2383
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2384
    private void withStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2385
        // 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
  2386
        final int  withLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2387
        final long withToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2388
        // WITH tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2389
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2390
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2391
        // ECMA 12.10.1 strict mode restrictions
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2392
        if (isStrictMode) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2393
            throw error(AbstractParser.message("strict.no.with"), withToken);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2394
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2395
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2396
        expect(LPAREN);
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2397
        final Expression expression = expression();
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2398
        expect(RPAREN);
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2399
        final Block body = getStatement();
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2400
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2401
        appendStatement(new WithNode(withLine, withToken, finish, expression, body));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2402
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2403
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2404
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2405
     * SwitchStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2406
     *      switch ( Expression ) CaseBlock
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2407
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2408
     * CaseBlock :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2409
     *      { CaseClauses? }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2410
     *      { CaseClauses? DefaultClause CaseClauses }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2411
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2412
     * CaseClauses :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2413
     *      CaseClause
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2414
     *      CaseClauses CaseClause
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2415
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2416
     * CaseClause :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2417
     *      case Expression : StatementList?
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2418
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2419
     * DefaultClause :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2420
     *      default : StatementList?
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2421
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2422
     * See 12.11
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2423
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2424
     * Parse SWITCH statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2425
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2426
    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
  2427
        final int  switchLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2428
        final long switchToken = token;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2429
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2430
        // Block to capture variables declared inside the switch statement.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2431
        final ParserContextBlockNode switchBlock = newBlock();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2432
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2433
        // SWITCH tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2434
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2435
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2436
        // Create and add switch statement.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2437
        final ParserContextSwitchNode switchNode = new ParserContextSwitchNode();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2438
        lc.push(switchNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2439
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2440
        CaseNode defaultCase = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2441
        // 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
  2442
        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
  2443
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2444
        Expression expression = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2445
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2446
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2447
            expect(LPAREN);
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2448
            expression = expression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2449
            expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2450
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2451
            expect(LBRACE);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2452
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2453
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2454
            while (type != RBRACE) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2455
                // Prepare for next case.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2456
                Expression caseExpression = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2457
                final long caseToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2458
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2459
                switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2460
                case CASE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2461
                    next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2462
                    caseExpression = expression();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2463
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2464
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2465
                case DEFAULT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2466
                    if (defaultCase != null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2467
                        throw error(AbstractParser.message("duplicate.default.in.switch"));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2468
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2469
                    next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2470
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2471
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2472
                default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2473
                    // Force an error.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2474
                    expect(CASE);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2475
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2476
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2477
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2478
                expect(COLON);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2479
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2480
                // Get CASE body.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2481
                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
  2482
                final CaseNode caseNode = new CaseNode(caseToken, finish, caseExpression, statements);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2483
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2484
                if (caseExpression == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2485
                    defaultCase = caseNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2486
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2487
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2488
                cases.add(caseNode);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2489
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2490
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2491
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2492
        } finally {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2493
            lc.pop(switchNode);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2494
            restoreBlock(switchBlock);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2495
        }
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2496
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2497
        final SwitchNode switchStatement = new SwitchNode(switchLine, switchToken, finish, expression, cases, defaultCase);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2498
        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
  2499
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2500
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2501
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2502
     * LabelledStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2503
     *      Identifier : Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2504
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2505
     * See 12.12
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2506
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2507
     * Parse label statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2508
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2509
    private void labelStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2510
        // Capture label token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2511
        final long labelToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2512
        // Get label ident.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2513
        final IdentNode ident = getIdent();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2514
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2515
        expect(COLON);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2516
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2517
        if (lc.findLabel(ident.getName()) != null) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2518
            throw error(AbstractParser.message("duplicate.label", ident.getName()), labelToken);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2519
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2520
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2521
        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
  2522
        Block body = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2523
        try {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2524
            lc.push(labelNode);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2525
            body = getStatement(true);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2526
        } finally {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2527
            assert lc.peek() instanceof ParserContextLabelNode;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2528
            lc.pop(labelNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2529
        }
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2530
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  2531
        appendStatement(new LabelNode(line, labelToken, finish, ident.getName(), body));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2532
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2533
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  2534
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2535
     * ThrowStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2536
     *      throw Expression ; // [no LineTerminator here]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2537
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2538
     * See 12.13
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2539
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2540
     * Parse throw statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2541
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2542
    private void throwStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2543
        // 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
  2544
        final int  throwLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2545
        final long throwToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2546
        // THROW tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2547
        nextOrEOL();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2548
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2549
        Expression expression = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2550
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2551
        // SEMICOLON or expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2552
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2553
        case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2554
        case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2555
        case EOL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2556
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2557
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2558
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2559
            expression = expression();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2560
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2561
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2562
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2563
        if (expression == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2564
            throw error(AbstractParser.message("expected.operand", type.getNameOrType()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2565
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2566
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2567
        endOfLine();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2568
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2569
        appendStatement(new ThrowNode(throwLine, throwToken, finish, expression, false));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2570
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2571
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2572
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2573
     * TryStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2574
     *      try Block Catch
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2575
     *      try Block Finally
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2576
     *      try Block Catch Finally
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2577
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2578
     * Catch :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2579
     *      catch( Identifier if Expression ) Block
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2580
     *      catch( Identifier ) Block
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2581
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2582
     * Finally :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2583
     *      finally Block
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2584
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2585
     * See 12.14
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2586
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2587
     * Parse TRY statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2588
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2589
    private void tryStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2590
        // 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
  2591
        final int  tryLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2592
        final long tryToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2593
        // TRY tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2594
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2595
16239
fbae49f786c6 8008215: break in catch clause causes java.lang.VerifyError: Inconsistent stackmap
hannesw
parents: 16237
diff changeset
  2596
        // 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
  2597
        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
  2598
        final ParserContextBlockNode outer = newBlock();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2599
        // Create try.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2600
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2601
        try {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2602
            final Block       tryBody     = getBlock(true);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2603
            final List<Block> catchBlocks = new ArrayList<>();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2604
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2605
            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
  2606
                final int  catchLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2607
                final long catchToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2608
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2609
                expect(LPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2610
                final IdentNode exception = getIdent();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2611
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2612
                // ECMA 12.4.1 strict mode restrictions
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2613
                verifyStrictIdent(exception, "catch argument");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2614
23766
a3ef17770bab 8039047: Parser accepts conditional catch clauses even when --no-syntax-extensions / -nse option is passed
sundar
parents: 23372
diff changeset
  2615
                // 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
  2616
                // 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
  2617
                // 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
  2618
                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
  2619
                if (!env._no_syntax_extensions && type == IF) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2620
                    next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2621
                    // Get the exception condition.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2622
                    ifExpression = expression();
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2623
                } else {
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2624
                    ifExpression = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2625
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2626
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2627
                expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2628
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2629
                final ParserContextBlockNode catchBlock = newBlock();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2630
                try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2631
                    // Get CATCH body.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2632
                    final Block catchBody = getBlock(true);
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2633
                    final CatchNode catchNode = new CatchNode(catchLine, catchToken, finish, exception, ifExpression, catchBody, false);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2634
                    appendStatement(catchNode);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2635
                } finally {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2636
                    restoreBlock(catchBlock);
29407
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
  2637
                    catchBlocks.add(new Block(catchBlock.getToken(), finish, catchBlock.getFlags() | Block.IS_SYNTHETIC, catchBlock.getStatements()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2638
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2639
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2640
                // If unconditional catch then should to be the end.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2641
                if (ifExpression == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2642
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2643
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2644
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2645
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2646
            // Prepare to capture finally statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2647
            Block finallyStatements = null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2648
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2649
            if (type == FINALLY) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2650
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2651
                finallyStatements = getBlock(true);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2652
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2653
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2654
            // Need at least one catch or a finally.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2655
            if (catchBlocks.isEmpty() && finallyStatements == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2656
                throw error(AbstractParser.message("missing.catch.or.finally"), tryToken);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2657
            }
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 TryNode tryNode = new TryNode(tryLine, tryToken, finish, tryBody, catchBlocks, finallyStatements);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2660
            // Add try.
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2661
            assert lc.peek() == outer;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2662
            appendStatement(tryNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2663
        } finally {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  2664
            restoreBlock(outer);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2665
        }
16239
fbae49f786c6 8008215: break in catch clause causes java.lang.VerifyError: Inconsistent stackmap
hannesw
parents: 16237
diff changeset
  2666
29407
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
  2667
        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
  2668
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2669
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2670
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2671
     * DebuggerStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2672
     *      debugger ;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2673
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2674
     * See 12.15
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2675
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2676
     * Parse debugger statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2677
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2678
    private void  debuggerStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2679
        // 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
  2680
        final int  debuggerLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2681
        final long debuggerToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2682
        // DEBUGGER tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2683
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2684
        endOfLine();
29407
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 27974
diff changeset
  2685
        appendStatement(new DebuggerNode(debuggerLine, debuggerToken, finish));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2686
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2687
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2688
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2689
     * PrimaryExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2690
     *      this
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2691
     *      IdentifierReference
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2692
     *      Literal
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2693
     *      ArrayLiteral
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2694
     *      ObjectLiteral
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  2695
     *      RegularExpressionLiteral
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  2696
     *      TemplateLiteral
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2697
     *      CoverParenthesizedExpressionAndArrowParameterList
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2698
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2699
     * CoverParenthesizedExpressionAndArrowParameterList :
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2700
     *      ( Expression )
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2701
     *      ( )
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2702
     *      ( ... BindingIdentifier )
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2703
     *      ( Expression , ... BindingIdentifier )
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2704
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2705
     * Parse primary expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2706
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2707
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2708
    @SuppressWarnings("fallthrough")
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2709
    private Expression primaryExpression() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2710
        // 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
  2711
        final int  primaryLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2712
        final long primaryToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2713
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2714
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2715
        case THIS:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2716
            final String name = type.getName();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2717
            next();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2718
            markThis(lc);
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  2719
            return new IdentNode(primaryToken, finish, name);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2720
        case IDENT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2721
            final IdentNode ident = getIdent();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2722
            if (ident == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2723
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2724
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2725
            detectSpecialProperty(ident);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2726
            return ident;
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
  2727
        case OCTAL_LEGACY:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2728
            if (isStrictMode) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2729
               throw error(AbstractParser.message("strict.no.octal"), token);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2730
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2731
        case STRING:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2732
        case ESCSTRING:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2733
        case DECIMAL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2734
        case HEXADECIMAL:
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
  2735
        case OCTAL:
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
  2736
        case BINARY_NUMBER:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2737
        case FLOATING:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2738
        case REGEX:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2739
        case XML:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2740
            return getLiteral();
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2741
        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
  2742
            return execString(primaryLine, primaryToken);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2743
        case FALSE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2744
            next();
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  2745
            return LiteralNode.newInstance(primaryToken, finish, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2746
        case TRUE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2747
            next();
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  2748
            return LiteralNode.newInstance(primaryToken, finish, true);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2749
        case NULL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2750
            next();
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  2751
            return LiteralNode.newInstance(primaryToken, finish);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2752
        case LBRACKET:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2753
            return arrayLiteral();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2754
        case LBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2755
            return objectLiteral();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2756
        case LPAREN:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2757
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2758
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2759
            if (isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2760
                if (type == RPAREN) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2761
                    // ()
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2762
                    nextOrEOL();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2763
                    expectDontAdvance(ARROW);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2764
                    return new ExpressionList(primaryToken, finish, Collections.emptyList());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2765
                } else if (type == ELLIPSIS) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2766
                    // (...rest)
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2767
                    final IdentNode restParam = formalParameterList(false).get(0);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2768
                    expectDontAdvance(RPAREN);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2769
                    nextOrEOL();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2770
                    expectDontAdvance(ARROW);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2771
                    return new ExpressionList(primaryToken, finish, Collections.singletonList(restParam));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2772
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2773
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2774
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2775
            final Expression expression = expression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2776
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2777
            expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2778
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2779
            return expression;
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  2780
        case TEMPLATE:
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  2781
        case TEMPLATE_HEAD:
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  2782
            return templateLiteral();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2783
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2784
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2785
            // 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
  2786
            if (lexer.scanLiteral(primaryToken, type, lineInfoReceiver)) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2787
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2788
                return getLiteral();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2789
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2790
            if (isNonStrictModeIdent()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2791
                return getIdent();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2792
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2793
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2794
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2795
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2796
        return null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2797
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2798
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2799
    /**
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2800
     * Convert execString to a call to $EXEC.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2801
     *
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2802
     * @param primaryToken Original string token.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2803
     * @return callNode to $EXEC.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2804
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2805
    CallNode execString(final int primaryLine, final long primaryToken) {
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2806
        // 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
  2807
        final IdentNode execIdent = new IdentNode(primaryToken, finish, ScriptingFunctions.EXEC_NAME);
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2808
        // Skip over EXECSTRING.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2809
        next();
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2810
        // Set up argument list for call.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2811
        // Skip beginning of edit string expression.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2812
        expect(LBRACE);
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2813
        // Add the following expression to arguments.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2814
        final List<Expression> arguments = Collections.singletonList(expression());
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2815
        // Skip ending of edit string expression.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2816
        expect(RBRACE);
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2817
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2818
        return new CallNode(primaryLine, primaryToken, finish, execIdent, arguments, false);
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2819
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2820
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2821
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2822
     * ArrayLiteral :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2823
     *      [ Elision? ]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2824
     *      [ ElementList ]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2825
     *      [ ElementList , Elision? ]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2826
     *      [ expression for (LeftHandExpression in expression) ( (if ( Expression ) )? ]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2827
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2828
     * ElementList : Elision? AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2829
     *      ElementList , Elision? AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2830
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2831
     * Elision :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2832
     *      ,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2833
     *      Elision ,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2834
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2835
     * See 12.1.4
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2836
     * JavaScript 1.8
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2837
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2838
     * Parse array literal.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2839
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2840
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2841
    private LiteralNode<Expression[]> arrayLiteral() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2842
        // Capture LBRACKET token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2843
        final long arrayToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2844
        // LBRACKET tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2845
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2846
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2847
        // Prepare to accumulate elements.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2848
        final List<Expression> elements = new ArrayList<>();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2849
        // Track elisions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2850
        boolean elision = true;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2851
        loop:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2852
        while (true) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2853
            long spreadToken = 0;
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  2854
            switch (type) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2855
            case RBRACKET:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2856
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2857
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2858
                break loop;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2859
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2860
            case COMMARIGHT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2861
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2862
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2863
                // If no prior expression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2864
                if (elision) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2865
                    elements.add(null);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2866
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2867
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2868
                elision = true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2869
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2870
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2871
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2872
            case ELLIPSIS:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2873
                if (isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2874
                    spreadToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2875
                    next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2876
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2877
                // fall through
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2878
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2879
            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
  2880
                if (!elision) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2881
                    throw error(AbstractParser.message("expected.comma", type.getNameOrType()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2882
                }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2883
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2884
                // Add expression element.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2885
                Expression expression = assignmentExpression(false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2886
                if (expression != null) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2887
                    if (spreadToken != 0) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2888
                        expression = new UnaryNode(Token.recast(spreadToken, SPREAD_ARRAY), expression);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2889
                    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2890
                    elements.add(expression);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2891
                } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2892
                    expect(RBRACKET);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2893
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2894
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2895
                elision = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2896
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2897
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2898
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2899
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  2900
        return LiteralNode.newInstance(arrayToken, finish, elements);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2901
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2902
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2903
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2904
     * ObjectLiteral :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2905
     *      { }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2906
     *      { PropertyNameAndValueList } { PropertyNameAndValueList , }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2907
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2908
     * PropertyNameAndValueList :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2909
     *      PropertyAssignment
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2910
     *      PropertyNameAndValueList , PropertyAssignment
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2911
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2912
     * See 11.1.5
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2913
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2914
     * Parse an object literal.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2915
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2916
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2917
    private ObjectNode objectLiteral() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2918
        // Capture LBRACE token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2919
        final long objectToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2920
        // LBRACE tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2921
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2922
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2923
        // Object context.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2924
        // Prepare to accumulate elements.
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2925
        final List<PropertyNode> elements = new ArrayList<>();
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2926
        final Map<String, Integer> map = new HashMap<>();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2927
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
  2928
        // 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
  2929
        boolean commaSeen = true;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2930
        loop:
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2931
        while (true) {
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2932
            switch (type) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2933
                case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2934
                    next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2935
                    break loop;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2936
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2937
                case COMMARIGHT:
18629
6b0b6aab4280 8019508: Comma handling in object literal parsing is wrong
sundar
parents: 18625
diff changeset
  2938
                    if (commaSeen) {
6b0b6aab4280 8019508: Comma handling in object literal parsing is wrong
sundar
parents: 18625
diff changeset
  2939
                        throw error(AbstractParser.message("expected.property.id", type.getNameOrType()));
6b0b6aab4280 8019508: Comma handling in object literal parsing is wrong
sundar
parents: 18625
diff changeset
  2940
                    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2941
                    next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2942
                    commaSeen = true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2943
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2944
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2945
                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
  2946
                    if (!commaSeen) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2947
                        throw error(AbstractParser.message("expected.comma", type.getNameOrType()));
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2948
                    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2949
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2950
                    commaSeen = false;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2951
                    // Get and add the next property.
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2952
                    final PropertyNode property = propertyAssignment();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2953
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2954
                    if (property.isComputed()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2955
                        elements.add(property);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2956
                        break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2957
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2958
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2959
                    final String key = property.getKeyName();
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2960
                    final Integer existing = map.get(key);
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2961
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2962
                    if (existing == null) {
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2963
                        map.put(key, elements.size());
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2964
                        elements.add(property);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2965
                        break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2966
                    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2967
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2968
                    final PropertyNode existingProperty = elements.get(existing);
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2969
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
  2970
                    // 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
  2971
                    // point # 4 on property assignment production
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2972
                    final Expression   value  = property.getValue();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2973
                    final FunctionNode getter = property.getGetter();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2974
                    final FunctionNode setter = property.getSetter();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2975
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2976
                    final Expression   prevValue  = existingProperty.getValue();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2977
                    final FunctionNode prevGetter = existingProperty.getGetter();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2978
                    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
  2979
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2980
                    if (!isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2981
                        checkPropertyRedefinition(property, value, getter, setter, prevValue, prevGetter, prevSetter);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2982
                    } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2983
                        if (property.getKey() instanceof IdentNode && ((IdentNode)property.getKey()).isProtoPropertyName() &&
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2984
                                        existingProperty.getKey() instanceof IdentNode && ((IdentNode)existingProperty.getKey()).isProtoPropertyName()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2985
                            throw error(AbstractParser.message("multiple.proto.key"), property.getToken());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2986
                        }
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
  2987
                    }
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
  2988
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2989
                    if (value != null || prevValue != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2990
                        map.put(key, elements.size());
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2991
                        elements.add(property);
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2992
                    } else if (getter != null) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2993
                        assert prevGetter != null || prevSetter != null;
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2994
                        elements.set(existing, existingProperty.setGetter(getter));
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2995
                    } else if (setter != null) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  2996
                        assert prevGetter != null || prevSetter != null;
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2997
                        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
  2998
                    }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2999
                    break;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3000
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3001
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3002
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  3003
        return new ObjectNode(objectToken, finish, elements);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3004
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3005
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3006
    private void checkPropertyRedefinition(final PropertyNode property, final Expression value, final FunctionNode getter, final FunctionNode setter, final Expression prevValue, final FunctionNode prevGetter, final FunctionNode prevSetter) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3007
        // ECMA 11.1.5 strict mode restrictions
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3008
        if (isStrictMode && value != null && prevValue != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3009
            throw error(AbstractParser.message("property.redefinition", property.getKeyName()), property.getToken());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3010
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3011
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3012
        final boolean isPrevAccessor = prevGetter != null || prevSetter != null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3013
        final boolean isAccessor     = getter != null     || setter != null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3014
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3015
        // data property redefined as accessor property
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3016
        if (prevValue != null && isAccessor) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3017
            throw error(AbstractParser.message("property.redefinition", property.getKeyName()), property.getToken());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3018
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3019
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3020
        // accessor property redefined as data
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3021
        if (isPrevAccessor && value != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3022
            throw error(AbstractParser.message("property.redefinition", property.getKeyName()), property.getToken());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3023
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3024
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3025
        if (isAccessor && isPrevAccessor) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3026
            if (getter != null && prevGetter != null ||
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3027
                    setter != null && prevSetter != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3028
                throw error(AbstractParser.message("property.redefinition", property.getKeyName()), property.getToken());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3029
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3030
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3031
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3032
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3033
    /**
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3034
     * LiteralPropertyName :
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3035
     *      IdentifierName
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3036
     *      StringLiteral
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3037
     *      NumericLiteral
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3038
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3039
     * @return PropertyName node
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3040
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3041
    @SuppressWarnings("fallthrough")
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3042
    private PropertyKey literalPropertyName() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3043
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3044
        case IDENT:
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3045
            return getIdent().setIsPropertyName();
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
  3046
        case OCTAL_LEGACY:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3047
            if (isStrictMode) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3048
                throw error(AbstractParser.message("strict.no.octal"), token);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3049
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3050
        case STRING:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3051
        case ESCSTRING:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3052
        case DECIMAL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3053
        case HEXADECIMAL:
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
  3054
        case OCTAL:
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
  3055
        case BINARY_NUMBER:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3056
        case FLOATING:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3057
            return getLiteral();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3058
        default:
19883
aae0838ac6ee 8024255: When a keyword is used as object property name, the property can not be deleted
sundar
parents: 19472
diff changeset
  3059
            return getIdentifierName().setIsPropertyName();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3060
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3061
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3062
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3063
    /**
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3064
     * ComputedPropertyName :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3065
     *      AssignmentExpression
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3066
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3067
     * @return PropertyName node
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3068
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3069
    private Expression computedPropertyName() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3070
        expect(LBRACKET);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3071
        Expression expression = assignmentExpression(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3072
        expect(RBRACKET);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3073
        return expression;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3074
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3075
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3076
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3077
     * PropertyName :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3078
     *      LiteralPropertyName
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3079
     *      ComputedPropertyName
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3080
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3081
     * @return PropertyName node
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3082
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3083
    private Expression propertyName() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3084
        if (type == LBRACKET && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3085
            return computedPropertyName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3086
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3087
            return (Expression)literalPropertyName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3088
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3089
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3090
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3091
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3092
     * PropertyAssignment :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3093
     *      PropertyName : AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3094
     *      get PropertyName ( ) { FunctionBody }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3095
     *      set PropertyName ( PropertySetParameterList ) { FunctionBody }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3096
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3097
     * PropertySetParameterList :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3098
     *      Identifier
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3099
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3100
     * PropertyName :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3101
     *      IdentifierName
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3102
     *      StringLiteral
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3103
     *      NumericLiteral
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3104
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3105
     * See 11.1.5
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3106
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3107
     * Parse an object literal property.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3108
     * @return Property or reference node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3109
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3110
    private PropertyNode propertyAssignment() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3111
        // Capture firstToken.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3112
        final long propertyToken = token;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3113
        final int  functionLine  = line;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3114
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3115
        final Expression propertyName;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3116
        final boolean isIdentifier;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3117
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3118
        boolean generator = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3119
        if (type == MUL && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3120
            generator = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3121
            next();
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
        final boolean computed = type == LBRACKET;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3125
        if (type == IDENT) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3126
            // Get IDENT.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3127
            final String ident = (String)expectValue(IDENT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3128
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3129
            if (type != COLON && (type != LPAREN || !isES6())) {
20938
e92d8249f60c 8026302: source representation of getter and setter methods is wrong
sundar
parents: 20934
diff changeset
  3130
                final long getSetToken = propertyToken;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3131
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3132
                switch (ident) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3133
                case "get":
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3134
                    final PropertyFunction getter = propertyGetterFunction(getSetToken, functionLine);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3135
                    return new PropertyNode(propertyToken, finish, getter.key, null, getter.functionNode, null, false, getter.computed);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3136
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3137
                case "set":
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3138
                    final PropertyFunction setter = propertySetterFunction(getSetToken, functionLine);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3139
                    return new PropertyNode(propertyToken, finish, setter.key, null, null, setter.functionNode, false, setter.computed);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3140
                default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3141
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3142
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3143
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3144
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3145
            isIdentifier = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3146
            IdentNode identNode = createIdentNode(propertyToken, finish, ident).setIsPropertyName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3147
            if (type == COLON && ident.equals("__proto__")) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3148
                identNode = identNode.setIsProtoPropertyName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3149
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3150
            propertyName = identNode;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3151
        } else {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3152
            isIdentifier = isNonStrictModeIdent();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3153
            propertyName = propertyName();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3154
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3155
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3156
        Expression propertyValue;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3157
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3158
        if (generator) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3159
            expectDontAdvance(LPAREN);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3160
        }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3161
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3162
        if (type == LPAREN && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3163
            propertyValue = propertyMethodFunction(propertyName, propertyToken, functionLine, generator, FunctionNode.ES6_IS_METHOD, computed).functionNode;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3164
        } else if (isIdentifier && (type == COMMARIGHT || type == RBRACE || type == ASSIGN) && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3165
            propertyValue = createIdentNode(propertyToken, finish, ((IdentNode) propertyName).getPropertyName());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3166
            if (type == ASSIGN && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3167
                // TODO if not destructuring, this is a SyntaxError
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3168
                final long assignToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3169
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3170
                final Expression rhs = assignmentExpression(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3171
                propertyValue = verifyAssignment(assignToken, propertyValue, rhs);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3172
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3173
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3174
            expect(COLON);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3175
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3176
            defaultNames.push(propertyName);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3177
            try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3178
                propertyValue = assignmentExpression(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3179
            } finally {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3180
                defaultNames.pop();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3181
            }
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
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3184
        return new PropertyNode(propertyToken, finish, propertyName, propertyValue, null, null, false, computed);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3185
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3186
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3187
    private PropertyFunction propertyGetterFunction(final long getSetToken, final int functionLine) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3188
        return propertyGetterFunction(getSetToken, functionLine, FunctionNode.ES6_IS_METHOD);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3189
    }
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
    private PropertyFunction propertyGetterFunction(final long getSetToken, final int functionLine, final int flags) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3192
        final boolean computed = type == LBRACKET;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3193
        final Expression propertyName = propertyName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3194
        final String getterName = propertyName instanceof PropertyKey ? ((PropertyKey) propertyName).getPropertyName() : getDefaultValidFunctionName(functionLine, false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3195
        final IdentNode getNameNode = createIdentNode((propertyName).getToken(), finish, NameCodec.encode("get " + getterName));
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3196
        expect(LPAREN);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3197
        expect(RPAREN);
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3198
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3199
        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
  3200
        functionNode.setFlag(flags);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3201
        if (computed) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3202
            functionNode.setFlag(FunctionNode.IS_ANONYMOUS);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3203
        }
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3204
        lc.push(functionNode);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3205
27819
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3206
        Block functionBody;
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3207
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3208
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3209
        try {
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3210
            functionBody = functionBody(functionNode);
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3211
        } finally {
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3212
            lc.pop(functionNode);
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3213
        }
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3214
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3215
        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
  3216
                functionNode,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3217
                getSetToken,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3218
                getNameNode,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3219
                Collections.<IdentNode>emptyList(),
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3220
                FunctionNode.Kind.GETTER,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3221
                functionLine,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3222
                functionBody);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3223
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3224
        return new PropertyFunction(propertyName, function, computed);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3225
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3226
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3227
    private PropertyFunction propertySetterFunction(final long getSetToken, final int functionLine) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3228
        return propertySetterFunction(getSetToken, functionLine, FunctionNode.ES6_IS_METHOD);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3229
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3230
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3231
    private PropertyFunction propertySetterFunction(final long getSetToken, final int functionLine, final int flags) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3232
        final boolean computed = type == LBRACKET;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3233
        final Expression propertyName = propertyName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3234
        final String setterName = propertyName instanceof PropertyKey ? ((PropertyKey) propertyName).getPropertyName() : getDefaultValidFunctionName(functionLine, false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3235
        final IdentNode setNameNode = createIdentNode((propertyName).getToken(), finish, NameCodec.encode("set " + setterName));
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3236
        expect(LPAREN);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3237
        // be sloppy and allow missing setter parameter even though
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3238
        // spec does not permit it!
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3239
        final IdentNode argIdent;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3240
        if (isBindingIdentifier()) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3241
            argIdent = getIdent();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3242
            verifyIdent(argIdent, "setter argument");
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3243
        } else {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3244
            argIdent = null;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3245
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3246
        expect(RPAREN);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3247
        final List<IdentNode> parameters = new ArrayList<>();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3248
        if (argIdent != null) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3249
            parameters.add(argIdent);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3250
        }
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3251
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3252
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3253
        final ParserContextFunctionNode functionNode = createParserContextFunctionNode(setNameNode, getSetToken, FunctionNode.Kind.SETTER, functionLine, parameters);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3254
        functionNode.setFlag(flags);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3255
        if (computed) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3256
            functionNode.setFlag(FunctionNode.IS_ANONYMOUS);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3257
        }
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3258
        lc.push(functionNode);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3259
27819
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3260
        Block functionBody;
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3261
        try {
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3262
            functionBody = functionBody(functionNode);
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3263
        } finally {
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3264
            lc.pop(functionNode);
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3265
        }
74baae50e5cd 8066238: AssertionError in parser when syntax errors appeared in non finished Blocks
lagergren
parents: 27817
diff changeset
  3266
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3267
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3268
        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
  3269
                functionNode,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3270
                getSetToken,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3271
                setNameNode,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3272
                parameters,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3273
                FunctionNode.Kind.SETTER,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3274
                functionLine,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3275
                functionBody);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3276
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3277
        return new PropertyFunction(propertyName, function, computed);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3278
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3279
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3280
    private PropertyFunction propertyMethodFunction(Expression key, final long methodToken, final int methodLine, final boolean generator, final int flags, boolean computed) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3281
        final String methodName = key instanceof PropertyKey ? ((PropertyKey) key).getPropertyName() : getDefaultValidFunctionName(methodLine, false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3282
        final IdentNode methodNameNode = createIdentNode(((Node)key).getToken(), finish, methodName);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3283
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3284
        FunctionNode.Kind functionKind = generator ? FunctionNode.Kind.GENERATOR : FunctionNode.Kind.NORMAL;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3285
        final ParserContextFunctionNode functionNode = createParserContextFunctionNode(methodNameNode, methodToken, functionKind, methodLine, null);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3286
        functionNode.setFlag(flags);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3287
        if (computed) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3288
            functionNode.setFlag(FunctionNode.IS_ANONYMOUS);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3289
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3290
        lc.push(functionNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3291
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3292
        try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3293
            final ParserContextBlockNode parameterBlock = newBlock();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3294
            final List<IdentNode> parameters;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3295
            try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3296
                expect(LPAREN);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3297
                parameters = formalParameterList(generator);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3298
                functionNode.setParameters(parameters);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3299
                expect(RPAREN);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3300
            } finally {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3301
                restoreBlock(parameterBlock);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3302
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3303
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3304
            Block functionBody = functionBody(functionNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3305
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3306
            functionBody = maybeWrapBodyInParameterBlock(functionBody, parameterBlock);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3307
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3308
            final FunctionNode  function = createFunctionNode(
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3309
                            functionNode,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3310
                            methodToken,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3311
                            methodNameNode,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3312
                            parameters,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3313
                            functionKind,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3314
                            methodLine,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3315
                            functionBody);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3316
            return new PropertyFunction(key, function, computed);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3317
        } finally {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3318
            lc.pop(functionNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3319
        }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3320
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3321
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3322
    private static class PropertyFunction {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3323
        final Expression key;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3324
        final FunctionNode functionNode;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3325
        final boolean computed;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3326
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3327
        PropertyFunction(final Expression key, final FunctionNode function, final boolean computed) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3328
            this.key = key;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3329
            this.functionNode = function;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3330
            this.computed = computed;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3331
        }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3332
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3333
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3334
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3335
     * LeftHandSideExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3336
     *      NewExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3337
     *      CallExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3338
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3339
     * CallExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3340
     *      MemberExpression Arguments
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3341
     *      SuperCall
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3342
     *      CallExpression Arguments
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3343
     *      CallExpression [ Expression ]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3344
     *      CallExpression . IdentifierName
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3345
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3346
     * SuperCall :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3347
     *      super Arguments
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3348
     *
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3349
     * See 11.2
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3350
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3351
     * Parse left hand side expression.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3352
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3353
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3354
    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
  3355
        int  callLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3356
        long callToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3357
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3358
        Expression lhs = memberExpression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3359
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3360
        if (type == LPAREN) {
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3361
            final List<Expression> arguments = optimizeList(argumentList());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3362
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3363
            // Catch special functions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3364
            if (lhs instanceof IdentNode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3365
                detectSpecialFunction((IdentNode)lhs);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3366
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3367
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3368
            lhs = new CallNode(callLine, callToken, finish, lhs, arguments, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3369
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3370
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3371
        loop:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3372
        while (true) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3373
            // 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
  3374
            callLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3375
            callToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3376
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3377
            switch (type) {
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3378
            case LPAREN: {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3379
                // Get NEW or FUNCTION arguments.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3380
                final List<Expression> arguments = optimizeList(argumentList());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3381
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3382
                // Create call node.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3383
                lhs = new CallNode(callLine, callToken, finish, lhs, arguments, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3384
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3385
                break;
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3386
            }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3387
            case LBRACKET: {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3388
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3389
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3390
                // Get array index.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3391
                final Expression rhs = expression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3392
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3393
                expect(RBRACKET);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3394
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3395
                // Create indexing node.
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  3396
                lhs = new IndexNode(callToken, finish, lhs, rhs);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3397
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3398
                break;
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3399
            }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3400
            case PERIOD: {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3401
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3402
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3403
                final IdentNode property = getIdentifierName();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3404
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3405
                // Create property access node.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3406
                lhs = new AccessNode(callToken, finish, lhs, property.getName());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3407
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3408
                break;
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3409
            }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3410
            case TEMPLATE:
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3411
            case TEMPLATE_HEAD: {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3412
                // tagged template literal
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3413
                final List<Expression> arguments = templateLiteralArgumentList();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3414
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3415
                // Create call node.
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3416
                lhs = new CallNode(callLine, callToken, finish, lhs, arguments, false);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3417
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3418
                break;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3419
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3420
            default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3421
                break loop;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3422
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3423
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3424
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3425
        return lhs;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3426
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3427
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3428
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3429
     * NewExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3430
     *      MemberExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3431
     *      new NewExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3432
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3433
     * See 11.2
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3434
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3435
     * Parse new expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3436
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3437
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3438
    private Expression newExpression() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3439
        final long newToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3440
        // NEW is tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3441
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3442
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3443
        if (type == PERIOD && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3444
            next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3445
            if (type == IDENT && "target".equals(getValue())) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3446
                if (lc.getCurrentFunction().isProgram()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3447
                    throw error(AbstractParser.message("new.target.in.function"), token);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3448
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3449
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3450
                markNewTarget(lc);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3451
                return new IdentNode(newToken, finish, "new.target");
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3452
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3453
                throw error(AbstractParser.message("expected.target"), token);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3454
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3455
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3456
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3457
        // 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
  3458
        final int  callLine    = line;
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3459
        final Expression constructor = memberExpression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3460
        if (constructor == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3461
            return null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3462
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3463
        // Get arguments.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3464
        ArrayList<Expression> arguments;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3465
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3466
        // Allow for missing arguments.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3467
        if (type == LPAREN) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3468
            arguments = argumentList();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3469
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3470
            arguments = new ArrayList<>();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3471
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3472
16196
58f6f046bb5e 8006983: Introduce a command line option to switch off syntactic extensions of nashorn
sundar
parents: 16191
diff changeset
  3473
        // 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
  3474
        // syntax:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3475
        //
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3476
        //     var r = new java.lang.Runnable() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3477
        //         run: function() { println("run"); }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3478
        //     };
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3479
        //
32534
b3ec7f3b3c2a 8136349: Typos patch for nashorn sources submitted on Sep 10, 2015
sundar
parents: 32444
diff changeset
  3480
        // The object literal following the "new Constructor()" expression
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3481
        // 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
  3482
        if (!env._no_syntax_extensions && type == LBRACE) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3483
            arguments.add(objectLiteral());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3484
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3485
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3486
        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
  3487
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  3488
        return new UnaryNode(newToken, callNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3489
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3490
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3491
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3492
     * MemberExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3493
     *      PrimaryExpression
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3494
     *        FunctionExpression
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3495
     *        ClassExpression
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3496
     *        GeneratorExpression
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3497
     *      MemberExpression [ Expression ]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3498
     *      MemberExpression . IdentifierName
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3499
     *      MemberExpression TemplateLiteral
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3500
     *      SuperProperty
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3501
     *      MetaProperty
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3502
     *      new MemberExpression Arguments
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3503
     *
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3504
     * SuperProperty :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3505
     *      super [ Expression ]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3506
     *      super . IdentifierName
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3507
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3508
     * MetaProperty :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3509
     *      NewTarget
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3510
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3511
     * Parse member expression.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3512
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3513
     */
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3514
    @SuppressWarnings("fallthrough")
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3515
    private Expression memberExpression() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3516
        // Prepare to build operation.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3517
        Expression lhs;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3518
        boolean isSuper = false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3519
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3520
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3521
        case NEW:
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3522
            // Get new expression.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3523
            lhs = newExpression();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3524
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3525
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3526
        case FUNCTION:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3527
            // Get function expression.
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  3528
            lhs = functionExpression(false, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3529
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3530
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3531
        case CLASS:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3532
            if (isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3533
                lhs = classExpression(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3534
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3535
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3536
                // fall through
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3537
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3538
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3539
        case SUPER:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3540
            if (isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3541
                final ParserContextFunctionNode currentFunction = getCurrentNonArrowFunction();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3542
                if (currentFunction.isMethod()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3543
                    long identToken = Token.recast(token, IDENT);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3544
                    next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3545
                    lhs = createIdentNode(identToken, finish, SUPER.getName());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3546
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3547
                    switch (type) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3548
                        case LBRACKET:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3549
                        case PERIOD:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3550
                            getCurrentNonArrowFunction().setFlag(FunctionNode.ES6_USES_SUPER);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3551
                            isSuper = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3552
                            break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3553
                        case LPAREN:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3554
                            if (currentFunction.isSubclassConstructor()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3555
                                lhs = ((IdentNode)lhs).setIsDirectSuper();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3556
                                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3557
                            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3558
                                // fall through to throw error
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3559
                            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3560
                        default:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3561
                            throw error(AbstractParser.message("invalid.super"), identToken);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3562
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3563
                    break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3564
                } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3565
                    // fall through
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3566
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3567
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3568
                // fall through
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3569
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3570
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3571
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3572
            // Get primary expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3573
            lhs = primaryExpression();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3574
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3575
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3576
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3577
        loop:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3578
        while (true) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3579
            // Capture token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3580
            final long callToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3581
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3582
            switch (type) {
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  3583
            case LBRACKET: {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3584
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3585
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3586
                // Get array index.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3587
                final Expression index = expression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3588
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3589
                expect(RBRACKET);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3590
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3591
                // Create indexing node.
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  3592
                lhs = new IndexNode(callToken, finish, lhs, index);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3593
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3594
                if (isSuper) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3595
                    isSuper = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3596
                    lhs = ((BaseNode) lhs).setIsSuper();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3597
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3598
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3599
                break;
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  3600
            }
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  3601
            case PERIOD: {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3602
                if (lhs == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3603
                    throw error(AbstractParser.message("expected.operand", type.getNameOrType()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3604
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3605
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3606
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3607
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3608
                final IdentNode property = getIdentifierName();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3609
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3610
                // Create property access node.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3611
                lhs = new AccessNode(callToken, finish, lhs, property.getName());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3612
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3613
                if (isSuper) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3614
                    isSuper = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3615
                    lhs = ((BaseNode) lhs).setIsSuper();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3616
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3617
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3618
                break;
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  3619
            }
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3620
            case TEMPLATE:
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3621
            case TEMPLATE_HEAD: {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3622
                // tagged template literal
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3623
                final int callLine = line;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3624
                final List<Expression> arguments = templateLiteralArgumentList();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3625
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3626
                lhs = new CallNode(callLine, callToken, finish, lhs, arguments, false);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3627
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3628
                break;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  3629
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3630
            default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3631
                break loop;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3632
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3633
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3634
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3635
        return lhs;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3636
    }
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
     * Arguments :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3640
     *      ( )
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3641
     *      ( ArgumentList )
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3642
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3643
     * ArgumentList :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3644
     *      AssignmentExpression
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3645
     *      ... AssignmentExpression
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3646
     *      ArgumentList , AssignmentExpression
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3647
     *      ArgumentList , ... AssignmentExpression
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3648
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3649
     * See 11.2
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3650
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3651
     * Parse function call arguments.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3652
     * @return Argument list.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3653
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3654
    private ArrayList<Expression> argumentList() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3655
        // Prepare to accumulate list of arguments.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3656
        final ArrayList<Expression> nodeList = new ArrayList<>();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3657
        // LPAREN tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3658
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3659
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3660
        // Track commas.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3661
        boolean first = true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3662
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3663
        while (type != RPAREN) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3664
            // Comma prior to every argument except the first.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3665
            if (!first) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3666
                expect(COMMARIGHT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3667
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3668
                first = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3669
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3670
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3671
            long spreadToken = 0;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3672
            if (type == ELLIPSIS && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3673
                spreadToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3674
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3675
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3676
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3677
            // Get argument expression.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3678
            Expression expression = assignmentExpression(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3679
            if (spreadToken != 0) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3680
                expression = new UnaryNode(Token.recast(spreadToken, TokenType.SPREAD_ARGUMENT), expression);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3681
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3682
            nodeList.add(expression);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3683
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3684
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3685
        expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3686
        return nodeList;
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3687
    }
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3688
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
  3689
    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
  3690
        switch(list.size()) {
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3691
            case 0: {
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3692
                return Collections.emptyList();
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3693
            }
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3694
            case 1: {
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3695
                return Collections.singletonList(list.get(0));
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3696
            }
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3697
            default: {
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3698
                list.trimToSize();
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3699
                return list;
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3700
            }
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3701
        }
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3702
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3703
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3704
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3705
     * FunctionDeclaration :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3706
     *      function Identifier ( FormalParameterList? ) { FunctionBody }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3707
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3708
     * FunctionExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3709
     *      function Identifier? ( FormalParameterList? ) { FunctionBody }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3710
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3711
     * See 13
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3712
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3713
     * Parse function declaration.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3714
     * @param isStatement True if for is a statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3715
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3716
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3717
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3718
    private Expression functionExpression(final boolean isStatement, final boolean topLevel) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3719
        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
  3720
        final int  functionLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3721
        // FUNCTION is tested in caller.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3722
        assert type == FUNCTION;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3723
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3724
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3725
        boolean generator = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3726
        if (type == MUL && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3727
            generator = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3728
            next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3729
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3730
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3731
        IdentNode name = null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3732
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3733
        if (isBindingIdentifier()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3734
            if (type == YIELD && ((!isStatement && generator) || (isStatement && inGeneratorFunction()))) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3735
                // 12.1.1 Early SyntaxError if:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3736
                // GeneratorExpression with BindingIdentifier yield
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3737
                // HoistableDeclaration with BindingIdentifier yield in generator function body
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3738
                expect(IDENT);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3739
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3740
            name = getIdent();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3741
            verifyStrictIdent(name, "function name");
16196
58f6f046bb5e 8006983: Introduce a command line option to switch off syntactic extensions of nashorn
sundar
parents: 16191
diff changeset
  3742
        } else if (isStatement) {
31095
790fc3d576f9 8085802: Nashorn -nse option causes parse error on anonymous function definition
sundar
parents: 30392
diff changeset
  3743
            // Nashorn extension: anonymous function statements.
790fc3d576f9 8085802: Nashorn -nse option causes parse error on anonymous function definition
sundar
parents: 30392
diff changeset
  3744
            // 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
  3745
            // 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
  3746
            // 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
  3747
            // expression in surrounding code.
790fc3d576f9 8085802: Nashorn -nse option causes parse error on anonymous function definition
sundar
parents: 30392
diff changeset
  3748
            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
  3749
                expect(IDENT);
58f6f046bb5e 8006983: Introduce a command line option to switch off syntactic extensions of nashorn
sundar
parents: 16191
diff changeset
  3750
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3751
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3752
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3753
        // name is null, generate anonymous name
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3754
        boolean isAnonymous = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3755
        if (name == null) {
27974
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3756
            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
  3757
            name = new IdentNode(functionToken, Token.descPosition(functionToken), tmpName);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3758
            isAnonymous = true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3759
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3760
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3761
        FunctionNode.Kind functionKind = generator ? FunctionNode.Kind.GENERATOR : FunctionNode.Kind.NORMAL;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3762
        List<IdentNode> parameters = Collections.emptyList();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3763
        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
  3764
        lc.push(functionNode);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3765
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3766
        Block functionBody = null;
27974
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3767
        // 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
  3768
        // 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
  3769
        hideDefaultName();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3770
        try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3771
            final ParserContextBlockNode parameterBlock = newBlock();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3772
            try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3773
                expect(LPAREN);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3774
                parameters = formalParameterList(generator);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3775
                functionNode.setParameters(parameters);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3776
                expect(RPAREN);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3777
            } finally {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3778
                restoreBlock(parameterBlock);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3779
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3780
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3781
            functionBody = functionBody(functionNode);
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3782
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3783
            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
  3784
        } finally {
27974
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3785
            defaultNames.pop();
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3786
            lc.pop(functionNode);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3787
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3788
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  3789
        if (isStatement) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3790
            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
  3791
                functionNode.setFlag(FunctionNode.IS_DECLARED);
17257
a2232050cd8f 8008814: Configurable ignore/warning/error behavior for function declaration as statement
attila
parents: 17255
diff changeset
  3792
            } else if (isStrictMode) {
a2232050cd8f 8008814: Configurable ignore/warning/error behavior for function declaration as statement
attila
parents: 17255
diff changeset
  3793
                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
  3794
            } 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
  3795
                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
  3796
            } 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
  3797
                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
  3798
            }
19898
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
  3799
            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
  3800
               lc.getCurrentFunction().setFlag(FunctionNode.DEFINES_ARGUMENTS);
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
  3801
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3802
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3803
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3804
        if (isAnonymous) {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3805
            functionNode.setFlag(FunctionNode.IS_ANONYMOUS);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3806
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3807
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3808
        verifyParameterList(parameters, functionNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3809
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3810
        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
  3811
                functionNode,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3812
                functionToken,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3813
                name,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3814
                parameters,
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3815
                functionKind,
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3816
                functionLine,
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3817
                functionBody);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3818
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3819
        if (isStatement) {
31485
be1acaee8e9e 8114838: Anonymous functions escape to surrounding scope when defined under "with" statement
sundar
parents: 31095
diff changeset
  3820
            if (isAnonymous) {
be1acaee8e9e 8114838: Anonymous functions escape to surrounding scope when defined under "with" statement
sundar
parents: 31095
diff changeset
  3821
                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
  3822
                return function;
be1acaee8e9e 8114838: Anonymous functions escape to surrounding scope when defined under "with" statement
sundar
parents: 31095
diff changeset
  3823
            }
be1acaee8e9e 8114838: Anonymous functions escape to surrounding scope when defined under "with" statement
sundar
parents: 31095
diff changeset
  3824
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  3825
            // mark ES6 block functions as lexically scoped
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  3826
            final int     varFlags = (topLevel || !useBlockScope()) ? 0 : VarNode.IS_LET;
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27814
diff changeset
  3827
            final VarNode varNode  = new VarNode(functionLine, functionToken, finish, name, function, varFlags);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3828
            if (topLevel) {
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  3829
                functionDeclarations.add(varNode);
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  3830
            } else if (useBlockScope()) {
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  3831
                prependStatement(varNode); // Hoist to beginning of current block
16191
7dd981da8e11 8006755: Functions inside with statements dont get correct scope
sundar
parents: 16187
diff changeset
  3832
            } else {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3833
                appendStatement(varNode);
16191
7dd981da8e11 8006755: Functions inside with statements dont get correct scope
sundar
parents: 16187
diff changeset
  3834
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3835
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3836
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  3837
        return function;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3838
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3839
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3840
    private void verifyParameterList(final List<IdentNode> parameters, final ParserContextFunctionNode functionNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3841
        final IdentNode duplicateParameter = functionNode.getDuplicateParameterBinding();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3842
        if (duplicateParameter != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3843
            if (functionNode.isStrict() || functionNode.getKind() == FunctionNode.Kind.ARROW || !functionNode.isSimpleParameterList()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3844
                throw error(AbstractParser.message("strict.param.redefinition", duplicateParameter.getName()), duplicateParameter.getToken());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3845
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3846
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3847
            final int arity = parameters.size();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3848
            final HashSet<String> parametersSet = new HashSet<>(arity);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3849
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3850
            for (int i = arity - 1; i >= 0; i--) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3851
                final IdentNode parameter = parameters.get(i);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3852
                String parameterName = parameter.getName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3853
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3854
                if (parametersSet.contains(parameterName)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3855
                    // redefinition of parameter name, rename in non-strict mode
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3856
                    parameterName = functionNode.uniqueName(parameterName);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3857
                    final long parameterToken = parameter.getToken();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3858
                    parameters.set(i, new IdentNode(parameterToken, Token.descPosition(parameterToken), functionNode.uniqueName(parameterName)));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3859
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3860
                parametersSet.add(parameterName);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3861
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3862
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3863
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3864
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3865
    private static Block maybeWrapBodyInParameterBlock(Block functionBody, ParserContextBlockNode parameterBlock) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3866
        assert functionBody.isFunctionBody();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3867
        if (!parameterBlock.getStatements().isEmpty()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3868
            parameterBlock.appendStatement(new BlockStatement(functionBody));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3869
            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
  3870
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3871
        return functionBody;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3872
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3873
27974
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3874
    private String getDefaultValidFunctionName(final int functionLine, final boolean isStatement) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3875
        final String defaultFunctionName = getDefaultFunctionName();
27974
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3876
        if (isValidIdentifier(defaultFunctionName)) {
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3877
            if (isStatement) {
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3878
                // 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
  3879
                // 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
  3880
                return ANON_FUNCTION_PREFIX.symbolName() + defaultFunctionName;
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3881
            }
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3882
            return defaultFunctionName;
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3883
        }
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3884
        return ANON_FUNCTION_PREFIX.symbolName() + functionLine;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3885
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3886
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
  3887
    private static boolean isValidIdentifier(final String name) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3888
        if (name == null || name.isEmpty()) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3889
            return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3890
        }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3891
        if (!Character.isJavaIdentifierStart(name.charAt(0))) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3892
            return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3893
        }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3894
        for (int i = 1; i < name.length(); ++i) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3895
            if (!Character.isJavaIdentifierPart(name.charAt(i))) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3896
                return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3897
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3898
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3899
        return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3900
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3901
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3902
    private String getDefaultFunctionName() {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3903
        if (!defaultNames.isEmpty()) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3904
            final Object nameExpr = defaultNames.peek();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3905
            if (nameExpr instanceof PropertyKey) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3906
                markDefaultNameUsed();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3907
                return ((PropertyKey)nameExpr).getPropertyName();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3908
            } else if (nameExpr instanceof AccessNode) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3909
                markDefaultNameUsed();
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3910
                return ((AccessNode)nameExpr).getProperty();
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3911
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3912
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3913
        return null;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3914
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3915
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3916
    private void markDefaultNameUsed() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3917
        defaultNames.pop();
27974
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3918
        hideDefaultName();
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3919
    }
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3920
4eca5d2c0088 8066221: anonymous function statement name clashes with another symbol
attila
parents: 27819
diff changeset
  3921
    private void hideDefaultName() {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3922
        // 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
  3923
        // from. Can't be null
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3924
        defaultNames.push("");
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3925
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3926
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3927
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3928
     * FormalParameterList :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3929
     *      Identifier
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3930
     *      FormalParameterList , Identifier
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3931
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3932
     * See 13
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3933
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3934
     * Parse function parameter list.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3935
     * @return List of parameter nodes.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3936
     */
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3937
    private List<IdentNode> formalParameterList(final boolean yield) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3938
        return formalParameterList(RPAREN, yield);
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3939
    }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3940
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3941
    /**
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3942
     * 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
  3943
     * token type expected is passed as argument to this method.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3944
     *
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3945
     * FormalParameterList :
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3946
     *      Identifier
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3947
     *      FormalParameterList , Identifier
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3948
     *
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3949
     * See 13
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3950
     *
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3951
     * Parse function parameter list.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3952
     * @return List of parameter nodes.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3953
     */
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3954
    private List<IdentNode> formalParameterList(final TokenType endType, final boolean yield) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3955
        // Prepare to gather parameters.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3956
        final ArrayList<IdentNode> parameters = new ArrayList<>();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3957
        // Track commas.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3958
        boolean first = true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3959
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  3960
        while (type != endType) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3961
            // Comma prior to every argument except the first.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3962
            if (!first) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3963
                expect(COMMARIGHT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3964
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3965
                first = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3966
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3967
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3968
            boolean restParameter = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3969
            if (type == ELLIPSIS && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3970
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3971
                restParameter = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3972
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3973
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3974
            if (type == YIELD && yield) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3975
                expect(IDENT);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3976
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3977
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3978
            final long paramToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3979
            final int paramLine = line;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3980
            final String contextString = "function parameter";
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3981
            IdentNode ident;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3982
            if (isBindingIdentifier() || restParameter || !isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3983
                ident = bindingIdentifier(contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3984
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3985
                if (restParameter) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3986
                    ident = ident.setIsRestParameter();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3987
                    // rest parameter must be last
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3988
                    expectDontAdvance(endType);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3989
                    parameters.add(ident);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3990
                    break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3991
                } else if (type == ASSIGN && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3992
                    next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3993
                    ident = ident.setIsDefaultParameter();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3994
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3995
                    if (type == YIELD && yield) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3996
                        // error: yield in default expression
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3997
                        expect(IDENT);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3998
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  3999
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4000
                    // default parameter
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4001
                    Expression initializer = assignmentExpression(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4002
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4003
                    ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4004
                    if (currentFunction != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4005
                        // desugar to: param = (param === undefined) ? initializer : param;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4006
                        // possible alternative: if (param === undefined) param = initializer;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4007
                        BinaryNode test = new BinaryNode(Token.recast(paramToken, EQ_STRICT), ident, newUndefinedLiteral(paramToken, finish));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4008
                        TernaryNode value = new TernaryNode(Token.recast(paramToken, TERNARY), test, new JoinPredecessorExpression(initializer), new JoinPredecessorExpression(ident));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4009
                        BinaryNode assignment = new BinaryNode(Token.recast(paramToken, ASSIGN), ident, value);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4010
                        lc.getFunctionBody(currentFunction).appendStatement(new ExpressionStatement(paramLine, assignment.getToken(), assignment.getFinish(), assignment));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4011
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4012
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4013
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4014
                ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4015
                if (currentFunction != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4016
                    currentFunction.addParameterBinding(ident);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4017
                    if (ident.isRestParameter() || ident.isDefaultParameter()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4018
                        currentFunction.setSimpleParameterList(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4019
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4020
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4021
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4022
                final Expression pattern = bindingPattern();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4023
                // Introduce synthetic temporary parameter to capture the object to be destructured.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4024
                ident = createIdentNode(paramToken, pattern.getFinish(), String.format("arguments[%d]", parameters.size())).setIsDestructuredParameter();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4025
                verifyDestructuringParameterBindingPattern(pattern, paramToken, paramLine, contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4026
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4027
                Expression value = ident;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4028
                if (type == ASSIGN) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4029
                    next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4030
                    ident = ident.setIsDefaultParameter();
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
                    // binding pattern with initializer. desugar to: (param === undefined) ? initializer : param
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4033
                    Expression initializer = assignmentExpression(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4034
                    // TODO initializer must not contain yield expression if yield=true (i.e. this is generator function's parameter list)
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4035
                    BinaryNode test = new BinaryNode(Token.recast(paramToken, EQ_STRICT), ident, newUndefinedLiteral(paramToken, finish));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4036
                    value = new TernaryNode(Token.recast(paramToken, TERNARY), test, new JoinPredecessorExpression(initializer), new JoinPredecessorExpression(ident));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4037
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4038
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4039
                ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4040
                if (currentFunction != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4041
                    // destructuring assignment
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4042
                    BinaryNode assignment = new BinaryNode(Token.recast(paramToken, ASSIGN), pattern, value);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4043
                    lc.getFunctionBody(currentFunction).appendStatement(new ExpressionStatement(paramLine, assignment.getToken(), assignment.getFinish(), assignment));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4044
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4045
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4046
            parameters.add(ident);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4047
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4048
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  4049
        parameters.trimToSize();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4050
        return parameters;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4051
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4052
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4053
    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
  4054
        verifyDestructuringBindingPattern(pattern, new Consumer<IdentNode>() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4055
            public void accept(IdentNode identNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4056
                verifyIdent(identNode, contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4057
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4058
                ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4059
                if (currentFunction != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4060
                    // declare function-scope variables for destructuring bindings
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4061
                    lc.getFunctionBody(currentFunction).appendStatement(new VarNode(paramLine, Token.recast(paramToken, VAR), pattern.getFinish(), identNode, null));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4062
                    // detect duplicate bounds names in parameter list
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4063
                    currentFunction.addParameterBinding(identNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4064
                    currentFunction.setSimpleParameterList(false);
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
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4067
        });
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4068
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4069
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4070
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4071
     * FunctionBody :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4072
     *      SourceElements?
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4073
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4074
     * See 13
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4075
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4076
     * Parse function body.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4077
     * @return function node (body.)
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4078
     */
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4079
    private Block functionBody(final ParserContextFunctionNode functionNode) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4080
        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
  4081
        ParserContextBlockNode body = null;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4082
        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
  4083
        Block functionBody;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4084
        int bodyFinish = 0;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4085
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4086
        final boolean parseBody;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4087
        Object endParserState = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4088
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4089
            // 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
  4090
            body = newBlock();
33888
0c7b0ab328e0 8131929: Add option for debuggable scopes
hannesw
parents: 33533
diff changeset
  4091
            if (env._debug_scopes) {
0c7b0ab328e0 8131929: Add option for debuggable scopes
hannesw
parents: 33533
diff changeset
  4092
                // debug scope options forces everything to be in scope
0c7b0ab328e0 8131929: Add option for debuggable scopes
hannesw
parents: 33533
diff changeset
  4093
                markEval(lc);
0c7b0ab328e0 8131929: Add option for debuggable scopes
hannesw
parents: 33533
diff changeset
  4094
            }
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4095
            assert functionNode != null;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4096
            final int functionId = functionNode.getId();
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4097
            parseBody = reparsedFunction == null || functionId <= reparsedFunction.getFunctionNodeId();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4098
            // Nashorn extension: expression closures
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4099
            if ((!env._no_syntax_extensions || functionNode.getKind() == FunctionNode.Kind.ARROW) && type != LBRACE) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4100
                /*
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4101
                 * Example:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4102
                 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4103
                 * function square(x) x * x;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4104
                 * print(square(3));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4105
                 */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4106
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4107
                // just expression as function body
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4108
                final Expression expr = assignmentExpression(false);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4109
                lastToken = previousToken;
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4110
                functionNode.setLastToken(previousToken);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4111
                assert lc.getCurrentBlock() == lc.getFunctionBody(functionNode);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4112
                // EOL uses length field to store the line number
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4113
                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
  4114
                // 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
  4115
                // 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
  4116
                // 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
  4117
                // 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
  4118
                // details).
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4119
                if (parseBody) {
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4120
                    final ReturnNode returnNode = new ReturnNode(functionNode.getLineNumber(), expr.getToken(), lastFinish, expr);
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4121
                    appendStatement(returnNode);
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4122
                }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4123
                // bodyFinish = finish;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4124
            } else {
26505
d29bf8787b43 8057931: Instead of not skipping small functions in parser, make lexer avoid them instead
attila
parents: 26503
diff changeset
  4125
                expectDontAdvance(LBRACE);
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4126
                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
  4127
                    next();
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4128
                    // Gather the function elements.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4129
                    final List<Statement> prevFunctionDecls = functionDeclarations;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4130
                    functionDeclarations = new ArrayList<>();
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4131
                    try {
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4132
                        sourceElements(false);
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4133
                        addFunctionDeclarations(functionNode);
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4134
                    } finally {
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4135
                        functionDeclarations = prevFunctionDecls;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4136
                    }
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4137
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4138
                    lastToken = token;
26505
d29bf8787b43 8057931: Instead of not skipping small functions in parser, make lexer avoid them instead
attila
parents: 26503
diff changeset
  4139
                    if (parseBody) {
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4140
                        // 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
  4141
                        // 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
  4142
                        // 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
  4143
                        // ahead) state.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4144
                        endParserState = new ParserState(Token.descPosition(token), line, linePosition);
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4145
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4146
                        // 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
  4147
                        // 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
  4148
                        // 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
  4149
                        // 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
  4150
                        // point. Typical example of a weird lexer state after RBRACE would be:
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4151
                        //     function this_is_skipped() { ... } "use strict";
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4152
                        // 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
  4153
                        // 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
  4154
                        // 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
  4155
                    }
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  4156
                }
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4157
                bodyFinish = finish;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4158
                functionNode.setLastToken(token);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4159
                expect(RBRACE);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4160
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4161
        } finally {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4162
            restoreBlock(body);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4163
        }
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4164
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4165
        // NOTE: we can only do alterations to the function node after restoreFunctionNode.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4166
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4167
        if (parseBody) {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4168
            functionNode.setEndParserState(endParserState);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4169
        } else if (!body.getStatements().isEmpty()){
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4170
            // 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
  4171
            // 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
  4172
            // 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
  4173
            // 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
  4174
            // 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
  4175
            body.setStatements(Collections.<Statement>emptyList());
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4176
        }
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4177
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4178
        if (reparsedFunction != null) {
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4179
            // 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
  4180
            // 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
  4181
            // 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
  4182
            // skipped during an on-demand compilation.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4183
            final RecompilableScriptFunctionData data = reparsedFunction.getScriptFunctionData(functionNode.getId());
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4184
            if (data != null) {
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4185
                // 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
  4186
                // 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
  4187
                functionNode.setFlag(data.getFunctionFlags());
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4188
                // 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
  4189
                // 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
  4190
                if (functionNode.hasNestedEval()) {
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4191
                    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
  4192
                    body.setFlag(Block.NEEDS_SCOPE);
26503
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
        }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4196
        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
  4197
        return functionBody;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4198
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4199
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4200
    private boolean skipFunctionBody(final ParserContextFunctionNode functionNode) {
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4201
        if (reparsedFunction == null) {
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4202
            // Not reparsing, so don't skip any function body.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4203
            return false;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4204
        }
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4205
        // Skip to the RBRACE of this function, and continue parsing from there.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4206
        final RecompilableScriptFunctionData data = reparsedFunction.getScriptFunctionData(functionNode.getId());
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4207
        if (data == null) {
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4208
            // 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
  4209
            // 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
  4210
            // FunctionNode was dropped before a RecompilableScriptFunctionData could've been created for it.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4211
            return false;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4212
        }
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4213
        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
  4214
        assert parserState != null;
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4215
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4216
        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
  4217
            // RBRACE is already in the token stream, so fast forward to it
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4218
            for (; k < stream.last(); k++) {
34447
ec4c069f9436 8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents: 33888
diff changeset
  4219
                final long nextToken = stream.get(k + 1);
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4220
                if (Token.descPosition(nextToken) == parserState.position && Token.descType(nextToken) == RBRACE) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4221
                    token = stream.get(k);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4222
                    type = Token.descType(token);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4223
                    next();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4224
                    assert type == RBRACE && start == parserState.position;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4225
                    return true;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4226
                }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4227
            }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4228
        }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4229
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4230
        stream.reset();
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
  4231
        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
  4232
        line = parserState.line;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4233
        linePosition = parserState.linePosition;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4234
        // 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
  4235
        // the RBRACE.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4236
        type = SEMICOLON;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4237
        scanFirstToken();
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4238
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4239
        return true;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4240
    }
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4241
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4242
    /**
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4243
     * 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
  4244
     * for resuming parsing after skipping a function body.
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4245
     */
26646
332e9901f0ed 8058304: Non-serializable fields in serializable classes
hannesw
parents: 26505
diff changeset
  4246
    private static class ParserState implements Serializable {
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4247
        private final int position;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4248
        private final int line;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4249
        private final int linePosition;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4250
26646
332e9901f0ed 8058304: Non-serializable fields in serializable classes
hannesw
parents: 26505
diff changeset
  4251
        private static final long serialVersionUID = -2382565130754093694L;
332e9901f0ed 8058304: Non-serializable fields in serializable classes
hannesw
parents: 26505
diff changeset
  4252
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4253
        ParserState(final int position, final int line, final int linePosition) {
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4254
            this.position = position;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4255
            this.line = line;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4256
            this.linePosition = linePosition;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4257
        }
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4258
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32437
diff changeset
  4259
        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
  4260
            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
  4261
            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
  4262
            return newLexer;
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4263
        }
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4264
    }
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  4265
26065
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  4266
    private void printAST(final FunctionNode functionNode) {
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4267
        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
  4268
            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
  4269
        }
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  4270
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4271
        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
  4272
            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
  4273
        }
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  4274
    }
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  4275
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  4276
    private void addFunctionDeclarations(final ParserContextFunctionNode functionNode) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4277
        VarNode lastDecl = null;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4278
        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
  4279
            Statement decl = functionDeclarations.get(i);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4280
            if (lastDecl == null && decl instanceof VarNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4281
                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
  4282
                functionNode.setFlag(FunctionNode.HAS_FUNCTION_DECLARATIONS);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4283
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4284
            prependStatement(decl);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4285
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4286
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4287
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4288
    private RuntimeNode referenceError(final Expression lhs, final Expression rhs, final boolean earlyError) {
18632
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  4289
        if (earlyError) {
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  4290
            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
  4291
        }
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4292
        final ArrayList<Expression> args = new ArrayList<>();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4293
        args.add(lhs);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4294
        if (rhs == null) {
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  4295
            args.add(LiteralNode.newInstance(lhs.getToken(), lhs.getFinish()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4296
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4297
            args.add(rhs);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4298
        }
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  4299
        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
  4300
        return new RuntimeNode(lhs.getToken(), lhs.getFinish(), RuntimeNode.Request.REFERENCE_ERROR, args);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4301
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4302
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4303
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4304
     * PostfixExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4305
     *      LeftHandSideExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4306
     *      LeftHandSideExpression ++ // [no LineTerminator here]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4307
     *      LeftHandSideExpression -- // [no LineTerminator here]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4308
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4309
     * See 11.3
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4310
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4311
     * UnaryExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4312
     *      PostfixExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4313
     *      delete UnaryExpression
32437
153cb8aeb422 8134865: Need to restore for container block from lexical context in finally
aw
parents: 32245
diff changeset
  4314
     *      void UnaryExpression
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4315
     *      typeof UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4316
     *      ++ UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4317
     *      -- UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4318
     *      + UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4319
     *      - UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4320
     *      ~ UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4321
     *      ! UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4322
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4323
     * See 11.4
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4324
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4325
     * Parse unary expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4326
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4327
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4328
    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
  4329
        final int  unaryLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4330
        final long unaryToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4331
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4332
        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
  4333
        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
  4334
            next();
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4335
            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
  4336
            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
  4337
                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
  4338
            }
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4339
            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
  4340
            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
  4341
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4342
        case VOID:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4343
        case TYPEOF:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4344
        case ADD:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4345
        case SUB:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4346
        case BIT_NOT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4347
        case NOT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4348
            next();
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4349
            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
  4350
            return new UnaryNode(unaryToken, expr);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4351
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4352
        case INCPREFIX:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4353
        case DECPREFIX:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4354
            final TokenType opType = type;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4355
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4356
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4357
            final Expression lhs = leftHandSideExpression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4358
            // ++, -- without operand..
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4359
            if (lhs == null) {
18632
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  4360
                throw error(AbstractParser.message("expected.lvalue", type.getNameOrType()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4361
            }
18632
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  4362
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4363
            return verifyIncDecExpression(unaryToken, opType, lhs, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4364
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4365
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4366
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4367
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4368
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4369
        Expression expression = leftHandSideExpression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4370
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4371
        if (last != EOL) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4372
            switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4373
            case INCPREFIX:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4374
            case DECPREFIX:
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4375
                final long opToken = token;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4376
                final TokenType opType = type;
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4377
                final Expression lhs = expression;
18632
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  4378
                // ++, -- without operand..
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  4379
                if (lhs == null) {
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  4380
                    throw error(AbstractParser.message("expected.lvalue", type.getNameOrType()));
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  4381
                }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4382
                next();
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4383
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4384
                return verifyIncDecExpression(opToken, opType, lhs, true);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4385
            default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4386
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4387
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4388
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4389
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4390
        if (expression == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4391
            throw error(AbstractParser.message("expected.operand", type.getNameOrType()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4392
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4393
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4394
        return expression;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4395
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4396
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4397
    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
  4398
        assert lhs != null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4399
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4400
        if (!(lhs instanceof AccessNode ||
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4401
              lhs instanceof IndexNode ||
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4402
              lhs instanceof IdentNode)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4403
            return referenceError(lhs, null, env._early_lvalue_error);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4404
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4405
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4406
        if (lhs instanceof IdentNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4407
            if (!checkIdentLValue((IdentNode)lhs)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4408
                return referenceError(lhs, null, false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4409
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4410
            verifyIdent((IdentNode)lhs, "operand for " + opType.getName() + " operator");
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4411
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4412
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4413
        return incDecExpression(unaryToken, opType, lhs, isPostfix);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4414
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4415
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4416
    /**
32245
80164edf8a10 8133872: Expression completion should work on contexts where an expression is accepted
sundar
parents: 31485
diff changeset
  4417
     * {@code
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4418
     * MultiplicativeExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4419
     *      UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4420
     *      MultiplicativeExpression * UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4421
     *      MultiplicativeExpression / UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4422
     *      MultiplicativeExpression % UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4423
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4424
     * See 11.5
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4425
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4426
     * AdditiveExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4427
     *      MultiplicativeExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4428
     *      AdditiveExpression + MultiplicativeExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4429
     *      AdditiveExpression - MultiplicativeExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4430
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4431
     * See 11.6
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4432
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4433
     * ShiftExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4434
     *      AdditiveExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4435
     *      ShiftExpression << AdditiveExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4436
     *      ShiftExpression >> AdditiveExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4437
     *      ShiftExpression >>> AdditiveExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4438
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4439
     * See 11.7
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4440
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4441
     * RelationalExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4442
     *      ShiftExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4443
     *      RelationalExpression < ShiftExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4444
     *      RelationalExpression > ShiftExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4445
     *      RelationalExpression <= ShiftExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4446
     *      RelationalExpression >= ShiftExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4447
     *      RelationalExpression instanceof ShiftExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4448
     *      RelationalExpression in ShiftExpression // if !noIf
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4449
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4450
     * See 11.8
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4451
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4452
     *      RelationalExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4453
     *      EqualityExpression == RelationalExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4454
     *      EqualityExpression != RelationalExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4455
     *      EqualityExpression === RelationalExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4456
     *      EqualityExpression !== RelationalExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4457
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4458
     * See 11.9
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4459
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4460
     * BitwiseANDExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4461
     *      EqualityExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4462
     *      BitwiseANDExpression & EqualityExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4463
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4464
     * BitwiseXORExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4465
     *      BitwiseANDExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4466
     *      BitwiseXORExpression ^ BitwiseANDExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4467
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4468
     * BitwiseORExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4469
     *      BitwiseXORExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4470
     *      BitwiseORExpression | BitwiseXORExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4471
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4472
     * See 11.10
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4473
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4474
     * LogicalANDExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4475
     *      BitwiseORExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4476
     *      LogicalANDExpression && BitwiseORExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4477
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4478
     * LogicalORExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4479
     *      LogicalANDExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4480
     *      LogicalORExpression || LogicalANDExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4481
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4482
     * See 11.11
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4483
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4484
     * ConditionalExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4485
     *      LogicalORExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4486
     *      LogicalORExpression ? AssignmentExpression : AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4487
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4488
     * See 11.12
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4489
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4490
     * AssignmentExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4491
     *      ConditionalExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4492
     *      LeftHandSideExpression AssignmentOperator AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4493
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4494
     * AssignmentOperator :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4495
     *      = *= /= %= += -= <<= >>= >>>= &= ^= |=
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4496
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4497
     * See 11.13
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4498
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4499
     * Expression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4500
     *      AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4501
     *      Expression , AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4502
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4503
     * See 11.14
32245
80164edf8a10 8133872: Expression completion should work on contexts where an expression is accepted
sundar
parents: 31485
diff changeset
  4504
     * }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4505
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4506
     * Parse expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4507
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4508
     */
32245
80164edf8a10 8133872: Expression completion should work on contexts where an expression is accepted
sundar
parents: 31485
diff changeset
  4509
    protected Expression expression() {
80164edf8a10 8133872: Expression completion should work on contexts where an expression is accepted
sundar
parents: 31485
diff changeset
  4510
        // 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
  4511
        // at expression start point!
80164edf8a10 8133872: Expression completion should work on contexts where an expression is accepted
sundar
parents: 31485
diff changeset
  4512
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4513
        // Include commas in expression parsing.
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4514
        return expression(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4515
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4516
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4517
    private Expression expression(final boolean noIn) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4518
        Expression assignmentExpression = assignmentExpression(noIn);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4519
        while (type == COMMARIGHT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4520
            long commaToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4521
            next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4522
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4523
            boolean rhsRestParameter = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4524
            if (type == ELLIPSIS && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4525
                // (a, b, ...rest) is not a valid expression, unless we're parsing the parameter list of an arrow function (we need to throw the right error).
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4526
                // But since the rest parameter is always last, at least we know that the expression has to end here and be followed by RPAREN and ARROW, so peek ahead.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4527
                if (isRestParameterEndOfArrowFunctionParameterList()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4528
                    next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4529
                    rhsRestParameter = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4530
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4531
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4532
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4533
            Expression rhs = assignmentExpression(noIn);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4534
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4535
            if (rhsRestParameter) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4536
                rhs = ((IdentNode)rhs).setIsRestParameter();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4537
                // 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
  4538
                // 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
  4539
                // 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
  4540
                assert type == RPAREN;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4541
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4542
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4543
            assignmentExpression = new BinaryNode(commaToken, assignmentExpression, rhs);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4544
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4545
        return assignmentExpression;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4546
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4547
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4548
    private Expression expression(final int minPrecedence, final boolean noIn) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4549
        return expression(unaryExpression(), minPrecedence, noIn);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4550
    }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  4551
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  4552
    private JoinPredecessorExpression joinPredecessorExpression() {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  4553
        return new JoinPredecessorExpression(expression());
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  4554
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  4555
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4556
    private Expression expression(final Expression exprLhs, final int minPrecedence, final boolean noIn) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4557
        // Get the precedence of the next operator.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4558
        int precedence = type.getPrecedence();
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  4559
        Expression lhs = exprLhs;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4560
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4561
        // While greater precedence.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4562
        while (type.isOperator(noIn) && precedence >= minPrecedence) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4563
            // Capture the operator token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4564
            final long op = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4565
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4566
            if (type == TERNARY) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4567
                // Skip operator.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4568
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4569
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4570
                // Pass expression. Middle expression of a conditional expression can be a "in"
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4571
                // expression - even in the contexts where "in" is not permitted.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  4572
                final Expression trueExpr = expression(unaryExpression(), ASSIGN.getPrecedence(), false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4573
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4574
                expect(COLON);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4575
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4576
                // Fail expression.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  4577
                final Expression falseExpr = expression(unaryExpression(), ASSIGN.getPrecedence(), noIn);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4578
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4579
                // Build up node.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  4580
                lhs = new TernaryNode(op, lhs, new JoinPredecessorExpression(trueExpr), new JoinPredecessorExpression(falseExpr));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4581
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4582
                // Skip operator.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4583
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4584
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4585
                 // Get the next primary expression.
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4586
                Expression rhs;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4587
                final boolean isAssign = Token.descType(op) == ASSIGN;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4588
                if(isAssign) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4589
                    defaultNames.push(lhs);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4590
                }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4591
                try {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4592
                    rhs = unaryExpression();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4593
                    // Get precedence of next operator.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4594
                    int nextPrecedence = type.getPrecedence();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4595
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4596
                    // Subtask greater precedence.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4597
                    while (type.isOperator(noIn) &&
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4598
                           (nextPrecedence > precedence ||
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4599
                           nextPrecedence == precedence && !type.isLeftAssociative())) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4600
                        rhs = expression(rhs, nextPrecedence, noIn);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4601
                        nextPrecedence = type.getPrecedence();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4602
                    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4603
                } finally {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4604
                    if(isAssign) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4605
                        defaultNames.pop();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4606
                    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  4607
                }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4608
                lhs = verifyAssignment(op, lhs, rhs);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4609
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4610
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4611
            precedence = type.getPrecedence();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4612
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4613
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4614
        return lhs;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4615
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4616
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4617
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4618
     * AssignmentExpression.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4619
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4620
     * AssignmentExpression[In, Yield] :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4621
     *   ConditionalExpression[?In, ?Yield]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4622
     *   [+Yield] YieldExpression[?In]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4623
     *   ArrowFunction[?In, ?Yield]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4624
     *   LeftHandSideExpression[?Yield] = AssignmentExpression[?In, ?Yield]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4625
     *   LeftHandSideExpression[?Yield] AssignmentOperator AssignmentExpression[?In, ?Yield]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4626
     */
32245
80164edf8a10 8133872: Expression completion should work on contexts where an expression is accepted
sundar
parents: 31485
diff changeset
  4627
    protected Expression assignmentExpression(final boolean noIn) {
80164edf8a10 8133872: Expression completion should work on contexts where an expression is accepted
sundar
parents: 31485
diff changeset
  4628
        // 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
  4629
        // at assignment expression start point!
80164edf8a10 8133872: Expression completion should work on contexts where an expression is accepted
sundar
parents: 31485
diff changeset
  4630
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4631
        if (type == YIELD && inGeneratorFunction() && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4632
            return yieldExpression(noIn);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4633
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4634
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4635
        final long startToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4636
        final int startLine = line;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4637
        final Expression exprLhs = conditionalExpression(noIn);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4638
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4639
        if (type == ARROW && isES6()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4640
            if (checkNoLineTerminator()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4641
                final Expression paramListExpr;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4642
                if (exprLhs instanceof ExpressionList) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4643
                    paramListExpr = (((ExpressionList)exprLhs).getExpressions().isEmpty() ? null : ((ExpressionList)exprLhs).getExpressions().get(0));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4644
                } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4645
                    paramListExpr = exprLhs;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4646
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4647
                return arrowFunction(startToken, startLine, paramListExpr);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4648
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4649
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4650
        assert !(exprLhs instanceof ExpressionList);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4651
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4652
        if (isAssignmentOperator(type)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4653
            final boolean isAssign = type == ASSIGN;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4654
            if (isAssign) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4655
                defaultNames.push(exprLhs);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4656
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4657
            try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4658
                final long assignToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4659
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4660
                final Expression exprRhs = assignmentExpression(noIn);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4661
                return verifyAssignment(assignToken, exprLhs, exprRhs);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4662
            } finally {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4663
                if (isAssign) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4664
                    defaultNames.pop();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4665
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4666
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4667
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4668
            return exprLhs;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4669
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4670
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4671
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4672
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4673
     * Is type one of {@code = *= /= %= += -= <<= >>= >>>= &= ^= |=}?
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4674
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4675
    private static boolean isAssignmentOperator(TokenType type) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4676
        switch (type) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4677
        case ASSIGN:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4678
        case ASSIGN_ADD:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4679
        case ASSIGN_BIT_AND:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4680
        case ASSIGN_BIT_OR:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4681
        case ASSIGN_BIT_XOR:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4682
        case ASSIGN_DIV:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4683
        case ASSIGN_MOD:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4684
        case ASSIGN_MUL:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4685
        case ASSIGN_SAR:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4686
        case ASSIGN_SHL:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4687
        case ASSIGN_SHR:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4688
        case ASSIGN_SUB:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4689
            return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4690
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4691
        return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4692
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4693
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4694
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4695
     * ConditionalExpression.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4696
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4697
    private Expression conditionalExpression(boolean noIn) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4698
        return expression(TERNARY.getPrecedence(), noIn);
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
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4701
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4702
     * ArrowFunction.
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
     * @param startToken start token of the ArrowParameters expression
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4705
     * @param functionLine start line of the arrow function
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4706
     * @param paramListExpr ArrowParameters expression or {@code null} for {@code ()} (empty list)
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4707
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4708
    private Expression arrowFunction(final long startToken, final int functionLine, final Expression paramListExpr) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4709
        // 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
  4710
        assert type != ARROW || checkNoLineTerminator();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4711
        expect(ARROW);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4712
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4713
        final long functionToken = Token.recast(startToken, ARROW);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4714
        final IdentNode name = new IdentNode(functionToken, Token.descPosition(functionToken), "=>:" + functionLine);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4715
        final ParserContextFunctionNode functionNode = createParserContextFunctionNode(name, functionToken, FunctionNode.Kind.ARROW, functionLine, null);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4716
        functionNode.setFlag(FunctionNode.IS_ANONYMOUS);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4717
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4718
        lc.push(functionNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4719
        try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4720
            ParserContextBlockNode parameterBlock = newBlock();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4721
            final List<IdentNode> parameters;
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
                parameters = convertArrowFunctionParameterList(paramListExpr, functionLine);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4724
                functionNode.setParameters(parameters);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4725
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4726
                if (!functionNode.isSimpleParameterList()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4727
                    markEvalInArrowParameterList(parameterBlock);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4728
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4729
            } finally {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4730
                restoreBlock(parameterBlock);
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
            Block functionBody = functionBody(functionNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4733
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4734
            functionBody = maybeWrapBodyInParameterBlock(functionBody, parameterBlock);
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
            verifyParameterList(parameters, functionNode);
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
            final FunctionNode function = createFunctionNode(
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4739
                            functionNode,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4740
                            functionToken,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4741
                            name,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4742
                            parameters,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4743
                            FunctionNode.Kind.ARROW,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4744
                            functionLine,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4745
                            functionBody);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4746
            return function;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4747
        } finally {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4748
            lc.pop(functionNode);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4749
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4750
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4751
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4752
    private void markEvalInArrowParameterList(final ParserContextBlockNode parameterBlock) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4753
        final Iterator<ParserContextFunctionNode> iter = lc.getFunctions();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4754
        final ParserContextFunctionNode current = iter.next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4755
        final ParserContextFunctionNode parent = iter.next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4756
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4757
        if (parent.getFlag(FunctionNode.HAS_EVAL) != 0) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4758
            // 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
  4759
            // 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
  4760
            for (final Statement st : parameterBlock.getStatements()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4761
                st.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4762
                    @Override
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4763
                    public boolean enterCallNode(final CallNode callNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4764
                        if (callNode.getFunction() instanceof IdentNode && ((IdentNode) callNode.getFunction()).getName().equals("eval")) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4765
                            current.setFlag(FunctionNode.HAS_EVAL);
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
                        return true;
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
                });
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4770
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4771
            // TODO: function containing the arrow function should not be flagged has-eval
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
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4774
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4775
    private List<IdentNode> convertArrowFunctionParameterList(final Expression paramListExpr, final int functionLine) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4776
        final List<IdentNode> parameters;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4777
        if (paramListExpr == null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4778
            // empty parameter list, i.e. () =>
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4779
            parameters = Collections.emptyList();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4780
        } else if (paramListExpr instanceof IdentNode || paramListExpr.isTokenType(ASSIGN) || isDestructuringLhs(paramListExpr)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4781
            parameters = Collections.singletonList(verifyArrowParameter(paramListExpr, 0, functionLine));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4782
        } else if (paramListExpr instanceof BinaryNode && Token.descType(paramListExpr.getToken()) == COMMARIGHT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4783
            parameters = new ArrayList<>();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4784
            Expression car = paramListExpr;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4785
            do {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4786
                final Expression cdr = ((BinaryNode) car).rhs();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4787
                parameters.add(0, verifyArrowParameter(cdr, parameters.size(), functionLine));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4788
                car = ((BinaryNode) car).lhs();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4789
            } while (car instanceof BinaryNode && Token.descType(car.getToken()) == COMMARIGHT);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4790
            parameters.add(0, verifyArrowParameter(car, parameters.size(), functionLine));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4791
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4792
            throw error(AbstractParser.message("expected.arrow.parameter"), paramListExpr.getToken());
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
        return parameters;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4795
    }
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
    private IdentNode verifyArrowParameter(Expression param, int index, int paramLine) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4798
        final String contextString = "function parameter";
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4799
        if (param instanceof IdentNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4800
            IdentNode ident = (IdentNode)param;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4801
            verifyStrictIdent(ident, contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4802
            ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4803
            if (currentFunction != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4804
                currentFunction.addParameterBinding(ident);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4805
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4806
            return ident;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4807
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4808
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4809
        if (param.isTokenType(ASSIGN)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4810
            Expression lhs = ((BinaryNode) param).lhs();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4811
            long paramToken = lhs.getToken();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4812
            Expression initializer = ((BinaryNode) param).rhs();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4813
            if (lhs instanceof IdentNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4814
                // default parameter
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4815
                IdentNode ident = (IdentNode) lhs;
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
                ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4818
                if (currentFunction != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4819
                    BinaryNode test = new BinaryNode(Token.recast(paramToken, EQ_STRICT), ident, newUndefinedLiteral(paramToken, finish));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4820
                    TernaryNode value = new TernaryNode(Token.recast(paramToken, TERNARY), test, new JoinPredecessorExpression(initializer), new JoinPredecessorExpression(ident));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4821
                    BinaryNode assignment = new BinaryNode(Token.recast(paramToken, ASSIGN), ident, value);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4822
                    lc.getFunctionBody(currentFunction).appendStatement(new ExpressionStatement(paramLine, assignment.getToken(), assignment.getFinish(), assignment));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4823
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4824
                    currentFunction.addParameterBinding(ident);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4825
                    currentFunction.setSimpleParameterList(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4826
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4827
                return ident;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4828
            } else if (isDestructuringLhs(lhs)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4829
                // binding pattern with initializer
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4830
                // Introduce synthetic temporary parameter to capture the object to be destructured.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4831
                IdentNode ident = createIdentNode(paramToken, param.getFinish(), String.format("arguments[%d]", index)).setIsDestructuredParameter().setIsDefaultParameter();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4832
                verifyDestructuringParameterBindingPattern(param, paramToken, paramLine, contextString);
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
                ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4835
                if (currentFunction != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4836
                    BinaryNode test = new BinaryNode(Token.recast(paramToken, EQ_STRICT), ident, newUndefinedLiteral(paramToken, finish));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4837
                    TernaryNode value = new TernaryNode(Token.recast(paramToken, TERNARY), test, new JoinPredecessorExpression(initializer), new JoinPredecessorExpression(ident));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4838
                    BinaryNode assignment = new BinaryNode(Token.recast(paramToken, ASSIGN), param, value);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4839
                    lc.getFunctionBody(currentFunction).appendStatement(new ExpressionStatement(paramLine, assignment.getToken(), assignment.getFinish(), assignment));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4840
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4841
                return ident;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4842
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4843
        } else if (isDestructuringLhs(param)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4844
            // binding pattern
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4845
            long paramToken = param.getToken();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4846
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4847
            // Introduce synthetic temporary parameter to capture the object to be destructured.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4848
            IdentNode ident = createIdentNode(paramToken, param.getFinish(), String.format("arguments[%d]", index)).setIsDestructuredParameter();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4849
            verifyDestructuringParameterBindingPattern(param, paramToken, paramLine, contextString);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4850
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4851
            ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4852
            if (currentFunction != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4853
                BinaryNode assignment = new BinaryNode(Token.recast(paramToken, ASSIGN), param, ident);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4854
                lc.getFunctionBody(currentFunction).appendStatement(new ExpressionStatement(paramLine, assignment.getToken(), assignment.getFinish(), assignment));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4855
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4856
            return ident;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4857
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4858
        throw error(AbstractParser.message("invalid.arrow.parameter"), param.getToken());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4859
    }
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
    private boolean checkNoLineTerminator() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4862
        assert type == ARROW;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4863
        if (last == RPAREN) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4864
            return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4865
        } else if (last == IDENT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4866
            return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4867
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4868
        for (int i = k - 1; i >= 0; i--) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4869
            TokenType t = T(i);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4870
            switch (t) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4871
            case RPAREN:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4872
            case IDENT:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4873
                return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4874
            case EOL:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4875
                return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4876
            case COMMENT:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4877
                continue;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4878
            default:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4879
                if (t.getKind() == TokenKind.FUTURESTRICT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4880
                    return true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4881
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4882
                return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4883
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4884
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4885
        return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4886
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4887
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4888
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4889
     * 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
  4890
     * at the end of an arrow function parameter list.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4891
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4892
    private boolean isRestParameterEndOfArrowFunctionParameterList() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4893
        assert type == ELLIPSIS;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4894
        // 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
  4895
        int i = 1;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4896
        for (;;) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4897
            TokenType t = T(k + i++);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4898
            if (t == IDENT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4899
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4900
            } else if (t == EOL || t == COMMENT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4901
                continue;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4902
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4903
                return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4904
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4905
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4906
        for (;;) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4907
            TokenType t = T(k + i++);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4908
            if (t == RPAREN) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4909
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4910
            } else if (t == EOL || t == COMMENT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4911
                continue;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4912
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4913
                return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4914
            }
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
        for (;;) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4917
            TokenType t = T(k + i++);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4918
            if (t == ARROW) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4919
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4920
            } else if (t == COMMENT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4921
                continue;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4922
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4923
                return false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4924
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4925
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  4926
        return true;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4927
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4928
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4929
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4930
     * Parse an end of line.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4931
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4932
    private void endOfLine() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4933
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4934
        case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4935
        case EOL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4936
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4937
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4938
        case RPAREN:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4939
        case RBRACKET:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4940
        case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4941
        case EOF:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4942
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4943
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4944
            if (last != EOL) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4945
                expect(SEMICOLON);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4946
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4947
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4948
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4949
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  4950
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4951
    /**
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4952
     * Parse untagged template literal as string concatenation.
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4953
     */
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4954
    private Expression templateLiteral() {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4955
        assert type == TEMPLATE || type == TEMPLATE_HEAD;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4956
        final boolean noSubstitutionTemplate = type == TEMPLATE;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4957
        long lastLiteralToken = token;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4958
        LiteralNode<?> literal = getLiteral();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4959
        if (noSubstitutionTemplate) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4960
            return literal;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4961
        }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4962
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4963
        Expression concat = literal;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4964
        TokenType lastLiteralType;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4965
        do {
34447
ec4c069f9436 8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents: 33888
diff changeset
  4966
            final Expression expression = expression();
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4967
            if (type != TEMPLATE_MIDDLE && type != TEMPLATE_TAIL) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4968
                throw error(AbstractParser.message("unterminated.template.expression"), token);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4969
            }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4970
            concat = new BinaryNode(Token.recast(lastLiteralToken, TokenType.ADD), concat, expression);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4971
            lastLiteralType = type;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4972
            lastLiteralToken = token;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4973
            literal = getLiteral();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4974
            concat = new BinaryNode(Token.recast(lastLiteralToken, TokenType.ADD), concat, literal);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4975
        } while (lastLiteralType == TEMPLATE_MIDDLE);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4976
        return concat;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4977
    }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4978
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4979
    /**
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4980
     * Parse tagged template literal as argument list.
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4981
     * @return argument list for a tag function call (template object, ...substitutions)
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4982
     */
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4983
    private List<Expression> templateLiteralArgumentList() {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4984
        assert type == TEMPLATE || type == TEMPLATE_HEAD;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4985
        final ArrayList<Expression> argumentList = new ArrayList<>();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4986
        final ArrayList<Expression> rawStrings = new ArrayList<>();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4987
        final ArrayList<Expression> cookedStrings = new ArrayList<>();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4988
        argumentList.add(null); // filled at the end
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4989
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4990
        final long templateToken = token;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4991
        final boolean hasSubstitutions = type == TEMPLATE_HEAD;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4992
        addTemplateLiteralString(rawStrings, cookedStrings);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4993
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4994
        if (hasSubstitutions) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4995
            TokenType lastLiteralType;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4996
            do {
34447
ec4c069f9436 8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents: 33888
diff changeset
  4997
                final Expression expression = expression();
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4998
                if (type != TEMPLATE_MIDDLE && type != TEMPLATE_TAIL) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  4999
                    throw error(AbstractParser.message("unterminated.template.expression"), token);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5000
                }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5001
                argumentList.add(expression);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5002
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5003
                lastLiteralType = type;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5004
                addTemplateLiteralString(rawStrings, cookedStrings);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5005
            } while (lastLiteralType == TEMPLATE_MIDDLE);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5006
        }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5007
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5008
        final LiteralNode<Expression[]> rawStringArray = LiteralNode.newInstance(templateToken, finish, rawStrings);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5009
        final LiteralNode<Expression[]> cookedStringArray = LiteralNode.newInstance(templateToken, finish, cookedStrings);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5010
        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
  5011
        argumentList.set(0, templateObject);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5012
        return optimizeList(argumentList);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5013
    }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5014
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5015
    private void addTemplateLiteralString(final ArrayList<Expression> rawStrings, final ArrayList<Expression> cookedStrings) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5016
        final long stringToken = token;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5017
        final String rawString = lexer.valueOfRawString(stringToken);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5018
        final String cookedString = (String) getValue();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5019
        next();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5020
        rawStrings.add(LiteralNode.newInstance(stringToken, finish, rawString));
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5021
        cookedStrings.add(LiteralNode.newInstance(stringToken, finish, cookedString));
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5022
    }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32692
diff changeset
  5023
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5024
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5025
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5026
     * Parse a module.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5027
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5028
     * Module :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5029
     *      ModuleBody?
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5030
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5031
     * ModuleBody :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5032
     *      ModuleItemList
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5033
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5034
    private FunctionNode module(final String moduleName) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5035
        boolean oldStrictMode = isStrictMode;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5036
        try {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5037
            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
  5038
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5039
            // Make a pseudo-token for the script holding its start and length.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5040
            int functionStart = Math.min(Token.descPosition(Token.withDelimiter(token)), finish);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5041
            final long functionToken = Token.toDesc(FUNCTION, functionStart, source.getLength() - functionStart);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5042
            final int  functionLine  = line;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5043
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5044
            final IdentNode ident = new IdentNode(functionToken, Token.descPosition(functionToken), moduleName);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5045
            final ParserContextFunctionNode script = createParserContextFunctionNode(
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5046
                            ident,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5047
                            functionToken,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5048
                            FunctionNode.Kind.MODULE,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5049
                            functionLine,
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5050
                            Collections.<IdentNode>emptyList());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5051
            lc.push(script);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5052
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5053
            final ParserContextModuleNode module = new ParserContextModuleNode(moduleName);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5054
            lc.push(module);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5055
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5056
            final ParserContextBlockNode body = newBlock();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5057
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5058
            functionDeclarations = new ArrayList<>();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5059
            moduleBody();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5060
            addFunctionDeclarations(script);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5061
            functionDeclarations = null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5062
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5063
            restoreBlock(body);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5064
            body.setFlag(Block.NEEDS_SCOPE);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5065
            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
  5066
            lc.pop(module);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5067
            lc.pop(script);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5068
            script.setLastToken(token);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5069
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5070
            expect(EOF);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5071
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5072
            script.setModule(module.createModule());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5073
            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
  5074
        } finally {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5075
            isStrictMode = oldStrictMode;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5076
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5077
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5078
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5079
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5080
     * Parse module body.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5081
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5082
     * ModuleBody :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5083
     *      ModuleItemList
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5084
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5085
     * ModuleItemList :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5086
     *      ModuleItem
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5087
     *      ModuleItemList ModuleItem
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5088
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5089
     * ModuleItem :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5090
     *      ImportDeclaration
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5091
     *      ExportDeclaration
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5092
     *      StatementListItem
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5093
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5094
    private void moduleBody() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5095
        loop:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5096
        while (type != EOF) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5097
            switch (type) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5098
            case EOF:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5099
                break loop;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5100
            case IMPORT:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5101
                importDeclaration();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5102
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5103
            case EXPORT:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5104
                exportDeclaration();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5105
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5106
            default:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5107
                // StatementListItem
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5108
                statement(true, false, false, false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5109
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5110
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5111
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5112
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5113
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5114
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5115
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5116
     * Parse import declaration.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5117
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5118
     * ImportDeclaration :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5119
     *     import ImportClause FromClause ;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5120
     *     import ModuleSpecifier ;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5121
     * ImportClause :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5122
     *     ImportedDefaultBinding
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5123
     *     NameSpaceImport
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5124
     *     NamedImports
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5125
     *     ImportedDefaultBinding , NameSpaceImport
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5126
     *     ImportedDefaultBinding , NamedImports
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5127
     * ImportedDefaultBinding :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5128
     *     ImportedBinding
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5129
     * ModuleSpecifier :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5130
     *     StringLiteral
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5131
     * ImportedBinding :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5132
     *     BindingIdentifier
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5133
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5134
    private void importDeclaration() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5135
        expect(IMPORT);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5136
        final ParserContextModuleNode module = lc.getCurrentModule();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5137
        if (type == STRING || type == ESCSTRING) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5138
            // import ModuleSpecifier ;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5139
            final String moduleSpecifier = (String) getValue();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5140
            next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5141
            module.addModuleRequest(moduleSpecifier);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5142
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5143
            // import ImportClause FromClause ;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5144
            List<Module.ImportEntry> importEntries;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5145
            if (type == MUL) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5146
                importEntries = Collections.singletonList(nameSpaceImport());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5147
            } else if (type == LBRACE) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5148
                importEntries = namedImports();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5149
            } else if (isBindingIdentifier()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5150
                // ImportedDefaultBinding
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5151
                final IdentNode importedDefaultBinding = bindingIdentifier("ImportedBinding");
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5152
                Module.ImportEntry defaultImport = Module.ImportEntry.importDefault(importedDefaultBinding.getName());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5153
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5154
                if (type == COMMARIGHT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5155
                    next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5156
                    importEntries = new ArrayList<>();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5157
                    if (type == MUL) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5158
                        importEntries.add(nameSpaceImport());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5159
                    } else if (type == LBRACE) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5160
                        importEntries.addAll(namedImports());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5161
                    } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5162
                        throw error(AbstractParser.message("expected.named.import"));
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
                } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5165
                    importEntries = Collections.singletonList(defaultImport);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5166
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5167
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5168
                throw error(AbstractParser.message("expected.import"));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5169
            }
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
            final String moduleSpecifier = fromClause();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5172
            module.addModuleRequest(moduleSpecifier);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5173
            for (int i = 0; i < importEntries.size(); i++) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5174
                module.addImportEntry(importEntries.get(i).withFrom(moduleSpecifier));
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
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5177
        expect(SEMICOLON);
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
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5180
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5181
     * NameSpaceImport :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5182
     *     * as ImportedBinding
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5183
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5184
     * @return imported binding identifier
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5185
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5186
    private Module.ImportEntry nameSpaceImport() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5187
        assert type == MUL;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5188
        next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5189
        final long asToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5190
        final String as = (String) expectValue(IDENT);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5191
        if (!"as".equals(as)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5192
            throw error(AbstractParser.message("expected.as"), asToken);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5193
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5194
        final IdentNode localNameSpace = bindingIdentifier("ImportedBinding");
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5195
        return Module.ImportEntry.importStarAsNameSpaceFrom(localNameSpace.getName());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5196
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5197
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5198
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5199
     * NamedImports :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5200
     *     { }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5201
     *     { ImportsList }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5202
     *     { ImportsList , }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5203
     * ImportsList :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5204
     *     ImportSpecifier
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5205
     *     ImportsList , ImportSpecifier
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5206
     * ImportSpecifier :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5207
     *     ImportedBinding
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5208
     *     IdentifierName as ImportedBinding
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5209
     * ImportedBinding :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5210
     *     BindingIdentifier
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
    private List<Module.ImportEntry> namedImports() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5213
        assert type == LBRACE;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5214
        next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5215
        List<Module.ImportEntry> importEntries = new ArrayList<>();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5216
        while (type != RBRACE) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5217
            final boolean bindingIdentifier = isBindingIdentifier();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5218
            final long nameToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5219
            final IdentNode importName = getIdentifierName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5220
            if (type == IDENT && "as".equals(getValue())) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5221
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5222
                final IdentNode localName = bindingIdentifier("ImportedBinding");
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5223
                importEntries.add(Module.ImportEntry.importSpecifier(importName.getName(), localName.getName()));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5224
            } else if (!bindingIdentifier) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5225
                throw error(AbstractParser.message("expected.binding.identifier"), nameToken);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5226
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5227
                importEntries.add(Module.ImportEntry.importSpecifier(importName.getName()));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5228
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5229
            if (type == COMMARIGHT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5230
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5231
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5232
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5233
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5234
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5235
        expect(RBRACE);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5236
        return importEntries;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5237
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5238
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5239
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5240
     * FromClause :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5241
     *     from ModuleSpecifier
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5242
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5243
    private String fromClause() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5244
        final long fromToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5245
        final String name = (String) expectValue(IDENT);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5246
        if (!"from".equals(name)) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5247
            throw error(AbstractParser.message("expected.from"), fromToken);
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 == STRING || type == ESCSTRING) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5250
            final String moduleSpecifier = (String) getValue();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5251
            next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5252
            return moduleSpecifier;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5253
        } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5254
            throw error(expectMessage(STRING));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5255
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5256
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5257
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
     * Parse export declaration.
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5260
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5261
     * ExportDeclaration :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5262
     *     export * FromClause ;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5263
     *     export ExportClause FromClause ;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5264
     *     export ExportClause ;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5265
     *     export VariableStatement
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5266
     *     export Declaration
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5267
     *     export default HoistableDeclaration[Default]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5268
     *     export default ClassDeclaration[Default]
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5269
     *     export default [lookahead !in {function, class}] AssignmentExpression[In] ;
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
    private void exportDeclaration() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5272
        expect(EXPORT);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5273
        final ParserContextModuleNode module = lc.getCurrentModule();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5274
        switch (type) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5275
            case MUL: {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5276
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5277
                final String moduleRequest = fromClause();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5278
                expect(SEMICOLON);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5279
                module.addModuleRequest(moduleRequest);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5280
                module.addStarExportEntry(Module.ExportEntry.exportStarFrom(moduleRequest));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5281
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5282
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5283
            case LBRACE: {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5284
                final List<Module.ExportEntry> exportEntries = exportClause();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5285
                if (type == IDENT && "from".equals(getValue())) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5286
                    final String moduleRequest = fromClause();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5287
                    module.addModuleRequest(moduleRequest);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5288
                    for (Module.ExportEntry exportEntry : exportEntries) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5289
                        module.addIndirectExportEntry(exportEntry.withFrom(moduleRequest));
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
                } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5292
                    for (Module.ExportEntry exportEntry : exportEntries) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5293
                        module.addLocalExportEntry(exportEntry);
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
                expect(SEMICOLON);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5297
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5298
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5299
            case DEFAULT:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5300
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5301
                final Expression assignmentExpression;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5302
                IdentNode ident;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5303
                final int lineNumber = line;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5304
                final long rhsToken = token;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5305
                final boolean declaration;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5306
                switch (type) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5307
                    case FUNCTION:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5308
                        assignmentExpression = functionExpression(false, true);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5309
                        ident = ((FunctionNode) assignmentExpression).getIdent();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5310
                        declaration = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5311
                        break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5312
                    case CLASS:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5313
                        assignmentExpression = classDeclaration(true);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5314
                        ident = ((ClassNode) assignmentExpression).getIdent();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5315
                        declaration = true;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5316
                        break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5317
                    default:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5318
                        assignmentExpression = assignmentExpression(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5319
                        ident = null;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5320
                        declaration = false;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5321
                        break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5322
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5323
                if (ident != null) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5324
                    module.addLocalExportEntry(Module.ExportEntry.exportDefault(ident.getName()));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5325
                } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5326
                    ident = createIdentNode(Token.recast(rhsToken, IDENT), finish, Module.DEFAULT_EXPORT_BINDING_NAME);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5327
                    lc.appendStatementToCurrentNode(new VarNode(lineNumber, Token.recast(rhsToken, LET), finish, ident, assignmentExpression));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5328
                    if (!declaration) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5329
                        expect(SEMICOLON);
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
                    module.addLocalExportEntry(Module.ExportEntry.exportDefault());
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5332
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5333
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5334
            case VAR:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5335
            case LET:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5336
            case CONST:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5337
                final List<Statement> statements = lc.getCurrentBlock().getStatements();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5338
                final int previousEnd = statements.size();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5339
                variableStatement(type);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5340
                for (final Statement statement : statements.subList(previousEnd, statements.size())) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5341
                    if (statement instanceof VarNode) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5342
                        module.addLocalExportEntry(Module.ExportEntry.exportSpecifier(((VarNode) statement).getName().getName()));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5343
                    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5344
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5345
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5346
            case CLASS: {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5347
                final ClassNode classDeclaration = classDeclaration(false);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5348
                module.addLocalExportEntry(Module.ExportEntry.exportSpecifier(classDeclaration.getIdent().getName()));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5349
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5350
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5351
            case FUNCTION: {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5352
                final FunctionNode functionDeclaration = (FunctionNode) functionExpression(true, true);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5353
                module.addLocalExportEntry(Module.ExportEntry.exportSpecifier(functionDeclaration.getIdent().getName()));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5354
                break;
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
            default:
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5357
                throw error(AbstractParser.message("invalid.export"), token);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5358
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5359
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5360
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5361
    /**
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5362
     * ExportClause :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5363
     *     { }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5364
     *     { ExportsList }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5365
     *     { ExportsList , }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5366
     * ExportsList :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5367
     *     ExportSpecifier
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5368
     *     ExportsList , ExportSpecifier
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5369
     * ExportSpecifier :
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5370
     *     IdentifierName
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5371
     *     IdentifierName as IdentifierName
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5372
     *
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5373
     * @return a list of ExportSpecifiers
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5374
     */
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5375
    private List<Module.ExportEntry> exportClause() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5376
        assert type == LBRACE;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5377
        next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5378
        List<Module.ExportEntry> exports = new ArrayList<>();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5379
        while (type != RBRACE) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5380
            final IdentNode localName = getIdentifierName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5381
            if (type == IDENT && "as".equals(getValue())) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5382
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5383
                final IdentNode exportName = getIdentifierName();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5384
                exports.add(Module.ExportEntry.exportSpecifier(exportName.getName(), localName.getName()));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5385
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5386
                exports.add(Module.ExportEntry.exportSpecifier(localName.getName()));
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5387
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5388
            if (type == COMMARIGHT) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5389
                next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5390
            } else {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5391
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5392
            }
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
        expect(RBRACE);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5395
        return exports;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5396
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5397
16252
3bfe9b68a0fa 8008648: Lazy JIT scope and callee semantics bugfixes. Broke out wallclock timer.
lagergren
parents: 16245
diff changeset
  5398
    @Override
3bfe9b68a0fa 8008648: Lazy JIT scope and callee semantics bugfixes. Broke out wallclock timer.
lagergren
parents: 16245
diff changeset
  5399
    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
  5400
        return "'JavaScript Parsing'";
16252
3bfe9b68a0fa 8008648: Lazy JIT scope and callee semantics bugfixes. Broke out wallclock timer.
lagergren
parents: 16245
diff changeset
  5401
    }
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  5402
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  5403
    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
  5404
        final Iterator<ParserContextFunctionNode> iter = lc.getFunctions();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  5405
        boolean flaggedCurrentFn = false;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  5406
        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
  5407
            final ParserContextFunctionNode fn = iter.next();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  5408
            if (!flaggedCurrentFn) {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  5409
                fn.setFlag(FunctionNode.HAS_EVAL);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  5410
                flaggedCurrentFn = true;
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5411
                if (fn.getKind() == FunctionNode.Kind.ARROW) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5412
                    // 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
  5413
                    // function fun(){ return (() => eval("this"))(); };
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5414
                    markThis(lc);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5415
                    markNewTarget(lc);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5416
                }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  5417
            } else {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  5418
                fn.setFlag(FunctionNode.HAS_NESTED_EVAL);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  5419
            }
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26646
diff changeset
  5420
            final ParserContextBlockNode body = lc.getFunctionBody(fn);
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26377
diff changeset
  5421
            // 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
  5422
            // 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
  5423
            // 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
  5424
            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
  5425
            fn.setFlag(FunctionNode.HAS_SCOPE_BLOCK);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  5426
        }
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  5427
    }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  5428
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
  5429
    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
  5430
        lc.prependStatementToCurrentNode(statement);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  5431
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  5432
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
  5433
    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
  5434
        lc.appendStatementToCurrentNode(statement);
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  5435
    }
37732
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5436
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5437
    private static void markSuperCall(final ParserContext lc) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5438
        final Iterator<ParserContextFunctionNode> iter = lc.getFunctions();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5439
        while (iter.hasNext()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5440
            final ParserContextFunctionNode fn = iter.next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5441
            if (fn.getKind() != FunctionNode.Kind.ARROW) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5442
                assert fn.isSubclassConstructor();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5443
                fn.setFlag(FunctionNode.ES6_HAS_DIRECT_SUPER);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5444
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5445
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5446
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5447
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5448
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5449
    private ParserContextFunctionNode getCurrentNonArrowFunction() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5450
        final Iterator<ParserContextFunctionNode> iter = lc.getFunctions();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5451
        while (iter.hasNext()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5452
            final ParserContextFunctionNode fn = iter.next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5453
            if (fn.getKind() != FunctionNode.Kind.ARROW) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5454
                return fn;
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
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5457
        return null;
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
    private static void markThis(final ParserContext lc) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5461
        final Iterator<ParserContextFunctionNode> iter = lc.getFunctions();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5462
        while (iter.hasNext()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5463
            final ParserContextFunctionNode fn = iter.next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5464
            fn.setFlag(FunctionNode.USES_THIS);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5465
            if (fn.getKind() != FunctionNode.Kind.ARROW) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5466
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5467
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5468
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5469
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5470
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5471
    private static void markNewTarget(final ParserContext lc) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5472
        final Iterator<ParserContextFunctionNode> iter = lc.getFunctions();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5473
        while (iter.hasNext()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5474
            final ParserContextFunctionNode fn = iter.next();
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5475
            if (fn.getKind() != FunctionNode.Kind.ARROW) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5476
                if (!fn.isProgram()) {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5477
                    fn.setFlag(FunctionNode.ES6_USES_NEW_TARGET);
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5478
                }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5479
                break;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5480
            }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5481
        }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5482
    }
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5483
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5484
    private boolean inGeneratorFunction() {
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5485
        return lc.getCurrentFunction().getKind() == FunctionNode.Kind.GENERATOR;
3673fec68d16 8134503: support ES6 parsing in Nashorn
hannesw
parents: 36696
diff changeset
  5486
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  5487
}