New function process_closures.
authorJean Privat <jean@pryen.org>
Sat, 24 Jan 2009 01:58:24 +0000 (20:58 -0500)
committerJean Privat <jean@pryen.org>
Sat, 24 Jan 2009 01:58:24 +0000 (20:58 -0500)
Extract closure processing from ASendExpr into a new function in AAbsSendExpr.
Add process_closures in do_typing.
Update tests since error message has changed.

src/syntax/typing.nit
tests/sav/base_closure1_alt10.sav
tests/sav/base_closure2_alt10.sav
tests/sav/base_closure4_alt10.sav
tests/sav/base_closure_break_alt10.sav
tests/sav/base_closure_multi_alt1.sav
tests/sav/base_closure_multi_alt2.sav
tests/sav/base_closure_multi_alt3.sav
tests/sav/base_closure_multi_alt4.sav

index ed9d8e7..d0c5a50 100644 (file)
@@ -846,7 +846,7 @@ special PExpr
        readable attr _prop_signature: MMSignature
 
        # Compute the called global property
-       private meth do_typing(v: TypingVisitor, type_recv: MMType, is_implicit_self: Bool, recv_is_self: Bool, name: Symbol, raw_args: Array[PExpr])
+       private meth do_typing(v: TypingVisitor, type_recv: MMType, is_implicit_self: Bool, recv_is_self: Bool, name: Symbol, raw_args: Array[PExpr], closure_defs: Array[PClosureDef])
        do
                var prop = get_property(v, type_recv, is_implicit_self, name)
                if prop == null then return
@@ -854,9 +854,11 @@ special PExpr
                if sig == null then return
                var args = process_signature(v, sig, prop.name, raw_args)
                if args == null then return
+               var rtype = process_closures(v, sig, prop.name, closure_defs)
                _prop = prop
                _prop_signature = sig
                _arguments = args
+               _return_type = rtype
        end
 
        private meth get_property(v: TypingVisitor, type_recv: MMType, is_implicit_self: Bool, name: Symbol): MMMethod
@@ -886,6 +888,7 @@ special PExpr
                return prop
        end
 
+       # Get the signature for a local property and a receiver
        private meth get_signature(v: TypingVisitor, type_recv: MMType, prop: MMMethod, recv_is_self: Bool): MMSignature
        do
                prop.global.check_visibility(v, self, v.module, recv_is_self)
@@ -893,7 +896,7 @@ special PExpr
                if not recv_is_self then psig = psig.not_for_self
                return psig
        end
-       
+
        # Check the conformity of a set of arguments `raw_args' to a signature.
        private meth process_signature(v: TypingVisitor, psig: MMSignature, name: Symbol, raw_args: Array[PExpr]): Array[PExpr]
        do
@@ -931,11 +934,51 @@ special PExpr
                return args
        end
 
+       # Check the conformity of a set of defined closures
+       private meth process_closures(v: TypingVisitor, psig: MMSignature, name: Symbol, cd: Array[PClosureDef]): MMType
+       do
+               var t = psig.return_type
+               var cs = psig.closures # Declared closures
+               if cd != null then
+                       if cs.length == 0 then
+                               v.error(self, "Error: {name} does not require blocs.")
+                       else if cs.length != cd.length then
+                               v.error(self, "Error: {name} requires {cs.length} blocs, {cd.length} found.")
+                       else
+                               var old_bbst = v.closure_break_stype
+                               var old_bl = v.break_list
+                               v.closure_break_stype = t
+                               v.break_list = new Array[ABreakExpr]
+                               for i in [0..cs.length[ do
+                                       cd[i].accept_typing2(v, cs[i])
+                               end
+                               for n in v.break_list do
+                                       var ntype = n.stype
+                                       if t == null or (t != null and t < ntype) then
+                                               t = ntype
+                                       end
+                               end
+                               for n in v.break_list do
+                                       v.check_conform_expr(n, t)
+                               end
+
+                               v.closure_break_stype = old_bbst
+                               v.break_list = old_bl
+                       end
+               else if cs.length != 0 then
+                       v.error(self, "Error: {name} requires {cs.length} blocs.")
+               end
+               return t
+       end
+
        # The invoked method (once computed)
        readable attr _prop: MMMethod
 
        # The real arguments used (after star transformation) (once computed)
        readable attr _arguments: Array[PExpr]
+
+       # The return type (if any) (once computed)
+       readable attr _return_type: MMType
 end
 
 # A possible call of constructor in a super class
@@ -994,7 +1037,7 @@ special AAbsSendExpr
                        name = n_id.to_symbol
                end
 
-               do_typing(v, t, false, false, name, n_args.to_a)
+               do_typing(v, t, false, false, name, n_args.to_a, null)
                if prop == null then return
 
                if not prop.global.is_init then
@@ -1024,44 +1067,9 @@ special ASuperInitCall
        private meth do_all_typing(v: TypingVisitor)
        do
                if not v.check_expr(n_expr) then return
-               do_typing(v, n_expr.stype, n_expr.is_implicit_self, n_expr.is_self, name, raw_arguments)
+               do_typing(v, n_expr.stype, n_expr.is_implicit_self, n_expr.is_self, name, raw_arguments, closure_defs)
                if prop == null then return
 
-               var t = prop.signature_for(n_expr.stype).return_type
-               if t != null and not n_expr.is_self then t = t.not_for_self
-
-               var cd = closure_defs
-               var cs = _prop_signature.closures # Closure signatures
-               if cd != null then
-                       if cs.length == 0 then
-                               v.error(self, "Error: property {prop} does not require blocs.")
-                       else if cs.length != cd.length then
-                               v.error(self, "Error: property {prop} requires {cs.length} blocs, {cd.length} found.")
-                       else
-                               var old_bbst = v.closure_break_stype
-                               var old_bl = v.break_list
-                               v.closure_break_stype = t
-                               v.break_list = new Array[ABreakExpr]
-                               for i in [0..cs.length[ do
-                                       cd[i].accept_typing2(v, cs[i])
-                               end
-                               for n in v.break_list do
-                                       var ntype = n.stype
-                                       if t == null or (t != null and t < ntype) then
-                                               t = ntype
-                                       end
-                               end
-                               for n in v.break_list do
-                                       v.check_conform_expr(n, t)
-                               end
-
-                               v.closure_break_stype = old_bbst
-                               v.break_list = old_bl
-                       end
-               else if cs.length != 0 then
-                       v.error(self, "Error: property {prop} requires {cs.length} blocs.")
-               end
-
                if prop.global.is_init then
                        if not v.local_property.global.is_init then
                                v.error(self, "Error: try to invoke constructor {prop} in a method.")
@@ -1071,7 +1079,8 @@ special ASuperInitCall
                                register_super_init_call(v, prop)
                        end
                end
-               _stype = t
+
+               _stype = return_type
        end
 end
 
@@ -1083,7 +1092,7 @@ special AReassignFormExpr
        do
                if not v.check_expr(n_expr) then return
                var raw_args = raw_arguments
-               do_typing(v, n_expr.stype, n_expr.is_implicit_self, n_expr.is_self, name, raw_args)
+               do_typing(v, n_expr.stype, n_expr.is_implicit_self, n_expr.is_self, name, raw_args, null)
                if prop == null then return
                if prop.global.is_init then
                        if not v.local_property.global.is_init then
@@ -1101,7 +1110,7 @@ special AReassignFormExpr
                var old_args = arguments
                raw_args.add(n_value)
 
-               do_typing(v, n_expr.stype, n_expr.is_implicit_self, n_expr.is_self, "{name}=".to_symbol, raw_args)
+               do_typing(v, n_expr.stype, n_expr.is_implicit_self, n_expr.is_self, "{name}=".to_symbol, raw_args, null)
                if prop == null then return
                if prop.global.is_init then
                        if not v.local_property.global.is_init then
@@ -1265,7 +1274,7 @@ redef class AClosureCallExpr
        redef meth after_typing(v)
        do
                var va = variable
-               var sig = va.closure.signature 
+               var sig = va.closure.signature
                var args = process_signature(v, sig, n_id.to_symbol, n_args.to_a)
                if args == null then return
                _prop = null
index 18489ae..36c2332 100644 (file)
@@ -1 +1 @@
-alt/base_closure1_alt10.nit:45,3--7: Error: property foo requires 1 blocs.
+alt/base_closure1_alt10.nit:45,3--7: Error: foo requires 1 blocs.
index b713fb2..4002cf1 100644 (file)
@@ -1 +1 @@
-alt/base_closure2_alt10.nit:46,3--7: Error: property foo requires 1 blocs.
+alt/base_closure2_alt10.nit:46,3--7: Error: foo requires 1 blocs.
index 374da95..450544f 100644 (file)
@@ -1 +1 @@
-alt/base_closure4_alt10.nit:45,3--7: Error: property foo requires 1 blocs.
+alt/base_closure4_alt10.nit:45,3--7: Error: foo requires 1 blocs.
index 291fd47..75580db 100644 (file)
@@ -1 +1 @@
-alt/base_closure_break_alt10.nit:47,3--7: Error: property foo requires 1 blocs.
+alt/base_closure_break_alt10.nit:47,3--7: Error: foo requires 1 blocs.
index 8e2826e..45f9eca 100644 (file)
@@ -1 +1 @@
-alt/base_closure_multi_alt1.nit:52,1--61:9: Error: property a requires 1 blocs, 2 found.
+alt/base_closure_multi_alt1.nit:52,1--61:9: Error: a requires 1 blocs, 2 found.
index 265cc8d..a025b0b 100644 (file)
@@ -1 +1 @@
-alt/base_closure_multi_alt2.nit:54,1--63:9: Error: property a requires 3 blocs, 2 found.
+alt/base_closure_multi_alt2.nit:54,1--63:9: Error: a requires 3 blocs, 2 found.
index 2acde52..c2794e6 100644 (file)
@@ -1 +1 @@
-alt/base_closure_multi_alt3.nit:55,2--56:10: Error: property b requires 2 blocs, 1 found.
+alt/base_closure_multi_alt3.nit:55,2--56:10: Error: b requires 2 blocs, 1 found.
index ee09b6a..818cc53 100644 (file)
@@ -1 +1 @@
-alt/base_closure_multi_alt4.nit:55,2--60:11: Error: property b requires 2 blocs, 3 found.
+alt/base_closure_multi_alt4.nit:55,2--60:11: Error: b requires 2 blocs, 3 found.