file.write("class {self}\n")
for p in global_properties do
var lp = self[p]
- file.write("\t{lp}{lp.signature}\n")
+ file.write("\t{lp}{lp.signature_for(get_type)}\n")
end
file.write("end # {self}\n")
end
redef meth do_compile_inside(v, method, params)
do
var orig_meth: MMLocalProperty = method.global.intro
- var orig_sig = orig_meth.signature.adaptation_to(method.signature.recv)
+ var orig_sig = orig_meth.signature_for(method.signature.recv)
if n_signature != null then
var sig = n_signature
assert sig isa ASignature
# The global property where belong the local property
readable attr _global: MMGlobalProperty
- # The original property where self is derived
- # May be null if self is an original one
- readable attr _super_prop: MMLocalProperty
-
# The concrete property
# May be self if self is a concrete property
readable attr _concrete_property: MMConcreteProperty
meth is_generic: Bool do return arity > 0
end
-redef class MMSignature
- # Adapt the signature to a different receiver
- meth adaptation_to(r: MMType): MMSignature
- do
- if _recv == r then
- return self
- end
- var mod = r.module
- var p = _params
- if p != null then
- p = new Array[MMType]
- for i in _params do
- p.add(i.for_module(mod).adapt_to(r))
- end
- end
- var rv = _return_type
- if rv != null then
- rv = rv.for_module(mod).adapt_to(r)
- end
- return new MMSignature(p,rv,r)
- end
-end
-
-redef class MMLocalProperty
- # The receiver type if the signature is unknown (aka lazily computed)
- attr _recv_alone: MMType
-
- meth recv: MMType
- do
- assert signature != null
- return signature.recv
- end
-
- meth recv=(rec: MMType)
- do
- assert rec != null
- # print("setting recv for {self} {rec} {_recv == null}")
- assert _signature_cache == null
- _recv_alone = rec
- end
-
- redef meth signature
- do
- var sig = _signature_cache
- if sig != null then
- return sig
- end
- if self isa MMConcreteProperty then
- return null
- end
- var sp = _super_prop
- #assert self != sp
- var impl = _concrete_property
- if sp == null then # superprop ?
- # print("building signature for {self}:{self.object_id} and type {_recv}")
- _signature_cache = impl.signature
- assert _signature_cache != null
- else
- # print("adapting signature for {self}:{self.object_id} and type {_recv}")
- assert sp.signature != null
- assert _recv_alone != null
- #_signature = sp.signature
- _signature_cache = sp.signature.adaptation_to(_recv_alone)
- end
- assert _signature_cache != null
- # print("finally recv is {_recv} for {self}:{self.object_id} and sig is {_signature.recv}")
- return _signature_cache
- end
-
- # Adapt the property to a different receiver
- # TODO: Merge with inheritance stuff
- meth adapt_property(t: MMType): MMLocalProperty
- do
- assert t != null
- var recv = local_class.get_type
- if t == recv then
- return self
- else
- return inherit_to(t)
- end
- end
-
- redef meth inherit_from(s, t) # for the super bugs
- do
- super
- _recv_alone = t
- end
-end
-
redef class MMType
# TODO: IS this useful?
meth is_generic: Bool is abstract
assert _local_class != null
var p = _local_class[g]
if p != null then
- var p2 = p.adapt_property(self)
- _props[g] = p2
- return p2
+ #var p2 = p.adapt_property(self)
+ #_props[g] = p2
+ #return p2
+ return p
else
assert false
end
redef meth adapt_to(r)
do
+ r = r.direct_type
var old_r = r.upcast_for(def_class)
- #print "adapt {self} for ({old_r} -> {r})"
+ #if not old_r isa MMTypeGeneric then
+ # print "adapt {self}'{def_class}'{self.module} to {r}'{r.module}"
+ # print " old_r = {old_r}'{old_r.module}"
+ #end
assert old_r isa MMTypeGeneric
var reduct = old_r.params[position]
assert reduct != null
assert a.local_class != self
var sup = a.select_property(glob) # Select super prop
assert sup != null
- var prop = sup.inherit_to(get_type) # special the new prop
- return prop
+ return sup
end
end
# What the next line used for?
g.add_concrete_property(concrete_property, g.get_compatible_concrete_properties_for(local_class))
end
-
- # Create an adaptation of self to a different receiver
- meth inherit_to(t: MMType): MMLocalProperty is abstract
-
- # ?
- protected meth inherit_from(s: MMLocalProperty, t: MMType) # for the super bugs
- do
- assert _super_prop == null
- _super_prop = s
- if _global == null then
- set_global(s.global)
- end
- end
-
-end
-
-redef class MMMethod
- redef meth inherit_to(t) do
- return new MMImplicitMethod(self, t)
- end
-end
-
-# A local property that is an adatation of an exiting one
-class MMImplicitProperty
-special MMLocalProperty
- # Create a property from an existing property and a new receiver
- init(prop: MMLocalProperty, bt: MMType)
- do
- super(prop.name, bt.local_class, prop.concrete_property)
- inherit_from(prop, bt)
- end
-end
-
-class MMImplicitMethod
-special MMMethod
-special MMImplicitProperty
- init(p, t) do super
-end
-
-redef class MMAttribute
- redef meth inherit_to(t)
- do
- return new MMImplicitAttribute(self,t)
- end
-end
-
-class MMImplicitAttribute
-special MMAttribute
-special MMImplicitProperty
- init(p, t) do super
end
redef class MMAncestor
end
redef class MMLocalProperty
- # The cached result of signature
- attr _signature_cache: MMSignature
-
- # return signature for this property
- meth signature: MMSignature # FIXME must rewrite
- do
- if _signature_cache == null then
- if _super_prop == null then
- _signature_cache = _concrete_property.signature
- else
- _signature_cache = _super_prop.signature
- end
- end
- assert _signature_cache != null
- return _signature_cache
+ # The signature of the property (where it is declared)
+ readable writable attr _signature: MMSignature
+
+ # Return the adapted signature of self for a receiver of type t
+ meth signature_for(t: MMType): MMSignature do
+ var x = self
+ assert x isa MMConcreteProperty
+ return x.signature.adaptation_to(t)
end
-
- meth signature=(s: MMSignature) do _signature_cache = s
end
# Signature for local properties
return s
end
+ # Adapt the signature to a different receiver
+ meth adaptation_to(r: MMType): MMSignature
+ do
+ if _recv == r then
+ return self
+ end
+ var mod = r.module
+ var p = _params
+ if p != null then
+ p = new Array[MMType]
+ for i in _params do
+ p.add(i.for_module(mod).adapt_to(r))
+ end
+ end
+ var rv = _return_type
+ if rv != null then
+ rv = rv.for_module(mod).adapt_to(r)
+ end
+ return new MMSignature(p,rv,r)
+ end
+
init(params: Array[MMType], return_type: MMType, r: MMType)
do
assert params != null
# Virtual type properties
class MMTypeProperty
special MMLocalProperty
- redef meth inherit_to(t)
+ # The virtual static type associated
+ meth stype_for(recv: MMType): MMVirtualType
do
- return new MMImplicitType(self, t)
+ var prop = recv.select_property(global)
+ assert prop isa MMTypeProperty
+ return prop.real_stype_for(recv)
end
- # Cached result of stype
- attr _stype_cache: MMVirtualType
+ # Cached results of stype
+ attr _stypes_cache: HashMap[MMType, MMVirtualType] = new HashMap[MMType, MMVirtualType]
- # The virtual static type associated
- meth stype: MMVirtualType
+ private meth real_stype_for(recv: MMType): MMVirtualType
do
# If the signature is not build: Circular definition
if signature == null then return null
- var r = _stype_cache
- if r == null then
- r = new MMVirtualType(self)
- _stype_cache = r
- end
- return r
+ if _stypes_cache.has_key(recv) then return _stypes_cache[recv]
+
+ var res = new MMVirtualType(self, recv)
+ _stypes_cache[recv] = res
+
+ return res
end
end
# The property associed
readable attr _property: MMTypeProperty
- protected init(p: MMTypeProperty)
+ # The receiver type
+ readable attr _recv: MMType
+
+ protected init(p: MMTypeProperty, recv: MMType)
do
- super(p.name, p.signature.return_type)
+ super(p.name, p.signature_for(recv).return_type)
_property = p
+ _recv = recv
end
+ redef meth module do return _recv.module
+
redef meth for_module(mod)
do
- var recv = _property.signature.recv.for_module(mod)
- return adapt_to(recv)
+ if mod == module then return self
+ return adapt_to(recv.for_module(mod))
end
redef meth not_for_self
redef meth adapt_to(recv)
do
- # print "adapt {self} from {_property.signature.recv.module}::{_property.signature.recv} to {recv.module}::{recv}"
- var prop = recv.select_property(_property.global)
- assert prop isa MMTypeProperty
- return prop.stype
+ return property.stype_for(recv)
end
end
return null
end
end
-
-class MMImplicitType
-special MMTypeProperty
-special MMImplicitProperty
- init(p, t) do super
-end
do
var s = prop.signature
for ip in supers do
+ assert ip isa MMConcreteProperty
var isig = ip.signature.adaptation_to(v.local_class.get_type)
if s == null then
if subtype < stype then
return true
end
+ #error(n, "Type error: expected {stype}'{stype.module}, got {subtype}'{subtype.module}")
+ #abort
error(n, "Type error: expected {stype}, got {subtype}")
return false
end
v.error(self, "Type error: formal type {name} cannot have formal parameters.")
return null
end
- var t = cla.get_type.select_virtual_type(name).stype
+ var t = cla.get_type.select_virtual_type(name).stype_for(cla.get_type)
if t == null then
v.error(self, "Type error: circular definition in formal type {name}.")
return null
init(tc, module) do super
- private meth get_default_constructor_for(n: PNode, c: MMLocalClass, prop: MMMethod): MMMethod
+ private meth get_default_constructor_for(n: PNode, c: MMLocalClass, prop: MMSrcMethod): MMMethod
do
var v = self
#var prop = v.local_property
if not g.is_init then continue
if g.intro.local_class != c then continue
var gp = c[g]
- assert gp isa MMMethod
+ assert gp isa MMSrcMethod
var garity = gp.signature.arity
if prop != null and g.intro.name == prop.name then
if garity == 0 or prop.signature < gp.signature then
v.error(self, "Error: Collection MUST have an iterate method")
return
end
- var iter_type = prop.signature.return_type
+ var iter_type = prop.signature_for(expr_type).return_type
var prop2 = iter_type.select_method(once ("item".to_symbol))
if prop2 == null then
v.error(self, "Error: {iter_type} MUST have an item method")
return
end
- var t = prop2.signature.return_type
+ var t = prop2.signature_for(iter_type).return_type
if not n_expr.is_self then t = t.not_for_self
va.stype = t
end
return
end
prop.global.check_visibility(v, self, v.module, false)
- var psig = prop.signature
+ var psig = prop.signature_for(type_lvalue)
_assign_method = prop
- v.check_conform(self, n_value.stype, psig[0].not_for_self)
+ v.check_conform(n_value, n_value.stype, psig[0].not_for_self)
v.check_conform(self, psig.return_type.not_for_self, n_value.stype)
end
_init_in_superclass = p
register_super_init_call(v, p)
if n_args.length > 0 then
- _arguments = process_signature(v, p, true, n_args.to_a)
+ _arguments = process_signature(v, v.self_type, p, true, n_args.to_a)
end
else
v.error(self, "Error: No super method to call for {v.local_property}.")
return
end
- if precs.first.signature.return_type != null then
+ if precs.first.signature_for(v.self_type).return_type != null then
var stypes = new Array[MMType]
var stype: MMType = null
for prop in precs do
assert prop isa MMMethod
- var t = prop.signature.return_type.for_module(v.module).adapt_to(v.local_property.signature.recv)
+ var t = prop.signature_for(v.self_type).return_type.for_module(v.module).adapt_to(v.local_property.signature.recv)
stypes.add(t)
if stype == null or stype < t then
stype = t
# Attribute accessed
readable attr _prop: MMAttribute
+ # Attribute type of the acceded attribute
+ readable attr _attr_type: MMType
+
# Compute the attribute accessed
private meth do_typing(v: TypingVisitor)
do
v.error(self, "Error: Attribute {name} from {prop.global.local_class.module} is invisible in {v.module}")
end
_prop = prop
+ var at = prop.signature_for(type_recv).return_type
+ if not n_expr.is_self then at = at.not_for_self
+ _attr_type = at
end
end
if prop == null then
return
end
- var attr_type = prop.signature.return_type
- if not n_expr.is_self then attr_type = attr_type.not_for_self
_stype = attr_type
end
end
if prop == null then
return
end
- var attr_type = prop.signature.return_type
- if not n_expr.is_self then attr_type = attr_type.not_for_self
v.check_conform(self, n_value.stype, attr_type)
end
end
if prop == null then
return
end
- var attr_type = prop.signature.return_type
- if not n_expr.is_self then attr_type = attr_type.not_for_self
do_lvalue_typing(v, attr_type)
end
end
do
var prop = get_property(v, type_recv, is_implicit_self, name)
if prop == null then return
- var args = process_signature(v, prop, recv_is_self, raw_args)
+ var args = process_signature(v, type_recv, prop, recv_is_self, raw_args)
if args == null then return
_prop = prop
_arguments = args
return prop
end
- private meth process_signature(v: TypingVisitor, prop: MMMethod, recv_is_self: Bool, raw_args: Array[PExpr]): Array[PExpr]
+ private meth process_signature(v: TypingVisitor, type_recv: MMType, prop: MMMethod, recv_is_self: Bool, raw_args: Array[PExpr]): Array[PExpr]
do
prop.global.check_visibility(v, self, v.module, recv_is_self)
- var psig = prop.signature
+ var psig = prop.signature_for(type_recv)
var par_vararg = psig.vararg_rank
var par_arity = psig.arity
var raw_arity: Int
register_super_init_call(v, prop)
end
end
- var t = prop.signature.return_type
+ var t = prop.signature_for(n_expr.stype).return_type
if t != null and not n_expr.is_self then t = t.not_for_self
_stype = t
end
v.error(self, "Error: constructor {prop} is not invoken on 'self'.")
end
end
- var t = prop.signature.return_type
+ var t = prop.signature_for(n_expr.stype).return_type
if not n_expr.is_self then t = t.not_for_self
do_lvalue_typing(v, t)