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/object.h" | 5 #include "vm/object.h" |
6 | 6 |
7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
10 #include "vm/bigint_operations.h" | 10 #include "vm/bigint_operations.h" |
(...skipping 19 matching lines...) Expand all Loading... |
30 #include "vm/scopes.h" | 30 #include "vm/scopes.h" |
31 #include "vm/stack_frame.h" | 31 #include "vm/stack_frame.h" |
32 #include "vm/symbols.h" | 32 #include "vm/symbols.h" |
33 #include "vm/timer.h" | 33 #include "vm/timer.h" |
34 #include "vm/unicode.h" | 34 #include "vm/unicode.h" |
35 | 35 |
36 namespace dart { | 36 namespace dart { |
37 | 37 |
38 DEFINE_FLAG(bool, generate_gdb_symbols, false, | 38 DEFINE_FLAG(bool, generate_gdb_symbols, false, |
39 "Generate symbols of generated dart functions for debugging with GDB"); | 39 "Generate symbols of generated dart functions for debugging with GDB"); |
| 40 DEFINE_FLAG(bool, reject_named_argument_as_positional, false, |
| 41 "Enforce new rules for optional parameters and disallow passing of named " |
| 42 "arguments to optional positional formal parameters"); |
40 DEFINE_FLAG(bool, show_internal_names, false, | 43 DEFINE_FLAG(bool, show_internal_names, false, |
41 "Show names of internal classes (e.g. \"OneByteString\") in error messages " | 44 "Show names of internal classes (e.g. \"OneByteString\") in error messages " |
42 "instead of showing the corresponding interface names (e.g. \"String\")"); | 45 "instead of showing the corresponding interface names (e.g. \"String\")"); |
43 DECLARE_FLAG(bool, trace_compiler); | 46 DECLARE_FLAG(bool, trace_compiler); |
44 DECLARE_FLAG(bool, enable_type_checks); | 47 DECLARE_FLAG(bool, enable_type_checks); |
45 | 48 |
46 static const char* kGetterPrefix = "get:"; | 49 static const char* kGetterPrefix = "get:"; |
47 static const intptr_t kGetterPrefixLength = strlen(kGetterPrefix); | 50 static const intptr_t kGetterPrefixLength = strlen(kGetterPrefix); |
48 static const char* kSetterPrefix = "set:"; | 51 static const char* kSetterPrefix = "set:"; |
49 static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix); | 52 static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix); |
(...skipping 3811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3861 StorePointer(&raw_ptr()->parameter_names_, value.raw()); | 3864 StorePointer(&raw_ptr()->parameter_names_, value.raw()); |
3862 } | 3865 } |
3863 | 3866 |
3864 | 3867 |
3865 void Function::set_kind(RawFunction::Kind value) const { | 3868 void Function::set_kind(RawFunction::Kind value) const { |
3866 uword bits = raw_ptr()->kind_tag_; | 3869 uword bits = raw_ptr()->kind_tag_; |
3867 raw_ptr()->kind_tag_ = KindBits::update(value, bits); | 3870 raw_ptr()->kind_tag_ = KindBits::update(value, bits); |
3868 } | 3871 } |
3869 | 3872 |
3870 | 3873 |
3871 void Function::set_is_static(bool is_static) const { | 3874 void Function::set_is_static(bool value) const { |
3872 uword bits = raw_ptr()->kind_tag_; | 3875 uword bits = raw_ptr()->kind_tag_; |
3873 raw_ptr()->kind_tag_ = StaticBit::update(is_static, bits); | 3876 raw_ptr()->kind_tag_ = StaticBit::update(value, bits); |
3874 } | 3877 } |
3875 | 3878 |
3876 | 3879 |
3877 void Function::set_is_const(bool is_const) const { | 3880 void Function::set_is_const(bool value) const { |
3878 uword bits = raw_ptr()->kind_tag_; | 3881 uword bits = raw_ptr()->kind_tag_; |
3879 raw_ptr()->kind_tag_ = ConstBit::update(is_const, bits); | 3882 raw_ptr()->kind_tag_ = ConstBit::update(value, bits); |
3880 } | 3883 } |
3881 | 3884 |
3882 | 3885 |
3883 void Function::set_is_external(bool is_external) const { | 3886 void Function::set_is_external(bool value) const { |
3884 uword bits = raw_ptr()->kind_tag_; | 3887 uword bits = raw_ptr()->kind_tag_; |
3885 raw_ptr()->kind_tag_ = ExternalBit::update(is_external, bits); | 3888 raw_ptr()->kind_tag_ = ExternalBit::update(value, bits); |
3886 } | 3889 } |
3887 | 3890 |
3888 | 3891 |
3889 void Function::set_token_pos(intptr_t pos) const { | 3892 void Function::set_token_pos(intptr_t value) const { |
3890 ASSERT(pos >= 0); | 3893 ASSERT(value >= 0); |
3891 raw_ptr()->token_pos_ = pos; | 3894 raw_ptr()->token_pos_ = value; |
3892 } | 3895 } |
3893 | 3896 |
3894 | 3897 |
3895 void Function::set_kind_tag(intptr_t value) const { | 3898 void Function::set_kind_tag(intptr_t value) const { |
3896 raw_ptr()->kind_tag_ = value; | 3899 raw_ptr()->kind_tag_ = value; |
3897 } | 3900 } |
3898 | 3901 |
3899 | 3902 |
3900 void Function::set_num_fixed_parameters(intptr_t n) const { | 3903 void Function::set_num_fixed_parameters(intptr_t value) const { |
3901 ASSERT(n >= 0); | 3904 ASSERT(value >= 0); |
3902 raw_ptr()->num_fixed_parameters_ = n; | 3905 raw_ptr()->num_fixed_parameters_ = value; |
3903 } | 3906 } |
3904 | 3907 |
3905 | 3908 |
3906 void Function::set_num_optional_parameters(intptr_t n) const { | 3909 void Function::set_num_optional_positional_parameters(intptr_t value) const { |
3907 ASSERT(n >= 0); | 3910 ASSERT(value >= 0); |
3908 raw_ptr()->num_optional_parameters_ = n; | 3911 raw_ptr()->num_optional_positional_parameters_ = value; |
| 3912 // Optional positional and optional named parameters are mutually exclusive. |
| 3913 ASSERT((num_optional_positional_parameters() == 0) || |
| 3914 (num_optional_named_parameters() == 0)); |
| 3915 } |
| 3916 |
| 3917 |
| 3918 void Function::set_num_optional_named_parameters(intptr_t value) const { |
| 3919 ASSERT(value >= 0); |
| 3920 raw_ptr()->num_optional_named_parameters_ = value; |
| 3921 // Optional positional and optional named parameters are mutually exclusive. |
| 3922 ASSERT((num_optional_positional_parameters() == 0) || |
| 3923 (num_optional_named_parameters() == 0)); |
3909 } | 3924 } |
3910 | 3925 |
3911 | 3926 |
3912 bool Function::is_optimizable() const { | 3927 bool Function::is_optimizable() const { |
3913 return OptimizableBit::decode(raw_ptr()->kind_tag_) && | 3928 return OptimizableBit::decode(raw_ptr()->kind_tag_) && |
3914 (script() != Script::null()) && | 3929 (script() != Script::null()) && |
3915 !is_native(); | 3930 !is_native(); |
3916 } | 3931 } |
3917 | 3932 |
3918 | 3933 |
(...skipping 15 matching lines...) Expand all Loading... |
3934 } | 3949 } |
3935 | 3950 |
3936 | 3951 |
3937 void Function::set_is_abstract(bool value) const { | 3952 void Function::set_is_abstract(bool value) const { |
3938 uword bits = raw_ptr()->kind_tag_; | 3953 uword bits = raw_ptr()->kind_tag_; |
3939 raw_ptr()->kind_tag_ = AbstractBit::update(value, bits); | 3954 raw_ptr()->kind_tag_ = AbstractBit::update(value, bits); |
3940 } | 3955 } |
3941 | 3956 |
3942 | 3957 |
3943 intptr_t Function::NumberOfParameters() const { | 3958 intptr_t Function::NumberOfParameters() const { |
3944 return num_fixed_parameters() + num_optional_parameters(); | 3959 return num_fixed_parameters() + |
| 3960 num_optional_positional_parameters() + num_optional_named_parameters(); |
3945 } | 3961 } |
3946 | 3962 |
3947 | 3963 |
3948 intptr_t Function::NumberOfImplicitParameters() const { | 3964 intptr_t Function::NumberOfImplicitParameters() const { |
3949 if (kind() == RawFunction::kConstructor) { | 3965 if (kind() == RawFunction::kConstructor) { |
3950 if (is_static()) { | 3966 if (is_static()) { |
3951 ASSERT(IsFactory()); | 3967 ASSERT(IsFactory()); |
3952 return 1; // Type arguments. | 3968 return 1; // Type arguments. |
3953 } else { | 3969 } else { |
3954 ASSERT(IsConstructor()); | 3970 ASSERT(IsConstructor()); |
3955 return 2; // Instance, phase. | 3971 return 2; // Instance, phase. |
3956 } | 3972 } |
3957 } | 3973 } |
3958 if (!is_static() && (kind() != RawFunction::kClosureFunction)) { | 3974 if (!is_static() && (kind() != RawFunction::kClosureFunction)) { |
3959 // Closure functions defined inside instance (i.e. non-static) functions are | 3975 // Closure functions defined inside instance (i.e. non-static) functions are |
3960 // marked as non-static, but they do not have a receiver. | 3976 // marked as non-static, but they do not have a receiver. |
3961 return 1; // Receiver. | 3977 return 1; // Receiver. |
3962 } | 3978 } |
3963 return 0; // No implicit parameters. | 3979 return 0; // No implicit parameters. |
3964 } | 3980 } |
3965 | 3981 |
3966 | 3982 |
| 3983 void Function::SetNumberOfParameters(intptr_t num_fixed_parameters, |
| 3984 intptr_t num_optional_parameters, |
| 3985 bool are_optional_positional) const { |
| 3986 set_num_fixed_parameters(num_fixed_parameters); |
| 3987 if (are_optional_positional) { |
| 3988 set_num_optional_positional_parameters(num_optional_parameters); |
| 3989 set_num_optional_named_parameters(0); |
| 3990 } else { |
| 3991 set_num_optional_positional_parameters(0); |
| 3992 set_num_optional_named_parameters(num_optional_parameters); |
| 3993 } |
| 3994 } |
| 3995 |
| 3996 |
3967 bool Function::AreValidArgumentCounts(int num_arguments, | 3997 bool Function::AreValidArgumentCounts(int num_arguments, |
3968 int num_named_arguments, | 3998 int num_named_arguments, |
3969 String* error_message) const { | 3999 String* error_message) const { |
| 4000 if (FLAG_reject_named_argument_as_positional) { |
| 4001 if (num_named_arguments > num_optional_named_parameters()) { |
| 4002 if (error_message != NULL) { |
| 4003 const intptr_t kMessageBufferSize = 64; |
| 4004 char message_buffer[kMessageBufferSize]; |
| 4005 OS::SNPrint(message_buffer, |
| 4006 kMessageBufferSize, |
| 4007 "%d named passed, at most %"Pd" expected", |
| 4008 num_named_arguments, |
| 4009 num_optional_named_parameters()); |
| 4010 *error_message = String::New(message_buffer); |
| 4011 } |
| 4012 return false; // Too many named arguments. |
| 4013 } |
| 4014 const int num_pos_args = num_arguments - num_named_arguments; |
| 4015 const int num_opt_pos_params = num_optional_positional_parameters(); |
| 4016 const int num_pos_params = num_fixed_parameters() + num_opt_pos_params; |
| 4017 if (num_pos_args > num_pos_params) { |
| 4018 if (error_message != NULL) { |
| 4019 const intptr_t kMessageBufferSize = 64; |
| 4020 char message_buffer[kMessageBufferSize]; |
| 4021 // Hide implicit parameters to the user. |
| 4022 const intptr_t num_hidden_params = NumberOfImplicitParameters(); |
| 4023 OS::SNPrint(message_buffer, |
| 4024 kMessageBufferSize, |
| 4025 "%"Pd"%s passed, %s%"Pd" expected", |
| 4026 num_pos_args - num_hidden_params, |
| 4027 num_opt_pos_params > 0 ? " positional" : "", |
| 4028 num_opt_pos_params > 0 ? "at most " : "", |
| 4029 num_pos_params - num_hidden_params); |
| 4030 *error_message = String::New(message_buffer); |
| 4031 } |
| 4032 return false; // Too many fixed and/or positional arguments. |
| 4033 } |
| 4034 if (num_pos_args < num_fixed_parameters()) { |
| 4035 if (error_message != NULL) { |
| 4036 const intptr_t kMessageBufferSize = 64; |
| 4037 char message_buffer[kMessageBufferSize]; |
| 4038 // Hide implicit parameters to the user. |
| 4039 const intptr_t num_hidden_params = NumberOfImplicitParameters(); |
| 4040 OS::SNPrint(message_buffer, |
| 4041 kMessageBufferSize, |
| 4042 "%"Pd"%s passed, %s%"Pd" expected", |
| 4043 num_pos_args - num_hidden_params, |
| 4044 num_opt_pos_params > 0 ? " positional" : "", |
| 4045 num_opt_pos_params > 0 ? "at least " : "", |
| 4046 num_fixed_parameters() - num_hidden_params); |
| 4047 *error_message = String::New(message_buffer); |
| 4048 } |
| 4049 return false; // Too few fixed and/or positional arguments. |
| 4050 } |
| 4051 return true; |
| 4052 } |
| 4053 |
| 4054 // TODO(regis): Remove the following code once the flag is removed. |
| 4055 |
3970 if (num_arguments > NumberOfParameters()) { | 4056 if (num_arguments > NumberOfParameters()) { |
3971 if (error_message != NULL) { | 4057 if (error_message != NULL) { |
3972 const intptr_t kMessageBufferSize = 64; | 4058 const intptr_t kMessageBufferSize = 64; |
3973 char message_buffer[kMessageBufferSize]; | 4059 char message_buffer[kMessageBufferSize]; |
3974 // Hide implicit parameters to the user. | 4060 // Hide implicit parameters to the user. |
3975 const intptr_t num_hidden_params = NumberOfImplicitParameters(); | 4061 const intptr_t num_hidden_params = NumberOfImplicitParameters(); |
3976 OS::SNPrint(message_buffer, | 4062 OS::SNPrint(message_buffer, |
3977 kMessageBufferSize, | 4063 kMessageBufferSize, |
3978 "%"Pd" passed, %s%"Pd" expected", | 4064 "%"Pd" passed, %s%"Pd" expected", |
3979 num_arguments - num_hidden_params, | 4065 num_arguments - num_hidden_params, |
3980 num_optional_parameters() > 0 ? "at most " : "", | 4066 HasOptionalParameters() ? "at most " : "", |
3981 NumberOfParameters() - num_hidden_params); | 4067 NumberOfParameters() - num_hidden_params); |
3982 *error_message = String::New(message_buffer); | 4068 *error_message = String::New(message_buffer); |
3983 } | 4069 } |
3984 return false; // Too many arguments. | 4070 return false; // Too many arguments. |
3985 } | 4071 } |
3986 const int num_positional_args = num_arguments - num_named_arguments; | 4072 const int num_positional_args = num_arguments - num_named_arguments; |
3987 if (num_positional_args < num_fixed_parameters()) { | 4073 if (num_positional_args < num_fixed_parameters()) { |
3988 if (error_message != NULL) { | 4074 if (error_message != NULL) { |
3989 const intptr_t kMessageBufferSize = 64; | 4075 const intptr_t kMessageBufferSize = 64; |
3990 char message_buffer[kMessageBufferSize]; | 4076 char message_buffer[kMessageBufferSize]; |
3991 // Hide implicit parameters to the user. | 4077 // Hide implicit parameters to the user. |
3992 const intptr_t num_hidden_params = NumberOfImplicitParameters(); | 4078 const intptr_t num_hidden_params = NumberOfImplicitParameters(); |
3993 OS::SNPrint(message_buffer, | 4079 OS::SNPrint(message_buffer, |
3994 kMessageBufferSize, | 4080 kMessageBufferSize, |
3995 "%"Pd" %spassed, %"Pd" expected", | 4081 "%"Pd" %spassed, %"Pd" expected", |
3996 num_positional_args - num_hidden_params, | 4082 num_positional_args - num_hidden_params, |
3997 num_optional_parameters() > 0 ? "positional " : "", | 4083 HasOptionalParameters() ? "positional " : "", |
3998 num_fixed_parameters() - num_hidden_params); | 4084 num_fixed_parameters() - num_hidden_params); |
3999 *error_message = String::New(message_buffer); | 4085 *error_message = String::New(message_buffer); |
4000 } | 4086 } |
4001 return false; // Too few arguments. | 4087 return false; // Too few arguments. |
4002 } | 4088 } |
4003 return true; | 4089 return true; |
4004 } | 4090 } |
4005 | 4091 |
4006 | 4092 |
4007 bool Function::AreValidArguments(int num_arguments, | 4093 bool Function::AreValidArguments(int num_arguments, |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4095 | 4181 |
4096 | 4182 |
4097 const char* Function::ToFullyQualifiedCString() const { | 4183 const char* Function::ToFullyQualifiedCString() const { |
4098 char* chars = NULL; | 4184 char* chars = NULL; |
4099 ConstructFunctionFullyQualifiedCString(*this, &chars, 0); | 4185 ConstructFunctionFullyQualifiedCString(*this, &chars, 0); |
4100 return chars; | 4186 return chars; |
4101 } | 4187 } |
4102 | 4188 |
4103 | 4189 |
4104 bool Function::HasCompatibleParametersWith(const Function& other) const { | 4190 bool Function::HasCompatibleParametersWith(const Function& other) const { |
| 4191 const intptr_t num_fixed_params = num_fixed_parameters(); |
| 4192 const intptr_t num_opt_pos_params = num_optional_positional_parameters(); |
| 4193 const intptr_t num_opt_named_params = num_optional_named_parameters(); |
| 4194 const intptr_t other_num_fixed_params = other.num_fixed_parameters(); |
| 4195 const intptr_t other_num_opt_pos_params = |
| 4196 other.num_optional_positional_parameters(); |
| 4197 const intptr_t other_num_opt_named_params = |
| 4198 other.num_optional_named_parameters(); |
| 4199 if (FLAG_reject_named_argument_as_positional) { |
| 4200 // The default values of optional parameters can differ. |
| 4201 if ((num_fixed_params != other_num_fixed_params) || |
| 4202 (num_opt_pos_params < other_num_opt_pos_params) || |
| 4203 (num_opt_named_params < other_num_opt_named_params)) { |
| 4204 return false; |
| 4205 } |
| 4206 if (other_num_opt_named_params == 0) { |
| 4207 return true; |
| 4208 } |
| 4209 // Check that for each optional named parameter of the other function there |
| 4210 // exists an optional named parameter of this function with an identical |
| 4211 // name. |
| 4212 // Note that SetParameterNameAt() guarantees that names are symbols, so we |
| 4213 // can compare their raw pointers. |
| 4214 const int num_params = num_fixed_params + num_opt_named_params; |
| 4215 const int other_num_params = |
| 4216 other_num_fixed_params + other_num_opt_named_params; |
| 4217 bool found_param_name; |
| 4218 String& other_param_name = String::Handle(); |
| 4219 for (intptr_t i = other_num_fixed_params; i < other_num_params; i++) { |
| 4220 other_param_name = other.ParameterNameAt(i); |
| 4221 found_param_name = false; |
| 4222 for (intptr_t j = num_fixed_params; j < num_params; j++) { |
| 4223 if (ParameterNameAt(j) == other_param_name.raw()) { |
| 4224 found_param_name = true; |
| 4225 break; |
| 4226 } |
| 4227 } |
| 4228 if (!found_param_name) { |
| 4229 return false; |
| 4230 } |
| 4231 } |
| 4232 return true; |
| 4233 } |
| 4234 |
| 4235 // TODO(regis): Remove the following code once the flag is removed. |
| 4236 |
4105 // The default values of optional parameters can differ. | 4237 // The default values of optional parameters can differ. |
4106 const intptr_t num_fixed_params = num_fixed_parameters(); | 4238 const intptr_t num_opt_params = num_opt_pos_params + num_opt_named_params; |
4107 const intptr_t num_opt_params = num_optional_parameters(); | 4239 const intptr_t other_num_opt_params = |
4108 const intptr_t other_num_fixed_params = other.num_fixed_parameters(); | 4240 other_num_opt_pos_params + other_num_opt_named_params; |
4109 const intptr_t other_num_opt_params = other.num_optional_parameters(); | |
4110 if ((num_fixed_params != other_num_fixed_params) || | 4241 if ((num_fixed_params != other_num_fixed_params) || |
4111 (num_opt_params < other_num_opt_params)) { | 4242 (num_opt_params < other_num_opt_params)) { |
4112 return false; | 4243 return false; |
4113 } | 4244 } |
4114 // Check that for each optional named parameter of the other function there is | 4245 // Check that for each optional named parameter of the other function there is |
4115 // a corresponding optional named parameter of this function with an identical | 4246 // a corresponding optional named parameter of this function with an identical |
4116 // name at the same position. | 4247 // name at the same position. |
4117 // Note that SetParameterNameAt() guarantees that names are symbols, so we can | 4248 // Note that SetParameterNameAt() guarantees that names are symbols, so we can |
4118 // compare their raw pointers. | 4249 // compare their raw pointers. |
4119 const int other_num_params = other_num_fixed_params + other_num_opt_params; | 4250 const int other_num_params = other_num_fixed_params + other_num_opt_params; |
4120 for (intptr_t i = other_num_fixed_params; i < other_num_params; i++) { | 4251 for (intptr_t i = other_num_fixed_params; i < other_num_params; i++) { |
4121 const String& other_param_name = String::Handle(other.ParameterNameAt(i)); | 4252 const String& other_param_name = String::Handle(other.ParameterNameAt(i)); |
| 4253 ASSERT(other_param_name.IsSymbol()); |
| 4254 ASSERT(String::Handle(ParameterNameAt(i)).IsSymbol()); |
4122 if (ParameterNameAt(i) != other_param_name.raw()) { | 4255 if (ParameterNameAt(i) != other_param_name.raw()) { |
4123 return false; | 4256 return false; |
4124 } | 4257 } |
4125 } | 4258 } |
4126 return true; | 4259 return true; |
4127 } | 4260 } |
4128 | 4261 |
4129 | 4262 |
4130 // If test_kind == kIsSubtypeOf, checks if the type of the specified parameter | 4263 // If test_kind == kIsSubtypeOf, checks if the type of the specified parameter |
4131 // of this function is a subtype or a supertype of the type of the corresponding | 4264 // of this function is a subtype or a supertype of the type of the specified |
4132 // parameter of the other function. | 4265 // parameter of the other function. |
4133 // If test_kind == kIsMoreSpecificThan, checks if the type of the specified | 4266 // If test_kind == kIsMoreSpecificThan, checks if the type of the specified |
4134 // parameter of this function is more specific than the type of the | 4267 // parameter of this function is more specific than the type of the specified |
4135 // corresponding parameter of the other function. | 4268 // parameter of the other function. |
4136 // Note that we do not apply contravariance of parameter types, but covariance | 4269 // Note that we do not apply contravariance of parameter types, but covariance |
4137 // of both parameter types and result type. | 4270 // of both parameter types and result type. |
4138 bool Function::TestParameterType( | 4271 bool Function::TestParameterType( |
4139 TypeTestKind test_kind, | 4272 TypeTestKind test_kind, |
4140 intptr_t parameter_position, | 4273 intptr_t parameter_position, |
| 4274 intptr_t other_parameter_position, |
4141 const AbstractTypeArguments& type_arguments, | 4275 const AbstractTypeArguments& type_arguments, |
4142 const Function& other, | 4276 const Function& other, |
4143 const AbstractTypeArguments& other_type_arguments, | 4277 const AbstractTypeArguments& other_type_arguments, |
4144 Error* malformed_error) const { | 4278 Error* malformed_error) const { |
4145 AbstractType& other_param_type = | 4279 AbstractType& other_param_type = |
4146 AbstractType::Handle(other.ParameterTypeAt(parameter_position)); | 4280 AbstractType::Handle(other.ParameterTypeAt(other_parameter_position)); |
4147 if (!other_param_type.IsInstantiated()) { | 4281 if (!other_param_type.IsInstantiated()) { |
4148 other_param_type = other_param_type.InstantiateFrom(other_type_arguments); | 4282 other_param_type = other_param_type.InstantiateFrom(other_type_arguments); |
4149 } | 4283 } |
4150 if (other_param_type.IsDynamicType()) { | 4284 if (other_param_type.IsDynamicType()) { |
4151 return true; | 4285 return true; |
4152 } | 4286 } |
4153 AbstractType& param_type = | 4287 AbstractType& param_type = |
4154 AbstractType::Handle(ParameterTypeAt(parameter_position)); | 4288 AbstractType::Handle(ParameterTypeAt(parameter_position)); |
4155 if (!param_type.IsInstantiated()) { | 4289 if (!param_type.IsInstantiated()) { |
4156 param_type = param_type.InstantiateFrom(type_arguments); | 4290 param_type = param_type.InstantiateFrom(type_arguments); |
(...skipping 15 matching lines...) Expand all Loading... |
4172 return true; | 4306 return true; |
4173 } | 4307 } |
4174 | 4308 |
4175 | 4309 |
4176 bool Function::TypeTest(TypeTestKind test_kind, | 4310 bool Function::TypeTest(TypeTestKind test_kind, |
4177 const AbstractTypeArguments& type_arguments, | 4311 const AbstractTypeArguments& type_arguments, |
4178 const Function& other, | 4312 const Function& other, |
4179 const AbstractTypeArguments& other_type_arguments, | 4313 const AbstractTypeArguments& other_type_arguments, |
4180 Error* malformed_error) const { | 4314 Error* malformed_error) const { |
4181 const intptr_t num_fixed_params = num_fixed_parameters(); | 4315 const intptr_t num_fixed_params = num_fixed_parameters(); |
4182 const intptr_t num_opt_params = num_optional_parameters(); | 4316 const intptr_t num_opt_pos_params = num_optional_positional_parameters(); |
| 4317 const intptr_t num_opt_named_params = num_optional_named_parameters(); |
4183 const intptr_t other_num_fixed_params = other.num_fixed_parameters(); | 4318 const intptr_t other_num_fixed_params = other.num_fixed_parameters(); |
4184 const intptr_t other_num_opt_params = other.num_optional_parameters(); | 4319 const intptr_t other_num_opt_pos_params = |
| 4320 other.num_optional_positional_parameters(); |
| 4321 const intptr_t other_num_opt_named_params = |
| 4322 other.num_optional_named_parameters(); |
4185 if ((num_fixed_params != other_num_fixed_params) || | 4323 if ((num_fixed_params != other_num_fixed_params) || |
4186 (num_opt_params < other_num_opt_params)) { | 4324 (num_opt_pos_params < other_num_opt_pos_params) || |
| 4325 (num_opt_named_params < other_num_opt_named_params)) { |
4187 return false; | 4326 return false; |
4188 } | 4327 } |
4189 // Check the result type. | 4328 // Check the result type. |
4190 AbstractType& other_res_type = AbstractType::Handle(other.result_type()); | 4329 AbstractType& other_res_type = AbstractType::Handle(other.result_type()); |
4191 if (!other_res_type.IsInstantiated()) { | 4330 if (!other_res_type.IsInstantiated()) { |
4192 other_res_type = other_res_type.InstantiateFrom(other_type_arguments); | 4331 other_res_type = other_res_type.InstantiateFrom(other_type_arguments); |
4193 } | 4332 } |
4194 if (!other_res_type.IsDynamicType() && !other_res_type.IsVoidType()) { | 4333 if (!other_res_type.IsDynamicType() && !other_res_type.IsVoidType()) { |
4195 AbstractType& res_type = AbstractType::Handle(result_type()); | 4334 AbstractType& res_type = AbstractType::Handle(result_type()); |
4196 if (!res_type.IsInstantiated()) { | 4335 if (!res_type.IsInstantiated()) { |
4197 res_type = res_type.InstantiateFrom(type_arguments); | 4336 res_type = res_type.InstantiateFrom(type_arguments); |
4198 } | 4337 } |
4199 if (res_type.IsVoidType()) { | 4338 if (res_type.IsVoidType()) { |
4200 return false; | 4339 return false; |
4201 } | 4340 } |
4202 if (test_kind == kIsSubtypeOf) { | 4341 if (test_kind == kIsSubtypeOf) { |
4203 if (!res_type.IsSubtypeOf(other_res_type, malformed_error) && | 4342 if (!res_type.IsSubtypeOf(other_res_type, malformed_error) && |
4204 !other_res_type.IsSubtypeOf(res_type, malformed_error)) { | 4343 !other_res_type.IsSubtypeOf(res_type, malformed_error)) { |
4205 return false; | 4344 return false; |
4206 } | 4345 } |
4207 } else { | 4346 } else { |
4208 ASSERT(test_kind == kIsMoreSpecificThan); | 4347 ASSERT(test_kind == kIsMoreSpecificThan); |
4209 if (!res_type.IsMoreSpecificThan(other_res_type, malformed_error)) { | 4348 if (!res_type.IsMoreSpecificThan(other_res_type, malformed_error)) { |
4210 return false; | 4349 return false; |
4211 } | 4350 } |
4212 } | 4351 } |
4213 } | 4352 } |
| 4353 if (FLAG_reject_named_argument_as_positional) { |
| 4354 // Check the types of fixed and optional positional parameters. |
| 4355 for (intptr_t i = 0; i < num_fixed_params + other_num_opt_pos_params; i++) { |
| 4356 if (!TestParameterType(test_kind, |
| 4357 i, i, type_arguments, other, other_type_arguments, |
| 4358 malformed_error)) { |
| 4359 return false; |
| 4360 } |
| 4361 } |
| 4362 // Check the names and types of optional named parameters. |
| 4363 if (other_num_opt_named_params == 0) { |
| 4364 return true; |
| 4365 } |
| 4366 // Check that for each optional named parameter of type T of the other |
| 4367 // function type, there exists an optional named parameter of this function |
| 4368 // type with an identical name and with a type S that is a either a subtype |
| 4369 // or supertype of T (if test_kind == kIsSubtypeOf) or that is more specific |
| 4370 // than T (if test_kind == kIsMoreSpecificThan). |
| 4371 // Note that SetParameterNameAt() guarantees that names are symbols, so we |
| 4372 // can compare their raw pointers. |
| 4373 const int num_params = num_fixed_params + num_opt_named_params; |
| 4374 const int other_num_params = |
| 4375 other_num_fixed_params + other_num_opt_named_params; |
| 4376 bool found_param_name; |
| 4377 String& other_param_name = String::Handle(); |
| 4378 for (intptr_t i = other_num_fixed_params; i < other_num_params; i++) { |
| 4379 other_param_name = other.ParameterNameAt(i); |
| 4380 ASSERT(other_param_name.IsSymbol()); |
| 4381 found_param_name = false; |
| 4382 for (intptr_t j = num_fixed_params; j < num_params; j++) { |
| 4383 ASSERT(String::Handle(ParameterNameAt(j)).IsSymbol()); |
| 4384 if (ParameterNameAt(j) == other_param_name.raw()) { |
| 4385 found_param_name = true; |
| 4386 if (!TestParameterType(test_kind, |
| 4387 j, i, |
| 4388 type_arguments, other, other_type_arguments, |
| 4389 malformed_error)) { |
| 4390 return false; |
| 4391 } |
| 4392 break; |
| 4393 } |
| 4394 } |
| 4395 if (!found_param_name) { |
| 4396 return false; |
| 4397 } |
| 4398 } |
| 4399 } |
| 4400 |
| 4401 // TODO(regis): Remove the following code once the flag is removed. |
| 4402 |
4214 // Check the types of fixed parameters. | 4403 // Check the types of fixed parameters. |
4215 for (intptr_t i = 0; i < num_fixed_params; i++) { | 4404 for (intptr_t i = 0; i < num_fixed_params; i++) { |
4216 if (!TestParameterType(test_kind, | 4405 if (!TestParameterType(test_kind, |
4217 i, type_arguments, other, other_type_arguments, | 4406 i, i, type_arguments, other, other_type_arguments, |
4218 malformed_error)) { | 4407 malformed_error)) { |
4219 return false; | 4408 return false; |
4220 } | 4409 } |
4221 } | 4410 } |
4222 // Check the names and types of optional parameters. | 4411 // Check the names and types of optional parameters. |
4223 // Check that for each optional named parameter of type T of the other | 4412 // Check that for each optional named parameter of type T of the other |
4224 // function type, there is a corresponding optional named parameter of this | 4413 // function type, there is a corresponding optional named parameter of this |
4225 // function at the same position with an identical name and with a type S | 4414 // function at the same position with an identical name and with a type S |
4226 // that is a either a subtype or supertype of T (if test_kind == kIsSubtypeOf) | 4415 // that is a either a subtype or supertype of T (if test_kind == kIsSubtypeOf) |
4227 // or that is more specific than T (if test_kind == kIsMoreSpecificThan). | 4416 // or that is more specific than T (if test_kind == kIsMoreSpecificThan). |
4228 // Note that SetParameterNameAt() guarantees that names are symbols, so we | 4417 // Note that SetParameterNameAt() guarantees that names are symbols, so we |
4229 // can compare their raw pointers. | 4418 // can compare their raw pointers. |
4230 const intptr_t other_num_params = | 4419 const intptr_t other_num_params = other_num_fixed_params + |
4231 other_num_fixed_params + other_num_opt_params; | 4420 other_num_opt_pos_params + other_num_opt_named_params; |
4232 String& other_param_name = String::Handle(); | 4421 String& other_param_name = String::Handle(); |
4233 for (intptr_t i = other_num_fixed_params; i < other_num_params; i++) { | 4422 for (intptr_t i = other_num_fixed_params; i < other_num_params; i++) { |
4234 other_param_name = other.ParameterNameAt(i); | 4423 other_param_name = other.ParameterNameAt(i); |
| 4424 ASSERT(other_param_name.IsSymbol()); |
| 4425 ASSERT(String::Handle(ParameterNameAt(i)).IsSymbol()); |
4235 if ((ParameterNameAt(i) != other_param_name.raw()) || | 4426 if ((ParameterNameAt(i) != other_param_name.raw()) || |
4236 !TestParameterType(test_kind, | 4427 !TestParameterType(test_kind, |
4237 i, type_arguments, other, other_type_arguments, | 4428 i, i, type_arguments, other, other_type_arguments, |
4238 malformed_error)) { | 4429 malformed_error)) { |
4239 return false; | 4430 return false; |
4240 } | 4431 } |
4241 } | 4432 } |
4242 return true; | 4433 return true; |
4243 } | 4434 } |
4244 | 4435 |
4245 | 4436 |
4246 bool Function::IsImplicitClosureFunction() const { | 4437 bool Function::IsImplicitClosureFunction() const { |
4247 if (!IsClosureFunction()) { | 4438 if (!IsClosureFunction()) { |
(...skipping 30 matching lines...) Expand all Loading... |
4278 result.set_name(name); | 4469 result.set_name(name); |
4279 result.set_kind(kind); | 4470 result.set_kind(kind); |
4280 result.set_is_static(is_static); | 4471 result.set_is_static(is_static); |
4281 result.set_is_const(is_const); | 4472 result.set_is_const(is_const); |
4282 result.set_is_abstract(is_abstract); | 4473 result.set_is_abstract(is_abstract); |
4283 result.set_is_external(is_external); | 4474 result.set_is_external(is_external); |
4284 result.set_owner(owner); | 4475 result.set_owner(owner); |
4285 result.set_token_pos(token_pos); | 4476 result.set_token_pos(token_pos); |
4286 result.set_end_token_pos(token_pos); | 4477 result.set_end_token_pos(token_pos); |
4287 result.set_num_fixed_parameters(0); | 4478 result.set_num_fixed_parameters(0); |
4288 result.set_num_optional_parameters(0); | 4479 result.set_num_optional_positional_parameters(0); |
| 4480 result.set_num_optional_named_parameters(0); |
4289 result.set_usage_counter(0); | 4481 result.set_usage_counter(0); |
4290 result.set_deoptimization_counter(0); | 4482 result.set_deoptimization_counter(0); |
4291 result.set_is_optimizable(true); | 4483 result.set_is_optimizable(true); |
4292 result.set_has_finally(false); | 4484 result.set_has_finally(false); |
4293 result.set_is_native(false); | 4485 result.set_is_native(false); |
4294 return result.raw(); | 4486 return result.raw(); |
4295 } | 4487 } |
4296 | 4488 |
4297 | 4489 |
4298 RawFunction* Function::NewClosureFunction(const String& name, | 4490 RawFunction* Function::NewClosureFunction(const String& name, |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4337 } | 4529 } |
4338 closure_function.set_context_scope(context_scope); | 4530 closure_function.set_context_scope(context_scope); |
4339 | 4531 |
4340 // Set closure function's result type to this result type. | 4532 // Set closure function's result type to this result type. |
4341 closure_function.set_result_type(AbstractType::Handle(result_type())); | 4533 closure_function.set_result_type(AbstractType::Handle(result_type())); |
4342 | 4534 |
4343 // Set closure function's formal parameters to this formal parameters, | 4535 // Set closure function's formal parameters to this formal parameters, |
4344 // removing the receiver if this is an instance method. | 4536 // removing the receiver if this is an instance method. |
4345 const int has_receiver = is_static() ? 0 : 1; | 4537 const int has_receiver = is_static() ? 0 : 1; |
4346 const int num_fixed_params = num_fixed_parameters() - has_receiver; | 4538 const int num_fixed_params = num_fixed_parameters() - has_receiver; |
4347 const int num_optional_params = num_optional_parameters(); | 4539 const int num_opt_pos_params = num_optional_positional_parameters(); |
4348 const int num_params = num_fixed_params + num_optional_params; | 4540 const int num_opt_named_params = num_optional_named_parameters(); |
| 4541 const int num_params = |
| 4542 num_fixed_params + num_opt_pos_params + num_opt_named_params; |
4349 closure_function.set_num_fixed_parameters(num_fixed_params); | 4543 closure_function.set_num_fixed_parameters(num_fixed_params); |
4350 closure_function.set_num_optional_parameters(num_optional_params); | 4544 closure_function.set_num_optional_positional_parameters(num_opt_pos_params); |
| 4545 closure_function.set_num_optional_named_parameters(num_opt_named_params); |
4351 closure_function.set_parameter_types(Array::Handle(Array::New(num_params, | 4546 closure_function.set_parameter_types(Array::Handle(Array::New(num_params, |
4352 Heap::kOld))); | 4547 Heap::kOld))); |
4353 closure_function.set_parameter_names(Array::Handle(Array::New(num_params, | 4548 closure_function.set_parameter_names(Array::Handle(Array::New(num_params, |
4354 Heap::kOld))); | 4549 Heap::kOld))); |
4355 AbstractType& param_type = AbstractType::Handle(); | 4550 AbstractType& param_type = AbstractType::Handle(); |
4356 String& param_name = String::Handle(); | 4551 String& param_name = String::Handle(); |
4357 for (int i = 0; i < num_params; i++) { | 4552 for (int i = 0; i < num_params; i++) { |
4358 param_type = ParameterTypeAt(i + has_receiver); | 4553 param_type = ParameterTypeAt(i + has_receiver); |
4359 closure_function.SetParameterTypeAt(i, param_type); | 4554 closure_function.SetParameterTypeAt(i, param_type); |
4360 param_name = ParameterNameAt(i + has_receiver); | 4555 param_name = ParameterNameAt(i + has_receiver); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4396 NameVisibility name_visibility, | 4591 NameVisibility name_visibility, |
4397 const AbstractTypeArguments& instantiator) const { | 4592 const AbstractTypeArguments& instantiator) const { |
4398 const GrowableObjectArray& pieces = | 4593 const GrowableObjectArray& pieces = |
4399 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 4594 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
4400 const String& kCommaSpace = String::Handle(Symbols::New(", ")); | 4595 const String& kCommaSpace = String::Handle(Symbols::New(", ")); |
4401 const String& kColonSpace = String::Handle(Symbols::New(": ")); | 4596 const String& kColonSpace = String::Handle(Symbols::New(": ")); |
4402 const String& kLParen = String::Handle(Symbols::New("(")); | 4597 const String& kLParen = String::Handle(Symbols::New("(")); |
4403 const String& kRParen = String::Handle(Symbols::New(") => ")); | 4598 const String& kRParen = String::Handle(Symbols::New(") => ")); |
4404 const String& kLBracket = String::Handle(Symbols::New("[")); | 4599 const String& kLBracket = String::Handle(Symbols::New("[")); |
4405 const String& kRBracket = String::Handle(Symbols::New("]")); | 4600 const String& kRBracket = String::Handle(Symbols::New("]")); |
| 4601 const String& kLBrace = String::Handle(Symbols::New("{")); |
| 4602 const String& kRBrace = String::Handle(Symbols::New("}")); |
4406 String& name = String::Handle(); | 4603 String& name = String::Handle(); |
4407 if (!instantiate && !is_static()) { | 4604 if (!instantiate && !is_static()) { |
4408 // Prefix the signature with its type parameters, if any (e.g. "<K, V>"). | 4605 // Prefix the signature with its type parameters, if any (e.g. "<K, V>"). |
4409 // The signature of static functions cannot be type parameterized. | 4606 // The signature of static functions cannot be type parameterized. |
4410 const String& kSpaceExtendsSpace = | 4607 const String& kSpaceExtendsSpace = |
4411 String::Handle(Symbols::New(" extends ")); | 4608 String::Handle(Symbols::New(" extends ")); |
4412 const String& kLAngleBracket = String::Handle(Symbols::New("<")); | 4609 const String& kLAngleBracket = String::Handle(Symbols::New("<")); |
4413 const String& kRAngleBracket = String::Handle(Symbols::New(">")); | 4610 const String& kRAngleBracket = String::Handle(Symbols::New(">")); |
4414 const Class& function_class = Class::Handle(Owner()); | 4611 const Class& function_class = Class::Handle(Owner()); |
4415 ASSERT(!function_class.IsNull()); | 4612 ASSERT(!function_class.IsNull()); |
(...skipping 17 matching lines...) Expand all Loading... |
4433 if (i < num_type_parameters - 1) { | 4630 if (i < num_type_parameters - 1) { |
4434 pieces.Add(kCommaSpace); | 4631 pieces.Add(kCommaSpace); |
4435 } | 4632 } |
4436 } | 4633 } |
4437 pieces.Add(kRAngleBracket); | 4634 pieces.Add(kRAngleBracket); |
4438 } | 4635 } |
4439 } | 4636 } |
4440 AbstractType& param_type = AbstractType::Handle(); | 4637 AbstractType& param_type = AbstractType::Handle(); |
4441 const intptr_t num_params = NumberOfParameters(); | 4638 const intptr_t num_params = NumberOfParameters(); |
4442 const intptr_t num_fixed_params = num_fixed_parameters(); | 4639 const intptr_t num_fixed_params = num_fixed_parameters(); |
4443 const intptr_t num_opt_params = num_optional_parameters(); | 4640 const intptr_t num_opt_pos_params = num_optional_positional_parameters(); |
| 4641 const intptr_t num_opt_named_params = num_optional_named_parameters(); |
| 4642 const intptr_t num_opt_params = num_opt_pos_params + num_opt_named_params; |
4444 ASSERT((num_fixed_params + num_opt_params) == num_params); | 4643 ASSERT((num_fixed_params + num_opt_params) == num_params); |
4445 pieces.Add(kLParen); | 4644 pieces.Add(kLParen); |
4446 for (intptr_t i = 0; i < num_fixed_params; i++) { | 4645 for (intptr_t i = 0; i < num_fixed_params; i++) { |
4447 param_type = ParameterTypeAt(i); | 4646 param_type = ParameterTypeAt(i); |
4448 ASSERT(!param_type.IsNull()); | 4647 ASSERT(!param_type.IsNull()); |
4449 if (instantiate && !param_type.IsInstantiated()) { | 4648 if (instantiate && !param_type.IsInstantiated()) { |
4450 param_type = param_type.InstantiateFrom(instantiator); | 4649 param_type = param_type.InstantiateFrom(instantiator); |
4451 } | 4650 } |
4452 name = param_type.BuildName(name_visibility); | 4651 name = param_type.BuildName(name_visibility); |
4453 pieces.Add(name); | 4652 pieces.Add(name); |
4454 if (i != (num_params - 1)) { | 4653 if (i != (num_params - 1)) { |
4455 pieces.Add(kCommaSpace); | 4654 pieces.Add(kCommaSpace); |
4456 } | 4655 } |
4457 } | 4656 } |
4458 if (num_opt_params > 0) { | 4657 if (num_opt_params > 0) { |
4459 pieces.Add(kLBracket); | 4658 if (num_opt_pos_params > 0) { |
| 4659 pieces.Add(kLBracket); |
| 4660 } else { |
| 4661 pieces.Add(kLBrace); |
| 4662 } |
4460 for (intptr_t i = num_fixed_params; i < num_params; i++) { | 4663 for (intptr_t i = num_fixed_params; i < num_params; i++) { |
4461 name = ParameterNameAt(i); | 4664 // The parameter name of an optional positional parameter does not need |
4462 pieces.Add(name); | 4665 // to be part of the signature, since it is not used. |
4463 pieces.Add(kColonSpace); | 4666 if (!FLAG_reject_named_argument_as_positional || |
| 4667 (num_opt_named_params > 0)) { |
| 4668 name = ParameterNameAt(i); |
| 4669 pieces.Add(name); |
| 4670 pieces.Add(kColonSpace); |
| 4671 } |
4464 param_type = ParameterTypeAt(i); | 4672 param_type = ParameterTypeAt(i); |
4465 if (instantiate && !param_type.IsInstantiated()) { | 4673 if (instantiate && !param_type.IsInstantiated()) { |
4466 param_type = param_type.InstantiateFrom(instantiator); | 4674 param_type = param_type.InstantiateFrom(instantiator); |
4467 } | 4675 } |
4468 ASSERT(!param_type.IsNull()); | 4676 ASSERT(!param_type.IsNull()); |
4469 name = param_type.BuildName(name_visibility); | 4677 name = param_type.BuildName(name_visibility); |
4470 pieces.Add(name); | 4678 pieces.Add(name); |
4471 if (i != (num_params - 1)) { | 4679 if (i != (num_params - 1)) { |
4472 pieces.Add(kCommaSpace); | 4680 pieces.Add(kCommaSpace); |
4473 } | 4681 } |
4474 } | 4682 } |
4475 pieces.Add(kRBracket); | 4683 if (num_opt_pos_params > 0) { |
| 4684 pieces.Add(kRBracket); |
| 4685 } else { |
| 4686 pieces.Add(kRBrace); |
| 4687 } |
4476 } | 4688 } |
4477 pieces.Add(kRParen); | 4689 pieces.Add(kRParen); |
4478 AbstractType& res_type = AbstractType::Handle(result_type()); | 4690 AbstractType& res_type = AbstractType::Handle(result_type()); |
4479 if (instantiate && !res_type.IsInstantiated()) { | 4691 if (instantiate && !res_type.IsInstantiated()) { |
4480 res_type = res_type.InstantiateFrom(instantiator); | 4692 res_type = res_type.InstantiateFrom(instantiator); |
4481 } | 4693 } |
4482 name = res_type.BuildName(name_visibility); | 4694 name = res_type.BuildName(name_visibility); |
4483 pieces.Add(name); | 4695 pieces.Add(name); |
4484 const Array& strings = Array::Handle(Array::MakeArray(pieces)); | 4696 const Array& strings = Array::Handle(Array::MakeArray(pieces)); |
4485 return Symbols::New(String::Handle(String::ConcatAll(strings))); | 4697 return Symbols::New(String::Handle(String::ConcatAll(strings))); |
(...skipping 6716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11202 } | 11414 } |
11203 return result.raw(); | 11415 return result.raw(); |
11204 } | 11416 } |
11205 | 11417 |
11206 | 11418 |
11207 const char* WeakProperty::ToCString() const { | 11419 const char* WeakProperty::ToCString() const { |
11208 return "_WeakProperty"; | 11420 return "_WeakProperty"; |
11209 } | 11421 } |
11210 | 11422 |
11211 } // namespace dart | 11423 } // namespace dart |
OLD | NEW |