test_phase: provide a simpler way to implement POC of nit tools
[nit.git] / src / modelize_property.nit
index 2f94421..1245af5 100644 (file)
@@ -158,6 +158,16 @@ redef class MClass
        var inherit_init_from: nullable MClass = null
 end
 
+redef class MClassDef
+       private var propdef_names = new HashSet[String]
+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
+       var has_supercall: Bool writable = false
+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
@@ -228,6 +238,12 @@ redef class APropdef
                return mvisibility
        end
 
+       private fun set_doc(mpropdef: MPropDef)
+       do
+               var ndoc = self.n_doc
+               if ndoc != null then mpropdef.mdoc = ndoc.to_mdoc
+       end
+
        private fun check_redef_property_visibility(modelbuilder: ModelBuilder, nclassdef: AClassdef, nvisibility: nullable AVisibility, mprop: MProperty)
        do
                if nvisibility == null then return
@@ -304,10 +320,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
@@ -396,6 +408,22 @@ 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)
+
+               set_doc(mpropdef)
+
                self.mpropdef = mpropdef
                modelbuilder.mpropdef2npropdef[mpropdef] = self
                if mpropdef.is_intro then
@@ -482,16 +510,6 @@ redef class AMethPropdef
                msignature = new MSignature(mparameters, ret_type)
                mpropdef.msignature = msignature
                mpropdef.is_abstract = self isa ADeferredMethPropdef
-
-               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
-
        end
 
        redef fun check_signature(modelbuilder, nclassdef)
@@ -521,9 +539,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
@@ -532,7 +550,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
@@ -584,6 +602,7 @@ redef class AAttrPropdef
                        var mpropdef = new MAttributeDef(mclassdef, mprop, self.location)
                        self.mpropdef = mpropdef
                        modelbuilder.mpropdef2npropdef[mpropdef] = self
+                       set_doc(mpropdef)
 
                        var nreadable = self.n_readable
                        if nreadable != null then
@@ -602,6 +621,7 @@ redef class AAttrPropdef
                                var mreadpropdef = new MMethodDef(mclassdef, mreadprop, self.location)
                                self.mreadpropdef = mreadpropdef
                                modelbuilder.mpropdef2npropdef[mreadpropdef] = self
+                               mreadpropdef.mdoc = mpropdef.mdoc
                        end
 
                        var nwritable = self.n_writable
@@ -621,6 +641,7 @@ redef class AAttrPropdef
                                var mwritepropdef = new MMethodDef(mclassdef, mwriteprop, self.location)
                                self.mwritepropdef = mwritepropdef
                                modelbuilder.mpropdef2npropdef[mwritepropdef] = self
+                               mwritepropdef.mdoc = mpropdef.mdoc
                        end
                else
                        # New attribute style
@@ -629,6 +650,7 @@ redef class AAttrPropdef
                        var mpropdef = new MAttributeDef(mclassdef, mprop, self.location)
                        self.mpropdef = mpropdef
                        modelbuilder.mpropdef2npropdef[mpropdef] = self
+                       set_doc(mpropdef)
 
                        var readname = name
                        var mreadprop = modelbuilder.try_get_mproperty_by_name(nid2, mclassdef, readname).as(nullable MMethod)
@@ -645,6 +667,7 @@ redef class AAttrPropdef
                        var mreadpropdef = new MMethodDef(mclassdef, mreadprop, self.location)
                        self.mreadpropdef = mreadpropdef
                        modelbuilder.mpropdef2npropdef[mreadpropdef] = self
+                       mreadpropdef.mdoc = mpropdef.mdoc
 
                        var writename = name + "="
                        var nwritable = self.n_writable
@@ -671,6 +694,7 @@ redef class AAttrPropdef
                        var mwritepropdef = new MMethodDef(mclassdef, mwriteprop, self.location)
                        self.mwritepropdef = mwritepropdef
                        modelbuilder.mpropdef2npropdef[mwritepropdef] = self
+                       mwritepropdef.mdoc = mpropdef.mdoc
                end
        end
 
@@ -687,8 +711,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)
@@ -717,6 +741,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
@@ -851,6 +883,7 @@ redef class ATypePropdef
 
                var mpropdef = new MVirtualTypeDef(mclassdef, mprop, self.location)
                self.mpropdef = mpropdef
+               set_doc(mpropdef)
        end
 
        redef fun build_signature(modelbuilder, nclassdef)
@@ -870,6 +903,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