X-Git-Url: http://nitlanguage.org diff --git a/src/modelize/modelize_property.nit b/src/modelize/modelize_property.nit index d291ec3..aabe809 100644 --- a/src/modelize/modelize_property.nit +++ b/src/modelize/modelize_property.nit @@ -769,22 +769,21 @@ redef class AMethPropdef do var n_kwinit = n_kwinit var n_kwnew = n_kwnew - var is_init = n_kwinit != null or n_kwnew != null + var is_new = n_kwnew != null + var is_init = n_kwinit != null or is_new var name: String var amethodid = self.n_methid var name_node: ANode if amethodid == null then - if not is_init then - name = "main" - name_node = self - else if n_kwinit != null then + if n_kwinit != null then name = "init" name_node = n_kwinit else if n_kwnew != null then name = "new" name_node = n_kwnew else - abort + name = "main" + name_node = self end else if amethodid isa AIdMethid then name = amethodid.n_id.text @@ -828,8 +827,8 @@ redef class AMethPropdef mprop.is_root_init = true end mprop.is_init = is_init - mprop.is_new = n_kwnew != null - if mprop.is_new then mclassdef.mclass.has_new_factory = true + mprop.is_new = is_new + if is_new then mclassdef.mclass.has_new_factory = true if name == "sys" then mprop.is_toplevel = true # special case for sys allowed in `new` factories if not self.check_redef_keyword(modelbuilder, mclassdef, n_kwredef, false, mprop) then mprop.is_broken = true @@ -1207,6 +1206,12 @@ redef class AAttrPropdef end mclassdef.mprop2npropdef[mreadprop] = self + var attr_mpropdef = mpropdef + if attr_mpropdef != null then + mreadprop.getter_for = attr_mpropdef.mproperty + attr_mpropdef.mproperty.getter = mreadprop + end + var mreadpropdef = new MMethodDef(mclassdef, mreadprop, self.location) self.mreadpropdef = mreadpropdef modelbuilder.mpropdef2npropdef[mreadpropdef] = self @@ -1313,6 +1318,11 @@ redef class AAttrPropdef end mclassdef.mprop2npropdef[mwriteprop] = self + if attr_mpropdef != null then + mwriteprop.setter_for = attr_mpropdef.mproperty + attr_mpropdef.mproperty.setter = mwriteprop + end + var mwritepropdef = new MMethodDef(mclassdef, mwriteprop, self.location) self.mwritepropdef = mwritepropdef modelbuilder.mpropdef2npropdef[mwritepropdef] = self @@ -1368,66 +1378,7 @@ redef class AAttrPropdef var nexpr = self.n_expr if mtype == null then if nexpr != null then - if nexpr isa ANewExpr then - mtype = modelbuilder.resolve_mtype_unchecked(mclassdef, nexpr.n_type, true) - else if nexpr isa AAsCastExpr then - mtype = modelbuilder.resolve_mtype_unchecked(mclassdef, nexpr.n_type, true) - else if nexpr isa AIntegerExpr then - var cla: nullable MClass = null - if nexpr.value isa Int then - cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Int") - else if nexpr.value isa Byte then - cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Byte") - else if nexpr.value isa Int8 then - cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Int8") - else if nexpr.value isa Int16 then - cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Int16") - else if nexpr.value isa UInt16 then - cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "UInt16") - else if nexpr.value isa Int32 then - cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Int32") - else if nexpr.value isa UInt32 then - cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "UInt32") - else - # Should not happen, and should be updated as new types are added - abort - end - if cla != null then mtype = cla.mclass_type - else if nexpr isa AFloatExpr then - var cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Float") - if cla != null then mtype = cla.mclass_type - else if nexpr isa ACharExpr then - var cla: nullable MClass - if nexpr.is_ascii then - cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Byte") - else if nexpr.is_code_point then - cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Int") - else - cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Char") - end - if cla != null then mtype = cla.mclass_type - else if nexpr isa ABoolExpr then - var cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Bool") - if cla != null then mtype = cla.mclass_type - else if nexpr isa ASuperstringExpr then - var cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "String") - if cla != null then mtype = cla.mclass_type - else if nexpr isa AStringFormExpr then - var cla: nullable MClass - if nexpr.is_bytestring then - cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Bytes") - else if nexpr.is_re then - cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Regex") - else if nexpr.is_string then - cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "String") - else - abort - end - if cla != null then mtype = cla.mclass_type - else - modelbuilder.error(self, "Error: untyped attribute `{mreadpropdef}`. Implicit typing allowed only for literals and new.") - end - + mtype = infer_static_type(modelbuilder, nexpr, mclassdef, mmodule, mreadpropdef) if mtype == null then return end else if ntype != null and inherited_type == mtype then @@ -1475,6 +1426,75 @@ redef class AAttrPropdef check_repeated_types(modelbuilder) end + # Detect the static type from the value assigned to the attribute `self` + # + # Return the static type if it can be safely inferred. + private fun infer_static_type(modelbuilder: ModelBuilder, nexpr: AExpr, + mclassdef: MClassDef, mmodule: MModule, mreadpropdef: MPropDef): nullable MType + do + var mtype = null + if nexpr isa ANewExpr then + mtype = modelbuilder.resolve_mtype_unchecked(mclassdef, nexpr.n_type, true) + else if nexpr isa AAsCastExpr then + mtype = modelbuilder.resolve_mtype_unchecked(mclassdef, nexpr.n_type, true) + else if nexpr isa AIntegerExpr then + var cla: nullable MClass = null + if nexpr.value isa Int then + cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Int") + else if nexpr.value isa Byte then + cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Byte") + else if nexpr.value isa Int8 then + cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Int8") + else if nexpr.value isa Int16 then + cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Int16") + else if nexpr.value isa UInt16 then + cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "UInt16") + else if nexpr.value isa Int32 then + cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Int32") + else if nexpr.value isa UInt32 then + cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "UInt32") + else + # Should not happen, and should be updated as new types are added + abort + end + if cla != null then mtype = cla.mclass_type + else if nexpr isa AFloatExpr then + var cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Float") + if cla != null then mtype = cla.mclass_type + else if nexpr isa ACharExpr then + var cla: nullable MClass + if nexpr.is_ascii then + cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Byte") + else if nexpr.is_code_point then + cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Int") + else + cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Char") + end + if cla != null then mtype = cla.mclass_type + else if nexpr isa ABoolExpr then + var cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Bool") + if cla != null then mtype = cla.mclass_type + else if nexpr isa ASuperstringExpr then + var cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "String") + if cla != null then mtype = cla.mclass_type + else if nexpr isa AStringFormExpr then + var cla: nullable MClass + if nexpr.is_bytestring then + cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Bytes") + else if nexpr.is_re then + cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Regex") + else if nexpr.is_string then + cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "String") + else + abort + end + if cla != null then mtype = cla.mclass_type + else + modelbuilder.error(self, "Error: untyped attribute `{mreadpropdef}`. Implicit typing allowed only for literals and new.") + end + return mtype + end + redef fun check_signature(modelbuilder) do var mpropdef = self.mpropdef