| 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 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
| 9 #include "vm/ast_transformer.h" | 9 #include "vm/ast_transformer.h" |
| 10 #include "vm/bootstrap.h" | 10 #include "vm/bootstrap.h" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 #include "vm/scanner.h" | 30 #include "vm/scanner.h" |
| 31 #include "vm/scopes.h" | 31 #include "vm/scopes.h" |
| 32 #include "vm/stack_frame.h" | 32 #include "vm/stack_frame.h" |
| 33 #include "vm/symbols.h" | 33 #include "vm/symbols.h" |
| 34 #include "vm/tags.h" | 34 #include "vm/tags.h" |
| 35 #include "vm/timer.h" | 35 #include "vm/timer.h" |
| 36 #include "vm/zone.h" | 36 #include "vm/zone.h" |
| 37 | 37 |
| 38 namespace dart { | 38 namespace dart { |
| 39 | 39 |
| 40 DEFINE_FLAG(bool, enable_asserts, false, "Enable assert statements."); | |
| 41 DEFINE_FLAG(bool, enable_debug_break, false, "Allow use of break \"message\"."); | 40 DEFINE_FLAG(bool, enable_debug_break, false, "Allow use of break \"message\"."); |
| 42 DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks."); | |
| 43 DEFINE_FLAG(bool, load_deferred_eagerly, false, | 41 DEFINE_FLAG(bool, load_deferred_eagerly, false, |
| 44 "Load deferred libraries eagerly."); | 42 "Load deferred libraries eagerly."); |
| 45 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); | 43 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); |
| 46 DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef."); | 44 DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef."); |
| 47 DECLARE_FLAG(bool, error_on_bad_type); | |
| 48 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); | 45 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); |
| 49 DECLARE_FLAG(bool, warn_on_javascript_compatibility); | 46 DECLARE_FLAG(bool, warn_on_javascript_compatibility); |
| 50 | 47 |
| 51 static void CheckedModeHandler(bool value) { | |
| 52 FLAG_enable_asserts = value; | |
| 53 FLAG_enable_type_checks = value; | |
| 54 } | |
| 55 | |
| 56 // --enable-checked-mode and --checked both enable checked mode which is | |
| 57 // equivalent to setting --enable-asserts and --enable-type-checks. | |
| 58 DEFINE_FLAG_HANDLER(CheckedModeHandler, | |
| 59 enable_checked_mode, | |
| 60 "Enable checked mode."); | |
| 61 | |
| 62 DEFINE_FLAG_HANDLER(CheckedModeHandler, | |
| 63 checked, | |
| 64 "Enable checked mode."); | |
| 65 | |
| 66 | 48 |
| 67 // Quick access to the current isolate and zone. | 49 // Quick access to the current isolate and zone. |
| 68 #define I (isolate()) | 50 #define I (isolate()) |
| 69 #define Z (zone()) | 51 #define Z (zone()) |
| 70 | 52 |
| 71 | 53 |
| 72 #if defined(DEBUG) | 54 #if defined(DEBUG) |
| 73 class TraceParser : public ValueObject { | 55 class TraceParser : public ValueObject { |
| 74 public: | 56 public: |
| 75 TraceParser(intptr_t token_pos, | 57 TraceParser(intptr_t token_pos, |
| (...skipping 3147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3223 ParamDesc& param = (*params.parameters)[i]; | 3205 ParamDesc& param = (*params.parameters)[i]; |
| 3224 if (param.is_field_initializer) { | 3206 if (param.is_field_initializer) { |
| 3225 ReportError(param.name_pos, | 3207 ReportError(param.name_pos, |
| 3226 "field initializer only allowed in constructors"); | 3208 "field initializer only allowed in constructors"); |
| 3227 } | 3209 } |
| 3228 } | 3210 } |
| 3229 } | 3211 } |
| 3230 // Populate function scope with the formal parameters. | 3212 // Populate function scope with the formal parameters. |
| 3231 AddFormalParamsToScope(¶ms, current_block_->scope); | 3213 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 3232 | 3214 |
| 3233 if (I->TypeChecksEnabled() && | 3215 if (I->flags().type_checks() && |
| 3234 (current_block_->scope->function_level() > 0)) { | 3216 (current_block_->scope->function_level() > 0)) { |
| 3235 // We are parsing, but not compiling, a local function. | 3217 // We are parsing, but not compiling, a local function. |
| 3236 // The instantiator may be required at run time for generic type checks. | 3218 // The instantiator may be required at run time for generic type checks. |
| 3237 if (IsInstantiatorRequired()) { | 3219 if (IsInstantiatorRequired()) { |
| 3238 // Make sure that the receiver of the enclosing instance function | 3220 // Make sure that the receiver of the enclosing instance function |
| 3239 // (or implicit first parameter of an enclosing factory) is marked as | 3221 // (or implicit first parameter of an enclosing factory) is marked as |
| 3240 // captured if type checks are enabled, because they may access it to | 3222 // captured if type checks are enabled, because they may access it to |
| 3241 // instantiate types. | 3223 // instantiate types. |
| 3242 CaptureInstantiator(); | 3224 CaptureInstantiator(); |
| 3243 } | 3225 } |
| (...skipping 4031 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7275 | 7257 |
| 7276 // Returns ast nodes of the variable initialization. Variables without an | 7258 // Returns ast nodes of the variable initialization. Variables without an |
| 7277 // explicit initializer are initialized to null. If several variables are | 7259 // explicit initializer are initialized to null. If several variables are |
| 7278 // declared, the individual initializers are collected in a sequence node. | 7260 // declared, the individual initializers are collected in a sequence node. |
| 7279 AstNode* Parser::ParseVariableDeclarationList() { | 7261 AstNode* Parser::ParseVariableDeclarationList() { |
| 7280 TRACE_PARSER("ParseVariableDeclarationList"); | 7262 TRACE_PARSER("ParseVariableDeclarationList"); |
| 7281 SkipMetadata(); | 7263 SkipMetadata(); |
| 7282 bool is_final = (CurrentToken() == Token::kFINAL); | 7264 bool is_final = (CurrentToken() == Token::kFINAL); |
| 7283 bool is_const = (CurrentToken() == Token::kCONST); | 7265 bool is_const = (CurrentToken() == Token::kCONST); |
| 7284 const AbstractType& type = AbstractType::ZoneHandle(Z, | 7266 const AbstractType& type = AbstractType::ZoneHandle(Z, |
| 7285 ParseConstFinalVarOrType(I->TypeChecksEnabled() ? | 7267 ParseConstFinalVarOrType(I->flags().type_checks() ? |
| 7286 ClassFinalizer::kCanonicalize : ClassFinalizer::kIgnore)); | 7268 ClassFinalizer::kCanonicalize : ClassFinalizer::kIgnore)); |
| 7287 if (!IsIdentifier()) { | 7269 if (!IsIdentifier()) { |
| 7288 ReportError("identifier expected"); | 7270 ReportError("identifier expected"); |
| 7289 } | 7271 } |
| 7290 | 7272 |
| 7291 SequenceNode* preamble = NULL; | 7273 SequenceNode* preamble = NULL; |
| 7292 AstNode* initializers = | 7274 AstNode* initializers = |
| 7293 ParseVariableDeclaration(type, is_final, is_const, &preamble); | 7275 ParseVariableDeclaration(type, is_final, is_const, &preamble); |
| 7294 ASSERT(initializers != NULL); | 7276 ASSERT(initializers != NULL); |
| 7295 if (preamble != NULL) { | 7277 if (preamble != NULL) { |
| (...skipping 1088 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8384 ReportError("Loop variable cannot be 'const'"); | 8366 ReportError("Loop variable cannot be 'const'"); |
| 8385 } | 8367 } |
| 8386 bool new_loop_var = false; | 8368 bool new_loop_var = false; |
| 8387 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); | 8369 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); |
| 8388 if (LookaheadToken(1) != Token::kIN) { | 8370 if (LookaheadToken(1) != Token::kIN) { |
| 8389 // Declaration of a new loop variable. | 8371 // Declaration of a new loop variable. |
| 8390 // Delay creation of the local variable until we know its actual | 8372 // Delay creation of the local variable until we know its actual |
| 8391 // position, which is inside the loop body. | 8373 // position, which is inside the loop body. |
| 8392 new_loop_var = true; | 8374 new_loop_var = true; |
| 8393 loop_var_type = ParseConstFinalVarOrType( | 8375 loop_var_type = ParseConstFinalVarOrType( |
| 8394 I->TypeChecksEnabled() ? ClassFinalizer::kCanonicalize : | 8376 I->flags().type_checks() ? ClassFinalizer::kCanonicalize : |
| 8395 ClassFinalizer::kIgnore); | 8377 ClassFinalizer::kIgnore); |
| 8396 } | 8378 } |
| 8397 intptr_t loop_var_pos = TokenPos(); | 8379 intptr_t loop_var_pos = TokenPos(); |
| 8398 const String* loop_var_name = ExpectIdentifier("variable name expected"); | 8380 const String* loop_var_name = ExpectIdentifier("variable name expected"); |
| 8399 | 8381 |
| 8400 // Parse stream expression. | 8382 // Parse stream expression. |
| 8401 ExpectToken(Token::kIN); | 8383 ExpectToken(Token::kIN); |
| 8402 const intptr_t stream_pos = TokenPos(); | 8384 const intptr_t stream_pos = TokenPos(); |
| 8403 AstNode* stream_expr = | 8385 AstNode* stream_expr = |
| 8404 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 8386 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 8405 ExpectToken(Token::kRPAREN); | 8387 ExpectToken(Token::kRPAREN); |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8664 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); | 8646 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); |
| 8665 if (LookaheadToken(1) == Token::kIN) { | 8647 if (LookaheadToken(1) == Token::kIN) { |
| 8666 loop_var_pos = TokenPos(); | 8648 loop_var_pos = TokenPos(); |
| 8667 loop_var_name = ExpectIdentifier("variable name expected"); | 8649 loop_var_name = ExpectIdentifier("variable name expected"); |
| 8668 } else { | 8650 } else { |
| 8669 // The case without a type is handled above, so require a type here. | 8651 // The case without a type is handled above, so require a type here. |
| 8670 // Delay creation of the local variable until we know its actual | 8652 // Delay creation of the local variable until we know its actual |
| 8671 // position, which is inside the loop body. | 8653 // position, which is inside the loop body. |
| 8672 new_loop_var = true; | 8654 new_loop_var = true; |
| 8673 loop_var_type = ParseConstFinalVarOrType( | 8655 loop_var_type = ParseConstFinalVarOrType( |
| 8674 I->TypeChecksEnabled() ? ClassFinalizer::kCanonicalize : | 8656 I->flags().type_checks() ? ClassFinalizer::kCanonicalize : |
| 8675 ClassFinalizer::kIgnore); | 8657 ClassFinalizer::kIgnore); |
| 8676 loop_var_name = ExpectIdentifier("variable name expected"); | 8658 loop_var_name = ExpectIdentifier("variable name expected"); |
| 8677 } | 8659 } |
| 8678 ExpectToken(Token::kIN); | 8660 ExpectToken(Token::kIN); |
| 8679 const intptr_t collection_pos = TokenPos(); | 8661 const intptr_t collection_pos = TokenPos(); |
| 8680 AstNode* collection_expr = | 8662 AstNode* collection_expr = |
| 8681 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 8663 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 8682 ExpectToken(Token::kRPAREN); | 8664 ExpectToken(Token::kRPAREN); |
| 8683 | 8665 |
| 8684 OpenBlock(); // Implicit block around while loop. | 8666 OpenBlock(); // Implicit block around while loop. |
| 8685 | 8667 |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8883 } | 8865 } |
| 8884 return condition; | 8866 return condition; |
| 8885 } | 8867 } |
| 8886 | 8868 |
| 8887 | 8869 |
| 8888 AstNode* Parser::ParseAssertStatement() { | 8870 AstNode* Parser::ParseAssertStatement() { |
| 8889 TRACE_PARSER("ParseAssertStatement"); | 8871 TRACE_PARSER("ParseAssertStatement"); |
| 8890 ConsumeToken(); // Consume assert keyword. | 8872 ConsumeToken(); // Consume assert keyword. |
| 8891 ExpectToken(Token::kLPAREN); | 8873 ExpectToken(Token::kLPAREN); |
| 8892 const intptr_t condition_pos = TokenPos(); | 8874 const intptr_t condition_pos = TokenPos(); |
| 8893 if (!I->AssertsEnabled() && !I->TypeChecksEnabled()) { | 8875 if (!I->flags().asserts() && !I->flags().type_checks()) { |
| 8894 SkipExpr(); | 8876 SkipExpr(); |
| 8895 ExpectToken(Token::kRPAREN); | 8877 ExpectToken(Token::kRPAREN); |
| 8896 return NULL; | 8878 return NULL; |
| 8897 } | 8879 } |
| 8898 AstNode* condition = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 8880 AstNode* condition = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 8899 const intptr_t condition_end = TokenPos(); | 8881 const intptr_t condition_end = TokenPos(); |
| 8900 ExpectToken(Token::kRPAREN); | 8882 ExpectToken(Token::kRPAREN); |
| 8901 condition = InsertClosureCallNodes(condition); | 8883 condition = InsertClosureCallNodes(condition); |
| 8902 condition = new(Z) UnaryOpNode(condition_pos, Token::kNOT, condition); | 8884 condition = new(Z) UnaryOpNode(condition_pos, Token::kNOT, condition); |
| 8903 AstNode* assert_throw = MakeAssertCall(condition_pos, condition_end); | 8885 AstNode* assert_throw = MakeAssertCall(condition_pos, condition_end); |
| (...skipping 3172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12076 ASSERT(!element_type.IsMalformed()); // Would be mapped to dynamic. | 12058 ASSERT(!element_type.IsMalformed()); // Would be mapped to dynamic. |
| 12077 ASSERT(!element_type.IsMalbounded()); // No declared bound in List. | 12059 ASSERT(!element_type.IsMalbounded()); // No declared bound in List. |
| 12078 if (element_type.IsDynamicType()) { | 12060 if (element_type.IsDynamicType()) { |
| 12079 list_type_arguments = TypeArguments::null(); | 12061 list_type_arguments = TypeArguments::null(); |
| 12080 } else if (is_const && !element_type.IsInstantiated()) { | 12062 } else if (is_const && !element_type.IsInstantiated()) { |
| 12081 ReportError(type_pos, | 12063 ReportError(type_pos, |
| 12082 "the type argument of a constant list literal cannot " | 12064 "the type argument of a constant list literal cannot " |
| 12083 "include a type variable"); | 12065 "include a type variable"); |
| 12084 } | 12066 } |
| 12085 } else { | 12067 } else { |
| 12086 if (I->ErrorOnBadTypeEnabled()) { | 12068 if (I->flags().error_on_bad_type()) { |
| 12087 ReportError(type_pos, | 12069 ReportError(type_pos, |
| 12088 "a list literal takes one type argument specifying " | 12070 "a list literal takes one type argument specifying " |
| 12089 "the element type"); | 12071 "the element type"); |
| 12090 } | 12072 } |
| 12091 // Ignore type arguments. | 12073 // Ignore type arguments. |
| 12092 list_type_arguments = TypeArguments::null(); | 12074 list_type_arguments = TypeArguments::null(); |
| 12093 } | 12075 } |
| 12094 } | 12076 } |
| 12095 ASSERT(list_type_arguments.IsNull() || (list_type_arguments.Length() == 1)); | 12077 ASSERT(list_type_arguments.IsNull() || (list_type_arguments.Length() == 1)); |
| 12096 const Class& array_class = Class::Handle(Z, I->object_store()->array_class()); | 12078 const Class& array_class = Class::Handle(Z, I->object_store()->array_class()); |
| 12097 Type& type = Type::ZoneHandle(Z, | 12079 Type& type = Type::ZoneHandle(Z, |
| 12098 Type::New(array_class, list_type_arguments, type_pos)); | 12080 Type::New(array_class, list_type_arguments, type_pos)); |
| 12099 type ^= ClassFinalizer::FinalizeType( | 12081 type ^= ClassFinalizer::FinalizeType( |
| 12100 current_class(), type, ClassFinalizer::kCanonicalize); | 12082 current_class(), type, ClassFinalizer::kCanonicalize); |
| 12101 GrowableArray<AstNode*> element_list; | 12083 GrowableArray<AstNode*> element_list; |
| 12102 // Parse the list elements. Note: there may be an optional extra | 12084 // Parse the list elements. Note: there may be an optional extra |
| 12103 // comma after the last element. | 12085 // comma after the last element. |
| 12104 if (!is_empty_literal) { | 12086 if (!is_empty_literal) { |
| 12105 const bool saved_mode = SetAllowFunctionLiterals(true); | 12087 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 12106 while (CurrentToken() != Token::kRBRACK) { | 12088 while (CurrentToken() != Token::kRBRACK) { |
| 12107 const intptr_t element_pos = TokenPos(); | 12089 const intptr_t element_pos = TokenPos(); |
| 12108 AstNode* element = ParseExpr(is_const, kConsumeCascades); | 12090 AstNode* element = ParseExpr(is_const, kConsumeCascades); |
| 12109 if (I->TypeChecksEnabled() && | 12091 if (I->flags().type_checks() && |
| 12110 !is_const && | 12092 !is_const && |
| 12111 !element_type.IsDynamicType()) { | 12093 !element_type.IsDynamicType()) { |
| 12112 element = new(Z) AssignableNode(element_pos, | 12094 element = new(Z) AssignableNode(element_pos, |
| 12113 element, | 12095 element, |
| 12114 element_type, | 12096 element_type, |
| 12115 Symbols::ListLiteralElement()); | 12097 Symbols::ListLiteralElement()); |
| 12116 } | 12098 } |
| 12117 element_list.Add(element); | 12099 element_list.Add(element); |
| 12118 if (CurrentToken() == Token::kCOMMA) { | 12100 if (CurrentToken() == Token::kCOMMA) { |
| 12119 ConsumeToken(); | 12101 ConsumeToken(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 12130 Array& const_list = | 12112 Array& const_list = |
| 12131 Array::ZoneHandle(Z, Array::New(element_list.length(), Heap::kOld)); | 12113 Array::ZoneHandle(Z, Array::New(element_list.length(), Heap::kOld)); |
| 12132 const_list.SetTypeArguments( | 12114 const_list.SetTypeArguments( |
| 12133 TypeArguments::Handle(Z, list_type_arguments.Canonicalize())); | 12115 TypeArguments::Handle(Z, list_type_arguments.Canonicalize())); |
| 12134 Error& malformed_error = Error::Handle(Z); | 12116 Error& malformed_error = Error::Handle(Z); |
| 12135 for (int i = 0; i < element_list.length(); i++) { | 12117 for (int i = 0; i < element_list.length(); i++) { |
| 12136 AstNode* elem = element_list[i]; | 12118 AstNode* elem = element_list[i]; |
| 12137 // Arguments have been evaluated to a literal value already. | 12119 // Arguments have been evaluated to a literal value already. |
| 12138 ASSERT(elem->IsLiteralNode()); | 12120 ASSERT(elem->IsLiteralNode()); |
| 12139 ASSERT(!is_top_level_); // We cannot check unresolved types. | 12121 ASSERT(!is_top_level_); // We cannot check unresolved types. |
| 12140 if (I->TypeChecksEnabled() && | 12122 if (I->flags().type_checks() && |
| 12141 !element_type.IsDynamicType() && | 12123 !element_type.IsDynamicType() && |
| 12142 (!elem->AsLiteralNode()->literal().IsNull() && | 12124 (!elem->AsLiteralNode()->literal().IsNull() && |
| 12143 !elem->AsLiteralNode()->literal().IsInstanceOf( | 12125 !elem->AsLiteralNode()->literal().IsInstanceOf( |
| 12144 element_type, | 12126 element_type, |
| 12145 TypeArguments::Handle(Z), | 12127 TypeArguments::Handle(Z), |
| 12146 &malformed_error))) { | 12128 &malformed_error))) { |
| 12147 // If the failure is due to a malformed type error, display it instead. | 12129 // If the failure is due to a malformed type error, display it instead. |
| 12148 if (!malformed_error.IsNull()) { | 12130 if (!malformed_error.IsNull()) { |
| 12149 ReportError(malformed_error); | 12131 ReportError(malformed_error); |
| 12150 } else { | 12132 } else { |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12273 // No declared bounds in Map. | 12255 // No declared bounds in Map. |
| 12274 ASSERT(!key_type.IsMalbounded() && !value_type.IsMalbounded()); | 12256 ASSERT(!key_type.IsMalbounded() && !value_type.IsMalbounded()); |
| 12275 if (key_type.IsDynamicType() && value_type.IsDynamicType()) { | 12257 if (key_type.IsDynamicType() && value_type.IsDynamicType()) { |
| 12276 map_type_arguments = TypeArguments::null(); | 12258 map_type_arguments = TypeArguments::null(); |
| 12277 } else if (is_const && !type_arguments.IsInstantiated()) { | 12259 } else if (is_const && !type_arguments.IsInstantiated()) { |
| 12278 ReportError(type_pos, | 12260 ReportError(type_pos, |
| 12279 "the type arguments of a constant map literal cannot " | 12261 "the type arguments of a constant map literal cannot " |
| 12280 "include a type variable"); | 12262 "include a type variable"); |
| 12281 } | 12263 } |
| 12282 } else { | 12264 } else { |
| 12283 if (I->ErrorOnBadTypeEnabled()) { | 12265 if (I->flags().error_on_bad_type()) { |
| 12284 ReportError(type_pos, | 12266 ReportError(type_pos, |
| 12285 "a map literal takes two type arguments specifying " | 12267 "a map literal takes two type arguments specifying " |
| 12286 "the key type and the value type"); | 12268 "the key type and the value type"); |
| 12287 } | 12269 } |
| 12288 // Ignore type arguments. | 12270 // Ignore type arguments. |
| 12289 map_type_arguments = TypeArguments::null(); | 12271 map_type_arguments = TypeArguments::null(); |
| 12290 } | 12272 } |
| 12291 } | 12273 } |
| 12292 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); | 12274 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); |
| 12293 map_type_arguments ^= map_type_arguments.Canonicalize(); | 12275 map_type_arguments ^= map_type_arguments.Canonicalize(); |
| 12294 | 12276 |
| 12295 GrowableArray<AstNode*> kv_pairs_list; | 12277 GrowableArray<AstNode*> kv_pairs_list; |
| 12296 // Parse the map entries. Note: there may be an optional extra | 12278 // Parse the map entries. Note: there may be an optional extra |
| 12297 // comma after the last entry. | 12279 // comma after the last entry. |
| 12298 while (CurrentToken() != Token::kRBRACE) { | 12280 while (CurrentToken() != Token::kRBRACE) { |
| 12299 const bool saved_mode = SetAllowFunctionLiterals(true); | 12281 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 12300 const intptr_t key_pos = TokenPos(); | 12282 const intptr_t key_pos = TokenPos(); |
| 12301 AstNode* key = ParseExpr(is_const, kConsumeCascades); | 12283 AstNode* key = ParseExpr(is_const, kConsumeCascades); |
| 12302 if (I->TypeChecksEnabled() && | 12284 if (I->flags().type_checks() && |
| 12303 !is_const && | 12285 !is_const && |
| 12304 !key_type.IsDynamicType()) { | 12286 !key_type.IsDynamicType()) { |
| 12305 key = new(Z) AssignableNode( | 12287 key = new(Z) AssignableNode( |
| 12306 key_pos, key, key_type, Symbols::ListLiteralElement()); | 12288 key_pos, key, key_type, Symbols::ListLiteralElement()); |
| 12307 } | 12289 } |
| 12308 if (is_const) { | 12290 if (is_const) { |
| 12309 ASSERT(key->IsLiteralNode()); | 12291 ASSERT(key->IsLiteralNode()); |
| 12310 const Instance& key_value = key->AsLiteralNode()->literal(); | 12292 const Instance& key_value = key->AsLiteralNode()->literal(); |
| 12311 if (key_value.IsDouble()) { | 12293 if (key_value.IsDouble()) { |
| 12312 ReportError(key_pos, "key value must not be of type double"); | 12294 ReportError(key_pos, "key value must not be of type double"); |
| 12313 } | 12295 } |
| 12314 if (!key_value.IsInteger() && | 12296 if (!key_value.IsInteger() && |
| 12315 !key_value.IsString() && | 12297 !key_value.IsString() && |
| 12316 (key_value.clazz() != I->object_store()->symbol_class()) && | 12298 (key_value.clazz() != I->object_store()->symbol_class()) && |
| 12317 ImplementsEqualOperator(key_value)) { | 12299 ImplementsEqualOperator(key_value)) { |
| 12318 ReportError(key_pos, "key value must not implement operator =="); | 12300 ReportError(key_pos, "key value must not implement operator =="); |
| 12319 } | 12301 } |
| 12320 } | 12302 } |
| 12321 ExpectToken(Token::kCOLON); | 12303 ExpectToken(Token::kCOLON); |
| 12322 const intptr_t value_pos = TokenPos(); | 12304 const intptr_t value_pos = TokenPos(); |
| 12323 AstNode* value = ParseExpr(is_const, kConsumeCascades); | 12305 AstNode* value = ParseExpr(is_const, kConsumeCascades); |
| 12324 SetAllowFunctionLiterals(saved_mode); | 12306 SetAllowFunctionLiterals(saved_mode); |
| 12325 if (I->TypeChecksEnabled() && | 12307 if (I->flags().type_checks() && |
| 12326 !is_const && | 12308 !is_const && |
| 12327 !value_type.IsDynamicType()) { | 12309 !value_type.IsDynamicType()) { |
| 12328 value = new(Z) AssignableNode( | 12310 value = new(Z) AssignableNode( |
| 12329 value_pos, value, value_type, Symbols::ListLiteralElement()); | 12311 value_pos, value, value_type, Symbols::ListLiteralElement()); |
| 12330 } | 12312 } |
| 12331 AddKeyValuePair(&kv_pairs_list, is_const, key, value); | 12313 AddKeyValuePair(&kv_pairs_list, is_const, key, value); |
| 12332 | 12314 |
| 12333 if (CurrentToken() == Token::kCOMMA) { | 12315 if (CurrentToken() == Token::kCOMMA) { |
| 12334 ConsumeToken(); | 12316 ConsumeToken(); |
| 12335 } else if (CurrentToken() != Token::kRBRACE) { | 12317 } else if (CurrentToken() != Token::kRBRACE) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 12347 // First, create the canonicalized key-value pair array. | 12329 // First, create the canonicalized key-value pair array. |
| 12348 Array& key_value_array = | 12330 Array& key_value_array = |
| 12349 Array::ZoneHandle(Z, Array::New(kv_pairs_list.length(), Heap::kOld)); | 12331 Array::ZoneHandle(Z, Array::New(kv_pairs_list.length(), Heap::kOld)); |
| 12350 AbstractType& arg_type = Type::Handle(Z); | 12332 AbstractType& arg_type = Type::Handle(Z); |
| 12351 Error& malformed_error = Error::Handle(Z); | 12333 Error& malformed_error = Error::Handle(Z); |
| 12352 for (int i = 0; i < kv_pairs_list.length(); i++) { | 12334 for (int i = 0; i < kv_pairs_list.length(); i++) { |
| 12353 AstNode* arg = kv_pairs_list[i]; | 12335 AstNode* arg = kv_pairs_list[i]; |
| 12354 // Arguments have been evaluated to a literal value already. | 12336 // Arguments have been evaluated to a literal value already. |
| 12355 ASSERT(arg->IsLiteralNode()); | 12337 ASSERT(arg->IsLiteralNode()); |
| 12356 ASSERT(!is_top_level_); // We cannot check unresolved types. | 12338 ASSERT(!is_top_level_); // We cannot check unresolved types. |
| 12357 if (I->TypeChecksEnabled()) { | 12339 if (I->flags().type_checks()) { |
| 12358 if ((i % 2) == 0) { | 12340 if ((i % 2) == 0) { |
| 12359 // Check key type. | 12341 // Check key type. |
| 12360 arg_type = key_type.raw(); | 12342 arg_type = key_type.raw(); |
| 12361 } else { | 12343 } else { |
| 12362 // Check value type. | 12344 // Check value type. |
| 12363 arg_type = value_type.raw(); | 12345 arg_type = value_type.raw(); |
| 12364 } | 12346 } |
| 12365 if (!arg_type.IsDynamicType() && | 12347 if (!arg_type.IsDynamicType() && |
| 12366 (!arg->AsLiteralNode()->literal().IsNull() && | 12348 (!arg->AsLiteralNode()->literal().IsNull() && |
| 12367 !arg->AsLiteralNode()->literal().IsInstanceOf( | 12349 !arg->AsLiteralNode()->literal().IsInstanceOf( |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12672 "redirecting factory type '%s' cannot be instantiated", | 12654 "redirecting factory type '%s' cannot be instantiated", |
| 12673 String::Handle(Z, redirect_type.UserVisibleName()).ToCString()); | 12655 String::Handle(Z, redirect_type.UserVisibleName()).ToCString()); |
| 12674 } | 12656 } |
| 12675 } | 12657 } |
| 12676 if (redirect_type.IsMalformedOrMalbounded()) { | 12658 if (redirect_type.IsMalformedOrMalbounded()) { |
| 12677 if (is_const) { | 12659 if (is_const) { |
| 12678 ReportError(Error::Handle(Z, redirect_type.error())); | 12660 ReportError(Error::Handle(Z, redirect_type.error())); |
| 12679 } | 12661 } |
| 12680 return ThrowTypeError(redirect_type.token_pos(), redirect_type); | 12662 return ThrowTypeError(redirect_type.token_pos(), redirect_type); |
| 12681 } | 12663 } |
| 12682 if (I->TypeChecksEnabled() && !redirect_type.IsSubtypeOf(type, NULL)) { | 12664 if (I->flags().type_checks() && !redirect_type.IsSubtypeOf(type, NULL)) { |
| 12683 // Additional type checking of the result is necessary. | 12665 // Additional type checking of the result is necessary. |
| 12684 type_bound = type.raw(); | 12666 type_bound = type.raw(); |
| 12685 } | 12667 } |
| 12686 type = redirect_type.raw(); | 12668 type = redirect_type.raw(); |
| 12687 type_class = type.type_class(); | 12669 type_class = type.type_class(); |
| 12688 type_class_name = type_class.Name(); | 12670 type_class_name = type_class.Name(); |
| 12689 type_arguments = type.arguments(); | 12671 type_arguments = type.arguments(); |
| 12690 constructor = constructor.RedirectionTarget(); | 12672 constructor = constructor.RedirectionTarget(); |
| 12691 constructor_name = constructor.name(); | 12673 constructor_name = constructor.name(); |
| 12692 ASSERT(!constructor.IsNull()); | 12674 ASSERT(!constructor.IsNull()); |
| (...skipping 801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13494 void Parser::SkipQualIdent() { | 13476 void Parser::SkipQualIdent() { |
| 13495 ASSERT(IsIdentifier()); | 13477 ASSERT(IsIdentifier()); |
| 13496 ConsumeToken(); | 13478 ConsumeToken(); |
| 13497 if (CurrentToken() == Token::kPERIOD) { | 13479 if (CurrentToken() == Token::kPERIOD) { |
| 13498 ConsumeToken(); // Consume the kPERIOD token. | 13480 ConsumeToken(); // Consume the kPERIOD token. |
| 13499 ExpectIdentifier("identifier expected after '.'"); | 13481 ExpectIdentifier("identifier expected after '.'"); |
| 13500 } | 13482 } |
| 13501 } | 13483 } |
| 13502 | 13484 |
| 13503 } // namespace dart | 13485 } // namespace dart |
| OLD | NEW |