src: introduce new constructors
[nit.git] / src / abstract_compiler.nit
index 4660b0b..9d441cc 100644 (file)
@@ -51,8 +51,10 @@ redef class ToolContext
        var opt_no_check_assert: OptionBool = new OptionBool("Disable the evaluation of explicit 'assert' and 'as' (dangerous)", "--no-check-assert")
        # --no-check-autocast
        var opt_no_check_autocast: OptionBool = new OptionBool("Disable implicit casts on unsafe expression usage (dangerous)", "--no-check-autocast")
-       # --no-check-other
-       var opt_no_check_other: OptionBool = new OptionBool("Disable implicit tests: unset attribute, null receiver (dangerous)", "--no-check-other")
+       # --no-check-null
+       var opt_no_check_null: OptionBool = new OptionBool("Disable tests of null receiver (dangerous)", "--no-check-null")
+       # --no-check-all
+       var opt_no_check_all: OptionBool = new OptionBool("Disable all tests (dangerous)", "--no-check-all")
        # --typing-test-metrics
        var opt_typing_test_metrics: OptionBool = new OptionBool("Enable static and dynamic count of all type tests", "--typing-test-metrics")
        # --invocation-metrics
@@ -70,7 +72,7 @@ redef class ToolContext
        do
                super
                self.option_context.add_option(self.opt_output, self.opt_dir, self.opt_no_cc, self.opt_no_main, self.opt_make_flags, self.opt_compile_dir, self.opt_hardening, self.opt_no_shortcut_range)
-               self.option_context.add_option(self.opt_no_check_covariance, self.opt_no_check_attr_isset, self.opt_no_check_assert, self.opt_no_check_autocast, self.opt_no_check_other)
+               self.option_context.add_option(self.opt_no_check_covariance, self.opt_no_check_attr_isset, self.opt_no_check_assert, self.opt_no_check_autocast, self.opt_no_check_null, self.opt_no_check_all)
                self.option_context.add_option(self.opt_typing_test_metrics, self.opt_invocation_metrics, self.opt_isset_checks_metrics)
                self.option_context.add_option(self.opt_stacktrace)
                self.option_context.add_option(self.opt_no_gcc_directive)
@@ -96,6 +98,14 @@ redef class ToolContext
                        print "Error: cannot use both --dir and --output"
                        exit(1)
                end
+
+               if opt_no_check_all.value then
+                       opt_no_check_covariance.value = true
+                       opt_no_check_attr_isset.value = true
+                       opt_no_check_assert.value = true
+                       opt_no_check_autocast.value = true
+                       opt_no_check_null.value = true
+               end
        end
 end
 
@@ -1034,9 +1044,27 @@ abstract class AbstractCompilerVisitor
                return self.compiler.modelbuilder.force_get_primitive_method(self.current_node.as(not null), name, recv.mclass, self.compiler.mainmodule)
        end
 
-       fun compile_callsite(callsite: CallSite, args: Array[RuntimeVariable]): nullable RuntimeVariable
+       fun compile_callsite(callsite: CallSite, arguments: Array[RuntimeVariable]): nullable RuntimeVariable
        do
-               return self.send(callsite.mproperty, args)
+               var initializers = callsite.mpropdef.initializers
+               if not initializers.is_empty then
+                       var recv = arguments.first
+
+                       assert initializers.length == arguments.length - 1 else debug("expected {initializers.length}, got {arguments.length - 1}")
+                       var i = 1
+                       for p in initializers do
+                               if p isa MMethod then
+                                       self.send(p, [recv, arguments[i]])
+                               else if p isa MAttribute then
+                                       self.write_attribute(p, recv, arguments[i])
+                               else abort
+                               i += 1
+                       end
+
+                       return self.send(callsite.mproperty, [recv])
+               end
+
+               return self.send(callsite.mproperty, arguments)
        end
 
        fun native_array_instance(elttype: MType, length: RuntimeVariable): RuntimeVariable is abstract
@@ -1174,7 +1202,7 @@ abstract class AbstractCompilerVisitor
        # Add a check and an abort for a null reciever if needed
        fun check_recv_notnull(recv: RuntimeVariable)
        do
-               if self.compiler.modelbuilder.toolcontext.opt_no_check_other.value then return
+               if self.compiler.modelbuilder.toolcontext.opt_no_check_null.value then return
 
                var maybenull = recv.mcasttype isa MNullableType or recv.mcasttype isa MNullType
                if maybenull then
@@ -1819,13 +1847,18 @@ redef class AMethPropdef
                if auto_super_inits != null then
                        var args = [arguments.first]
                        for auto_super_init in auto_super_inits do
+                               assert auto_super_init.mproperty != mpropdef.mproperty
                                args.clear
                                for i in [0..auto_super_init.msignature.arity+1[ do
                                        args.add(arguments[i])
                                end
+                               assert auto_super_init.mproperty != mpropdef.mproperty
                                v.compile_callsite(auto_super_init, args)
                        end
                end
+               if auto_super_call then
+                       v.supercall(mpropdef, arguments.first.mtype.as(MClassType), arguments)
+               end
 
                var n_block = n_block
                if n_block != null then
@@ -1842,6 +1875,8 @@ redef class AMethPropdef
                        else
                                compile_externmeth_to_c(v, mpropdef, arguments)
                        end
+               else
+                       abort
                end
        end
 
@@ -2234,6 +2269,15 @@ redef class AClassdef
        private fun compile_to_c(v: AbstractCompilerVisitor, mpropdef: MMethodDef, arguments: Array[RuntimeVariable])
        do
                if mpropdef == self.mfree_init then
+                       if mpropdef.mproperty.is_root_init then
+                               assert self.super_inits == null
+                               assert arguments.length == 1
+                               if not mpropdef.is_intro then
+                                       v.supercall(mpropdef, arguments.first.mtype.as(MClassType), arguments)
+                               end
+                               return
+                       end
+
                        var super_inits = self.super_inits
                        if super_inits != null then
                                var args_of_super = arguments
@@ -2242,6 +2286,7 @@ redef class AClassdef
                                        v.send(su, args_of_super)
                                end
                        end
+
                        var recv = arguments.first
                        var i = 1
                        # Collect undefined attributes