Merge: doc: fixed some typos and other misc. corrections
[nit.git] / src / nitrestful.nit
index 68e8258..6a93f30 100644 (file)
@@ -23,7 +23,7 @@ private class RestfulPhase
        super Phase
 
        # Classes with methods marked with the `restful` annotation
-       var restful_classes = new HashSet[MClass]
+       var restful_classes = new HashSet[MClassDef]
 
        redef fun process_annotated_node(node, nat)
        do
@@ -77,16 +77,15 @@ private class RestfulPhase
                end
 
                # Register the property
-               var mclass = mclassdef.mclass
-               mclass.restful_methods.add mproperty
-               restful_classes.add mclass
+               mclassdef.restful_methods.add mproperty
+               restful_classes.add mclassdef
 
                if http_resources.not_empty then mproperty.restful_resources = http_resources
                mproperty.restful_verbs = http_methods
        end
 end
 
-redef class MClass
+redef class MClassDef
 
        # Methods with the `restful` annotation in this class
        private var restful_methods = new Array[MMethod]
@@ -132,7 +131,7 @@ redef class MType
                else
                        # Deserialize everything else
                        template.add """
-                       var out_{{{arg_name}}} = deserialize_arg(in_{{{arg_name}}})
+                       var out_{{{arg_name}}} = deserialize_arg(in_{{{arg_name}}}, "{{{self.name}}}")
 """
                end
        end
@@ -194,6 +193,7 @@ else
 end
 
 var nit_module = new NitModule(module_name)
+nit_module.annotations.add """generated"""
 nit_module.annotations.add """no_warning("parentheses")"""
 nit_module.header = """
 # This file is generated by nitrestful
@@ -207,11 +207,15 @@ end
 var phase = toolcontext.restful_phase
 assert phase isa RestfulPhase
 
-for mclass in phase.restful_classes do
+for mclassdef in phase.restful_classes do
+       var mclass = mclassdef.mclass
 
        var t = new Template
        nit_module.content.add t
 
+       var classes = new Template
+       nit_module.content.add classes
+
        t.add """
 redef class {{{mclass}}}
        redef fun prepare_respond_and_close(request, truncated_uri, http_server)
@@ -226,7 +230,7 @@ redef class {{{mclass}}}
                var resource = resources.first
 
 """
-       var methods = mclass.restful_methods
+       var methods = mclassdef.restful_methods
        for i in methods.length.times, method in methods do
                var msig = method.intro.msignature
                if msig == null then continue
@@ -260,7 +264,11 @@ redef class {{{mclass}}}
 """
 
                        var mtype = param.mtype
-                       mtype.gen_arg_convert(t, param.name)
+                       var bound_mtype = mclassdef.bound_mtype
+                       var resolved_mtype = mtype.resolve_for(bound_mtype, bound_mtype, mclassdef.mmodule, true)
+                       var resolved_type_name = resolved_mtype.name
+
+                       resolved_mtype.gen_arg_convert(t, param.name)
 
                        var arg = "out_{param.name}"
                        args.add arg
@@ -279,12 +287,50 @@ redef class {{{mclass}}}
                var sig = ""
                if args.not_empty then sig = "({args.join(", ")})"
 
-               t.add """
+               if not method.restful_async then
+                       # Synchronous method
+                       t.add """
                                var response = {{{method.name}}}{{{sig}}}
                                http_server.respond response
                                http_server.close
                                return
 """
+               else
+                       # Asynchronous method
+                       var task_name = "Task_{mclass}_{method.name}"
+                       args.unshift "http_server"
+                       args.unshift "request"
+                       args.unshift "self"
+
+                       t.add """
+                               var task = new {{{task_name}}}({{{args.join(", ")}}})
+                               self.thread_pool.execute task
+                               return
+"""
+
+                       var thread_attribs = new Array[String]
+                       for param in msig.mparameters do
+                               thread_attribs.add """
+       private var out_{{{param.name}}}: {{{param.mtype}}}"""
+                       end
+
+                       classes.add """
+
+# Generated task to execute {{{mclass}}}::{{{method.name}}}
+class {{{task_name}}}
+       super RestfulTask
+
+       redef type A: {{{mclass}}}
+
+{{{thread_attribs.join("\n")}}}
+
+       redef fun indirect_restful_method
+       do
+               return action.{{{method.name}}}{{{sig}}}
+       end
+end
+"""
+               end
 
                if isas.not_empty then t.add """
                        end