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 "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
9 #include "vm/class_finalizer.h" | 9 #include "vm/class_finalizer.h" |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 11 matching lines...) Expand all Loading... |
22 #include "vm/stack_frame.h" | 22 #include "vm/stack_frame.h" |
23 #include "vm/symbols.h" | 23 #include "vm/symbols.h" |
24 | 24 |
25 namespace dart { | 25 namespace dart { |
26 | 26 |
27 DEFINE_FLAG(bool, enable_asserts, false, "Enable assert statements."); | 27 DEFINE_FLAG(bool, enable_asserts, false, "Enable assert statements."); |
28 DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks."); | 28 DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks."); |
29 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); | 29 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); |
30 DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors."); | 30 DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors."); |
31 DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings."); | 31 DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings."); |
| 32 DECLARE_FLAG(bool, error_on_malformed_type); |
32 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); | 33 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); |
33 | 34 |
34 static void CheckedModeHandler(bool value) { | 35 static void CheckedModeHandler(bool value) { |
35 FLAG_enable_asserts = value; | 36 FLAG_enable_asserts = value; |
36 FLAG_enable_type_checks = value; | 37 FLAG_enable_type_checks = value; |
37 } | 38 } |
38 | 39 |
39 // --enable-checked-mode and --checked both enable checked mode which is | 40 // --enable-checked-mode and --checked both enable checked mode which is |
40 // equivalent to setting --enable-asserts and --enable-type-checks. | 41 // equivalent to setting --enable-asserts and --enable-type-checks. |
41 DEFINE_FLAG_HANDLER(CheckedModeHandler, | 42 DEFINE_FLAG_HANDLER(CheckedModeHandler, |
(...skipping 2885 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2927 ConsumeToken(); | 2928 ConsumeToken(); |
2928 const intptr_t type_pos = TokenPos(); | 2929 const intptr_t type_pos = TokenPos(); |
2929 const AbstractType& type = AbstractType::Handle( | 2930 const AbstractType& type = AbstractType::Handle( |
2930 ParseType(ClassFinalizer::kResolveTypeParameters)); | 2931 ParseType(ClassFinalizer::kResolveTypeParameters)); |
2931 if (!type.IsMalformed() && type.IsTypeParameter()) { | 2932 if (!type.IsMalformed() && type.IsTypeParameter()) { |
2932 // Replace the type with a malformed type and compile a throw when called. | 2933 // Replace the type with a malformed type and compile a throw when called. |
2933 redirection_type = ClassFinalizer::NewFinalizedMalformedType( | 2934 redirection_type = ClassFinalizer::NewFinalizedMalformedType( |
2934 Error::Handle(), // No previous error. | 2935 Error::Handle(), // No previous error. |
2935 current_class(), | 2936 current_class(), |
2936 type_pos, | 2937 type_pos, |
2937 ClassFinalizer::kResolveTypeParameters, // No compile-time error. | |
2938 "factory '%s' may not redirect to type parameter '%s'", | 2938 "factory '%s' may not redirect to type parameter '%s'", |
2939 method->name->ToCString(), | 2939 method->name->ToCString(), |
2940 String::Handle(type.UserVisibleName()).ToCString()); | 2940 String::Handle(type.UserVisibleName()).ToCString()); |
2941 } else { | 2941 } else { |
2942 redirection_type ^= type.raw(); | 2942 redirection_type ^= type.raw(); |
2943 } | 2943 } |
2944 if (CurrentToken() == Token::kPERIOD) { | 2944 if (CurrentToken() == Token::kPERIOD) { |
2945 // Named constructor or factory. | 2945 // Named constructor or factory. |
2946 ConsumeToken(); | 2946 ConsumeToken(); |
2947 redirection_identifier = ExpectIdentifier("identifier expected")->raw(); | 2947 redirection_identifier = ExpectIdentifier("identifier expected")->raw(); |
(...skipping 1164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4112 ResolveTypeFromClass(cls, | 4112 ResolveTypeFromClass(cls, |
4113 ClassFinalizer::kResolveTypeParameters, | 4113 ClassFinalizer::kResolveTypeParameters, |
4114 &type_parameter_bound); | 4114 &type_parameter_bound); |
4115 type_parameter.set_bound(type_parameter_bound); | 4115 type_parameter.set_bound(type_parameter_bound); |
4116 } | 4116 } |
4117 } | 4117 } |
4118 } | 4118 } |
4119 | 4119 |
4120 | 4120 |
4121 RawAbstractTypeArguments* Parser::ParseTypeArguments( | 4121 RawAbstractTypeArguments* Parser::ParseTypeArguments( |
4122 Error* malformed_error, | |
4123 ClassFinalizer::FinalizationKind finalization) { | 4122 ClassFinalizer::FinalizationKind finalization) { |
4124 TRACE_PARSER("ParseTypeArguments"); | 4123 TRACE_PARSER("ParseTypeArguments"); |
4125 if (CurrentToken() == Token::kLT) { | 4124 if (CurrentToken() == Token::kLT) { |
4126 const GrowableObjectArray& types = | 4125 const GrowableObjectArray& types = |
4127 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 4126 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
4128 AbstractType& type = AbstractType::Handle(); | 4127 AbstractType& type = AbstractType::Handle(); |
4129 do { | 4128 do { |
4130 ConsumeToken(); | 4129 ConsumeToken(); |
4131 type = ParseType(finalization); | 4130 type = ParseType(finalization); |
4132 // Only keep the error for the first malformed type argument. | 4131 // Map a malformed type argument to dynamic. |
4133 if (malformed_error->IsNull() && type.IsMalformed()) { | |
4134 *malformed_error = type.malformed_error(); | |
4135 } | |
4136 // Map a malformed type argument to dynamic, so that malformed types with | |
4137 // a resolved type class are handled properly in production mode. | |
4138 if (type.IsMalformed()) { | 4132 if (type.IsMalformed()) { |
4139 ASSERT(finalization < ClassFinalizer::kCanonicalizeWellFormed); | |
4140 type = Type::DynamicType(); | 4133 type = Type::DynamicType(); |
4141 } | 4134 } |
4142 types.Add(type); | 4135 types.Add(type); |
4143 } while (CurrentToken() == Token::kCOMMA); | 4136 } while (CurrentToken() == Token::kCOMMA); |
4144 Token::Kind token = CurrentToken(); | 4137 Token::Kind token = CurrentToken(); |
4145 if ((token == Token::kGT) || (token == Token::kSHR)) { | 4138 if ((token == Token::kGT) || (token == Token::kSHR)) { |
4146 ConsumeRightAngleBracket(); | 4139 ConsumeRightAngleBracket(); |
4147 } else { | 4140 } else { |
4148 ErrorMsg("right angle bracket expected"); | 4141 ErrorMsg("right angle bracket expected"); |
4149 } | 4142 } |
(...skipping 2273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6423 current_block_->scope->AddLabel(end_catch_label); | 6416 current_block_->scope->AddLabel(end_catch_label); |
6424 const GrowableObjectArray& handler_types = | 6417 const GrowableObjectArray& handler_types = |
6425 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 6418 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
6426 while ((CurrentToken() == Token::kCATCH) || IsLiteral("on")) { | 6419 while ((CurrentToken() == Token::kCATCH) || IsLiteral("on")) { |
6427 const intptr_t catch_pos = TokenPos(); | 6420 const intptr_t catch_pos = TokenPos(); |
6428 CatchParamDesc exception_param; | 6421 CatchParamDesc exception_param; |
6429 CatchParamDesc stack_trace_param; | 6422 CatchParamDesc stack_trace_param; |
6430 catch_seen = true; | 6423 catch_seen = true; |
6431 if (IsLiteral("on")) { | 6424 if (IsLiteral("on")) { |
6432 ConsumeToken(); | 6425 ConsumeToken(); |
6433 // TODO(regis): The spec may change in the way a malformed 'on' type is | |
6434 // treated. For now, we require the type to be wellformed. | |
6435 exception_param.type = &AbstractType::ZoneHandle( | 6426 exception_param.type = &AbstractType::ZoneHandle( |
6436 ParseType(ClassFinalizer::kCanonicalizeWellFormed)); | 6427 ParseType(ClassFinalizer::kCanonicalize)); |
6437 } else { | 6428 } else { |
6438 exception_param.type = | 6429 exception_param.type = |
6439 &AbstractType::ZoneHandle(Type::DynamicType()); | 6430 &AbstractType::ZoneHandle(Type::DynamicType()); |
6440 } | 6431 } |
6441 if (CurrentToken() == Token::kCATCH) { | 6432 if (CurrentToken() == Token::kCATCH) { |
6442 ConsumeToken(); // Consume the 'catch'. | 6433 ConsumeToken(); // Consume the 'catch'. |
6443 ExpectToken(Token::kLPAREN); | 6434 ExpectToken(Token::kLPAREN); |
6444 exception_param.token_pos = TokenPos(); | 6435 exception_param.token_pos = TokenPos(); |
6445 exception_param.var = ExpectIdentifier("identifier expected"); | 6436 exception_param.var = ExpectIdentifier("identifier expected"); |
6446 if (CurrentToken() == Token::kCOMMA) { | 6437 if (CurrentToken() == Token::kCOMMA) { |
(...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7134 if ((op_kind != Token::kIS) && (op_kind != Token::kAS)) { | 7125 if ((op_kind != Token::kIS) && (op_kind != Token::kAS)) { |
7135 right_operand = ParseBinaryExpr(current_preced + 1); | 7126 right_operand = ParseBinaryExpr(current_preced + 1); |
7136 } else { | 7127 } else { |
7137 // For 'is' and 'as' we expect the right operand to be a type. | 7128 // For 'is' and 'as' we expect the right operand to be a type. |
7138 if ((op_kind == Token::kIS) && (CurrentToken() == Token::kNOT)) { | 7129 if ((op_kind == Token::kIS) && (CurrentToken() == Token::kNOT)) { |
7139 ConsumeToken(); | 7130 ConsumeToken(); |
7140 op_kind = Token::kISNOT; | 7131 op_kind = Token::kISNOT; |
7141 } | 7132 } |
7142 const intptr_t type_pos = TokenPos(); | 7133 const intptr_t type_pos = TokenPos(); |
7143 const AbstractType& type = AbstractType::ZoneHandle( | 7134 const AbstractType& type = AbstractType::ZoneHandle( |
7144 ParseType(ClassFinalizer::kCanonicalizeExpression)); | 7135 ParseType(ClassFinalizer::kCanonicalize)); |
7145 if (!type.IsInstantiated() && | 7136 if (!type.IsInstantiated() && |
7146 (current_block_->scope->function_level() > 0)) { | 7137 (current_block_->scope->function_level() > 0)) { |
7147 // Make sure that the instantiator is captured. | 7138 // Make sure that the instantiator is captured. |
7148 CaptureInstantiator(); | 7139 CaptureInstantiator(); |
7149 } | 7140 } |
7150 right_operand = new TypeNode(type_pos, type); | 7141 right_operand = new TypeNode(type_pos, type); |
| 7142 // If the type is malformed, it is actually malbounded in checked mode. |
| 7143 ASSERT(!type.IsMalformed() || FLAG_enable_type_checks); |
7151 if (((op_kind == Token::kIS) || (op_kind == Token::kISNOT)) && | 7144 if (((op_kind == Token::kIS) || (op_kind == Token::kISNOT)) && |
7152 type.IsMalformed()) { | 7145 type.IsMalformed()) { |
7153 // Note that a type error is thrown even if the tested value is null | 7146 // Note that a type error is thrown even if the tested value is null |
7154 // in a type test. However, no cast exception is thrown if the value | 7147 // in a type test. However, no cast exception is thrown if the value |
7155 // is null in a type cast. | 7148 // is null in a type cast. |
7156 return ThrowTypeError(type_pos, type); | 7149 return ThrowTypeError(type_pos, type); |
7157 } | 7150 } |
7158 } | 7151 } |
7159 if (Token::IsRelationalOperator(op_kind) | 7152 if (Token::IsRelationalOperator(op_kind) |
7160 || Token::IsTypeTestOperator(op_kind) | 7153 || Token::IsTypeTestOperator(op_kind) |
(...skipping 991 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8152 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { | 8145 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { |
8153 if (!scope_class.IsNull()) { | 8146 if (!scope_class.IsNull()) { |
8154 // First check if the type is a type parameter of the given scope class. | 8147 // First check if the type is a type parameter of the given scope class. |
8155 const TypeParameter& type_parameter = TypeParameter::Handle( | 8148 const TypeParameter& type_parameter = TypeParameter::Handle( |
8156 scope_class.LookupTypeParameter(unresolved_class_name)); | 8149 scope_class.LookupTypeParameter(unresolved_class_name)); |
8157 if (!type_parameter.IsNull()) { | 8150 if (!type_parameter.IsNull()) { |
8158 // A type parameter is considered to be a malformed type when | 8151 // A type parameter is considered to be a malformed type when |
8159 // referenced by a static member. | 8152 // referenced by a static member. |
8160 if (ParsingStaticMember()) { | 8153 if (ParsingStaticMember()) { |
8161 ASSERT(scope_class.raw() == current_class().raw()); | 8154 ASSERT(scope_class.raw() == current_class().raw()); |
8162 *type = ClassFinalizer::NewFinalizedMalformedType( | 8155 if ((finalization == ClassFinalizer::kCanonicalizeWellFormed) || |
8163 Error::Handle(), // No previous error. | 8156 FLAG_error_on_malformed_type) { |
8164 scope_class, | 8157 *type = ClassFinalizer::NewFinalizedMalformedType( |
8165 type->token_pos(), | 8158 Error::Handle(), // No previous error. |
8166 finalization, | 8159 scope_class, |
8167 "type parameter '%s' cannot be referenced " | 8160 type->token_pos(), |
8168 "from static member", | 8161 "type parameter '%s' cannot be referenced " |
8169 String::Handle(type_parameter.name()).ToCString()); | 8162 "from static member", |
| 8163 String::Handle(type_parameter.name()).ToCString()); |
| 8164 } else { |
| 8165 // Map the malformed type to dynamic and ignore type arguments. |
| 8166 *type = Type::DynamicType(); |
| 8167 } |
8170 return; | 8168 return; |
8171 } | 8169 } |
8172 // A type parameter cannot be parameterized, so make the type | 8170 // A type parameter cannot be parameterized, so make the type |
8173 // malformed if type arguments have previously been parsed. | 8171 // malformed if type arguments have previously been parsed. |
8174 if (!AbstractTypeArguments::Handle(type->arguments()).IsNull()) { | 8172 if (!AbstractTypeArguments::Handle(type->arguments()).IsNull()) { |
8175 *type = ClassFinalizer::NewFinalizedMalformedType( | 8173 if ((finalization == ClassFinalizer::kCanonicalizeWellFormed) || |
8176 Error::Handle(), // No previous error. | 8174 FLAG_error_on_malformed_type) { |
8177 scope_class, | 8175 *type = ClassFinalizer::NewFinalizedMalformedType( |
8178 type_parameter.token_pos(), | 8176 Error::Handle(), // No previous error. |
8179 finalization, | 8177 scope_class, |
8180 "type parameter '%s' cannot be parameterized", | 8178 type_parameter.token_pos(), |
8181 String::Handle(type_parameter.name()).ToCString()); | 8179 "type parameter '%s' cannot be parameterized", |
| 8180 String::Handle(type_parameter.name()).ToCString()); |
| 8181 } else { |
| 8182 // Map the malformed type to dynamic and ignore type arguments. |
| 8183 *type = Type::DynamicType(); |
| 8184 } |
8182 return; | 8185 return; |
8183 } | 8186 } |
8184 *type = type_parameter.raw(); | 8187 *type = type_parameter.raw(); |
8185 return; | 8188 return; |
8186 } | 8189 } |
8187 } | 8190 } |
8188 // The referenced class may not have been parsed yet. It would be wrong | 8191 // The referenced class may not have been parsed yet. It would be wrong |
8189 // to resolve it too early to an imported class of the same name. | 8192 // to resolve it too early to an imported class of the same name. |
8190 if (finalization > ClassFinalizer::kResolveTypeParameters) { | 8193 if (finalization > ClassFinalizer::kResolveTypeParameters) { |
8191 // Resolve classname in the scope of the current library. | 8194 // Resolve classname in the scope of the current library. |
8192 Error& error = Error::Handle(); | 8195 Error& error = Error::Handle(); |
8193 // If we finalize a type expression, as opposed to a type annotation, | |
8194 // we tell the resolver (by passing NULL) to immediately report an | |
8195 // ambiguous type as a compile time error. | |
8196 resolved_type_class = ResolveClassInCurrentLibraryScope( | 8196 resolved_type_class = ResolveClassInCurrentLibraryScope( |
8197 unresolved_class.token_pos(), | 8197 unresolved_class.token_pos(), |
8198 unresolved_class_name, | 8198 unresolved_class_name, |
8199 finalization >= ClassFinalizer::kCanonicalizeExpression ? | 8199 &error); |
8200 NULL : &error); | |
8201 if (!error.IsNull()) { | 8200 if (!error.IsNull()) { |
8202 *type = ClassFinalizer::NewFinalizedMalformedType( | 8201 if ((finalization == ClassFinalizer::kCanonicalizeWellFormed) || |
8203 error, | 8202 FLAG_error_on_malformed_type) { |
8204 scope_class, | 8203 *type = ClassFinalizer::NewFinalizedMalformedType( |
8205 unresolved_class.token_pos(), | 8204 error, |
8206 finalization, | 8205 scope_class, |
8207 "cannot resolve class '%s'", | 8206 unresolved_class.token_pos(), |
8208 unresolved_class_name.ToCString()); | 8207 "cannot resolve class '%s'", |
| 8208 unresolved_class_name.ToCString()); |
| 8209 } else { |
| 8210 // Map the malformed type to dynamic and ignore type arguments. |
| 8211 *type = Type::DynamicType(); |
| 8212 } |
8209 return; | 8213 return; |
8210 } | 8214 } |
8211 } | 8215 } |
8212 } else { | 8216 } else { |
8213 LibraryPrefix& lib_prefix = | 8217 LibraryPrefix& lib_prefix = |
8214 LibraryPrefix::Handle(unresolved_class.library_prefix()); | 8218 LibraryPrefix::Handle(unresolved_class.library_prefix()); |
8215 // Resolve class name in the scope of the library prefix. | 8219 // Resolve class name in the scope of the library prefix. |
8216 Error& error = Error::Handle(); | 8220 Error& error = Error::Handle(); |
8217 // If we finalize a type expression, as opposed to a type annotation, we | |
8218 // tell the resolver (by passing NULL) to immediately report an ambiguous | |
8219 // type as a compile time error. | |
8220 resolved_type_class = ResolveClassInPrefixScope( | 8221 resolved_type_class = ResolveClassInPrefixScope( |
8221 unresolved_class.token_pos(), | 8222 unresolved_class.token_pos(), |
8222 lib_prefix, | 8223 lib_prefix, |
8223 unresolved_class_name, | 8224 unresolved_class_name, |
8224 finalization >= ClassFinalizer::kCanonicalizeExpression ? | 8225 &error); |
8225 NULL : &error); | |
8226 if (!error.IsNull()) { | 8226 if (!error.IsNull()) { |
8227 *type = ClassFinalizer::NewFinalizedMalformedType( | 8227 if ((finalization == ClassFinalizer::kCanonicalizeWellFormed) || |
8228 error, | 8228 FLAG_error_on_malformed_type) { |
8229 scope_class, | 8229 *type = ClassFinalizer::NewFinalizedMalformedType( |
8230 unresolved_class.token_pos(), | 8230 error, |
8231 finalization, | 8231 scope_class, |
8232 "cannot resolve class '%s'", | 8232 unresolved_class.token_pos(), |
8233 unresolved_class_name.ToCString()); | 8233 "cannot resolve class '%s'", |
| 8234 unresolved_class_name.ToCString()); |
| 8235 } else { |
| 8236 // Map the malformed type to dynamic and ignore type arguments. |
| 8237 *type = Type::DynamicType(); |
| 8238 } |
8234 return; | 8239 return; |
8235 } | 8240 } |
8236 } | 8241 } |
8237 // At this point, we can only have a parameterized_type. | 8242 // At this point, we can only have a parameterized_type. |
8238 Type& parameterized_type = Type::Handle(); | 8243 const Type& parameterized_type = Type::Cast(*type); |
8239 parameterized_type ^= type->raw(); | |
8240 if (!resolved_type_class.IsNull()) { | 8244 if (!resolved_type_class.IsNull()) { |
8241 // Replace unresolved class with resolved type class. | 8245 // Replace unresolved class with resolved type class. |
8242 parameterized_type.set_type_class(resolved_type_class); | 8246 parameterized_type.set_type_class(resolved_type_class); |
8243 } else if (finalization >= ClassFinalizer::kCanonicalize) { | 8247 } else if (finalization >= ClassFinalizer::kCanonicalize) { |
8244 // The type is malformed. | 8248 if ((finalization == ClassFinalizer::kCanonicalizeWellFormed) || |
8245 ClassFinalizer::FinalizeMalformedType( | 8249 FLAG_error_on_malformed_type) { |
8246 Error::Handle(), // No previous error. | 8250 ClassFinalizer::FinalizeMalformedType( |
8247 current_class(), parameterized_type, finalization, | 8251 Error::Handle(), // No previous error. |
8248 "type '%s' is not loaded", | 8252 scope_class, |
8249 String::Handle(parameterized_type.UserVisibleName()).ToCString()); | 8253 parameterized_type, |
| 8254 "type '%s' is not loaded", |
| 8255 String::Handle(parameterized_type.UserVisibleName()).ToCString()); |
| 8256 } else { |
| 8257 // Map the malformed type to dynamic and ignore type arguments. |
| 8258 *type = Type::DynamicType(); |
| 8259 } |
| 8260 return; |
8250 } | 8261 } |
8251 } | 8262 } |
8252 // Resolve type arguments, if any. | 8263 // Resolve type arguments, if any. |
8253 const AbstractTypeArguments& arguments = | 8264 const AbstractTypeArguments& arguments = |
8254 AbstractTypeArguments::Handle(type->arguments()); | 8265 AbstractTypeArguments::Handle(type->arguments()); |
8255 if (!arguments.IsNull()) { | 8266 if (!arguments.IsNull()) { |
8256 const intptr_t num_arguments = arguments.Length(); | 8267 const intptr_t num_arguments = arguments.Length(); |
8257 for (intptr_t i = 0; i < num_arguments; i++) { | 8268 for (intptr_t i = 0; i < num_arguments; i++) { |
8258 AbstractType& type_argument = AbstractType::Handle(arguments.TypeAt(i)); | 8269 AbstractType& type_argument = AbstractType::Handle(arguments.TypeAt(i)); |
8259 ResolveTypeFromClass(scope_class, finalization, &type_argument); | 8270 ResolveTypeFromClass(scope_class, finalization, &type_argument); |
(...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8947 } | 8958 } |
8948 QualIdent type_name; | 8959 QualIdent type_name; |
8949 if (finalization == ClassFinalizer::kIgnore) { | 8960 if (finalization == ClassFinalizer::kIgnore) { |
8950 SkipQualIdent(); | 8961 SkipQualIdent(); |
8951 } else { | 8962 } else { |
8952 ParseQualIdent(&type_name); | 8963 ParseQualIdent(&type_name); |
8953 // An identifier cannot be resolved in a local scope when top level parsing. | 8964 // An identifier cannot be resolved in a local scope when top level parsing. |
8954 if (!is_top_level_ && | 8965 if (!is_top_level_ && |
8955 (type_name.lib_prefix == NULL) && | 8966 (type_name.lib_prefix == NULL) && |
8956 ResolveIdentInLocalScope(type_name.ident_pos, *type_name.ident, NULL)) { | 8967 ResolveIdentInLocalScope(type_name.ident_pos, *type_name.ident, NULL)) { |
8957 ErrorMsg(type_name.ident_pos, "using '%s' in this context is invalid", | 8968 // The type is malformed. Skip over its type arguments. |
8958 type_name.ident->ToCString()); | 8969 ParseTypeArguments(ClassFinalizer::kIgnore); |
| 8970 if (finalization == ClassFinalizer::kCanonicalizeWellFormed) { |
| 8971 return ClassFinalizer::NewFinalizedMalformedType( |
| 8972 Error::Handle(), // No previous error. |
| 8973 current_class(), |
| 8974 type_name.ident_pos, |
| 8975 "using '%s' in this context is invalid", |
| 8976 type_name.ident->ToCString()); |
| 8977 } |
| 8978 return Type::DynamicType(); |
8959 } | 8979 } |
8960 } | 8980 } |
8961 Object& type_class = Object::Handle(isolate()); | 8981 Object& type_class = Object::Handle(isolate()); |
8962 // Leave type_class as null if type finalization mode is kIgnore. | 8982 // Leave type_class as null if type finalization mode is kIgnore. |
8963 if (finalization != ClassFinalizer::kIgnore) { | 8983 if (finalization != ClassFinalizer::kIgnore) { |
8964 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(isolate()); | 8984 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(isolate()); |
8965 if (type_name.lib_prefix != NULL) { | 8985 if (type_name.lib_prefix != NULL) { |
8966 lib_prefix = type_name.lib_prefix->raw(); | 8986 lib_prefix = type_name.lib_prefix->raw(); |
8967 } | 8987 } |
8968 type_class = UnresolvedClass::New(lib_prefix, | 8988 type_class = UnresolvedClass::New(lib_prefix, |
8969 *type_name.ident, | 8989 *type_name.ident, |
8970 type_name.ident_pos); | 8990 type_name.ident_pos); |
8971 } | 8991 } |
8972 Error& malformed_error = Error::Handle(isolate()); | 8992 AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle( |
8973 AbstractTypeArguments& type_arguments = | 8993 isolate(), ParseTypeArguments(finalization)); |
8974 AbstractTypeArguments::Handle(isolate(), | |
8975 ParseTypeArguments(&malformed_error, | |
8976 finalization)); | |
8977 if (finalization == ClassFinalizer::kIgnore) { | 8994 if (finalization == ClassFinalizer::kIgnore) { |
8978 return Type::DynamicType(); | 8995 return Type::DynamicType(); |
8979 } | 8996 } |
8980 AbstractType& type = AbstractType::Handle( | 8997 AbstractType& type = AbstractType::Handle( |
8981 isolate(), | 8998 isolate(), Type::New(type_class, type_arguments, type_name.ident_pos)); |
8982 Type::New(type_class, type_arguments, type_name.ident_pos)); | |
8983 // In production mode, malformed type arguments are mapped to dynamic. | |
8984 // In checked mode, a type with malformed type arguments is malformed. | |
8985 if (FLAG_enable_type_checks && !malformed_error.IsNull()) { | |
8986 Type& parameterized_type = Type::Handle(isolate()); | |
8987 parameterized_type ^= type.raw(); | |
8988 parameterized_type.set_type_class( | |
8989 Class::Handle(isolate(), Object::dynamic_class())); | |
8990 parameterized_type.set_arguments(Object::null_abstract_type_arguments()); | |
8991 parameterized_type.set_malformed_error(malformed_error); | |
8992 } | |
8993 if (finalization >= ClassFinalizer::kResolveTypeParameters) { | 8999 if (finalization >= ClassFinalizer::kResolveTypeParameters) { |
8994 ResolveTypeFromClass(current_class(), finalization, &type); | 9000 ResolveTypeFromClass(current_class(), finalization, &type); |
8995 if (finalization >= ClassFinalizer::kCanonicalize) { | 9001 if (finalization >= ClassFinalizer::kCanonicalize) { |
8996 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization); | 9002 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization); |
8997 } | 9003 } |
8998 } | 9004 } |
8999 return type.raw(); | 9005 return type.raw(); |
9000 } | 9006 } |
9001 | 9007 |
9002 | 9008 |
(...skipping 21 matching lines...) Expand all Loading... |
9024 bool is_const, | 9030 bool is_const, |
9025 const AbstractTypeArguments& type_arguments) { | 9031 const AbstractTypeArguments& type_arguments) { |
9026 TRACE_PARSER("ParseListLiteral"); | 9032 TRACE_PARSER("ParseListLiteral"); |
9027 ASSERT(type_pos >= 0); | 9033 ASSERT(type_pos >= 0); |
9028 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); | 9034 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); |
9029 const intptr_t literal_pos = TokenPos(); | 9035 const intptr_t literal_pos = TokenPos(); |
9030 bool is_empty_literal = CurrentToken() == Token::kINDEX; | 9036 bool is_empty_literal = CurrentToken() == Token::kINDEX; |
9031 ConsumeToken(); | 9037 ConsumeToken(); |
9032 | 9038 |
9033 AbstractType& element_type = Type::ZoneHandle(Type::DynamicType()); | 9039 AbstractType& element_type = Type::ZoneHandle(Type::DynamicType()); |
| 9040 AbstractTypeArguments& list_type_arguments = |
| 9041 AbstractTypeArguments::ZoneHandle(type_arguments.raw()); |
9034 // If no type argument vector is provided, leave it as null, which is | 9042 // If no type argument vector is provided, leave it as null, which is |
9035 // equivalent to using dynamic as the type argument for the element type. | 9043 // equivalent to using dynamic as the type argument for the element type. |
9036 if (!type_arguments.IsNull()) { | 9044 if (!list_type_arguments.IsNull()) { |
9037 ASSERT(type_arguments.Length() > 0); | 9045 ASSERT(list_type_arguments.Length() > 0); |
9038 // List literals take a single type argument. | 9046 // List literals take a single type argument. |
9039 element_type = type_arguments.TypeAt(0); | 9047 if (list_type_arguments.Length() == 1) { |
9040 if (type_arguments.Length() != 1) { | 9048 element_type = list_type_arguments.TypeAt(0); |
9041 ErrorMsg(type_pos, | 9049 } else { |
9042 "a list literal takes one type argument specifying " | 9050 if (FLAG_error_on_malformed_type) { |
9043 "the element type"); | 9051 ErrorMsg(type_pos, |
| 9052 "a list literal takes one type argument specifying " |
| 9053 "the element type"); |
| 9054 } |
| 9055 // Ignore type arguments. |
| 9056 list_type_arguments = AbstractTypeArguments::null(); |
9044 } | 9057 } |
9045 if (is_const && !element_type.IsInstantiated()) { | 9058 if (is_const && !element_type.IsInstantiated()) { |
9046 ErrorMsg(type_pos, | 9059 ErrorMsg(type_pos, |
9047 "the type argument of a constant list literal cannot include " | 9060 "the type argument of a constant list literal cannot include " |
9048 "a type variable"); | 9061 "a type variable"); |
9049 } | 9062 } |
9050 } | 9063 } |
9051 ASSERT(type_arguments.IsNull() || (type_arguments.Length() == 1)); | 9064 ASSERT((list_type_arguments.IsNull() && element_type.IsDynamicType()) || |
| 9065 ((list_type_arguments.Length() == 1) && !element_type.IsNull())); |
9052 const Class& array_class = Class::Handle( | 9066 const Class& array_class = Class::Handle( |
9053 isolate()->object_store()->array_class()); | 9067 isolate()->object_store()->array_class()); |
9054 Type& type = Type::ZoneHandle( | 9068 Type& type = Type::ZoneHandle( |
9055 Type::New(array_class, type_arguments, type_pos)); | 9069 Type::New(array_class, list_type_arguments, type_pos)); |
9056 type ^= ClassFinalizer::FinalizeType( | 9070 type ^= ClassFinalizer::FinalizeType( |
9057 current_class(), type, ClassFinalizer::kCanonicalize); | 9071 current_class(), type, ClassFinalizer::kCanonicalize); |
9058 GrowableArray<AstNode*> element_list; | 9072 GrowableArray<AstNode*> element_list; |
9059 // Parse the list elements. Note: there may be an optional extra | 9073 // Parse the list elements. Note: there may be an optional extra |
9060 // comma after the last element. | 9074 // comma after the last element. |
9061 if (!is_empty_literal) { | 9075 if (!is_empty_literal) { |
9062 const bool saved_mode = SetAllowFunctionLiterals(true); | 9076 const bool saved_mode = SetAllowFunctionLiterals(true); |
9063 while (CurrentToken() != Token::kRBRACK) { | 9077 while (CurrentToken() != Token::kRBRACK) { |
9064 const intptr_t element_pos = TokenPos(); | 9078 const intptr_t element_pos = TokenPos(); |
9065 AstNode* element = ParseExpr(is_const, kConsumeCascades); | 9079 AstNode* element = ParseExpr(is_const, kConsumeCascades); |
(...skipping 14 matching lines...) Expand all Loading... |
9080 } | 9094 } |
9081 ExpectToken(Token::kRBRACK); | 9095 ExpectToken(Token::kRBRACK); |
9082 SetAllowFunctionLiterals(saved_mode); | 9096 SetAllowFunctionLiterals(saved_mode); |
9083 } | 9097 } |
9084 | 9098 |
9085 if (is_const) { | 9099 if (is_const) { |
9086 // Allocate and initialize the const list at compile time. | 9100 // Allocate and initialize the const list at compile time. |
9087 Array& const_list = | 9101 Array& const_list = |
9088 Array::ZoneHandle(Array::New(element_list.length(), Heap::kOld)); | 9102 Array::ZoneHandle(Array::New(element_list.length(), Heap::kOld)); |
9089 const_list.SetTypeArguments( | 9103 const_list.SetTypeArguments( |
9090 AbstractTypeArguments::Handle(type_arguments.Canonicalize())); | 9104 AbstractTypeArguments::Handle(list_type_arguments.Canonicalize())); |
9091 Error& malformed_error = Error::Handle(); | 9105 Error& malformed_error = Error::Handle(); |
9092 for (int i = 0; i < element_list.length(); i++) { | 9106 for (int i = 0; i < element_list.length(); i++) { |
9093 AstNode* elem = element_list[i]; | 9107 AstNode* elem = element_list[i]; |
9094 // Arguments have been evaluated to a literal value already. | 9108 // Arguments have been evaluated to a literal value already. |
9095 ASSERT(elem->IsLiteralNode()); | 9109 ASSERT(elem->IsLiteralNode()); |
9096 ASSERT(!is_top_level_); // We cannot check unresolved types. | 9110 ASSERT(!is_top_level_); // We cannot check unresolved types. |
9097 if (FLAG_enable_type_checks && | 9111 if (FLAG_enable_type_checks && |
9098 !element_type.IsDynamicType() && | 9112 !element_type.IsDynamicType() && |
9099 (!elem->AsLiteralNode()->literal().IsNull() && | 9113 (!elem->AsLiteralNode()->literal().IsNull() && |
9100 !elem->AsLiteralNode()->literal().IsInstanceOf( | 9114 !elem->AsLiteralNode()->literal().IsInstanceOf( |
(...skipping 16 matching lines...) Expand all Loading... |
9117 return new LiteralNode(literal_pos, const_list); | 9131 return new LiteralNode(literal_pos, const_list); |
9118 } else { | 9132 } else { |
9119 // Factory call at runtime. | 9133 // Factory call at runtime. |
9120 const Class& factory_class = | 9134 const Class& factory_class = |
9121 Class::Handle(LookupCoreClass(Symbols::List())); | 9135 Class::Handle(LookupCoreClass(Symbols::List())); |
9122 ASSERT(!factory_class.IsNull()); | 9136 ASSERT(!factory_class.IsNull()); |
9123 const Function& factory_method = Function::ZoneHandle( | 9137 const Function& factory_method = Function::ZoneHandle( |
9124 factory_class.LookupFactory( | 9138 factory_class.LookupFactory( |
9125 PrivateCoreLibName(Symbols::ListLiteralFactory()))); | 9139 PrivateCoreLibName(Symbols::ListLiteralFactory()))); |
9126 ASSERT(!factory_method.IsNull()); | 9140 ASSERT(!factory_method.IsNull()); |
9127 if (!type_arguments.IsNull() && | 9141 if (!list_type_arguments.IsNull() && |
9128 !type_arguments.IsInstantiated() && | 9142 !list_type_arguments.IsInstantiated() && |
9129 (current_block_->scope->function_level() > 0)) { | 9143 (current_block_->scope->function_level() > 0)) { |
9130 // Make sure that the instantiator is captured. | 9144 // Make sure that the instantiator is captured. |
9131 CaptureInstantiator(); | 9145 CaptureInstantiator(); |
9132 } | 9146 } |
9133 AbstractTypeArguments& factory_type_args = | 9147 AbstractTypeArguments& factory_type_args = |
9134 AbstractTypeArguments::ZoneHandle(type_arguments.raw()); | 9148 AbstractTypeArguments::ZoneHandle(list_type_arguments.raw()); |
9135 // If the factory class extends other parameterized classes, adjust the | 9149 // If the factory class extends other parameterized classes, adjust the |
9136 // type argument vector. | 9150 // type argument vector. |
9137 if (!factory_type_args.IsNull() && (factory_class.NumTypeArguments() > 1)) { | 9151 if (!factory_type_args.IsNull() && (factory_class.NumTypeArguments() > 1)) { |
9138 ASSERT(factory_type_args.Length() == 1); | 9152 ASSERT(factory_type_args.Length() == 1); |
9139 Type& factory_type = Type::Handle(Type::New( | 9153 Type& factory_type = Type::Handle(Type::New( |
9140 factory_class, factory_type_args, type_pos, Heap::kNew)); | 9154 factory_class, factory_type_args, type_pos, Heap::kNew)); |
9141 factory_type ^= ClassFinalizer::FinalizeType( | 9155 factory_type ^= ClassFinalizer::FinalizeType( |
9142 current_class(), factory_type, ClassFinalizer::kFinalize); | 9156 current_class(), factory_type, ClassFinalizer::kFinalize); |
9143 factory_type_args = factory_type.arguments(); | 9157 factory_type_args = factory_type.arguments(); |
9144 ASSERT(factory_type_args.Length() == factory_class.NumTypeArguments()); | 9158 ASSERT(factory_type_args.Length() == factory_class.NumTypeArguments()); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9205 | 9219 |
9206 AstNode* Parser::ParseMapLiteral(intptr_t type_pos, | 9220 AstNode* Parser::ParseMapLiteral(intptr_t type_pos, |
9207 bool is_const, | 9221 bool is_const, |
9208 const AbstractTypeArguments& type_arguments) { | 9222 const AbstractTypeArguments& type_arguments) { |
9209 TRACE_PARSER("ParseMapLiteral"); | 9223 TRACE_PARSER("ParseMapLiteral"); |
9210 ASSERT(type_pos >= 0); | 9224 ASSERT(type_pos >= 0); |
9211 ASSERT(CurrentToken() == Token::kLBRACE); | 9225 ASSERT(CurrentToken() == Token::kLBRACE); |
9212 const intptr_t literal_pos = TokenPos(); | 9226 const intptr_t literal_pos = TokenPos(); |
9213 ConsumeToken(); | 9227 ConsumeToken(); |
9214 | 9228 |
| 9229 AbstractType& key_type = Type::ZoneHandle(Type::DynamicType()); |
9215 AbstractType& value_type = Type::ZoneHandle(Type::DynamicType()); | 9230 AbstractType& value_type = Type::ZoneHandle(Type::DynamicType()); |
9216 AbstractTypeArguments& map_type_arguments = | 9231 AbstractTypeArguments& map_type_arguments = |
9217 AbstractTypeArguments::ZoneHandle(type_arguments.raw()); | 9232 AbstractTypeArguments::ZoneHandle(type_arguments.raw()); |
9218 // If no type argument vector is provided, leave it as null, which is | 9233 // If no type argument vector is provided, leave it as null, which is |
9219 // equivalent to using dynamic as the type argument for the value type. | 9234 // equivalent to using dynamic as the type argument for the both key and value |
| 9235 // types. |
9220 if (!map_type_arguments.IsNull()) { | 9236 if (!map_type_arguments.IsNull()) { |
9221 ASSERT(map_type_arguments.Length() > 0); | 9237 ASSERT(map_type_arguments.Length() > 0); |
9222 // Map literals take two type arguments. | 9238 // Map literals take two type arguments. |
9223 if (map_type_arguments.Length() != 2) { | 9239 if (map_type_arguments.Length() == 2) { |
9224 ErrorMsg(type_pos, | 9240 key_type = map_type_arguments.TypeAt(0); |
9225 "a map literal takes two type arguments specifying " | 9241 value_type = map_type_arguments.TypeAt(1); |
9226 "the key type and the value type"); | 9242 if (is_const && !type_arguments.IsInstantiated()) { |
9227 } | 9243 ErrorMsg(type_pos, |
9228 const AbstractType& key_type = | 9244 "the type arguments of a constant map literal cannot include " |
9229 AbstractType::Handle(map_type_arguments.TypeAt(0)); | 9245 "a type variable"); |
9230 value_type = map_type_arguments.TypeAt(1); | 9246 } |
9231 if (!key_type.IsStringType()) { | 9247 if (key_type.IsMalformed()) { |
9232 ErrorMsg(type_pos, "the key type of a map literal must be 'String'"); | 9248 if (FLAG_error_on_malformed_type) { |
9233 } | 9249 ErrorMsg(Error::Handle(key_type.malformed_error())); |
9234 if (is_const && !value_type.IsInstantiated()) { | 9250 } |
9235 ErrorMsg(type_pos, | 9251 // Map malformed key type to dynamic. |
9236 "the type argument of a constant map literal cannot include " | 9252 key_type = Type::DynamicType(); |
9237 "a type variable"); | 9253 map_type_arguments.SetTypeAt(0, key_type); |
| 9254 } |
| 9255 if (value_type.IsMalformed()) { |
| 9256 if (FLAG_error_on_malformed_type) { |
| 9257 ErrorMsg(Error::Handle(value_type.malformed_error())); |
| 9258 } |
| 9259 // Map malformed value type to dynamic. |
| 9260 value_type = Type::DynamicType(); |
| 9261 map_type_arguments.SetTypeAt(1, value_type); |
| 9262 } |
| 9263 } else { |
| 9264 if (FLAG_error_on_malformed_type) { |
| 9265 ErrorMsg(type_pos, |
| 9266 "a map literal takes two type arguments specifying " |
| 9267 "the key type and the value type"); |
| 9268 } |
| 9269 // Ignore type arguments. |
| 9270 map_type_arguments = AbstractTypeArguments::null(); |
9238 } | 9271 } |
9239 } | 9272 } |
9240 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); | 9273 ASSERT((map_type_arguments.IsNull() && |
| 9274 key_type.IsDynamicType() && value_type.IsDynamicType()) || |
| 9275 ((map_type_arguments.Length() == 2) && |
| 9276 !key_type.IsMalformed() && !value_type.IsMalformed())); |
9241 map_type_arguments ^= map_type_arguments.Canonicalize(); | 9277 map_type_arguments ^= map_type_arguments.Canonicalize(); |
9242 | 9278 |
9243 GrowableArray<AstNode*> kv_pairs_list; | 9279 GrowableArray<AstNode*> kv_pairs_list; |
9244 // Parse the map entries. Note: there may be an optional extra | 9280 // Parse the map entries. Note: there may be an optional extra |
9245 // comma after the last entry. | 9281 // comma after the last entry. |
9246 while (CurrentToken() != Token::kRBRACE) { | 9282 while (CurrentToken() != Token::kRBRACE) { |
9247 AstNode* key = NULL; | 9283 const bool saved_mode = SetAllowFunctionLiterals(true); |
9248 if (CurrentToken() == Token::kSTRING) { | 9284 const intptr_t key_pos = TokenPos(); |
9249 key = ParseStringLiteral(); | 9285 AstNode* key = ParseExpr(is_const, kConsumeCascades); |
9250 } | 9286 if (FLAG_enable_type_checks && |
9251 if (key == NULL) { | 9287 !is_const && |
9252 ErrorMsg("map entry key must be string literal"); | 9288 !key_type.IsDynamicType()) { |
9253 } else if (is_const && !key->IsLiteralNode()) { | 9289 key = new AssignableNode(key_pos, |
9254 ErrorMsg("map entry key must be compile-time constant string"); | 9290 key, |
| 9291 key_type, |
| 9292 Symbols::ListLiteralElement()); |
9255 } | 9293 } |
9256 ExpectToken(Token::kCOLON); | 9294 ExpectToken(Token::kCOLON); |
9257 const bool saved_mode = SetAllowFunctionLiterals(true); | |
9258 const intptr_t value_pos = TokenPos(); | 9295 const intptr_t value_pos = TokenPos(); |
9259 AstNode* value = ParseExpr(is_const, kConsumeCascades); | 9296 AstNode* value = ParseExpr(is_const, kConsumeCascades); |
9260 SetAllowFunctionLiterals(saved_mode); | 9297 SetAllowFunctionLiterals(saved_mode); |
9261 if (FLAG_enable_type_checks && | 9298 if (FLAG_enable_type_checks && |
9262 !is_const && | 9299 !is_const && |
9263 !value_type.IsDynamicType()) { | 9300 !value_type.IsDynamicType()) { |
9264 value = new AssignableNode(value_pos, | 9301 value = new AssignableNode(value_pos, |
9265 value, | 9302 value, |
9266 value_type, | 9303 value_type, |
9267 Symbols::ListLiteralElement()); | 9304 Symbols::ListLiteralElement()); |
(...skipping 10 matching lines...) Expand all Loading... |
9278 ExpectToken(Token::kRBRACE); | 9315 ExpectToken(Token::kRBRACE); |
9279 | 9316 |
9280 if (is_const) { | 9317 if (is_const) { |
9281 // Create the key-value pair array, canonicalize it and then create | 9318 // Create the key-value pair array, canonicalize it and then create |
9282 // the immutable map object with it. This all happens at compile time. | 9319 // the immutable map object with it. This all happens at compile time. |
9283 // The resulting immutable map object is returned as a literal. | 9320 // The resulting immutable map object is returned as a literal. |
9284 | 9321 |
9285 // First, create the canonicalized key-value pair array. | 9322 // First, create the canonicalized key-value pair array. |
9286 Array& key_value_array = | 9323 Array& key_value_array = |
9287 Array::ZoneHandle(Array::New(kv_pairs_list.length(), Heap::kOld)); | 9324 Array::ZoneHandle(Array::New(kv_pairs_list.length(), Heap::kOld)); |
| 9325 AbstractType& arg_type = Type::Handle(); |
9288 Error& malformed_error = Error::Handle(); | 9326 Error& malformed_error = Error::Handle(); |
9289 for (int i = 0; i < kv_pairs_list.length(); i++) { | 9327 for (int i = 0; i < kv_pairs_list.length(); i++) { |
9290 AstNode* arg = kv_pairs_list[i]; | 9328 AstNode* arg = kv_pairs_list[i]; |
9291 // Arguments have been evaluated to a literal value already. | 9329 // Arguments have been evaluated to a literal value already. |
9292 ASSERT(arg->IsLiteralNode()); | 9330 ASSERT(arg->IsLiteralNode()); |
9293 ASSERT(!is_top_level_); // We cannot check unresolved types. | 9331 ASSERT(!is_top_level_); // We cannot check unresolved types. |
9294 if (FLAG_enable_type_checks && | 9332 if (FLAG_enable_type_checks) { |
9295 ((i % 2) == 1) && // Check values only, not keys. | 9333 if ((i % 2) == 0) { |
9296 !value_type.IsDynamicType() && | 9334 // Check key type. |
9297 (!arg->AsLiteralNode()->literal().IsNull() && | 9335 arg_type = key_type.raw(); |
9298 !arg->AsLiteralNode()->literal().IsInstanceOf( | |
9299 value_type, TypeArguments::Handle(), &malformed_error))) { | |
9300 // If the failure is due to a malformed type error, display it instead. | |
9301 if (!malformed_error.IsNull()) { | |
9302 ErrorMsg(malformed_error); | |
9303 } else { | 9336 } else { |
9304 ErrorMsg(arg->AsLiteralNode()->token_pos(), | 9337 // Check value type. |
9305 "map literal value at index %d must be " | 9338 arg_type = value_type.raw(); |
9306 "a constant of type '%s'", | 9339 } |
9307 i >> 1, | 9340 if (!arg_type.IsDynamicType() && |
9308 String::Handle(value_type.UserVisibleName()).ToCString()); | 9341 (!arg->AsLiteralNode()->literal().IsNull() && |
| 9342 !arg->AsLiteralNode()->literal().IsInstanceOf( |
| 9343 arg_type, |
| 9344 Object::null_abstract_type_arguments(), |
| 9345 &malformed_error))) { |
| 9346 // If the failure is due to a malformed type error, display it. |
| 9347 if (!malformed_error.IsNull()) { |
| 9348 ErrorMsg(malformed_error); |
| 9349 } else { |
| 9350 ErrorMsg(arg->AsLiteralNode()->token_pos(), |
| 9351 "map literal %s at index %d must be " |
| 9352 "a constant of type '%s'", |
| 9353 ((i % 2) == 0) ? "key" : "value", |
| 9354 i >> 1, |
| 9355 String::Handle(arg_type.UserVisibleName()).ToCString()); |
| 9356 } |
9309 } | 9357 } |
9310 } | 9358 } |
9311 key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); | 9359 key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); |
9312 } | 9360 } |
9313 key_value_array ^= TryCanonicalize(key_value_array, TokenPos()); | 9361 key_value_array ^= TryCanonicalize(key_value_array, TokenPos()); |
9314 key_value_array.MakeImmutable(); | 9362 key_value_array.MakeImmutable(); |
9315 | 9363 |
9316 // Construct the map object. | 9364 // Construct the map object. |
9317 const Class& immutable_map_class = | 9365 const Class& immutable_map_class = |
9318 Class::Handle(LookupCoreClass(Symbols::ImmutableMap())); | 9366 Class::Handle(LookupCoreClass(Symbols::ImmutableMap())); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9384 | 9432 |
9385 | 9433 |
9386 AstNode* Parser::ParseCompoundLiteral() { | 9434 AstNode* Parser::ParseCompoundLiteral() { |
9387 TRACE_PARSER("ParseCompoundLiteral"); | 9435 TRACE_PARSER("ParseCompoundLiteral"); |
9388 bool is_const = false; | 9436 bool is_const = false; |
9389 if (CurrentToken() == Token::kCONST) { | 9437 if (CurrentToken() == Token::kCONST) { |
9390 is_const = true; | 9438 is_const = true; |
9391 ConsumeToken(); | 9439 ConsumeToken(); |
9392 } | 9440 } |
9393 const intptr_t type_pos = TokenPos(); | 9441 const intptr_t type_pos = TokenPos(); |
9394 Error& malformed_error = Error::Handle(); | 9442 AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle( |
9395 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle( | 9443 ParseTypeArguments(ClassFinalizer::kCanonicalize)); |
9396 ParseTypeArguments(&malformed_error, | |
9397 ClassFinalizer::kCanonicalizeWellFormed)); | |
9398 // Map and List interfaces do not declare bounds on their type parameters, so | 9444 // Map and List interfaces do not declare bounds on their type parameters, so |
9399 // we should never see a malformed type error here. | 9445 // we should never see a malformed type argument mapped to dynamic here. |
9400 // Note that a bound error is the only possible malformed type error returned | |
9401 // when requesting kCanonicalizeWellFormed type finalization. | |
9402 ASSERT(malformed_error.IsNull()); | |
9403 AstNode* primary = NULL; | 9446 AstNode* primary = NULL; |
9404 if ((CurrentToken() == Token::kLBRACK) || | 9447 if ((CurrentToken() == Token::kLBRACK) || |
9405 (CurrentToken() == Token::kINDEX)) { | 9448 (CurrentToken() == Token::kINDEX)) { |
9406 primary = ParseListLiteral(type_pos, is_const, type_arguments); | 9449 primary = ParseListLiteral(type_pos, is_const, type_arguments); |
9407 } else if (CurrentToken() == Token::kLBRACE) { | 9450 } else if (CurrentToken() == Token::kLBRACE) { |
9408 primary = ParseMapLiteral(type_pos, is_const, type_arguments); | 9451 primary = ParseMapLiteral(type_pos, is_const, type_arguments); |
9409 } else { | 9452 } else { |
9410 ErrorMsg("unexpected token %s", Token::Str(CurrentToken())); | 9453 ErrorMsg("unexpected token %s", Token::Str(CurrentToken())); |
9411 } | 9454 } |
9412 return primary; | 9455 return primary; |
(...skipping 18 matching lines...) Expand all Loading... |
9431 AstNode* Parser::ParseNewOperator(Token::Kind op_kind) { | 9474 AstNode* Parser::ParseNewOperator(Token::Kind op_kind) { |
9432 TRACE_PARSER("ParseNewOperator"); | 9475 TRACE_PARSER("ParseNewOperator"); |
9433 const intptr_t new_pos = TokenPos(); | 9476 const intptr_t new_pos = TokenPos(); |
9434 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); | 9477 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); |
9435 bool is_const = (op_kind == Token::kCONST); | 9478 bool is_const = (op_kind == Token::kCONST); |
9436 if (!IsIdentifier()) { | 9479 if (!IsIdentifier()) { |
9437 ErrorMsg("type name expected"); | 9480 ErrorMsg("type name expected"); |
9438 } | 9481 } |
9439 intptr_t type_pos = TokenPos(); | 9482 intptr_t type_pos = TokenPos(); |
9440 AbstractType& type = AbstractType::Handle( | 9483 AbstractType& type = AbstractType::Handle( |
9441 ParseType(ClassFinalizer::kCanonicalizeExpression)); | 9484 ParseType(ClassFinalizer::kCanonicalizeWellFormed)); |
9442 // In case the type is malformed, throw a dynamic type error after finishing | 9485 // In case the type is malformed, throw a dynamic type error after finishing |
9443 // parsing the instance creation expression. | 9486 // parsing the instance creation expression. |
9444 if (!type.IsMalformed() && (type.IsTypeParameter() || type.IsDynamicType())) { | 9487 if (!type.IsMalformed() && (type.IsTypeParameter() || type.IsDynamicType())) { |
9445 // Replace the type with a malformed type. | 9488 // Replace the type with a malformed type. |
9446 type = ClassFinalizer::NewFinalizedMalformedType( | 9489 type = ClassFinalizer::NewFinalizedMalformedType( |
9447 Error::Handle(), // No previous error. | 9490 Error::Handle(), // No previous error. |
9448 current_class(), | 9491 current_class(), |
9449 type_pos, | 9492 type_pos, |
9450 ClassFinalizer::kResolveTypeParameters, // No compile-time error. | |
9451 "%s'%s' cannot be instantiated", | 9493 "%s'%s' cannot be instantiated", |
9452 type.IsTypeParameter() ? "type parameter " : "", | 9494 type.IsTypeParameter() ? "type parameter " : "", |
9453 type.IsTypeParameter() ? | 9495 type.IsTypeParameter() ? |
9454 String::Handle(type.UserVisibleName()).ToCString() : "dynamic"); | 9496 String::Handle(type.UserVisibleName()).ToCString() : "dynamic"); |
9455 } | 9497 } |
9456 | 9498 |
9457 // The grammar allows for an optional ('.' identifier)? after the type, which | 9499 // The grammar allows for an optional ('.' identifier)? after the type, which |
9458 // is a named constructor. Note that ParseType(kMustResolve) above will not | 9500 // is a named constructor. Note that ParseType() above will not consume it as |
9459 // consume it as part of a misinterpreted qualified identifier, because only a | 9501 // part of a misinterpreted qualified identifier, because only a valid library |
9460 // valid library prefix is accepted as qualifier. | 9502 // prefix is accepted as qualifier. |
9461 String* named_constructor = NULL; | 9503 String* named_constructor = NULL; |
9462 if (CurrentToken() == Token::kPERIOD) { | 9504 if (CurrentToken() == Token::kPERIOD) { |
9463 ConsumeToken(); | 9505 ConsumeToken(); |
9464 named_constructor = ExpectIdentifier("name of constructor expected"); | 9506 named_constructor = ExpectIdentifier("name of constructor expected"); |
9465 } | 9507 } |
9466 | 9508 |
9467 // Parse constructor parameters. | 9509 // Parse constructor parameters. |
9468 if (CurrentToken() != Token::kLPAREN) { | 9510 if (CurrentToken() != Token::kLPAREN) { |
9469 ErrorMsg("'(' expected"); | 9511 ErrorMsg("'(' expected"); |
9470 } | 9512 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9506 if (constructor.IsNull()) { | 9548 if (constructor.IsNull()) { |
9507 const String& external_constructor_name = | 9549 const String& external_constructor_name = |
9508 (named_constructor ? constructor_name : type_class_name); | 9550 (named_constructor ? constructor_name : type_class_name); |
9509 // Replace the type with a malformed type and compile a throw or report a | 9551 // Replace the type with a malformed type and compile a throw or report a |
9510 // compile-time error if the constructor is const. | 9552 // compile-time error if the constructor is const. |
9511 if (is_const) { | 9553 if (is_const) { |
9512 type = ClassFinalizer::NewFinalizedMalformedType( | 9554 type = ClassFinalizer::NewFinalizedMalformedType( |
9513 Error::Handle(), // No previous error. | 9555 Error::Handle(), // No previous error. |
9514 current_class(), | 9556 current_class(), |
9515 call_pos, | 9557 call_pos, |
9516 ClassFinalizer::kResolveTypeParameters, // No compile-time error. | |
9517 "class '%s' has no constructor or factory named '%s'", | 9558 "class '%s' has no constructor or factory named '%s'", |
9518 String::Handle(type_class.Name()).ToCString(), | 9559 String::Handle(type_class.Name()).ToCString(), |
9519 external_constructor_name.ToCString()); | 9560 external_constructor_name.ToCString()); |
9520 const Error& error = Error::Handle(type.malformed_error()); | 9561 const Error& error = Error::Handle(type.malformed_error()); |
9521 ErrorMsg(error); | 9562 ErrorMsg(error); |
9522 } | 9563 } |
9523 return ThrowNoSuchMethodError(call_pos, | 9564 return ThrowNoSuchMethodError(call_pos, |
9524 type_class, | 9565 type_class, |
9525 external_constructor_name, | 9566 external_constructor_name, |
9526 InvocationMirror::kConstructor, | 9567 InvocationMirror::kConstructor, |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9626 ASSERT(!type_bound.IsMalformed()); | 9667 ASSERT(!type_bound.IsMalformed()); |
9627 Error& malformed_error = Error::Handle(); | 9668 Error& malformed_error = Error::Handle(); |
9628 ASSERT(!is_top_level_); // We cannot check unresolved types. | 9669 ASSERT(!is_top_level_); // We cannot check unresolved types. |
9629 if (!const_instance.IsInstanceOf(type_bound, | 9670 if (!const_instance.IsInstanceOf(type_bound, |
9630 TypeArguments::Handle(), | 9671 TypeArguments::Handle(), |
9631 &malformed_error)) { | 9672 &malformed_error)) { |
9632 type_bound = ClassFinalizer::NewFinalizedMalformedType( | 9673 type_bound = ClassFinalizer::NewFinalizedMalformedType( |
9633 malformed_error, | 9674 malformed_error, |
9634 current_class(), | 9675 current_class(), |
9635 new_pos, | 9676 new_pos, |
9636 ClassFinalizer::kResolveTypeParameters, // No compile-time error. | |
9637 "const factory result is not an instance of '%s'", | 9677 "const factory result is not an instance of '%s'", |
9638 String::Handle(type_bound.UserVisibleName()).ToCString()); | 9678 String::Handle(type_bound.UserVisibleName()).ToCString()); |
9639 new_object = ThrowTypeError(new_pos, type_bound); | 9679 new_object = ThrowTypeError(new_pos, type_bound); |
9640 } | 9680 } |
9641 type_bound = AbstractType::null(); | 9681 type_bound = AbstractType::null(); |
9642 } | 9682 } |
9643 } | 9683 } |
9644 } else { | 9684 } else { |
9645 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); | 9685 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); |
9646 if (!type_arguments.IsNull() && | 9686 if (!type_arguments.IsNull() && |
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10209 void Parser::SkipQualIdent() { | 10249 void Parser::SkipQualIdent() { |
10210 ASSERT(IsIdentifier()); | 10250 ASSERT(IsIdentifier()); |
10211 ConsumeToken(); | 10251 ConsumeToken(); |
10212 if (CurrentToken() == Token::kPERIOD) { | 10252 if (CurrentToken() == Token::kPERIOD) { |
10213 ConsumeToken(); // Consume the kPERIOD token. | 10253 ConsumeToken(); // Consume the kPERIOD token. |
10214 ExpectIdentifier("identifier expected after '.'"); | 10254 ExpectIdentifier("identifier expected after '.'"); |
10215 } | 10255 } |
10216 } | 10256 } |
10217 | 10257 |
10218 } // namespace dart | 10258 } // namespace dart |
OLD | NEW |