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

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

Issue 2302643002: Split the AST representation of class properties from object properties (Closed)
Patch Set: rebase 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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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