end
end
+redef class MMImplicitInit
+ redef meth do_compile_inside(v, params)
+ do
+ var f = params.length - unassigned_attributes.length
+ var recv = params.first
+ for sp in super_inits do
+ assert sp isa MMMethod
+ var args_recv = [recv]
+ if sp == super_init then
+ var args = new Array[String].with_capacity(f)
+ args.add(recv)
+ for i in [1..f[ do
+ args.add(params[i])
+ end
+ sp.compile_call(v, args)
+ else
+ sp.compile_call(v, args_recv)
+ end
+ end
+ for i in [f..params.length[ do
+ var attribute = unassigned_attributes[i-f]
+ v.add_assignment(attribute.compile_access(v, recv), params[i])
+ end
+ return null
+ end
+end
+
redef class MMType
# Compile a subtype check to self
# Return a NIT Bool
end
# Collect visible constructors in super stateful classes
+ var super_inits = new ArraySet[MMLocalProperty]
var super_constructors = new ArraySet[MMGlobalProperty]
for sc in che.direct_greaters do
if sc.global.is_universal or sc.global.is_interface then continue
if not gp.is_init then continue
super_constructors.add(gp)
end
+ var gp = sc.get_property_by_name(once ("init".to_symbol))
+ if gp != null then
+ super_inits.add(self[gp])
+ end
+ end
+
+ # Collect unassigned attributes
+ var unassigned_attributes = new Array[MMSrcAttribute]
+ for a in src_local_properties do
+ if a isa MMSrcAttribute then
+ var n = a.node
+ assert n isa AAttrPropdef
+ if n.n_expr == null then unassigned_attributes.add(a)
+ end
end
if not super_constructors.is_empty then
end
end
_is_mixin = true
+ else
+ # v.error(nodes.first, "Error, constructor required in {self} since no anonimous init found in {sc}.")
+
+ # unassigned attributes, then implicit consructors are generated
+ var p = new MMImplicitInit(self, unassigned_attributes, super_inits.to_a)
+ add_src_local_property(v, p)
+ #print("Create implicit init {p} in {self} from {super_inits.join(", ")} + {unassigned_attributes.length} args")
end
end
do
end
end
+
+redef class MMImplicitInit
+ readable attr _super_init: MMLocalProperty = null
+ redef meth accept_property_visitor(v)
+ do
+ var base: MMLocalProperty = null
+ for p in super_inits do
+ if p.signature.arity > 0 then
+ if base == null then
+ base = p
+ else
+ v.error(null, "Error: explicit constructor needed in {local_class} since both super-constructor {base.full_name} and {p.full_name} have paramters")
+ return
+ end
+ end
+ end
+ _super_init = base
+
+ var params = new Array[MMType]
+ if base != null then
+ var sig = base.signature
+ for i in [0..sig.arity[ do
+ params.add(sig[i])
+ end
+ end
+ for a in unassigned_attributes do
+ params.add(a.signature.return_type)
+ end
+ signature = new MMSignature(params, null, local_class.get_type)
+ end
+end
+
+
# Concrete NIT class specialization relation
class MMSrcAncestor
special MMAncestor
end
end
+# Concrete NIT implicit constructor
+class MMImplicitInit
+special MMMethSrcMethod
+ redef meth is_init do return true
+ readable attr _unassigned_attributes: Array[MMSrcAttribute]
+ readable attr _super_inits: Array[MMLocalProperty]
+ init(cla: MMLocalClass, unassigned_attributes: Array[MMSrcAttribute], super_inits: Array[MMLocalProperty])
+ do
+ super(once "init".to_symbol, cla, null)
+ _unassigned_attributes = unassigned_attributes
+ _super_inits = super_inits
+ end
+end
# Local variable and method parameter
class Variable