modelize_property: Adding unsafe method to register an mpropdef
[nit.git] / src / modelize / modelize_property.nit
index aabe809..35e210e 100644 (file)
@@ -42,6 +42,17 @@ redef class ModelBuilder
        # Public clients need to use `mpropdef2node` to access stuff.
        private var mpropdef2npropdef = new HashMap[MPropDef, APropdef]
 
+       # Associate a `npropdef` with its `mpropdef`
+       #
+       # Be careful, this method is unsafe, no checking is done when it's used.
+       # The safe way to add method it's to use the `build_property`
+       #
+       # See `mpropdef2npropdef`
+       fun unsafe_add_mpropdef2npropdef(mpropdef: MPropDef,npropdef: APropdef)
+       do
+               mpropdef2npropdef[mpropdef] = npropdef
+       end
+
        # Retrieve the associated AST node of a mpropertydef.
        # This method is used to associate model entity with syntactic entities.
        #
@@ -1463,9 +1474,7 @@ redef class AAttrPropdef
                        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
+                       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")
@@ -1489,6 +1498,35 @@ redef class AAttrPropdef
                                abort
                        end
                        if cla != null then mtype = cla.mclass_type
+               else if nexpr isa AArrayExpr and nexpr.n_type == null and nexpr.n_exprs.not_empty then
+                       # Non-empty arrays without an explicit type
+
+                       var item_mtypes = new Set[MType]
+                       var fails = false
+                       for node in nexpr.n_exprs do
+                               var item_mtype = infer_static_type(modelbuilder, node, mclassdef, mmodule, mreadpropdef)
+                               if item_mtype == null then
+                                       fails = true
+                               else
+                                       item_mtypes.add item_mtype
+                               end
+                       end
+
+                       if fails then return null # Failed to infer some types
+
+                       if item_mtypes.length > 1 then
+                               modelbuilder.error(self, "Type Error: ambiguous array type {item_mtypes.join(" ")}")
+                       end
+
+                       mtype = mmodule.array_type(item_mtypes.first)
+               else if nexpr isa AUminusExpr and (nexpr.n_expr isa AIntegerExpr or nexpr.n_expr isa AFloatExpr) then
+                       # The Int and Float unary - is defined in `kernel`, so this may
+                       # result in an invalid behavior when using a custom kernel.
+                       # A workaround is to declare the attribute static type.
+                       # This is still very useful, especially to novice programmers.
+                       mtype = infer_static_type(modelbuilder, nexpr.n_expr, mclassdef, mmodule, mreadpropdef)
+               else if nexpr isa AOnceExpr then
+                       mtype = infer_static_type(modelbuilder, nexpr.n_expr, mclassdef, mmodule, mreadpropdef)
                else
                        modelbuilder.error(self, "Error: untyped attribute `{mreadpropdef}`. Implicit typing allowed only for literals and new.")
                end