Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(195)

Side by Side Diff: src/parsing/parser-base.h

Issue 2315733003: Class fields, part 1 (parsing and infrastructure) (Closed)
Patch Set: whitespace Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698