X-Git-Url: http://nitlanguage.org diff --git a/src/modelize/modelize_property.nit b/src/modelize/modelize_property.nit index 53af250..28e6a03 100644 --- a/src/modelize/modelize_property.nit +++ b/src/modelize/modelize_property.nit @@ -82,8 +82,6 @@ redef class ModelBuilder # Are we a refinement if not mclassdef.is_intro then return - var mmodule = nclassdef.mclassdef.mmodule - # Look for the init in Object, or create it if mclassdef.mclass.name == "Object" and the_root_init_mmethod == null then # Create the implicit root-init method @@ -112,46 +110,38 @@ redef class ModelBuilder if mpropdef.mproperty.is_root_init then assert defined_init == null defined_init = mpropdef - else - # An explicit old-style init, so return + else if mpropdef.mproperty.name == "init" then + # An explicit old-style init named "init", so return return end end if not nclassdef isa AStdClassdef then return - # Do we inherit a old-style constructor? - var combine = new Array[MMethod] # old-style constructors without arguments - var inhc: nullable MClass = null # single super-class with a constructor with arguments - if defined_init == null then for st in mclassdef.supertypes do - var c = st.mclass - if not c.kind.need_init then continue - st = st.anchor_to(mmodule, mclassdef.bound_mtype) - var candidate = self.try_get_mproperty_by_name2(nclassdef, mmodule, st, "init").as(nullable MMethod) - if candidate != null then - if candidate.is_root_init then continue - if candidate.intro.msignature != null then - if candidate.intro.msignature.arity == 0 then - combine.add(candidate) - continue - end - end - end - var inhc2 = c.inherit_init_from - if inhc2 == null then inhc2 = c - if inhc2 == inhc then continue - if inhc != null then - self.error(nclassdef, "Error: Cannot provide a defaut constructor: conflict for {inhc} and {c}") - else - inhc = inhc2 - end - end - # Collect undefined attributes var mparameters = new Array[MParameter] var initializers = new Array[MProperty] - var anode: nullable ANode = null for npropdef in nclassdef.n_propdefs do + if npropdef isa AMethPropdef then + if npropdef.mpropdef == null then return # Skip broken attribute + var at = npropdef.get_single_annotation("autoinit", self) + if at == null then continue # Skip non tagged init + + var sig = npropdef.mpropdef.msignature + if sig == null then continue # Skip broken method + + if not npropdef.mpropdef.is_intro then + self.error(at, "Error: `autoinit` cannot be set on redefinitions") + continue + end + + for param in sig.mparameters do + var ret_type = param.mtype + var mparameter = new MParameter(param.name, ret_type, false) + mparameters.add(mparameter) + end + initializers.add(npropdef.mpropdef.mproperty) + end if npropdef isa AAttrPropdef then if npropdef.mpropdef == null then return # Skip broken attribute var at = npropdef.get_single_annotation("noinit", self) @@ -176,49 +166,12 @@ redef class ModelBuilder # Add the setter to the list initializers.add(msetter.mproperty) end - if anode == null then anode = npropdef - end - end - if anode == null then anode = nclassdef - - if combine.is_empty and inhc != null then - if not mparameters.is_empty then - self.error(anode,"Error: {mclassdef} cannot inherit constructors from {inhc} because there is attributes without initial values: {mparameters.join(", ")}") - return end - - # TODO: actively inherit the consturctor - self.toolcontext.info("{mclassdef} inherits all constructors from {inhc}", 3) - #mclassdef.mclass.inherit_init_from = inhc - #return - end - - if not combine.is_empty and inhc != null then - self.error(nclassdef, "Error: Cannot provide a defaut constructor: conflict for {combine.join(", ")} and {inhc}") - return - end - if not combine.is_empty then - if mparameters.is_empty and combine.length == 1 then - # No need to create a local init, the inherited one is enough - inhc = combine.first.intro_mclassdef.mclass - mclassdef.mclass.inherit_init_from = inhc - self.toolcontext.info("{mclassdef} inherits all constructors from {inhc}", 3) - return - end - nclassdef.super_inits = combine - var mprop = new MMethod(mclassdef, "init", mclassdef.mclass.visibility) - var mpropdef = new MMethodDef(mclassdef, mprop, nclassdef.location) - var msignature = new MSignature(mparameters, null) - mpropdef.msignature = msignature - mprop.is_init = true - nclassdef.mfree_init = mpropdef - self.toolcontext.info("{mclassdef} gets a free empty constructor {mpropdef}{msignature}", 3) - return end if the_root_init_mmethod == null then return - # Look for nost-specific new-stype init definitions + # Look for most-specific new-stype init definitions var spropdefs = the_root_init_mmethod.lookup_super_definitions(mclassdef.mmodule, mclassdef.bound_mtype) if spropdefs.is_empty then toolcontext.fatal_error(nclassdef.location, "Fatal error: {mclassdef} does not specialize {the_root_init_mmethod.intro_mclassdef}. Possible duplication of the root class `Object`?") @@ -328,12 +281,6 @@ redef class ModelBuilder end end -redef class MClass - # The class whose self inherit all the constructors. - # FIXME: this is needed to implement the crazy constructor mixin thing of the of old compiler. We need to think what to do with since this cannot stay in the modelbuilder - var inherit_init_from: nullable MClass = null -end - redef class MPropDef # Does the MPropDef contains a call to super or a call of a super-constructor? # Subsequent phases of the frontend (esp. typing) set it if required @@ -342,9 +289,6 @@ end redef class AClassdef var build_properties_is_done: Bool = false - # The list of super-constructor to call at the start of the free constructor - # FIXME: this is needed to implement the crazy constructor thing of the of old compiler. We need to think what to do with since this cannot stay in the modelbuilder - var super_inits: nullable Collection[MMethod] = null # The free init (implicitely constructed by the class if required) var mfree_init: nullable MMethodDef = null @@ -404,8 +348,7 @@ redef class APropdef modelbuilder.error(nvisibility, "Error: The only legal visibility for properties in a private class is private.") else if mvisibility == private_visibility then assert nvisibility != null - # Not yet - # modelbuilder.warning(nvisibility, "Warning: private is unrequired since the only legal visibility for properties in a private class is private.") + modelbuilder.advice(nvisibility, "useless-visibility", "Warning: private is superfluous since the only legal visibility for properties in a private class is private.") end mvisibility = private_visibility end @@ -419,6 +362,8 @@ redef class APropdef var mdoc = ndoc.to_mdoc mpropdef.mdoc = mdoc mdoc.original_mentity = mpropdef + else if mpropdef.is_intro and mpropdef.mproperty.visibility >= protected_visibility then + modelbuilder.advice(self, "missing-doc", "Documentation warning: Undocumented property `{mpropdef.mproperty}`") end var at_deprecated = get_single_annotation("deprecated", modelbuilder) @@ -616,6 +561,10 @@ redef class AMethPropdef if not is_init or n_kwredef != null then mprop = modelbuilder.try_get_mproperty_by_name(name_node, mclassdef, name).as(nullable MMethod) if mprop == null and look_like_a_root_init(modelbuilder) then mprop = modelbuilder.the_root_init_mmethod + var nb = n_block + if nb isa ABlockExpr and nb.n_expr.is_empty and n_doc == null then + modelbuilder.advice(self, "useless-init", "Warning: useless empty init in {mclassdef}") + end end if mprop == null then var mvisibility = new_property_visibility(modelbuilder, mclassdef, self.n_visibility) @@ -955,8 +904,8 @@ redef class AAttrPropdef else if ntype != null then if nexpr isa ANewExpr then var xmtype = modelbuilder.resolve_mtype(mmodule, mclassdef, nexpr.n_type) - if xmtype == mtype and modelbuilder.toolcontext.opt_warn.value >= 2 then - modelbuilder.warning(ntype, "Warning: useless type definition") + if xmtype == mtype then + modelbuilder.advice(ntype, "useless-type", "Warning: useless type definition") end end end @@ -1094,7 +1043,7 @@ redef class ATypePropdef var mvisibility = new_property_visibility(modelbuilder, mclassdef, self.n_visibility) mprop = new MVirtualTypeProp(mclassdef, name, mvisibility) for c in name.chars do if c >= 'a' and c<= 'z' then - modelbuilder.warning(n_id, "Warning: lowercase in the virtual type {name}") + modelbuilder.warning(n_id, "bad-type-name", "Warning: lowercase in the virtual type {name}") break end if not self.check_redef_keyword(modelbuilder, mclassdef, self.n_kwredef, false, mprop) then return @@ -1173,7 +1122,7 @@ redef class ATypePropdef end if p.mclassdef.mclass == mclassdef.mclass then # Still a warning to pass existing bad code - modelbuilder.warning(n_type, "Redef Error: a virtual type cannot be refined.") + modelbuilder.warning(n_type, "refine-type", "Redef Error: a virtual type cannot be refined.") break end if not bound.is_subtype(mmodule, anchor, supbound) then