Chromium Code Reviews| Index: runtime/vm/object.cc |
| diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc |
| index cfb435779f0cec5208e0365cee5029c8a4ca7621..372a10fd041f635dacfd93fab3501a181773df20 100644 |
| --- a/runtime/vm/object.cc |
| +++ b/runtime/vm/object.cc |
| @@ -2483,8 +2483,6 @@ void Class::set_super_type(const AbstractType& value) const { |
| } |
| -// Return a TypeParameter if the type_name is a type parameter of this class. |
| -// Return null otherwise. |
| RawTypeParameter* Class::LookupTypeParameter(const String& type_name) const { |
| ASSERT(!type_name.IsNull()); |
| Thread* thread = Thread::Current(); |
| @@ -5503,6 +5501,12 @@ RawFunction* Function::parent_function() const { |
| const Object& obj = Object::Handle(raw_ptr()->data_); |
| ASSERT(!obj.IsNull()); |
| return ClosureData::Cast(obj).parent_function(); |
| + } else if (IsSignatureFunction()) { |
| + const Object& obj = Object::Handle(raw_ptr()->data_); |
| + // Parent function may be null or data_ may already be set to function type. |
| + if (!obj.IsNull() && obj.IsFunction()) { |
| + return Function::Cast(obj).raw(); |
| + } |
| } |
| return Function::null(); |
| } |
| @@ -5514,6 +5518,9 @@ void Function::set_parent_function(const Function& value) const { |
| ASSERT(!obj.IsNull()); |
| ClosureData::Cast(obj).set_parent_function(value); |
| return; |
| + } else if (IsSignatureFunction()) { |
| + set_data(value); // Temporarily set during parsing only. |
| + return; |
| } |
| UNREACHABLE(); |
| } |
| @@ -5861,6 +5868,61 @@ void Function::set_parameter_names(const Array& value) const { |
| } |
| +void Function::set_type_parameters(const TypeArguments& value) const { |
| + StorePointer(&raw_ptr()->type_parameters_, value.raw()); |
| +} |
| + |
| + |
| +intptr_t Function::NumTypeParameters(Thread* thread) const { |
| + if (type_parameters() == TypeArguments::null()) { |
| + return 0; |
| + } |
| + REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread); |
| + TypeArguments& type_params = thread->TypeArgumentsHandle(); |
| + type_params = type_parameters(); |
| + return type_params.Length(); |
| +} |
| + |
| + |
| +RawTypeParameter* Function::LookupTypeParameter( |
| + const String& type_name, intptr_t* function_level) const { |
| + ASSERT(!type_name.IsNull()); |
| + Thread* thread = Thread::Current(); |
| + REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread); |
| + REUSABLE_TYPE_PARAMETER_HANDLESCOPE(thread); |
| + REUSABLE_STRING_HANDLESCOPE(thread); |
| + TypeArguments& type_params = thread->TypeArgumentsHandle(); |
| + TypeParameter& type_param = thread->TypeParameterHandle(); |
| + String& type_param_name = thread->StringHandle(); |
| + Function& function = thread->FunctionHandle(); |
|
siva
2016/09/19 23:23:46
REUSABLE_FUNCTION_HANDLESCOPE(thread);
needed her
regis
2016/09/23 00:35:23
Done.
|
| + |
| + function ^= this->raw(); |
| + intptr_t parent_level = -1; |
| + while (!function.IsNull()) { |
| + type_params ^= function.type_parameters(); |
| + if (!type_params.IsNull()) { |
| + parent_level++; |
| + const intptr_t num_type_params = type_params.Length(); |
| + for (intptr_t i = 0; i < num_type_params; i++) { |
| + type_param ^= type_params.TypeAt(i); |
| + type_param_name = type_param.name(); |
| + if (type_param_name.Equals(type_name)) { |
| + if (parent_level > 0) { |
| + // TODO(regis): Clone type parameter and set parent_level. |
| + } |
| + return type_param.raw(); |
| + } |
| + } |
| + } |
| + function ^= function.parent_function(); |
| + if (function_level != NULL) { |
| + (*function_level)--; |
| + } |
| + } |
| + return TypeParameter::null(); |
| +} |
| + |
| + |
| void Function::set_kind(RawFunction::Kind value) const { |
| set_kind_tag(KindBits::update(value, raw_ptr()->kind_tag_)); |
| } |
| @@ -17708,6 +17770,11 @@ RawClass* TypeParameter::parameterized_class() const { |
| } |
| +void TypeParameter::set_parameterized_function(const Function& value) const { |
| + StorePointer(&raw_ptr()->parameterized_function_, value.raw()); |
| +} |
| + |
| + |
| void TypeParameter::set_index(intptr_t value) const { |
| ASSERT(value >= 0); |
| ASSERT(Utils::IsInt(16, value)); |
| @@ -17818,6 +17885,7 @@ RawAbstractType* TypeParameter::CloneUnfinalized() const { |
| } |
| // No need to clone bound, as it is not part of the finalization state. |
| return TypeParameter::New(Class::Handle(parameterized_class()), |
| + Function::Handle(parameterized_function()), |
| index(), |
| String::Handle(name()), |
| AbstractType::Handle(bound()), |
| @@ -17837,7 +17905,9 @@ RawAbstractType* TypeParameter::CloneUninstantiated( |
| const intptr_t new_index = index() + |
| new_owner.NumTypeArguments() - old_owner.NumTypeArguments(); |
| AbstractType& upper_bound = AbstractType::Handle(bound()); |
| + ASSERT(parameterized_function() == Function::null()); |
| clone = TypeParameter::New(new_owner, |
| + Function::Handle(), |
| new_index, |
| String::Handle(name()), |
| upper_bound, // Not cloned yet. |
| @@ -17888,12 +17958,15 @@ RawTypeParameter* TypeParameter::New() { |
| RawTypeParameter* TypeParameter::New(const Class& parameterized_class, |
| + const Function& parameterized_function, |
| intptr_t index, |
| const String& name, |
| const AbstractType& bound, |
| TokenPosition token_pos) { |
| + ASSERT(parameterized_class.IsNull() != parameterized_function.IsNull()); |
| const TypeParameter& result = TypeParameter::Handle(TypeParameter::New()); |
| result.set_parameterized_class(parameterized_class); |
| + result.set_parameterized_function(parameterized_function); |
| result.set_index(index); |
| result.set_name(name); |
| result.set_bound(bound); |