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" |
11 #include "src/func-name-inferrer.h" | 11 #include "src/func-name-inferrer.h" |
12 #include "src/hashmap.h" | 12 #include "src/hashmap.h" |
13 #include "src/scanner.h" | 13 #include "src/scanner.h" |
14 #include "src/scopes.h" | 14 #include "src/scopes.h" |
15 #include "src/token.h" | 15 #include "src/token.h" |
16 | 16 |
17 namespace v8 { | 17 namespace v8 { |
18 namespace internal { | 18 namespace internal { |
19 | 19 |
20 | 20 |
21 // When parsing the formal parameters of a function, we usually don't yet know | 21 // When parsing the formal parameters of a function, we usually don't yet know |
22 // if the function will be strict, so we cannot yet produce errors for | 22 // if the function will be strict, so we cannot yet produce errors for |
23 // parameter names or duplicates. Instead, we remember the locations of these | 23 // parameter names or duplicates. Instead, we remember the locations of these |
24 // errors if they occur and produce the errors later. | 24 // errors if they occur and produce the errors later. |
25 class FormalParameterErrorLocations BASE_EMBEDDED { | 25 class FormalParameterErrorLocations BASE_EMBEDDED { |
26 public: | 26 public: |
27 FormalParameterErrorLocations() | 27 FormalParameterErrorLocations() |
28 : eval_or_arguments_(Scanner::Location::invalid()), | 28 : eval_or_arguments(Scanner::Location::invalid()), |
29 undefined_(Scanner::Location::invalid()), | 29 undefined(Scanner::Location::invalid()), |
30 duplicate_(Scanner::Location::invalid()), | 30 duplicate(Scanner::Location::invalid()), |
31 reserved_(Scanner::Location::invalid()) {} | 31 reserved(Scanner::Location::invalid()) {} |
32 | 32 |
33 Scanner::Location eval_or_arguments_; | 33 Scanner::Location eval_or_arguments; |
34 Scanner::Location undefined_; | 34 Scanner::Location undefined; |
35 Scanner::Location duplicate_; | 35 Scanner::Location duplicate; |
36 Scanner::Location reserved_; | 36 Scanner::Location reserved; |
37 }; | 37 }; |
38 | 38 |
39 | 39 |
40 // Common base class shared between parser and pre-parser. Traits encapsulate | 40 // Common base class shared between parser and pre-parser. Traits encapsulate |
41 // the differences between Parser and PreParser: | 41 // the differences between Parser and PreParser: |
42 | 42 |
43 // - Return types: For example, Parser functions return Expression* and | 43 // - Return types: For example, Parser functions return Expression* and |
44 // PreParser functions return PreParserExpression. | 44 // PreParser functions return PreParserExpression. |
45 | 45 |
46 // - Creating parse tree nodes: Parser generates an AST during the recursive | 46 // - Creating parse tree nodes: Parser generates an AST during the recursive |
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
515 } | 515 } |
516 } | 516 } |
517 | 517 |
518 // Checking the parameter names of a function literal. This has to be done | 518 // Checking the parameter names of a function literal. This has to be done |
519 // after parsing the function, since the function can declare itself strict. | 519 // after parsing the function, since the function can declare itself strict. |
520 void CheckFunctionParameterNames(LanguageMode language_mode, | 520 void CheckFunctionParameterNames(LanguageMode language_mode, |
521 bool strict_params, | 521 bool strict_params, |
522 const FormalParameterErrorLocations& locs, | 522 const FormalParameterErrorLocations& locs, |
523 bool* ok) { | 523 bool* ok) { |
524 if (is_sloppy(language_mode) && !strict_params) return; | 524 if (is_sloppy(language_mode) && !strict_params) return; |
525 if (is_strict(language_mode) && locs.eval_or_arguments_.IsValid()) { | 525 if (is_strict(language_mode) && locs.eval_or_arguments.IsValid()) { |
526 Traits::ReportMessageAt(locs.eval_or_arguments_, "strict_eval_arguments"); | 526 Traits::ReportMessageAt(locs.eval_or_arguments, "strict_eval_arguments"); |
527 *ok = false; | 527 *ok = false; |
528 return; | 528 return; |
529 } | 529 } |
530 if (is_strict(language_mode) && locs.reserved_.IsValid()) { | 530 if (is_strict(language_mode) && locs.reserved.IsValid()) { |
531 Traits::ReportMessageAt(locs.reserved_, "unexpected_strict_reserved"); | 531 Traits::ReportMessageAt(locs.reserved, "unexpected_strict_reserved"); |
532 *ok = false; | 532 *ok = false; |
533 return; | 533 return; |
534 } | 534 } |
535 if (is_strong(language_mode) && locs.undefined_.IsValid()) { | 535 if (is_strong(language_mode) && locs.undefined.IsValid()) { |
536 Traits::ReportMessageAt(locs.undefined_, "strong_undefined"); | 536 Traits::ReportMessageAt(locs.undefined, "strong_undefined"); |
537 *ok = false; | 537 *ok = false; |
538 return; | 538 return; |
539 } | 539 } |
540 // TODO(arv): When we add support for destructuring in setters we also need | 540 // TODO(arv): When we add support for destructuring in setters we also need |
541 // to check for duplicate names. | 541 // to check for duplicate names. |
542 if (locs.duplicate_.IsValid()) { | 542 if (locs.duplicate.IsValid()) { |
543 Traits::ReportMessageAt(locs.duplicate_, "strict_param_dupe"); | 543 Traits::ReportMessageAt(locs.duplicate, "strict_param_dupe"); |
544 *ok = false; | 544 *ok = false; |
545 return; | 545 return; |
546 } | 546 } |
547 } | 547 } |
548 | 548 |
549 // Determine precedence of given token. | 549 // Determine precedence of given token. |
550 static int Precedence(Token::Value token, bool accept_IN) { | 550 static int Precedence(Token::Value token, bool accept_IN) { |
551 if (token == Token::IN && !accept_IN) | 551 if (token == Token::IN && !accept_IN) |
552 return 0; // 0 precedence will terminate binary expression parsing | 552 return 0; // 0 precedence will terminate binary expression parsing |
553 return Token::Precedence(token); | 553 return Token::Precedence(token); |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
939 bool IsValidArrowParamList(FormalParameterErrorLocations* locs, | 939 bool IsValidArrowParamList(FormalParameterErrorLocations* locs, |
940 const Scanner::Location& params_loc) const { | 940 const Scanner::Location& params_loc) const { |
941 ValidArrowParam valid = ValidateArrowParams(); | 941 ValidArrowParam valid = ValidateArrowParams(); |
942 if (ParenthesizationField::decode(code_) == kMultiParenthesizedExpression) { | 942 if (ParenthesizationField::decode(code_) == kMultiParenthesizedExpression) { |
943 return false; | 943 return false; |
944 } | 944 } |
945 switch (valid) { | 945 switch (valid) { |
946 case kInvalidArrowParam: | 946 case kInvalidArrowParam: |
947 return false; | 947 return false; |
948 case kInvalidStrongArrowParam: | 948 case kInvalidStrongArrowParam: |
949 locs->undefined_ = params_loc; | 949 locs->undefined = params_loc; |
950 return true; | 950 return true; |
951 case kInvalidStrictReservedArrowParam: | 951 case kInvalidStrictReservedArrowParam: |
952 locs->reserved_ = params_loc; | 952 locs->reserved = params_loc; |
953 return true; | 953 return true; |
954 case kInvalidStrictEvalArgumentsArrowParam: | 954 case kInvalidStrictEvalArgumentsArrowParam: |
955 locs->eval_or_arguments_ = params_loc; | 955 locs->eval_or_arguments = params_loc; |
956 return true; | 956 return true; |
957 default: | 957 default: |
958 DCHECK_EQ(valid, kValidArrowParam); | 958 DCHECK_EQ(valid, kValidArrowParam); |
959 return true; | 959 return true; |
960 } | 960 } |
961 } | 961 } |
962 | 962 |
963 // At the moment PreParser doesn't track these expression types. | 963 // At the moment PreParser doesn't track these expression types. |
964 bool IsFunctionLiteral() const { return false; } | 964 bool IsFunctionLiteral() const { return false; } |
965 bool IsCallNew() const { return false; } | 965 bool IsCallNew() const { return false; } |
(...skipping 2130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3096 FormalParameterErrorLocations* locs, | 3096 FormalParameterErrorLocations* locs, |
3097 bool* ok) { | 3097 bool* ok) { |
3098 // FormalParameter[Yield,GeneratorParameter] : | 3098 // FormalParameter[Yield,GeneratorParameter] : |
3099 // BindingElement[?Yield, ?GeneratorParameter] | 3099 // BindingElement[?Yield, ?GeneratorParameter] |
3100 bool is_strict_reserved; | 3100 bool is_strict_reserved; |
3101 IdentifierT name = | 3101 IdentifierT name = |
3102 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, ok); | 3102 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, ok); |
3103 if (!*ok) return this->EmptyFormalParameter(); | 3103 if (!*ok) return this->EmptyFormalParameter(); |
3104 | 3104 |
3105 // Store locations for possible future error reports. | 3105 // Store locations for possible future error reports. |
3106 if (!locs->eval_or_arguments_.IsValid() && this->IsEvalOrArguments(name)) { | 3106 if (!locs->eval_or_arguments.IsValid() && this->IsEvalOrArguments(name)) { |
3107 locs->eval_or_arguments_ = scanner()->location(); | 3107 locs->eval_or_arguments = scanner()->location(); |
3108 } | 3108 } |
3109 if (!locs->undefined_.IsValid() && this->IsUndefined(name)) { | 3109 if (!locs->undefined.IsValid() && this->IsUndefined(name)) { |
3110 locs->undefined_ = scanner()->location(); | 3110 locs->undefined = scanner()->location(); |
3111 } | 3111 } |
3112 if (!locs->reserved_.IsValid() && is_strict_reserved) { | 3112 if (!locs->reserved.IsValid() && is_strict_reserved) { |
3113 locs->reserved_ = scanner()->location(); | 3113 locs->reserved = scanner()->location(); |
3114 } | 3114 } |
3115 if (!locs->duplicate_.IsValid() && duplicate_finder != nullptr) { | 3115 if (!locs->duplicate.IsValid() && duplicate_finder != nullptr) { |
3116 int prev_value = scanner()->FindSymbol(duplicate_finder, 1); | 3116 int prev_value = scanner()->FindSymbol(duplicate_finder, 1); |
3117 if (prev_value != 0) locs->duplicate_ = scanner()->location(); | 3117 if (prev_value != 0) locs->duplicate = scanner()->location(); |
3118 } | 3118 } |
3119 | 3119 |
3120 return name; | 3120 return name; |
3121 } | 3121 } |
3122 | 3122 |
3123 | 3123 |
3124 template <class Traits> | 3124 template <class Traits> |
3125 typename ParserBase<Traits>::FormalParameterListT | 3125 typename ParserBase<Traits>::FormalParameterListT |
3126 ParserBase<Traits>::ParseFormalParameterList( | 3126 ParserBase<Traits>::ParseFormalParameterList( |
3127 FormalParameterErrorLocations* locs, bool* is_rest, bool* ok) { | 3127 FormalParameterErrorLocations* locs, bool* is_rest, bool* ok) { |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3469 *ok = false; | 3469 *ok = false; |
3470 return; | 3470 return; |
3471 } | 3471 } |
3472 has_seen_constructor_ = true; | 3472 has_seen_constructor_ = true; |
3473 return; | 3473 return; |
3474 } | 3474 } |
3475 } | 3475 } |
3476 } } // v8::internal | 3476 } } // v8::internal |
3477 | 3477 |
3478 #endif // V8_PREPARSER_H | 3478 #endif // V8_PREPARSER_H |
OLD | NEW |