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

Unified Diff: runtime/vm/object.cc

Issue 2349593003: Support generic method syntax (fixes #25869). (Closed)
Patch Set: address comments Created 4 years, 3 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 side-by-side diff with in-line comments
Download patch
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);

Powered by Google App Engine
This is Rietveld 408576698