| 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 1263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1274 // We have an identifier followed by a 'follower' token. | 1274 // We have an identifier followed by a 'follower' token. |
| 1275 // We either parse a type or assume that no type is specified. | 1275 // We either parse a type or assume that no type is specified. |
| 1276 if ((follower == Token::kLT) || // Parameterized type. | 1276 if ((follower == Token::kLT) || // Parameterized type. |
| 1277 (follower == Token::kPERIOD) || // Qualified class name of type. | 1277 (follower == Token::kPERIOD) || // Qualified class name of type. |
| 1278 Token::IsIdentifier(follower) || // Parameter name following a type. | 1278 Token::IsIdentifier(follower) || // Parameter name following a type. |
| 1279 (follower == Token::kTHIS)) { // Field parameter following a type. | 1279 (follower == Token::kTHIS)) { // Field parameter following a type. |
| 1280 // The types of formal parameters are never ignored, even in unchecked | 1280 // The types of formal parameters are never ignored, even in unchecked |
| 1281 // mode, because they are part of the function type of closurized | 1281 // mode, because they are part of the function type of closurized |
| 1282 // functions appearing in type tests with typedefs. | 1282 // functions appearing in type tests with typedefs. |
| 1283 parameter.type = &AbstractType::ZoneHandle( | 1283 parameter.type = &AbstractType::ZoneHandle( |
| 1284 ParseType(is_top_level_ ? ClassFinalizer::kTryResolve : | 1284 ParseType(is_top_level_ ? ClassFinalizer::kResolveTypeParameters : |
| 1285 ClassFinalizer::kCanonicalize)); | 1285 ClassFinalizer::kCanonicalize)); |
| 1286 } else { | 1286 } else { |
| 1287 parameter.type = &Type::ZoneHandle(Type::DynamicType()); | 1287 parameter.type = &Type::ZoneHandle(Type::DynamicType()); |
| 1288 } | 1288 } |
| 1289 } | 1289 } |
| 1290 if (!this_seen && (CurrentToken() == Token::kTHIS)) { | 1290 if (!this_seen && (CurrentToken() == Token::kTHIS)) { |
| 1291 ConsumeToken(); | 1291 ConsumeToken(); |
| 1292 ExpectToken(Token::kPERIOD); | 1292 ExpectToken(Token::kPERIOD); |
| 1293 this_seen = true; | 1293 this_seen = true; |
| 1294 parameter.is_field_initializer = true; | 1294 parameter.is_field_initializer = true; |
| (...skipping 1498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2793 } | 2793 } |
| 2794 } | 2794 } |
| 2795 | 2795 |
| 2796 // Parse redirecting factory constructor. | 2796 // Parse redirecting factory constructor. |
| 2797 Type& redirection_type = Type::Handle(); | 2797 Type& redirection_type = Type::Handle(); |
| 2798 String& redirection_identifier = String::Handle(); | 2798 String& redirection_identifier = String::Handle(); |
| 2799 if (method->IsFactory() && (CurrentToken() == Token::kASSIGN)) { | 2799 if (method->IsFactory() && (CurrentToken() == Token::kASSIGN)) { |
| 2800 ConsumeToken(); | 2800 ConsumeToken(); |
| 2801 const intptr_t type_pos = TokenPos(); | 2801 const intptr_t type_pos = TokenPos(); |
| 2802 const AbstractType& type = AbstractType::Handle( | 2802 const AbstractType& type = AbstractType::Handle( |
| 2803 ParseType(ClassFinalizer::kTryResolve)); | 2803 ParseType(ClassFinalizer::kResolveTypeParameters)); |
| 2804 if (!type.IsMalformed() && | 2804 if (!type.IsMalformed() && type.IsTypeParameter()) { |
| 2805 (type.IsTypeParameter() || type.IsDynamicType())) { | |
| 2806 // Replace the type with a malformed type and compile a throw when called. | 2805 // Replace the type with a malformed type and compile a throw when called. |
| 2807 redirection_type = ClassFinalizer::NewFinalizedMalformedType( | 2806 redirection_type = ClassFinalizer::NewFinalizedMalformedType( |
| 2808 Error::Handle(), // No previous error. | 2807 Error::Handle(), // No previous error. |
| 2809 current_class(), | 2808 current_class(), |
| 2810 type_pos, | 2809 type_pos, |
| 2811 ClassFinalizer::kTryResolve, // No compile-time error. | 2810 ClassFinalizer::kResolveTypeParameters, // No compile-time error. |
| 2812 "factory '%s' may not redirect to %s'%s'", | 2811 "factory '%s' may not redirect to type parameter '%s'", |
| 2813 method->name->ToCString(), | 2812 method->name->ToCString(), |
| 2814 type.IsTypeParameter() ? "type parameter " : "", | 2813 String::Handle(type.UserVisibleName()).ToCString()); |
| 2815 type.IsTypeParameter() ? | |
| 2816 String::Handle(type.UserVisibleName()).ToCString() : "dynamic"); | |
| 2817 } else { | 2814 } else { |
| 2818 redirection_type ^= type.raw(); | 2815 redirection_type ^= type.raw(); |
| 2819 } | 2816 } |
| 2820 if (CurrentToken() == Token::kPERIOD) { | 2817 if (CurrentToken() == Token::kPERIOD) { |
| 2821 // Named constructor or factory. | 2818 // Named constructor or factory. |
| 2822 ConsumeToken(); | 2819 ConsumeToken(); |
| 2823 redirection_identifier = ExpectIdentifier("identifier expected")->raw(); | 2820 redirection_identifier = ExpectIdentifier("identifier expected")->raw(); |
| 2824 } | 2821 } |
| 2825 } else if (CurrentToken() == Token::kCOLON) { | 2822 } else if (CurrentToken() == Token::kCOLON) { |
| 2826 // Parse initializers. | 2823 // Parse initializers. |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3015 bool has_initializer = CurrentToken() == Token::kASSIGN; | 3012 bool has_initializer = CurrentToken() == Token::kASSIGN; |
| 3016 bool has_simple_literal = false; | 3013 bool has_simple_literal = false; |
| 3017 if (has_initializer) { | 3014 if (has_initializer) { |
| 3018 ConsumeToken(); | 3015 ConsumeToken(); |
| 3019 init_value = Object::sentinel().raw(); | 3016 init_value = Object::sentinel().raw(); |
| 3020 // For static const fields, the initialization expression | 3017 // For static const fields, the initialization expression |
| 3021 // will be parsed through the kConstImplicitGetter method | 3018 // will be parsed through the kConstImplicitGetter method |
| 3022 // invocation/compilation. | 3019 // invocation/compilation. |
| 3023 // For instance fields, the expression is parsed when a constructor | 3020 // For instance fields, the expression is parsed when a constructor |
| 3024 // is compiled. | 3021 // is compiled. |
| 3025 // For static fields with very simple initializer expressions | 3022 // For static const fields with very simple initializer expressions |
| 3026 // (e.g. a literal number or string) we optimize away the | 3023 // (e.g. a literal number or string) we optimize away the |
| 3027 // kConstImplicitGetter and initialize the field here. | 3024 // kConstImplicitGetter and initialize the field here. |
| 3025 // We also do it for static final non-const fields, but only in production |
| 3026 // mode. |
| 3028 | 3027 |
| 3029 if (field->has_static && (field->has_final || field->has_const) && | 3028 if (field->has_static && |
| 3029 (field->has_const || |
| 3030 (!FLAG_enable_type_checks && field->has_final)) && |
| 3030 (LookaheadToken(1) == Token::kSEMICOLON)) { | 3031 (LookaheadToken(1) == Token::kSEMICOLON)) { |
| 3031 has_simple_literal = IsSimpleLiteral(*field->type, &init_value); | 3032 has_simple_literal = IsSimpleLiteral(*field->type, &init_value); |
| 3032 } | 3033 } |
| 3033 SkipExpr(); | 3034 SkipExpr(); |
| 3034 } else { | 3035 } else { |
| 3035 if (field->has_const || (field->has_static && field->has_final)) { | 3036 if (field->has_const || (field->has_static && field->has_final)) { |
| 3036 ErrorMsg(field->name_pos, | 3037 ErrorMsg(field->name_pos, |
| 3037 "%s%s field '%s' must have an initializer expression", | 3038 "%s%s field '%s' must have an initializer expression", |
| 3038 field->has_static ? "static " : "", | 3039 field->has_static ? "static " : "", |
| 3039 field->has_const ? "const" : "final", | 3040 field->has_const ? "const" : "final", |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3208 (follower == Token::kSET) || // Setter following a type. | 3209 (follower == Token::kSET) || // Setter following a type. |
| 3209 (follower == Token::kOPERATOR) || // Operator following a type. | 3210 (follower == Token::kOPERATOR) || // Operator following a type. |
| 3210 (Token::IsIdentifier(follower)) || // Member name following a type. | 3211 (Token::IsIdentifier(follower)) || // Member name following a type. |
| 3211 ((follower == Token::kPERIOD) && // Qualified class name of type, | 3212 ((follower == Token::kPERIOD) && // Qualified class name of type, |
| 3212 (LookaheadToken(3) != Token::kLPAREN))) { // but not a named constr. | 3213 (LookaheadToken(3) != Token::kLPAREN))) { // but not a named constr. |
| 3213 ASSERT(is_top_level_); | 3214 ASSERT(is_top_level_); |
| 3214 // The declared type of fields is never ignored, even in unchecked mode, | 3215 // The declared type of fields is never ignored, even in unchecked mode, |
| 3215 // because getters and setters could be closurized at some time (not | 3216 // because getters and setters could be closurized at some time (not |
| 3216 // supported yet). | 3217 // supported yet). |
| 3217 member.type = &AbstractType::ZoneHandle( | 3218 member.type = &AbstractType::ZoneHandle( |
| 3218 ParseType(ClassFinalizer::kTryResolve)); | 3219 ParseType(ClassFinalizer::kResolveTypeParameters)); |
| 3219 } | 3220 } |
| 3220 } | 3221 } |
| 3221 } | 3222 } |
| 3222 | 3223 |
| 3223 // Optionally parse a (possibly named) constructor name or factory. | 3224 // Optionally parse a (possibly named) constructor name or factory. |
| 3224 if (IsIdentifier() && | 3225 if (IsIdentifier() && |
| 3225 (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) { | 3226 (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) { |
| 3226 member.name_pos = TokenPos(); | 3227 member.name_pos = TokenPos(); |
| 3227 member.name = CurrentLiteral(); // Unqualified identifier. | 3228 member.name = CurrentLiteral(); // Unqualified identifier. |
| 3228 ConsumeToken(); | 3229 ConsumeToken(); |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3457 } | 3458 } |
| 3458 // We do not check that the bounds are repeated. We use the original ones. | 3459 // We do not check that the bounds are repeated. We use the original ones. |
| 3459 // TODO(regis): Should we check? | 3460 // TODO(regis): Should we check? |
| 3460 } | 3461 } |
| 3461 cls.set_type_parameters(orig_type_parameters); | 3462 cls.set_type_parameters(orig_type_parameters); |
| 3462 } | 3463 } |
| 3463 AbstractType& super_type = Type::Handle(); | 3464 AbstractType& super_type = Type::Handle(); |
| 3464 if (CurrentToken() == Token::kEXTENDS) { | 3465 if (CurrentToken() == Token::kEXTENDS) { |
| 3465 ConsumeToken(); | 3466 ConsumeToken(); |
| 3466 const intptr_t type_pos = TokenPos(); | 3467 const intptr_t type_pos = TokenPos(); |
| 3467 super_type = ParseType(ClassFinalizer::kTryResolve); | 3468 super_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 3468 if (super_type.IsTypeParameter()) { | 3469 if (super_type.IsTypeParameter()) { |
| 3469 ErrorMsg(type_pos, | 3470 ErrorMsg(type_pos, |
| 3470 "class '%s' may not extend type parameter '%s'", | 3471 "class '%s' may not extend type parameter '%s'", |
| 3471 class_name.ToCString(), | 3472 class_name.ToCString(), |
| 3472 String::Handle(super_type.UserVisibleName()).ToCString()); | 3473 String::Handle(super_type.UserVisibleName()).ToCString()); |
| 3473 } | 3474 } |
| 3474 if (super_type.IsDynamicType()) { | |
| 3475 ErrorMsg(type_pos, | |
| 3476 "class '%s' may not extend 'dynamic'", | |
| 3477 class_name.ToCString()); | |
| 3478 } | |
| 3479 if (CurrentToken() == Token::kWITH) { | 3475 if (CurrentToken() == Token::kWITH) { |
| 3480 super_type = ParseMixins(super_type); | 3476 super_type = ParseMixins(super_type); |
| 3481 } | 3477 } |
| 3482 } else { | 3478 } else { |
| 3483 // No extends clause: implicitly extend Object, unless Object itself. | 3479 // No extends clause: implicitly extend Object, unless Object itself. |
| 3484 if (!cls.IsObjectClass()) { | 3480 if (!cls.IsObjectClass()) { |
| 3485 super_type = Type::ObjectType(); | 3481 super_type = Type::ObjectType(); |
| 3486 } | 3482 } |
| 3487 } | 3483 } |
| 3488 ASSERT(!super_type.IsNull() || cls.IsObjectClass()); | 3484 ASSERT(!super_type.IsNull() || cls.IsObjectClass()); |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3664 | 3660 |
| 3665 ExpectToken(Token::kASSIGN); | 3661 ExpectToken(Token::kASSIGN); |
| 3666 | 3662 |
| 3667 if (CurrentToken() == Token::kABSTRACT) { | 3663 if (CurrentToken() == Token::kABSTRACT) { |
| 3668 mixin_application.set_is_abstract(); | 3664 mixin_application.set_is_abstract(); |
| 3669 ConsumeToken(); | 3665 ConsumeToken(); |
| 3670 } | 3666 } |
| 3671 | 3667 |
| 3672 const intptr_t type_pos = TokenPos(); | 3668 const intptr_t type_pos = TokenPos(); |
| 3673 AbstractType& type = | 3669 AbstractType& type = |
| 3674 AbstractType::Handle(ParseType(ClassFinalizer::kTryResolve)); | 3670 AbstractType::Handle(ParseType(ClassFinalizer::kResolveTypeParameters)); |
| 3675 if (type.IsTypeParameter()) { | 3671 if (type.IsTypeParameter()) { |
| 3676 ErrorMsg(type_pos, | 3672 ErrorMsg(type_pos, |
| 3677 "class '%s' may not extend type parameter '%s'", | 3673 "class '%s' may not extend type parameter '%s'", |
| 3678 class_name.ToCString(), | 3674 class_name.ToCString(), |
| 3679 String::Handle(type.UserVisibleName()).ToCString()); | 3675 String::Handle(type.UserVisibleName()).ToCString()); |
| 3680 } | 3676 } |
| 3681 | 3677 |
| 3682 if (CurrentToken() != Token::kWITH) { | 3678 if (CurrentToken() != Token::kWITH) { |
| 3683 ErrorMsg("mixin application 'with Type' expected"); | 3679 ErrorMsg("mixin application 'with Type' expected"); |
| 3684 } | 3680 } |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3780 script_, | 3776 script_, |
| 3781 alias_name_pos)); | 3777 alias_name_pos)); |
| 3782 library_.AddClass(function_type_alias); | 3778 library_.AddClass(function_type_alias); |
| 3783 set_current_class(function_type_alias); | 3779 set_current_class(function_type_alias); |
| 3784 // Parse the type parameters of the function type. | 3780 // Parse the type parameters of the function type. |
| 3785 ParseTypeParameters(function_type_alias); | 3781 ParseTypeParameters(function_type_alias); |
| 3786 // At this point, the type parameters have been parsed, so we can resolve the | 3782 // At this point, the type parameters have been parsed, so we can resolve the |
| 3787 // result type. | 3783 // result type. |
| 3788 if (!result_type.IsNull()) { | 3784 if (!result_type.IsNull()) { |
| 3789 ResolveTypeFromClass(function_type_alias, | 3785 ResolveTypeFromClass(function_type_alias, |
| 3790 ClassFinalizer::kTryResolve, | 3786 ClassFinalizer::kResolveTypeParameters, |
| 3791 &result_type); | 3787 &result_type); |
| 3792 } | 3788 } |
| 3793 // Parse the formal parameters of the function type. | 3789 // Parse the formal parameters of the function type. |
| 3794 if (CurrentToken() != Token::kLPAREN) { | 3790 if (CurrentToken() != Token::kLPAREN) { |
| 3795 ErrorMsg("formal parameter list expected"); | 3791 ErrorMsg("formal parameter list expected"); |
| 3796 } | 3792 } |
| 3797 ParamList func_params; | 3793 ParamList func_params; |
| 3798 | 3794 |
| 3799 // Add implicit closure object parameter. | 3795 // Add implicit closure object parameter. |
| 3800 func_params.AddFinalParameter( | 3796 func_params.AddFinalParameter( |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3977 const TypeArguments& type_parameters = | 3973 const TypeArguments& type_parameters = |
| 3978 TypeArguments::Handle(NewTypeArguments(type_parameters_array)); | 3974 TypeArguments::Handle(NewTypeArguments(type_parameters_array)); |
| 3979 cls.set_type_parameters(type_parameters); | 3975 cls.set_type_parameters(type_parameters); |
| 3980 // Try to resolve the upper bounds, which will at least resolve the | 3976 // Try to resolve the upper bounds, which will at least resolve the |
| 3981 // referenced type parameters. | 3977 // referenced type parameters. |
| 3982 const intptr_t num_types = type_parameters.Length(); | 3978 const intptr_t num_types = type_parameters.Length(); |
| 3983 for (intptr_t i = 0; i < num_types; i++) { | 3979 for (intptr_t i = 0; i < num_types; i++) { |
| 3984 type_parameter ^= type_parameters.TypeAt(i); | 3980 type_parameter ^= type_parameters.TypeAt(i); |
| 3985 type_parameter_bound = type_parameter.bound(); | 3981 type_parameter_bound = type_parameter.bound(); |
| 3986 ResolveTypeFromClass(cls, | 3982 ResolveTypeFromClass(cls, |
| 3987 ClassFinalizer::kTryResolve, | 3983 ClassFinalizer::kResolveTypeParameters, |
| 3988 &type_parameter_bound); | 3984 &type_parameter_bound); |
| 3989 type_parameter.set_bound(type_parameter_bound); | 3985 type_parameter.set_bound(type_parameter_bound); |
| 3990 } | 3986 } |
| 3991 } | 3987 } |
| 3992 } | 3988 } |
| 3993 | 3989 |
| 3994 | 3990 |
| 3995 RawAbstractTypeArguments* Parser::ParseTypeArguments( | 3991 RawAbstractTypeArguments* Parser::ParseTypeArguments( |
| 3996 Error* malformed_error, | 3992 Error* malformed_error, |
| 3997 ClassFinalizer::FinalizationKind finalization) { | 3993 ClassFinalizer::FinalizationKind finalization) { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4039 // First get all the interfaces already implemented by class. | 4035 // First get all the interfaces already implemented by class. |
| 4040 Array& cls_interfaces = Array::Handle(cls.interfaces()); | 4036 Array& cls_interfaces = Array::Handle(cls.interfaces()); |
| 4041 for (intptr_t i = 0; i < cls_interfaces.Length(); i++) { | 4037 for (intptr_t i = 0; i < cls_interfaces.Length(); i++) { |
| 4042 interface ^= cls_interfaces.At(i); | 4038 interface ^= cls_interfaces.At(i); |
| 4043 all_interfaces.Add(interface); | 4039 all_interfaces.Add(interface); |
| 4044 } | 4040 } |
| 4045 // Now parse and add the new interfaces. | 4041 // Now parse and add the new interfaces. |
| 4046 do { | 4042 do { |
| 4047 ConsumeToken(); | 4043 ConsumeToken(); |
| 4048 intptr_t interface_pos = TokenPos(); | 4044 intptr_t interface_pos = TokenPos(); |
| 4049 interface = ParseType(ClassFinalizer::kTryResolve); | 4045 interface = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 4050 if (interface.IsTypeParameter()) { | 4046 if (interface.IsTypeParameter()) { |
| 4051 ErrorMsg(interface_pos, | 4047 ErrorMsg(interface_pos, |
| 4052 "type parameter '%s' may not be used in interface list", | 4048 "type parameter '%s' may not be used in interface list", |
| 4053 String::Handle(interface.UserVisibleName()).ToCString()); | 4049 String::Handle(interface.UserVisibleName()).ToCString()); |
| 4054 } | 4050 } |
| 4055 if (interface.IsDynamicType()) { | |
| 4056 ErrorMsg(interface_pos, "'dynamic' may not be used in interface list"); | |
| 4057 } | |
| 4058 all_interfaces.Add(interface); | 4051 all_interfaces.Add(interface); |
| 4059 } while (CurrentToken() == Token::kCOMMA); | 4052 } while (CurrentToken() == Token::kCOMMA); |
| 4060 cls_interfaces = Array::MakeArray(all_interfaces); | 4053 cls_interfaces = Array::MakeArray(all_interfaces); |
| 4061 cls.set_interfaces(cls_interfaces); | 4054 cls.set_interfaces(cls_interfaces); |
| 4062 } | 4055 } |
| 4063 | 4056 |
| 4064 | 4057 |
| 4065 RawAbstractType* Parser::ParseMixins(const AbstractType& super_type) { | 4058 RawAbstractType* Parser::ParseMixins(const AbstractType& super_type) { |
| 4066 TRACE_PARSER("ParseMixins"); | 4059 TRACE_PARSER("ParseMixins"); |
| 4067 ASSERT(CurrentToken() == Token::kWITH); | 4060 ASSERT(CurrentToken() == Token::kWITH); |
| 4068 | 4061 |
| 4069 const GrowableObjectArray& mixin_apps = | 4062 const GrowableObjectArray& mixin_apps = |
| 4070 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 4063 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 4071 AbstractType& mixin_type = AbstractType::Handle(); | 4064 AbstractType& mixin_type = AbstractType::Handle(); |
| 4072 AbstractTypeArguments& mixin_type_arguments = | 4065 AbstractTypeArguments& mixin_type_arguments = |
| 4073 AbstractTypeArguments::Handle(); | 4066 AbstractTypeArguments::Handle(); |
| 4074 Class& mixin_application = Class::Handle(); | 4067 Class& mixin_application = Class::Handle(); |
| 4075 Type& mixin_application_type = Type::Handle(); | 4068 Type& mixin_application_type = Type::Handle(); |
| 4076 Type& mixin_super_type = Type::Handle(); | 4069 Type& mixin_super_type = Type::Handle(); |
| 4077 ASSERT(super_type.IsType()); | 4070 ASSERT(super_type.IsType()); |
| 4078 mixin_super_type ^= super_type.raw(); | 4071 mixin_super_type ^= super_type.raw(); |
| 4079 Array& mixin_application_interfaces = Array::Handle(); | 4072 Array& mixin_application_interfaces = Array::Handle(); |
| 4080 do { | 4073 do { |
| 4081 ConsumeToken(); | 4074 ConsumeToken(); |
| 4082 const intptr_t mixin_pos = TokenPos(); | 4075 const intptr_t mixin_pos = TokenPos(); |
| 4083 mixin_type = ParseType(ClassFinalizer::kTryResolve); | 4076 mixin_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 4084 if (mixin_type.IsTypeParameter()) { | 4077 if (mixin_type.IsTypeParameter()) { |
| 4085 ErrorMsg(mixin_pos, | 4078 ErrorMsg(mixin_pos, |
| 4086 "mixin type '%s' may not be a type parameter", | 4079 "mixin type '%s' may not be a type parameter", |
| 4087 String::Handle(mixin_type.UserVisibleName()).ToCString()); | 4080 String::Handle(mixin_type.UserVisibleName()).ToCString()); |
| 4088 } | 4081 } |
| 4089 | 4082 |
| 4090 // The name of the mixin application class is a combination of | 4083 // The name of the mixin application class is a combination of |
| 4091 // the superclass and mixin class. | 4084 // the superclass and mixin class. |
| 4092 String& mixin_app_name = String::Handle(); | 4085 String& mixin_app_name = String::Handle(); |
| 4093 mixin_app_name = mixin_super_type.ClassName(); | 4086 mixin_app_name = mixin_super_type.ClassName(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 4106 // class implements. This is necessary so that type tests work. | 4099 // class implements. This is necessary so that type tests work. |
| 4107 mixin_application_interfaces = Array::New(1); | 4100 mixin_application_interfaces = Array::New(1); |
| 4108 mixin_application_interfaces.SetAt(0, mixin_type); | 4101 mixin_application_interfaces.SetAt(0, mixin_type); |
| 4109 mixin_application.set_interfaces(mixin_application_interfaces); | 4102 mixin_application.set_interfaces(mixin_application_interfaces); |
| 4110 | 4103 |
| 4111 // For the type arguments of the mixin application type, we need | 4104 // For the type arguments of the mixin application type, we need |
| 4112 // a copy of the type arguments to the mixin type. The simplest way | 4105 // a copy of the type arguments to the mixin type. The simplest way |
| 4113 // to get the copy is to rewind the parser, parse the mixin type | 4106 // to get the copy is to rewind the parser, parse the mixin type |
| 4114 // again and steal its type arguments. | 4107 // again and steal its type arguments. |
| 4115 SetPosition(mixin_pos); | 4108 SetPosition(mixin_pos); |
| 4116 mixin_type = ParseType(ClassFinalizer::kTryResolve); | 4109 mixin_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 4117 mixin_type_arguments = mixin_type.arguments(); | 4110 mixin_type_arguments = mixin_type.arguments(); |
| 4118 | 4111 |
| 4119 mixin_application_type = Type::New(mixin_application, | 4112 mixin_application_type = Type::New(mixin_application, |
| 4120 mixin_type_arguments, | 4113 mixin_type_arguments, |
| 4121 mixin_pos); | 4114 mixin_pos); |
| 4122 mixin_super_type = mixin_application_type.raw(); | 4115 mixin_super_type = mixin_application_type.raw(); |
| 4123 mixin_apps.Add(mixin_application_type); | 4116 mixin_apps.Add(mixin_application_type); |
| 4124 } while (CurrentToken() == Token::kCOMMA); | 4117 } while (CurrentToken() == Token::kCOMMA); |
| 4125 return MixinAppType::New(super_type, | 4118 return MixinAppType::New(super_type, |
| 4126 Array::Handle(Array::MakeArray(mixin_apps))); | 4119 Array::Handle(Array::MakeArray(mixin_apps))); |
| 4127 } | 4120 } |
| 4128 | 4121 |
| 4129 | 4122 |
| 4130 void Parser::ParseTopLevelVariable(TopLevel* top_level, | 4123 void Parser::ParseTopLevelVariable(TopLevel* top_level, |
| 4131 intptr_t metadata_pos) { | 4124 intptr_t metadata_pos) { |
| 4132 TRACE_PARSER("ParseTopLevelVariable"); | 4125 TRACE_PARSER("ParseTopLevelVariable"); |
| 4133 const bool is_const = (CurrentToken() == Token::kCONST); | 4126 const bool is_const = (CurrentToken() == Token::kCONST); |
| 4134 // Const fields are implicitly final. | 4127 // Const fields are implicitly final. |
| 4135 const bool is_final = is_const || (CurrentToken() == Token::kFINAL); | 4128 const bool is_final = is_const || (CurrentToken() == Token::kFINAL); |
| 4136 const bool is_static = true; | 4129 const bool is_static = true; |
| 4137 const AbstractType& type = | 4130 const AbstractType& type = |
| 4138 AbstractType::ZoneHandle(ParseConstFinalVarOrType( | 4131 AbstractType::ZoneHandle(ParseConstFinalVarOrType( |
| 4139 FLAG_enable_type_checks ? ClassFinalizer::kTryResolve : | 4132 FLAG_enable_type_checks ? ClassFinalizer::kResolveTypeParameters : |
| 4140 ClassFinalizer::kIgnore)); | 4133 ClassFinalizer::kIgnore)); |
| 4141 Field& field = Field::Handle(); | 4134 Field& field = Field::Handle(); |
| 4142 Function& getter = Function::Handle(); | 4135 Function& getter = Function::Handle(); |
| 4143 while (true) { | 4136 while (true) { |
| 4144 const intptr_t name_pos = TokenPos(); | 4137 const intptr_t name_pos = TokenPos(); |
| 4145 String& var_name = *ExpectIdentifier("variable name expected"); | 4138 String& var_name = *ExpectIdentifier("variable name expected"); |
| 4146 | 4139 |
| 4147 if (library_.LookupLocalObject(var_name) != Object::null()) { | 4140 if (library_.LookupLocalObject(var_name) != Object::null()) { |
| 4148 ErrorMsg(name_pos, "'%s' is already defined", var_name.ToCString()); | 4141 ErrorMsg(name_pos, "'%s' is already defined", var_name.ToCString()); |
| 4149 } | 4142 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 4168 field.set_value(Instance::Handle(Instance::null())); | 4161 field.set_value(Instance::Handle(Instance::null())); |
| 4169 top_level->fields.Add(field); | 4162 top_level->fields.Add(field); |
| 4170 library_.AddObject(field, var_name); | 4163 library_.AddObject(field, var_name); |
| 4171 if (metadata_pos >= 0) { | 4164 if (metadata_pos >= 0) { |
| 4172 library_.AddFieldMetadata(field, metadata_pos); | 4165 library_.AddFieldMetadata(field, metadata_pos); |
| 4173 } | 4166 } |
| 4174 if (CurrentToken() == Token::kASSIGN) { | 4167 if (CurrentToken() == Token::kASSIGN) { |
| 4175 ConsumeToken(); | 4168 ConsumeToken(); |
| 4176 Instance& field_value = Instance::Handle(Object::sentinel().raw()); | 4169 Instance& field_value = Instance::Handle(Object::sentinel().raw()); |
| 4177 bool has_simple_literal = false; | 4170 bool has_simple_literal = false; |
| 4178 if (is_final && (LookaheadToken(1) == Token::kSEMICOLON)) { | 4171 if ((is_const || (!FLAG_enable_type_checks && is_final)) && |
| 4172 (LookaheadToken(1) == Token::kSEMICOLON)) { |
| 4179 has_simple_literal = IsSimpleLiteral(type, &field_value); | 4173 has_simple_literal = IsSimpleLiteral(type, &field_value); |
| 4180 } | 4174 } |
| 4181 SkipExpr(); | 4175 SkipExpr(); |
| 4182 field.set_value(field_value); | 4176 field.set_value(field_value); |
| 4183 if (!has_simple_literal) { | 4177 if (!has_simple_literal) { |
| 4184 // Create a static const getter. | 4178 // Create a static const getter. |
| 4185 String& getter_name = String::ZoneHandle(Field::GetterSymbol(var_name)); | 4179 String& getter_name = String::ZoneHandle(Field::GetterSymbol(var_name)); |
| 4186 getter = Function::New(getter_name, | 4180 getter = Function::New(getter_name, |
| 4187 RawFunction::kConstImplicitGetter, | 4181 RawFunction::kConstImplicitGetter, |
| 4188 is_static, | 4182 is_static, |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4227 ConsumeToken(); | 4221 ConsumeToken(); |
| 4228 is_external = true; | 4222 is_external = true; |
| 4229 } | 4223 } |
| 4230 if (CurrentToken() == Token::kVOID) { | 4224 if (CurrentToken() == Token::kVOID) { |
| 4231 ConsumeToken(); | 4225 ConsumeToken(); |
| 4232 result_type = Type::VoidType(); | 4226 result_type = Type::VoidType(); |
| 4233 } else { | 4227 } else { |
| 4234 // Parse optional type. | 4228 // Parse optional type. |
| 4235 if ((CurrentToken() == Token::kIDENT) && | 4229 if ((CurrentToken() == Token::kIDENT) && |
| 4236 (LookaheadToken(1) != Token::kLPAREN)) { | 4230 (LookaheadToken(1) != Token::kLPAREN)) { |
| 4237 result_type = ParseType(ClassFinalizer::kTryResolve); | 4231 result_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 4238 } | 4232 } |
| 4239 } | 4233 } |
| 4240 const intptr_t name_pos = TokenPos(); | 4234 const intptr_t name_pos = TokenPos(); |
| 4241 const String& func_name = *ExpectIdentifier("function name expected"); | 4235 const String& func_name = *ExpectIdentifier("function name expected"); |
| 4242 | 4236 |
| 4243 bool found = library_.LookupLocalObject(func_name) != Object::null(); | 4237 bool found = library_.LookupLocalObject(func_name) != Object::null(); |
| 4244 if (found && !is_patch) { | 4238 if (found && !is_patch) { |
| 4245 ErrorMsg(name_pos, "'%s' is already defined", func_name.ToCString()); | 4239 ErrorMsg(name_pos, "'%s' is already defined", func_name.ToCString()); |
| 4246 } else if (!found && is_patch) { | 4240 } else if (!found && is_patch) { |
| 4247 ErrorMsg(name_pos, "missing '%s' cannot be patched", func_name.ToCString()); | 4241 ErrorMsg(name_pos, "missing '%s' cannot be patched", func_name.ToCString()); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4321 bool is_getter = (CurrentToken() == Token::kGET); | 4315 bool is_getter = (CurrentToken() == Token::kGET); |
| 4322 if (CurrentToken() == Token::kGET || | 4316 if (CurrentToken() == Token::kGET || |
| 4323 CurrentToken() == Token::kSET) { | 4317 CurrentToken() == Token::kSET) { |
| 4324 ConsumeToken(); | 4318 ConsumeToken(); |
| 4325 result_type = Type::DynamicType(); | 4319 result_type = Type::DynamicType(); |
| 4326 } else { | 4320 } else { |
| 4327 if (CurrentToken() == Token::kVOID) { | 4321 if (CurrentToken() == Token::kVOID) { |
| 4328 ConsumeToken(); | 4322 ConsumeToken(); |
| 4329 result_type = Type::VoidType(); | 4323 result_type = Type::VoidType(); |
| 4330 } else { | 4324 } else { |
| 4331 result_type = ParseType(ClassFinalizer::kTryResolve); | 4325 result_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 4332 } | 4326 } |
| 4333 is_getter = (CurrentToken() == Token::kGET); | 4327 is_getter = (CurrentToken() == Token::kGET); |
| 4334 if (CurrentToken() == Token::kGET || CurrentToken() == Token::kSET) { | 4328 if (CurrentToken() == Token::kGET || CurrentToken() == Token::kSET) { |
| 4335 ConsumeToken(); | 4329 ConsumeToken(); |
| 4336 } else { | 4330 } else { |
| 4337 UnexpectedToken(); | 4331 UnexpectedToken(); |
| 4338 } | 4332 } |
| 4339 } | 4333 } |
| 4340 const intptr_t name_pos = TokenPos(); | 4334 const intptr_t name_pos = TokenPos(); |
| 4341 const String* field_name = ExpectIdentifier("accessor name expected"); | 4335 const String* field_name = ExpectIdentifier("accessor name expected"); |
| (...skipping 975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5317 } while (nesting_level > 0); | 5311 } while (nesting_level > 0); |
| 5318 if (nesting_level < 0) { | 5312 if (nesting_level < 0) { |
| 5319 return false; | 5313 return false; |
| 5320 } | 5314 } |
| 5321 } | 5315 } |
| 5322 return true; | 5316 return true; |
| 5323 } | 5317 } |
| 5324 | 5318 |
| 5325 | 5319 |
| 5326 bool Parser::IsSimpleLiteral(const AbstractType& type, Instance* value) { | 5320 bool Parser::IsSimpleLiteral(const AbstractType& type, Instance* value) { |
| 5327 bool no_check = type.IsDynamicType(); | 5321 // Assigning null never causes a type error. |
| 5328 if ((CurrentToken() == Token::kINTEGER) && | 5322 if (CurrentToken() == Token::kNULL) { |
| 5329 (no_check || type.IsIntType() || type.IsNumberType())) { | 5323 *value = Instance::null(); |
| 5324 return true; |
| 5325 } |
| 5326 // If the type of the const field is guaranteed to be instantiated once |
| 5327 // resolved at class finalization time, and if the type of the literal is one |
| 5328 // of int, double, String, or bool, then preset the field with the value and |
| 5329 // perform the type check (in checked mode only) at finalization time. |
| 5330 if (type.IsTypeParameter() || |
| 5331 (type.arguments() != AbstractTypeArguments::null())) { |
| 5332 // Type parameters are always resolved eagerly by the parser and never |
| 5333 // resolved later by the class finalizer. Therefore, we know here that if |
| 5334 // 'type' is not a type parameter (an unresolved type will not get resolved |
| 5335 // to a type parameter later) and if 'type' has no type arguments, then it |
| 5336 // will be instantiated at class finalization time. Otherwise, we return |
| 5337 // false, since the type test would not be possible at finalization time for |
| 5338 // an uninstantiated type. |
| 5339 return false; |
| 5340 } |
| 5341 if (CurrentToken() == Token::kINTEGER) { |
| 5330 *value = CurrentIntegerLiteral(); | 5342 *value = CurrentIntegerLiteral(); |
| 5331 return true; | 5343 return true; |
| 5332 } else if ((CurrentToken() == Token::kDOUBLE) && | 5344 } else if (CurrentToken() == Token::kDOUBLE) { |
| 5333 (no_check || type.IsDoubleType() || type.IsNumberType())) { | |
| 5334 *value = CurrentDoubleLiteral(); | 5345 *value = CurrentDoubleLiteral(); |
| 5335 return true; | 5346 return true; |
| 5336 } else if ((CurrentToken() == Token::kSTRING) && | 5347 } else if (CurrentToken() == Token::kSTRING) { |
| 5337 (no_check || type.IsStringType())) { | |
| 5338 *value = CurrentLiteral()->raw(); | 5348 *value = CurrentLiteral()->raw(); |
| 5339 return true; | 5349 return true; |
| 5340 } else if ((CurrentToken() == Token::kTRUE) && | 5350 } else if (CurrentToken() == Token::kTRUE) { |
| 5341 (no_check || type.IsBoolType())) { | |
| 5342 *value = Bool::True().raw(); | 5351 *value = Bool::True().raw(); |
| 5343 return true; | 5352 return true; |
| 5344 } else if ((CurrentToken() == Token::kFALSE) && | 5353 } else if (CurrentToken() == Token::kFALSE) { |
| 5345 (no_check || type.IsBoolType())) { | |
| 5346 *value = Bool::False().raw(); | 5354 *value = Bool::False().raw(); |
| 5347 return true; | 5355 return true; |
| 5348 } else if (CurrentToken() == Token::kNULL) { | |
| 5349 *value = Instance::null(); | |
| 5350 return true; | |
| 5351 } | 5356 } |
| 5352 return false; | 5357 return false; |
| 5353 } | 5358 } |
| 5354 | 5359 |
| 5355 | 5360 |
| 5356 // Returns true if the current token is kIDENT or a pseudo-keyword. | 5361 // Returns true if the current token is kIDENT or a pseudo-keyword. |
| 5357 bool Parser::IsIdentifier() { | 5362 bool Parser::IsIdentifier() { |
| 5358 return Token::IsIdentifier(CurrentToken()); | 5363 return Token::IsIdentifier(CurrentToken()); |
| 5359 } | 5364 } |
| 5360 | 5365 |
| (...skipping 2634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7995 // Resolve the given type and its type arguments from the given scope class | 8000 // Resolve the given type and its type arguments from the given scope class |
| 7996 // according to the given type finalization mode. | 8001 // according to the given type finalization mode. |
| 7997 // If the given scope class is null, use the current library, but do not try to | 8002 // If the given scope class is null, use the current library, but do not try to |
| 7998 // resolve type parameters. | 8003 // resolve type parameters. |
| 7999 // Not all involved type classes may get resolved yet, but at least the type | 8004 // Not all involved type classes may get resolved yet, but at least the type |
| 8000 // parameters of the given class will get resolved, thereby relieving the class | 8005 // parameters of the given class will get resolved, thereby relieving the class |
| 8001 // finalizer from resolving type parameters out of context. | 8006 // finalizer from resolving type parameters out of context. |
| 8002 void Parser::ResolveTypeFromClass(const Class& scope_class, | 8007 void Parser::ResolveTypeFromClass(const Class& scope_class, |
| 8003 ClassFinalizer::FinalizationKind finalization, | 8008 ClassFinalizer::FinalizationKind finalization, |
| 8004 AbstractType* type) { | 8009 AbstractType* type) { |
| 8005 ASSERT(finalization >= ClassFinalizer::kTryResolve); | 8010 ASSERT(finalization >= ClassFinalizer::kResolveTypeParameters); |
| 8006 ASSERT(type != NULL); | 8011 ASSERT(type != NULL); |
| 8007 if (type->IsResolved()) { | 8012 if (type->IsResolved()) { |
| 8008 return; | 8013 return; |
| 8009 } | 8014 } |
| 8010 // Resolve class. | 8015 // Resolve class. |
| 8011 if (!type->HasResolvedTypeClass()) { | 8016 if (!type->HasResolvedTypeClass()) { |
| 8012 const UnresolvedClass& unresolved_class = | 8017 const UnresolvedClass& unresolved_class = |
| 8013 UnresolvedClass::Handle(type->unresolved_class()); | 8018 UnresolvedClass::Handle(type->unresolved_class()); |
| 8014 const String& unresolved_class_name = | 8019 const String& unresolved_class_name = |
| 8015 String::Handle(unresolved_class.ident()); | 8020 String::Handle(unresolved_class.ident()); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 8043 type_parameter.token_pos(), | 8048 type_parameter.token_pos(), |
| 8044 finalization, | 8049 finalization, |
| 8045 "type parameter '%s' cannot be parameterized", | 8050 "type parameter '%s' cannot be parameterized", |
| 8046 String::Handle(type_parameter.name()).ToCString()); | 8051 String::Handle(type_parameter.name()).ToCString()); |
| 8047 return; | 8052 return; |
| 8048 } | 8053 } |
| 8049 *type = type_parameter.raw(); | 8054 *type = type_parameter.raw(); |
| 8050 return; | 8055 return; |
| 8051 } | 8056 } |
| 8052 } | 8057 } |
| 8053 // Resolve classname in the scope of the current library. | 8058 // The referenced class may not have been parsed yet. It would be wrong |
| 8054 Error& error = Error::Handle(); | 8059 // to resolve it too early to an imported class of the same name. |
| 8055 // If we finalize a type expression, as opposed to a type annotation, we | 8060 if (finalization > ClassFinalizer::kResolveTypeParameters) { |
| 8056 // tell the resolver (by passing NULL) to immediately report an ambiguous | 8061 // Resolve classname in the scope of the current library. |
| 8057 // type as a compile time error. | 8062 Error& error = Error::Handle(); |
| 8058 resolved_type_class = ResolveClassInCurrentLibraryScope( | 8063 // If we finalize a type expression, as opposed to a type annotation, |
| 8059 unresolved_class.token_pos(), | 8064 // we tell the resolver (by passing NULL) to immediately report an |
| 8060 unresolved_class_name, | 8065 // ambiguous type as a compile time error. |
| 8061 finalization >= ClassFinalizer::kCanonicalizeExpression ? | 8066 resolved_type_class = ResolveClassInCurrentLibraryScope( |
| 8062 NULL : &error); | |
| 8063 if (!error.IsNull()) { | |
| 8064 *type = ClassFinalizer::NewFinalizedMalformedType( | |
| 8065 error, | |
| 8066 scope_class, | |
| 8067 unresolved_class.token_pos(), | 8067 unresolved_class.token_pos(), |
| 8068 finalization, | 8068 unresolved_class_name, |
| 8069 "cannot resolve class '%s'", | 8069 finalization >= ClassFinalizer::kCanonicalizeExpression ? |
| 8070 unresolved_class_name.ToCString()); | 8070 NULL : &error); |
| 8071 return; | 8071 if (!error.IsNull()) { |
| 8072 *type = ClassFinalizer::NewFinalizedMalformedType( |
| 8073 error, |
| 8074 scope_class, |
| 8075 unresolved_class.token_pos(), |
| 8076 finalization, |
| 8077 "cannot resolve class '%s'", |
| 8078 unresolved_class_name.ToCString()); |
| 8079 return; |
| 8080 } |
| 8072 } | 8081 } |
| 8073 } else { | 8082 } else { |
| 8074 LibraryPrefix& lib_prefix = | 8083 LibraryPrefix& lib_prefix = |
| 8075 LibraryPrefix::Handle(unresolved_class.library_prefix()); | 8084 LibraryPrefix::Handle(unresolved_class.library_prefix()); |
| 8076 // Resolve class name in the scope of the library prefix. | 8085 // Resolve class name in the scope of the library prefix. |
| 8077 Error& error = Error::Handle(); | 8086 Error& error = Error::Handle(); |
| 8078 // If we finalize a type expression, as opposed to a type annotation, we | 8087 // If we finalize a type expression, as opposed to a type annotation, we |
| 8079 // tell the resolver (by passing NULL) to immediately report an ambiguous | 8088 // tell the resolver (by passing NULL) to immediately report an ambiguous |
| 8080 // type as a compile time error. | 8089 // type as a compile time error. |
| 8081 resolved_type_class = ResolveClassInPrefixScope( | 8090 resolved_type_class = ResolveClassInPrefixScope( |
| (...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8523 import = library_.ImportAt(i); | 8532 import = library_.ImportAt(i); |
| 8524 imported_obj = LookupNameInImport(isolate(), import, name); | 8533 imported_obj = LookupNameInImport(isolate(), import, name); |
| 8525 if (!imported_obj.IsNull()) { | 8534 if (!imported_obj.IsNull()) { |
| 8526 lib ^= import.library(); | 8535 lib ^= import.library(); |
| 8527 if (!first_lib_url.IsNull()) { | 8536 if (!first_lib_url.IsNull()) { |
| 8528 // Found duplicate definition. | 8537 // Found duplicate definition. |
| 8529 Error& ambiguous_ref_error = Error::Handle(); | 8538 Error& ambiguous_ref_error = Error::Handle(); |
| 8530 if (first_lib_url.raw() == lib.url()) { | 8539 if (first_lib_url.raw() == lib.url()) { |
| 8531 ambiguous_ref_error = FormatErrorMsg( | 8540 ambiguous_ref_error = FormatErrorMsg( |
| 8532 script_, ident_pos, "Error", | 8541 script_, ident_pos, "Error", |
| 8533 "ambiguous reference: " | 8542 "ambiguous reference to '%s', " |
| 8534 "'%s' as library '%s' is imported multiple times", | 8543 "as library '%s' is imported multiple times", |
| 8535 name.ToCString(), | 8544 name.ToCString(), |
| 8536 first_lib_url.ToCString()); | 8545 first_lib_url.ToCString()); |
| 8537 } else { | 8546 } else { |
| 8538 ambiguous_ref_error = FormatErrorMsg( | 8547 ambiguous_ref_error = FormatErrorMsg( |
| 8539 script_, ident_pos, "Error", | 8548 script_, ident_pos, "Error", |
| 8540 "ambiguous reference: " | 8549 "ambiguous reference: " |
| 8541 "'%s' is defined in library '%s' and also in '%s'", | 8550 "'%s' is defined in library '%s' and also in '%s'", |
| 8542 name.ToCString(), | 8551 name.ToCString(), |
| 8543 first_lib_url.ToCString(), | 8552 first_lib_url.ToCString(), |
| 8544 String::Handle(lib.url()).ToCString()); | 8553 String::Handle(lib.url()).ToCString()); |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8843 // In production mode, malformed type arguments are mapped to dynamic. | 8852 // In production mode, malformed type arguments are mapped to dynamic. |
| 8844 // In checked mode, a type with malformed type arguments is malformed. | 8853 // In checked mode, a type with malformed type arguments is malformed. |
| 8845 if (FLAG_enable_type_checks && !malformed_error.IsNull()) { | 8854 if (FLAG_enable_type_checks && !malformed_error.IsNull()) { |
| 8846 Type& parameterized_type = Type::Handle(isolate()); | 8855 Type& parameterized_type = Type::Handle(isolate()); |
| 8847 parameterized_type ^= type.raw(); | 8856 parameterized_type ^= type.raw(); |
| 8848 parameterized_type.set_type_class( | 8857 parameterized_type.set_type_class( |
| 8849 Class::Handle(isolate(), Object::dynamic_class())); | 8858 Class::Handle(isolate(), Object::dynamic_class())); |
| 8850 parameterized_type.set_arguments(Object::null_abstract_type_arguments()); | 8859 parameterized_type.set_arguments(Object::null_abstract_type_arguments()); |
| 8851 parameterized_type.set_malformed_error(malformed_error); | 8860 parameterized_type.set_malformed_error(malformed_error); |
| 8852 } | 8861 } |
| 8853 if (finalization >= ClassFinalizer::kTryResolve) { | 8862 if (finalization >= ClassFinalizer::kResolveTypeParameters) { |
| 8854 ResolveTypeFromClass(current_class(), finalization, &type); | 8863 ResolveTypeFromClass(current_class(), finalization, &type); |
| 8855 if (finalization >= ClassFinalizer::kCanonicalize) { | 8864 if (finalization >= ClassFinalizer::kCanonicalize) { |
| 8856 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization); | 8865 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization); |
| 8857 } | 8866 } |
| 8858 } | 8867 } |
| 8859 return type.raw(); | 8868 return type.raw(); |
| 8860 } | 8869 } |
| 8861 | 8870 |
| 8862 | 8871 |
| 8863 void Parser::CheckConstructorCallTypeArguments( | 8872 void Parser::CheckConstructorCallTypeArguments( |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8946 // Allocate and initialize the const list at compile time. | 8955 // Allocate and initialize the const list at compile time. |
| 8947 Array& const_list = | 8956 Array& const_list = |
| 8948 Array::ZoneHandle(Array::New(element_list.length(), Heap::kOld)); | 8957 Array::ZoneHandle(Array::New(element_list.length(), Heap::kOld)); |
| 8949 const_list.SetTypeArguments( | 8958 const_list.SetTypeArguments( |
| 8950 AbstractTypeArguments::Handle(type_arguments.Canonicalize())); | 8959 AbstractTypeArguments::Handle(type_arguments.Canonicalize())); |
| 8951 Error& malformed_error = Error::Handle(); | 8960 Error& malformed_error = Error::Handle(); |
| 8952 for (int i = 0; i < element_list.length(); i++) { | 8961 for (int i = 0; i < element_list.length(); i++) { |
| 8953 AstNode* elem = element_list[i]; | 8962 AstNode* elem = element_list[i]; |
| 8954 // Arguments have been evaluated to a literal value already. | 8963 // Arguments have been evaluated to a literal value already. |
| 8955 ASSERT(elem->IsLiteralNode()); | 8964 ASSERT(elem->IsLiteralNode()); |
| 8965 ASSERT(!is_top_level_); // We cannot check unresolved types. |
| 8956 if (FLAG_enable_type_checks && | 8966 if (FLAG_enable_type_checks && |
| 8957 !element_type.IsDynamicType() && | 8967 !element_type.IsDynamicType() && |
| 8958 (!elem->AsLiteralNode()->literal().IsNull() && | 8968 (!elem->AsLiteralNode()->literal().IsNull() && |
| 8959 !elem->AsLiteralNode()->literal().IsInstanceOf( | 8969 !elem->AsLiteralNode()->literal().IsInstanceOf( |
| 8960 element_type, TypeArguments::Handle(), &malformed_error))) { | 8970 element_type, TypeArguments::Handle(), &malformed_error))) { |
| 8961 // If the failure is due to a malformed type error, display it instead. | 8971 // If the failure is due to a malformed type error, display it instead. |
| 8962 if (!malformed_error.IsNull()) { | 8972 if (!malformed_error.IsNull()) { |
| 8963 ErrorMsg(malformed_error); | 8973 ErrorMsg(malformed_error); |
| 8964 } else { | 8974 } else { |
| 8965 ErrorMsg(elem->AsLiteralNode()->token_pos(), | 8975 ErrorMsg(elem->AsLiteralNode()->token_pos(), |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9142 // The resulting immutable map object is returned as a literal. | 9152 // The resulting immutable map object is returned as a literal. |
| 9143 | 9153 |
| 9144 // First, create the canonicalized key-value pair array. | 9154 // First, create the canonicalized key-value pair array. |
| 9145 Array& key_value_array = | 9155 Array& key_value_array = |
| 9146 Array::ZoneHandle(Array::New(kv_pairs_list.length(), Heap::kOld)); | 9156 Array::ZoneHandle(Array::New(kv_pairs_list.length(), Heap::kOld)); |
| 9147 Error& malformed_error = Error::Handle(); | 9157 Error& malformed_error = Error::Handle(); |
| 9148 for (int i = 0; i < kv_pairs_list.length(); i++) { | 9158 for (int i = 0; i < kv_pairs_list.length(); i++) { |
| 9149 AstNode* arg = kv_pairs_list[i]; | 9159 AstNode* arg = kv_pairs_list[i]; |
| 9150 // Arguments have been evaluated to a literal value already. | 9160 // Arguments have been evaluated to a literal value already. |
| 9151 ASSERT(arg->IsLiteralNode()); | 9161 ASSERT(arg->IsLiteralNode()); |
| 9162 ASSERT(!is_top_level_); // We cannot check unresolved types. |
| 9152 if (FLAG_enable_type_checks && | 9163 if (FLAG_enable_type_checks && |
| 9153 ((i % 2) == 1) && // Check values only, not keys. | 9164 ((i % 2) == 1) && // Check values only, not keys. |
| 9154 !value_type.IsDynamicType() && | 9165 !value_type.IsDynamicType() && |
| 9155 (!arg->AsLiteralNode()->literal().IsNull() && | 9166 (!arg->AsLiteralNode()->literal().IsNull() && |
| 9156 !arg->AsLiteralNode()->literal().IsInstanceOf( | 9167 !arg->AsLiteralNode()->literal().IsInstanceOf( |
| 9157 value_type, TypeArguments::Handle(), &malformed_error))) { | 9168 value_type, TypeArguments::Handle(), &malformed_error))) { |
| 9158 // If the failure is due to a malformed type error, display it instead. | 9169 // If the failure is due to a malformed type error, display it instead. |
| 9159 if (!malformed_error.IsNull()) { | 9170 if (!malformed_error.IsNull()) { |
| 9160 ErrorMsg(malformed_error); | 9171 ErrorMsg(malformed_error); |
| 9161 } else { | 9172 } else { |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9298 AbstractType& type = AbstractType::Handle( | 9309 AbstractType& type = AbstractType::Handle( |
| 9299 ParseType(ClassFinalizer::kCanonicalizeExpression)); | 9310 ParseType(ClassFinalizer::kCanonicalizeExpression)); |
| 9300 // In case the type is malformed, throw a dynamic type error after finishing | 9311 // In case the type is malformed, throw a dynamic type error after finishing |
| 9301 // parsing the instance creation expression. | 9312 // parsing the instance creation expression. |
| 9302 if (!type.IsMalformed() && (type.IsTypeParameter() || type.IsDynamicType())) { | 9313 if (!type.IsMalformed() && (type.IsTypeParameter() || type.IsDynamicType())) { |
| 9303 // Replace the type with a malformed type. | 9314 // Replace the type with a malformed type. |
| 9304 type = ClassFinalizer::NewFinalizedMalformedType( | 9315 type = ClassFinalizer::NewFinalizedMalformedType( |
| 9305 Error::Handle(), // No previous error. | 9316 Error::Handle(), // No previous error. |
| 9306 current_class(), | 9317 current_class(), |
| 9307 type_pos, | 9318 type_pos, |
| 9308 ClassFinalizer::kTryResolve, // No compile-time error. | 9319 ClassFinalizer::kResolveTypeParameters, // No compile-time error. |
| 9309 "%s'%s' cannot be instantiated", | 9320 "%s'%s' cannot be instantiated", |
| 9310 type.IsTypeParameter() ? "type parameter " : "", | 9321 type.IsTypeParameter() ? "type parameter " : "", |
| 9311 type.IsTypeParameter() ? | 9322 type.IsTypeParameter() ? |
| 9312 String::Handle(type.UserVisibleName()).ToCString() : "dynamic"); | 9323 String::Handle(type.UserVisibleName()).ToCString() : "dynamic"); |
| 9313 } | 9324 } |
| 9314 | 9325 |
| 9315 // The grammar allows for an optional ('.' identifier)? after the type, which | 9326 // The grammar allows for an optional ('.' identifier)? after the type, which |
| 9316 // is a named constructor. Note that ParseType(kMustResolve) above will not | 9327 // is a named constructor. Note that ParseType(kMustResolve) above will not |
| 9317 // consume it as part of a misinterpreted qualified identifier, because only a | 9328 // consume it as part of a misinterpreted qualified identifier, because only a |
| 9318 // valid library prefix is accepted as qualifier. | 9329 // valid library prefix is accepted as qualifier. |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9364 if (constructor.IsNull()) { | 9375 if (constructor.IsNull()) { |
| 9365 const String& external_constructor_name = | 9376 const String& external_constructor_name = |
| 9366 (named_constructor ? constructor_name : type_class_name); | 9377 (named_constructor ? constructor_name : type_class_name); |
| 9367 // Replace the type with a malformed type and compile a throw or report a | 9378 // Replace the type with a malformed type and compile a throw or report a |
| 9368 // compile-time error if the constructor is const. | 9379 // compile-time error if the constructor is const. |
| 9369 if (is_const) { | 9380 if (is_const) { |
| 9370 type = ClassFinalizer::NewFinalizedMalformedType( | 9381 type = ClassFinalizer::NewFinalizedMalformedType( |
| 9371 Error::Handle(), // No previous error. | 9382 Error::Handle(), // No previous error. |
| 9372 current_class(), | 9383 current_class(), |
| 9373 call_pos, | 9384 call_pos, |
| 9374 ClassFinalizer::kTryResolve, // No compile-time error. | 9385 ClassFinalizer::kResolveTypeParameters, // No compile-time error. |
| 9375 "class '%s' has no constructor or factory named '%s'", | 9386 "class '%s' has no constructor or factory named '%s'", |
| 9376 String::Handle(type_class.Name()).ToCString(), | 9387 String::Handle(type_class.Name()).ToCString(), |
| 9377 external_constructor_name.ToCString()); | 9388 external_constructor_name.ToCString()); |
| 9378 const Error& error = Error::Handle(type.malformed_error()); | 9389 const Error& error = Error::Handle(type.malformed_error()); |
| 9379 ErrorMsg(error); | 9390 ErrorMsg(error); |
| 9380 } | 9391 } |
| 9381 return ThrowNoSuchMethodError(call_pos, | 9392 return ThrowNoSuchMethodError(call_pos, |
| 9382 type_class, | 9393 type_class, |
| 9383 external_constructor_name, | 9394 external_constructor_name, |
| 9384 InvocationMirror::kConstructor, | 9395 InvocationMirror::kConstructor, |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9475 arguments)); | 9486 arguments)); |
| 9476 if (constructor_result.IsUnhandledException()) { | 9487 if (constructor_result.IsUnhandledException()) { |
| 9477 new_object = GenerateRethrow(new_pos, constructor_result); | 9488 new_object = GenerateRethrow(new_pos, constructor_result); |
| 9478 } else { | 9489 } else { |
| 9479 const Instance& const_instance = Instance::Cast(constructor_result); | 9490 const Instance& const_instance = Instance::Cast(constructor_result); |
| 9480 new_object = new LiteralNode(new_pos, | 9491 new_object = new LiteralNode(new_pos, |
| 9481 Instance::ZoneHandle(const_instance.raw())); | 9492 Instance::ZoneHandle(const_instance.raw())); |
| 9482 if (!type_bound.IsNull()) { | 9493 if (!type_bound.IsNull()) { |
| 9483 ASSERT(!type_bound.IsMalformed()); | 9494 ASSERT(!type_bound.IsMalformed()); |
| 9484 Error& malformed_error = Error::Handle(); | 9495 Error& malformed_error = Error::Handle(); |
| 9496 ASSERT(!is_top_level_); // We cannot check unresolved types. |
| 9485 if (!const_instance.IsInstanceOf(type_bound, | 9497 if (!const_instance.IsInstanceOf(type_bound, |
| 9486 TypeArguments::Handle(), | 9498 TypeArguments::Handle(), |
| 9487 &malformed_error)) { | 9499 &malformed_error)) { |
| 9488 type_bound = ClassFinalizer::NewFinalizedMalformedType( | 9500 type_bound = ClassFinalizer::NewFinalizedMalformedType( |
| 9489 malformed_error, | 9501 malformed_error, |
| 9490 current_class(), | 9502 current_class(), |
| 9491 new_pos, | 9503 new_pos, |
| 9492 ClassFinalizer::kTryResolve, // No compile-time error. | 9504 ClassFinalizer::kResolveTypeParameters, // No compile-time error. |
| 9493 "const factory result is not an instance of '%s'", | 9505 "const factory result is not an instance of '%s'", |
| 9494 String::Handle(type_bound.UserVisibleName()).ToCString()); | 9506 String::Handle(type_bound.UserVisibleName()).ToCString()); |
| 9495 new_object = ThrowTypeError(new_pos, type_bound); | 9507 new_object = ThrowTypeError(new_pos, type_bound); |
| 9496 } | 9508 } |
| 9497 type_bound = AbstractType::null(); | 9509 type_bound = AbstractType::null(); |
| 9498 } | 9510 } |
| 9499 } | 9511 } |
| 9500 } else { | 9512 } else { |
| 9501 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); | 9513 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); |
| 9502 if (!type_arguments.IsNull() && | 9514 if (!type_arguments.IsNull() && |
| (...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10065 void Parser::SkipQualIdent() { | 10077 void Parser::SkipQualIdent() { |
| 10066 ASSERT(IsIdentifier()); | 10078 ASSERT(IsIdentifier()); |
| 10067 ConsumeToken(); | 10079 ConsumeToken(); |
| 10068 if (CurrentToken() == Token::kPERIOD) { | 10080 if (CurrentToken() == Token::kPERIOD) { |
| 10069 ConsumeToken(); // Consume the kPERIOD token. | 10081 ConsumeToken(); // Consume the kPERIOD token. |
| 10070 ExpectIdentifier("identifier expected after '.'"); | 10082 ExpectIdentifier("identifier expected after '.'"); |
| 10071 } | 10083 } |
| 10072 } | 10084 } |
| 10073 | 10085 |
| 10074 } // namespace dart | 10086 } // namespace dart |
| OLD | NEW |