X-Git-Url: http://nitlanguage.org diff --git a/src/modelize_property.nit b/src/modelize_property.nit index 931551b..89eb0f3 100644 --- a/src/modelize_property.nit +++ b/src/modelize_property.nit @@ -35,10 +35,10 @@ end redef class ModelBuilder # Register the npropdef associated to each mpropdef - # FIXME: why not refine the MPropDef class with a nullable attribute? + # FIXME: why not refine the `MPropDef` class with a nullable attribute? var mpropdef2npropdef: HashMap[MPropDef, APropdef] = new HashMap[MPropDef, APropdef] - # Build the properties of `nclassdef'. + # Build the properties of `nclassdef`. # REQUIRE: all superclasses are built. private fun build_properties(nclassdef: AClassdef) do @@ -64,7 +64,7 @@ redef class ModelBuilder end # Introduce or inherit default constructor - # This is the last part of `build_properties'. + # This is the last part of `build_properties`. private fun process_default_constructors(nclassdef: AClassdef) do var mclassdef = nclassdef.mclassdef.as(not null) @@ -158,6 +158,10 @@ redef class MClass var inherit_init_from: nullable MClass = null end +redef class MClassDef + private var propdef_names = new HashSet[String] +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 @@ -167,7 +171,7 @@ redef class AClassdef # The free init (implicitely constructed by the class if required) var mfree_init: nullable MMethodDef = null - # What is the APropdef associated to a MProperty? + # What is the `APropdef` associated to a `MProperty`? # Used to check multiple definition of a property. var mprop2npropdef: Map[MProperty, APropdef] = new HashMap[MProperty, APropdef] end @@ -195,19 +199,25 @@ private class TextCollectorVisitor end redef class APropdef - private fun build_property(modelbuilder: ModelBuilder, nclassdef: AClassdef) - do - end - private fun build_signature(modelbuilder: ModelBuilder, nclassdef: AClassdef) - do - end - private fun check_signature(modelbuilder: ModelBuilder, nclassdef: AClassdef) - do - end + # The associated main model entity + type MPROPDEF: MPropDef + + # The associated propdef once build by a `ModelBuilder` + var mpropdef: nullable MPROPDEF writable + + private fun build_property(modelbuilder: ModelBuilder, nclassdef: AClassdef) is abstract + private fun build_signature(modelbuilder: ModelBuilder, nclassdef: AClassdef) is abstract + private fun check_signature(modelbuilder: ModelBuilder, nclassdef: AClassdef) is abstract private fun new_property_visibility(modelbuilder: ModelBuilder, nclassdef: AClassdef, nvisibility: nullable AVisibility): MVisibility do var mvisibility = public_visibility - if nvisibility != null then mvisibility = nvisibility.mvisibility + if nvisibility != null then + mvisibility = nvisibility.mvisibility + if mvisibility == intrude_visibility then + modelbuilder.error(nvisibility, "Error: intrude is not a legal visibility for properties.") + mvisibility = public_visibility + end + end if nclassdef.mclassdef.mclass.visibility == private_visibility then if mvisibility == protected_visibility then assert nvisibility != null @@ -298,10 +308,6 @@ redef class ASignature if self.ret_type == null then return false # Skip errir end - for nclosure in self.n_closure_decls do - if not nclosure.n_signature.visit_signature(modelbuilder, nclassdef) then return false - end - self.is_visited = true return true end @@ -318,6 +324,7 @@ redef class ASignature var mparameters = new Array[MParameter] for i in [0..param_names.length[ do var mparameter = new MParameter(param_names[i], param_types[i], i == vararg_rank) + self.n_params[i].mparameter = mparameter mparameters.add(mparameter) end @@ -326,12 +333,14 @@ redef class ASignature end end +redef class AParam + # The associated mparameter if any + var mparameter: nullable MParameter = null +end + redef class AMethPropdef - # The associated MMethodDef once build by a `ModelBuilder' - var mpropdef: nullable MMethodDef + redef type MPROPDEF: MMethodDef - # The associated super init if any - var super_init: nullable MMethod redef fun build_property(modelbuilder, nclassdef) do var is_init = self isa AInitPropdef @@ -387,6 +396,20 @@ redef class AMethPropdef var mpropdef = new MMethodDef(mclassdef, mprop, self.location) + if mclassdef.propdef_names.has(mprop.name) then + var loc: nullable Location = null + for i in mclassdef.mpropdefs do + if i.mproperty.name == mprop.name then + loc = i.location + break + end + end + if loc == null then abort + modelbuilder.error(self, "Error: a property {mprop} is already defined in class {mclassdef.mclass} at {loc}") + end + + mclassdef.propdef_names.add(mpropdef.mproperty.name) + self.mpropdef = mpropdef modelbuilder.mpropdef2npropdef[mpropdef] = self if mpropdef.is_intro then @@ -466,21 +489,13 @@ redef class AMethPropdef var mparameters = new Array[MParameter] for i in [0..param_names.length[ do var mparameter = new MParameter(param_names[i], param_types[i], i == vararg_rank) + if nsig != null then nsig.n_params[i].mparameter = mparameter mparameters.add(mparameter) end msignature = new MSignature(mparameters, ret_type) mpropdef.msignature = msignature - - if nsig != null then - for nclosure in nsig.n_closure_decls do - var clos_signature = nclosure.n_signature.build_signature(modelbuilder, nclassdef) - if clos_signature == null then return - var mparameter = new MParameter(nclosure.n_id.text, clos_signature, false) - msignature.mclosures.add(mparameter) - end - end - + mpropdef.is_abstract = self isa ADeferredMethPropdef end redef fun check_signature(modelbuilder, nclassdef) @@ -510,9 +525,9 @@ redef class AMethPropdef for i in [0..mysignature.arity[ do var myt = mysignature.mparameters[i].mtype var prt = msignature.mparameters[i].mtype - if not myt.is_subtype(mmodule, nclassdef.mclassdef.bound_mtype, prt) and + if not myt.is_subtype(mmodule, nclassdef.mclassdef.bound_mtype, prt) or not prt.is_subtype(mmodule, nclassdef.mclassdef.bound_mtype, myt) then - modelbuilder.error(nsig.n_params[i], "Redef Error: Wrong type for parameter `{mysignature.mparameters[i].name}'. found {myt}, expected {prt}.") + modelbuilder.error(nsig.n_params[i], "Redef Error: Wrong type for parameter `{mysignature.mparameters[i].name}'. found {myt}, expected {prt} as in {mpropdef.mproperty.intro}.") end end end @@ -521,7 +536,7 @@ redef class AMethPropdef # Inherit the return type ret_type = precursor_ret_type else if not ret_type.is_subtype(mmodule, nclassdef.mclassdef.bound_mtype, precursor_ret_type) then - modelbuilder.error(nsig.n_type.as(not null), "Redef Error: Wrong return type. found {ret_type}, expected {precursor_ret_type}.") + modelbuilder.error(nsig.n_type.as(not null), "Redef Error: Wrong return type. found {ret_type}, expected {precursor_ret_type} as in {mpropdef.mproperty.intro}.") end end end @@ -529,12 +544,12 @@ redef class AMethPropdef end redef class AAttrPropdef - # The associated MAttributeDef once build by a `ModelBuilder' - var mpropdef: nullable MAttributeDef + redef type MPROPDEF: MAttributeDef + # The associated getter (read accessor) if any - var mreadpropdef: nullable MMethodDef + var mreadpropdef: nullable MMethodDef writable # The associated setter (write accessor) if any - var mwritepropdef: nullable MMethodDef + var mwritepropdef: nullable MMethodDef writable redef fun build_property(modelbuilder, nclassdef) do var mclassdef = nclassdef.mclassdef.as(not null) @@ -676,8 +691,8 @@ redef class AAttrPropdef if mtype == null then return end + var nexpr = self.n_expr if mtype == null then - var nexpr = self.n_expr if nexpr != null then if nexpr isa ANewExpr then mtype = modelbuilder.resolve_mtype(nclassdef, nexpr.n_type) @@ -706,6 +721,14 @@ redef class AAttrPropdef else modelbuilder.error(self, "Error: Untyped attribute {mpropdef}") end + else + assert ntype != null + if nexpr isa ANewExpr then + var xmtype = modelbuilder.resolve_mtype(nclassdef, nexpr.n_type) + if xmtype == mtype and modelbuilder.toolcontext.opt_warn.value >= 2 then + modelbuilder.warning(ntype, "Warning: useless type definition") + end + end end if mtype == null then return @@ -816,8 +839,8 @@ redef class AAttrPropdef end redef class ATypePropdef - # The associated MVirtualTypeDef once build by a `ModelBuilder' - var mpropdef: nullable MVirtualTypeDef + redef type MPROPDEF: MVirtualTypeDef + redef fun build_property(modelbuilder, nclassdef) do var mclassdef = nclassdef.mclassdef.as(not null) @@ -826,6 +849,10 @@ redef class ATypePropdef if mprop == null then var mvisibility = new_property_visibility(modelbuilder, nclassdef, self.n_visibility) mprop = new MVirtualTypeProp(mclassdef, name, mvisibility) + for c in name do if c >= 'a' and c<= 'z' then + modelbuilder.warning(n_id, "Warning: lowercase in the virtual type {name}") + break + end if not self.check_redef_keyword(modelbuilder, nclassdef, self.n_kwredef, false, mprop) then return else if not self.check_redef_keyword(modelbuilder, nclassdef, self.n_kwredef, true, mprop) then return @@ -855,6 +882,9 @@ redef class ATypePropdef redef fun check_signature(modelbuilder, nclassdef) do + var mpropdef = self.mpropdef + if mpropdef == null then return # Error thus skiped + var bound = self.mpropdef.bound # Fast case: the bound is not a formal type