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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 lhs = lhs | rhs; | 50 lhs = lhs | rhs; |
51 return lhs; | 51 return lhs; |
52 } | 52 } |
53 | 53 |
54 static inline bool operator&(ParseFunctionFlags bitfield, | 54 static inline bool operator&(ParseFunctionFlags bitfield, |
55 ParseFunctionFlags mask) { | 55 ParseFunctionFlags mask) { |
56 typedef unsigned char T; | 56 typedef unsigned char T; |
57 return static_cast<T>(bitfield) & static_cast<T>(mask); | 57 return static_cast<T>(bitfield) & static_cast<T>(mask); |
58 } | 58 } |
59 | 59 |
60 enum class MethodKind { | |
61 kNormal = 0, | |
62 kStatic = 1 << 0, | |
63 kGenerator = 1 << 1, | |
64 kStaticGenerator = kStatic | kGenerator, | |
65 kAsync = 1 << 2, | |
66 kStaticAsync = kStatic | kAsync, | |
67 | |
68 /* Any non-ordinary method kinds */ | |
69 kSpecialMask = kGenerator | kAsync | |
70 }; | |
71 | |
72 inline bool IsValidMethodKind(MethodKind kind) { | |
73 return kind == MethodKind::kNormal || kind == MethodKind::kStatic || | |
74 kind == MethodKind::kGenerator || | |
75 kind == MethodKind::kStaticGenerator || kind == MethodKind::kAsync || | |
76 kind == MethodKind::kStaticAsync; | |
77 } | |
78 | |
79 static inline MethodKind operator|(MethodKind lhs, MethodKind rhs) { | |
80 typedef unsigned char T; | |
81 return static_cast<MethodKind>(static_cast<T>(lhs) | static_cast<T>(rhs)); | |
82 } | |
83 | |
84 static inline MethodKind& operator|=(MethodKind& lhs, const MethodKind& rhs) { | |
85 lhs = lhs | rhs; | |
86 DCHECK(IsValidMethodKind(lhs)); | |
87 return lhs; | |
88 } | |
89 | |
90 static inline bool operator&(MethodKind bitfield, MethodKind mask) { | |
91 typedef unsigned char T; | |
92 return static_cast<T>(bitfield) & static_cast<T>(mask); | |
93 } | |
94 | |
95 inline bool IsNormalMethod(MethodKind kind) { | |
96 return kind == MethodKind::kNormal; | |
97 } | |
98 | |
99 inline bool IsSpecialMethod(MethodKind kind) { | |
100 return kind & MethodKind::kSpecialMask; | |
101 } | |
102 | |
103 inline bool IsStaticMethod(MethodKind kind) { | |
104 return kind & MethodKind::kStatic; | |
105 } | |
106 | |
107 inline bool IsGeneratorMethod(MethodKind kind) { | |
108 return kind & MethodKind::kGenerator; | |
109 } | |
110 | |
111 inline bool IsAsyncMethod(MethodKind kind) { return kind & MethodKind::kAsync; } | |
112 | |
113 struct FormalParametersBase { | 60 struct FormalParametersBase { |
114 explicit FormalParametersBase(DeclarationScope* scope) : scope(scope) {} | 61 explicit FormalParametersBase(DeclarationScope* scope) : scope(scope) {} |
115 DeclarationScope* scope; | 62 DeclarationScope* scope; |
116 bool has_rest = false; | 63 bool has_rest = false; |
117 bool is_simple = true; | 64 bool is_simple = true; |
118 int materialized_literals_count = 0; | 65 int materialized_literals_count = 0; |
119 }; | 66 }; |
120 | 67 |
121 | 68 |
122 // ---------------------------------------------------------------------------- | 69 // ---------------------------------------------------------------------------- |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 // typedef Base; | 124 // typedef Base; |
178 // typedef Impl; | 125 // typedef Impl; |
179 // // TODO(nikolaos): this one will probably go away, as it is | 126 // // TODO(nikolaos): this one will probably go away, as it is |
180 // // not related to pure parsing. | 127 // // not related to pure parsing. |
181 // typedef GeneratorVariable; | 128 // typedef GeneratorVariable; |
182 // // Return types for traversing functions. | 129 // // Return types for traversing functions. |
183 // typedef Identifier; | 130 // typedef Identifier; |
184 // typedef Expression; | 131 // typedef Expression; |
185 // typedef FunctionLiteral; | 132 // typedef FunctionLiteral; |
186 // typedef ObjectLiteralProperty; | 133 // typedef ObjectLiteralProperty; |
| 134 // typedef ClassLiteralProperty; |
187 // typedef ExpressionList; | 135 // typedef ExpressionList; |
188 // typedef PropertyList; | 136 // typedef PropertyList; |
189 // typedef FormalParameters; | 137 // typedef FormalParameters; |
190 // typedef Statement; | 138 // typedef Statement; |
191 // typedef StatementList; | 139 // typedef StatementList; |
192 // typedef Block; | 140 // typedef Block; |
193 // // For constructing objects returned by the traversing functions. | 141 // // For constructing objects returned by the traversing functions. |
194 // typedef Factory; | 142 // typedef Factory; |
195 // // For other implementation-specific tasks. | 143 // // For other implementation-specific tasks. |
196 // typedef Target; | 144 // typedef Target; |
197 // typedef TargetScope; | 145 // typedef TargetScope; |
198 // }; | 146 // }; |
199 | 147 |
200 template <typename Impl> | 148 template <typename Impl> |
201 struct ParserTypes; | 149 struct ParserTypes; |
202 | 150 |
203 template <typename Impl> | 151 template <typename Impl> |
204 class ParserBase { | 152 class ParserBase { |
205 public: | 153 public: |
206 // Shorten type names defined by ParserTypes<Impl>. | 154 // Shorten type names defined by ParserTypes<Impl>. |
207 typedef ParserTypes<Impl> Types; | 155 typedef ParserTypes<Impl> Types; |
208 typedef typename Types::Identifier IdentifierT; | 156 typedef typename Types::Identifier IdentifierT; |
209 typedef typename Types::Expression ExpressionT; | 157 typedef typename Types::Expression ExpressionT; |
210 typedef typename Types::FunctionLiteral FunctionLiteralT; | 158 typedef typename Types::FunctionLiteral FunctionLiteralT; |
211 typedef typename Types::ObjectLiteralProperty ObjectLiteralPropertyT; | 159 typedef typename Types::ObjectLiteralProperty ObjectLiteralPropertyT; |
| 160 typedef typename Types::ClassLiteralProperty ClassLiteralPropertyT; |
212 typedef typename Types::ExpressionList ExpressionListT; | 161 typedef typename Types::ExpressionList ExpressionListT; |
213 typedef typename Types::PropertyList PropertyListT; | 162 typedef typename Types::PropertyList PropertyListT; |
214 typedef typename Types::FormalParameters FormalParametersT; | 163 typedef typename Types::FormalParameters FormalParametersT; |
215 typedef typename Types::Statement StatementT; | 164 typedef typename Types::Statement StatementT; |
216 typedef typename Types::StatementList StatementListT; | 165 typedef typename Types::StatementList StatementListT; |
217 typedef typename Types::Block BlockT; | 166 typedef typename Types::Block BlockT; |
218 typedef typename v8::internal::ExpressionClassifier<Types> | 167 typedef typename v8::internal::ExpressionClassifier<Types> |
219 ExpressionClassifier; | 168 ExpressionClassifier; |
220 | 169 |
221 // All implementation-specific methods must be called through this. | 170 // All implementation-specific methods must be called through this. |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 }; | 242 }; |
294 | 243 |
295 enum VariableDeclarationContext { | 244 enum VariableDeclarationContext { |
296 kStatementListItem, | 245 kStatementListItem, |
297 kStatement, | 246 kStatement, |
298 kForStatement | 247 kForStatement |
299 }; | 248 }; |
300 // clang-format on | 249 // clang-format on |
301 | 250 |
302 class Checkpoint; | 251 class Checkpoint; |
303 class ObjectLiteralCheckerBase; | 252 class ClassLiteralChecker; |
| 253 class ObjectLiteralChecker; |
304 | 254 |
305 // --------------------------------------------------------------------------- | 255 // --------------------------------------------------------------------------- |
306 // ScopeState and its subclasses implement the parser's scope stack. | 256 // ScopeState and its subclasses implement the parser's scope stack. |
307 // ScopeState keeps track of the current scope, and the outer ScopeState. The | 257 // ScopeState keeps track of the current scope, and the outer ScopeState. The |
308 // parser's scope_state_ points to the top ScopeState. ScopeState's | 258 // parser's scope_state_ points to the top ScopeState. ScopeState's |
309 // constructor push on the scope stack and the destructors pop. BlockState and | 259 // constructor push on the scope stack and the destructors pop. BlockState and |
310 // FunctionState are used to hold additional per-block and per-function state. | 260 // FunctionState are used to hold additional per-block and per-function state. |
311 class ScopeState BASE_EMBEDDED { | 261 class ScopeState BASE_EMBEDDED { |
312 public: | 262 public: |
313 V8_INLINE Scope* scope() const { return scope_; } | 263 V8_INLINE Scope* scope() const { return scope_; } |
(...skipping 826 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1140 enum class PropertyKind { | 1090 enum class PropertyKind { |
1141 kAccessorProperty, | 1091 kAccessorProperty, |
1142 kValueProperty, | 1092 kValueProperty, |
1143 kShorthandProperty, | 1093 kShorthandProperty, |
1144 kMethodProperty, | 1094 kMethodProperty, |
1145 kNotSet | 1095 kNotSet |
1146 }; | 1096 }; |
1147 | 1097 |
1148 bool SetPropertyKindFromToken(Token::Value token, PropertyKind* kind); | 1098 bool SetPropertyKindFromToken(Token::Value token, PropertyKind* kind); |
1149 ExpressionT ParsePropertyName(IdentifierT* name, PropertyKind* kind, | 1099 ExpressionT ParsePropertyName(IdentifierT* name, PropertyKind* kind, |
1150 bool in_class, bool* is_generator, bool* is_get, | 1100 bool* is_generator, bool* is_get, bool* is_set, |
1151 bool* is_set, bool* is_async, bool* is_static, | 1101 bool* is_async, bool* is_computed_name, |
1152 bool* is_computed_name, bool* ok); | 1102 bool* ok); |
1153 | |
1154 ExpressionT ParseObjectLiteral(bool* ok); | 1103 ExpressionT ParseObjectLiteral(bool* ok); |
1155 ObjectLiteralPropertyT ParsePropertyDefinition( | 1104 ClassLiteralPropertyT ParseClassPropertyDefinition( |
1156 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 1105 ClassLiteralChecker* checker, bool has_extends, bool* is_computed_name, |
1157 bool* is_computed_name, bool* has_seen_constructor, IdentifierT* name, | 1106 bool* has_seen_constructor, IdentifierT* name, bool* ok); |
| 1107 ObjectLiteralPropertyT ParseObjectPropertyDefinition( |
| 1108 ObjectLiteralChecker* checker, bool* is_computed_name, IdentifierT* name, |
1158 bool* ok); | 1109 bool* ok); |
1159 ExpressionListT ParseArguments(Scanner::Location* first_spread_pos, | 1110 ExpressionListT ParseArguments(Scanner::Location* first_spread_pos, |
1160 bool maybe_arrow, bool* ok); | 1111 bool maybe_arrow, bool* ok); |
1161 ExpressionListT ParseArguments(Scanner::Location* first_spread_pos, | 1112 ExpressionListT ParseArguments(Scanner::Location* first_spread_pos, |
1162 bool* ok) { | 1113 bool* ok) { |
1163 return ParseArguments(first_spread_pos, false, ok); | 1114 return ParseArguments(first_spread_pos, false, ok); |
1164 } | 1115 } |
1165 | 1116 |
1166 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); | 1117 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); |
1167 ExpressionT ParseYieldExpression(bool accept_IN, bool* ok); | 1118 ExpressionT ParseYieldExpression(bool accept_IN, bool* ok); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1259 if (is_sloppy(scope->language_mode())) { | 1210 if (is_sloppy(scope->language_mode())) { |
1260 // For sloppy scopes we also have to record the call at function level, | 1211 // For sloppy scopes we also have to record the call at function level, |
1261 // in case it includes declarations that will be hoisted. | 1212 // in case it includes declarations that will be hoisted. |
1262 scope->GetDeclarationScope()->RecordEvalCall(); | 1213 scope->GetDeclarationScope()->RecordEvalCall(); |
1263 } | 1214 } |
1264 return Call::IS_POSSIBLY_EVAL; | 1215 return Call::IS_POSSIBLY_EVAL; |
1265 } | 1216 } |
1266 return Call::NOT_EVAL; | 1217 return Call::NOT_EVAL; |
1267 } | 1218 } |
1268 | 1219 |
1269 class ObjectLiteralCheckerBase { | |
1270 public: | |
1271 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {} | |
1272 | |
1273 virtual void CheckProperty(Token::Value property, PropertyKind type, | |
1274 MethodKind method_type, bool* ok) = 0; | |
1275 | |
1276 virtual ~ObjectLiteralCheckerBase() {} | |
1277 | |
1278 protected: | |
1279 ParserBase* parser() const { return parser_; } | |
1280 Scanner* scanner() const { return parser_->scanner(); } | |
1281 | |
1282 private: | |
1283 ParserBase* parser_; | |
1284 }; | |
1285 | |
1286 // Validation per ES6 object literals. | 1220 // Validation per ES6 object literals. |
1287 class ObjectLiteralChecker : public ObjectLiteralCheckerBase { | 1221 class ObjectLiteralChecker { |
1288 public: | 1222 public: |
1289 explicit ObjectLiteralChecker(ParserBase* parser) | 1223 explicit ObjectLiteralChecker(ParserBase* parser) |
1290 : ObjectLiteralCheckerBase(parser), has_seen_proto_(false) {} | 1224 : parser_(parser), has_seen_proto_(false) {} |
1291 | 1225 |
1292 void CheckProperty(Token::Value property, PropertyKind type, | 1226 void CheckDuplicateProto(Token::Value property); |
1293 MethodKind method_type, bool* ok) override; | |
1294 | 1227 |
1295 private: | 1228 private: |
1296 bool IsProto() { return this->scanner()->LiteralMatches("__proto__", 9); } | 1229 bool IsProto() { return this->scanner()->LiteralMatches("__proto__", 9); } |
1297 | 1230 |
| 1231 ParserBase* parser() const { return parser_; } |
| 1232 Scanner* scanner() const { return parser_->scanner(); } |
| 1233 |
| 1234 ParserBase* parser_; |
1298 bool has_seen_proto_; | 1235 bool has_seen_proto_; |
1299 }; | 1236 }; |
1300 | 1237 |
1301 // Validation per ES6 class literals. | 1238 // Validation per ES6 class literals. |
1302 class ClassLiteralChecker : public ObjectLiteralCheckerBase { | 1239 class ClassLiteralChecker { |
1303 public: | 1240 public: |
1304 explicit ClassLiteralChecker(ParserBase* parser) | 1241 explicit ClassLiteralChecker(ParserBase* parser) |
1305 : ObjectLiteralCheckerBase(parser), has_seen_constructor_(false) {} | 1242 : parser_(parser), has_seen_constructor_(false) {} |
1306 | 1243 |
1307 void CheckProperty(Token::Value property, PropertyKind type, | 1244 void CheckClassMethodName(Token::Value property, PropertyKind type, |
1308 MethodKind method_type, bool* ok) override; | 1245 bool is_generator, bool is_async, bool is_static, |
| 1246 bool* ok); |
1309 | 1247 |
1310 private: | 1248 private: |
1311 bool IsConstructor() { | 1249 bool IsConstructor() { |
1312 return this->scanner()->LiteralMatches("constructor", 11); | 1250 return this->scanner()->LiteralMatches("constructor", 11); |
1313 } | 1251 } |
1314 bool IsPrototype() { | 1252 bool IsPrototype() { |
1315 return this->scanner()->LiteralMatches("prototype", 9); | 1253 return this->scanner()->LiteralMatches("prototype", 9); |
1316 } | 1254 } |
1317 | 1255 |
| 1256 ParserBase* parser() const { return parser_; } |
| 1257 Scanner* scanner() const { return parser_->scanner(); } |
| 1258 |
| 1259 ParserBase* parser_; |
1318 bool has_seen_constructor_; | 1260 bool has_seen_constructor_; |
1319 }; | 1261 }; |
1320 | 1262 |
1321 ModuleDescriptor* module() const { | 1263 ModuleDescriptor* module() const { |
1322 return scope()->AsModuleScope()->module(); | 1264 return scope()->AsModuleScope()->module(); |
1323 } | 1265 } |
1324 Scope* scope() const { return scope_state_->scope(); } | 1266 Scope* scope() const { return scope_state_->scope(); } |
1325 | 1267 |
1326 // Stack of expression classifiers. | 1268 // Stack of expression classifiers. |
1327 // The top of the stack is always pointed to by classifier(). | 1269 // The top of the stack is always pointed to by classifier(). |
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1950 *kind = PropertyKind::kMethodProperty; | 1892 *kind = PropertyKind::kMethodProperty; |
1951 return true; | 1893 return true; |
1952 default: | 1894 default: |
1953 break; | 1895 break; |
1954 } | 1896 } |
1955 return false; | 1897 return false; |
1956 } | 1898 } |
1957 | 1899 |
1958 template <class Impl> | 1900 template <class Impl> |
1959 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName( | 1901 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName( |
1960 IdentifierT* name, PropertyKind* kind, bool in_class, bool* is_generator, | 1902 IdentifierT* name, PropertyKind* kind, bool* is_generator, bool* is_get, |
1961 bool* is_get, bool* is_set, bool* is_async, bool* is_static, | 1903 bool* is_set, bool* is_async, bool* is_computed_name, bool* ok) { |
1962 bool* is_computed_name, bool* ok) { | |
1963 DCHECK(*kind == PropertyKind::kNotSet); | 1904 DCHECK(*kind == PropertyKind::kNotSet); |
1964 DCHECK(!*is_generator); | 1905 DCHECK(!*is_generator); |
1965 DCHECK(!*is_get); | 1906 DCHECK(!*is_get); |
1966 DCHECK(!*is_set); | 1907 DCHECK(!*is_set); |
1967 DCHECK(!*is_async); | 1908 DCHECK(!*is_async); |
1968 DCHECK(!*is_static); | |
1969 DCHECK(!*is_computed_name); | 1909 DCHECK(!*is_computed_name); |
1970 | 1910 |
1971 *is_generator = Check(Token::MUL); | 1911 *is_generator = Check(Token::MUL); |
1972 if (*is_generator) { | 1912 if (*is_generator) { |
1973 *kind = PropertyKind::kMethodProperty; | 1913 *kind = PropertyKind::kMethodProperty; |
1974 } | 1914 } |
1975 | 1915 |
1976 Token::Value token = peek(); | 1916 Token::Value token = peek(); |
1977 int pos = peek_position(); | 1917 int pos = peek_position(); |
1978 | 1918 |
1979 if (in_class && !*is_generator && token == Token::STATIC) { | |
1980 Consume(Token::STATIC); | |
1981 *kind = PropertyKind::kMethodProperty; | |
1982 if (peek() == Token::LPAREN) { | |
1983 *name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static' | |
1984 return factory()->NewStringLiteral(*name, pos); | |
1985 } | |
1986 *is_generator = Check(Token::MUL); | |
1987 *is_static = true; | |
1988 token = peek(); | |
1989 pos = peek_position(); | |
1990 } | |
1991 | |
1992 if (allow_harmony_async_await() && !*is_generator && token == Token::ASYNC && | 1919 if (allow_harmony_async_await() && !*is_generator && token == Token::ASYNC && |
1993 !scanner()->HasAnyLineTerminatorAfterNext()) { | 1920 !scanner()->HasAnyLineTerminatorAfterNext()) { |
1994 Consume(Token::ASYNC); | 1921 Consume(Token::ASYNC); |
1995 token = peek(); | 1922 token = peek(); |
1996 if (SetPropertyKindFromToken(token, kind)) { | 1923 if (SetPropertyKindFromToken(token, kind)) { |
1997 *name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'async' | 1924 *name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'async' |
1998 impl()->PushLiteralName(*name); | 1925 impl()->PushLiteralName(*name); |
1999 return factory()->NewStringLiteral(*name, pos); | 1926 return factory()->NewStringLiteral(*name, pos); |
2000 } | 1927 } |
2001 *kind = PropertyKind::kMethodProperty; | 1928 *kind = PropertyKind::kMethodProperty; |
2002 *is_async = true; | 1929 *is_async = true; |
2003 pos = peek_position(); | 1930 pos = peek_position(); |
2004 } | 1931 } |
2005 | 1932 |
2006 if (token == Token::IDENTIFIER && !*is_generator && !*is_async) { | 1933 if (token == Token::IDENTIFIER && !*is_generator && !*is_async) { |
2007 // This is checking for 'get' and 'set' in particular. Any other identifier | 1934 // This is checking for 'get' and 'set' in particular. |
2008 // must be the property name, and so SetPropertyKindFromToken will return | |
2009 // true (unless there's a syntax error). | |
2010 Consume(Token::IDENTIFIER); | 1935 Consume(Token::IDENTIFIER); |
2011 token = peek(); | 1936 token = peek(); |
2012 if (SetPropertyKindFromToken(token, kind)) { | 1937 if (SetPropertyKindFromToken(token, kind) || |
| 1938 !scanner()->IsGetOrSet(is_get, is_set)) { |
2013 *name = impl()->GetSymbol(); | 1939 *name = impl()->GetSymbol(); |
2014 impl()->PushLiteralName(*name); | 1940 impl()->PushLiteralName(*name); |
2015 return factory()->NewStringLiteral(*name, pos); | 1941 return factory()->NewStringLiteral(*name, pos); |
2016 } | 1942 } |
2017 scanner()->IsGetOrSet(is_get, is_set); | |
2018 if (!*is_get && !*is_set) { // TODO(bakkot) have IsGetOrSet return a bool | |
2019 Token::Value next = Next(); | |
2020 ReportUnexpectedToken(next); | |
2021 *ok = false; | |
2022 return impl()->EmptyExpression(); | |
2023 } | |
2024 *kind = PropertyKind::kAccessorProperty; | 1943 *kind = PropertyKind::kAccessorProperty; |
2025 pos = peek_position(); | 1944 pos = peek_position(); |
2026 } | 1945 } |
2027 | 1946 |
2028 // For non computed property names we normalize the name a bit: | 1947 // For non computed property names we normalize the name a bit: |
2029 // | 1948 // |
2030 // "12" -> 12 | 1949 // "12" -> 12 |
2031 // 12.3 -> "12.3" | 1950 // 12.3 -> "12.3" |
2032 // 12.30 -> "12.3" | 1951 // 12.30 -> "12.3" |
2033 // identifier -> "identifier" | 1952 // identifier -> "identifier" |
(...skipping 28 matching lines...) Expand all Loading... |
2062 Expect(Token::RBRACK, CHECK_OK); | 1981 Expect(Token::RBRACK, CHECK_OK); |
2063 break; | 1982 break; |
2064 } | 1983 } |
2065 | 1984 |
2066 default: | 1985 default: |
2067 *name = ParseIdentifierName(CHECK_OK); | 1986 *name = ParseIdentifierName(CHECK_OK); |
2068 break; | 1987 break; |
2069 } | 1988 } |
2070 | 1989 |
2071 if (*kind == PropertyKind::kNotSet) { | 1990 if (*kind == PropertyKind::kNotSet) { |
2072 if (!SetPropertyKindFromToken(peek(), kind) || | 1991 SetPropertyKindFromToken(peek(), kind); |
2073 (*kind == PropertyKind::kShorthandProperty && | |
2074 !Token::IsIdentifier(token, language_mode(), this->is_generator(), | |
2075 parsing_module_ || is_async_function()))) { | |
2076 Token::Value next = Next(); | |
2077 ReportUnexpectedToken(next); | |
2078 *ok = false; | |
2079 return impl()->EmptyExpression(); | |
2080 } | |
2081 } | 1992 } |
2082 DCHECK(*kind != PropertyKind::kNotSet); | |
2083 | 1993 |
2084 if (*is_computed_name) { | 1994 if (*is_computed_name) { |
2085 return expression; | 1995 return expression; |
2086 } | 1996 } |
2087 | 1997 |
2088 impl()->PushLiteralName(*name); | 1998 impl()->PushLiteralName(*name); |
2089 | 1999 |
2090 uint32_t index; | 2000 uint32_t index; |
2091 return impl()->IsArrayIndex(*name, &index) | 2001 return impl()->IsArrayIndex(*name, &index) |
2092 ? factory()->NewNumberLiteral(index, pos) | 2002 ? factory()->NewNumberLiteral(index, pos) |
2093 : factory()->NewStringLiteral(*name, pos); | 2003 : factory()->NewStringLiteral(*name, pos); |
2094 } | 2004 } |
2095 | 2005 |
2096 template <typename Impl> | 2006 template <typename Impl> |
2097 typename ParserBase<Impl>::ObjectLiteralPropertyT | 2007 typename ParserBase<Impl>::ClassLiteralPropertyT |
2098 ParserBase<Impl>::ParsePropertyDefinition(ObjectLiteralCheckerBase* checker, | 2008 ParserBase<Impl>::ParseClassPropertyDefinition(ClassLiteralChecker* checker, |
2099 bool in_class, bool has_extends, | 2009 bool has_extends, |
2100 bool* is_computed_name, | 2010 bool* is_computed_name, |
2101 bool* has_seen_constructor, | 2011 bool* has_seen_constructor, |
2102 IdentifierT* name, bool* ok) { | 2012 IdentifierT* name, bool* ok) { |
2103 DCHECK(!in_class || has_seen_constructor != nullptr); | 2013 DCHECK(has_seen_constructor != nullptr); |
2104 bool is_get = false; | 2014 bool is_get = false; |
2105 bool is_set = false; | 2015 bool is_set = false; |
2106 bool is_generator = false; | 2016 bool is_generator = false; |
2107 bool is_async = false; | 2017 bool is_async = false; |
2108 bool is_static = false; | 2018 bool is_static = false; |
2109 PropertyKind kind = PropertyKind::kNotSet; | 2019 PropertyKind kind = PropertyKind::kNotSet; |
2110 | 2020 |
2111 Token::Value name_token = peek(); | 2021 Token::Value name_token = peek(); |
| 2022 |
| 2023 ExpressionT name_expression; |
| 2024 if (name_token == Token::STATIC) { |
| 2025 Consume(Token::STATIC); |
| 2026 if (peek() == Token::LPAREN) { |
| 2027 kind = PropertyKind::kMethodProperty; |
| 2028 *name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static' |
| 2029 name_expression = factory()->NewStringLiteral(*name, position()); |
| 2030 } else { |
| 2031 is_static = true; |
| 2032 name_expression = ParsePropertyName( |
| 2033 name, &kind, &is_generator, &is_get, &is_set, &is_async, |
| 2034 is_computed_name, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
| 2035 } |
| 2036 } else { |
| 2037 name_expression = ParsePropertyName( |
| 2038 name, &kind, &is_generator, &is_get, &is_set, &is_async, |
| 2039 is_computed_name, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
| 2040 } |
| 2041 |
| 2042 switch (kind) { |
| 2043 case PropertyKind::kShorthandProperty: |
| 2044 case PropertyKind::kValueProperty: |
| 2045 ReportUnexpectedToken(Next()); |
| 2046 *ok = false; |
| 2047 return impl()->EmptyClassLiteralProperty(); |
| 2048 |
| 2049 case PropertyKind::kMethodProperty: { |
| 2050 DCHECK(!is_get && !is_set); |
| 2051 |
| 2052 // MethodDefinition |
| 2053 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
| 2054 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
| 2055 |
| 2056 if (!*is_computed_name) { |
| 2057 checker->CheckClassMethodName( |
| 2058 name_token, PropertyKind::kMethodProperty, is_generator, is_async, |
| 2059 is_static, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
| 2060 } |
| 2061 |
| 2062 FunctionKind kind = is_generator |
| 2063 ? FunctionKind::kConciseGeneratorMethod |
| 2064 : is_async ? FunctionKind::kAsyncConciseMethod |
| 2065 : FunctionKind::kConciseMethod; |
| 2066 |
| 2067 if (!is_static && impl()->IsConstructor(*name)) { |
| 2068 *has_seen_constructor = true; |
| 2069 kind = has_extends ? FunctionKind::kSubclassConstructor |
| 2070 : FunctionKind::kBaseConstructor; |
| 2071 } |
| 2072 |
| 2073 ExpressionT value = impl()->ParseFunctionLiteral( |
| 2074 *name, scanner()->location(), kSkipFunctionNameCheck, kind, |
| 2075 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, |
| 2076 language_mode(), CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
| 2077 |
| 2078 return factory()->NewClassLiteralProperty(name_expression, value, |
| 2079 ClassLiteralProperty::METHOD, |
| 2080 is_static, *is_computed_name); |
| 2081 } |
| 2082 |
| 2083 case PropertyKind::kAccessorProperty: { |
| 2084 DCHECK((is_get || is_set) && !is_generator && !is_async); |
| 2085 |
| 2086 if (!*is_computed_name) { |
| 2087 checker->CheckClassMethodName( |
| 2088 name_token, PropertyKind::kAccessorProperty, false, false, |
| 2089 is_static, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
| 2090 // Make sure the name expression is a string since we need a Name for |
| 2091 // Runtime_DefineAccessorPropertyUnchecked and since we can determine |
| 2092 // this statically we can skip the extra runtime check. |
| 2093 name_expression = |
| 2094 factory()->NewStringLiteral(*name, name_expression->position()); |
| 2095 } |
| 2096 |
| 2097 FunctionKind kind = is_get ? FunctionKind::kGetterFunction |
| 2098 : FunctionKind::kSetterFunction; |
| 2099 |
| 2100 ExpressionT value = impl()->ParseFunctionLiteral( |
| 2101 *name, scanner()->location(), kSkipFunctionNameCheck, kind, |
| 2102 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, |
| 2103 language_mode(), CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
| 2104 |
| 2105 return factory()->NewClassLiteralProperty( |
| 2106 name_expression, value, |
| 2107 is_get ? ClassLiteralProperty::GETTER : ClassLiteralProperty::SETTER, |
| 2108 is_static, *is_computed_name); |
| 2109 } |
| 2110 |
| 2111 case PropertyKind::kNotSet: |
| 2112 ReportUnexpectedToken(Next()); |
| 2113 *ok = false; |
| 2114 return impl()->EmptyClassLiteralProperty(); |
| 2115 } |
| 2116 UNREACHABLE(); |
| 2117 return impl()->EmptyClassLiteralProperty(); |
| 2118 } |
| 2119 |
| 2120 template <typename Impl> |
| 2121 typename ParserBase<Impl>::ObjectLiteralPropertyT |
| 2122 ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker, |
| 2123 bool* is_computed_name, |
| 2124 IdentifierT* name, bool* ok) { |
| 2125 bool is_get = false; |
| 2126 bool is_set = false; |
| 2127 bool is_generator = false; |
| 2128 bool is_async = false; |
| 2129 PropertyKind kind = PropertyKind::kNotSet; |
| 2130 |
| 2131 Token::Value name_token = peek(); |
2112 int next_beg_pos = scanner()->peek_location().beg_pos; | 2132 int next_beg_pos = scanner()->peek_location().beg_pos; |
2113 int next_end_pos = scanner()->peek_location().end_pos; | 2133 int next_end_pos = scanner()->peek_location().end_pos; |
2114 | 2134 |
2115 ExpressionT name_expression = | 2135 ExpressionT name_expression = ParsePropertyName( |
2116 ParsePropertyName(name, &kind, in_class, &is_generator, &is_get, &is_set, | 2136 name, &kind, &is_generator, &is_get, &is_set, &is_async, is_computed_name, |
2117 &is_async, &is_static, is_computed_name, | 2137 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2118 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | |
2119 | 2138 |
2120 switch (kind) { | 2139 switch (kind) { |
2121 case PropertyKind::kValueProperty: { | 2140 case PropertyKind::kValueProperty: { |
2122 if (in_class) { | 2141 DCHECK(!is_get && !is_set && !is_generator && !is_async); |
2123 Token::Value next = Next(); | |
2124 ReportUnexpectedToken(next); | |
2125 *ok = false; | |
2126 return impl()->EmptyObjectLiteralProperty(); | |
2127 } | |
2128 | |
2129 DCHECK(!is_get && !is_set && !is_generator && !is_async && !is_static); | |
2130 | 2142 |
2131 if (!*is_computed_name) { | 2143 if (!*is_computed_name) { |
2132 checker->CheckProperty(name_token, PropertyKind::kValueProperty, | 2144 checker->CheckDuplicateProto(name_token); |
2133 MethodKind::kNormal, | |
2134 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | |
2135 } | 2145 } |
2136 Consume(Token::COLON); | 2146 Consume(Token::COLON); |
2137 int beg_pos = peek_position(); | 2147 int beg_pos = peek_position(); |
2138 ExpressionT value = ParseAssignmentExpression( | 2148 ExpressionT value = ParseAssignmentExpression( |
2139 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2149 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2140 CheckDestructuringElement(value, beg_pos, scanner()->location().end_pos); | 2150 CheckDestructuringElement(value, beg_pos, scanner()->location().end_pos); |
2141 | 2151 |
2142 return factory()->NewObjectLiteralProperty(name_expression, value, | 2152 return factory()->NewObjectLiteralProperty(name_expression, value, |
2143 is_static, *is_computed_name); | 2153 *is_computed_name); |
2144 } | 2154 } |
2145 | 2155 |
2146 case PropertyKind::kShorthandProperty: { | 2156 case PropertyKind::kShorthandProperty: { |
2147 // PropertyDefinition | 2157 // PropertyDefinition |
2148 // IdentifierReference | 2158 // IdentifierReference |
2149 // CoverInitializedName | 2159 // CoverInitializedName |
2150 // | 2160 // |
2151 // CoverInitializedName | 2161 // CoverInitializedName |
2152 // IdentifierReference Initializer? | 2162 // IdentifierReference Initializer? |
2153 if (in_class) { | 2163 DCHECK(!is_get && !is_set && !is_generator && !is_async); |
2154 Token::Value next = Next(); | 2164 |
2155 ReportUnexpectedToken(next); | 2165 if (!Token::IsIdentifier(name_token, language_mode(), |
| 2166 this->is_generator(), |
| 2167 parsing_module_ || is_async_function())) { |
| 2168 ReportUnexpectedToken(Next()); |
2156 *ok = false; | 2169 *ok = false; |
2157 return impl()->EmptyObjectLiteralProperty(); | 2170 return impl()->EmptyObjectLiteralProperty(); |
2158 } | 2171 } |
2159 | 2172 |
2160 DCHECK(!is_get && !is_set && !is_generator && !is_async && !is_static && | 2173 DCHECK(!*is_computed_name); |
2161 !*is_computed_name); | |
2162 | 2174 |
2163 if (classifier()->duplicate_finder() != nullptr && | 2175 if (classifier()->duplicate_finder() != nullptr && |
2164 scanner()->FindSymbol(classifier()->duplicate_finder(), 1) != 0) { | 2176 scanner()->FindSymbol(classifier()->duplicate_finder(), 1) != 0) { |
2165 classifier()->RecordDuplicateFormalParameterError( | 2177 classifier()->RecordDuplicateFormalParameterError( |
2166 scanner()->location()); | 2178 scanner()->location()); |
2167 } | 2179 } |
2168 | 2180 |
2169 if (impl()->IsEvalOrArguments(*name) && is_strict(language_mode())) { | 2181 if (impl()->IsEvalOrArguments(*name) && is_strict(language_mode())) { |
2170 classifier()->RecordBindingPatternError( | 2182 classifier()->RecordBindingPatternError( |
2171 scanner()->location(), MessageTemplate::kStrictEvalArguments); | 2183 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
(...skipping 26 matching lines...) Expand all Loading... |
2198 classifier()->RecordExpressionError( | 2210 classifier()->RecordExpressionError( |
2199 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | 2211 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
2200 MessageTemplate::kInvalidCoverInitializedName); | 2212 MessageTemplate::kInvalidCoverInitializedName); |
2201 | 2213 |
2202 impl()->SetFunctionNameFromIdentifierRef(rhs, lhs); | 2214 impl()->SetFunctionNameFromIdentifierRef(rhs, lhs); |
2203 } else { | 2215 } else { |
2204 value = lhs; | 2216 value = lhs; |
2205 } | 2217 } |
2206 | 2218 |
2207 return factory()->NewObjectLiteralProperty( | 2219 return factory()->NewObjectLiteralProperty( |
2208 name_expression, value, ObjectLiteralProperty::COMPUTED, is_static, | 2220 name_expression, value, ObjectLiteralProperty::COMPUTED, false); |
2209 false); | |
2210 } | 2221 } |
2211 | 2222 |
2212 case PropertyKind::kMethodProperty: { | 2223 case PropertyKind::kMethodProperty: { |
2213 DCHECK(!is_get && !is_set); | 2224 DCHECK(!is_get && !is_set); |
2214 | 2225 |
2215 MethodKind method_kind = MethodKind::kNormal; | |
2216 if (is_generator) { | |
2217 method_kind |= MethodKind::kGenerator; | |
2218 } | |
2219 if (is_async) { | |
2220 method_kind |= MethodKind::kAsync; | |
2221 } | |
2222 if (is_static) { | |
2223 method_kind |= MethodKind::kStatic; | |
2224 } | |
2225 | |
2226 // MethodDefinition | 2226 // MethodDefinition |
2227 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 2227 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
2228 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 2228 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
2229 | 2229 |
2230 classifier()->RecordPatternError( | 2230 classifier()->RecordPatternError( |
2231 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | 2231 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
2232 MessageTemplate::kInvalidDestructuringTarget); | 2232 MessageTemplate::kInvalidDestructuringTarget); |
2233 | 2233 |
2234 if (!*is_computed_name) { | |
2235 checker->CheckProperty(name_token, PropertyKind::kMethodProperty, | |
2236 method_kind, | |
2237 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | |
2238 } | |
2239 | |
2240 FunctionKind kind = is_generator | 2234 FunctionKind kind = is_generator |
2241 ? FunctionKind::kConciseGeneratorMethod | 2235 ? FunctionKind::kConciseGeneratorMethod |
2242 : is_async ? FunctionKind::kAsyncConciseMethod | 2236 : is_async ? FunctionKind::kAsyncConciseMethod |
2243 : FunctionKind::kConciseMethod; | 2237 : FunctionKind::kConciseMethod; |
2244 | 2238 |
2245 if (in_class && !is_static && impl()->IsConstructor(*name)) { | |
2246 *has_seen_constructor = true; | |
2247 kind = has_extends ? FunctionKind::kSubclassConstructor | |
2248 : FunctionKind::kBaseConstructor; | |
2249 } | |
2250 | |
2251 ExpressionT value = impl()->ParseFunctionLiteral( | 2239 ExpressionT value = impl()->ParseFunctionLiteral( |
2252 *name, scanner()->location(), kSkipFunctionNameCheck, kind, | 2240 *name, scanner()->location(), kSkipFunctionNameCheck, kind, |
2253 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, | 2241 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, |
2254 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2242 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2255 | 2243 |
2256 return factory()->NewObjectLiteralProperty( | 2244 return factory()->NewObjectLiteralProperty( |
2257 name_expression, value, ObjectLiteralProperty::COMPUTED, is_static, | 2245 name_expression, value, ObjectLiteralProperty::COMPUTED, |
2258 *is_computed_name); | 2246 *is_computed_name); |
2259 } | 2247 } |
2260 | 2248 |
2261 case PropertyKind::kAccessorProperty: { | 2249 case PropertyKind::kAccessorProperty: { |
2262 DCHECK((is_get || is_set) && !is_generator && !is_async); | 2250 DCHECK((is_get || is_set) && !(is_set && is_get) && !is_generator && |
2263 | 2251 !is_async); |
2264 MethodKind method_kind = MethodKind::kNormal; | |
2265 if (is_static) { | |
2266 DCHECK(in_class); | |
2267 method_kind |= MethodKind::kStatic; | |
2268 } | |
2269 | 2252 |
2270 classifier()->RecordPatternError( | 2253 classifier()->RecordPatternError( |
2271 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | 2254 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
2272 MessageTemplate::kInvalidDestructuringTarget); | 2255 MessageTemplate::kInvalidDestructuringTarget); |
| 2256 |
2273 if (!*is_computed_name) { | 2257 if (!*is_computed_name) { |
2274 checker->CheckProperty(name_token, PropertyKind::kAccessorProperty, | 2258 // Make sure the name expression is a string since we need a Name for |
2275 method_kind, | 2259 // Runtime_DefineAccessorPropertyUnchecked and since we can determine |
2276 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2260 // this statically we can skip the extra runtime check. |
2277 } | |
2278 | |
2279 FunctionLiteralT value = impl()->ParseFunctionLiteral( | |
2280 *name, scanner()->location(), kSkipFunctionNameCheck, | |
2281 is_get ? FunctionKind::kGetterFunction | |
2282 : FunctionKind::kSetterFunction, | |
2283 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, | |
2284 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | |
2285 | |
2286 // Make sure the name expression is a string since we need a Name for | |
2287 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this | |
2288 // statically we can skip the extra runtime check. | |
2289 if (!*is_computed_name) { | |
2290 name_expression = | 2261 name_expression = |
2291 factory()->NewStringLiteral(*name, name_expression->position()); | 2262 factory()->NewStringLiteral(*name, name_expression->position()); |
2292 } | 2263 } |
2293 | 2264 |
| 2265 FunctionKind kind = is_get ? FunctionKind::kGetterFunction |
| 2266 : FunctionKind::kSetterFunction; |
| 2267 |
| 2268 ExpressionT value = impl()->ParseFunctionLiteral( |
| 2269 *name, scanner()->location(), kSkipFunctionNameCheck, kind, |
| 2270 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, |
| 2271 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2272 |
2294 return factory()->NewObjectLiteralProperty( | 2273 return factory()->NewObjectLiteralProperty( |
2295 name_expression, value, is_get ? ObjectLiteralProperty::GETTER | 2274 name_expression, value, is_get ? ObjectLiteralProperty::GETTER |
2296 : ObjectLiteralProperty::SETTER, | 2275 : ObjectLiteralProperty::SETTER, |
2297 is_static, *is_computed_name); | 2276 *is_computed_name); |
2298 } | 2277 } |
2299 | 2278 |
2300 case PropertyKind::kNotSet: | 2279 case PropertyKind::kNotSet: |
2301 UNREACHABLE(); | 2280 ReportUnexpectedToken(Next()); |
| 2281 *ok = false; |
| 2282 return impl()->EmptyObjectLiteralProperty(); |
2302 } | 2283 } |
2303 UNREACHABLE(); | 2284 UNREACHABLE(); |
2304 return impl()->EmptyObjectLiteralProperty(); | 2285 return impl()->EmptyObjectLiteralProperty(); |
2305 } | 2286 } |
2306 | 2287 |
2307 template <typename Impl> | 2288 template <typename Impl> |
2308 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral( | 2289 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral( |
2309 bool* ok) { | 2290 bool* ok) { |
2310 // ObjectLiteral :: | 2291 // ObjectLiteral :: |
2311 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' | 2292 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' |
2312 | 2293 |
2313 int pos = peek_position(); | 2294 int pos = peek_position(); |
2314 PropertyListT properties = impl()->NewPropertyList(4); | 2295 PropertyListT properties = impl()->NewPropertyList(4); |
2315 int number_of_boilerplate_properties = 0; | 2296 int number_of_boilerplate_properties = 0; |
2316 bool has_computed_names = false; | 2297 bool has_computed_names = false; |
2317 ObjectLiteralChecker checker(this); | 2298 ObjectLiteralChecker checker(this); |
2318 | 2299 |
2319 Expect(Token::LBRACE, CHECK_OK); | 2300 Expect(Token::LBRACE, CHECK_OK); |
2320 | 2301 |
2321 while (peek() != Token::RBRACE) { | 2302 while (peek() != Token::RBRACE) { |
2322 FuncNameInferrer::State fni_state(fni_); | 2303 FuncNameInferrer::State fni_state(fni_); |
2323 | 2304 |
2324 const bool in_class = false; | |
2325 const bool has_extends = false; | |
2326 bool is_computed_name = false; | 2305 bool is_computed_name = false; |
2327 IdentifierT name = impl()->EmptyIdentifier(); | 2306 IdentifierT name = impl()->EmptyIdentifier(); |
2328 ObjectLiteralPropertyT property = | 2307 ObjectLiteralPropertyT property = ParseObjectPropertyDefinition( |
2329 ParsePropertyDefinition(&checker, in_class, has_extends, | 2308 &checker, &is_computed_name, &name, CHECK_OK); |
2330 &is_computed_name, nullptr, &name, CHECK_OK); | |
2331 | 2309 |
2332 if (is_computed_name) { | 2310 if (is_computed_name) { |
2333 has_computed_names = true; | 2311 has_computed_names = true; |
2334 } | 2312 } |
2335 | 2313 |
2336 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. | 2314 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. |
2337 if (!has_computed_names && impl()->IsBoilerplateProperty(property)) { | 2315 if (!has_computed_names && impl()->IsBoilerplateProperty(property)) { |
2338 number_of_boilerplate_properties++; | 2316 number_of_boilerplate_properties++; |
2339 } | 2317 } |
2340 properties->Add(property, zone()); | 2318 properties->Add(property, zone()); |
(...skipping 1857 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4198 default: | 4176 default: |
4199 UNREACHABLE(); | 4177 UNREACHABLE(); |
4200 return impl()->NullStatement(); | 4178 return impl()->NullStatement(); |
4201 } | 4179 } |
4202 } | 4180 } |
4203 | 4181 |
4204 #undef CHECK_OK | 4182 #undef CHECK_OK |
4205 #undef CHECK_OK_CUSTOM | 4183 #undef CHECK_OK_CUSTOM |
4206 | 4184 |
4207 template <typename Impl> | 4185 template <typename Impl> |
4208 void ParserBase<Impl>::ObjectLiteralChecker::CheckProperty( | 4186 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto( |
4209 Token::Value property, PropertyKind type, MethodKind method_type, | 4187 Token::Value property) { |
4210 bool* ok) { | |
4211 DCHECK(!IsStaticMethod(method_type)); | |
4212 DCHECK(!IsSpecialMethod(method_type) || | |
4213 type == PropertyKind::kMethodProperty); | |
4214 | |
4215 if (property == Token::SMI || property == Token::NUMBER) return; | 4188 if (property == Token::SMI || property == Token::NUMBER) return; |
4216 | 4189 |
4217 if (type == PropertyKind::kValueProperty && IsProto()) { | 4190 if (IsProto()) { |
4218 if (has_seen_proto_) { | 4191 if (has_seen_proto_) { |
4219 this->parser()->classifier()->RecordExpressionError( | 4192 this->parser()->classifier()->RecordExpressionError( |
4220 this->scanner()->location(), MessageTemplate::kDuplicateProto); | 4193 this->scanner()->location(), MessageTemplate::kDuplicateProto); |
4221 return; | 4194 return; |
4222 } | 4195 } |
4223 has_seen_proto_ = true; | 4196 has_seen_proto_ = true; |
4224 } | 4197 } |
4225 } | 4198 } |
4226 | 4199 |
4227 template <typename Impl> | 4200 template <typename Impl> |
4228 void ParserBase<Impl>::ClassLiteralChecker::CheckProperty( | 4201 void ParserBase<Impl>::ClassLiteralChecker::CheckClassMethodName( |
4229 Token::Value property, PropertyKind type, MethodKind method_type, | 4202 Token::Value property, PropertyKind type, bool is_generator, bool is_async, |
4230 bool* ok) { | 4203 bool is_static, bool* ok) { |
4231 DCHECK(type == PropertyKind::kMethodProperty || | 4204 DCHECK(type == PropertyKind::kMethodProperty || |
4232 type == PropertyKind::kAccessorProperty); | 4205 type == PropertyKind::kAccessorProperty); |
4233 | 4206 |
4234 if (property == Token::SMI || property == Token::NUMBER) return; | 4207 if (property == Token::SMI || property == Token::NUMBER) return; |
4235 | 4208 |
4236 if (IsStaticMethod(method_type)) { | 4209 if (is_static) { |
4237 if (IsPrototype()) { | 4210 if (IsPrototype()) { |
4238 this->parser()->ReportMessage(MessageTemplate::kStaticPrototype); | 4211 this->parser()->ReportMessage(MessageTemplate::kStaticPrototype); |
4239 *ok = false; | 4212 *ok = false; |
4240 return; | 4213 return; |
4241 } | 4214 } |
4242 } else if (IsConstructor()) { | 4215 } else if (IsConstructor()) { |
4243 const bool is_generator = IsGeneratorMethod(method_type); | |
4244 const bool is_async = IsAsyncMethod(method_type); | |
4245 if (is_generator || is_async || type == PropertyKind::kAccessorProperty) { | 4216 if (is_generator || is_async || type == PropertyKind::kAccessorProperty) { |
4246 MessageTemplate::Template msg = | 4217 MessageTemplate::Template msg = |
4247 is_generator ? MessageTemplate::kConstructorIsGenerator | 4218 is_generator ? MessageTemplate::kConstructorIsGenerator |
4248 : is_async ? MessageTemplate::kConstructorIsAsync | 4219 : is_async ? MessageTemplate::kConstructorIsAsync |
4249 : MessageTemplate::kConstructorIsAccessor; | 4220 : MessageTemplate::kConstructorIsAccessor; |
4250 this->parser()->ReportMessage(msg); | 4221 this->parser()->ReportMessage(msg); |
4251 *ok = false; | 4222 *ok = false; |
4252 return; | 4223 return; |
4253 } | 4224 } |
4254 if (has_seen_constructor_) { | 4225 if (has_seen_constructor_) { |
4255 this->parser()->ReportMessage(MessageTemplate::kDuplicateConstructor); | 4226 this->parser()->ReportMessage(MessageTemplate::kDuplicateConstructor); |
4256 *ok = false; | 4227 *ok = false; |
4257 return; | 4228 return; |
4258 } | 4229 } |
4259 has_seen_constructor_ = true; | 4230 has_seen_constructor_ = true; |
4260 return; | 4231 return; |
4261 } | 4232 } |
4262 } | 4233 } |
4263 | 4234 |
4264 | 4235 |
4265 } // namespace internal | 4236 } // namespace internal |
4266 } // namespace v8 | 4237 } // namespace v8 |
4267 | 4238 |
4268 #endif // V8_PARSING_PARSER_BASE_H | 4239 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |