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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 DEFINE_FLAG_HANDLER(CheckedModeHandler, | 59 DEFINE_FLAG_HANDLER(CheckedModeHandler, |
60 checked, | 60 checked, |
61 "Enable checked mode."); | 61 "Enable checked mode."); |
62 | 62 |
63 | 63 |
64 // Quick access to the current isolate and zone. | 64 // Quick access to the current isolate and zone. |
65 #define I (thread()->isolate()) | 65 #define I (thread()->isolate()) |
66 #define Z (zone()) | 66 #define Z (zone()) |
67 | 67 |
68 | 68 |
| 69 static bool TypeChecksEnabled(Isolate* isolate) { |
| 70 return FLAG_enable_type_checks || isolate->checked_mode(); |
| 71 } |
| 72 |
| 73 |
| 74 static bool AssertsEnabled(Isolate* isolate) { |
| 75 return FLAG_enable_asserts || isolate->checked_mode(); |
| 76 } |
| 77 |
| 78 |
| 79 static bool ErrorOnBadTypeEnabled(Isolate* isolate) { |
| 80 return FLAG_error_on_bad_type || isolate->checked_mode(); |
| 81 } |
| 82 |
| 83 |
69 #if defined(DEBUG) | 84 #if defined(DEBUG) |
70 class TraceParser : public ValueObject { | 85 class TraceParser : public ValueObject { |
71 public: | 86 public: |
72 TraceParser(intptr_t token_pos, const Script& script, const char* msg) { | 87 TraceParser(intptr_t token_pos, const Script& script, const char* msg) { |
73 if (FLAG_trace_parser) { | 88 if (FLAG_trace_parser) { |
74 // Skips tracing of bootstrap libraries. | 89 // Skips tracing of bootstrap libraries. |
75 if (script.HasSource()) { | 90 if (script.HasSource()) { |
76 intptr_t line, column; | 91 intptr_t line, column; |
77 script.GetTokenLocation(token_pos, &line, &column); | 92 script.GetTokenLocation(token_pos, &line, &column); |
78 PrintIndent(); | 93 PrintIndent(); |
(...skipping 3039 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3118 ParamDesc& param = (*params.parameters)[i]; | 3133 ParamDesc& param = (*params.parameters)[i]; |
3119 if (param.is_field_initializer) { | 3134 if (param.is_field_initializer) { |
3120 ReportError(param.name_pos, | 3135 ReportError(param.name_pos, |
3121 "field initializer only allowed in constructors"); | 3136 "field initializer only allowed in constructors"); |
3122 } | 3137 } |
3123 } | 3138 } |
3124 } | 3139 } |
3125 // Populate function scope with the formal parameters. | 3140 // Populate function scope with the formal parameters. |
3126 AddFormalParamsToScope(¶ms, current_block_->scope); | 3141 AddFormalParamsToScope(¶ms, current_block_->scope); |
3127 | 3142 |
3128 if (FLAG_enable_type_checks && | 3143 if (TypeChecksEnabled(I) && |
3129 (current_block_->scope->function_level() > 0)) { | 3144 (current_block_->scope->function_level() > 0)) { |
3130 // We are parsing, but not compiling, a local function. | 3145 // We are parsing, but not compiling, a local function. |
3131 // The instantiator may be required at run time for generic type checks. | 3146 // The instantiator may be required at run time for generic type checks. |
3132 if (IsInstantiatorRequired()) { | 3147 if (IsInstantiatorRequired()) { |
3133 // Make sure that the receiver of the enclosing instance function | 3148 // Make sure that the receiver of the enclosing instance function |
3134 // (or implicit first parameter of an enclosing factory) is marked as | 3149 // (or implicit first parameter of an enclosing factory) is marked as |
3135 // captured if type checks are enabled, because they may access it to | 3150 // captured if type checks are enabled, because they may access it to |
3136 // instantiate types. | 3151 // instantiate types. |
3137 CaptureInstantiator(); | 3152 CaptureInstantiator(); |
3138 } | 3153 } |
(...skipping 3415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6554 | 6569 |
6555 // Returns ast nodes of the variable initialization. Variables without an | 6570 // Returns ast nodes of the variable initialization. Variables without an |
6556 // explicit initializer are initialized to null. If several variables are | 6571 // explicit initializer are initialized to null. If several variables are |
6557 // declared, the individual initializers are collected in a sequence node. | 6572 // declared, the individual initializers are collected in a sequence node. |
6558 AstNode* Parser::ParseVariableDeclarationList() { | 6573 AstNode* Parser::ParseVariableDeclarationList() { |
6559 TRACE_PARSER("ParseVariableDeclarationList"); | 6574 TRACE_PARSER("ParseVariableDeclarationList"); |
6560 SkipMetadata(); | 6575 SkipMetadata(); |
6561 bool is_final = (CurrentToken() == Token::kFINAL); | 6576 bool is_final = (CurrentToken() == Token::kFINAL); |
6562 bool is_const = (CurrentToken() == Token::kCONST); | 6577 bool is_const = (CurrentToken() == Token::kCONST); |
6563 const AbstractType& type = AbstractType::ZoneHandle(Z, | 6578 const AbstractType& type = AbstractType::ZoneHandle(Z, |
6564 ParseConstFinalVarOrType(FLAG_enable_type_checks ? | 6579 ParseConstFinalVarOrType(TypeChecksEnabled(I) ? |
6565 ClassFinalizer::kCanonicalize : ClassFinalizer::kIgnore)); | 6580 ClassFinalizer::kCanonicalize : ClassFinalizer::kIgnore)); |
6566 if (!IsIdentifier()) { | 6581 if (!IsIdentifier()) { |
6567 ReportError("identifier expected"); | 6582 ReportError("identifier expected"); |
6568 } | 6583 } |
6569 | 6584 |
6570 SequenceNode* preamble = NULL; | 6585 SequenceNode* preamble = NULL; |
6571 AstNode* initializers = | 6586 AstNode* initializers = |
6572 ParseVariableDeclaration(type, is_final, is_const, &preamble); | 6587 ParseVariableDeclaration(type, is_final, is_const, &preamble); |
6573 ASSERT(initializers != NULL); | 6588 ASSERT(initializers != NULL); |
6574 if (preamble != NULL) { | 6589 if (preamble != NULL) { |
(...skipping 967 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7542 ReportError("Loop variable cannot be 'const'"); | 7557 ReportError("Loop variable cannot be 'const'"); |
7543 } | 7558 } |
7544 bool new_loop_var = false; | 7559 bool new_loop_var = false; |
7545 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); | 7560 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); |
7546 if (LookaheadToken(1) != Token::kIN) { | 7561 if (LookaheadToken(1) != Token::kIN) { |
7547 // Declaration of a new loop variable. | 7562 // Declaration of a new loop variable. |
7548 // Delay creation of the local variable until we know its actual | 7563 // Delay creation of the local variable until we know its actual |
7549 // position, which is inside the loop body. | 7564 // position, which is inside the loop body. |
7550 new_loop_var = true; | 7565 new_loop_var = true; |
7551 loop_var_type = ParseConstFinalVarOrType( | 7566 loop_var_type = ParseConstFinalVarOrType( |
7552 FLAG_enable_type_checks ? ClassFinalizer::kCanonicalize : | 7567 TypeChecksEnabled(I) ? ClassFinalizer::kCanonicalize : |
7553 ClassFinalizer::kIgnore); | 7568 ClassFinalizer::kIgnore); |
7554 } | 7569 } |
7555 intptr_t loop_var_pos = TokenPos(); | 7570 intptr_t loop_var_pos = TokenPos(); |
7556 const String* loop_var_name = ExpectIdentifier("variable name expected"); | 7571 const String* loop_var_name = ExpectIdentifier("variable name expected"); |
7557 | 7572 |
7558 // Parse stream expression. | 7573 // Parse stream expression. |
7559 ExpectToken(Token::kIN); | 7574 ExpectToken(Token::kIN); |
7560 const intptr_t stream_pos = TokenPos(); | 7575 const intptr_t stream_pos = TokenPos(); |
7561 AstNode* stream_expr = | 7576 AstNode* stream_expr = |
7562 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 7577 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7685 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); | 7700 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); |
7686 if (LookaheadToken(1) == Token::kIN) { | 7701 if (LookaheadToken(1) == Token::kIN) { |
7687 loop_var_pos = TokenPos(); | 7702 loop_var_pos = TokenPos(); |
7688 loop_var_name = ExpectIdentifier("variable name expected"); | 7703 loop_var_name = ExpectIdentifier("variable name expected"); |
7689 } else { | 7704 } else { |
7690 // The case without a type is handled above, so require a type here. | 7705 // The case without a type is handled above, so require a type here. |
7691 // Delay creation of the local variable until we know its actual | 7706 // Delay creation of the local variable until we know its actual |
7692 // position, which is inside the loop body. | 7707 // position, which is inside the loop body. |
7693 new_loop_var = true; | 7708 new_loop_var = true; |
7694 loop_var_type = ParseConstFinalVarOrType( | 7709 loop_var_type = ParseConstFinalVarOrType( |
7695 FLAG_enable_type_checks ? ClassFinalizer::kCanonicalize : | 7710 TypeChecksEnabled(I) ? ClassFinalizer::kCanonicalize : |
7696 ClassFinalizer::kIgnore); | 7711 ClassFinalizer::kIgnore); |
7697 loop_var_name = ExpectIdentifier("variable name expected"); | 7712 loop_var_name = ExpectIdentifier("variable name expected"); |
7698 } | 7713 } |
7699 ExpectToken(Token::kIN); | 7714 ExpectToken(Token::kIN); |
7700 const intptr_t collection_pos = TokenPos(); | 7715 const intptr_t collection_pos = TokenPos(); |
7701 AstNode* collection_expr = | 7716 AstNode* collection_expr = |
7702 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 7717 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
7703 ExpectToken(Token::kRPAREN); | 7718 ExpectToken(Token::kRPAREN); |
7704 | 7719 |
7705 OpenBlock(); // Implicit block around while loop. | 7720 OpenBlock(); // Implicit block around while loop. |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7904 } | 7919 } |
7905 return condition; | 7920 return condition; |
7906 } | 7921 } |
7907 | 7922 |
7908 | 7923 |
7909 AstNode* Parser::ParseAssertStatement() { | 7924 AstNode* Parser::ParseAssertStatement() { |
7910 TRACE_PARSER("ParseAssertStatement"); | 7925 TRACE_PARSER("ParseAssertStatement"); |
7911 ConsumeToken(); // Consume assert keyword. | 7926 ConsumeToken(); // Consume assert keyword. |
7912 ExpectToken(Token::kLPAREN); | 7927 ExpectToken(Token::kLPAREN); |
7913 const intptr_t condition_pos = TokenPos(); | 7928 const intptr_t condition_pos = TokenPos(); |
7914 if (!FLAG_enable_asserts && !FLAG_enable_type_checks) { | 7929 if (!AssertsEnabled(I) && !TypeChecksEnabled(I)) { |
7915 SkipExpr(); | 7930 SkipExpr(); |
7916 ExpectToken(Token::kRPAREN); | 7931 ExpectToken(Token::kRPAREN); |
7917 return NULL; | 7932 return NULL; |
7918 } | 7933 } |
7919 AstNode* condition = ParseExpr(kAllowConst, kConsumeCascades); | 7934 AstNode* condition = ParseExpr(kAllowConst, kConsumeCascades); |
7920 const intptr_t condition_end = TokenPos(); | 7935 const intptr_t condition_end = TokenPos(); |
7921 ExpectToken(Token::kRPAREN); | 7936 ExpectToken(Token::kRPAREN); |
7922 condition = InsertClosureCallNodes(condition); | 7937 condition = InsertClosureCallNodes(condition); |
7923 condition = new(Z) UnaryOpNode(condition_pos, Token::kNOT, condition); | 7938 condition = new(Z) UnaryOpNode(condition_pos, Token::kNOT, condition); |
7924 AstNode* assert_throw = MakeAssertCall(condition_pos, condition_end); | 7939 AstNode* assert_throw = MakeAssertCall(condition_pos, condition_end); |
(...skipping 2889 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10814 ASSERT(!element_type.IsMalformed()); // Would be mapped to dynamic. | 10829 ASSERT(!element_type.IsMalformed()); // Would be mapped to dynamic. |
10815 ASSERT(!element_type.IsMalbounded()); // No declared bound in List. | 10830 ASSERT(!element_type.IsMalbounded()); // No declared bound in List. |
10816 if (element_type.IsDynamicType()) { | 10831 if (element_type.IsDynamicType()) { |
10817 list_type_arguments = TypeArguments::null(); | 10832 list_type_arguments = TypeArguments::null(); |
10818 } else if (is_const && !element_type.IsInstantiated()) { | 10833 } else if (is_const && !element_type.IsInstantiated()) { |
10819 ReportError(type_pos, | 10834 ReportError(type_pos, |
10820 "the type argument of a constant list literal cannot " | 10835 "the type argument of a constant list literal cannot " |
10821 "include a type variable"); | 10836 "include a type variable"); |
10822 } | 10837 } |
10823 } else { | 10838 } else { |
10824 if (FLAG_error_on_bad_type) { | 10839 if (ErrorOnBadTypeEnabled(I)) { |
10825 ReportError(type_pos, | 10840 ReportError(type_pos, |
10826 "a list literal takes one type argument specifying " | 10841 "a list literal takes one type argument specifying " |
10827 "the element type"); | 10842 "the element type"); |
10828 } | 10843 } |
10829 // Ignore type arguments. | 10844 // Ignore type arguments. |
10830 list_type_arguments = TypeArguments::null(); | 10845 list_type_arguments = TypeArguments::null(); |
10831 } | 10846 } |
10832 } | 10847 } |
10833 ASSERT(list_type_arguments.IsNull() || (list_type_arguments.Length() == 1)); | 10848 ASSERT(list_type_arguments.IsNull() || (list_type_arguments.Length() == 1)); |
10834 const Class& array_class = Class::Handle(Z, I->object_store()->array_class()); | 10849 const Class& array_class = Class::Handle(Z, I->object_store()->array_class()); |
10835 Type& type = Type::ZoneHandle(Z, | 10850 Type& type = Type::ZoneHandle(Z, |
10836 Type::New(array_class, list_type_arguments, type_pos)); | 10851 Type::New(array_class, list_type_arguments, type_pos)); |
10837 type ^= ClassFinalizer::FinalizeType( | 10852 type ^= ClassFinalizer::FinalizeType( |
10838 current_class(), type, ClassFinalizer::kCanonicalize); | 10853 current_class(), type, ClassFinalizer::kCanonicalize); |
10839 GrowableArray<AstNode*> element_list; | 10854 GrowableArray<AstNode*> element_list; |
10840 // Parse the list elements. Note: there may be an optional extra | 10855 // Parse the list elements. Note: there may be an optional extra |
10841 // comma after the last element. | 10856 // comma after the last element. |
10842 if (!is_empty_literal) { | 10857 if (!is_empty_literal) { |
10843 const bool saved_mode = SetAllowFunctionLiterals(true); | 10858 const bool saved_mode = SetAllowFunctionLiterals(true); |
10844 while (CurrentToken() != Token::kRBRACK) { | 10859 while (CurrentToken() != Token::kRBRACK) { |
10845 const intptr_t element_pos = TokenPos(); | 10860 const intptr_t element_pos = TokenPos(); |
10846 AstNode* element = ParseExpr(is_const, kConsumeCascades); | 10861 AstNode* element = ParseExpr(is_const, kConsumeCascades); |
10847 if (FLAG_enable_type_checks && | 10862 if (TypeChecksEnabled(I) && |
10848 !is_const && | 10863 !is_const && |
10849 !element_type.IsDynamicType()) { | 10864 !element_type.IsDynamicType()) { |
10850 element = new(Z) AssignableNode(element_pos, | 10865 element = new(Z) AssignableNode(element_pos, |
10851 element, | 10866 element, |
10852 element_type, | 10867 element_type, |
10853 Symbols::ListLiteralElement()); | 10868 Symbols::ListLiteralElement()); |
10854 } | 10869 } |
10855 element_list.Add(element); | 10870 element_list.Add(element); |
10856 if (CurrentToken() == Token::kCOMMA) { | 10871 if (CurrentToken() == Token::kCOMMA) { |
10857 ConsumeToken(); | 10872 ConsumeToken(); |
(...skipping 10 matching lines...) Expand all Loading... |
10868 Array& const_list = | 10883 Array& const_list = |
10869 Array::ZoneHandle(Z, Array::New(element_list.length(), Heap::kOld)); | 10884 Array::ZoneHandle(Z, Array::New(element_list.length(), Heap::kOld)); |
10870 const_list.SetTypeArguments( | 10885 const_list.SetTypeArguments( |
10871 TypeArguments::Handle(Z, list_type_arguments.Canonicalize())); | 10886 TypeArguments::Handle(Z, list_type_arguments.Canonicalize())); |
10872 Error& malformed_error = Error::Handle(Z); | 10887 Error& malformed_error = Error::Handle(Z); |
10873 for (int i = 0; i < element_list.length(); i++) { | 10888 for (int i = 0; i < element_list.length(); i++) { |
10874 AstNode* elem = element_list[i]; | 10889 AstNode* elem = element_list[i]; |
10875 // Arguments have been evaluated to a literal value already. | 10890 // Arguments have been evaluated to a literal value already. |
10876 ASSERT(elem->IsLiteralNode()); | 10891 ASSERT(elem->IsLiteralNode()); |
10877 ASSERT(!is_top_level_); // We cannot check unresolved types. | 10892 ASSERT(!is_top_level_); // We cannot check unresolved types. |
10878 if (FLAG_enable_type_checks && | 10893 if (TypeChecksEnabled(I) && |
10879 !element_type.IsDynamicType() && | 10894 !element_type.IsDynamicType() && |
10880 (!elem->AsLiteralNode()->literal().IsNull() && | 10895 (!elem->AsLiteralNode()->literal().IsNull() && |
10881 !elem->AsLiteralNode()->literal().IsInstanceOf( | 10896 !elem->AsLiteralNode()->literal().IsInstanceOf( |
10882 element_type, | 10897 element_type, |
10883 TypeArguments::Handle(Z), | 10898 TypeArguments::Handle(Z), |
10884 &malformed_error))) { | 10899 &malformed_error))) { |
10885 // If the failure is due to a malformed type error, display it instead. | 10900 // If the failure is due to a malformed type error, display it instead. |
10886 if (!malformed_error.IsNull()) { | 10901 if (!malformed_error.IsNull()) { |
10887 ReportError(malformed_error); | 10902 ReportError(malformed_error); |
10888 } else { | 10903 } else { |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11011 // No declared bounds in Map. | 11026 // No declared bounds in Map. |
11012 ASSERT(!key_type.IsMalbounded() && !value_type.IsMalbounded()); | 11027 ASSERT(!key_type.IsMalbounded() && !value_type.IsMalbounded()); |
11013 if (key_type.IsDynamicType() && value_type.IsDynamicType()) { | 11028 if (key_type.IsDynamicType() && value_type.IsDynamicType()) { |
11014 map_type_arguments = TypeArguments::null(); | 11029 map_type_arguments = TypeArguments::null(); |
11015 } else if (is_const && !type_arguments.IsInstantiated()) { | 11030 } else if (is_const && !type_arguments.IsInstantiated()) { |
11016 ReportError(type_pos, | 11031 ReportError(type_pos, |
11017 "the type arguments of a constant map literal cannot " | 11032 "the type arguments of a constant map literal cannot " |
11018 "include a type variable"); | 11033 "include a type variable"); |
11019 } | 11034 } |
11020 } else { | 11035 } else { |
11021 if (FLAG_error_on_bad_type) { | 11036 if (ErrorOnBadTypeEnabled(I)) { |
11022 ReportError(type_pos, | 11037 ReportError(type_pos, |
11023 "a map literal takes two type arguments specifying " | 11038 "a map literal takes two type arguments specifying " |
11024 "the key type and the value type"); | 11039 "the key type and the value type"); |
11025 } | 11040 } |
11026 // Ignore type arguments. | 11041 // Ignore type arguments. |
11027 map_type_arguments = TypeArguments::null(); | 11042 map_type_arguments = TypeArguments::null(); |
11028 } | 11043 } |
11029 } | 11044 } |
11030 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); | 11045 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); |
11031 map_type_arguments ^= map_type_arguments.Canonicalize(); | 11046 map_type_arguments ^= map_type_arguments.Canonicalize(); |
11032 | 11047 |
11033 GrowableArray<AstNode*> kv_pairs_list; | 11048 GrowableArray<AstNode*> kv_pairs_list; |
11034 // Parse the map entries. Note: there may be an optional extra | 11049 // Parse the map entries. Note: there may be an optional extra |
11035 // comma after the last entry. | 11050 // comma after the last entry. |
11036 while (CurrentToken() != Token::kRBRACE) { | 11051 while (CurrentToken() != Token::kRBRACE) { |
11037 const bool saved_mode = SetAllowFunctionLiterals(true); | 11052 const bool saved_mode = SetAllowFunctionLiterals(true); |
11038 const intptr_t key_pos = TokenPos(); | 11053 const intptr_t key_pos = TokenPos(); |
11039 AstNode* key = ParseExpr(is_const, kConsumeCascades); | 11054 AstNode* key = ParseExpr(is_const, kConsumeCascades); |
11040 if (FLAG_enable_type_checks && | 11055 if (TypeChecksEnabled(I) && |
11041 !is_const && | 11056 !is_const && |
11042 !key_type.IsDynamicType()) { | 11057 !key_type.IsDynamicType()) { |
11043 key = new(Z) AssignableNode( | 11058 key = new(Z) AssignableNode( |
11044 key_pos, key, key_type, Symbols::ListLiteralElement()); | 11059 key_pos, key, key_type, Symbols::ListLiteralElement()); |
11045 } | 11060 } |
11046 if (is_const) { | 11061 if (is_const) { |
11047 ASSERT(key->IsLiteralNode()); | 11062 ASSERT(key->IsLiteralNode()); |
11048 const Instance& key_value = key->AsLiteralNode()->literal(); | 11063 const Instance& key_value = key->AsLiteralNode()->literal(); |
11049 if (key_value.IsDouble()) { | 11064 if (key_value.IsDouble()) { |
11050 ReportError(key_pos, "key value must not be of type double"); | 11065 ReportError(key_pos, "key value must not be of type double"); |
11051 } | 11066 } |
11052 if (!key_value.IsInteger() && | 11067 if (!key_value.IsInteger() && |
11053 !key_value.IsString() && | 11068 !key_value.IsString() && |
11054 (key_value.clazz() != I->object_store()->symbol_class()) && | 11069 (key_value.clazz() != I->object_store()->symbol_class()) && |
11055 ImplementsEqualOperator(key_value)) { | 11070 ImplementsEqualOperator(key_value)) { |
11056 ReportError(key_pos, "key value must not implement operator =="); | 11071 ReportError(key_pos, "key value must not implement operator =="); |
11057 } | 11072 } |
11058 } | 11073 } |
11059 ExpectToken(Token::kCOLON); | 11074 ExpectToken(Token::kCOLON); |
11060 const intptr_t value_pos = TokenPos(); | 11075 const intptr_t value_pos = TokenPos(); |
11061 AstNode* value = ParseExpr(is_const, kConsumeCascades); | 11076 AstNode* value = ParseExpr(is_const, kConsumeCascades); |
11062 SetAllowFunctionLiterals(saved_mode); | 11077 SetAllowFunctionLiterals(saved_mode); |
11063 if (FLAG_enable_type_checks && | 11078 if (TypeChecksEnabled(I) && |
11064 !is_const && | 11079 !is_const && |
11065 !value_type.IsDynamicType()) { | 11080 !value_type.IsDynamicType()) { |
11066 value = new(Z) AssignableNode( | 11081 value = new(Z) AssignableNode( |
11067 value_pos, value, value_type, Symbols::ListLiteralElement()); | 11082 value_pos, value, value_type, Symbols::ListLiteralElement()); |
11068 } | 11083 } |
11069 AddKeyValuePair(&kv_pairs_list, is_const, key, value); | 11084 AddKeyValuePair(&kv_pairs_list, is_const, key, value); |
11070 | 11085 |
11071 if (CurrentToken() == Token::kCOMMA) { | 11086 if (CurrentToken() == Token::kCOMMA) { |
11072 ConsumeToken(); | 11087 ConsumeToken(); |
11073 } else if (CurrentToken() != Token::kRBRACE) { | 11088 } else if (CurrentToken() != Token::kRBRACE) { |
(...skipping 11 matching lines...) Expand all Loading... |
11085 // First, create the canonicalized key-value pair array. | 11100 // First, create the canonicalized key-value pair array. |
11086 Array& key_value_array = | 11101 Array& key_value_array = |
11087 Array::ZoneHandle(Z, Array::New(kv_pairs_list.length(), Heap::kOld)); | 11102 Array::ZoneHandle(Z, Array::New(kv_pairs_list.length(), Heap::kOld)); |
11088 AbstractType& arg_type = Type::Handle(Z); | 11103 AbstractType& arg_type = Type::Handle(Z); |
11089 Error& malformed_error = Error::Handle(Z); | 11104 Error& malformed_error = Error::Handle(Z); |
11090 for (int i = 0; i < kv_pairs_list.length(); i++) { | 11105 for (int i = 0; i < kv_pairs_list.length(); i++) { |
11091 AstNode* arg = kv_pairs_list[i]; | 11106 AstNode* arg = kv_pairs_list[i]; |
11092 // Arguments have been evaluated to a literal value already. | 11107 // Arguments have been evaluated to a literal value already. |
11093 ASSERT(arg->IsLiteralNode()); | 11108 ASSERT(arg->IsLiteralNode()); |
11094 ASSERT(!is_top_level_); // We cannot check unresolved types. | 11109 ASSERT(!is_top_level_); // We cannot check unresolved types. |
11095 if (FLAG_enable_type_checks) { | 11110 if (TypeChecksEnabled(I)) { |
11096 if ((i % 2) == 0) { | 11111 if ((i % 2) == 0) { |
11097 // Check key type. | 11112 // Check key type. |
11098 arg_type = key_type.raw(); | 11113 arg_type = key_type.raw(); |
11099 } else { | 11114 } else { |
11100 // Check value type. | 11115 // Check value type. |
11101 arg_type = value_type.raw(); | 11116 arg_type = value_type.raw(); |
11102 } | 11117 } |
11103 if (!arg_type.IsDynamicType() && | 11118 if (!arg_type.IsDynamicType() && |
11104 (!arg->AsLiteralNode()->literal().IsNull() && | 11119 (!arg->AsLiteralNode()->literal().IsNull() && |
11105 !arg->AsLiteralNode()->literal().IsInstanceOf( | 11120 !arg->AsLiteralNode()->literal().IsInstanceOf( |
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11410 "redirecting factory type '%s' cannot be instantiated", | 11425 "redirecting factory type '%s' cannot be instantiated", |
11411 String::Handle(Z, redirect_type.UserVisibleName()).ToCString()); | 11426 String::Handle(Z, redirect_type.UserVisibleName()).ToCString()); |
11412 } | 11427 } |
11413 } | 11428 } |
11414 if (redirect_type.IsMalformedOrMalbounded()) { | 11429 if (redirect_type.IsMalformedOrMalbounded()) { |
11415 if (is_const) { | 11430 if (is_const) { |
11416 ReportError(Error::Handle(Z, redirect_type.error())); | 11431 ReportError(Error::Handle(Z, redirect_type.error())); |
11417 } | 11432 } |
11418 return ThrowTypeError(redirect_type.token_pos(), redirect_type); | 11433 return ThrowTypeError(redirect_type.token_pos(), redirect_type); |
11419 } | 11434 } |
11420 if (FLAG_enable_type_checks && !redirect_type.IsSubtypeOf(type, NULL)) { | 11435 if (TypeChecksEnabled(I) && !redirect_type.IsSubtypeOf(type, NULL)) { |
11421 // Additional type checking of the result is necessary. | 11436 // Additional type checking of the result is necessary. |
11422 type_bound = type.raw(); | 11437 type_bound = type.raw(); |
11423 } | 11438 } |
11424 type = redirect_type.raw(); | 11439 type = redirect_type.raw(); |
11425 type_class = type.type_class(); | 11440 type_class = type.type_class(); |
11426 type_class_name = type_class.Name(); | 11441 type_class_name = type_class.Name(); |
11427 type_arguments = type.arguments(); | 11442 type_arguments = type.arguments(); |
11428 constructor = constructor.RedirectionTarget(); | 11443 constructor = constructor.RedirectionTarget(); |
11429 constructor_name = constructor.name(); | 11444 constructor_name = constructor.name(); |
11430 ASSERT(!constructor.IsNull()); | 11445 ASSERT(!constructor.IsNull()); |
(...skipping 801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12232 void Parser::SkipQualIdent() { | 12247 void Parser::SkipQualIdent() { |
12233 ASSERT(IsIdentifier()); | 12248 ASSERT(IsIdentifier()); |
12234 ConsumeToken(); | 12249 ConsumeToken(); |
12235 if (CurrentToken() == Token::kPERIOD) { | 12250 if (CurrentToken() == Token::kPERIOD) { |
12236 ConsumeToken(); // Consume the kPERIOD token. | 12251 ConsumeToken(); // Consume the kPERIOD token. |
12237 ExpectIdentifier("identifier expected after '.'"); | 12252 ExpectIdentifier("identifier expected after '.'"); |
12238 } | 12253 } |
12239 } | 12254 } |
12240 | 12255 |
12241 } // namespace dart | 12256 } // namespace dart |
OLD | NEW |