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

Unified Diff: runtime/vm/class_finalizer.cc

Issue 12210127: First stab at mixins in VM compiler (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 10 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/class_finalizer.cc
===================================================================
--- runtime/vm/class_finalizer.cc (revision 18363)
+++ runtime/vm/class_finalizer.cc (working copy)
@@ -1245,6 +1245,61 @@
}
+void ClassFinalizer::ApplyMixin(const Class& cls, const Type& mixin) {
+ ASSERT(mixin.HasResolvedTypeClass());
+ const Class& mixin_cls = Class::Handle(mixin.type_class());
+
+ // Check that the super class of the mixin class is extending
+ // class Object.
+ const Type& mixin_super_type = Type::Handle(mixin_cls.super_type());
+ ResolveType(mixin_cls, mixin_super_type, kCanonicalizeWellFormed);
+ if (!mixin_super_type.IsObjectType()) {
+ const Script& script = Script::Handle(cls.script());
+ const String& class_name = String::Handle(mixin_cls.Name());
+ ReportError(script, cls.token_pos(),
siva 2013/02/13 01:34:37 I am wondering if it would be more helpful if you
hausner 2013/02/13 19:58:14 I thought it makes more sense to report it where t
+ "mixin class %s must extend class Object",
+ class_name.ToCString());
+ }
+
+ const Array& functions = Array::Handle(mixin_cls.functions());
+ Function& func = Function::Handle();
+ const intptr_t num_functions = functions.Length();
+ for (int i = 0; i < num_functions; i++) {
+ func ^= functions.At(i);
+ if (func.IsConstructor()) {
+ // A mixin class must not have explicit constructors.
+ if (!func.IsImplicitConstructor()) {
+ const Script& script = Script::Handle(cls.script());
+ ReportError(script, cls.token_pos(),
siva 2013/02/13 01:34:37 Ditto.
hausner 2013/02/13 19:58:14 Ditto.
+ "mixin class %s must not have constructors\n",
+ String::Handle(mixin_cls.Name()).ToCString());
+ }
+ continue; // Skip the implicit constructor.
+ }
+ // TODO(hausner): must check whether the function contains
+ // super calls. If so, report error.
+ if (!func.is_static()) {
+ func = func.Clone(cls);
+ cls.AddFunction(func);
siva 2013/02/13 01:34:37 Our AddFunction implementation is very inefficient
hausner 2013/02/13 19:58:14 I agree with what you suggest, but let me check it
+ }
+ }
+ Array& fields = Array::Handle(mixin_cls.fields());
+ Field& field = Field::Handle();
+ const GrowableObjectArray& cloned_fields =
+ GrowableObjectArray::Handle(GrowableObjectArray::New());
+ const intptr_t num_fields = fields.Length();
+ for (int i = 0; i < num_fields; i++) {
+ field ^= fields.At(i);
+ if (!field.is_static()) {
+ field = field.Clone(cls);
+ cloned_fields.Add(field);
+ }
+ }
+ fields = Array::MakeArray(cloned_fields);
siva 2013/02/13 01:34:37 Maybe we should assert here that ASSERT(cls.fields
hausner 2013/02/13 19:58:14 Done.
+ cls.SetFields(fields);
+}
+
+
// Recursively walks the graph of explicitly declared super type and
// interfaces, resolving unresolved super types and interfaces.
// Reports an error if there is an interface reference that cannot be
@@ -1267,16 +1322,24 @@
}
}
- // If the class/interface has no explicit super class/interfaces, we are done.
+ // If the class/interface has no explicit super class/interfaces
+ // and is not a mixin application, we are done.
Type& super_type = Type::Handle(cls.super_type());
+ Type& mixin_type = Type::Handle(cls.mixin());
Array& super_interfaces = Array::Handle(cls.interfaces());
if ((super_type.IsNull() || super_type.IsObjectType()) &&
- (super_interfaces.Length() == 0)) {
+ (super_interfaces.Length() == 0) &&
+ (mixin_type.IsNull())) {
return;
}
- // If cls belongs to core lib or to core lib's implementation, restrictions
- // about allowed interfaces are lifted.
+ if (!mixin_type.IsNull()) {
+ ResolveType(cls, mixin_type, kCanonicalizeWellFormed);
+ ApplyMixin(cls, mixin_type);
+ }
+
+ // If cls belongs to core lib, restrictions about allowed interfaces
+ // are lifted.
const bool cls_belongs_to_core_lib = cls.library() == Library::CoreLibrary();
// Resolve and check the super type and interfaces of cls.
@@ -1287,7 +1350,6 @@
// Resolve super type. Failures lead to a longjmp.
ResolveType(cls, super_type, kCanonicalizeWellFormed);
- // If cls belongs to core lib or to core lib's implementation, restrictions
interface_class = super_type.type_class();
// If cls belongs to core lib or to core lib's implementation, restrictions
// about allowed interfaces are lifted.
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/object.h » ('j') | runtime/vm/object.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698