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

Unified Diff: runtime/vm/class_finalizer.cc

Issue 23453024: Keep track of type parameter processing in mixin application classes. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 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
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/object.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/class_finalizer.cc
===================================================================
--- runtime/vm/class_finalizer.cc (revision 27156)
+++ runtime/vm/class_finalizer.cc (working copy)
@@ -511,6 +511,10 @@
void ClassFinalizer::FinalizeTypeParameters(const Class& cls) {
+ if (cls.IsMixinApplication()) {
+ // Copy the type parameters to the mixin application.
+ ApplyMixinType(cls);
+ }
// The type parameter bounds are not finalized here.
const TypeArguments& type_parameters =
TypeArguments::Handle(cls.type_parameters());
@@ -1310,14 +1314,14 @@
// mixin application class. Change type arguments of super type and of
// interfaces to refer to the respective type parameters of the mixin
// application class.
-void ClassFinalizer::CloneTypeParameters(const Class& mixapp_class) {
- ASSERT(mixapp_class.NumTypeParameters() == 0);
+void ClassFinalizer::CloneTypeParameters(const Class& mixin_app_class) {
+ ASSERT(mixin_app_class.type_parameters() == AbstractTypeArguments::null());
const AbstractType& super_type =
- AbstractType::Handle(mixapp_class.super_type());
+ AbstractType::Handle(mixin_app_class.super_type());
ASSERT(super_type.IsResolved());
const Class& super_class = Class::Handle(super_type.type_class());
- const Type& mixin_type = Type::Handle(mixapp_class.mixin());
+ const Type& mixin_type = Type::Handle(mixin_app_class.mixin());
const Class& mixin_class = Class::Handle(mixin_type.type_class());
const int num_super_parameters = super_class.NumTypeParameters();
const int num_mixin_parameters = mixin_class.NumTypeParameters();
@@ -1346,7 +1350,7 @@
param_bound = param.bound();
// TODO(hausner): handle type bounds.
if (!param_bound.IsObjectType()) {
- const Script& script = Script::Handle(mixapp_class.script());
+ const Script& script = Script::Handle(mixin_app_class.script());
ReportError(Error::Handle(), // No previous error.
script, param.token_pos(),
"type parameter '%s': type bounds not yet"
@@ -1355,7 +1359,7 @@
}
param_name = String::Concat(param_name, Symbols::Backtick());
param_name = Symbols::New(param_name);
- cloned_param = TypeParameter::New(mixapp_class,
+ cloned_param = TypeParameter::New(mixin_app_class,
cloned_index,
param_name,
param_bound,
@@ -1389,14 +1393,14 @@
// TODO(hausner): handle type bounds.
if (!param_bound.IsObjectType()) {
- const Script& script = Script::Handle(mixapp_class.script());
+ const Script& script = Script::Handle(mixin_app_class.script());
ReportError(Error::Handle(), // No previous error.
script, param.token_pos(),
"type parameter '%s': type bounds not yet"
" implemented for mixins\n",
param_name.ToCString());
}
- cloned_param = TypeParameter::New(mixapp_class,
+ cloned_param = TypeParameter::New(mixin_app_class,
cloned_index,
param_name,
param_bound,
@@ -1408,7 +1412,7 @@
// Lastly, change the type arguments of the single interface type to
// refer to the cloned type parameters of the mixin application class.
- Array& interface_types = Array::Handle(mixapp_class.interfaces());
+ Array& interface_types = Array::Handle(mixin_app_class.interfaces());
ASSERT(interface_types.Length() == 1);
AbstractType& interface_type = AbstractType::Handle();
interface_type ^= interface_types.At(0);
@@ -1418,21 +1422,24 @@
Type::Cast(interface_type).set_arguments(interface_type_args);
ASSERT(!interface_type.IsFinalized());
}
- mixapp_class.set_type_parameters(cloned_type_params);
+ mixin_app_class.set_type_parameters(cloned_type_params);
}
-void ClassFinalizer::ApplyMixinTypes(const Class& cls) {
- const Type& mixin_type = Type::Handle(cls.mixin());
+void ClassFinalizer::ApplyMixinType(const Class& mixin_app_class) {
+ if (mixin_app_class.is_mixin_type_applied()) {
+ return;
+ }
+ const Type& mixin_type = Type::Handle(mixin_app_class.mixin());
ASSERT(!mixin_type.IsNull());
ASSERT(mixin_type.HasResolvedTypeClass());
const Class& mixin_cls = Class::Handle(mixin_type.type_class());
if (FLAG_trace_class_finalization) {
- OS::Print("Applying mixin type '%s' to '%s' at pos %" Pd "\n",
+ OS::Print("Applying mixin type '%s' to %s at pos %" Pd "\n",
String::Handle(mixin_type.Name()).ToCString(),
- cls.ToCString(),
- cls.token_pos());
+ mixin_app_class.ToCString(),
+ mixin_app_class.token_pos());
}
// Check that the super class of the mixin class is extending
@@ -1440,24 +1447,26 @@
const AbstractType& mixin_super_type =
AbstractType::Handle(mixin_cls.super_type());
if (!mixin_super_type.IsObjectType()) {
- const Script& script = Script::Handle(cls.script());
+ const Script& script = Script::Handle(mixin_app_class.script());
const String& class_name = String::Handle(mixin_cls.Name());
ReportError(Error::Handle(), // No previous error.
- script, cls.token_pos(),
- "mixin class %s must extend class Object",
+ script, mixin_app_class.token_pos(),
+ "mixin class '%s' must extend class Object",
class_name.ToCString());
}
// Copy type parameters to mixin application class.
- CloneTypeParameters(cls);
+ CloneTypeParameters(mixin_app_class);
if (FLAG_trace_class_finalization) {
- OS::Print("Done applying mixin type '%s' to class %s %s extending '%s'\n",
+ OS::Print("Done applying mixin type '%s' to class '%s' %s extending '%s'\n",
String::Handle(mixin_type.Name()).ToCString(),
- String::Handle(cls.Name()).ToCString(),
- TypeArguments::Handle(cls.type_parameters()).ToCString(),
- AbstractType::Handle(cls.super_type()).ToCString());
+ String::Handle(mixin_app_class.Name()).ToCString(),
+ TypeArguments::Handle(
+ mixin_app_class.type_parameters()).ToCString(),
+ AbstractType::Handle(mixin_app_class.super_type()).ToCString());
}
+ mixin_app_class.set_is_mixin_type_applied();
}
@@ -1514,7 +1523,7 @@
}
-void ClassFinalizer::ApplyMixin(const Class& cls) {
+void ClassFinalizer::ApplyMixinMembers(const Class& cls) {
Isolate* isolate = Isolate::Current();
const Type& mixin_type = Type::Handle(isolate, cls.mixin());
ASSERT(!mixin_type.IsNull());
@@ -1523,8 +1532,8 @@
mixin_cls.EnsureIsFinalized(isolate);
if (FLAG_trace_class_finalization) {
- OS::Print("Applying mixin '%s' to '%s' at pos %" Pd "\n",
- String::Handle(mixin_cls.Name()).ToCString(),
+ OS::Print("Applying mixin members of %s to %s at pos %" Pd "\n",
+ mixin_cls.ToCString(),
cls.ToCString(),
cls.token_pos());
}
@@ -1549,7 +1558,7 @@
const Script& script = Script::Handle(isolate, cls.script());
ReportError(Error::Handle(), // No previous error.
script, cls.token_pos(),
- "mixin class %s must not have constructors\n",
+ "mixin class '%s' must not have constructors\n",
String::Handle(isolate, mixin_cls.Name()).ToCString());
}
continue; // Skip the implicit constructor.
@@ -1581,10 +1590,9 @@
cls.SetFields(fields);
if (FLAG_trace_class_finalization) {
- OS::Print("done mixin appl '%s' '%s' extending '%s'\n",
- String::Handle(cls.Name()).ToCString(),
- TypeArguments::Handle(cls.type_parameters()).ToCString(),
- AbstractType::Handle(cls.super_type()).ToCString());
+ OS::Print("done applying mixin members of %s to %s\n",
+ mixin_cls.ToCString(),
+ cls.ToCString());
}
}
@@ -1610,10 +1618,6 @@
if (!super_class.IsNull()) {
FinalizeTypesInClass(super_class);
}
- if (cls.mixin() != Type::null()) {
- // Copy the type parameters to the mixin application.
- ApplyMixinTypes(cls);
- }
// Finalize type parameters before finalizing the super type.
FinalizeTypeParameters(cls);
ResolveUpperBounds(cls);
@@ -1724,11 +1728,11 @@
if (FLAG_trace_class_finalization) {
OS::Print("Finalize %s\n", cls.ToCString());
}
- if (cls.mixin() != Type::null()) {
+ if (cls.IsMixinApplication()) {
// Copy instance methods and fields from the mixin class.
// This has to happen before the check whether the methods of
// the class conflict with inherited methods.
- ApplyMixin(cls);
+ ApplyMixinMembers(cls);
}
// Ensure super class is finalized.
const Class& super = Class::Handle(cls.SuperClass());
@@ -1860,6 +1864,7 @@
if (num_type_arguments != num_type_parameters) {
const Script& script = Script::Handle(cls.script());
const String& type_class_name = String::Handle(type_class.Name());
+ // TODO(regis): This should not be a compile time error anymore.
ReportError(Error::Handle(), // No previous error.
script, type.token_pos(),
"wrong number of type arguments for class '%s'",
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698