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_PREPARSER_H | 5 #ifndef V8_PREPARSER_H |
6 #define V8_PREPARSER_H | 6 #define V8_PREPARSER_H |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 } | 131 } |
132 bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; } | 132 bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; } |
133 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); } | 133 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); } |
134 bool allow_harmony_computed_property_names() const { | 134 bool allow_harmony_computed_property_names() const { |
135 return allow_harmony_computed_property_names_; | 135 return allow_harmony_computed_property_names_; |
136 } | 136 } |
137 bool allow_harmony_rest_params() const { | 137 bool allow_harmony_rest_params() const { |
138 return allow_harmony_rest_params_; | 138 return allow_harmony_rest_params_; |
139 } | 139 } |
140 bool allow_harmony_spreadcalls() const { return allow_harmony_spreadcalls_; } | 140 bool allow_harmony_spreadcalls() const { return allow_harmony_spreadcalls_; } |
| 141 bool allow_harmony_destructuring() const { |
| 142 return allow_harmony_destructuring_; |
| 143 } |
141 | 144 |
142 bool allow_strong_mode() const { return allow_strong_mode_; } | 145 bool allow_strong_mode() const { return allow_strong_mode_; } |
143 | 146 |
144 // Setters that determine whether certain syntactical constructs are | 147 // Setters that determine whether certain syntactical constructs are |
145 // allowed to be parsed by this instance of the parser. | 148 // allowed to be parsed by this instance of the parser. |
146 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } | 149 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } |
147 void set_allow_natives(bool allow) { allow_natives_ = allow; } | 150 void set_allow_natives(bool allow) { allow_natives_ = allow; } |
148 void set_allow_harmony_arrow_functions(bool allow) { | 151 void set_allow_harmony_arrow_functions(bool allow) { |
149 allow_harmony_arrow_functions_ = allow; | 152 allow_harmony_arrow_functions_ = allow; |
150 } | 153 } |
(...skipping 15 matching lines...) Expand all Loading... |
166 void set_allow_harmony_computed_property_names(bool allow) { | 169 void set_allow_harmony_computed_property_names(bool allow) { |
167 allow_harmony_computed_property_names_ = allow; | 170 allow_harmony_computed_property_names_ = allow; |
168 } | 171 } |
169 void set_allow_harmony_rest_params(bool allow) { | 172 void set_allow_harmony_rest_params(bool allow) { |
170 allow_harmony_rest_params_ = allow; | 173 allow_harmony_rest_params_ = allow; |
171 } | 174 } |
172 void set_allow_harmony_spreadcalls(bool allow) { | 175 void set_allow_harmony_spreadcalls(bool allow) { |
173 allow_harmony_spreadcalls_ = allow; | 176 allow_harmony_spreadcalls_ = allow; |
174 } | 177 } |
175 void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; } | 178 void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; } |
| 179 void set_allow_harmony_destructuring(bool allow) { |
| 180 allow_harmony_destructuring_ = allow; |
| 181 } |
| 182 |
176 | 183 |
177 protected: | 184 protected: |
178 enum AllowRestrictedIdentifiers { | 185 enum AllowRestrictedIdentifiers { |
179 kAllowRestrictedIdentifiers, | 186 kAllowRestrictedIdentifiers, |
180 kDontAllowRestrictedIdentifiers | 187 kDontAllowRestrictedIdentifiers |
181 }; | 188 }; |
182 | 189 |
183 enum Mode { | 190 enum Mode { |
184 PARSE_LAZILY, | 191 PARSE_LAZILY, |
185 PARSE_EAGERLY | 192 PARSE_EAGERLY |
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
672 } | 679 } |
673 | 680 |
674 void ValidateAssignmentPattern(const ExpressionClassifier* classifier, | 681 void ValidateAssignmentPattern(const ExpressionClassifier* classifier, |
675 bool* ok) { | 682 bool* ok) { |
676 if (!classifier->is_valid_assignment_pattern()) { | 683 if (!classifier->is_valid_assignment_pattern()) { |
677 ReportClassifierError(classifier->assignment_pattern_error()); | 684 ReportClassifierError(classifier->assignment_pattern_error()); |
678 *ok = false; | 685 *ok = false; |
679 } | 686 } |
680 } | 687 } |
681 | 688 |
| 689 void BindingPatternUnexpectedToken(ExpressionClassifier* classifier) { |
| 690 classifier->RecordBindingPatternError( |
| 691 scanner()->location(), "unexpected_token", Token::String(peek())); |
| 692 } |
682 | 693 |
683 // Recursive descent functions: | 694 // Recursive descent functions: |
684 | 695 |
685 // Parses an identifier that is valid for the current scope, in particular it | 696 // Parses an identifier that is valid for the current scope, in particular it |
686 // fails on strict mode future reserved keywords in a strict scope. If | 697 // fails on strict mode future reserved keywords in a strict scope. If |
687 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or | 698 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or |
688 // "arguments" as identifier even in strict mode (this is needed in cases like | 699 // "arguments" as identifier even in strict mode (this is needed in cases like |
689 // "var foo = eval;"). | 700 // "var foo = eval;"). |
690 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok); | 701 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok); |
691 IdentifierT ParseAndClassifyIdentifier(ExpressionClassifier* classifier, | 702 IdentifierT ParseAndClassifyIdentifier(ExpressionClassifier* classifier, |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
850 bool stack_overflow_; | 861 bool stack_overflow_; |
851 | 862 |
852 bool allow_lazy_; | 863 bool allow_lazy_; |
853 bool allow_natives_; | 864 bool allow_natives_; |
854 bool allow_harmony_arrow_functions_; | 865 bool allow_harmony_arrow_functions_; |
855 bool allow_harmony_object_literals_; | 866 bool allow_harmony_object_literals_; |
856 bool allow_harmony_sloppy_; | 867 bool allow_harmony_sloppy_; |
857 bool allow_harmony_computed_property_names_; | 868 bool allow_harmony_computed_property_names_; |
858 bool allow_harmony_rest_params_; | 869 bool allow_harmony_rest_params_; |
859 bool allow_harmony_spreadcalls_; | 870 bool allow_harmony_spreadcalls_; |
| 871 bool allow_harmony_destructuring_; |
860 bool allow_strong_mode_; | 872 bool allow_strong_mode_; |
861 }; | 873 }; |
862 | 874 |
863 | 875 |
864 class PreParserIdentifier { | 876 class PreParserIdentifier { |
865 public: | 877 public: |
866 PreParserIdentifier() : type_(kUnknownIdentifier) {} | 878 PreParserIdentifier() : type_(kUnknownIdentifier) {} |
867 static PreParserIdentifier Default() { | 879 static PreParserIdentifier Default() { |
868 return PreParserIdentifier(kUnknownIdentifier); | 880 return PreParserIdentifier(kUnknownIdentifier); |
869 } | 881 } |
(...skipping 1315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2185 // ClassLiteral | 2197 // ClassLiteral |
2186 // '(' Expression ')' | 2198 // '(' Expression ')' |
2187 // TemplateLiteral | 2199 // TemplateLiteral |
2188 | 2200 |
2189 int beg_pos = scanner()->peek_location().beg_pos; | 2201 int beg_pos = scanner()->peek_location().beg_pos; |
2190 int end_pos = scanner()->peek_location().end_pos; | 2202 int end_pos = scanner()->peek_location().end_pos; |
2191 ExpressionT result = this->EmptyExpression(); | 2203 ExpressionT result = this->EmptyExpression(); |
2192 Token::Value token = peek(); | 2204 Token::Value token = peek(); |
2193 switch (token) { | 2205 switch (token) { |
2194 case Token::THIS: { | 2206 case Token::THIS: { |
| 2207 BindingPatternUnexpectedToken(classifier); |
2195 Consume(Token::THIS); | 2208 Consume(Token::THIS); |
2196 if (is_strong(language_mode())) { | 2209 if (is_strong(language_mode())) { |
2197 // Constructors' usages of 'this' in strong mode are parsed separately. | 2210 // Constructors' usages of 'this' in strong mode are parsed separately. |
2198 // TODO(rossberg): this does not work with arrow functions yet. | 2211 // TODO(rossberg): this does not work with arrow functions yet. |
2199 if (i::IsConstructor(function_state_->kind())) { | 2212 if (i::IsConstructor(function_state_->kind())) { |
2200 ReportMessage("strong_constructor_this"); | 2213 ReportMessage("strong_constructor_this"); |
2201 *ok = false; | 2214 *ok = false; |
2202 break; | 2215 break; |
2203 } | 2216 } |
2204 } | 2217 } |
2205 scope_->RecordThisUsage(); | 2218 scope_->RecordThisUsage(); |
2206 result = this->ThisExpression(scope_, factory(), beg_pos); | 2219 result = this->ThisExpression(scope_, factory(), beg_pos); |
2207 break; | 2220 break; |
2208 } | 2221 } |
2209 | 2222 |
2210 case Token::NULL_LITERAL: | 2223 case Token::NULL_LITERAL: |
2211 case Token::TRUE_LITERAL: | 2224 case Token::TRUE_LITERAL: |
2212 case Token::FALSE_LITERAL: | 2225 case Token::FALSE_LITERAL: |
2213 case Token::SMI: | 2226 BindingPatternUnexpectedToken(classifier); |
2214 case Token::NUMBER: | |
2215 Next(); | 2227 Next(); |
2216 result = | 2228 result = |
2217 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory()); | 2229 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory()); |
| 2230 break; |
| 2231 case Token::SMI: |
| 2232 case Token::NUMBER: |
| 2233 classifier->RecordBindingPatternError(scanner()->location(), |
| 2234 "unexpected_token_number"); |
| 2235 Next(); |
| 2236 result = |
| 2237 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory()); |
2218 break; | 2238 break; |
2219 | 2239 |
2220 case Token::IDENTIFIER: | 2240 case Token::IDENTIFIER: |
2221 case Token::LET: | 2241 case Token::LET: |
2222 case Token::STATIC: | 2242 case Token::STATIC: |
2223 case Token::YIELD: | 2243 case Token::YIELD: |
2224 case Token::FUTURE_STRICT_RESERVED_WORD: { | 2244 case Token::FUTURE_STRICT_RESERVED_WORD: { |
2225 // Using eval or arguments in this context is OK even in strict mode. | 2245 // Using eval or arguments in this context is OK even in strict mode. |
2226 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); | 2246 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); |
2227 result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_, | 2247 result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_, |
2228 factory()); | 2248 factory()); |
2229 break; | 2249 break; |
2230 } | 2250 } |
2231 | 2251 |
2232 case Token::STRING: { | 2252 case Token::STRING: { |
| 2253 classifier->RecordBindingPatternError(scanner()->location(), |
| 2254 "unexpected_token_string"); |
2233 Consume(Token::STRING); | 2255 Consume(Token::STRING); |
2234 result = this->ExpressionFromString(beg_pos, scanner(), factory()); | 2256 result = this->ExpressionFromString(beg_pos, scanner(), factory()); |
2235 break; | 2257 break; |
2236 } | 2258 } |
2237 | 2259 |
2238 case Token::ASSIGN_DIV: | 2260 case Token::ASSIGN_DIV: |
2239 result = this->ParseRegExpLiteral(true, classifier, CHECK_OK); | 2261 result = this->ParseRegExpLiteral(true, classifier, CHECK_OK); |
2240 break; | 2262 break; |
2241 | 2263 |
2242 case Token::DIV: | 2264 case Token::DIV: |
2243 result = this->ParseRegExpLiteral(false, classifier, CHECK_OK); | 2265 result = this->ParseRegExpLiteral(false, classifier, CHECK_OK); |
2244 break; | 2266 break; |
2245 | 2267 |
2246 case Token::LBRACK: | 2268 case Token::LBRACK: |
2247 result = this->ParseArrayLiteral(classifier, CHECK_OK); | 2269 result = this->ParseArrayLiteral(classifier, CHECK_OK); |
2248 break; | 2270 break; |
2249 | 2271 |
2250 case Token::LBRACE: | 2272 case Token::LBRACE: |
2251 result = this->ParseObjectLiteral(classifier, CHECK_OK); | 2273 result = this->ParseObjectLiteral(classifier, CHECK_OK); |
2252 break; | 2274 break; |
2253 | 2275 |
2254 case Token::LPAREN: | 2276 case Token::LPAREN: |
| 2277 BindingPatternUnexpectedToken(classifier); |
2255 Consume(Token::LPAREN); | 2278 Consume(Token::LPAREN); |
2256 classifier->RecordBindingPatternError(scanner()->location(), | |
2257 "unexpected_token", "("); | |
2258 classifier->RecordAssignmentPatternError(scanner()->location(), | |
2259 "unexpected_token", "("); | |
2260 if (allow_harmony_arrow_functions() && Check(Token::RPAREN)) { | 2279 if (allow_harmony_arrow_functions() && Check(Token::RPAREN)) { |
2261 // As a primary expression, the only thing that can follow "()" is "=>". | 2280 // As a primary expression, the only thing that can follow "()" is "=>". |
2262 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); | 2281 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); |
2263 scope->set_start_position(beg_pos); | 2282 scope->set_start_position(beg_pos); |
2264 FormalParameterErrorLocations error_locs; | 2283 FormalParameterErrorLocations error_locs; |
2265 bool has_rest = false; | 2284 bool has_rest = false; |
2266 result = this->ParseArrowFunctionLiteral(scope, error_locs, has_rest, | 2285 result = this->ParseArrowFunctionLiteral(scope, error_locs, has_rest, |
2267 classifier, CHECK_OK); | 2286 classifier, CHECK_OK); |
2268 } else { | 2287 } else { |
2269 // Heuristically try to detect immediately called functions before | 2288 // Heuristically try to detect immediately called functions before |
2270 // seeing the call parentheses. | 2289 // seeing the call parentheses. |
2271 parenthesized_function_ = (peek() == Token::FUNCTION); | 2290 parenthesized_function_ = (peek() == Token::FUNCTION); |
2272 result = this->ParseExpression(true, classifier, CHECK_OK); | 2291 result = this->ParseExpression(true, classifier, CHECK_OK); |
2273 result->increase_parenthesization_level(); | 2292 result->increase_parenthesization_level(); |
2274 Expect(Token::RPAREN, CHECK_OK); | 2293 Expect(Token::RPAREN, CHECK_OK); |
2275 } | 2294 } |
2276 break; | 2295 break; |
2277 | 2296 |
2278 case Token::CLASS: { | 2297 case Token::CLASS: { |
| 2298 BindingPatternUnexpectedToken(classifier); |
2279 Consume(Token::CLASS); | 2299 Consume(Token::CLASS); |
2280 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { | 2300 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { |
2281 ReportMessage("sloppy_lexical"); | 2301 ReportMessage("sloppy_lexical"); |
2282 *ok = false; | 2302 *ok = false; |
2283 break; | 2303 break; |
2284 } | 2304 } |
2285 int class_token_position = position(); | 2305 int class_token_position = position(); |
2286 IdentifierT name = this->EmptyIdentifier(); | 2306 IdentifierT name = this->EmptyIdentifier(); |
2287 bool is_strict_reserved_name = false; | 2307 bool is_strict_reserved_name = false; |
2288 Scanner::Location class_name_location = Scanner::Location::invalid(); | 2308 Scanner::Location class_name_location = Scanner::Location::invalid(); |
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2933 // 'typeof' UnaryExpression | 2953 // 'typeof' UnaryExpression |
2934 // '++' UnaryExpression | 2954 // '++' UnaryExpression |
2935 // '--' UnaryExpression | 2955 // '--' UnaryExpression |
2936 // '+' UnaryExpression | 2956 // '+' UnaryExpression |
2937 // '-' UnaryExpression | 2957 // '-' UnaryExpression |
2938 // '~' UnaryExpression | 2958 // '~' UnaryExpression |
2939 // '!' UnaryExpression | 2959 // '!' UnaryExpression |
2940 | 2960 |
2941 Token::Value op = peek(); | 2961 Token::Value op = peek(); |
2942 if (Token::IsUnaryOp(op)) { | 2962 if (Token::IsUnaryOp(op)) { |
| 2963 BindingPatternUnexpectedToken(classifier); |
| 2964 |
2943 op = Next(); | 2965 op = Next(); |
2944 int pos = position(); | 2966 int pos = position(); |
2945 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); | 2967 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); |
2946 | 2968 |
2947 if (op == Token::DELETE && is_strict(language_mode())) { | 2969 if (op == Token::DELETE && is_strict(language_mode())) { |
2948 if (is_strong(language_mode())) { | 2970 if (is_strong(language_mode())) { |
2949 ReportMessage("strong_delete"); | 2971 ReportMessage("strong_delete"); |
2950 *ok = false; | 2972 *ok = false; |
2951 return this->EmptyExpression(); | 2973 return this->EmptyExpression(); |
2952 } else if (this->IsIdentifier(expression)) { | 2974 } else if (this->IsIdentifier(expression)) { |
2953 // "delete identifier" is a syntax error in strict mode. | 2975 // "delete identifier" is a syntax error in strict mode. |
2954 ReportMessage("strict_delete"); | 2976 ReportMessage("strict_delete"); |
2955 *ok = false; | 2977 *ok = false; |
2956 return this->EmptyExpression(); | 2978 return this->EmptyExpression(); |
2957 } | 2979 } |
2958 } | 2980 } |
2959 | 2981 |
2960 // Allow Traits do rewrite the expression. | 2982 // Allow Traits do rewrite the expression. |
2961 return this->BuildUnaryExpression(expression, op, pos, factory()); | 2983 return this->BuildUnaryExpression(expression, op, pos, factory()); |
2962 } else if (Token::IsCountOp(op)) { | 2984 } else if (Token::IsCountOp(op)) { |
| 2985 BindingPatternUnexpectedToken(classifier); |
2963 op = Next(); | 2986 op = Next(); |
2964 Scanner::Location lhs_location = scanner()->peek_location(); | 2987 Scanner::Location lhs_location = scanner()->peek_location(); |
2965 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK); | 2988 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK); |
2966 expression = this->CheckAndRewriteReferenceExpression( | 2989 expression = this->CheckAndRewriteReferenceExpression( |
2967 expression, lhs_location, "invalid_lhs_in_prefix_op", CHECK_OK); | 2990 expression, lhs_location, "invalid_lhs_in_prefix_op", CHECK_OK); |
2968 this->MarkExpressionAsAssigned(expression); | 2991 this->MarkExpressionAsAssigned(expression); |
2969 | 2992 |
2970 return factory()->NewCountOperation(op, | 2993 return factory()->NewCountOperation(op, |
2971 true /* prefix */, | 2994 true /* prefix */, |
2972 expression, | 2995 expression, |
(...skipping 10 matching lines...) Expand all Loading... |
2983 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, | 3006 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, |
2984 bool* ok) { | 3007 bool* ok) { |
2985 // PostfixExpression :: | 3008 // PostfixExpression :: |
2986 // LeftHandSideExpression ('++' | '--')? | 3009 // LeftHandSideExpression ('++' | '--')? |
2987 | 3010 |
2988 Scanner::Location lhs_location = scanner()->peek_location(); | 3011 Scanner::Location lhs_location = scanner()->peek_location(); |
2989 ExpressionT expression = | 3012 ExpressionT expression = |
2990 this->ParseLeftHandSideExpression(classifier, CHECK_OK); | 3013 this->ParseLeftHandSideExpression(classifier, CHECK_OK); |
2991 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 3014 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
2992 Token::IsCountOp(peek())) { | 3015 Token::IsCountOp(peek())) { |
| 3016 BindingPatternUnexpectedToken(classifier); |
| 3017 |
2993 expression = this->CheckAndRewriteReferenceExpression( | 3018 expression = this->CheckAndRewriteReferenceExpression( |
2994 expression, lhs_location, "invalid_lhs_in_postfix_op", CHECK_OK); | 3019 expression, lhs_location, "invalid_lhs_in_postfix_op", CHECK_OK); |
2995 expression = this->MarkExpressionAsAssigned(expression); | 3020 expression = this->MarkExpressionAsAssigned(expression); |
2996 | 3021 |
2997 Token::Value next = Next(); | 3022 Token::Value next = Next(); |
2998 expression = | 3023 expression = |
2999 factory()->NewCountOperation(next, | 3024 factory()->NewCountOperation(next, |
3000 false /* postfix */, | 3025 false /* postfix */, |
3001 expression, | 3026 expression, |
3002 position()); | 3027 position()); |
3003 } | 3028 } |
3004 return expression; | 3029 return expression; |
3005 } | 3030 } |
3006 | 3031 |
3007 | 3032 |
3008 template <class Traits> | 3033 template <class Traits> |
3009 typename ParserBase<Traits>::ExpressionT | 3034 typename ParserBase<Traits>::ExpressionT |
3010 ParserBase<Traits>::ParseLeftHandSideExpression( | 3035 ParserBase<Traits>::ParseLeftHandSideExpression( |
3011 ExpressionClassifier* classifier, bool* ok) { | 3036 ExpressionClassifier* classifier, bool* ok) { |
3012 // LeftHandSideExpression :: | 3037 // LeftHandSideExpression :: |
3013 // (NewExpression | MemberExpression) ... | 3038 // (NewExpression | MemberExpression) ... |
3014 | 3039 |
3015 ExpressionT result = | 3040 ExpressionT result = |
3016 this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); | 3041 this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); |
3017 | 3042 |
3018 while (true) { | 3043 while (true) { |
3019 switch (peek()) { | 3044 switch (peek()) { |
3020 case Token::LBRACK: { | 3045 case Token::LBRACK: { |
| 3046 BindingPatternUnexpectedToken(classifier); |
3021 Consume(Token::LBRACK); | 3047 Consume(Token::LBRACK); |
3022 int pos = position(); | 3048 int pos = position(); |
3023 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); | 3049 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); |
3024 result = factory()->NewProperty(result, index, pos); | 3050 result = factory()->NewProperty(result, index, pos); |
3025 Expect(Token::RBRACK, CHECK_OK); | 3051 Expect(Token::RBRACK, CHECK_OK); |
3026 break; | 3052 break; |
3027 } | 3053 } |
3028 | 3054 |
3029 case Token::LPAREN: { | 3055 case Token::LPAREN: { |
| 3056 BindingPatternUnexpectedToken(classifier); |
| 3057 |
3030 if (is_strong(language_mode()) && this->IsIdentifier(result) && | 3058 if (is_strong(language_mode()) && this->IsIdentifier(result) && |
3031 this->IsEval(this->AsIdentifier(result))) { | 3059 this->IsEval(this->AsIdentifier(result))) { |
3032 ReportMessage("strong_direct_eval"); | 3060 ReportMessage("strong_direct_eval"); |
3033 *ok = false; | 3061 *ok = false; |
3034 return this->EmptyExpression(); | 3062 return this->EmptyExpression(); |
3035 } | 3063 } |
3036 int pos; | 3064 int pos; |
3037 if (scanner()->current_token() == Token::IDENTIFIER) { | 3065 if (scanner()->current_token() == Token::IDENTIFIER) { |
3038 // For call of an identifier we want to report position of | 3066 // For call of an identifier we want to report position of |
3039 // the identifier as position of the call in the stack trace. | 3067 // the identifier as position of the call in the stack trace. |
(...skipping 29 matching lines...) Expand all Loading... |
3069 args = Traits::PrepareSpreadArguments(args); | 3097 args = Traits::PrepareSpreadArguments(args); |
3070 result = Traits::SpreadCall(result, args, pos); | 3098 result = Traits::SpreadCall(result, args, pos); |
3071 } else { | 3099 } else { |
3072 result = factory()->NewCall(result, args, pos); | 3100 result = factory()->NewCall(result, args, pos); |
3073 } | 3101 } |
3074 if (fni_ != NULL) fni_->RemoveLastFunction(); | 3102 if (fni_ != NULL) fni_->RemoveLastFunction(); |
3075 break; | 3103 break; |
3076 } | 3104 } |
3077 | 3105 |
3078 case Token::PERIOD: { | 3106 case Token::PERIOD: { |
| 3107 BindingPatternUnexpectedToken(classifier); |
3079 Consume(Token::PERIOD); | 3108 Consume(Token::PERIOD); |
3080 int pos = position(); | 3109 int pos = position(); |
3081 IdentifierT name = ParseIdentifierName(CHECK_OK); | 3110 IdentifierT name = ParseIdentifierName(CHECK_OK); |
3082 result = factory()->NewProperty( | 3111 result = factory()->NewProperty( |
3083 result, factory()->NewStringLiteral(name, pos), pos); | 3112 result, factory()->NewStringLiteral(name, pos), pos); |
3084 if (fni_ != NULL) this->PushLiteralName(fni_, name); | 3113 if (fni_ != NULL) this->PushLiteralName(fni_, name); |
3085 break; | 3114 break; |
3086 } | 3115 } |
3087 | 3116 |
3088 default: | 3117 default: |
(...skipping 18 matching lines...) Expand all Loading... |
3107 | 3136 |
3108 // Examples of new expression: | 3137 // Examples of new expression: |
3109 // new foo.bar().baz means (new (foo.bar)()).baz | 3138 // new foo.bar().baz means (new (foo.bar)()).baz |
3110 // new foo()() means (new foo())() | 3139 // new foo()() means (new foo())() |
3111 // new new foo()() means (new (new foo())()) | 3140 // new new foo()() means (new (new foo())()) |
3112 // new new foo means new (new foo) | 3141 // new new foo means new (new foo) |
3113 // new new foo() means new (new foo()) | 3142 // new new foo() means new (new foo()) |
3114 // new new foo().bar().baz means (new (new foo()).bar()).baz | 3143 // new new foo().bar().baz means (new (new foo()).bar()).baz |
3115 | 3144 |
3116 if (peek() == Token::NEW) { | 3145 if (peek() == Token::NEW) { |
| 3146 BindingPatternUnexpectedToken(classifier); |
3117 Consume(Token::NEW); | 3147 Consume(Token::NEW); |
3118 int new_pos = position(); | 3148 int new_pos = position(); |
3119 ExpressionT result = this->EmptyExpression(); | 3149 ExpressionT result = this->EmptyExpression(); |
3120 if (peek() == Token::SUPER) { | 3150 if (peek() == Token::SUPER) { |
3121 const bool is_new = true; | 3151 const bool is_new = true; |
3122 result = ParseSuperExpression(is_new, classifier, CHECK_OK); | 3152 result = ParseSuperExpression(is_new, classifier, CHECK_OK); |
3123 } else { | 3153 } else { |
3124 result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); | 3154 result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); |
3125 } | 3155 } |
3126 if (peek() == Token::LPAREN) { | 3156 if (peek() == Token::LPAREN) { |
(...skipping 30 matching lines...) Expand all Loading... |
3157 // (PrimaryExpression | FunctionLiteral | ClassLiteral) | 3187 // (PrimaryExpression | FunctionLiteral | ClassLiteral) |
3158 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* | 3188 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* |
3159 | 3189 |
3160 // The '[' Expression ']' and '.' Identifier parts are parsed by | 3190 // The '[' Expression ']' and '.' Identifier parts are parsed by |
3161 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the | 3191 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the |
3162 // caller. | 3192 // caller. |
3163 | 3193 |
3164 // Parse the initial primary or function expression. | 3194 // Parse the initial primary or function expression. |
3165 ExpressionT result = this->EmptyExpression(); | 3195 ExpressionT result = this->EmptyExpression(); |
3166 if (peek() == Token::FUNCTION) { | 3196 if (peek() == Token::FUNCTION) { |
| 3197 BindingPatternUnexpectedToken(classifier); |
| 3198 |
3167 Consume(Token::FUNCTION); | 3199 Consume(Token::FUNCTION); |
3168 int function_token_position = position(); | 3200 int function_token_position = position(); |
3169 bool is_generator = Check(Token::MUL); | 3201 bool is_generator = Check(Token::MUL); |
3170 IdentifierT name = this->EmptyIdentifier(); | 3202 IdentifierT name = this->EmptyIdentifier(); |
3171 bool is_strict_reserved_name = false; | 3203 bool is_strict_reserved_name = false; |
3172 Scanner::Location function_name_location = Scanner::Location::invalid(); | 3204 Scanner::Location function_name_location = Scanner::Location::invalid(); |
3173 FunctionLiteral::FunctionType function_type = | 3205 FunctionLiteral::FunctionType function_type = |
3174 FunctionLiteral::ANONYMOUS_EXPRESSION; | 3206 FunctionLiteral::ANONYMOUS_EXPRESSION; |
3175 if (peek_any_identifier()) { | 3207 if (peek_any_identifier()) { |
3176 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 3208 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3277 return factory()->NewAssignment(Token::ASSIGN, left, right, pos); | 3309 return factory()->NewAssignment(Token::ASSIGN, left, right, pos); |
3278 } | 3310 } |
3279 | 3311 |
3280 | 3312 |
3281 template <class Traits> | 3313 template <class Traits> |
3282 typename ParserBase<Traits>::ExpressionT | 3314 typename ParserBase<Traits>::ExpressionT |
3283 ParserBase<Traits>::ParseStrongSuperCallExpression( | 3315 ParserBase<Traits>::ParseStrongSuperCallExpression( |
3284 ExpressionClassifier* classifier, bool* ok) { | 3316 ExpressionClassifier* classifier, bool* ok) { |
3285 // SuperCallExpression :: (strong mode) | 3317 // SuperCallExpression :: (strong mode) |
3286 // 'super' '(' ExpressionList ')' | 3318 // 'super' '(' ExpressionList ')' |
| 3319 BindingPatternUnexpectedToken(classifier); |
3287 | 3320 |
3288 Consume(Token::SUPER); | 3321 Consume(Token::SUPER); |
3289 int pos = position(); | 3322 int pos = position(); |
3290 Scanner::Location super_loc = scanner()->location(); | 3323 Scanner::Location super_loc = scanner()->location(); |
3291 ExpressionT expr = this->SuperReference(scope_, factory()); | 3324 ExpressionT expr = this->SuperReference(scope_, factory()); |
3292 | 3325 |
3293 if (peek() != Token::LPAREN) { | 3326 if (peek() != Token::LPAREN) { |
3294 ReportMessage("strong_constructor_super"); | 3327 ReportMessage("strong_constructor_super"); |
3295 *ok = false; | 3328 *ok = false; |
3296 return this->EmptyExpression(); | 3329 return this->EmptyExpression(); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3373 | 3406 |
3374 template <class Traits> | 3407 template <class Traits> |
3375 typename ParserBase<Traits>::ExpressionT | 3408 typename ParserBase<Traits>::ExpressionT |
3376 ParserBase<Traits>::ParseMemberExpressionContinuation( | 3409 ParserBase<Traits>::ParseMemberExpressionContinuation( |
3377 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) { | 3410 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) { |
3378 // Parses this part of MemberExpression: | 3411 // Parses this part of MemberExpression: |
3379 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* | 3412 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* |
3380 while (true) { | 3413 while (true) { |
3381 switch (peek()) { | 3414 switch (peek()) { |
3382 case Token::LBRACK: { | 3415 case Token::LBRACK: { |
| 3416 BindingPatternUnexpectedToken(classifier); |
| 3417 |
3383 Consume(Token::LBRACK); | 3418 Consume(Token::LBRACK); |
3384 int pos = position(); | 3419 int pos = position(); |
3385 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); | 3420 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); |
3386 expression = factory()->NewProperty(expression, index, pos); | 3421 expression = factory()->NewProperty(expression, index, pos); |
3387 if (fni_ != NULL) { | 3422 if (fni_ != NULL) { |
3388 this->PushPropertyName(fni_, index); | 3423 this->PushPropertyName(fni_, index); |
3389 } | 3424 } |
3390 Expect(Token::RBRACK, CHECK_OK); | 3425 Expect(Token::RBRACK, CHECK_OK); |
3391 break; | 3426 break; |
3392 } | 3427 } |
3393 case Token::PERIOD: { | 3428 case Token::PERIOD: { |
| 3429 BindingPatternUnexpectedToken(classifier); |
| 3430 |
3394 Consume(Token::PERIOD); | 3431 Consume(Token::PERIOD); |
3395 int pos = position(); | 3432 int pos = position(); |
3396 IdentifierT name = ParseIdentifierName(CHECK_OK); | 3433 IdentifierT name = ParseIdentifierName(CHECK_OK); |
3397 expression = factory()->NewProperty( | 3434 expression = factory()->NewProperty( |
3398 expression, factory()->NewStringLiteral(name, pos), pos); | 3435 expression, factory()->NewStringLiteral(name, pos), pos); |
3399 if (fni_ != NULL) { | 3436 if (fni_ != NULL) { |
3400 this->PushLiteralName(fni_, name); | 3437 this->PushLiteralName(fni_, name); |
3401 } | 3438 } |
3402 break; | 3439 break; |
3403 } | 3440 } |
3404 case Token::TEMPLATE_SPAN: | 3441 case Token::TEMPLATE_SPAN: |
3405 case Token::TEMPLATE_TAIL: { | 3442 case Token::TEMPLATE_TAIL: { |
| 3443 BindingPatternUnexpectedToken(classifier); |
3406 int pos; | 3444 int pos; |
3407 if (scanner()->current_token() == Token::IDENTIFIER) { | 3445 if (scanner()->current_token() == Token::IDENTIFIER) { |
3408 pos = position(); | 3446 pos = position(); |
3409 } else { | 3447 } else { |
3410 pos = peek_position(); | 3448 pos = peek_position(); |
3411 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 3449 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
3412 // If the tag function looks like an IIFE, set_parenthesized() to | 3450 // If the tag function looks like an IIFE, set_parenthesized() to |
3413 // force eager compilation. | 3451 // force eager compilation. |
3414 expression->AsFunctionLiteral()->set_should_eager_compile(); | 3452 expression->AsFunctionLiteral()->set_should_eager_compile(); |
3415 } | 3453 } |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3542 int materialized_literal_count = -1; | 3580 int materialized_literal_count = -1; |
3543 int expected_property_count = -1; | 3581 int expected_property_count = -1; |
3544 int handler_count = 0; | 3582 int handler_count = 0; |
3545 Scanner::Location super_loc; | 3583 Scanner::Location super_loc; |
3546 | 3584 |
3547 { | 3585 { |
3548 typename Traits::Type::Factory function_factory(ast_value_factory()); | 3586 typename Traits::Type::Factory function_factory(ast_value_factory()); |
3549 FunctionState function_state(&function_state_, &scope_, scope, | 3587 FunctionState function_state(&function_state_, &scope_, scope, |
3550 kArrowFunction, &function_factory); | 3588 kArrowFunction, &function_factory); |
3551 | 3589 |
| 3590 if (peek() == Token::ARROW) { |
| 3591 BindingPatternUnexpectedToken(classifier); |
| 3592 } |
3552 Expect(Token::ARROW, CHECK_OK); | 3593 Expect(Token::ARROW, CHECK_OK); |
3553 | 3594 |
3554 if (peek() == Token::LBRACE) { | 3595 if (peek() == Token::LBRACE) { |
3555 // Multiple statement body | 3596 // Multiple statement body |
3556 Consume(Token::LBRACE); | 3597 Consume(Token::LBRACE); |
3557 bool is_lazily_parsed = | 3598 bool is_lazily_parsed = |
3558 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); | 3599 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); |
3559 if (is_lazily_parsed) { | 3600 if (is_lazily_parsed) { |
3560 body = this->NewStatementList(0, zone()); | 3601 body = this->NewStatementList(0, zone()); |
3561 this->SkipLazyFunctionBody(&materialized_literal_count, | 3602 this->SkipLazyFunctionBody(&materialized_literal_count, |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3799 *ok = false; | 3840 *ok = false; |
3800 return; | 3841 return; |
3801 } | 3842 } |
3802 has_seen_constructor_ = true; | 3843 has_seen_constructor_ = true; |
3803 return; | 3844 return; |
3804 } | 3845 } |
3805 } | 3846 } |
3806 } } // v8::internal | 3847 } } // v8::internal |
3807 | 3848 |
3808 #endif // V8_PREPARSER_H | 3849 #endif // V8_PREPARSER_H |
OLD | NEW |