# FIXME: why not refine the `MPropDef` class with a nullable attribute?
var mpropdef2npropdef = new HashMap[MPropDef, APropdef]
+ # Retrieve the associated AST node of a mpropertydef.
+ # This method is used to associate model entity with syntactic entities.
+ #
+ # If the property definition is not associated with a node, returns node.
+ fun mpropdef2node(mpropdef: MPropDef): nullable ANode
+ do
+ var res: nullable ANode = mpropdef2npropdef.get_or_null(mpropdef)
+ if res != null then return res
+ if mpropdef isa MMethodDef and mpropdef.mproperty.is_root_init then
+ res = mclassdef2nclassdef.get_or_null(mpropdef.mclassdef)
+ if res != null then return res
+ end
+ return null
+ end
+
+ # Retrieve all the attributes nodes localy definied
+ # FIXME think more about this method and how the separations separate/global and ast/model should be done.
+ fun collect_attr_propdef(mclassdef: MClassDef): Array[AAttrPropdef]
+ do
+ var res = new Array[AAttrPropdef]
+ var n = mclassdef2nclassdef.get_or_null(mclassdef)
+ if n == null then return res
+ for npropdef in n.n_propdefs do
+ if npropdef isa AAttrPropdef then
+ res.add(npropdef)
+ end
+ end
+ return res
+ end
+
# Build the properties of `nclassdef`.
# REQUIRE: all superclasses are built.
private fun build_properties(nclassdef: AClassdef)
mprop.is_init = is_init
mprop.is_new = n_kwnew != null
if parent isa ATopClassdef then mprop.is_toplevel = true
- if not self.check_redef_keyword(modelbuilder, mclassdef, n_kwredef, false, mprop) then return
+ self.check_redef_keyword(modelbuilder, mclassdef, n_kwredef, false, mprop)
else
if not mprop.is_root_init and not self.check_redef_keyword(modelbuilder, mclassdef, n_kwredef, not self isa AMainMethPropdef, mprop) then return
check_redef_property_visibility(modelbuilder, self.n_visibility, mprop)
if mtype == null then return
end
+ var inherited_type: nullable MType = null
# Inherit the type from the getter (usually an abstract getter)
- if mtype == null and mreadpropdef != null and not mreadpropdef.is_intro then
+ if mreadpropdef != null and not mreadpropdef.is_intro then
var msignature = mreadpropdef.mproperty.intro.msignature
if msignature == null then return # Error, thus skipped
- mtype = msignature.return_mtype
+ inherited_type = msignature.return_mtype
+ if mtype == null then mtype = inherited_type
end
var nexpr = self.n_expr
if mtype == null then return
end
- else if ntype != null then
+ else if ntype != null and inherited_type == mtype then
if nexpr isa ANewExpr then
var xmtype = modelbuilder.resolve_mtype(mmodule, mclassdef, nexpr.n_type)
if xmtype == mtype then