Chromium Code Reviews| 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) { | |
|
rossberg
2015/04/27 17:20:24
Nit: is this function worth it, especially since i
arv (Not doing code reviews)
2015/04/27 17:56:55
I think it is worth it. The code gets much more re
Dmitry Lomov (no reviews)
2015/04/28 10:15:49
+1 to arv.
Added more usages.
| |
| 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: |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 2269 // Heuristically try to detect immediately called functions before | 2291 // Heuristically try to detect immediately called functions before |
| 2270 // seeing the call parentheses. | 2292 // seeing the call parentheses. |
| 2271 parenthesized_function_ = (peek() == Token::FUNCTION); | 2293 parenthesized_function_ = (peek() == Token::FUNCTION); |
| 2272 result = this->ParseExpression(true, classifier, CHECK_OK); | 2294 result = this->ParseExpression(true, classifier, CHECK_OK); |
| 2273 result->increase_parenthesization_level(); | 2295 result->increase_parenthesization_level(); |
| 2274 Expect(Token::RPAREN, CHECK_OK); | 2296 Expect(Token::RPAREN, CHECK_OK); |
| 2275 } | 2297 } |
| 2276 break; | 2298 break; |
| 2277 | 2299 |
| 2278 case Token::CLASS: { | 2300 case Token::CLASS: { |
| 2301 BindingPatternUnexpectedToken(classifier); | |
| 2279 Consume(Token::CLASS); | 2302 Consume(Token::CLASS); |
| 2280 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { | 2303 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { |
| 2281 ReportMessage("sloppy_lexical"); | 2304 ReportMessage("sloppy_lexical"); |
| 2282 *ok = false; | 2305 *ok = false; |
| 2283 break; | 2306 break; |
| 2284 } | 2307 } |
| 2285 int class_token_position = position(); | 2308 int class_token_position = position(); |
| 2286 IdentifierT name = this->EmptyIdentifier(); | 2309 IdentifierT name = this->EmptyIdentifier(); |
| 2287 bool is_strict_reserved_name = false; | 2310 bool is_strict_reserved_name = false; |
| 2288 Scanner::Location class_name_location = Scanner::Location::invalid(); | 2311 Scanner::Location class_name_location = Scanner::Location::invalid(); |
| (...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2933 // 'typeof' UnaryExpression | 2956 // 'typeof' UnaryExpression |
| 2934 // '++' UnaryExpression | 2957 // '++' UnaryExpression |
| 2935 // '--' UnaryExpression | 2958 // '--' UnaryExpression |
| 2936 // '+' UnaryExpression | 2959 // '+' UnaryExpression |
| 2937 // '-' UnaryExpression | 2960 // '-' UnaryExpression |
| 2938 // '~' UnaryExpression | 2961 // '~' UnaryExpression |
| 2939 // '!' UnaryExpression | 2962 // '!' UnaryExpression |
| 2940 | 2963 |
| 2941 Token::Value op = peek(); | 2964 Token::Value op = peek(); |
| 2942 if (Token::IsUnaryOp(op)) { | 2965 if (Token::IsUnaryOp(op)) { |
| 2966 classifier->RecordBindingPatternError( | |
| 2967 scanner()->location(), "unexpected_token", Token::String(op)); | |
| 2968 classifier->RecordAssignmentPatternError( | |
| 2969 scanner()->location(), "unexpected_token", Token::String(op)); | |
| 2943 op = Next(); | 2970 op = Next(); |
| 2944 int pos = position(); | 2971 int pos = position(); |
| 2945 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); | 2972 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); |
| 2946 | 2973 |
| 2947 if (op == Token::DELETE && is_strict(language_mode())) { | 2974 if (op == Token::DELETE && is_strict(language_mode())) { |
| 2948 if (is_strong(language_mode())) { | 2975 if (is_strong(language_mode())) { |
| 2949 ReportMessage("strong_delete"); | 2976 ReportMessage("strong_delete"); |
| 2950 *ok = false; | 2977 *ok = false; |
| 2951 return this->EmptyExpression(); | 2978 return this->EmptyExpression(); |
| 2952 } else if (this->IsIdentifier(expression)) { | 2979 } else if (this->IsIdentifier(expression)) { |
| 2953 // "delete identifier" is a syntax error in strict mode. | 2980 // "delete identifier" is a syntax error in strict mode. |
| 2954 ReportMessage("strict_delete"); | 2981 ReportMessage("strict_delete"); |
| 2955 *ok = false; | 2982 *ok = false; |
| 2956 return this->EmptyExpression(); | 2983 return this->EmptyExpression(); |
| 2957 } | 2984 } |
| 2958 } | 2985 } |
| 2959 | 2986 |
| 2960 // Allow Traits do rewrite the expression. | 2987 // Allow Traits do rewrite the expression. |
| 2961 return this->BuildUnaryExpression(expression, op, pos, factory()); | 2988 return this->BuildUnaryExpression(expression, op, pos, factory()); |
| 2962 } else if (Token::IsCountOp(op)) { | 2989 } else if (Token::IsCountOp(op)) { |
| 2990 classifier->RecordBindingPatternError( | |
| 2991 scanner()->location(), "unexpected_token", Token::String(op)); | |
| 2992 classifier->RecordAssignmentPatternError( | |
| 2993 scanner()->location(), "unexpected_token", Token::String(op)); | |
| 2963 op = Next(); | 2994 op = Next(); |
| 2964 Scanner::Location lhs_location = scanner()->peek_location(); | 2995 Scanner::Location lhs_location = scanner()->peek_location(); |
| 2965 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK); | 2996 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK); |
| 2966 expression = this->CheckAndRewriteReferenceExpression( | 2997 expression = this->CheckAndRewriteReferenceExpression( |
| 2967 expression, lhs_location, "invalid_lhs_in_prefix_op", CHECK_OK); | 2998 expression, lhs_location, "invalid_lhs_in_prefix_op", CHECK_OK); |
| 2968 this->MarkExpressionAsAssigned(expression); | 2999 this->MarkExpressionAsAssigned(expression); |
| 2969 | 3000 |
| 2970 return factory()->NewCountOperation(op, | 3001 return factory()->NewCountOperation(op, |
| 2971 true /* prefix */, | 3002 true /* prefix */, |
| 2972 expression, | 3003 expression, |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 2983 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, | 3014 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, |
| 2984 bool* ok) { | 3015 bool* ok) { |
| 2985 // PostfixExpression :: | 3016 // PostfixExpression :: |
| 2986 // LeftHandSideExpression ('++' | '--')? | 3017 // LeftHandSideExpression ('++' | '--')? |
| 2987 | 3018 |
| 2988 Scanner::Location lhs_location = scanner()->peek_location(); | 3019 Scanner::Location lhs_location = scanner()->peek_location(); |
| 2989 ExpressionT expression = | 3020 ExpressionT expression = |
| 2990 this->ParseLeftHandSideExpression(classifier, CHECK_OK); | 3021 this->ParseLeftHandSideExpression(classifier, CHECK_OK); |
| 2991 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 3022 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 2992 Token::IsCountOp(peek())) { | 3023 Token::IsCountOp(peek())) { |
| 3024 classifier->RecordBindingPatternError( | |
|
arv (Not doing code reviews)
2015/04/27 17:56:55
Maybe introduce a RecordPatternError that does bot
Dmitry Lomov (no reviews)
2015/04/28 10:15:49
On second thoughts, I removed all RecordAssignment
| |
| 3025 scanner()->location(), "unexpected_token", Token::String(peek())); | |
| 3026 classifier->RecordAssignmentPatternError( | |
| 3027 scanner()->location(), "unexpected_token", Token::String(peek())); | |
| 3028 | |
| 2993 expression = this->CheckAndRewriteReferenceExpression( | 3029 expression = this->CheckAndRewriteReferenceExpression( |
| 2994 expression, lhs_location, "invalid_lhs_in_postfix_op", CHECK_OK); | 3030 expression, lhs_location, "invalid_lhs_in_postfix_op", CHECK_OK); |
| 2995 expression = this->MarkExpressionAsAssigned(expression); | 3031 expression = this->MarkExpressionAsAssigned(expression); |
| 2996 | 3032 |
| 2997 Token::Value next = Next(); | 3033 Token::Value next = Next(); |
| 2998 expression = | 3034 expression = |
| 2999 factory()->NewCountOperation(next, | 3035 factory()->NewCountOperation(next, |
| 3000 false /* postfix */, | 3036 false /* postfix */, |
| 3001 expression, | 3037 expression, |
| 3002 position()); | 3038 position()); |
| 3003 } | 3039 } |
| 3004 return expression; | 3040 return expression; |
| 3005 } | 3041 } |
| 3006 | 3042 |
| 3007 | 3043 |
| 3008 template <class Traits> | 3044 template <class Traits> |
| 3009 typename ParserBase<Traits>::ExpressionT | 3045 typename ParserBase<Traits>::ExpressionT |
| 3010 ParserBase<Traits>::ParseLeftHandSideExpression( | 3046 ParserBase<Traits>::ParseLeftHandSideExpression( |
| 3011 ExpressionClassifier* classifier, bool* ok) { | 3047 ExpressionClassifier* classifier, bool* ok) { |
| 3012 // LeftHandSideExpression :: | 3048 // LeftHandSideExpression :: |
| 3013 // (NewExpression | MemberExpression) ... | 3049 // (NewExpression | MemberExpression) ... |
| 3014 | 3050 |
| 3015 ExpressionT result = | 3051 ExpressionT result = |
| 3016 this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); | 3052 this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); |
| 3017 | 3053 |
| 3018 while (true) { | 3054 while (true) { |
| 3019 switch (peek()) { | 3055 switch (peek()) { |
| 3020 case Token::LBRACK: { | 3056 case Token::LBRACK: { |
| 3057 BindingPatternUnexpectedToken(classifier); | |
| 3021 Consume(Token::LBRACK); | 3058 Consume(Token::LBRACK); |
| 3022 int pos = position(); | 3059 int pos = position(); |
| 3023 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); | 3060 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); |
| 3024 result = factory()->NewProperty(result, index, pos); | 3061 result = factory()->NewProperty(result, index, pos); |
| 3025 Expect(Token::RBRACK, CHECK_OK); | 3062 Expect(Token::RBRACK, CHECK_OK); |
| 3026 break; | 3063 break; |
| 3027 } | 3064 } |
| 3028 | 3065 |
| 3029 case Token::LPAREN: { | 3066 case Token::LPAREN: { |
| 3067 BindingPatternUnexpectedToken(classifier); | |
| 3068 | |
| 3030 if (is_strong(language_mode()) && this->IsIdentifier(result) && | 3069 if (is_strong(language_mode()) && this->IsIdentifier(result) && |
| 3031 this->IsEval(this->AsIdentifier(result))) { | 3070 this->IsEval(this->AsIdentifier(result))) { |
| 3032 ReportMessage("strong_direct_eval"); | 3071 ReportMessage("strong_direct_eval"); |
| 3033 *ok = false; | 3072 *ok = false; |
| 3034 return this->EmptyExpression(); | 3073 return this->EmptyExpression(); |
| 3035 } | 3074 } |
| 3036 int pos; | 3075 int pos; |
| 3037 if (scanner()->current_token() == Token::IDENTIFIER) { | 3076 if (scanner()->current_token() == Token::IDENTIFIER) { |
| 3038 // For call of an identifier we want to report position of | 3077 // For call of an identifier we want to report position of |
| 3039 // the identifier as position of the call in the stack trace. | 3078 // the identifier as position of the call in the stack trace. |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 3069 args = Traits::PrepareSpreadArguments(args); | 3108 args = Traits::PrepareSpreadArguments(args); |
| 3070 result = Traits::SpreadCall(result, args, pos); | 3109 result = Traits::SpreadCall(result, args, pos); |
| 3071 } else { | 3110 } else { |
| 3072 result = factory()->NewCall(result, args, pos); | 3111 result = factory()->NewCall(result, args, pos); |
| 3073 } | 3112 } |
| 3074 if (fni_ != NULL) fni_->RemoveLastFunction(); | 3113 if (fni_ != NULL) fni_->RemoveLastFunction(); |
| 3075 break; | 3114 break; |
| 3076 } | 3115 } |
| 3077 | 3116 |
| 3078 case Token::PERIOD: { | 3117 case Token::PERIOD: { |
| 3118 BindingPatternUnexpectedToken(classifier); | |
| 3079 Consume(Token::PERIOD); | 3119 Consume(Token::PERIOD); |
| 3080 int pos = position(); | 3120 int pos = position(); |
| 3081 IdentifierT name = ParseIdentifierName(CHECK_OK); | 3121 IdentifierT name = ParseIdentifierName(CHECK_OK); |
| 3082 result = factory()->NewProperty( | 3122 result = factory()->NewProperty( |
| 3083 result, factory()->NewStringLiteral(name, pos), pos); | 3123 result, factory()->NewStringLiteral(name, pos), pos); |
| 3084 if (fni_ != NULL) this->PushLiteralName(fni_, name); | 3124 if (fni_ != NULL) this->PushLiteralName(fni_, name); |
| 3085 break; | 3125 break; |
| 3086 } | 3126 } |
| 3087 | 3127 |
| 3088 default: | 3128 default: |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 3107 | 3147 |
| 3108 // Examples of new expression: | 3148 // Examples of new expression: |
| 3109 // new foo.bar().baz means (new (foo.bar)()).baz | 3149 // new foo.bar().baz means (new (foo.bar)()).baz |
| 3110 // new foo()() means (new foo())() | 3150 // new foo()() means (new foo())() |
| 3111 // new new foo()() means (new (new foo())()) | 3151 // new new foo()() means (new (new foo())()) |
| 3112 // new new foo means new (new foo) | 3152 // new new foo means new (new foo) |
| 3113 // new new foo() means new (new foo()) | 3153 // new new foo() means new (new foo()) |
| 3114 // new new foo().bar().baz means (new (new foo()).bar()).baz | 3154 // new new foo().bar().baz means (new (new foo()).bar()).baz |
| 3115 | 3155 |
| 3116 if (peek() == Token::NEW) { | 3156 if (peek() == Token::NEW) { |
| 3157 BindingPatternUnexpectedToken(classifier); | |
| 3117 Consume(Token::NEW); | 3158 Consume(Token::NEW); |
| 3118 int new_pos = position(); | 3159 int new_pos = position(); |
| 3119 ExpressionT result = this->EmptyExpression(); | 3160 ExpressionT result = this->EmptyExpression(); |
| 3120 if (peek() == Token::SUPER) { | 3161 if (peek() == Token::SUPER) { |
| 3121 const bool is_new = true; | 3162 const bool is_new = true; |
| 3122 result = ParseSuperExpression(is_new, classifier, CHECK_OK); | 3163 result = ParseSuperExpression(is_new, classifier, CHECK_OK); |
| 3123 } else { | 3164 } else { |
| 3124 result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); | 3165 result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); |
| 3125 } | 3166 } |
| 3126 if (peek() == Token::LPAREN) { | 3167 if (peek() == Token::LPAREN) { |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 3157 // (PrimaryExpression | FunctionLiteral | ClassLiteral) | 3198 // (PrimaryExpression | FunctionLiteral | ClassLiteral) |
| 3158 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* | 3199 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* |
| 3159 | 3200 |
| 3160 // The '[' Expression ']' and '.' Identifier parts are parsed by | 3201 // The '[' Expression ']' and '.' Identifier parts are parsed by |
| 3161 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the | 3202 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the |
| 3162 // caller. | 3203 // caller. |
| 3163 | 3204 |
| 3164 // Parse the initial primary or function expression. | 3205 // Parse the initial primary or function expression. |
| 3165 ExpressionT result = this->EmptyExpression(); | 3206 ExpressionT result = this->EmptyExpression(); |
| 3166 if (peek() == Token::FUNCTION) { | 3207 if (peek() == Token::FUNCTION) { |
| 3208 BindingPatternUnexpectedToken(classifier); | |
| 3209 | |
| 3167 Consume(Token::FUNCTION); | 3210 Consume(Token::FUNCTION); |
| 3168 int function_token_position = position(); | 3211 int function_token_position = position(); |
| 3169 bool is_generator = Check(Token::MUL); | 3212 bool is_generator = Check(Token::MUL); |
| 3170 IdentifierT name = this->EmptyIdentifier(); | 3213 IdentifierT name = this->EmptyIdentifier(); |
| 3171 bool is_strict_reserved_name = false; | 3214 bool is_strict_reserved_name = false; |
| 3172 Scanner::Location function_name_location = Scanner::Location::invalid(); | 3215 Scanner::Location function_name_location = Scanner::Location::invalid(); |
| 3173 FunctionLiteral::FunctionType function_type = | 3216 FunctionLiteral::FunctionType function_type = |
| 3174 FunctionLiteral::ANONYMOUS_EXPRESSION; | 3217 FunctionLiteral::ANONYMOUS_EXPRESSION; |
| 3175 if (peek_any_identifier()) { | 3218 if (peek_any_identifier()) { |
| 3176 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 3219 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); | 3320 return factory()->NewAssignment(Token::ASSIGN, left, right, pos); |
| 3278 } | 3321 } |
| 3279 | 3322 |
| 3280 | 3323 |
| 3281 template <class Traits> | 3324 template <class Traits> |
| 3282 typename ParserBase<Traits>::ExpressionT | 3325 typename ParserBase<Traits>::ExpressionT |
| 3283 ParserBase<Traits>::ParseStrongSuperCallExpression( | 3326 ParserBase<Traits>::ParseStrongSuperCallExpression( |
| 3284 ExpressionClassifier* classifier, bool* ok) { | 3327 ExpressionClassifier* classifier, bool* ok) { |
| 3285 // SuperCallExpression :: (strong mode) | 3328 // SuperCallExpression :: (strong mode) |
| 3286 // 'super' '(' ExpressionList ')' | 3329 // 'super' '(' ExpressionList ')' |
| 3330 BindingPatternUnexpectedToken(classifier); | |
| 3287 | 3331 |
| 3288 Consume(Token::SUPER); | 3332 Consume(Token::SUPER); |
| 3289 int pos = position(); | 3333 int pos = position(); |
| 3290 Scanner::Location super_loc = scanner()->location(); | 3334 Scanner::Location super_loc = scanner()->location(); |
| 3291 ExpressionT expr = this->SuperReference(scope_, factory()); | 3335 ExpressionT expr = this->SuperReference(scope_, factory()); |
| 3292 | 3336 |
| 3293 if (peek() != Token::LPAREN) { | 3337 if (peek() != Token::LPAREN) { |
| 3294 ReportMessage("strong_constructor_super"); | 3338 ReportMessage("strong_constructor_super"); |
| 3295 *ok = false; | 3339 *ok = false; |
| 3296 return this->EmptyExpression(); | 3340 return this->EmptyExpression(); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3373 | 3417 |
| 3374 template <class Traits> | 3418 template <class Traits> |
| 3375 typename ParserBase<Traits>::ExpressionT | 3419 typename ParserBase<Traits>::ExpressionT |
| 3376 ParserBase<Traits>::ParseMemberExpressionContinuation( | 3420 ParserBase<Traits>::ParseMemberExpressionContinuation( |
| 3377 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) { | 3421 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) { |
| 3378 // Parses this part of MemberExpression: | 3422 // Parses this part of MemberExpression: |
| 3379 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* | 3423 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* |
| 3380 while (true) { | 3424 while (true) { |
| 3381 switch (peek()) { | 3425 switch (peek()) { |
| 3382 case Token::LBRACK: { | 3426 case Token::LBRACK: { |
| 3427 BindingPatternUnexpectedToken(classifier); | |
| 3428 | |
| 3383 Consume(Token::LBRACK); | 3429 Consume(Token::LBRACK); |
| 3384 int pos = position(); | 3430 int pos = position(); |
| 3385 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); | 3431 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); |
| 3386 expression = factory()->NewProperty(expression, index, pos); | 3432 expression = factory()->NewProperty(expression, index, pos); |
| 3387 if (fni_ != NULL) { | 3433 if (fni_ != NULL) { |
| 3388 this->PushPropertyName(fni_, index); | 3434 this->PushPropertyName(fni_, index); |
| 3389 } | 3435 } |
| 3390 Expect(Token::RBRACK, CHECK_OK); | 3436 Expect(Token::RBRACK, CHECK_OK); |
| 3391 break; | 3437 break; |
| 3392 } | 3438 } |
| 3393 case Token::PERIOD: { | 3439 case Token::PERIOD: { |
| 3440 BindingPatternUnexpectedToken(classifier); | |
| 3441 | |
| 3394 Consume(Token::PERIOD); | 3442 Consume(Token::PERIOD); |
| 3395 int pos = position(); | 3443 int pos = position(); |
| 3396 IdentifierT name = ParseIdentifierName(CHECK_OK); | 3444 IdentifierT name = ParseIdentifierName(CHECK_OK); |
| 3397 expression = factory()->NewProperty( | 3445 expression = factory()->NewProperty( |
| 3398 expression, factory()->NewStringLiteral(name, pos), pos); | 3446 expression, factory()->NewStringLiteral(name, pos), pos); |
| 3399 if (fni_ != NULL) { | 3447 if (fni_ != NULL) { |
| 3400 this->PushLiteralName(fni_, name); | 3448 this->PushLiteralName(fni_, name); |
| 3401 } | 3449 } |
| 3402 break; | 3450 break; |
| 3403 } | 3451 } |
| 3404 case Token::TEMPLATE_SPAN: | 3452 case Token::TEMPLATE_SPAN: |
| 3405 case Token::TEMPLATE_TAIL: { | 3453 case Token::TEMPLATE_TAIL: { |
| 3454 BindingPatternUnexpectedToken(classifier); | |
| 3406 int pos; | 3455 int pos; |
| 3407 if (scanner()->current_token() == Token::IDENTIFIER) { | 3456 if (scanner()->current_token() == Token::IDENTIFIER) { |
| 3408 pos = position(); | 3457 pos = position(); |
| 3409 } else { | 3458 } else { |
| 3410 pos = peek_position(); | 3459 pos = peek_position(); |
| 3411 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 3460 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
| 3412 // If the tag function looks like an IIFE, set_parenthesized() to | 3461 // If the tag function looks like an IIFE, set_parenthesized() to |
| 3413 // force eager compilation. | 3462 // force eager compilation. |
| 3414 expression->AsFunctionLiteral()->set_should_eager_compile(); | 3463 expression->AsFunctionLiteral()->set_should_eager_compile(); |
| 3415 } | 3464 } |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3542 int materialized_literal_count = -1; | 3591 int materialized_literal_count = -1; |
| 3543 int expected_property_count = -1; | 3592 int expected_property_count = -1; |
| 3544 int handler_count = 0; | 3593 int handler_count = 0; |
| 3545 Scanner::Location super_loc; | 3594 Scanner::Location super_loc; |
| 3546 | 3595 |
| 3547 { | 3596 { |
| 3548 typename Traits::Type::Factory function_factory(ast_value_factory()); | 3597 typename Traits::Type::Factory function_factory(ast_value_factory()); |
| 3549 FunctionState function_state(&function_state_, &scope_, scope, | 3598 FunctionState function_state(&function_state_, &scope_, scope, |
| 3550 kArrowFunction, &function_factory); | 3599 kArrowFunction, &function_factory); |
| 3551 | 3600 |
| 3601 if (peek() == Token::ARROW) { | |
| 3602 BindingPatternUnexpectedToken(classifier); | |
| 3603 } | |
| 3552 Expect(Token::ARROW, CHECK_OK); | 3604 Expect(Token::ARROW, CHECK_OK); |
| 3553 | 3605 |
| 3554 if (peek() == Token::LBRACE) { | 3606 if (peek() == Token::LBRACE) { |
| 3555 // Multiple statement body | 3607 // Multiple statement body |
| 3556 Consume(Token::LBRACE); | 3608 Consume(Token::LBRACE); |
| 3557 bool is_lazily_parsed = | 3609 bool is_lazily_parsed = |
| 3558 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); | 3610 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); |
| 3559 if (is_lazily_parsed) { | 3611 if (is_lazily_parsed) { |
| 3560 body = this->NewStatementList(0, zone()); | 3612 body = this->NewStatementList(0, zone()); |
| 3561 this->SkipLazyFunctionBody(&materialized_literal_count, | 3613 this->SkipLazyFunctionBody(&materialized_literal_count, |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3799 *ok = false; | 3851 *ok = false; |
| 3800 return; | 3852 return; |
| 3801 } | 3853 } |
| 3802 has_seen_constructor_ = true; | 3854 has_seen_constructor_ = true; |
| 3803 return; | 3855 return; |
| 3804 } | 3856 } |
| 3805 } | 3857 } |
| 3806 } } // v8::internal | 3858 } } // v8::internal |
| 3807 | 3859 |
| 3808 #endif // V8_PREPARSER_H | 3860 #endif // V8_PREPARSER_H |
| OLD | NEW |