src: use `ASuperExpr::mpropdef` instead of asking the frame or visitors
[nit.git] / src / abstract_compiler.nit
index 2640907..2de8333 100644 (file)
@@ -22,6 +22,7 @@ import typing
 import auto_super_init
 import frontend
 import common_ffi
+import platform
 
 # Add compiling options
 redef class ToolContext
@@ -68,6 +69,53 @@ redef class ToolContext
 end
 
 redef class ModelBuilder
+       redef init(model, toolcontext)
+       do
+               if toolcontext.opt_no_stacktrace.value and toolcontext.opt_stacktrace.value then
+                       print "Cannot use --nit-stacktrace when --no-stacktrace is activated"
+                       exit(1)
+               end
+
+               super
+       end
+
+       # The compilation directory
+       var compile_dir: String
+
+       # Simple indirection to `Toolchain::write_and_make`
+       protected fun write_and_make(compiler: AbstractCompiler)
+       do
+               var platform = compiler.mainmodule.target_platform
+               var toolchain
+               if platform == null then
+                       toolchain = new MakefileToolchain(toolcontext)
+               else
+                       toolchain = platform.toolchain(toolcontext)
+               end
+               compile_dir = toolchain.compile_dir
+               toolchain.write_and_make compiler
+       end
+end
+
+redef class Platform
+       fun toolchain(toolcontext: ToolContext): Toolchain is abstract
+end
+
+class Toolchain
+       var toolcontext: ToolContext
+
+       fun compile_dir: String
+       do
+               var compile_dir = toolcontext.opt_compile_dir.value
+               if compile_dir == null then compile_dir = ".nit_compile"
+               return compile_dir
+       end
+
+       fun write_and_make(compiler: AbstractCompiler) is abstract
+end
+
+class MakefileToolchain
+       super Toolchain
        # The list of directories to search for included C headers (-I for C compilers)
        # The list is initially set with :
        #   * the toolcontext --cc-path option
@@ -76,10 +124,8 @@ redef class ModelBuilder
        # Path can be added (or removed) by the client
        var cc_paths = new Array[String]
 
-       redef init(model, toolcontext)
+       protected fun gather_cc_paths
        do
-               super
-
                # Look for the the Nit clib path
                var path_env = "NIT_DIR".environ
                if not path_env.is_empty then
@@ -94,11 +140,6 @@ redef class ModelBuilder
                        toolcontext.error(null, "Cannot determine the nit clib path. define envvar NIT_DIR.")
                end
 
-               if toolcontext.opt_no_stacktrace.value and toolcontext.opt_stacktrace.value then
-                       print "Cannot use --nit-stacktrace when --no-stacktrace is activated"
-                       exit(1)
-               end
-
                # Add user defined cc_paths
                cc_paths.append(toolcontext.opt_cc_path.value)
 
@@ -106,18 +147,14 @@ redef class ModelBuilder
                if not path_env.is_empty then
                        cc_paths.append(path_env.split_with(':'))
                end
-
-               var compile_dir = toolcontext.opt_compile_dir.value
-               if compile_dir == null then compile_dir = ".nit_compile"
-               self.compile_dir = compile_dir
        end
 
-       # The compilation directory
-       var compile_dir: String
-
-       protected fun write_and_make(compiler: AbstractCompiler)
+       redef fun write_and_make(compiler)
        do
+               gather_cc_paths
+
                var mainmodule = compiler.mainmodule
+               var compile_dir = compile_dir
 
                # Generate the .h and .c files
                # A single C file regroups many compiled rumtime functions
@@ -161,8 +198,9 @@ redef class ModelBuilder
                compiler.files_to_copy.add "{cc_paths.first}/gc_chooser.h"
 
                # FFI
-               for m in compiler.mainmodule.in_importation.greaters do if mmodule2nmodule.keys.has(m) then
-                       var amodule = mmodule2nmodule[m]
+               var m2m = toolcontext.modelbuilder.mmodule2nmodule
+               for m in compiler.mainmodule.in_importation.greaters do if m2m.keys.has(m) then
+                       var amodule = m2m[m]
                        if m.uses_ffi or amodule.uses_legacy_ni then
                                compiler.finalize_ffi_for_module(amodule)
                        end
@@ -258,8 +296,9 @@ redef class ModelBuilder
                end
 
                var linker_options = new HashSet[String]
-               for m in mainmodule.in_importation.greaters do if mmodule2nmodule.keys.has(m) then
-                       var amod = mmodule2nmodule[m]
+               var m2m = toolcontext.modelbuilder.mmodule2nmodule
+               for m in mainmodule.in_importation.greaters do if m2m.keys.has(m) then
+                       var amod = m2m[m]
                        linker_options.add(amod.c_linker_options)
                end
 
@@ -289,7 +328,7 @@ redef class ModelBuilder
                                dep_rules.add(o)
                        else
                                var o = f.makefile_rule_name
-                               var ff = orig_dir.join_path(f.filename).simplify_path
+                               var ff = f.filename.basename("")
                                makefile.write("{o}: {ff}\n")
                                makefile.write("\t{f.makefile_rule_content}\n")
                                dep_rules.add(f.makefile_rule_name)
@@ -676,9 +715,6 @@ abstract class AbstractCompiler
                nmodule.finalize_ffi(visitor, modelbuilder)
                nmodule.finalize_nitni(visitor)
        end
-
-       # Does this compiler support the FFI?
-       fun supports_ffi: Bool do return false
 end
 
 # A file unit (may be more than one file if
@@ -1509,13 +1545,13 @@ redef class AConcreteMethPropdef
                # Call the implicit super-init
                var auto_super_inits = self.auto_super_inits
                if auto_super_inits != null then
-                       var selfarg = [arguments.first]
+                       var args = [arguments.first]
                        for auto_super_init in auto_super_inits do
-                               if auto_super_init.intro.msignature.arity == 0 then
-                                       v.send(auto_super_init, selfarg)
-                               else
-                                       v.send(auto_super_init, arguments)
+                               args.clear
+                               for i in [0..auto_super_init.msignature.arity+1[ do
+                                       args.add(arguments[i])
                                end
+                               v.compile_callsite(auto_super_init, args)
                        end
                end
                v.stmt(self.n_block)
@@ -2444,22 +2480,26 @@ redef class ASuperExpr
                for a in self.n_args.n_exprs do
                        args.add(v.expr(a, null))
                end
-               if args.length == 1 then
-                       args = v.frame.arguments
-               end
 
                var callsite = self.callsite
                if callsite != null then
-                       if callsite.mproperty.intro.msignature.arity == 0 then
-                               args = [recv]
+                       # Add additionnals arguments for the super init call
+                       if args.length == 1 then
+                               for i in [0..callsite.mproperty.intro.msignature.arity[ do
+                                       args.add(v.frame.arguments[i+1])
+                               end
                        end
                        # Super init call
                        var res = v.compile_callsite(callsite, args)
                        return res
                end
 
+               if args.length == 1 then
+                       args = v.frame.arguments
+               end
+
                # stantard call-next-method
-               return v.supercall(v.frame.mpropdef.as(MMethodDef), recv.mtype.as(MClassType), args)
+               return v.supercall(mpropdef.as(not null), recv.mtype.as(MClassType), args)
        end
 end