OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
6 #include "vm/flags.h" | 6 #include "vm/flags.h" |
7 | 7 |
8 #ifndef DART_PRECOMPILED_RUNTIME | 8 #ifndef DART_PRECOMPILED_RUNTIME |
9 | 9 |
10 #include "lib/invocation_mirror.h" | 10 #include "lib/invocation_mirror.h" |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
45 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); | 45 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); |
46 DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef."); | 46 DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef."); |
47 // TODO(floitsch): remove the conditional-directive flag, once we publicly | 47 // TODO(floitsch): remove the conditional-directive flag, once we publicly |
48 // committed to the current version. | 48 // committed to the current version. |
49 DEFINE_FLAG(bool, conditional_directives, true, | 49 DEFINE_FLAG(bool, conditional_directives, true, |
50 "Enable conditional directives"); | 50 "Enable conditional directives"); |
51 DEFINE_FLAG(bool, warn_super, false, | 51 DEFINE_FLAG(bool, warn_super, false, |
52 "Warning if super initializer not last in initializer list."); | 52 "Warning if super initializer not last in initializer list."); |
53 DEFINE_FLAG(bool, await_is_keyword, false, | 53 DEFINE_FLAG(bool, await_is_keyword, false, |
54 "await and yield are treated as proper keywords in synchronous code."); | 54 "await and yield are treated as proper keywords in synchronous code."); |
55 DEFINE_FLAG(bool, assert_initializer, false, | |
56 "Allow asserts in initializer lists."); | |
55 | 57 |
56 DECLARE_FLAG(bool, profile_vm); | 58 DECLARE_FLAG(bool, profile_vm); |
57 DECLARE_FLAG(bool, trace_service); | 59 DECLARE_FLAG(bool, trace_service); |
58 | 60 |
59 // Quick access to the current thread, isolate and zone. | 61 // Quick access to the current thread, isolate and zone. |
60 #define T (thread()) | 62 #define T (thread()) |
61 #define I (isolate()) | 63 #define I (isolate()) |
62 #define Z (zone()) | 64 #define Z (zone()) |
63 | 65 |
64 // Quick synthetic token position. | 66 // Quick synthetic token position. |
(...skipping 2519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2584 } | 2586 } |
2585 return new StaticCallNode(supercall_pos, super_ctor, arguments); | 2587 return new StaticCallNode(supercall_pos, super_ctor, arguments); |
2586 } | 2588 } |
2587 | 2589 |
2588 | 2590 |
2589 AstNode* Parser::ParseInitializer(const Class& cls, | 2591 AstNode* Parser::ParseInitializer(const Class& cls, |
2590 LocalVariable* receiver, | 2592 LocalVariable* receiver, |
2591 GrowableArray<Field*>* initialized_fields) { | 2593 GrowableArray<Field*>* initialized_fields) { |
2592 TRACE_PARSER("ParseInitializer"); | 2594 TRACE_PARSER("ParseInitializer"); |
2593 const TokenPosition field_pos = TokenPos(); | 2595 const TokenPosition field_pos = TokenPos(); |
2596 if (FLAG_assert_initializer && CurrentToken() == Token::kASSERT) { | |
hausner
2016/08/15 20:54:26
Extra parens around the == expression.
| |
2597 return ParseAssertStatement(current_function().is_const()); | |
2598 } | |
2594 if (CurrentToken() == Token::kTHIS) { | 2599 if (CurrentToken() == Token::kTHIS) { |
2595 ConsumeToken(); | 2600 ConsumeToken(); |
2596 ExpectToken(Token::kPERIOD); | 2601 ExpectToken(Token::kPERIOD); |
2597 } | 2602 } |
2598 const String& field_name = *ExpectIdentifier("field name expected"); | 2603 const String& field_name = *ExpectIdentifier("field name expected"); |
2599 ExpectToken(Token::kASSIGN); | 2604 ExpectToken(Token::kASSIGN); |
2600 | 2605 |
2601 const bool saved_mode = SetAllowFunctionLiterals(false); | 2606 const bool saved_mode = SetAllowFunctionLiterals(false); |
2602 // "this" must not be accessible in initializer expressions. | 2607 // "this" must not be accessible in initializer expressions. |
2603 receiver->set_invisible(true); | 2608 receiver->set_invisible(true); |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2873 ReportError("duplicate call to super constructor"); | 2878 ReportError("duplicate call to super constructor"); |
2874 } | 2879 } |
2875 super_init_call = ParseSuperInitializer(cls, receiver); | 2880 super_init_call = ParseSuperInitializer(cls, receiver); |
2876 super_init_index = current_block_->statements->length(); | 2881 super_init_index = current_block_->statements->length(); |
2877 current_block_->statements->Add(super_init_call); | 2882 current_block_->statements->Add(super_init_call); |
2878 super_init_is_last = true; | 2883 super_init_is_last = true; |
2879 } else { | 2884 } else { |
2880 AstNode* init_statement = | 2885 AstNode* init_statement = |
2881 ParseInitializer(cls, receiver, initialized_fields); | 2886 ParseInitializer(cls, receiver, initialized_fields); |
2882 super_init_is_last = false; | 2887 super_init_is_last = false; |
2883 current_block_->statements->Add(init_statement); | 2888 if (init_statement != NULL) { |
2889 current_block_->statements->Add(init_statement); | |
2890 } | |
2884 } | 2891 } |
2885 } while (CurrentToken() == Token::kCOMMA); | 2892 } while (CurrentToken() == Token::kCOMMA); |
2886 } | 2893 } |
2887 if (super_init_call == NULL) { | 2894 if (super_init_call == NULL) { |
2888 // Generate implicit super() if we haven't seen an explicit super call | 2895 // Generate implicit super() if we haven't seen an explicit super call |
2889 // or constructor redirection. | 2896 // or constructor redirection. |
2890 super_init_call = | 2897 super_init_call = |
2891 GenerateSuperConstructorCall(cls, TokenPos(), receiver, NULL); | 2898 GenerateSuperConstructorCall(cls, TokenPos(), receiver, NULL); |
2892 if (super_init_call != NULL) { | 2899 if (super_init_call != NULL) { |
2893 super_init_index = current_block_->statements->length(); | 2900 super_init_index = current_block_->statements->length(); |
(...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3584 do { | 3591 do { |
3585 ConsumeToken(); // Colon or comma. | 3592 ConsumeToken(); // Colon or comma. |
3586 if (CurrentToken() == Token::kSUPER) { | 3593 if (CurrentToken() == Token::kSUPER) { |
3587 ConsumeToken(); | 3594 ConsumeToken(); |
3588 if (CurrentToken() == Token::kPERIOD) { | 3595 if (CurrentToken() == Token::kPERIOD) { |
3589 ConsumeToken(); | 3596 ConsumeToken(); |
3590 ExpectIdentifier("identifier expected"); | 3597 ExpectIdentifier("identifier expected"); |
3591 } | 3598 } |
3592 CheckToken(Token::kLPAREN); | 3599 CheckToken(Token::kLPAREN); |
3593 SkipToMatchingParenthesis(); | 3600 SkipToMatchingParenthesis(); |
3601 } else if (FLAG_assert_initializer && CurrentToken() == Token::kASSERT) { | |
hausner
2016/08/15 20:54:26
Extra parens around the == expression.
Lasse Reichstein Nielsen
2016/08/23 07:05:30
Done.
| |
3602 ConsumeToken(); | |
3603 CheckToken(Token::kLPAREN); | |
3604 SkipToMatchingParenthesis(); | |
3594 } else { | 3605 } else { |
3595 SkipIf(Token::kTHIS); | 3606 SkipIf(Token::kTHIS); |
3596 SkipIf(Token::kPERIOD); | 3607 SkipIf(Token::kPERIOD); |
3597 ExpectIdentifier("identifier expected"); | 3608 ExpectIdentifier("identifier expected"); |
3598 ExpectToken(Token::kASSIGN); | 3609 ExpectToken(Token::kASSIGN); |
3599 SetAllowFunctionLiterals(false); | 3610 SetAllowFunctionLiterals(false); |
3600 SkipExpr(); | 3611 SkipExpr(); |
3601 SetAllowFunctionLiterals(true); | 3612 SetAllowFunctionLiterals(true); |
3602 } | 3613 } |
3603 } while (CurrentToken() == Token::kCOMMA); | 3614 } while (CurrentToken() == Token::kCOMMA); |
(...skipping 5583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9187 const Function& func = Function::ZoneHandle(Z, | 9198 const Function& func = Function::ZoneHandle(Z, |
9188 Resolver::ResolveStatic(cls, | 9199 Resolver::ResolveStatic(cls, |
9189 func_name, | 9200 func_name, |
9190 arguments->length(), | 9201 arguments->length(), |
9191 arguments->names())); | 9202 arguments->names())); |
9192 ASSERT(!func.IsNull()); | 9203 ASSERT(!func.IsNull()); |
9193 return new(Z) StaticCallNode(arguments->token_pos(), func, arguments); | 9204 return new(Z) StaticCallNode(arguments->token_pos(), func, arguments); |
9194 } | 9205 } |
9195 | 9206 |
9196 | 9207 |
9197 AstNode* Parser::ParseAssertStatement() { | 9208 AstNode* Parser::ParseAssertStatement(bool is_const) { |
9198 TRACE_PARSER("ParseAssertStatement"); | 9209 TRACE_PARSER("ParseAssertStatement"); |
9199 ConsumeToken(); // Consume assert keyword. | 9210 ConsumeToken(); // Consume assert keyword. |
9200 ExpectToken(Token::kLPAREN); | 9211 ExpectToken(Token::kLPAREN); |
9201 const TokenPosition condition_pos = TokenPos(); | 9212 const TokenPosition condition_pos = TokenPos(); |
9202 if (!I->asserts()) { | 9213 if (!I->asserts()) { |
9203 SkipExpr(); | 9214 SkipExpr(); |
9204 ExpectToken(Token::kRPAREN); | 9215 ExpectToken(Token::kRPAREN); |
9205 return NULL; | 9216 return NULL; |
9206 } | 9217 } |
9207 AstNode* condition = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 9218 AstNode* condition = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
9219 if (is_const && !condition->IsPotentiallyConst()) { | |
9220 ReportError(condition_pos, | |
9221 "initializer assert expression must be compile time constant."); | |
9222 } | |
9208 const TokenPosition condition_end = TokenPos(); | 9223 const TokenPosition condition_end = TokenPos(); |
9209 ExpectToken(Token::kRPAREN); | 9224 ExpectToken(Token::kRPAREN); |
9210 | 9225 |
9226 // Reuse the _AssertionError._checkAssertion function for const calls as well, | |
9227 // but ensure that the value is a bool. | |
Lasse Reichstein Nielsen
2016/07/07 12:48:41
Another option is to have a separate function that
hausner
2016/08/15 20:54:26
Maybe option 2 is cleaner. I'd prefer a separate f
Lasse Reichstein Nielsen
2016/08/23 07:05:31
Will do.
| |
9211 ArgumentListNode* arguments = new(Z) ArgumentListNode(condition_pos); | 9228 ArgumentListNode* arguments = new(Z) ArgumentListNode(condition_pos); |
9212 arguments->Add(condition); | 9229 if (is_const) { |
9230 arguments->Add(new(Z) LiteralNode(condition_pos, Bool::False())); | |
hausner
2016/08/15 20:54:26
I don't see a bool parameter in _AssertionError._c
Lasse Reichstein Nielsen
2016/08/23 07:05:31
Since I already checked the condition in the `IfNo
| |
9231 } else { | |
9232 arguments->Add(condition); | |
9233 } | |
9213 arguments->Add(new(Z) LiteralNode(condition_pos, | 9234 arguments->Add(new(Z) LiteralNode(condition_pos, |
9214 Integer::ZoneHandle(Z, Integer::New(condition_pos.value(), Heap::kOld)))); | 9235 Integer::ZoneHandle(Z, Integer::New(condition_pos.value(), Heap::kOld)))); |
9215 arguments->Add(new(Z) LiteralNode(condition_end, | 9236 arguments->Add(new(Z) LiteralNode(condition_end, |
9216 Integer::ZoneHandle(Z, Integer::New(condition_end.value(), Heap::kOld)))); | 9237 Integer::ZoneHandle(Z, Integer::New(condition_end.value(), Heap::kOld)))); |
9217 return MakeStaticCall(Symbols::AssertionError(), | 9238 AstNode* assert_throw = MakeStaticCall(Symbols::AssertionError(), |
9218 Library::PrivateCoreLibName(Symbols::CheckAssertion()), | 9239 Library::PrivateCoreLibName(Symbols::CheckAssertion()), |
9219 arguments); | 9240 arguments); |
9241 | |
9242 if (!is_const) return assert_throw; | |
9243 condition = new(Z) UnaryOpNode(condition_pos, Token::kNOT, condition); | |
9244 return new(Z) IfNode( | |
9245 condition_pos, | |
9246 condition, | |
hausner
2016/08/15 20:54:26
I don't think you can use the 'condition' expressi
Lasse Reichstein Nielsen
2016/08/23 07:05:31
I don't, as explained above.
| |
9247 NodeAsSequenceNode(condition_pos, assert_throw, NULL), | |
9248 NULL); | |
9220 } | 9249 } |
9221 | 9250 |
9222 | 9251 |
9223 // Populate local scope of the catch block with the catch parameters. | 9252 // Populate local scope of the catch block with the catch parameters. |
9224 void Parser::AddCatchParamsToScope(CatchParamDesc* exception_param, | 9253 void Parser::AddCatchParamsToScope(CatchParamDesc* exception_param, |
9225 CatchParamDesc* stack_trace_param, | 9254 CatchParamDesc* stack_trace_param, |
9226 LocalScope* scope) { | 9255 LocalScope* scope) { |
9227 if (exception_param->name != NULL) { | 9256 if (exception_param->name != NULL) { |
9228 LocalVariable* var = new(Z) LocalVariable( | 9257 LocalVariable* var = new(Z) LocalVariable( |
9229 exception_param->token_pos, | 9258 exception_param->token_pos, |
(...skipping 5406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
14636 const ArgumentListNode& function_args, | 14665 const ArgumentListNode& function_args, |
14637 const LocalVariable* temp_for_last_arg, | 14666 const LocalVariable* temp_for_last_arg, |
14638 bool is_super_invocation) { | 14667 bool is_super_invocation) { |
14639 UNREACHABLE(); | 14668 UNREACHABLE(); |
14640 return NULL; | 14669 return NULL; |
14641 } | 14670 } |
14642 | 14671 |
14643 } // namespace dart | 14672 } // namespace dart |
14644 | 14673 |
14645 #endif // DART_PRECOMPILED_RUNTIME | 14674 #endif // DART_PRECOMPILED_RUNTIME |
OLD | NEW |