nullable: convert lib, tools and tests
[nit.git] / src / compiling / compiling_global.nit
index c9dea50..96837be 100644 (file)
@@ -23,7 +23,7 @@ private import syntax
 
 # Something that store color of table elements
 class ColorContext
-       attr _colors: HashMap[TableElt, Int] = null
+       attr _colors: HashMap[TableElt, Int] = new HashMap[TableElt, Int]
 
        # The color of a table element.
        meth color(e: TableElt): Int
@@ -34,13 +34,12 @@ class ColorContext
        # Is a table element already colored?
        meth has_color(e: TableElt): Bool
        do
-               return _colors != null and _colors.has_key(e)
+               return _colors.has_key(e)
        end
 
        # Assign a color to a table element.
        meth color=(e: TableElt, c: Int)
        do
-               if _colors == null then _colors = new HashMap[TableElt, Int]
                _colors[e] = c
                var idx = c
                for i in [0..e.length[ do
@@ -54,17 +53,16 @@ end
 class GlobalAnalysis
 special ColorContext
        # Associate global classes to compiled classes
-       readable attr _compiled_classes: HashMap[MMGlobalClass, CompiledClass] 
+       readable attr _compiled_classes: HashMap[MMGlobalClass, CompiledClass] = new HashMap[MMGlobalClass, CompiledClass]
 
        # The main module of the program globally analysed
-       readable attr _module: MMModule 
+       readable attr _module: MMModule
 
        # FIXME: do something better.
-       readable writable attr _max_class_table_length: Int
+       readable writable attr _max_class_table_length: Int = 0
 
        init(module: MMSrcModule)
        do
-               _compiled_classes = new HashMap[MMGlobalClass, CompiledClass]
                _module = module
        end
 end
@@ -84,48 +82,48 @@ end
 class CompiledClass
 special ColorContext
        # The corresponding local class in the main module of the prgram
-       readable attr _local_class: MMLocalClass 
+       readable attr _local_class: MMLocalClass
 
        # The identifier of the class
-       readable writable attr _id: Int 
+       readable writable attr _id: Int = 0
 
        # The full class table of the class
-       readable writable attr _class_table: Array[TableElt] 
+       readable attr _class_table: Array[nullable TableElt] = new Array[nullable TableElt]
 
        # The full instance table of the class
-       readable writable attr _instance_table: Array[TableElt] 
+       readable attr _instance_table: Array[nullable TableElt] = new Array[nullable TableElt]
 
        # The proper class table part (no superclasses but all refinements)
-       readable writable attr _class_layout: TableEltComposite 
+       readable writable attr _class_layout: TableEltComposite = new TableEltComposite(self)
 
        # The proper instance table part (no superclasses but all refinements)
-       readable writable attr _instance_layout: TableEltComposite 
+       readable writable attr _instance_layout: TableEltComposite = new TableEltComposite(self)
 
        init(c: MMLocalClass) do _local_class = c
 end
 
 redef class MMSrcLocalClass
        # The table element of the subtype check
-       readable attr _class_color_pos: TableEltClassColor
+       meth class_color_pos: TableEltClassColor do return _class_color_pos.as(not null)
+       attr _class_color_pos: nullable TableEltClassColor
 
        # The proper local class table part (nor superclasses nor refinments)
-       readable attr _class_layout: Array[TableElt] 
+       readable attr _class_layout: Array[TableElt] = new Array[TableElt]
 
        # The proper local instance table part (nor superclasses nor refinments)
-       readable attr _instance_layout: Array[TableElt] 
+       readable attr _instance_layout: Array[TableElt] = new Array[TableElt]
 
        # Build the local layout of the class and feed the module table
        meth build_layout_in(tc: ToolContext, module_table: Array[ModuleTableElt])
        do
-               var clt = new Array[TableElt]
-               _class_layout = clt
-               var ilt = new Array[TableElt]
-               _instance_layout = ilt
+               var clt = _class_layout
+               var ilt = _instance_layout
 
                if global.intro == self then
                        module_table.add(new TableEltClassId(self))
-                       _class_color_pos = new TableEltClassColor(self)
-                       module_table.add(_class_color_pos)
+                       var cpp = new TableEltClassColor(self)
+                       _class_color_pos = cpp
+                       module_table.add(cpp)
                        clt.add(new TableEltClassInitTable(self))
                end
                for p in src_local_properties do
@@ -158,15 +156,13 @@ end
 
 redef class MMSrcModule
        # The local table of the module (refers things introduced in the module)
-       attr _local_table: Array[ModuleTableElt]
+       attr _local_table: Array[ModuleTableElt] = new Array[ModuleTableElt]
 
        # Builds the local tables and local classes layouts
        meth local_analysis(tc: ToolContext)
        do
-               var lt = new Array[ModuleTableElt]
-               _local_table = lt
                for c in src_local_classes do
-                       c.build_layout_in(tc, lt)
+                       c.build_layout_in(tc, _local_table)
                end
        end
 
@@ -182,7 +178,7 @@ redef class MMSrcModule
 
                ctab.add(new TableEltClassSelfId)
                itab.add(new TableEltVftPointer)
-               
+
                var pclassid = -1
                var classid = 3
 
@@ -228,7 +224,7 @@ redef class MMSrcModule
 
                # Compute core and crown classes for colorization
                var crown_classes = new HashSet[MMLocalClass]
-               var core_classes = new HashSet[MMLocalClass] 
+               var core_classes = new HashSet[MMLocalClass]
                for c in smallest_classes do
                        while c.cshe.direct_greaters.length == 1 do
                                c = c.cshe.direct_greaters.first
@@ -247,13 +243,14 @@ redef class MMSrcModule
                        var cc = ga.compiled_classes[c.global]
                        if core_classes.has(c) then
                                # For core classes, just build the table
-                               cc.class_table = build_tables(ga, c, ctab)
+                               build_tables_in(cc.class_table, ga, c, ctab)
                                if maxcolor < cc.class_table.length then maxcolor = cc.class_table.length
                        else
                                # For other classes, it's easier: just append to the parent tables
                                var sc = c.cshe.direct_greaters.first
                                var scc = ga.compiled_classes[sc.global]
-                               cc.class_table = scc.class_table.to_a
+                               assert cc.class_table.is_empty
+                               cc.class_table.add_all(scc.class_table)
                                var bc = c.global.intro
                                assert bc isa MMSrcLocalClass
                                var colpos = bc.class_color_pos
@@ -268,15 +265,13 @@ redef class MMSrcModule
                # Fill class table and instance tables pools
                for c in classes do
                        var cc = ga.compiled_classes[c.global]
-                       var cte = new TableEltComposite(cc)
-                       var ite = new TableEltComposite(cc)
+                       var cte = cc.class_layout
+                       var ite = cc.instance_layout
                        for sc in c.crhe.greaters_and_self do
                                if sc isa MMSrcLocalClass then
                                        cte.add(sc, sc.class_layout)
                                        ite.add(sc, sc.instance_layout)
                                end
-                               cc.class_layout = cte
-                               cc.instance_layout = ite
                        end
 
                        if core_classes.has(c) then
@@ -294,18 +289,19 @@ redef class MMSrcModule
                colorize(ga, itab, crown_classes, 0)
 
                # Build class and instance tables now things are colored
-               ga.max_class_table_length = 0 
+               ga.max_class_table_length = 0
                for c in classes do
                        var cc = ga.compiled_classes[c.global]
                        if core_classes.has(c) then
                                # For core classes, just build the table
-                               cc.class_table = build_tables(ga, c, ctab)
-                               cc.instance_table = build_tables(ga, c, itab)
+                               build_tables_in(cc.class_table, ga, c, ctab)
+                               build_tables_in(cc.instance_table, ga, c, itab)
                        else
                                # For other classes, it's easier: just append to the parent tables
                                var sc = c.cshe.direct_greaters.first
                                var scc = ga.compiled_classes[sc.global]
-                               cc.class_table = scc.class_table.to_a
+                               cc.class_table.clear
+                               cc.class_table.add_all(scc.class_table)
                                var bc = c.global.intro
                                assert bc isa MMSrcLocalClass
                                var colpos = bc.class_color_pos
@@ -314,7 +310,8 @@ redef class MMSrcModule
                                        cc.class_table.add(null)
                                end
                                append_to_table(ga, cc.class_table, cc.class_layout)
-                               cc.instance_table = scc.instance_table.to_a
+                               assert cc.instance_table.is_empty
+                               cc.instance_table.add_all(scc.instance_table)
                                append_to_table(ga, cc.instance_table, cc.instance_layout)
                        end
                end
@@ -322,7 +319,7 @@ redef class MMSrcModule
                return ga
        end
 
-       private meth append_to_table(cc: ColorContext, table: Array[TableElt], cmp: TableEltComposite)
+       private meth append_to_table(cc: ColorContext, table: Array[nullable TableElt], cmp: TableEltComposite)
        do
                for j in [0..cmp.length[ do
                        var e = cmp.item(j)
@@ -331,7 +328,7 @@ redef class MMSrcModule
                end
        end
 
-       private meth build_tables(ga: GlobalAnalysis, c: MMLocalClass, elts: Array[TableElt]): Array[TableElt]
+       private meth build_tables_in(table: Array[nullable TableElt], ga: GlobalAnalysis, c: MMLocalClass, elts: Array[TableElt])
        do
                var tab = new HashMap[Int, TableElt]
                var len = 0
@@ -345,21 +342,19 @@ redef class MMSrcModule
                                end
                        end
                end
-               var res = new Array[TableElt]
                var i = 0
                while i < len do
                        if tab.has_key(i) then
                                var e = tab[i]
                                for j in [0..e.length[ do
-                                       res[i] = e.item(j)
+                                       table[i] = e.item(j)
                                        i = i + 1
                                end
                        else
-                               res[i] = null
+                               table[i] = null
                                i = i + 1
                        end
                end
-               return res
        end
 
        # Perform coloring
@@ -383,7 +378,7 @@ redef class MMSrcModule
                                while trycolor != color do
                                        color = trycolor
                                        for c in rel_classes do
-                                               var idx = 0 
+                                               var idx = 0
                                                while idx < len do
                                                        if colors.has_key(trycolor + idx) and not free_color(colors[trycolor + idx], c) then
                                                                trycolor = trycolor + idx + 1
@@ -461,12 +456,11 @@ redef class MMSrcModule
                        print("No main")
                else
                        var sys = class_by_name(sysname)
-                       # var initm = sys.select_method(once "init".to_symbol)
-                       var mainm = sys.select_method(once "main".to_symbol)
-                       if mainm == null then
+                       var name = once "main".to_symbol
+                       if not sys.has_global_property_by_name(name) then
                                print("No main")
                        else
-                               #v.add_instr("G_sys = NEW_{initm.cname}();")
+                               var mainm = sys.select_method(name)
                                v.add_instr("G_sys = NEW_Sys();")
                                v.add_instr("{mainm.cname}(G_sys);")
                        end
@@ -475,8 +469,8 @@ redef class MMSrcModule
                v.unindent
                v.add_instr("}")
        end
-       
-       # Compile sep files 
+
+       # Compile sep files
        meth compile_mod_to_c(v: GlobalCompilerVisitor)
        do
                v.add_decl("extern const char *LOCATE_{name};")
@@ -633,8 +627,7 @@ special TableEltProp
                                end
                        end
                end
-               assert false
-               return null
+               abort
        end
 end
 
@@ -675,7 +668,7 @@ special AbsTableElt
        end
 end
 
-# An element of a class table representing a class information 
+# An element of a class table representing a class information
 class TableEltClass
 special TableElt
 special AbsTableEltClass
@@ -686,7 +679,7 @@ special AbsTableEltClass
        end
 end
 
-# An element representing the id of a class in a module table 
+# An element representing the id of a class in a module table
 class TableEltClassId
 special ModuleTableElt
 special AbsTableEltClass
@@ -776,7 +769,7 @@ special TableElt
        end
 end
 
-# The element that 
+# The element that
 class TableEltVftPointer
 special TableElt
        redef meth is_related_to(c) do return true
@@ -841,7 +834,7 @@ redef class MMLocalClass
        meth compile_tables_to_c(v: GlobalCompilerVisitor)
        do
                var cc = v.global_analysis.compiled_classes[self.global]
-               var ctab =  cc.class_table
+               var ctab = cc.class_table
                var clen = ctab.length
                if v.global_analysis.max_class_table_length > ctab.length then
                        clen = v.global_analysis.max_class_table_length
@@ -880,7 +873,7 @@ redef class MMLocalClass
                        var ctx_old = v.ctx
                        v.ctx = new CContext
 
-                       var self_var = new ParamVariable(null, null)
+                       var self_var = new ParamVariable(once ("self".to_symbol), null)
                        var self_var_cname = v.cfc.register_variable(self_var)
                        v.nmc.method_params = [self_var]
 
@@ -896,17 +889,10 @@ redef class MMLocalClass
                                        # FIXME: Not compatible with sep compilation
                                        assert p isa MMSrcAttribute
                                        var np = p.node
-                                       assert np isa AAttrPropdef
                                        var ne = np.n_expr
                                        if ne != null then
                                                var e = ne.compile_expr(v)
                                                v.add_instr("{p.global.attr_access}(obj) = {e};")
-                                       else
-                                               var pi = t.local_class.primitive_info
-                                               if pi != null and pi.tagged then
-                                                       var default = t.default_cvalue
-                                                       v.add_instr("{p.global.attr_access}(obj) = {default};")
-                                               end
                                        end
                                end
                        end
@@ -917,6 +903,24 @@ redef class MMLocalClass
                        v.unindent
                        v.add_instr("}")
 
+                       # Compile CHECKNAME
+                       var s = "void CHECKNEW_{name}(val_t self, char *from)"
+                       v.add_instr(s + " \{")
+                       v.indent
+                       var ctx_old = v.ctx
+                       v.ctx = new CContext
+                       for g in global_properties do
+                               var p = self[g]
+                               var t = p.signature.return_type
+                               if p isa MMAttribute and t != null and not t.is_nullable and v.tc.opt_warn.value > 0 then
+                                       v.add_instr("if ({p.global.attr_access}(self) == NIT_NULL) fprintf(stderr, \"Uninitialized attribute %s at %s.\\n\", \"{p.full_name}\", from);")
+                               end
+                       end
+                       ctx_old.append(v.ctx)
+                       v.ctx = ctx_old
+                       v.unindent
+                       v.add_instr("}")
+
                        var init_table_size = cshe.greaters.length + 1
                        var init_table_decl = "int init_table[{init_table_size}] = \{0{", 0" * (init_table_size-1)}};"
 
@@ -937,6 +941,7 @@ redef class MMLocalClass
                                v.add_instr(init_table_decl)
                                v.add_instr("val_t self = NEW_{name}();")
                                v.add_instr("{p.cname}({args.join(", ")});")
+                               v.add_instr("CHECKNEW_{name}(self, \"{p.full_name} for {self}\");")
                                v.add_instr("return self;")
                                v.unindent
                                v.add_instr("}")