Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(178)

Side by Side Diff: src/preparser.h

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

Powered by Google App Engine
This is Rietveld 408576698