Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(288)

Side by Side Diff: runtime/vm/parser.cc

Issue 19030004: Stop resolving classes prematurely in the vm (issue 11023). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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 381 matching lines...) Expand 10 before | Expand all | Expand 10 after
3208 (follower == Token::kSET) || // Setter following a type. 3205 (follower == Token::kSET) || // Setter following a type.
3209 (follower == Token::kOPERATOR) || // Operator following a type. 3206 (follower == Token::kOPERATOR) || // Operator following a type.
3210 (Token::IsIdentifier(follower)) || // Member name following a type. 3207 (Token::IsIdentifier(follower)) || // Member name following a type.
3211 ((follower == Token::kPERIOD) && // Qualified class name of type, 3208 ((follower == Token::kPERIOD) && // Qualified class name of type,
3212 (LookaheadToken(3) != Token::kLPAREN))) { // but not a named constr. 3209 (LookaheadToken(3) != Token::kLPAREN))) { // but not a named constr.
3213 ASSERT(is_top_level_); 3210 ASSERT(is_top_level_);
3214 // The declared type of fields is never ignored, even in unchecked mode, 3211 // The declared type of fields is never ignored, even in unchecked mode,
3215 // because getters and setters could be closurized at some time (not 3212 // because getters and setters could be closurized at some time (not
3216 // supported yet). 3213 // supported yet).
3217 member.type = &AbstractType::ZoneHandle( 3214 member.type = &AbstractType::ZoneHandle(
3218 ParseType(ClassFinalizer::kTryResolve)); 3215 ParseType(ClassFinalizer::kResolveTypeParameters));
3219 } 3216 }
3220 } 3217 }
3221 } 3218 }
3222 3219
3223 // Optionally parse a (possibly named) constructor name or factory. 3220 // Optionally parse a (possibly named) constructor name or factory.
3224 if (IsIdentifier() && 3221 if (IsIdentifier() &&
3225 (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) { 3222 (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) {
3226 member.name_pos = TokenPos(); 3223 member.name_pos = TokenPos();
3227 member.name = CurrentLiteral(); // Unqualified identifier. 3224 member.name = CurrentLiteral(); // Unqualified identifier.
3228 ConsumeToken(); 3225 ConsumeToken();
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
3457 } 3454 }
3458 // We do not check that the bounds are repeated. We use the original ones. 3455 // We do not check that the bounds are repeated. We use the original ones.
3459 // TODO(regis): Should we check? 3456 // TODO(regis): Should we check?
3460 } 3457 }
3461 cls.set_type_parameters(orig_type_parameters); 3458 cls.set_type_parameters(orig_type_parameters);
3462 } 3459 }
3463 AbstractType& super_type = Type::Handle(); 3460 AbstractType& super_type = Type::Handle();
3464 if (CurrentToken() == Token::kEXTENDS) { 3461 if (CurrentToken() == Token::kEXTENDS) {
3465 ConsumeToken(); 3462 ConsumeToken();
3466 const intptr_t type_pos = TokenPos(); 3463 const intptr_t type_pos = TokenPos();
3467 super_type = ParseType(ClassFinalizer::kTryResolve); 3464 super_type = ParseType(ClassFinalizer::kResolveTypeParameters);
3468 if (super_type.IsTypeParameter()) { 3465 if (super_type.IsTypeParameter()) {
3469 ErrorMsg(type_pos, 3466 ErrorMsg(type_pos,
3470 "class '%s' may not extend type parameter '%s'", 3467 "class '%s' may not extend type parameter '%s'",
3471 class_name.ToCString(), 3468 class_name.ToCString(),
3472 String::Handle(super_type.UserVisibleName()).ToCString()); 3469 String::Handle(super_type.UserVisibleName()).ToCString());
3473 } 3470 }
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) { 3471 if (CurrentToken() == Token::kWITH) {
3480 super_type = ParseMixins(super_type); 3472 super_type = ParseMixins(super_type);
3481 } 3473 }
3482 } else { 3474 } else {
3483 // No extends clause: implicitly extend Object, unless Object itself. 3475 // No extends clause: implicitly extend Object, unless Object itself.
3484 if (!cls.IsObjectClass()) { 3476 if (!cls.IsObjectClass()) {
3485 super_type = Type::ObjectType(); 3477 super_type = Type::ObjectType();
3486 } 3478 }
3487 } 3479 }
3488 ASSERT(!super_type.IsNull() || cls.IsObjectClass()); 3480 ASSERT(!super_type.IsNull() || cls.IsObjectClass());
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
3664 3656
3665 ExpectToken(Token::kASSIGN); 3657 ExpectToken(Token::kASSIGN);
3666 3658
3667 if (CurrentToken() == Token::kABSTRACT) { 3659 if (CurrentToken() == Token::kABSTRACT) {
3668 mixin_application.set_is_abstract(); 3660 mixin_application.set_is_abstract();
3669 ConsumeToken(); 3661 ConsumeToken();
3670 } 3662 }
3671 3663
3672 const intptr_t type_pos = TokenPos(); 3664 const intptr_t type_pos = TokenPos();
3673 AbstractType& type = 3665 AbstractType& type =
3674 AbstractType::Handle(ParseType(ClassFinalizer::kTryResolve)); 3666 AbstractType::Handle(ParseType(ClassFinalizer::kResolveTypeParameters));
3675 if (type.IsTypeParameter()) { 3667 if (type.IsTypeParameter()) {
3676 ErrorMsg(type_pos, 3668 ErrorMsg(type_pos,
3677 "class '%s' may not extend type parameter '%s'", 3669 "class '%s' may not extend type parameter '%s'",
3678 class_name.ToCString(), 3670 class_name.ToCString(),
3679 String::Handle(type.UserVisibleName()).ToCString()); 3671 String::Handle(type.UserVisibleName()).ToCString());
3680 } 3672 }
3681 3673
3682 if (CurrentToken() != Token::kWITH) { 3674 if (CurrentToken() != Token::kWITH) {
3683 ErrorMsg("mixin application 'with Type' expected"); 3675 ErrorMsg("mixin application 'with Type' expected");
3684 } 3676 }
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
3780 script_, 3772 script_,
3781 alias_name_pos)); 3773 alias_name_pos));
3782 library_.AddClass(function_type_alias); 3774 library_.AddClass(function_type_alias);
3783 set_current_class(function_type_alias); 3775 set_current_class(function_type_alias);
3784 // Parse the type parameters of the function type. 3776 // Parse the type parameters of the function type.
3785 ParseTypeParameters(function_type_alias); 3777 ParseTypeParameters(function_type_alias);
3786 // At this point, the type parameters have been parsed, so we can resolve the 3778 // At this point, the type parameters have been parsed, so we can resolve the
3787 // result type. 3779 // result type.
3788 if (!result_type.IsNull()) { 3780 if (!result_type.IsNull()) {
3789 ResolveTypeFromClass(function_type_alias, 3781 ResolveTypeFromClass(function_type_alias,
3790 ClassFinalizer::kTryResolve, 3782 ClassFinalizer::kResolveTypeParameters,
3791 &result_type); 3783 &result_type);
3792 } 3784 }
3793 // Parse the formal parameters of the function type. 3785 // Parse the formal parameters of the function type.
3794 if (CurrentToken() != Token::kLPAREN) { 3786 if (CurrentToken() != Token::kLPAREN) {
3795 ErrorMsg("formal parameter list expected"); 3787 ErrorMsg("formal parameter list expected");
3796 } 3788 }
3797 ParamList func_params; 3789 ParamList func_params;
3798 3790
3799 // Add implicit closure object parameter. 3791 // Add implicit closure object parameter.
3800 func_params.AddFinalParameter( 3792 func_params.AddFinalParameter(
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
3977 const TypeArguments& type_parameters = 3969 const TypeArguments& type_parameters =
3978 TypeArguments::Handle(NewTypeArguments(type_parameters_array)); 3970 TypeArguments::Handle(NewTypeArguments(type_parameters_array));
3979 cls.set_type_parameters(type_parameters); 3971 cls.set_type_parameters(type_parameters);
3980 // Try to resolve the upper bounds, which will at least resolve the 3972 // Try to resolve the upper bounds, which will at least resolve the
3981 // referenced type parameters. 3973 // referenced type parameters.
3982 const intptr_t num_types = type_parameters.Length(); 3974 const intptr_t num_types = type_parameters.Length();
3983 for (intptr_t i = 0; i < num_types; i++) { 3975 for (intptr_t i = 0; i < num_types; i++) {
3984 type_parameter ^= type_parameters.TypeAt(i); 3976 type_parameter ^= type_parameters.TypeAt(i);
3985 type_parameter_bound = type_parameter.bound(); 3977 type_parameter_bound = type_parameter.bound();
3986 ResolveTypeFromClass(cls, 3978 ResolveTypeFromClass(cls,
3987 ClassFinalizer::kTryResolve, 3979 ClassFinalizer::kResolveTypeParameters,
3988 &type_parameter_bound); 3980 &type_parameter_bound);
3989 type_parameter.set_bound(type_parameter_bound); 3981 type_parameter.set_bound(type_parameter_bound);
3990 } 3982 }
3991 } 3983 }
3992 } 3984 }
3993 3985
3994 3986
3995 RawAbstractTypeArguments* Parser::ParseTypeArguments( 3987 RawAbstractTypeArguments* Parser::ParseTypeArguments(
3996 Error* malformed_error, 3988 Error* malformed_error,
3997 ClassFinalizer::FinalizationKind finalization) { 3989 ClassFinalizer::FinalizationKind finalization) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
4039 // First get all the interfaces already implemented by class. 4031 // First get all the interfaces already implemented by class.
4040 Array& cls_interfaces = Array::Handle(cls.interfaces()); 4032 Array& cls_interfaces = Array::Handle(cls.interfaces());
4041 for (intptr_t i = 0; i < cls_interfaces.Length(); i++) { 4033 for (intptr_t i = 0; i < cls_interfaces.Length(); i++) {
4042 interface ^= cls_interfaces.At(i); 4034 interface ^= cls_interfaces.At(i);
4043 all_interfaces.Add(interface); 4035 all_interfaces.Add(interface);
4044 } 4036 }
4045 // Now parse and add the new interfaces. 4037 // Now parse and add the new interfaces.
4046 do { 4038 do {
4047 ConsumeToken(); 4039 ConsumeToken();
4048 intptr_t interface_pos = TokenPos(); 4040 intptr_t interface_pos = TokenPos();
4049 interface = ParseType(ClassFinalizer::kTryResolve); 4041 interface = ParseType(ClassFinalizer::kResolveTypeParameters);
4050 if (interface.IsTypeParameter()) { 4042 if (interface.IsTypeParameter()) {
4051 ErrorMsg(interface_pos, 4043 ErrorMsg(interface_pos,
4052 "type parameter '%s' may not be used in interface list", 4044 "type parameter '%s' may not be used in interface list",
4053 String::Handle(interface.UserVisibleName()).ToCString()); 4045 String::Handle(interface.UserVisibleName()).ToCString());
4054 } 4046 }
4055 if (interface.IsDynamicType()) {
4056 ErrorMsg(interface_pos, "'dynamic' may not be used in interface list");
4057 }
4058 all_interfaces.Add(interface); 4047 all_interfaces.Add(interface);
4059 } while (CurrentToken() == Token::kCOMMA); 4048 } while (CurrentToken() == Token::kCOMMA);
4060 cls_interfaces = Array::MakeArray(all_interfaces); 4049 cls_interfaces = Array::MakeArray(all_interfaces);
4061 cls.set_interfaces(cls_interfaces); 4050 cls.set_interfaces(cls_interfaces);
4062 } 4051 }
4063 4052
4064 4053
4065 RawAbstractType* Parser::ParseMixins(const AbstractType& super_type) { 4054 RawAbstractType* Parser::ParseMixins(const AbstractType& super_type) {
4066 TRACE_PARSER("ParseMixins"); 4055 TRACE_PARSER("ParseMixins");
4067 ASSERT(CurrentToken() == Token::kWITH); 4056 ASSERT(CurrentToken() == Token::kWITH);
4068 4057
4069 const GrowableObjectArray& mixin_apps = 4058 const GrowableObjectArray& mixin_apps =
4070 GrowableObjectArray::Handle(GrowableObjectArray::New()); 4059 GrowableObjectArray::Handle(GrowableObjectArray::New());
4071 AbstractType& mixin_type = AbstractType::Handle(); 4060 AbstractType& mixin_type = AbstractType::Handle();
4072 AbstractTypeArguments& mixin_type_arguments = 4061 AbstractTypeArguments& mixin_type_arguments =
4073 AbstractTypeArguments::Handle(); 4062 AbstractTypeArguments::Handle();
4074 Class& mixin_application = Class::Handle(); 4063 Class& mixin_application = Class::Handle();
4075 Type& mixin_application_type = Type::Handle(); 4064 Type& mixin_application_type = Type::Handle();
4076 Type& mixin_super_type = Type::Handle(); 4065 Type& mixin_super_type = Type::Handle();
4077 ASSERT(super_type.IsType()); 4066 ASSERT(super_type.IsType());
4078 mixin_super_type ^= super_type.raw(); 4067 mixin_super_type ^= super_type.raw();
4079 Array& mixin_application_interfaces = Array::Handle(); 4068 Array& mixin_application_interfaces = Array::Handle();
4080 do { 4069 do {
4081 ConsumeToken(); 4070 ConsumeToken();
4082 const intptr_t mixin_pos = TokenPos(); 4071 const intptr_t mixin_pos = TokenPos();
4083 mixin_type = ParseType(ClassFinalizer::kTryResolve); 4072 mixin_type = ParseType(ClassFinalizer::kResolveTypeParameters);
4084 if (mixin_type.IsTypeParameter()) { 4073 if (mixin_type.IsTypeParameter()) {
4085 ErrorMsg(mixin_pos, 4074 ErrorMsg(mixin_pos,
4086 "mixin type '%s' may not be a type parameter", 4075 "mixin type '%s' may not be a type parameter",
4087 String::Handle(mixin_type.UserVisibleName()).ToCString()); 4076 String::Handle(mixin_type.UserVisibleName()).ToCString());
4088 } 4077 }
4089 4078
4090 // The name of the mixin application class is a combination of 4079 // The name of the mixin application class is a combination of
4091 // the superclass and mixin class. 4080 // the superclass and mixin class.
4092 String& mixin_app_name = String::Handle(); 4081 String& mixin_app_name = String::Handle();
4093 mixin_app_name = mixin_super_type.ClassName(); 4082 mixin_app_name = mixin_super_type.ClassName();
(...skipping 12 matching lines...) Expand all
4106 // class implements. This is necessary so that type tests work. 4095 // class implements. This is necessary so that type tests work.
4107 mixin_application_interfaces = Array::New(1); 4096 mixin_application_interfaces = Array::New(1);
4108 mixin_application_interfaces.SetAt(0, mixin_type); 4097 mixin_application_interfaces.SetAt(0, mixin_type);
4109 mixin_application.set_interfaces(mixin_application_interfaces); 4098 mixin_application.set_interfaces(mixin_application_interfaces);
4110 4099
4111 // For the type arguments of the mixin application type, we need 4100 // 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 4101 // 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 4102 // to get the copy is to rewind the parser, parse the mixin type
4114 // again and steal its type arguments. 4103 // again and steal its type arguments.
4115 SetPosition(mixin_pos); 4104 SetPosition(mixin_pos);
4116 mixin_type = ParseType(ClassFinalizer::kTryResolve); 4105 mixin_type = ParseType(ClassFinalizer::kResolveTypeParameters);
4117 mixin_type_arguments = mixin_type.arguments(); 4106 mixin_type_arguments = mixin_type.arguments();
4118 4107
4119 mixin_application_type = Type::New(mixin_application, 4108 mixin_application_type = Type::New(mixin_application,
4120 mixin_type_arguments, 4109 mixin_type_arguments,
4121 mixin_pos); 4110 mixin_pos);
4122 mixin_super_type = mixin_application_type.raw(); 4111 mixin_super_type = mixin_application_type.raw();
4123 mixin_apps.Add(mixin_application_type); 4112 mixin_apps.Add(mixin_application_type);
4124 } while (CurrentToken() == Token::kCOMMA); 4113 } while (CurrentToken() == Token::kCOMMA);
4125 return MixinAppType::New(super_type, 4114 return MixinAppType::New(super_type,
4126 Array::Handle(Array::MakeArray(mixin_apps))); 4115 Array::Handle(Array::MakeArray(mixin_apps)));
4127 } 4116 }
4128 4117
4129 4118
4130 void Parser::ParseTopLevelVariable(TopLevel* top_level, 4119 void Parser::ParseTopLevelVariable(TopLevel* top_level,
4131 intptr_t metadata_pos) { 4120 intptr_t metadata_pos) {
4132 TRACE_PARSER("ParseTopLevelVariable"); 4121 TRACE_PARSER("ParseTopLevelVariable");
4133 const bool is_const = (CurrentToken() == Token::kCONST); 4122 const bool is_const = (CurrentToken() == Token::kCONST);
4134 // Const fields are implicitly final. 4123 // Const fields are implicitly final.
4135 const bool is_final = is_const || (CurrentToken() == Token::kFINAL); 4124 const bool is_final = is_const || (CurrentToken() == Token::kFINAL);
4136 const bool is_static = true; 4125 const bool is_static = true;
4137 const AbstractType& type = 4126 const AbstractType& type =
4138 AbstractType::ZoneHandle(ParseConstFinalVarOrType( 4127 AbstractType::ZoneHandle(ParseConstFinalVarOrType(
4139 FLAG_enable_type_checks ? ClassFinalizer::kTryResolve : 4128 FLAG_enable_type_checks ? ClassFinalizer::kResolveTypeParameters :
4140 ClassFinalizer::kIgnore)); 4129 ClassFinalizer::kIgnore));
4141 Field& field = Field::Handle(); 4130 Field& field = Field::Handle();
4142 Function& getter = Function::Handle(); 4131 Function& getter = Function::Handle();
4143 while (true) { 4132 while (true) {
4144 const intptr_t name_pos = TokenPos(); 4133 const intptr_t name_pos = TokenPos();
4145 String& var_name = *ExpectIdentifier("variable name expected"); 4134 String& var_name = *ExpectIdentifier("variable name expected");
4146 4135
4147 if (library_.LookupLocalObject(var_name) != Object::null()) { 4136 if (library_.LookupLocalObject(var_name) != Object::null()) {
4148 ErrorMsg(name_pos, "'%s' is already defined", var_name.ToCString()); 4137 ErrorMsg(name_pos, "'%s' is already defined", var_name.ToCString());
4149 } 4138 }
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
4227 ConsumeToken(); 4216 ConsumeToken();
4228 is_external = true; 4217 is_external = true;
4229 } 4218 }
4230 if (CurrentToken() == Token::kVOID) { 4219 if (CurrentToken() == Token::kVOID) {
4231 ConsumeToken(); 4220 ConsumeToken();
4232 result_type = Type::VoidType(); 4221 result_type = Type::VoidType();
4233 } else { 4222 } else {
4234 // Parse optional type. 4223 // Parse optional type.
4235 if ((CurrentToken() == Token::kIDENT) && 4224 if ((CurrentToken() == Token::kIDENT) &&
4236 (LookaheadToken(1) != Token::kLPAREN)) { 4225 (LookaheadToken(1) != Token::kLPAREN)) {
4237 result_type = ParseType(ClassFinalizer::kTryResolve); 4226 result_type = ParseType(ClassFinalizer::kResolveTypeParameters);
4238 } 4227 }
4239 } 4228 }
4240 const intptr_t name_pos = TokenPos(); 4229 const intptr_t name_pos = TokenPos();
4241 const String& func_name = *ExpectIdentifier("function name expected"); 4230 const String& func_name = *ExpectIdentifier("function name expected");
4242 4231
4243 bool found = library_.LookupLocalObject(func_name) != Object::null(); 4232 bool found = library_.LookupLocalObject(func_name) != Object::null();
4244 if (found && !is_patch) { 4233 if (found && !is_patch) {
4245 ErrorMsg(name_pos, "'%s' is already defined", func_name.ToCString()); 4234 ErrorMsg(name_pos, "'%s' is already defined", func_name.ToCString());
4246 } else if (!found && is_patch) { 4235 } else if (!found && is_patch) {
4247 ErrorMsg(name_pos, "missing '%s' cannot be patched", func_name.ToCString()); 4236 ErrorMsg(name_pos, "missing '%s' cannot be patched", func_name.ToCString());
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
4321 bool is_getter = (CurrentToken() == Token::kGET); 4310 bool is_getter = (CurrentToken() == Token::kGET);
4322 if (CurrentToken() == Token::kGET || 4311 if (CurrentToken() == Token::kGET ||
4323 CurrentToken() == Token::kSET) { 4312 CurrentToken() == Token::kSET) {
4324 ConsumeToken(); 4313 ConsumeToken();
4325 result_type = Type::DynamicType(); 4314 result_type = Type::DynamicType();
4326 } else { 4315 } else {
4327 if (CurrentToken() == Token::kVOID) { 4316 if (CurrentToken() == Token::kVOID) {
4328 ConsumeToken(); 4317 ConsumeToken();
4329 result_type = Type::VoidType(); 4318 result_type = Type::VoidType();
4330 } else { 4319 } else {
4331 result_type = ParseType(ClassFinalizer::kTryResolve); 4320 result_type = ParseType(ClassFinalizer::kResolveTypeParameters);
4332 } 4321 }
4333 is_getter = (CurrentToken() == Token::kGET); 4322 is_getter = (CurrentToken() == Token::kGET);
4334 if (CurrentToken() == Token::kGET || CurrentToken() == Token::kSET) { 4323 if (CurrentToken() == Token::kGET || CurrentToken() == Token::kSET) {
4335 ConsumeToken(); 4324 ConsumeToken();
4336 } else { 4325 } else {
4337 UnexpectedToken(); 4326 UnexpectedToken();
4338 } 4327 }
4339 } 4328 }
4340 const intptr_t name_pos = TokenPos(); 4329 const intptr_t name_pos = TokenPos();
4341 const String* field_name = ExpectIdentifier("accessor name expected"); 4330 const String* field_name = ExpectIdentifier("accessor name expected");
(...skipping 975 matching lines...) Expand 10 before | Expand all | Expand 10 after
5317 } while (nesting_level > 0); 5306 } while (nesting_level > 0);
5318 if (nesting_level < 0) { 5307 if (nesting_level < 0) {
5319 return false; 5308 return false;
5320 } 5309 }
5321 } 5310 }
5322 return true; 5311 return true;
5323 } 5312 }
5324 5313
5325 5314
5326 bool Parser::IsSimpleLiteral(const AbstractType& type, Instance* value) { 5315 bool Parser::IsSimpleLiteral(const AbstractType& type, Instance* value) {
5327 bool no_check = type.IsDynamicType(); 5316 // If the type of the const field is guaranteed to be instantiated once
5328 if ((CurrentToken() == Token::kINTEGER) && 5317 // resolved at class finalization time, and if the type of the literal is one
5329 (no_check || type.IsIntType() || type.IsNumberType())) { 5318 // of int, double, String, or bool, then preset the field with the value and
5319 // perform the type check (in checked mode only) at finalization time.
5320 if (type.IsTypeParameter() || // Always resolved at parse time.
5321 (type.arguments() != AbstractTypeArguments::null())) {
5322 return false;
5323 }
5324 if (CurrentToken() == Token::kINTEGER) {
5330 *value = CurrentIntegerLiteral(); 5325 *value = CurrentIntegerLiteral();
5331 return true; 5326 return true;
5332 } else if ((CurrentToken() == Token::kDOUBLE) && 5327 } else if (CurrentToken() == Token::kDOUBLE) {
5333 (no_check || type.IsDoubleType() || type.IsNumberType())) {
5334 *value = CurrentDoubleLiteral(); 5328 *value = CurrentDoubleLiteral();
5335 return true; 5329 return true;
5336 } else if ((CurrentToken() == Token::kSTRING) && 5330 } else if (CurrentToken() == Token::kSTRING) {
5337 (no_check || type.IsStringType())) {
5338 *value = CurrentLiteral()->raw(); 5331 *value = CurrentLiteral()->raw();
5339 return true; 5332 return true;
5340 } else if ((CurrentToken() == Token::kTRUE) && 5333 } else if (CurrentToken() == Token::kTRUE) {
5341 (no_check || type.IsBoolType())) {
5342 *value = Bool::True().raw(); 5334 *value = Bool::True().raw();
5343 return true; 5335 return true;
5344 } else if ((CurrentToken() == Token::kFALSE) && 5336 } else if (CurrentToken() == Token::kFALSE) {
5345 (no_check || type.IsBoolType())) {
5346 *value = Bool::False().raw(); 5337 *value = Bool::False().raw();
5347 return true; 5338 return true;
5348 } else if (CurrentToken() == Token::kNULL) { 5339 } else if (CurrentToken() == Token::kNULL) {
5349 *value = Instance::null(); 5340 *value = Instance::null();
5350 return true; 5341 return true;
5351 } 5342 }
5352 return false; 5343 return false;
5353 } 5344 }
5354 5345
5355 5346
(...skipping 2639 matching lines...) Expand 10 before | Expand all | Expand 10 after
7995 // Resolve the given type and its type arguments from the given scope class 7986 // Resolve the given type and its type arguments from the given scope class
7996 // according to the given type finalization mode. 7987 // according to the given type finalization mode.
7997 // If the given scope class is null, use the current library, but do not try to 7988 // If the given scope class is null, use the current library, but do not try to
7998 // resolve type parameters. 7989 // resolve type parameters.
7999 // Not all involved type classes may get resolved yet, but at least the type 7990 // 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 7991 // parameters of the given class will get resolved, thereby relieving the class
8001 // finalizer from resolving type parameters out of context. 7992 // finalizer from resolving type parameters out of context.
8002 void Parser::ResolveTypeFromClass(const Class& scope_class, 7993 void Parser::ResolveTypeFromClass(const Class& scope_class,
8003 ClassFinalizer::FinalizationKind finalization, 7994 ClassFinalizer::FinalizationKind finalization,
8004 AbstractType* type) { 7995 AbstractType* type) {
8005 ASSERT(finalization >= ClassFinalizer::kTryResolve); 7996 ASSERT(finalization >= ClassFinalizer::kResolveTypeParameters);
8006 ASSERT(type != NULL); 7997 ASSERT(type != NULL);
8007 if (type->IsResolved()) { 7998 if (type->IsResolved()) {
8008 return; 7999 return;
8009 } 8000 }
8010 // Resolve class. 8001 // Resolve class.
8011 if (!type->HasResolvedTypeClass()) { 8002 if (!type->HasResolvedTypeClass()) {
8012 const UnresolvedClass& unresolved_class = 8003 const UnresolvedClass& unresolved_class =
8013 UnresolvedClass::Handle(type->unresolved_class()); 8004 UnresolvedClass::Handle(type->unresolved_class());
8014 const String& unresolved_class_name = 8005 const String& unresolved_class_name =
8015 String::Handle(unresolved_class.ident()); 8006 String::Handle(unresolved_class.ident());
(...skipping 27 matching lines...) Expand all
8043 type_parameter.token_pos(), 8034 type_parameter.token_pos(),
8044 finalization, 8035 finalization,
8045 "type parameter '%s' cannot be parameterized", 8036 "type parameter '%s' cannot be parameterized",
8046 String::Handle(type_parameter.name()).ToCString()); 8037 String::Handle(type_parameter.name()).ToCString());
8047 return; 8038 return;
8048 } 8039 }
8049 *type = type_parameter.raw(); 8040 *type = type_parameter.raw();
8050 return; 8041 return;
8051 } 8042 }
8052 } 8043 }
8053 // Resolve classname in the scope of the current library. 8044 // The referenced class may not have been parsed yet. It would be wrong
8054 Error& error = Error::Handle(); 8045 // 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 8046 if (finalization > ClassFinalizer::kResolveTypeParameters) {
8056 // tell the resolver (by passing NULL) to immediately report an ambiguous 8047 // Resolve classname in the scope of the current library.
8057 // type as a compile time error. 8048 Error& error = Error::Handle();
8058 resolved_type_class = ResolveClassInCurrentLibraryScope( 8049 // If we finalize a type expression, as opposed to a type annotation,
8059 unresolved_class.token_pos(), 8050 // we tell the resolver (by passing NULL) to immediately report an
8060 unresolved_class_name, 8051 // ambiguous type as a compile time error.
8061 finalization >= ClassFinalizer::kCanonicalizeExpression ? 8052 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(), 8053 unresolved_class.token_pos(),
8068 finalization, 8054 unresolved_class_name,
8069 "cannot resolve class '%s'", 8055 finalization >= ClassFinalizer::kCanonicalizeExpression ?
8070 unresolved_class_name.ToCString()); 8056 NULL : &error);
8071 return; 8057 if (!error.IsNull()) {
8058 *type = ClassFinalizer::NewFinalizedMalformedType(
8059 error,
8060 scope_class,
8061 unresolved_class.token_pos(),
8062 finalization,
8063 "cannot resolve class '%s'",
8064 unresolved_class_name.ToCString());
8065 return;
8066 }
8072 } 8067 }
8073 } else { 8068 } else {
8074 LibraryPrefix& lib_prefix = 8069 LibraryPrefix& lib_prefix =
8075 LibraryPrefix::Handle(unresolved_class.library_prefix()); 8070 LibraryPrefix::Handle(unresolved_class.library_prefix());
8076 // Resolve class name in the scope of the library prefix. 8071 // Resolve class name in the scope of the library prefix.
8077 Error& error = Error::Handle(); 8072 Error& error = Error::Handle();
8078 // If we finalize a type expression, as opposed to a type annotation, we 8073 // 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 8074 // tell the resolver (by passing NULL) to immediately report an ambiguous
8080 // type as a compile time error. 8075 // type as a compile time error.
8081 resolved_type_class = ResolveClassInPrefixScope( 8076 resolved_type_class = ResolveClassInPrefixScope(
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after
8523 import = library_.ImportAt(i); 8518 import = library_.ImportAt(i);
8524 imported_obj = LookupNameInImport(isolate(), import, name); 8519 imported_obj = LookupNameInImport(isolate(), import, name);
8525 if (!imported_obj.IsNull()) { 8520 if (!imported_obj.IsNull()) {
8526 lib ^= import.library(); 8521 lib ^= import.library();
8527 if (!first_lib_url.IsNull()) { 8522 if (!first_lib_url.IsNull()) {
8528 // Found duplicate definition. 8523 // Found duplicate definition.
8529 Error& ambiguous_ref_error = Error::Handle(); 8524 Error& ambiguous_ref_error = Error::Handle();
8530 if (first_lib_url.raw() == lib.url()) { 8525 if (first_lib_url.raw() == lib.url()) {
8531 ambiguous_ref_error = FormatErrorMsg( 8526 ambiguous_ref_error = FormatErrorMsg(
8532 script_, ident_pos, "Error", 8527 script_, ident_pos, "Error",
8533 "ambiguous reference: " 8528 "ambiguous reference to '%s', "
8534 "'%s' as library '%s' is imported multiple times", 8529 "as library '%s' is imported multiple times",
8535 name.ToCString(), 8530 name.ToCString(),
8536 first_lib_url.ToCString()); 8531 first_lib_url.ToCString());
8537 } else { 8532 } else {
8538 ambiguous_ref_error = FormatErrorMsg( 8533 ambiguous_ref_error = FormatErrorMsg(
8539 script_, ident_pos, "Error", 8534 script_, ident_pos, "Error",
8540 "ambiguous reference: " 8535 "ambiguous reference: "
8541 "'%s' is defined in library '%s' and also in '%s'", 8536 "'%s' is defined in library '%s' and also in '%s'",
8542 name.ToCString(), 8537 name.ToCString(),
8543 first_lib_url.ToCString(), 8538 first_lib_url.ToCString(),
8544 String::Handle(lib.url()).ToCString()); 8539 String::Handle(lib.url()).ToCString());
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
8843 // In production mode, malformed type arguments are mapped to dynamic. 8838 // In production mode, malformed type arguments are mapped to dynamic.
8844 // In checked mode, a type with malformed type arguments is malformed. 8839 // In checked mode, a type with malformed type arguments is malformed.
8845 if (FLAG_enable_type_checks && !malformed_error.IsNull()) { 8840 if (FLAG_enable_type_checks && !malformed_error.IsNull()) {
8846 Type& parameterized_type = Type::Handle(isolate()); 8841 Type& parameterized_type = Type::Handle(isolate());
8847 parameterized_type ^= type.raw(); 8842 parameterized_type ^= type.raw();
8848 parameterized_type.set_type_class( 8843 parameterized_type.set_type_class(
8849 Class::Handle(isolate(), Object::dynamic_class())); 8844 Class::Handle(isolate(), Object::dynamic_class()));
8850 parameterized_type.set_arguments(Object::null_abstract_type_arguments()); 8845 parameterized_type.set_arguments(Object::null_abstract_type_arguments());
8851 parameterized_type.set_malformed_error(malformed_error); 8846 parameterized_type.set_malformed_error(malformed_error);
8852 } 8847 }
8853 if (finalization >= ClassFinalizer::kTryResolve) { 8848 if (finalization >= ClassFinalizer::kResolveTypeParameters) {
8854 ResolveTypeFromClass(current_class(), finalization, &type); 8849 ResolveTypeFromClass(current_class(), finalization, &type);
8855 if (finalization >= ClassFinalizer::kCanonicalize) { 8850 if (finalization >= ClassFinalizer::kCanonicalize) {
8856 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization); 8851 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization);
8857 } 8852 }
8858 } 8853 }
8859 return type.raw(); 8854 return type.raw();
8860 } 8855 }
8861 8856
8862 8857
8863 void Parser::CheckConstructorCallTypeArguments( 8858 void Parser::CheckConstructorCallTypeArguments(
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after
9298 AbstractType& type = AbstractType::Handle( 9293 AbstractType& type = AbstractType::Handle(
9299 ParseType(ClassFinalizer::kCanonicalizeExpression)); 9294 ParseType(ClassFinalizer::kCanonicalizeExpression));
9300 // In case the type is malformed, throw a dynamic type error after finishing 9295 // In case the type is malformed, throw a dynamic type error after finishing
9301 // parsing the instance creation expression. 9296 // parsing the instance creation expression.
9302 if (!type.IsMalformed() && (type.IsTypeParameter() || type.IsDynamicType())) { 9297 if (!type.IsMalformed() && (type.IsTypeParameter() || type.IsDynamicType())) {
9303 // Replace the type with a malformed type. 9298 // Replace the type with a malformed type.
9304 type = ClassFinalizer::NewFinalizedMalformedType( 9299 type = ClassFinalizer::NewFinalizedMalformedType(
9305 Error::Handle(), // No previous error. 9300 Error::Handle(), // No previous error.
9306 current_class(), 9301 current_class(),
9307 type_pos, 9302 type_pos,
9308 ClassFinalizer::kTryResolve, // No compile-time error. 9303 ClassFinalizer::kResolveTypeParameters, // No compile-time error.
9309 "%s'%s' cannot be instantiated", 9304 "%s'%s' cannot be instantiated",
9310 type.IsTypeParameter() ? "type parameter " : "", 9305 type.IsTypeParameter() ? "type parameter " : "",
9311 type.IsTypeParameter() ? 9306 type.IsTypeParameter() ?
9312 String::Handle(type.UserVisibleName()).ToCString() : "dynamic"); 9307 String::Handle(type.UserVisibleName()).ToCString() : "dynamic");
9313 } 9308 }
9314 9309
9315 // The grammar allows for an optional ('.' identifier)? after the type, which 9310 // The grammar allows for an optional ('.' identifier)? after the type, which
9316 // is a named constructor. Note that ParseType(kMustResolve) above will not 9311 // is a named constructor. Note that ParseType(kMustResolve) above will not
9317 // consume it as part of a misinterpreted qualified identifier, because only a 9312 // consume it as part of a misinterpreted qualified identifier, because only a
9318 // valid library prefix is accepted as qualifier. 9313 // valid library prefix is accepted as qualifier.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
9364 if (constructor.IsNull()) { 9359 if (constructor.IsNull()) {
9365 const String& external_constructor_name = 9360 const String& external_constructor_name =
9366 (named_constructor ? constructor_name : type_class_name); 9361 (named_constructor ? constructor_name : type_class_name);
9367 // Replace the type with a malformed type and compile a throw or report a 9362 // Replace the type with a malformed type and compile a throw or report a
9368 // compile-time error if the constructor is const. 9363 // compile-time error if the constructor is const.
9369 if (is_const) { 9364 if (is_const) {
9370 type = ClassFinalizer::NewFinalizedMalformedType( 9365 type = ClassFinalizer::NewFinalizedMalformedType(
9371 Error::Handle(), // No previous error. 9366 Error::Handle(), // No previous error.
9372 current_class(), 9367 current_class(),
9373 call_pos, 9368 call_pos,
9374 ClassFinalizer::kTryResolve, // No compile-time error. 9369 ClassFinalizer::kResolveTypeParameters, // No compile-time error.
9375 "class '%s' has no constructor or factory named '%s'", 9370 "class '%s' has no constructor or factory named '%s'",
9376 String::Handle(type_class.Name()).ToCString(), 9371 String::Handle(type_class.Name()).ToCString(),
9377 external_constructor_name.ToCString()); 9372 external_constructor_name.ToCString());
9378 const Error& error = Error::Handle(type.malformed_error()); 9373 const Error& error = Error::Handle(type.malformed_error());
9379 ErrorMsg(error); 9374 ErrorMsg(error);
9380 } 9375 }
9381 return ThrowNoSuchMethodError(call_pos, 9376 return ThrowNoSuchMethodError(call_pos,
9382 type_class, 9377 type_class,
9383 external_constructor_name, 9378 external_constructor_name,
9384 InvocationMirror::kConstructor, 9379 InvocationMirror::kConstructor,
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
9482 if (!type_bound.IsNull()) { 9477 if (!type_bound.IsNull()) {
9483 ASSERT(!type_bound.IsMalformed()); 9478 ASSERT(!type_bound.IsMalformed());
9484 Error& malformed_error = Error::Handle(); 9479 Error& malformed_error = Error::Handle();
9485 if (!const_instance.IsInstanceOf(type_bound, 9480 if (!const_instance.IsInstanceOf(type_bound,
9486 TypeArguments::Handle(), 9481 TypeArguments::Handle(),
9487 &malformed_error)) { 9482 &malformed_error)) {
9488 type_bound = ClassFinalizer::NewFinalizedMalformedType( 9483 type_bound = ClassFinalizer::NewFinalizedMalformedType(
9489 malformed_error, 9484 malformed_error,
9490 current_class(), 9485 current_class(),
9491 new_pos, 9486 new_pos,
9492 ClassFinalizer::kTryResolve, // No compile-time error. 9487 ClassFinalizer::kResolveTypeParameters, // No compile-time error.
9493 "const factory result is not an instance of '%s'", 9488 "const factory result is not an instance of '%s'",
9494 String::Handle(type_bound.UserVisibleName()).ToCString()); 9489 String::Handle(type_bound.UserVisibleName()).ToCString());
9495 new_object = ThrowTypeError(new_pos, type_bound); 9490 new_object = ThrowTypeError(new_pos, type_bound);
9496 } 9491 }
9497 type_bound = AbstractType::null(); 9492 type_bound = AbstractType::null();
9498 } 9493 }
9499 } 9494 }
9500 } else { 9495 } else {
9501 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); 9496 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments);
9502 if (!type_arguments.IsNull() && 9497 if (!type_arguments.IsNull() &&
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after
10065 void Parser::SkipQualIdent() { 10060 void Parser::SkipQualIdent() {
10066 ASSERT(IsIdentifier()); 10061 ASSERT(IsIdentifier());
10067 ConsumeToken(); 10062 ConsumeToken();
10068 if (CurrentToken() == Token::kPERIOD) { 10063 if (CurrentToken() == Token::kPERIOD) {
10069 ConsumeToken(); // Consume the kPERIOD token. 10064 ConsumeToken(); // Consume the kPERIOD token.
10070 ExpectIdentifier("identifier expected after '.'"); 10065 ExpectIdentifier("identifier expected after '.'");
10071 } 10066 }
10072 } 10067 }
10073 10068
10074 } // namespace dart 10069 } // namespace dart
OLDNEW
« runtime/vm/object.cc ('K') | « runtime/vm/object.cc ('k') | tests/language/language.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698