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/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
10 #include "src/base/hashmap.h" | 10 #include "src/base/hashmap.h" |
(...skipping 12 matching lines...) Expand all Loading... |
23 kFunctionNameIsStrictReserved, | 23 kFunctionNameIsStrictReserved, |
24 kSkipFunctionNameCheck, | 24 kSkipFunctionNameCheck, |
25 kFunctionNameValidityUnknown | 25 kFunctionNameValidityUnknown |
26 }; | 26 }; |
27 | 27 |
28 enum AllowLabelledFunctionStatement { | 28 enum AllowLabelledFunctionStatement { |
29 kAllowLabelledFunctionStatement, | 29 kAllowLabelledFunctionStatement, |
30 kDisallowLabelledFunctionStatement, | 30 kDisallowLabelledFunctionStatement, |
31 }; | 31 }; |
32 | 32 |
33 enum class FunctionBody { Normal, SingleExpression }; | |
34 | |
35 enum class ParseFunctionFlags { | 33 enum class ParseFunctionFlags { |
36 kIsNormal = 0, | 34 kIsNormal = 0, |
37 kIsGenerator = 1, | 35 kIsGenerator = 1, |
38 kIsAsync = 2, | 36 kIsAsync = 2, |
39 kIsDefault = 4 | 37 kIsDefault = 4 |
40 }; | 38 }; |
41 | 39 |
42 static inline ParseFunctionFlags operator|(ParseFunctionFlags lhs, | 40 static inline ParseFunctionFlags operator|(ParseFunctionFlags lhs, |
43 ParseFunctionFlags rhs) { | 41 ParseFunctionFlags rhs) { |
44 typedef unsigned char T; | 42 typedef unsigned char T; |
45 return static_cast<ParseFunctionFlags>(static_cast<T>(lhs) | | 43 return static_cast<ParseFunctionFlags>(static_cast<T>(lhs) | |
46 static_cast<T>(rhs)); | 44 static_cast<T>(rhs)); |
47 } | 45 } |
48 | 46 |
49 static inline ParseFunctionFlags& operator|=(ParseFunctionFlags& lhs, | 47 static inline ParseFunctionFlags& operator|=(ParseFunctionFlags& lhs, |
50 const ParseFunctionFlags& rhs) { | 48 const ParseFunctionFlags& rhs) { |
51 lhs = lhs | rhs; | 49 lhs = lhs | rhs; |
52 return lhs; | 50 return lhs; |
53 } | 51 } |
54 | 52 |
55 static inline bool operator&(ParseFunctionFlags bitfield, | 53 static inline bool operator&(ParseFunctionFlags bitfield, |
56 ParseFunctionFlags mask) { | 54 ParseFunctionFlags mask) { |
57 typedef unsigned char T; | 55 typedef unsigned char T; |
58 return static_cast<T>(bitfield) & static_cast<T>(mask); | 56 return static_cast<T>(bitfield) & static_cast<T>(mask); |
59 } | 57 } |
60 | 58 |
61 enum class MethodKind { | 59 enum class MethodKind { |
62 Normal = 0, | 60 kNormal = 0, |
63 Static = 1 << 0, | 61 kStatic = 1 << 0, |
64 Generator = 1 << 1, | 62 kGenerator = 1 << 1, |
65 StaticGenerator = Static | Generator, | 63 kStaticGenerator = kStatic | kGenerator, |
66 Async = 1 << 2, | 64 kAsync = 1 << 2, |
67 StaticAsync = Static | Async, | 65 kStaticAsync = kStatic | kAsync, |
68 | 66 |
69 /* Any non-ordinary method kinds */ | 67 /* Any non-ordinary method kinds */ |
70 SpecialMask = Generator | Async | 68 kSpecialMask = kGenerator | kAsync |
71 }; | 69 }; |
72 | 70 |
73 inline bool IsValidMethodKind(MethodKind kind) { | 71 inline bool IsValidMethodKind(MethodKind kind) { |
74 return kind == MethodKind::Normal || kind == MethodKind::Static || | 72 return kind == MethodKind::kNormal || kind == MethodKind::kStatic || |
75 kind == MethodKind::Generator || kind == MethodKind::StaticGenerator || | 73 kind == MethodKind::kGenerator || |
76 kind == MethodKind::Async || kind == MethodKind::StaticAsync; | 74 kind == MethodKind::kStaticGenerator || kind == MethodKind::kAsync || |
| 75 kind == MethodKind::kStaticAsync; |
77 } | 76 } |
78 | 77 |
79 static inline MethodKind operator|(MethodKind lhs, MethodKind rhs) { | 78 static inline MethodKind operator|(MethodKind lhs, MethodKind rhs) { |
80 typedef unsigned char T; | 79 typedef unsigned char T; |
81 return static_cast<MethodKind>(static_cast<T>(lhs) | static_cast<T>(rhs)); | 80 return static_cast<MethodKind>(static_cast<T>(lhs) | static_cast<T>(rhs)); |
82 } | 81 } |
83 | 82 |
84 static inline MethodKind& operator|=(MethodKind& lhs, const MethodKind& rhs) { | 83 static inline MethodKind& operator|=(MethodKind& lhs, const MethodKind& rhs) { |
85 lhs = lhs | rhs; | 84 lhs = lhs | rhs; |
86 DCHECK(IsValidMethodKind(lhs)); | 85 DCHECK(IsValidMethodKind(lhs)); |
87 return lhs; | 86 return lhs; |
88 } | 87 } |
89 | 88 |
90 static inline bool operator&(MethodKind bitfield, MethodKind mask) { | 89 static inline bool operator&(MethodKind bitfield, MethodKind mask) { |
91 typedef unsigned char T; | 90 typedef unsigned char T; |
92 return static_cast<T>(bitfield) & static_cast<T>(mask); | 91 return static_cast<T>(bitfield) & static_cast<T>(mask); |
93 } | 92 } |
94 | 93 |
95 inline bool IsNormalMethod(MethodKind kind) { | 94 inline bool IsNormalMethod(MethodKind kind) { |
96 return kind == MethodKind::Normal; | 95 return kind == MethodKind::kNormal; |
97 } | 96 } |
98 | 97 |
99 inline bool IsSpecialMethod(MethodKind kind) { | 98 inline bool IsSpecialMethod(MethodKind kind) { |
100 return kind & MethodKind::SpecialMask; | 99 return kind & MethodKind::kSpecialMask; |
101 } | 100 } |
102 | 101 |
103 inline bool IsStaticMethod(MethodKind kind) { | 102 inline bool IsStaticMethod(MethodKind kind) { |
104 return kind & MethodKind::Static; | 103 return kind & MethodKind::kStatic; |
105 } | 104 } |
106 | 105 |
107 inline bool IsGeneratorMethod(MethodKind kind) { | 106 inline bool IsGeneratorMethod(MethodKind kind) { |
108 return kind & MethodKind::Generator; | 107 return kind & MethodKind::kGenerator; |
109 } | 108 } |
110 | 109 |
111 inline bool IsAsyncMethod(MethodKind kind) { return kind & MethodKind::Async; } | 110 inline bool IsAsyncMethod(MethodKind kind) { return kind & MethodKind::kAsync; } |
112 | 111 |
113 struct FormalParametersBase { | 112 struct FormalParametersBase { |
114 explicit FormalParametersBase(DeclarationScope* scope) : scope(scope) {} | 113 explicit FormalParametersBase(DeclarationScope* scope) : scope(scope) {} |
115 DeclarationScope* scope; | 114 DeclarationScope* scope; |
116 bool has_rest = false; | 115 bool has_rest = false; |
117 bool is_simple = true; | 116 bool is_simple = true; |
118 int materialized_literals_count = 0; | 117 int materialized_literals_count = 0; |
119 }; | 118 }; |
120 | 119 |
121 | 120 |
(...skipping 1813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1935 bool is_get = false; | 1934 bool is_get = false; |
1936 bool is_set = false; | 1935 bool is_set = false; |
1937 bool is_await = false; | 1936 bool is_await = false; |
1938 bool is_generator = Check(Token::MUL); | 1937 bool is_generator = Check(Token::MUL); |
1939 bool is_async = false; | 1938 bool is_async = false; |
1940 const bool is_static = IsStaticMethod(method_kind); | 1939 const bool is_static = IsStaticMethod(method_kind); |
1941 | 1940 |
1942 Token::Value name_token = peek(); | 1941 Token::Value name_token = peek(); |
1943 | 1942 |
1944 if (is_generator) { | 1943 if (is_generator) { |
1945 method_kind |= MethodKind::Generator; | 1944 method_kind |= MethodKind::kGenerator; |
1946 } else if (allow_harmony_async_await() && name_token == Token::ASYNC && | 1945 } else if (allow_harmony_async_await() && name_token == Token::ASYNC && |
1947 !scanner()->HasAnyLineTerminatorAfterNext() && | 1946 !scanner()->HasAnyLineTerminatorAfterNext() && |
1948 PeekAhead() != Token::LPAREN && PeekAhead()) { | 1947 PeekAhead() != Token::LPAREN && PeekAhead()) { |
1949 is_async = true; | 1948 is_async = true; |
1950 } | 1949 } |
1951 | 1950 |
1952 int next_beg_pos = scanner()->peek_location().beg_pos; | 1951 int next_beg_pos = scanner()->peek_location().beg_pos; |
1953 int next_end_pos = scanner()->peek_location().end_pos; | 1952 int next_end_pos = scanner()->peek_location().end_pos; |
1954 ExpressionT name_expression = ParsePropertyName( | 1953 ExpressionT name_expression = ParsePropertyName( |
1955 name, &is_get, &is_set, &is_await, is_computed_name, classifier, | 1954 name, &is_get, &is_set, &is_await, is_computed_name, classifier, |
1956 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1955 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1957 | 1956 |
1958 if (fni_ != nullptr && !*is_computed_name) { | 1957 if (fni_ != nullptr && !*is_computed_name) { |
1959 this->PushLiteralName(fni_, *name); | 1958 this->PushLiteralName(fni_, *name); |
1960 } | 1959 } |
1961 | 1960 |
1962 if (!in_class && !is_generator) { | 1961 if (!in_class && !is_generator) { |
1963 DCHECK(!IsStaticMethod(method_kind)); | 1962 DCHECK(!IsStaticMethod(method_kind)); |
1964 | 1963 |
1965 if (peek() == Token::COLON) { | 1964 if (peek() == Token::COLON) { |
1966 // PropertyDefinition | 1965 // PropertyDefinition |
1967 // PropertyName ':' AssignmentExpression | 1966 // PropertyName ':' AssignmentExpression |
1968 if (!*is_computed_name) { | 1967 if (!*is_computed_name) { |
1969 checker->CheckProperty(name_token, kValueProperty, MethodKind::Normal, | 1968 checker->CheckProperty(name_token, kValueProperty, MethodKind::kNormal, |
1970 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1969 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1971 } | 1970 } |
1972 Consume(Token::COLON); | 1971 Consume(Token::COLON); |
1973 int beg_pos = peek_position(); | 1972 int beg_pos = peek_position(); |
1974 ExpressionT value = this->ParseAssignmentExpression( | 1973 ExpressionT value = this->ParseAssignmentExpression( |
1975 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1974 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1976 CheckDestructuringElement(value, classifier, beg_pos, | 1975 CheckDestructuringElement(value, classifier, beg_pos, |
1977 scanner()->location().end_pos); | 1976 scanner()->location().end_pos); |
1978 | 1977 |
1979 return factory()->NewObjectLiteralProperty(name_expression, value, | 1978 return factory()->NewObjectLiteralProperty(name_expression, value, |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2045 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | 2044 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
2046 MessageTemplate::kInvalidDestructuringTarget); | 2045 MessageTemplate::kInvalidDestructuringTarget); |
2047 | 2046 |
2048 if (is_async && !IsSpecialMethod(method_kind)) { | 2047 if (is_async && !IsSpecialMethod(method_kind)) { |
2049 DCHECK(!is_get); | 2048 DCHECK(!is_get); |
2050 DCHECK(!is_set); | 2049 DCHECK(!is_set); |
2051 bool dont_care; | 2050 bool dont_care; |
2052 name_expression = ParsePropertyName( | 2051 name_expression = ParsePropertyName( |
2053 name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier, | 2052 name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier, |
2054 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2053 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2055 method_kind |= MethodKind::Async; | 2054 method_kind |= MethodKind::kAsync; |
2056 } | 2055 } |
2057 | 2056 |
2058 if (is_generator || peek() == Token::LPAREN) { | 2057 if (is_generator || peek() == Token::LPAREN) { |
2059 // MethodDefinition | 2058 // MethodDefinition |
2060 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 2059 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
2061 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 2060 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
2062 if (!*is_computed_name) { | 2061 if (!*is_computed_name) { |
2063 checker->CheckProperty(name_token, kMethodProperty, method_kind, | 2062 checker->CheckProperty(name_token, kMethodProperty, method_kind, |
2064 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2063 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2065 } | 2064 } |
(...skipping 18 matching lines...) Expand all Loading... |
2084 return factory()->NewObjectLiteralProperty(name_expression, value, | 2083 return factory()->NewObjectLiteralProperty(name_expression, value, |
2085 ObjectLiteralProperty::COMPUTED, | 2084 ObjectLiteralProperty::COMPUTED, |
2086 is_static, *is_computed_name); | 2085 is_static, *is_computed_name); |
2087 } | 2086 } |
2088 | 2087 |
2089 if (in_class && name_token == Token::STATIC && IsNormalMethod(method_kind)) { | 2088 if (in_class && name_token == Token::STATIC && IsNormalMethod(method_kind)) { |
2090 // ClassElement (static) | 2089 // ClassElement (static) |
2091 // 'static' MethodDefinition | 2090 // 'static' MethodDefinition |
2092 *name = this->EmptyIdentifier(); | 2091 *name = this->EmptyIdentifier(); |
2093 ObjectLiteralPropertyT property = ParsePropertyDefinition( | 2092 ObjectLiteralPropertyT property = ParsePropertyDefinition( |
2094 checker, true, has_extends, MethodKind::Static, is_computed_name, | 2093 checker, true, has_extends, MethodKind::kStatic, is_computed_name, |
2095 nullptr, classifier, name, ok); | 2094 nullptr, classifier, name, ok); |
2096 Traits::RewriteNonPattern(classifier, ok); | 2095 Traits::RewriteNonPattern(classifier, ok); |
2097 return property; | 2096 return property; |
2098 } | 2097 } |
2099 | 2098 |
2100 if (is_get || is_set) { | 2099 if (is_get || is_set) { |
2101 // MethodDefinition (Accessors) | 2100 // MethodDefinition (Accessors) |
2102 // get PropertyName '(' ')' '{' FunctionBody '}' | 2101 // get PropertyName '(' ')' '{' FunctionBody '}' |
2103 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}' | 2102 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}' |
2104 *name = this->EmptyIdentifier(); | 2103 *name = this->EmptyIdentifier(); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2157 Expect(Token::LBRACE, CHECK_OK); | 2156 Expect(Token::LBRACE, CHECK_OK); |
2158 | 2157 |
2159 while (peek() != Token::RBRACE) { | 2158 while (peek() != Token::RBRACE) { |
2160 FuncNameInferrer::State fni_state(fni_); | 2159 FuncNameInferrer::State fni_state(fni_); |
2161 | 2160 |
2162 const bool in_class = false; | 2161 const bool in_class = false; |
2163 const bool has_extends = false; | 2162 const bool has_extends = false; |
2164 bool is_computed_name = false; | 2163 bool is_computed_name = false; |
2165 IdentifierT name = this->EmptyIdentifier(); | 2164 IdentifierT name = this->EmptyIdentifier(); |
2166 ObjectLiteralPropertyT property = this->ParsePropertyDefinition( | 2165 ObjectLiteralPropertyT property = this->ParsePropertyDefinition( |
2167 &checker, in_class, has_extends, MethodKind::Normal, &is_computed_name, | 2166 &checker, in_class, has_extends, MethodKind::kNormal, &is_computed_name, |
2168 NULL, classifier, &name, CHECK_OK); | 2167 NULL, classifier, &name, CHECK_OK); |
2169 | 2168 |
2170 if (is_computed_name) { | 2169 if (is_computed_name) { |
2171 has_computed_names = true; | 2170 has_computed_names = true; |
2172 } | 2171 } |
2173 | 2172 |
2174 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. | 2173 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. |
2175 if (!has_computed_names && this->IsBoilerplateProperty(property)) { | 2174 if (!has_computed_names && this->IsBoilerplateProperty(property)) { |
2176 number_of_boilerplate_properties++; | 2175 number_of_boilerplate_properties++; |
2177 } | 2176 } |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2323 expression = this->ParseConditionalExpression( | 2322 expression = this->ParseConditionalExpression( |
2324 accept_IN, &arrow_formals_classifier, CHECK_OK); | 2323 accept_IN, &arrow_formals_classifier, CHECK_OK); |
2325 } | 2324 } |
2326 | 2325 |
2327 if (is_async && this->IsIdentifier(expression) && peek_any_identifier() && | 2326 if (is_async && this->IsIdentifier(expression) && peek_any_identifier() && |
2328 PeekAhead() == Token::ARROW) { | 2327 PeekAhead() == Token::ARROW) { |
2329 // async Identifier => AsyncConciseBody | 2328 // async Identifier => AsyncConciseBody |
2330 IdentifierT name = | 2329 IdentifierT name = |
2331 ParseAndClassifyIdentifier(&arrow_formals_classifier, CHECK_OK); | 2330 ParseAndClassifyIdentifier(&arrow_formals_classifier, CHECK_OK); |
2332 expression = this->ExpressionFromIdentifier( | 2331 expression = this->ExpressionFromIdentifier( |
2333 name, position(), scanner()->location().end_pos, InferName::No); | 2332 name, position(), scanner()->location().end_pos, InferName::kNo); |
2334 if (fni_) { | 2333 if (fni_) { |
2335 // Remove `async` keyword from inferred name stack. | 2334 // Remove `async` keyword from inferred name stack. |
2336 fni_->RemoveAsyncKeywordFromEnd(); | 2335 fni_->RemoveAsyncKeywordFromEnd(); |
2337 } | 2336 } |
2338 } | 2337 } |
2339 | 2338 |
2340 if (peek() == Token::ARROW) { | 2339 if (peek() == Token::ARROW) { |
2341 Scanner::Location arrow_loc = scanner()->peek_location(); | 2340 Scanner::Location arrow_loc = scanner()->peek_location(); |
2342 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, | 2341 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, |
2343 parenthesized_formals, is_async, CHECK_OK); | 2342 parenthesized_formals, is_async, CHECK_OK); |
(...skipping 1390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3734 has_seen_constructor_ = true; | 3733 has_seen_constructor_ = true; |
3735 return; | 3734 return; |
3736 } | 3735 } |
3737 } | 3736 } |
3738 | 3737 |
3739 | 3738 |
3740 } // namespace internal | 3739 } // namespace internal |
3741 } // namespace v8 | 3740 } // namespace v8 |
3742 | 3741 |
3743 #endif // V8_PARSING_PARSER_BASE_H | 3742 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |