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 |