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

Side by Side Diff: runtime/vm/parser.cc

Issue 2574003003: Add optional message argument to assert statements in the VM. (Closed)
Patch Set: Update dart2js status file Created 4 years 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 | « runtime/vm/code_generator.cc ('k') | runtime/vm/symbols.h » ('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 (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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 DEFINE_FLAG(bool, warn_patch, false, "Warn on old-style patch syntax."); 63 DEFINE_FLAG(bool, warn_patch, false, "Warn on old-style patch syntax.");
64 DEFINE_FLAG( 64 DEFINE_FLAG(
65 bool, 65 bool,
66 await_is_keyword, 66 await_is_keyword,
67 false, 67 false,
68 "await and yield are treated as proper keywords in synchronous code."); 68 "await and yield are treated as proper keywords in synchronous code.");
69 DEFINE_FLAG(bool, 69 DEFINE_FLAG(bool,
70 assert_initializer, 70 assert_initializer,
71 false, 71 false,
72 "Allow asserts in initializer lists."); 72 "Allow asserts in initializer lists.");
73 DEFINE_FLAG(bool, assert_message, false, "Allow message in assert statements");
73 74
74 DECLARE_FLAG(bool, profile_vm); 75 DECLARE_FLAG(bool, profile_vm);
75 DECLARE_FLAG(bool, trace_service); 76 DECLARE_FLAG(bool, trace_service);
76 DECLARE_FLAG(bool, ignore_patch_signature_mismatch); 77 DECLARE_FLAG(bool, ignore_patch_signature_mismatch);
77 78
78 // Quick access to the current thread, isolate and zone. 79 // Quick access to the current thread, isolate and zone.
79 #define T (thread()) 80 #define T (thread())
80 #define I (isolate()) 81 #define I (isolate())
81 #define Z (zone()) 82 #define Z (zone())
82 83
(...skipping 9074 matching lines...) Expand 10 before | Expand all | Expand 10 after
9157 } 9158 }
9158 9159
9159 9160
9160 AstNode* Parser::ParseAssertStatement(bool is_const) { 9161 AstNode* Parser::ParseAssertStatement(bool is_const) {
9161 TRACE_PARSER("ParseAssertStatement"); 9162 TRACE_PARSER("ParseAssertStatement");
9162 ConsumeToken(); // Consume assert keyword. 9163 ConsumeToken(); // Consume assert keyword.
9163 ExpectToken(Token::kLPAREN); 9164 ExpectToken(Token::kLPAREN);
9164 const TokenPosition condition_pos = TokenPos(); 9165 const TokenPosition condition_pos = TokenPos();
9165 if (!I->asserts()) { 9166 if (!I->asserts()) {
9166 SkipExpr(); 9167 SkipExpr();
9168 if (FLAG_assert_message && (CurrentToken() == Token::kCOMMA)) {
9169 ConsumeToken();
9170 SkipExpr();
9171 }
9167 ExpectToken(Token::kRPAREN); 9172 ExpectToken(Token::kRPAREN);
9168 return NULL; 9173 return NULL;
9169 } 9174 }
9170 AstNode* condition = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); 9175
9176 BoolScope saved_seen_await(&parsed_function()->have_seen_await_expr_, false);
9177 AstNode* condition = ParseExpr(kAllowConst, kConsumeCascades);
9171 if (is_const && !condition->IsPotentiallyConst()) { 9178 if (is_const && !condition->IsPotentiallyConst()) {
9172 ReportError(condition_pos, 9179 ReportError(condition_pos,
9173 "initializer assert expression must be compile time constant."); 9180 "initializer assert expression must be compile time constant.");
9174 } 9181 }
9175 const TokenPosition condition_end = TokenPos(); 9182 const TokenPosition condition_end = TokenPos();
9183 AstNode* message = NULL;
9184 TokenPosition message_pos = TokenPosition::kNoSource;
9185 if (FLAG_assert_message && CurrentToken() == Token::kCOMMA) {
9186 ConsumeToken();
9187 message_pos = TokenPos();
9188 message = ParseExpr(kAllowConst, kConsumeCascades);
9189 if (is_const && !message->IsPotentiallyConst()) {
9190 ReportError(
9191 message_pos,
9192 "initializer assert expression must be compile time constant.");
9193 }
9194 }
9176 ExpectToken(Token::kRPAREN); 9195 ExpectToken(Token::kRPAREN);
9177 9196
9197 if (!is_const) {
9198 // Check for assertion condition being a function if not const.
9199 ArgumentListNode* arguments = new (Z) ArgumentListNode(condition_pos);
9200 arguments->Add(condition);
9201 condition = MakeStaticCall(
9202 Symbols::AssertionError(),
9203 Library::PrivateCoreLibName(Symbols::EvaluateAssertion()), arguments);
9204 }
9205 AstNode* not_condition =
9206 new (Z) UnaryOpNode(condition_pos, Token::kNOT, condition);
9207
9208 // Build call to _AsertionError._throwNew(start, end, message)
9178 ArgumentListNode* arguments = new (Z) ArgumentListNode(condition_pos); 9209 ArgumentListNode* arguments = new (Z) ArgumentListNode(condition_pos);
9179 arguments->Add(condition);
9180 arguments->Add(new (Z) LiteralNode( 9210 arguments->Add(new (Z) LiteralNode(
9181 condition_pos, 9211 condition_pos,
9182 Integer::ZoneHandle(Z, Integer::New(condition_pos.value(), Heap::kOld)))); 9212 Integer::ZoneHandle(Z, Integer::New(condition_pos.Pos()))));
9183 arguments->Add(new (Z) LiteralNode( 9213 arguments->Add(new (Z) LiteralNode(
9184 condition_end, 9214 condition_end,
9185 Integer::ZoneHandle(Z, Integer::New(condition_end.value(), Heap::kOld)))); 9215 Integer::ZoneHandle(Z, Integer::New(condition_end.Pos()))));
9216 if (message == NULL) {
9217 message = new (Z) LiteralNode(condition_end, Instance::ZoneHandle(Z));
9218 }
9219 arguments->Add(message);
9186 AstNode* assert_throw = MakeStaticCall( 9220 AstNode* assert_throw = MakeStaticCall(
9187 Symbols::AssertionError(), 9221 Symbols::AssertionError(),
9188 Library::PrivateCoreLibName(is_const ? Symbols::CheckConstAssertion() 9222 Library::PrivateCoreLibName(Symbols::ThrowNew()), arguments);
9189 : Symbols::CheckAssertion()),
9190 arguments);
9191 9223
9192 return assert_throw; 9224 AstNode* assertion_check = NULL;
9225 if (parsed_function()->have_seen_await()) {
9226 // The await transformation must be done manually because assertions
9227 // are parsed as statements, not expressions. Thus, we need to check
9228 // explicitely whether the arguments contain await operators. (Note that
9229 // we must not parse the arguments with ParseAwaitableExpr(). In the
9230 // corner case of assert(await a, await b), this would create two
9231 // sibling scopes containing the temporary values for a and b. Both
9232 // values would be allocated in the same internal context variable.)
9233 //
9234 // Build !condition ? _AsertionError._throwNew(...) : null;
9235 // We need to use a conditional expression because the await transformer
9236 // cannot transform if statements.
9237 assertion_check = new (Z) ConditionalExprNode(
9238 condition_pos, not_condition, assert_throw,
9239 new (Z) LiteralNode(condition_pos, Object::null_instance()));
9240 OpenBlock();
9241 AwaitTransformer at(current_block_->statements, async_temp_scope_);
9242 AstNode* transformed_assertion = at.Transform(assertion_check);
9243 SequenceNode* preamble = CloseBlock();
9244 preamble->Add(transformed_assertion);
9245 assertion_check = preamble;
9246 } else {
9247 // Build if (!condition) _AsertionError._throwNew(...)
9248 assertion_check = new (Z)
9249 IfNode(condition_pos, not_condition,
9250 NodeAsSequenceNode(condition_pos, assert_throw, NULL), NULL);
9251 }
9252 return assertion_check;
9193 } 9253 }
9194 9254
9195 9255
9196 // Populate local scope of the catch block with the catch parameters. 9256 // Populate local scope of the catch block with the catch parameters.
9197 void Parser::AddCatchParamsToScope(CatchParamDesc* exception_param, 9257 void Parser::AddCatchParamsToScope(CatchParamDesc* exception_param,
9198 CatchParamDesc* stack_trace_param, 9258 CatchParamDesc* stack_trace_param,
9199 LocalScope* scope) { 9259 LocalScope* scope) {
9200 if (exception_param->name != NULL) { 9260 if (exception_param->name != NULL) {
9201 LocalVariable* var = new (Z) 9261 LocalVariable* var = new (Z)
9202 LocalVariable(exception_param->token_pos, exception_param->token_pos, 9262 LocalVariable(exception_param->token_pos, exception_param->token_pos,
(...skipping 5281 matching lines...) Expand 10 before | Expand all | Expand 10 after
14484 const ArgumentListNode& function_args, 14544 const ArgumentListNode& function_args,
14485 const LocalVariable* temp_for_last_arg, 14545 const LocalVariable* temp_for_last_arg,
14486 bool is_super_invocation) { 14546 bool is_super_invocation) {
14487 UNREACHABLE(); 14547 UNREACHABLE();
14488 return NULL; 14548 return NULL;
14489 } 14549 }
14490 14550
14491 } // namespace dart 14551 } // namespace dart
14492 14552
14493 #endif // DART_PRECOMPILED_RUNTIME 14553 #endif // DART_PRECOMPILED_RUNTIME
OLDNEW
« no previous file with comments | « runtime/vm/code_generator.cc ('k') | runtime/vm/symbols.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698