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

Side by Side Diff: src/preparser.h

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

Powered by Google App Engine
This is Rietveld 408576698