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 | |
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 | |
23 // parameter names or duplicates. Instead, we remember the locations of these | |
24 // errors if they occur and produce the errors later. | |
25 class FormalParameterErrorLocations BASE_EMBEDDED { | |
26 public: | |
27 FormalParameterErrorLocations() | |
28 : eval_or_arguments(Scanner::Location::invalid()), | |
29 undefined(Scanner::Location::invalid()), | |
30 duplicate(Scanner::Location::invalid()), | |
31 reserved(Scanner::Location::invalid()) {} | |
32 | |
33 Scanner::Location eval_or_arguments; | |
34 Scanner::Location undefined; | |
35 Scanner::Location duplicate; | |
36 Scanner::Location reserved; | |
37 }; | |
38 | |
39 | |
40 // Common base class shared between parser and pre-parser. Traits encapsulate | 20 // Common base class shared between parser and pre-parser. Traits encapsulate |
41 // the differences between Parser and PreParser: | 21 // the differences between Parser and PreParser: |
42 | 22 |
43 // - Return types: For example, Parser functions return Expression* and | 23 // - Return types: For example, Parser functions return Expression* and |
44 // PreParser functions return PreParserExpression. | 24 // PreParser functions return PreParserExpression. |
45 | 25 |
46 // - Creating parse tree nodes: Parser generates an AST during the recursive | 26 // - Creating parse tree nodes: Parser generates an AST during the recursive |
47 // descent. PreParser doesn't create a tree. Instead, it passes around minimal | 27 // descent. PreParser doesn't create a tree. Instead, it passes around minimal |
48 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain | 28 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain |
49 // just enough data for the upper layer functions. PreParserFactory is | 29 // just enough data for the upper layer functions. PreParserFactory is |
(...skipping 14 matching lines...) Expand all Loading... |
64 // typedef GeneratorVariable; | 44 // typedef GeneratorVariable; |
65 // // Return types for traversing functions. | 45 // // Return types for traversing functions. |
66 // typedef Identifier; | 46 // typedef Identifier; |
67 // typedef Expression; | 47 // typedef Expression; |
68 // typedef FunctionLiteral; | 48 // typedef FunctionLiteral; |
69 // typedef ClassLiteral; | 49 // typedef ClassLiteral; |
70 // typedef ObjectLiteralProperty; | 50 // typedef ObjectLiteralProperty; |
71 // typedef Literal; | 51 // typedef Literal; |
72 // typedef ExpressionList; | 52 // typedef ExpressionList; |
73 // typedef PropertyList; | 53 // typedef PropertyList; |
74 // typedef FormalParameter; | |
75 // typedef FormalParameterList; | |
76 // // For constructing objects returned by the traversing functions. | 54 // // For constructing objects returned by the traversing functions. |
77 // typedef Factory; | 55 // typedef Factory; |
78 // }; | 56 // }; |
79 // // ... | 57 // // ... |
80 // }; | 58 // }; |
81 | 59 |
82 template <typename Traits> | 60 template <typename Traits> |
83 class ParserBase : public Traits { | 61 class ParserBase : public Traits { |
84 public: | 62 public: |
85 // Shorten type names defined by Traits. | 63 // Shorten type names defined by Traits. |
86 typedef typename Traits::Type::Expression ExpressionT; | 64 typedef typename Traits::Type::Expression ExpressionT; |
87 typedef typename Traits::Type::Identifier IdentifierT; | 65 typedef typename Traits::Type::Identifier IdentifierT; |
88 typedef typename Traits::Type::FormalParameter FormalParameterT; | |
89 typedef typename Traits::Type::FormalParameterList FormalParameterListT; | |
90 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT; | 66 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT; |
91 typedef typename Traits::Type::Literal LiteralT; | 67 typedef typename Traits::Type::Literal LiteralT; |
92 typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT; | 68 typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT; |
93 | 69 |
94 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit, | 70 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit, |
95 v8::Extension* extension, AstValueFactory* ast_value_factory, | 71 v8::Extension* extension, AstValueFactory* ast_value_factory, |
96 ParserRecorder* log, typename Traits::Type::Parser this_object) | 72 ParserRecorder* log, typename Traits::Type::Parser this_object) |
97 : Traits(this_object), | 73 : Traits(this_object), |
98 parenthesized_function_(false), | 74 parenthesized_function_(false), |
99 scope_(NULL), | 75 scope_(NULL), |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 Traits::ReportMessageAt(function_name_loc, "strong_undefined"); | 488 Traits::ReportMessageAt(function_name_loc, "strong_undefined"); |
513 *ok = false; | 489 *ok = false; |
514 return; | 490 return; |
515 } | 491 } |
516 } | 492 } |
517 | 493 |
518 // Checking the parameter names of a function literal. This has to be done | 494 // 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. | 495 // after parsing the function, since the function can declare itself strict. |
520 void CheckFunctionParameterNames(LanguageMode language_mode, | 496 void CheckFunctionParameterNames(LanguageMode language_mode, |
521 bool strict_params, | 497 bool strict_params, |
522 const FormalParameterErrorLocations& locs, | 498 const Scanner::Location& eval_args_loc, |
| 499 const Scanner::Location& undefined_loc, |
| 500 const Scanner::Location& dupe_loc, |
| 501 const Scanner::Location& reserved_loc, |
523 bool* ok) { | 502 bool* ok) { |
524 if (is_sloppy(language_mode) && !strict_params) return; | 503 if (is_sloppy(language_mode) && !strict_params) return; |
525 if (is_strict(language_mode) && locs.eval_or_arguments.IsValid()) { | 504 if (is_strict(language_mode) && eval_args_loc.IsValid()) { |
526 Traits::ReportMessageAt(locs.eval_or_arguments, "strict_eval_arguments"); | 505 Traits::ReportMessageAt(eval_args_loc, "strict_eval_arguments"); |
527 *ok = false; | 506 *ok = false; |
528 return; | 507 return; |
529 } | 508 } |
530 if (is_strict(language_mode) && locs.reserved.IsValid()) { | 509 if (is_strong(language_mode) && undefined_loc.IsValid()) { |
531 Traits::ReportMessageAt(locs.reserved, "unexpected_strict_reserved"); | 510 Traits::ReportMessageAt(undefined_loc, "strong_undefined"); |
532 *ok = false; | |
533 return; | |
534 } | |
535 if (is_strong(language_mode) && locs.undefined.IsValid()) { | |
536 Traits::ReportMessageAt(locs.undefined, "strong_undefined"); | |
537 *ok = false; | 511 *ok = false; |
538 return; | 512 return; |
539 } | 513 } |
540 // TODO(arv): When we add support for destructuring in setters we also need | 514 // TODO(arv): When we add support for destructuring in setters we also need |
541 // to check for duplicate names. | 515 // to check for duplicate names. |
542 if (locs.duplicate.IsValid()) { | 516 if (dupe_loc.IsValid()) { |
543 Traits::ReportMessageAt(locs.duplicate, "strict_param_dupe"); | 517 Traits::ReportMessageAt(dupe_loc, "strict_param_dupe"); |
544 *ok = false; | 518 *ok = false; |
545 return; | 519 return; |
546 } | 520 } |
| 521 if (reserved_loc.IsValid()) { |
| 522 Traits::ReportMessageAt(reserved_loc, "unexpected_strict_reserved"); |
| 523 *ok = false; |
| 524 return; |
| 525 } |
547 } | 526 } |
548 | 527 |
549 // Determine precedence of given token. | 528 // Determine precedence of given token. |
550 static int Precedence(Token::Value token, bool accept_IN) { | 529 static int Precedence(Token::Value token, bool accept_IN) { |
551 if (token == Token::IN && !accept_IN) | 530 if (token == Token::IN && !accept_IN) |
552 return 0; // 0 precedence will terminate binary expression parsing | 531 return 0; // 0 precedence will terminate binary expression parsing |
553 return Token::Precedence(token); | 532 return Token::Precedence(token); |
554 } | 533 } |
555 | 534 |
556 typename Traits::Type::Factory* factory() { | 535 typename Traits::Type::Factory* factory() { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 ExpressionT ParseYieldExpression(bool* ok); | 593 ExpressionT ParseYieldExpression(bool* ok); |
615 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 594 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
616 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 595 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
617 ExpressionT ParseUnaryExpression(bool* ok); | 596 ExpressionT ParseUnaryExpression(bool* ok); |
618 ExpressionT ParsePostfixExpression(bool* ok); | 597 ExpressionT ParsePostfixExpression(bool* ok); |
619 ExpressionT ParseLeftHandSideExpression(bool* ok); | 598 ExpressionT ParseLeftHandSideExpression(bool* ok); |
620 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 599 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
621 ExpressionT ParseMemberExpression(bool* ok); | 600 ExpressionT ParseMemberExpression(bool* ok); |
622 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 601 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
623 bool* ok); | 602 bool* ok); |
624 ExpressionT ParseArrowFunctionLiteral( | 603 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, |
625 int start_pos, FormalParameterListT params, | 604 bool* ok); |
626 const FormalParameterErrorLocations& error_locs, bool has_rest, bool* ok); | |
627 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); | 605 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); |
628 void AddTemplateExpression(ExpressionT); | 606 void AddTemplateExpression(ExpressionT); |
629 ExpressionT ParseSuperExpression(bool is_new, bool* ok); | 607 ExpressionT ParseSuperExpression(bool is_new, bool* ok); |
630 | 608 |
631 FormalParameterT ParseFormalParameter(DuplicateFinder* duplicate_finder, | |
632 FormalParameterErrorLocations* locs, | |
633 bool* ok); | |
634 FormalParameterListT ParseFormalParameterList( | |
635 FormalParameterErrorLocations* locs, bool* is_rest, bool* ok); | |
636 void CheckArityRestrictions( | |
637 int param_count, FunctionLiteral::ArityRestriction arity_restriction, | |
638 int formals_start_pos, int formals_end_pos, bool* ok); | |
639 | |
640 // Checks if the expression is a valid reference expression (e.g., on the | 609 // Checks if the expression is a valid reference expression (e.g., on the |
641 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 610 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
642 // we allow calls for web compatibility and rewrite them to a runtime throw. | 611 // we allow calls for web compatibility and rewrite them to a runtime throw. |
643 ExpressionT CheckAndRewriteReferenceExpression( | 612 ExpressionT CheckAndRewriteReferenceExpression( |
644 ExpressionT expression, | 613 ExpressionT expression, |
645 Scanner::Location location, const char* message, bool* ok); | 614 Scanner::Location location, const char* message, bool* ok); |
646 | 615 |
647 // Used to validate property names in object literals and class literals | 616 // Used to validate property names in object literals and class literals |
648 enum PropertyKind { | 617 enum PropertyKind { |
649 kAccessorProperty, | 618 kAccessorProperty, |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
839 ValidArrowParam valid_arrow_param_list = | 808 ValidArrowParam valid_arrow_param_list = |
840 (op == Token::COMMA && !left.is_parenthesized() && | 809 (op == Token::COMMA && !left.is_parenthesized() && |
841 !right.is_parenthesized()) ? | 810 !right.is_parenthesized()) ? |
842 std::min(left.ValidateArrowParams(), right.ValidateArrowParams()) | 811 std::min(left.ValidateArrowParams(), right.ValidateArrowParams()) |
843 : kInvalidArrowParam; | 812 : kInvalidArrowParam; |
844 return PreParserExpression( | 813 return PreParserExpression( |
845 TypeField::encode(kBinaryOperationExpression) | | 814 TypeField::encode(kBinaryOperationExpression) | |
846 IsValidArrowParamListField::encode(valid_arrow_param_list)); | 815 IsValidArrowParamListField::encode(valid_arrow_param_list)); |
847 } | 816 } |
848 | 817 |
| 818 static PreParserExpression EmptyArrowParamList() { |
| 819 // Any expression for which IsValidArrowParamList() returns true |
| 820 // will work here. |
| 821 return FromIdentifier(PreParserIdentifier::Default()); |
| 822 } |
| 823 |
849 static PreParserExpression StringLiteral() { | 824 static PreParserExpression StringLiteral() { |
850 return PreParserExpression(TypeField::encode(kStringLiteralExpression)); | 825 return PreParserExpression(TypeField::encode(kStringLiteralExpression)); |
851 } | 826 } |
852 | 827 |
853 static PreParserExpression UseStrictStringLiteral() { | 828 static PreParserExpression UseStrictStringLiteral() { |
854 return PreParserExpression(TypeField::encode(kStringLiteralExpression) | | 829 return PreParserExpression(TypeField::encode(kStringLiteralExpression) | |
855 IsUseStrictField::encode(true)); | 830 IsUseStrictField::encode(true)); |
856 } | 831 } |
857 | 832 |
858 static PreParserExpression UseStrongStringLiteral() { | 833 static PreParserExpression UseStrongStringLiteral() { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
929 | 904 |
930 bool IsCall() const { | 905 bool IsCall() const { |
931 return TypeField::decode(code_) == kExpression && | 906 return TypeField::decode(code_) == kExpression && |
932 ExpressionTypeField::decode(code_) == kCallExpression; | 907 ExpressionTypeField::decode(code_) == kCallExpression; |
933 } | 908 } |
934 | 909 |
935 bool IsValidReferenceExpression() const { | 910 bool IsValidReferenceExpression() const { |
936 return IsIdentifier() || IsProperty(); | 911 return IsIdentifier() || IsProperty(); |
937 } | 912 } |
938 | 913 |
939 bool IsValidArrowParamList(FormalParameterErrorLocations* locs, | 914 bool IsValidArrowParamList(Scanner::Location* undefined_loc) const { |
940 const Scanner::Location& params_loc) const { | |
941 ValidArrowParam valid = ValidateArrowParams(); | 915 ValidArrowParam valid = ValidateArrowParams(); |
942 if (ParenthesizationField::decode(code_) == kMultiParenthesizedExpression) { | 916 if (ParenthesizationField::decode(code_) == kMultiParenthesizedExpression) { |
943 return false; | 917 return false; |
944 } | 918 } |
945 switch (valid) { | 919 if (valid == kValidArrowParam) { |
946 case kInvalidArrowParam: | 920 return true; |
947 return false; | 921 } else if (valid == kInvalidStrongArrowParam) { |
948 case kInvalidStrongArrowParam: | 922 // Return true for now regardless of strong mode for compatibility with |
949 locs->undefined = params_loc; | 923 // parser. |
950 return true; | 924 *undefined_loc = Scanner::Location(); |
951 case kInvalidStrictReservedArrowParam: | 925 return true; |
952 locs->reserved = params_loc; | 926 } else { |
953 return true; | 927 return false; |
954 case kInvalidStrictEvalArgumentsArrowParam: | |
955 locs->eval_or_arguments = params_loc; | |
956 return true; | |
957 default: | |
958 DCHECK_EQ(valid, kValidArrowParam); | |
959 return true; | |
960 } | 928 } |
961 } | 929 } |
962 | 930 |
963 // At the moment PreParser doesn't track these expression types. | 931 // At the moment PreParser doesn't track these expression types. |
964 bool IsFunctionLiteral() const { return false; } | 932 bool IsFunctionLiteral() const { return false; } |
965 bool IsCallNew() const { return false; } | 933 bool IsCallNew() const { return false; } |
966 | 934 |
967 bool IsNoTemplateTag() const { | 935 bool IsNoTemplateTag() const { |
968 return TypeField::decode(code_) == kExpression && | 936 return TypeField::decode(code_) == kExpression && |
969 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; | 937 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1016 }; | 984 }; |
1017 | 985 |
1018 enum ExpressionType { | 986 enum ExpressionType { |
1019 kThisExpression, | 987 kThisExpression, |
1020 kThisPropertyExpression, | 988 kThisPropertyExpression, |
1021 kPropertyExpression, | 989 kPropertyExpression, |
1022 kCallExpression, | 990 kCallExpression, |
1023 kNoTemplateTagExpression | 991 kNoTemplateTagExpression |
1024 }; | 992 }; |
1025 | 993 |
1026 // These validity constraints are ordered such that a value of N implies lack | |
1027 // of errors M < N. | |
1028 enum ValidArrowParam { | 994 enum ValidArrowParam { |
1029 kInvalidArrowParam, | 995 kInvalidArrowParam, |
1030 kInvalidStrictEvalArgumentsArrowParam, | |
1031 kInvalidStrictReservedArrowParam, | |
1032 kInvalidStrongArrowParam, | 996 kInvalidStrongArrowParam, |
1033 kValidArrowParam | 997 kValidArrowParam |
1034 }; | 998 }; |
1035 | 999 |
1036 explicit PreParserExpression(uint32_t expression_code) | 1000 explicit PreParserExpression(uint32_t expression_code) |
1037 : code_(expression_code) {} | 1001 : code_(expression_code) {} |
1038 | 1002 |
1039 V8_INLINE ValidArrowParam ValidateArrowParams() const { | 1003 V8_INLINE ValidArrowParam ValidateArrowParams() const { |
1040 if (IsBinaryOperation()) { | 1004 if (IsBinaryOperation()) { |
1041 return IsValidArrowParamListField::decode(code_); | 1005 return IsValidArrowParamListField::decode(code_); |
1042 } | 1006 } |
1043 if (!IsIdentifier()) { | 1007 if (!IsIdentifier()) { |
1044 return kInvalidArrowParam; | 1008 return kInvalidArrowParam; |
1045 } | 1009 } |
1046 PreParserIdentifier ident = AsIdentifier(); | 1010 PreParserIdentifier ident = AsIdentifier(); |
1047 // In strict mode, eval and arguments are not valid formal parameter names. | 1011 // A valid identifier can be an arrow function parameter |
1048 if (ident.IsEval() || ident.IsArguments()) { | 1012 // except for eval, arguments, yield, and reserved keywords. |
1049 return kInvalidStrictEvalArgumentsArrowParam; | 1013 if (ident.IsEval() || ident.IsArguments() || |
| 1014 ident.IsFutureStrictReserved()) { |
| 1015 return kInvalidArrowParam; |
1050 } | 1016 } |
1051 // In strict mode, future reserved words are not valid either, and as they | 1017 // In strong mode, 'undefined' is similarly restricted. |
1052 // produce different errors we allot them their own error code. | |
1053 if (ident.IsFutureStrictReserved()) { | |
1054 return kInvalidStrictReservedArrowParam; | |
1055 } | |
1056 // In strong mode, 'undefined' isn't a valid formal parameter name either. | |
1057 if (ident.IsUndefined()) { | 1018 if (ident.IsUndefined()) { |
1058 return kInvalidStrongArrowParam; | 1019 return kInvalidStrongArrowParam; |
1059 } | 1020 } |
1060 return kValidArrowParam; | 1021 return kValidArrowParam; |
1061 } | 1022 } |
1062 | 1023 |
1063 // The first five bits are for the Type and Parenthesization. | 1024 // The first five bits are for the Type and Parenthesization. |
1064 typedef BitField<Type, 0, 3> TypeField; | 1025 typedef BitField<Type, 0, 3> TypeField; |
1065 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; | 1026 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; |
1066 | 1027 |
1067 // The rest of the bits are interpreted depending on the value | 1028 // The rest of the bits are interpreted depending on the value |
1068 // of the Type field, so they can share the storage. | 1029 // of the Type field, so they can share the storage. |
1069 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> | 1030 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> |
1070 ExpressionTypeField; | 1031 ExpressionTypeField; |
1071 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; | 1032 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; |
1072 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; | 1033 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; |
1073 typedef BitField<ValidArrowParam, ParenthesizationField::kNext, 3> | 1034 typedef BitField<ValidArrowParam, ParenthesizationField::kNext, 2> |
1074 IsValidArrowParamListField; | 1035 IsValidArrowParamListField; |
1075 typedef BitField<PreParserIdentifier::Type, ParenthesizationField::kNext, 10> | 1036 typedef BitField<PreParserIdentifier::Type, ParenthesizationField::kNext, 10> |
1076 IdentifierTypeField; | 1037 IdentifierTypeField; |
1077 | 1038 |
1078 uint32_t code_; | 1039 uint32_t code_; |
1079 }; | 1040 }; |
1080 | 1041 |
1081 | 1042 |
1082 // The pre-parser doesn't need to build lists of expressions, identifiers, or | 1043 // PreParserExpressionList doesn't actually store the expressions because |
1083 // the like. | 1044 // PreParser doesn't need to. |
1084 template <typename T> | 1045 class PreParserExpressionList { |
1085 class PreParserList { | |
1086 public: | 1046 public: |
1087 // These functions make list->Add(some_expression) work (and do nothing). | 1047 // These functions make list->Add(some_expression) work (and do nothing). |
1088 PreParserList() : length_(0) {} | 1048 PreParserExpressionList() : length_(0) {} |
1089 PreParserList* operator->() { return this; } | 1049 PreParserExpressionList* operator->() { return this; } |
1090 void Add(T, void*) { ++length_; } | 1050 void Add(PreParserExpression, void*) { ++length_; } |
1091 int length() const { return length_; } | 1051 int length() const { return length_; } |
1092 private: | 1052 private: |
1093 int length_; | 1053 int length_; |
1094 }; | 1054 }; |
1095 | 1055 |
1096 | 1056 |
1097 typedef PreParserList<PreParserExpression> PreParserExpressionList; | |
1098 typedef PreParserList<PreParserIdentifier> PreParserFormalParameterList; | |
1099 | |
1100 | |
1101 class PreParserStatement { | 1057 class PreParserStatement { |
1102 public: | 1058 public: |
1103 static PreParserStatement Default() { | 1059 static PreParserStatement Default() { |
1104 return PreParserStatement(kUnknownStatement); | 1060 return PreParserStatement(kUnknownStatement); |
1105 } | 1061 } |
1106 | 1062 |
1107 static PreParserStatement Jump() { | 1063 static PreParserStatement Jump() { |
1108 return PreParserStatement(kJumpStatement); | 1064 return PreParserStatement(kJumpStatement); |
1109 } | 1065 } |
1110 | 1066 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1155 kUseStrictExpressionStatement, | 1111 kUseStrictExpressionStatement, |
1156 kUseStrongExpressionStatement, | 1112 kUseStrongExpressionStatement, |
1157 kFunctionDeclaration | 1113 kFunctionDeclaration |
1158 }; | 1114 }; |
1159 | 1115 |
1160 explicit PreParserStatement(Type code) : code_(code) {} | 1116 explicit PreParserStatement(Type code) : code_(code) {} |
1161 Type code_; | 1117 Type code_; |
1162 }; | 1118 }; |
1163 | 1119 |
1164 | 1120 |
1165 typedef PreParserList<PreParserStatement> PreParserStatementList; | 1121 |
| 1122 // PreParserStatementList doesn't actually store the statements because |
| 1123 // the PreParser does not need them. |
| 1124 class PreParserStatementList { |
| 1125 public: |
| 1126 // These functions make list->Add(some_expression) work as no-ops. |
| 1127 PreParserStatementList() {} |
| 1128 PreParserStatementList* operator->() { return this; } |
| 1129 void Add(PreParserStatement, void*) {} |
| 1130 }; |
1166 | 1131 |
1167 | 1132 |
1168 class PreParserFactory { | 1133 class PreParserFactory { |
1169 public: | 1134 public: |
1170 explicit PreParserFactory(void* unused_value_factory) {} | 1135 explicit PreParserFactory(void* unused_value_factory) {} |
1171 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, | 1136 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, |
1172 int pos) { | 1137 int pos) { |
1173 return PreParserExpression::Default(); | 1138 return PreParserExpression::Default(); |
1174 } | 1139 } |
1175 PreParserExpression NewNumberLiteral(double number, | 1140 PreParserExpression NewNumberLiteral(double number, |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1320 // Return types for traversing functions. | 1285 // Return types for traversing functions. |
1321 typedef PreParserIdentifier Identifier; | 1286 typedef PreParserIdentifier Identifier; |
1322 typedef PreParserExpression Expression; | 1287 typedef PreParserExpression Expression; |
1323 typedef PreParserExpression YieldExpression; | 1288 typedef PreParserExpression YieldExpression; |
1324 typedef PreParserExpression FunctionLiteral; | 1289 typedef PreParserExpression FunctionLiteral; |
1325 typedef PreParserExpression ClassLiteral; | 1290 typedef PreParserExpression ClassLiteral; |
1326 typedef PreParserExpression ObjectLiteralProperty; | 1291 typedef PreParserExpression ObjectLiteralProperty; |
1327 typedef PreParserExpression Literal; | 1292 typedef PreParserExpression Literal; |
1328 typedef PreParserExpressionList ExpressionList; | 1293 typedef PreParserExpressionList ExpressionList; |
1329 typedef PreParserExpressionList PropertyList; | 1294 typedef PreParserExpressionList PropertyList; |
1330 typedef PreParserIdentifier FormalParameter; | |
1331 typedef PreParserFormalParameterList FormalParameterList; | |
1332 typedef PreParserStatementList StatementList; | 1295 typedef PreParserStatementList StatementList; |
1333 | 1296 |
1334 // For constructing objects returned by the traversing functions. | 1297 // For constructing objects returned by the traversing functions. |
1335 typedef PreParserFactory Factory; | 1298 typedef PreParserFactory Factory; |
1336 }; | 1299 }; |
1337 | 1300 |
1338 explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {} | 1301 explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {} |
1339 | 1302 |
1340 // Helper functions for recursive descent. | 1303 // Helper functions for recursive descent. |
1341 static bool IsEval(PreParserIdentifier identifier) { | 1304 static bool IsEval(PreParserIdentifier identifier) { |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1465 // "null" return type creators. | 1428 // "null" return type creators. |
1466 static PreParserIdentifier EmptyIdentifier() { | 1429 static PreParserIdentifier EmptyIdentifier() { |
1467 return PreParserIdentifier::Default(); | 1430 return PreParserIdentifier::Default(); |
1468 } | 1431 } |
1469 static PreParserIdentifier EmptyIdentifierString() { | 1432 static PreParserIdentifier EmptyIdentifierString() { |
1470 return PreParserIdentifier::Default(); | 1433 return PreParserIdentifier::Default(); |
1471 } | 1434 } |
1472 static PreParserExpression EmptyExpression() { | 1435 static PreParserExpression EmptyExpression() { |
1473 return PreParserExpression::Default(); | 1436 return PreParserExpression::Default(); |
1474 } | 1437 } |
| 1438 static PreParserExpression EmptyArrowParamList() { |
| 1439 return PreParserExpression::EmptyArrowParamList(); |
| 1440 } |
1475 static PreParserExpression EmptyLiteral() { | 1441 static PreParserExpression EmptyLiteral() { |
1476 return PreParserExpression::Default(); | 1442 return PreParserExpression::Default(); |
1477 } | 1443 } |
1478 static PreParserExpression EmptyObjectLiteralProperty() { | 1444 static PreParserExpression EmptyObjectLiteralProperty() { |
1479 return PreParserExpression::Default(); | 1445 return PreParserExpression::Default(); |
1480 } | 1446 } |
1481 static PreParserExpression EmptyFunctionLiteral() { | 1447 static PreParserExpression EmptyFunctionLiteral() { |
1482 return PreParserExpression::Default(); | 1448 return PreParserExpression::Default(); |
1483 } | 1449 } |
1484 static PreParserExpressionList NullExpressionList() { | 1450 static PreParserExpressionList NullExpressionList() { |
1485 return PreParserExpressionList(); | 1451 return PreParserExpressionList(); |
1486 } | 1452 } |
1487 static PreParserIdentifier EmptyFormalParameter() { | |
1488 return PreParserIdentifier::Default(); | |
1489 } | |
1490 static PreParserFormalParameterList NullFormalParameterList() { | |
1491 return PreParserFormalParameterList(); | |
1492 } | |
1493 | 1453 |
1494 // Odd-ball literal creators. | 1454 // Odd-ball literal creators. |
1495 static PreParserExpression GetLiteralTheHole(int position, | 1455 static PreParserExpression GetLiteralTheHole(int position, |
1496 PreParserFactory* factory) { | 1456 PreParserFactory* factory) { |
1497 return PreParserExpression::Default(); | 1457 return PreParserExpression::Default(); |
1498 } | 1458 } |
1499 | 1459 |
1500 // Producing data during the recursive descent. | 1460 // Producing data during the recursive descent. |
1501 PreParserIdentifier GetSymbol(Scanner* scanner); | 1461 PreParserIdentifier GetSymbol(Scanner* scanner); |
1502 PreParserIdentifier GetNumberAsSymbol(Scanner* scanner); | 1462 PreParserIdentifier GetNumberAsSymbol(Scanner* scanner); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1547 } | 1507 } |
1548 | 1508 |
1549 static PreParserStatementList NewStatementList(int size, Zone* zone) { | 1509 static PreParserStatementList NewStatementList(int size, Zone* zone) { |
1550 return PreParserStatementList(); | 1510 return PreParserStatementList(); |
1551 } | 1511 } |
1552 | 1512 |
1553 static PreParserExpressionList NewPropertyList(int size, Zone* zone) { | 1513 static PreParserExpressionList NewPropertyList(int size, Zone* zone) { |
1554 return PreParserExpressionList(); | 1514 return PreParserExpressionList(); |
1555 } | 1515 } |
1556 | 1516 |
1557 static PreParserFormalParameterList NewFormalParameterList(int size, | |
1558 Zone* zone) { | |
1559 return PreParserFormalParameterList(); | |
1560 } | |
1561 | |
1562 V8_INLINE void SkipLazyFunctionBody(PreParserIdentifier function_name, | 1517 V8_INLINE void SkipLazyFunctionBody(PreParserIdentifier function_name, |
1563 int* materialized_literal_count, | 1518 int* materialized_literal_count, |
1564 int* expected_property_count, bool* ok) { | 1519 int* expected_property_count, bool* ok) { |
1565 UNREACHABLE(); | 1520 UNREACHABLE(); |
1566 } | 1521 } |
1567 | 1522 |
1568 V8_INLINE PreParserStatementList | 1523 V8_INLINE PreParserStatementList |
1569 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, | 1524 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, |
1570 Variable* fvar, Token::Value fvar_init_op, | 1525 Variable* fvar, Token::Value fvar_init_op, |
1571 FunctionKind kind, bool* ok); | 1526 FunctionKind kind, bool* ok); |
1572 | 1527 |
1573 V8_INLINE PreParserFormalParameterList ParseArrowFunctionFormalParameterList( | 1528 // Utility functions |
1574 PreParserExpression expression, const Scanner::Location& params_loc, | 1529 int DeclareArrowParametersFromExpression(PreParserExpression expression, |
1575 FormalParameterErrorLocations* error_locs, bool* is_rest, bool* ok); | 1530 Scope* scope, |
| 1531 Scanner::Location* undefined_loc, |
| 1532 Scanner::Location* dupe_loc, |
| 1533 bool* ok) { |
| 1534 // TODO(aperez): Detect duplicated identifiers in paramlists. |
| 1535 *ok = expression.IsValidArrowParamList(undefined_loc); |
| 1536 return 0; |
| 1537 } |
1576 | 1538 |
1577 struct TemplateLiteralState {}; | 1539 struct TemplateLiteralState {}; |
1578 | 1540 |
1579 TemplateLiteralState OpenTemplateLiteral(int pos) { | 1541 TemplateLiteralState OpenTemplateLiteral(int pos) { |
1580 return TemplateLiteralState(); | 1542 return TemplateLiteralState(); |
1581 } | 1543 } |
1582 void AddTemplateSpan(TemplateLiteralState*, bool) {} | 1544 void AddTemplateSpan(TemplateLiteralState*, bool) {} |
1583 void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {} | 1545 void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {} |
1584 PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int, | 1546 PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int, |
1585 PreParserExpression tag) { | 1547 PreParserExpression tag) { |
1586 if (IsTaggedTemplate(tag)) { | 1548 if (IsTaggedTemplate(tag)) { |
1587 // Emulate generation of array literals for tag callsite | 1549 // Emulate generation of array literals for tag callsite |
1588 // 1st is array of cooked strings, second is array of raw strings | 1550 // 1st is array of cooked strings, second is array of raw strings |
1589 MaterializeTemplateCallsiteLiterals(); | 1551 MaterializeTemplateCallsiteLiterals(); |
1590 } | 1552 } |
1591 return EmptyExpression(); | 1553 return EmptyExpression(); |
1592 } | 1554 } |
1593 inline void MaterializeTemplateCallsiteLiterals(); | 1555 inline void MaterializeTemplateCallsiteLiterals(); |
1594 PreParserExpression NoTemplateTag() { | 1556 PreParserExpression NoTemplateTag() { |
1595 return PreParserExpression::NoTemplateTag(); | 1557 return PreParserExpression::NoTemplateTag(); |
1596 } | 1558 } |
1597 static bool IsTaggedTemplate(const PreParserExpression tag) { | 1559 static bool IsTaggedTemplate(const PreParserExpression tag) { |
1598 return !tag.IsNoTemplateTag(); | 1560 return !tag.IsNoTemplateTag(); |
1599 } | 1561 } |
1600 | 1562 |
1601 int DeclareFormalParameters(PreParserFormalParameterList params, Scope* scope, | |
1602 bool has_rest) { | |
1603 return params->length(); | |
1604 } | |
1605 | |
1606 void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {} | 1563 void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {} |
1607 | 1564 |
1608 // Temporary glue; these functions will move to ParserBase. | 1565 // Temporary glue; these functions will move to ParserBase. |
1609 PreParserExpression ParseV8Intrinsic(bool* ok); | 1566 PreParserExpression ParseV8Intrinsic(bool* ok); |
1610 PreParserExpression ParseFunctionLiteral( | 1567 PreParserExpression ParseFunctionLiteral( |
1611 PreParserIdentifier name, Scanner::Location function_name_location, | 1568 PreParserIdentifier name, Scanner::Location function_name_location, |
1612 bool name_is_strict_reserved, FunctionKind kind, | 1569 bool name_is_strict_reserved, FunctionKind kind, |
1613 int function_token_position, FunctionLiteral::FunctionType type, | 1570 int function_token_position, FunctionLiteral::FunctionType type, |
1614 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); | 1571 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); |
1615 | 1572 |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1784 return pre_parser_->factory()->NewCall(function, args, pos); | 1741 return pre_parser_->factory()->NewCall(function, args, pos); |
1785 } | 1742 } |
1786 | 1743 |
1787 PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function, | 1744 PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function, |
1788 PreParserExpressionList args, | 1745 PreParserExpressionList args, |
1789 int pos) { | 1746 int pos) { |
1790 return pre_parser_->factory()->NewCallNew(function, args, pos); | 1747 return pre_parser_->factory()->NewCallNew(function, args, pos); |
1791 } | 1748 } |
1792 | 1749 |
1793 | 1750 |
1794 PreParserFormalParameterList | |
1795 PreParserTraits::ParseArrowFunctionFormalParameterList( | |
1796 PreParserExpression params, const Scanner::Location& params_loc, | |
1797 FormalParameterErrorLocations* error_locs, bool* is_rest, bool* ok) { | |
1798 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter | |
1799 // lists that are too long. | |
1800 if (!params.IsValidArrowParamList(error_locs, params_loc)) { | |
1801 *ok = false; | |
1802 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); | |
1803 return this->NullFormalParameterList(); | |
1804 } | |
1805 | |
1806 return PreParserFormalParameterList(); | |
1807 } | |
1808 | |
1809 | |
1810 PreParserStatementList PreParser::ParseEagerFunctionBody( | 1751 PreParserStatementList PreParser::ParseEagerFunctionBody( |
1811 PreParserIdentifier function_name, int pos, Variable* fvar, | 1752 PreParserIdentifier function_name, int pos, Variable* fvar, |
1812 Token::Value fvar_init_op, FunctionKind kind, bool* ok) { | 1753 Token::Value fvar_init_op, FunctionKind kind, bool* ok) { |
1813 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 1754 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
1814 | 1755 |
1815 ParseStatementList(Token::RBRACE, ok); | 1756 ParseStatementList(Token::RBRACE, ok); |
1816 if (!*ok) return PreParserStatementList(); | 1757 if (!*ok) return PreParserStatementList(); |
1817 | 1758 |
1818 Expect(Token::RBRACE, ok); | 1759 Expect(Token::RBRACE, ok); |
1819 return PreParserStatementList(); | 1760 return PreParserStatementList(); |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2095 case Token::LBRACK: | 2036 case Token::LBRACK: |
2096 result = this->ParseArrayLiteral(CHECK_OK); | 2037 result = this->ParseArrayLiteral(CHECK_OK); |
2097 break; | 2038 break; |
2098 | 2039 |
2099 case Token::LBRACE: | 2040 case Token::LBRACE: |
2100 result = this->ParseObjectLiteral(CHECK_OK); | 2041 result = this->ParseObjectLiteral(CHECK_OK); |
2101 break; | 2042 break; |
2102 | 2043 |
2103 case Token::LPAREN: | 2044 case Token::LPAREN: |
2104 Consume(Token::LPAREN); | 2045 Consume(Token::LPAREN); |
2105 if (allow_harmony_arrow_functions() && Check(Token::RPAREN)) { | 2046 if (allow_harmony_arrow_functions() && peek() == Token::RPAREN) { |
2106 // As a primary expression, the only thing that can follow "()" is "=>". | 2047 // Arrow functions are the only expression type constructions |
2107 FormalParameterListT params = this->NewFormalParameterList(0, zone()); | 2048 // for which an empty parameter list "()" is valid input. |
2108 FormalParameterErrorLocations error_locs; | 2049 Consume(Token::RPAREN); |
2109 bool has_rest = false; | 2050 result = this->ParseArrowFunctionLiteral( |
2110 result = this->ParseArrowFunctionLiteral(beg_pos, params, error_locs, | 2051 beg_pos, this->EmptyArrowParamList(), CHECK_OK); |
2111 has_rest, CHECK_OK); | |
2112 } else { | 2052 } else { |
2113 // Heuristically try to detect immediately called functions before | 2053 // Heuristically try to detect immediately called functions before |
2114 // seeing the call parentheses. | 2054 // seeing the call parentheses. |
2115 parenthesized_function_ = (peek() == Token::FUNCTION); | 2055 parenthesized_function_ = (peek() == Token::FUNCTION); |
2116 result = this->ParseExpression(true, CHECK_OK); | 2056 result = this->ParseExpression(true, CHECK_OK); |
2117 result->increase_parenthesization_level(); | 2057 result->increase_parenthesization_level(); |
2118 Expect(Token::RPAREN, CHECK_OK); | 2058 Expect(Token::RPAREN, CHECK_OK); |
2119 } | 2059 } |
2120 break; | 2060 break; |
2121 | 2061 |
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2559 return this->ParseYieldExpression(ok); | 2499 return this->ParseYieldExpression(ok); |
2560 } | 2500 } |
2561 | 2501 |
2562 if (fni_ != NULL) fni_->Enter(); | 2502 if (fni_ != NULL) fni_->Enter(); |
2563 ParserBase<Traits>::Checkpoint checkpoint(this); | 2503 ParserBase<Traits>::Checkpoint checkpoint(this); |
2564 ExpressionT expression = | 2504 ExpressionT expression = |
2565 this->ParseConditionalExpression(accept_IN, CHECK_OK); | 2505 this->ParseConditionalExpression(accept_IN, CHECK_OK); |
2566 | 2506 |
2567 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { | 2507 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { |
2568 checkpoint.Restore(); | 2508 checkpoint.Restore(); |
2569 FormalParameterErrorLocations error_locs; | 2509 expression = this->ParseArrowFunctionLiteral(lhs_location.beg_pos, |
2570 Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos); | 2510 expression, CHECK_OK); |
2571 bool has_rest = false; | |
2572 FormalParameterListT params = this->ParseArrowFunctionFormalParameterList( | |
2573 expression, loc, &error_locs, &has_rest, CHECK_OK); | |
2574 expression = this->ParseArrowFunctionLiteral( | |
2575 lhs_location.beg_pos, params, error_locs, has_rest, CHECK_OK); | |
2576 return expression; | 2511 return expression; |
2577 } | 2512 } |
2578 | 2513 |
2579 if (!Token::IsAssignmentOp(peek())) { | 2514 if (!Token::IsAssignmentOp(peek())) { |
2580 if (fni_ != NULL) fni_->Leave(); | 2515 if (fni_ != NULL) fni_->Leave(); |
2581 // Parsed conditional expression only (no assignment). | 2516 // Parsed conditional expression only (no assignment). |
2582 return expression; | 2517 return expression; |
2583 } | 2518 } |
2584 | 2519 |
2585 expression = this->CheckAndRewriteReferenceExpression( | 2520 expression = this->CheckAndRewriteReferenceExpression( |
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3099 default: | 3034 default: |
3100 return expression; | 3035 return expression; |
3101 } | 3036 } |
3102 } | 3037 } |
3103 DCHECK(false); | 3038 DCHECK(false); |
3104 return this->EmptyExpression(); | 3039 return this->EmptyExpression(); |
3105 } | 3040 } |
3106 | 3041 |
3107 | 3042 |
3108 template <class Traits> | 3043 template <class Traits> |
3109 typename ParserBase<Traits>::FormalParameterT | |
3110 ParserBase<Traits>::ParseFormalParameter(DuplicateFinder* duplicate_finder, | |
3111 FormalParameterErrorLocations* locs, | |
3112 bool* ok) { | |
3113 // FormalParameter[Yield,GeneratorParameter] : | |
3114 // BindingElement[?Yield, ?GeneratorParameter] | |
3115 bool is_strict_reserved; | |
3116 IdentifierT name = | |
3117 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, ok); | |
3118 if (!*ok) return this->EmptyFormalParameter(); | |
3119 | |
3120 // Store locations for possible future error reports. | |
3121 if (!locs->eval_or_arguments.IsValid() && this->IsEvalOrArguments(name)) { | |
3122 locs->eval_or_arguments = scanner()->location(); | |
3123 } | |
3124 if (!locs->undefined.IsValid() && this->IsUndefined(name)) { | |
3125 locs->undefined = scanner()->location(); | |
3126 } | |
3127 if (!locs->reserved.IsValid() && is_strict_reserved) { | |
3128 locs->reserved = scanner()->location(); | |
3129 } | |
3130 if (!locs->duplicate.IsValid() && duplicate_finder != nullptr) { | |
3131 int prev_value = scanner()->FindSymbol(duplicate_finder, 1); | |
3132 if (prev_value != 0) locs->duplicate = scanner()->location(); | |
3133 } | |
3134 | |
3135 return name; | |
3136 } | |
3137 | |
3138 | |
3139 template <class Traits> | |
3140 typename ParserBase<Traits>::FormalParameterListT | |
3141 ParserBase<Traits>::ParseFormalParameterList( | |
3142 FormalParameterErrorLocations* locs, bool* is_rest, bool* ok) { | |
3143 // FormalParameters[Yield,GeneratorParameter] : | |
3144 // [empty] | |
3145 // FormalParameterList[?Yield, ?GeneratorParameter] | |
3146 // | |
3147 // FormalParameterList[Yield,GeneratorParameter] : | |
3148 // FunctionRestParameter[?Yield] | |
3149 // FormalsList[?Yield, ?GeneratorParameter] | |
3150 // FormalsList[?Yield, ?GeneratorParameter] , FunctionRestParameter[?Yield] | |
3151 // | |
3152 // FormalsList[Yield,GeneratorParameter] : | |
3153 // FormalParameter[?Yield, ?GeneratorParameter] | |
3154 // FormalsList[?Yield, ?GeneratorParameter] , | |
3155 // FormalParameter[?Yield,?GeneratorParameter] | |
3156 | |
3157 FormalParameterListT result = this->NewFormalParameterList(4, zone_); | |
3158 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); | |
3159 | |
3160 if (peek() != Token::RPAREN) { | |
3161 do { | |
3162 *is_rest = allow_harmony_rest_params() && Check(Token::ELLIPSIS); | |
3163 FormalParameterT param = | |
3164 ParseFormalParameter(&duplicate_finder, locs, ok); | |
3165 if (!*ok) return this->NullFormalParameterList(); | |
3166 result->Add(param, zone()); | |
3167 if (result->length() > Code::kMaxArguments) { | |
3168 ReportMessage("too_many_parameters"); | |
3169 *ok = false; | |
3170 return this->NullFormalParameterList(); | |
3171 } | |
3172 } while (!*is_rest && Check(Token::COMMA)); | |
3173 } | |
3174 | |
3175 if (is_rest && peek() == Token::COMMA) { | |
3176 ReportMessageAt(scanner()->peek_location(), "param_after_rest"); | |
3177 *ok = false; | |
3178 return this->NullFormalParameterList(); | |
3179 } | |
3180 | |
3181 return result; | |
3182 } | |
3183 | |
3184 | |
3185 template <class Traits> | |
3186 void ParserBase<Traits>::CheckArityRestrictions( | |
3187 int param_count, FunctionLiteral::ArityRestriction arity_restriction, | |
3188 int formals_start_pos, int formals_end_pos, bool* ok) { | |
3189 switch (arity_restriction) { | |
3190 case FunctionLiteral::GETTER_ARITY: | |
3191 if (param_count != 0) { | |
3192 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), | |
3193 "bad_getter_arity"); | |
3194 *ok = false; | |
3195 } | |
3196 break; | |
3197 case FunctionLiteral::SETTER_ARITY: | |
3198 if (param_count != 1) { | |
3199 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), | |
3200 "bad_setter_arity"); | |
3201 *ok = false; | |
3202 } | |
3203 break; | |
3204 default: | |
3205 break; | |
3206 } | |
3207 } | |
3208 | |
3209 | |
3210 template <class Traits> | |
3211 typename ParserBase<Traits>::ExpressionT | 3044 typename ParserBase<Traits>::ExpressionT |
3212 ParserBase<Traits>::ParseArrowFunctionLiteral( | 3045 ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos, |
3213 int start_pos, FormalParameterListT params, | 3046 ExpressionT params_ast, |
3214 const FormalParameterErrorLocations& error_locs, bool has_rest, bool* ok) { | 3047 bool* ok) { |
3215 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { | 3048 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { |
3216 // ASI inserts `;` after arrow parameters if a line terminator is found. | 3049 // ASI inserts `;` after arrow parameters if a line terminator is found. |
3217 // `=> ...` is never a valid expression, so report as syntax error. | 3050 // `=> ...` is never a valid expression, so report as syntax error. |
3218 // If next token is not `=>`, it's a syntax error anyways. | 3051 // If next token is not `=>`, it's a syntax error anyways. |
3219 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); | 3052 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); |
3220 *ok = false; | 3053 *ok = false; |
3221 return this->EmptyExpression(); | 3054 return this->EmptyExpression(); |
3222 } | 3055 } |
3223 | 3056 |
3224 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); | 3057 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); |
3225 typename Traits::Type::StatementList body; | 3058 typename Traits::Type::StatementList body; |
3226 int num_parameters = -1; | 3059 int num_parameters = -1; |
3227 int materialized_literal_count = -1; | 3060 int materialized_literal_count = -1; |
3228 int expected_property_count = -1; | 3061 int expected_property_count = -1; |
3229 int handler_count = 0; | 3062 int handler_count = 0; |
3230 Scanner::Location super_loc; | 3063 Scanner::Location super_loc; |
3231 | 3064 |
3232 { | 3065 { |
3233 typename Traits::Type::Factory function_factory(ast_value_factory()); | 3066 typename Traits::Type::Factory function_factory(ast_value_factory()); |
3234 FunctionState function_state(&function_state_, &scope_, scope, | 3067 FunctionState function_state(&function_state_, &scope_, scope, |
3235 kArrowFunction, &function_factory); | 3068 kArrowFunction, &function_factory); |
3236 num_parameters = this->DeclareFormalParameters(params, scope_, has_rest); | 3069 Scanner::Location undefined_loc = Scanner::Location::invalid(); |
| 3070 Scanner::Location dupe_loc = Scanner::Location::invalid(); |
| 3071 // TODO(arv): Pass in eval_args_loc and reserved_loc here. |
| 3072 num_parameters = Traits::DeclareArrowParametersFromExpression( |
| 3073 params_ast, scope_, &undefined_loc, &dupe_loc, ok); |
| 3074 if (!*ok) { |
| 3075 ReportMessageAt( |
| 3076 Scanner::Location(start_pos, scanner()->location().beg_pos), |
| 3077 "malformed_arrow_function_parameter_list"); |
| 3078 return this->EmptyExpression(); |
| 3079 } |
| 3080 |
| 3081 if (undefined_loc.IsValid()) { |
| 3082 // Workaround for preparser not keeping track of positions. |
| 3083 undefined_loc = Scanner::Location(start_pos, |
| 3084 scanner()->location().end_pos); |
| 3085 } |
| 3086 if (num_parameters > Code::kMaxArguments) { |
| 3087 ReportMessageAt(Scanner::Location(params_ast->position(), position()), |
| 3088 "too_many_parameters"); |
| 3089 *ok = false; |
| 3090 return this->EmptyExpression(); |
| 3091 } |
3237 | 3092 |
3238 Expect(Token::ARROW, CHECK_OK); | 3093 Expect(Token::ARROW, CHECK_OK); |
3239 | 3094 |
3240 if (peek() == Token::LBRACE) { | 3095 if (peek() == Token::LBRACE) { |
3241 // Multiple statement body | 3096 // Multiple statement body |
3242 Consume(Token::LBRACE); | 3097 Consume(Token::LBRACE); |
3243 bool is_lazily_parsed = | 3098 bool is_lazily_parsed = |
3244 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); | 3099 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); |
3245 if (is_lazily_parsed) { | 3100 if (is_lazily_parsed) { |
3246 body = this->NewStatementList(0, zone()); | 3101 body = this->NewStatementList(0, zone()); |
(...skipping 18 matching lines...) Expand all Loading... |
3265 body->Add(factory()->NewReturnStatement(expression, pos), zone()); | 3120 body->Add(factory()->NewReturnStatement(expression, pos), zone()); |
3266 materialized_literal_count = function_state.materialized_literal_count(); | 3121 materialized_literal_count = function_state.materialized_literal_count(); |
3267 expected_property_count = function_state.expected_property_count(); | 3122 expected_property_count = function_state.expected_property_count(); |
3268 handler_count = function_state.handler_count(); | 3123 handler_count = function_state.handler_count(); |
3269 } | 3124 } |
3270 super_loc = function_state.super_call_location(); | 3125 super_loc = function_state.super_call_location(); |
3271 | 3126 |
3272 scope->set_start_position(start_pos); | 3127 scope->set_start_position(start_pos); |
3273 scope->set_end_position(scanner()->location().end_pos); | 3128 scope->set_end_position(scanner()->location().end_pos); |
3274 | 3129 |
3275 // Arrow function formal parameters are parsed as StrictFormalParameterList, | 3130 // Arrow function *parameter lists* are always checked as in strict mode. |
3276 // which is not the same as "parameters of a strict function"; it only means | 3131 // TODO(arv): eval_args_loc and reserved_loc needs to be set by |
3277 // that duplicates are not allowed. Of course, the arrow function may | 3132 // DeclareArrowParametersFromExpression. |
3278 // itself be strict as well. | 3133 Scanner::Location eval_args_loc = Scanner::Location::invalid(); |
| 3134 Scanner::Location reserved_loc = Scanner::Location::invalid(); |
3279 const bool use_strict_params = true; | 3135 const bool use_strict_params = true; |
3280 this->CheckFunctionParameterNames(language_mode(), use_strict_params, | 3136 this->CheckFunctionParameterNames(language_mode(), use_strict_params, |
3281 error_locs, CHECK_OK); | 3137 eval_args_loc, undefined_loc, dupe_loc, |
| 3138 reserved_loc, CHECK_OK); |
3282 | 3139 |
3283 // Validate strict mode. | 3140 // Validate strict mode. |
3284 if (is_strict(language_mode())) { | 3141 if (is_strict(language_mode())) { |
3285 CheckStrictOctalLiteral(start_pos, scanner()->location().end_pos, | 3142 CheckStrictOctalLiteral(start_pos, scanner()->location().end_pos, |
3286 CHECK_OK); | 3143 CHECK_OK); |
3287 this->CheckConflictingVarDeclarations(scope, CHECK_OK); | 3144 this->CheckConflictingVarDeclarations(scope, CHECK_OK); |
3288 } | 3145 } |
3289 } | 3146 } |
3290 | 3147 |
3291 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 3148 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3484 *ok = false; | 3341 *ok = false; |
3485 return; | 3342 return; |
3486 } | 3343 } |
3487 has_seen_constructor_ = true; | 3344 has_seen_constructor_ = true; |
3488 return; | 3345 return; |
3489 } | 3346 } |
3490 } | 3347 } |
3491 } } // v8::internal | 3348 } } // v8::internal |
3492 | 3349 |
3493 #endif // V8_PREPARSER_H | 3350 #endif // V8_PREPARSER_H |
OLD | NEW |