OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_PARSING_PARSER_BASE_H | 5 #ifndef V8_PARSING_PARSER_BASE_H |
6 #define V8_PARSING_PARSER_BASE_H | 6 #define V8_PARSING_PARSER_BASE_H |
7 | 7 |
8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
9 #include "src/ast/scopes.h" | 9 #include "src/ast/scopes.h" |
10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 stack_overflow_(false), | 190 stack_overflow_(false), |
191 allow_lazy_(false), | 191 allow_lazy_(false), |
192 allow_natives_(false), | 192 allow_natives_(false), |
193 allow_tailcalls_(false), | 193 allow_tailcalls_(false), |
194 allow_harmony_restrictive_declarations_(false), | 194 allow_harmony_restrictive_declarations_(false), |
195 allow_harmony_do_expressions_(false), | 195 allow_harmony_do_expressions_(false), |
196 allow_harmony_for_in_(false), | 196 allow_harmony_for_in_(false), |
197 allow_harmony_function_sent_(false), | 197 allow_harmony_function_sent_(false), |
198 allow_harmony_async_await_(false), | 198 allow_harmony_async_await_(false), |
199 allow_harmony_restrictive_generators_(false), | 199 allow_harmony_restrictive_generators_(false), |
200 allow_harmony_trailing_commas_(false) {} | 200 allow_harmony_trailing_commas_(false), |
| 201 allow_harmony_class_fields_(false) {} |
201 | 202 |
202 #define ALLOW_ACCESSORS(name) \ | 203 #define ALLOW_ACCESSORS(name) \ |
203 bool allow_##name() const { return allow_##name##_; } \ | 204 bool allow_##name() const { return allow_##name##_; } \ |
204 void set_allow_##name(bool allow) { allow_##name##_ = allow; } | 205 void set_allow_##name(bool allow) { allow_##name##_ = allow; } |
205 | 206 |
206 ALLOW_ACCESSORS(lazy); | 207 ALLOW_ACCESSORS(lazy); |
207 ALLOW_ACCESSORS(natives); | 208 ALLOW_ACCESSORS(natives); |
208 ALLOW_ACCESSORS(tailcalls); | 209 ALLOW_ACCESSORS(tailcalls); |
209 ALLOW_ACCESSORS(harmony_restrictive_declarations); | 210 ALLOW_ACCESSORS(harmony_restrictive_declarations); |
210 ALLOW_ACCESSORS(harmony_do_expressions); | 211 ALLOW_ACCESSORS(harmony_do_expressions); |
211 ALLOW_ACCESSORS(harmony_for_in); | 212 ALLOW_ACCESSORS(harmony_for_in); |
212 ALLOW_ACCESSORS(harmony_function_sent); | 213 ALLOW_ACCESSORS(harmony_function_sent); |
213 ALLOW_ACCESSORS(harmony_async_await); | 214 ALLOW_ACCESSORS(harmony_async_await); |
214 ALLOW_ACCESSORS(harmony_restrictive_generators); | 215 ALLOW_ACCESSORS(harmony_restrictive_generators); |
215 ALLOW_ACCESSORS(harmony_trailing_commas); | 216 ALLOW_ACCESSORS(harmony_trailing_commas); |
| 217 ALLOW_ACCESSORS(harmony_class_fields); |
216 | 218 |
217 #undef ALLOW_ACCESSORS | 219 #undef ALLOW_ACCESSORS |
218 | 220 |
219 uintptr_t stack_limit() const { return stack_limit_; } | 221 uintptr_t stack_limit() const { return stack_limit_; } |
220 | 222 |
221 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; } | 223 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; } |
222 | 224 |
223 Zone* zone() const { return zone_; } | 225 Zone* zone() const { return zone_; } |
224 | 226 |
225 protected: | 227 protected: |
(...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1085 // specification). | 1087 // specification). |
1086 ExpressionT ParseExpressionCoverGrammar(bool accept_IN, bool* ok); | 1088 ExpressionT ParseExpressionCoverGrammar(bool accept_IN, bool* ok); |
1087 | 1089 |
1088 ExpressionT ParseArrayLiteral(bool* ok); | 1090 ExpressionT ParseArrayLiteral(bool* ok); |
1089 | 1091 |
1090 enum class PropertyKind { | 1092 enum class PropertyKind { |
1091 kAccessorProperty, | 1093 kAccessorProperty, |
1092 kValueProperty, | 1094 kValueProperty, |
1093 kShorthandProperty, | 1095 kShorthandProperty, |
1094 kMethodProperty, | 1096 kMethodProperty, |
| 1097 kClassField, |
1095 kNotSet | 1098 kNotSet |
1096 }; | 1099 }; |
1097 | 1100 |
1098 bool SetPropertyKindFromToken(Token::Value token, PropertyKind* kind); | 1101 bool SetPropertyKindFromToken(Token::Value token, PropertyKind* kind); |
1099 ExpressionT ParsePropertyName(IdentifierT* name, PropertyKind* kind, | 1102 ExpressionT ParsePropertyName(IdentifierT* name, PropertyKind* kind, |
1100 bool* is_generator, bool* is_get, bool* is_set, | 1103 bool* is_generator, bool* is_get, bool* is_set, |
1101 bool* is_async, bool* is_computed_name, | 1104 bool* is_async, bool* is_computed_name, |
1102 bool* ok); | 1105 bool* ok); |
1103 ExpressionT ParseObjectLiteral(bool* ok); | 1106 ExpressionT ParseObjectLiteral(bool* ok); |
1104 ClassLiteralPropertyT ParseClassPropertyDefinition( | 1107 ClassLiteralPropertyT ParseClassPropertyDefinition( |
1105 ClassLiteralChecker* checker, bool has_extends, bool* is_computed_name, | 1108 ClassLiteralChecker* checker, bool has_extends, bool* is_computed_name, |
1106 bool* has_seen_constructor, bool* ok); | 1109 bool* has_seen_constructor, bool* ok); |
| 1110 FunctionLiteralT ParseClassFieldForInitializer(bool has_initializer, |
| 1111 bool* ok); |
1107 ObjectLiteralPropertyT ParseObjectPropertyDefinition( | 1112 ObjectLiteralPropertyT ParseObjectPropertyDefinition( |
1108 ObjectLiteralChecker* checker, bool* is_computed_name, bool* ok); | 1113 ObjectLiteralChecker* checker, bool* is_computed_name, bool* ok); |
1109 ExpressionListT ParseArguments(Scanner::Location* first_spread_pos, | 1114 ExpressionListT ParseArguments(Scanner::Location* first_spread_pos, |
1110 bool maybe_arrow, bool* ok); | 1115 bool maybe_arrow, bool* ok); |
1111 ExpressionListT ParseArguments(Scanner::Location* first_spread_pos, | 1116 ExpressionListT ParseArguments(Scanner::Location* first_spread_pos, |
1112 bool* ok) { | 1117 bool* ok) { |
1113 return ParseArguments(first_spread_pos, false, ok); | 1118 return ParseArguments(first_spread_pos, false, ok); |
1114 } | 1119 } |
1115 | 1120 |
1116 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); | 1121 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1328 bool allow_lazy_; | 1333 bool allow_lazy_; |
1329 bool allow_natives_; | 1334 bool allow_natives_; |
1330 bool allow_tailcalls_; | 1335 bool allow_tailcalls_; |
1331 bool allow_harmony_restrictive_declarations_; | 1336 bool allow_harmony_restrictive_declarations_; |
1332 bool allow_harmony_do_expressions_; | 1337 bool allow_harmony_do_expressions_; |
1333 bool allow_harmony_for_in_; | 1338 bool allow_harmony_for_in_; |
1334 bool allow_harmony_function_sent_; | 1339 bool allow_harmony_function_sent_; |
1335 bool allow_harmony_async_await_; | 1340 bool allow_harmony_async_await_; |
1336 bool allow_harmony_restrictive_generators_; | 1341 bool allow_harmony_restrictive_generators_; |
1337 bool allow_harmony_trailing_commas_; | 1342 bool allow_harmony_trailing_commas_; |
| 1343 bool allow_harmony_class_fields_; |
1338 | 1344 |
1339 friend class DiscardableZoneScope; | 1345 friend class DiscardableZoneScope; |
1340 }; | 1346 }; |
1341 | 1347 |
1342 template <typename Impl> | 1348 template <typename Impl> |
1343 ParserBase<Impl>::FunctionState::FunctionState( | 1349 ParserBase<Impl>::FunctionState::FunctionState( |
1344 FunctionState** function_state_stack, ScopeState** scope_stack, | 1350 FunctionState** function_state_stack, ScopeState** scope_stack, |
1345 Scope* scope, FunctionKind kind) | 1351 Scope* scope, FunctionKind kind) |
1346 : ScopeState(scope_stack, scope), | 1352 : ScopeState(scope_stack, scope), |
1347 next_materialized_literal_index_(0), | 1353 next_materialized_literal_index_(0), |
(...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1883 *kind = PropertyKind::kValueProperty; | 1889 *kind = PropertyKind::kValueProperty; |
1884 return true; | 1890 return true; |
1885 case Token::COMMA: | 1891 case Token::COMMA: |
1886 case Token::RBRACE: | 1892 case Token::RBRACE: |
1887 case Token::ASSIGN: | 1893 case Token::ASSIGN: |
1888 *kind = PropertyKind::kShorthandProperty; | 1894 *kind = PropertyKind::kShorthandProperty; |
1889 return true; | 1895 return true; |
1890 case Token::LPAREN: | 1896 case Token::LPAREN: |
1891 *kind = PropertyKind::kMethodProperty; | 1897 *kind = PropertyKind::kMethodProperty; |
1892 return true; | 1898 return true; |
| 1899 case Token::MUL: |
| 1900 case Token::SEMICOLON: |
| 1901 *kind = PropertyKind::kClassField; |
| 1902 return true; |
1893 default: | 1903 default: |
1894 break; | 1904 break; |
1895 } | 1905 } |
1896 return false; | 1906 return false; |
1897 } | 1907 } |
1898 | 1908 |
1899 template <class Impl> | 1909 template <class Impl> |
1900 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName( | 1910 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName( |
1901 IdentifierT* name, PropertyKind* kind, bool* is_generator, bool* is_get, | 1911 IdentifierT* name, PropertyKind* kind, bool* is_generator, bool* is_get, |
1902 bool* is_set, bool* is_async, bool* is_computed_name, bool* ok) { | 1912 bool* is_set, bool* is_async, bool* is_computed_name, bool* ok) { |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2020 Token::Value name_token = peek(); | 2030 Token::Value name_token = peek(); |
2021 | 2031 |
2022 IdentifierT name = impl()->EmptyIdentifier(); | 2032 IdentifierT name = impl()->EmptyIdentifier(); |
2023 ExpressionT name_expression; | 2033 ExpressionT name_expression; |
2024 if (name_token == Token::STATIC) { | 2034 if (name_token == Token::STATIC) { |
2025 Consume(Token::STATIC); | 2035 Consume(Token::STATIC); |
2026 if (peek() == Token::LPAREN) { | 2036 if (peek() == Token::LPAREN) { |
2027 kind = PropertyKind::kMethodProperty; | 2037 kind = PropertyKind::kMethodProperty; |
2028 name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static' | 2038 name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static' |
2029 name_expression = factory()->NewStringLiteral(name, position()); | 2039 name_expression = factory()->NewStringLiteral(name, position()); |
| 2040 } else if (peek() == Token::ASSIGN || peek() == Token::SEMICOLON || |
| 2041 peek() == Token::RBRACE) { |
| 2042 name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static' |
| 2043 name_expression = factory()->NewStringLiteral(name, position()); |
2030 } else { | 2044 } else { |
2031 is_static = true; | 2045 is_static = true; |
2032 name_expression = ParsePropertyName( | 2046 name_expression = ParsePropertyName( |
2033 &name, &kind, &is_generator, &is_get, &is_set, &is_async, | 2047 &name, &kind, &is_generator, &is_get, &is_set, &is_async, |
2034 is_computed_name, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); | 2048 is_computed_name, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
2035 } | 2049 } |
2036 } else { | 2050 } else { |
2037 name_expression = ParsePropertyName( | 2051 name_expression = ParsePropertyName( |
2038 &name, &kind, &is_generator, &is_get, &is_set, &is_async, | 2052 &name, &kind, &is_generator, &is_get, &is_set, &is_async, |
2039 is_computed_name, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); | 2053 is_computed_name, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
2040 } | 2054 } |
2041 | 2055 |
2042 switch (kind) { | 2056 switch (kind) { |
| 2057 case PropertyKind::kClassField: |
| 2058 case PropertyKind::kNotSet: // This case is a name followed by a name or |
| 2059 // other property. Here we have to assume |
| 2060 // that's an uninitialized field followed by a |
| 2061 // linebreak followed by a property, with ASI |
| 2062 // adding the semicolon. If not, there will be |
| 2063 // a syntax error after parsing the first name |
| 2064 // as an uninitialized field. |
2043 case PropertyKind::kShorthandProperty: | 2065 case PropertyKind::kShorthandProperty: |
2044 case PropertyKind::kValueProperty: | 2066 case PropertyKind::kValueProperty: |
2045 ReportUnexpectedToken(Next()); | 2067 if (allow_harmony_class_fields()) { |
2046 *ok = false; | 2068 bool has_initializer = Check(Token::ASSIGN); |
2047 return impl()->EmptyClassLiteralProperty(); | 2069 ExpressionT function_literal = ParseClassFieldForInitializer( |
| 2070 has_initializer, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
| 2071 ExpectSemicolon(CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
| 2072 return factory()->NewClassLiteralProperty( |
| 2073 name_expression, function_literal, ClassLiteralProperty::FIELD, |
| 2074 is_static, *is_computed_name); |
| 2075 } else { |
| 2076 ReportUnexpectedToken(Next()); |
| 2077 *ok = false; |
| 2078 return impl()->EmptyClassLiteralProperty(); |
| 2079 } |
2048 | 2080 |
2049 case PropertyKind::kMethodProperty: { | 2081 case PropertyKind::kMethodProperty: { |
2050 DCHECK(!is_get && !is_set); | 2082 DCHECK(!is_get && !is_set); |
2051 | 2083 |
2052 // MethodDefinition | 2084 // MethodDefinition |
2053 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 2085 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
2054 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 2086 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
2055 | 2087 |
2056 if (!*is_computed_name) { | 2088 if (!*is_computed_name) { |
2057 checker->CheckClassMethodName( | 2089 checker->CheckClassMethodName( |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2104 | 2136 |
2105 if (!*is_computed_name) { | 2137 if (!*is_computed_name) { |
2106 impl()->AddAccessorPrefixToFunctionName(is_get, value, name); | 2138 impl()->AddAccessorPrefixToFunctionName(is_get, value, name); |
2107 } | 2139 } |
2108 | 2140 |
2109 return factory()->NewClassLiteralProperty( | 2141 return factory()->NewClassLiteralProperty( |
2110 name_expression, value, | 2142 name_expression, value, |
2111 is_get ? ClassLiteralProperty::GETTER : ClassLiteralProperty::SETTER, | 2143 is_get ? ClassLiteralProperty::GETTER : ClassLiteralProperty::SETTER, |
2112 is_static, *is_computed_name); | 2144 is_static, *is_computed_name); |
2113 } | 2145 } |
2114 | |
2115 case PropertyKind::kNotSet: | |
2116 ReportUnexpectedToken(Next()); | |
2117 *ok = false; | |
2118 return impl()->EmptyClassLiteralProperty(); | |
2119 } | 2146 } |
2120 UNREACHABLE(); | 2147 UNREACHABLE(); |
2121 return impl()->EmptyClassLiteralProperty(); | 2148 return impl()->EmptyClassLiteralProperty(); |
2122 } | 2149 } |
2123 | 2150 |
2124 template <typename Impl> | 2151 template <typename Impl> |
| 2152 typename ParserBase<Impl>::FunctionLiteralT |
| 2153 ParserBase<Impl>::ParseClassFieldForInitializer(bool has_initializer, |
| 2154 bool* ok) { |
| 2155 // Makes a concise method which evaluates and returns the initialized value |
| 2156 // (or undefined if absent). |
| 2157 FunctionKind kind = FunctionKind::kConciseMethod; |
| 2158 DeclarationScope* initializer_scope = NewFunctionScope(kind); |
| 2159 initializer_scope->set_start_position(scanner()->location().end_pos); |
| 2160 FunctionState initializer_state(&function_state_, &scope_state_, |
| 2161 initializer_scope, kind); |
| 2162 DCHECK(scope() == initializer_scope); |
| 2163 scope()->SetLanguageMode(STRICT); |
| 2164 ExpressionClassifier expression_classifier(this); |
| 2165 ExpressionT value; |
| 2166 if (has_initializer) { |
| 2167 value = this->ParseAssignmentExpression( |
| 2168 true, CHECK_OK_CUSTOM(EmptyFunctionLiteral)); |
| 2169 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(EmptyFunctionLiteral)); |
| 2170 } else { |
| 2171 value = factory()->NewUndefinedLiteral(kNoSourcePosition); |
| 2172 } |
| 2173 initializer_scope->set_end_position(scanner()->location().end_pos); |
| 2174 typename Types::StatementList body = impl()->NewStatementList(1); |
| 2175 body->Add(factory()->NewReturnStatement(value, kNoSourcePosition), zone()); |
| 2176 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
| 2177 impl()->EmptyIdentifierString(), initializer_scope, body, |
| 2178 initializer_state.materialized_literal_count(), |
| 2179 initializer_state.expected_property_count(), 0, |
| 2180 FunctionLiteral::kNoDuplicateParameters, |
| 2181 FunctionLiteral::kAnonymousExpression, |
| 2182 FunctionLiteral::kShouldLazyCompile, kind, |
| 2183 initializer_scope->start_position()); |
| 2184 function_literal->set_is_class_field_initializer(true); |
| 2185 return function_literal; |
| 2186 } |
| 2187 |
| 2188 template <typename Impl> |
2125 typename ParserBase<Impl>::ObjectLiteralPropertyT | 2189 typename ParserBase<Impl>::ObjectLiteralPropertyT |
2126 ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker, | 2190 ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker, |
2127 bool* is_computed_name, | 2191 bool* is_computed_name, |
2128 bool* ok) { | 2192 bool* ok) { |
2129 bool is_get = false; | 2193 bool is_get = false; |
2130 bool is_set = false; | 2194 bool is_set = false; |
2131 bool is_generator = false; | 2195 bool is_generator = false; |
2132 bool is_async = false; | 2196 bool is_async = false; |
2133 PropertyKind kind = PropertyKind::kNotSet; | 2197 PropertyKind kind = PropertyKind::kNotSet; |
2134 | 2198 |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2284 if (!*is_computed_name) { | 2348 if (!*is_computed_name) { |
2285 impl()->AddAccessorPrefixToFunctionName(is_get, value, name); | 2349 impl()->AddAccessorPrefixToFunctionName(is_get, value, name); |
2286 } | 2350 } |
2287 | 2351 |
2288 return factory()->NewObjectLiteralProperty( | 2352 return factory()->NewObjectLiteralProperty( |
2289 name_expression, value, is_get ? ObjectLiteralProperty::GETTER | 2353 name_expression, value, is_get ? ObjectLiteralProperty::GETTER |
2290 : ObjectLiteralProperty::SETTER, | 2354 : ObjectLiteralProperty::SETTER, |
2291 *is_computed_name); | 2355 *is_computed_name); |
2292 } | 2356 } |
2293 | 2357 |
| 2358 case PropertyKind::kClassField: |
2294 case PropertyKind::kNotSet: | 2359 case PropertyKind::kNotSet: |
2295 ReportUnexpectedToken(Next()); | 2360 ReportUnexpectedToken(Next()); |
2296 *ok = false; | 2361 *ok = false; |
2297 return impl()->EmptyObjectLiteralProperty(); | 2362 return impl()->EmptyObjectLiteralProperty(); |
2298 } | 2363 } |
2299 UNREACHABLE(); | 2364 UNREACHABLE(); |
2300 return impl()->EmptyObjectLiteralProperty(); | 2365 return impl()->EmptyObjectLiteralProperty(); |
2301 } | 2366 } |
2302 | 2367 |
2303 template <typename Impl> | 2368 template <typename Impl> |
(...skipping 1938 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4242 has_seen_constructor_ = true; | 4307 has_seen_constructor_ = true; |
4243 return; | 4308 return; |
4244 } | 4309 } |
4245 } | 4310 } |
4246 | 4311 |
4247 | 4312 |
4248 } // namespace internal | 4313 } // namespace internal |
4249 } // namespace v8 | 4314 } // namespace v8 |
4250 | 4315 |
4251 #endif // V8_PARSING_PARSER_BASE_H | 4316 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |