parser: add Visitor::current_node and Visitor::enter_visit
[nit.git] / src / syntax / typing.nit
index a0b437f..c29bffe 100644 (file)
@@ -27,7 +27,7 @@ redef class MMSrcModule
        fun do_typing(tc: ToolContext)
        do
                var tv = new TypingVisitor(tc, self)
-               tv.visit(node)
+               tv.enter_visit(node)
        end
 end
 
@@ -196,8 +196,6 @@ redef class AConcreteMethPropdef
 end
 
 redef class AConcreteInitPropdef
-       readable var _super_init_calls: Array[MMMethod] = new Array[MMMethod]
-       readable var _explicit_super_init_calls: Array[MMMethod] = new Array[MMMethod]
        redef fun accept_typing(v)
        do
                v.top_block = n_block
@@ -288,7 +286,8 @@ redef class AClosureDecl
 end
 
 redef class PType
-       fun stype: MMType do return _stype.as(not null)
+       redef fun stype: MMType do return _stype.as(not null)
+       redef fun is_typed: Bool do return _stype != null
        var _stype: nullable MMType
 
        redef fun after_typing(v)
@@ -342,6 +341,7 @@ redef class AVardeclExpr
                if n_expr != null then v.variable_ctx.mark_is_set(va)
 
                if n_type != null then
+                       if not n_type.is_typed then return
                        va.stype = n_type.stype
                        if n_expr != null then
                                v.check_conform_expr(n_expr.as(not null), va.stype)
@@ -365,7 +365,7 @@ redef class ABlockExpr
                                v.variable_ctx.already_unreash = true
                                v.warning(e, "Warning: unreachable statement.")
                        end
-                       v.visit(e)
+                       v.enter_visit(e)
                end
 
                old_var_ctx.merge(v.variable_ctx)
@@ -446,7 +446,7 @@ redef class AIfExpr
        redef fun accept_typing(v)
        do
                var old_var_ctx = v.variable_ctx
-               v.visit(n_expr)
+               v.enter_visit(n_expr)
                v.check_conform_expr(n_expr, v.type_bool)
 
                # Prepare 'then' context
@@ -455,7 +455,7 @@ redef class AIfExpr
                # Process the 'then'
                if n_then != null then
                        v.variable_ctx = v.variable_ctx.sub(n_then.as(not null))
-                       v.visit(n_then)
+                       v.enter_visit(n_then)
                end
 
                # Remember what appened in the 'then'
@@ -468,7 +468,7 @@ redef class AIfExpr
                # Process the 'else'
                if n_else != null then
                        v.variable_ctx = v.variable_ctx.sub(n_else.as(not null))
-                       v.visit(n_else)
+                       v.enter_visit(n_else)
                end
 
                # Merge 'then' and 'else' contexts
@@ -493,7 +493,7 @@ redef class AWhileExpr
                v.variable_ctx = v.variable_ctx.sub(self)
 
                # Process condition
-               v.visit(n_expr)
+               v.enter_visit(n_expr)
                v.check_conform_expr(n_expr, v.type_bool)
 
                # Prepare inside context (assert cond)
@@ -502,7 +502,7 @@ redef class AWhileExpr
                # Process inside
                if n_block != null then
                        v.variable_ctx = v.variable_ctx.sub(n_block.as(not null))
-                       v.visit(n_block)
+                       v.enter_visit(n_block)
                end
 
                v.variable_ctx = old_var_ctx
@@ -520,13 +520,13 @@ redef class AForExpr
        readable var _escapable: nullable EscapableBlock
 
        var _meth_iterator: nullable MMMethod
-       fun meth_iterator: MMMethod do return _meth_iterator.as(not null)
+       redef fun meth_iterator: MMMethod do return _meth_iterator.as(not null)
        var _meth_is_ok: nullable MMMethod
-       fun meth_is_ok: MMMethod do return _meth_is_ok.as(not null)
+       redef fun meth_is_ok: MMMethod do return _meth_is_ok.as(not null)
        var _meth_item: nullable MMMethod
-       fun meth_item: MMMethod do return _meth_item.as(not null)
+       redef fun meth_item: MMMethod do return _meth_item.as(not null)
        var _meth_next: nullable MMMethod
-       fun meth_next: MMMethod do return _meth_next.as(not null)
+       redef fun meth_next: MMMethod do return _meth_next.as(not null)
        redef fun accept_typing(v)
        do
                var escapable = new EscapableBlock(self)
@@ -541,7 +541,7 @@ redef class AForExpr
                _variable = va
                v.variable_ctx.add(va)
 
-               v.visit(n_expr)
+               v.enter_visit(n_expr)
 
                if not v.check_conform_expr(n_expr, v.type_collection) then return
                var expr_type = n_expr.stype
@@ -571,7 +571,7 @@ redef class AForExpr
                if not n_expr.is_self then t = t.not_for_self
                va.stype = t
 
-               if n_block != null then v.visit(n_block)
+               if n_block != null then v.enter_visit(n_block)
 
                # pop context
                v.variable_ctx = old_var_ctx
@@ -646,8 +646,8 @@ redef class AReassignFormExpr
                return psig.return_type.not_for_self
        end
 
-       # Method used through the reassigment operator (once computed)
-       readable var _assign_method: nullable MMMethod
+       redef fun assign_method do return _assign_method.as(not null)
+       var _assign_method: nullable MMMethod
 end
 
 redef class AVarReassignExpr
@@ -705,12 +705,12 @@ redef class AIfexprExpr
        do
                var old_var_ctx = v.variable_ctx
 
-               v.visit(n_expr)
+               v.enter_visit(n_expr)
                v.use_if_true_variable_ctx(n_expr)
-               v.visit(n_then)
+               v.enter_visit(n_then)
                v.variable_ctx = old_var_ctx
                v.use_if_false_variable_ctx(n_expr)
-               v.visit(n_else)
+               v.enter_visit(n_else)
 
                v.check_conform_expr(n_expr, v.type_bool)
 
@@ -732,10 +732,10 @@ redef class AOrExpr
        do
                var old_var_ctx = v.variable_ctx
 
-               v.visit(n_expr)
+               v.enter_visit(n_expr)
                v.use_if_false_variable_ctx(n_expr)
 
-               v.visit(n_expr2)
+               v.enter_visit(n_expr2)
                if n_expr2.if_false_variable_ctx != null then 
                        _if_false_variable_ctx = n_expr2.if_false_variable_ctx
                else
@@ -756,10 +756,10 @@ redef class AAndExpr
        do
                var old_var_ctx = v.variable_ctx
 
-               v.visit(n_expr)
+               v.enter_visit(n_expr)
                v.use_if_true_variable_ctx(n_expr)
 
-               v.visit(n_expr2)
+               v.enter_visit(n_expr2)
                if n_expr2.if_true_variable_ctx != null then 
                        _if_true_variable_ctx = n_expr2.if_true_variable_ctx
                else
@@ -815,7 +815,7 @@ end
 
 redef class AStringFormExpr
        var _meth_with_native: nullable MMMethod
-       fun meth_with_native: MMMethod do return _meth_with_native.as(not null)
+       redef fun meth_with_native: MMMethod do return _meth_with_native.as(not null)
        redef fun after_typing(v)
        do
                _stype = v.type_string
@@ -826,13 +826,14 @@ redef class AStringFormExpr
 end
 
 redef class ASuperstringExpr
-       fun meth_with_capacity: MMMethod do return _meth_with_capacity.as(not null)
+       redef fun meth_with_capacity: MMMethod do return _meth_with_capacity.as(not null)
        var _meth_with_capacity: nullable MMMethod
-       fun meth_add: MMMethod do return _meth_add.as(not null)
+       redef fun meth_add: MMMethod do return _meth_add.as(not null)
        var _meth_add: nullable MMMethod
-       fun meth_to_s: MMMethod do return _meth_to_s.as(not null)
+       redef fun meth_to_s: MMMethod do return _meth_to_s.as(not null)
        var _meth_to_s: nullable MMMethod
-       readable var _atype: nullable MMType
+       redef fun atype do return _atype.as(not null)
+       var _atype: nullable MMType
        redef fun after_typing(v)
        do
                var stype = v.type_string
@@ -858,9 +859,9 @@ redef class ANullExpr
 end
 
 redef class AArrayExpr
-       fun meth_with_capacity: MMMethod do return _meth_with_capacity.as(not null)
+       redef fun meth_with_capacity: MMMethod do return _meth_with_capacity.as(not null)
        var _meth_with_capacity: nullable MMMethod
-       fun meth_add: MMMethod do return _meth_add.as(not null)
+       redef fun meth_add: MMMethod do return _meth_add.as(not null)
        var _meth_add: nullable MMMethod
 
        redef fun after_typing(v)
@@ -883,7 +884,7 @@ redef class AArrayExpr
 end
 
 redef class ARangeExpr
-       fun meth_init: MMMethod do return _meth_init.as(not null)
+       redef fun meth_init: MMMethod do return _meth_init.as(not null)
        var _meth_init: nullable MMMethod
        redef fun after_typing(v)
        do
@@ -922,9 +923,7 @@ end
 
 
 redef class ASuperExpr
-special ASuperInitCall
-       # readable var _prop: MMSrcMethod
-       readable var _init_in_superclass: nullable MMMethod
+       redef readable var _init_in_superclass: nullable MMMethod
        redef fun after_typing(v)
        do
                var precs: Array[MMLocalProperty] = v.local_property.prhe.direct_greaters
@@ -983,11 +982,11 @@ special ASuperInitCall
 end
 
 redef class AAttrFormExpr
-       # Attribute accessed
-       readable var _prop: nullable MMAttribute
+       redef fun prop do return _prop.as(not null)
+       var _prop: nullable MMAttribute
 
-       # Attribute type of the acceded attribute
-       readable var _attr_type: nullable MMType
+       redef fun attr_type do return _attr_type.as(not null)
+       var _attr_type: nullable MMType
 
        # Compute the attribute accessed
        private fun do_typing(v: TypingVisitor)
@@ -1015,7 +1014,7 @@ redef class AAttrExpr
        redef fun after_typing(v)
        do
                do_typing(v)
-               if prop == null then return
+               if _prop == null then return
                _stype = attr_type
                _is_typed = true
        end
@@ -1025,7 +1024,7 @@ redef class AAttrAssignExpr
        redef fun after_typing(v)
        do
                do_typing(v)
-               if prop == null then return
+               if _prop == null then return
                if not v.check_conform_expr(n_value, attr_type) then return
                _is_typed = true
        end
@@ -1035,7 +1034,7 @@ redef class AAttrReassignExpr
        redef fun after_typing(v)
        do
                do_typing(v)
-               if prop == null then return
+               if _prop == null then return
                var t = do_rvalue_typing(v, attr_type)
                if t == null then return
                v.check_conform(self, t, n_value.stype)
@@ -1047,7 +1046,7 @@ redef class AIssetAttrExpr
        redef fun after_typing(v)
        do
                do_typing(v)
-               if prop == null then return
+               if _prop == null then return
                if attr_type.is_nullable then
                        v.error(self, "Error: isset on a nullable attribute.")
                end
@@ -1056,13 +1055,14 @@ redef class AIssetAttrExpr
        end
 end
 
-class AAbsAbsSendExpr
-special PExpr
+redef class AAbsAbsSendExpr
        # The signature of the called property
-       readable var _prop_signature: nullable MMSignature
+       redef fun prop_signature do return _prop_signature.as(not null)
+       var _prop_signature: nullable MMSignature
 
        # The real arguments used (after star transformation) (once computed)
-       readable var _arguments: nullable Array[PExpr]
+       redef fun arguments do return _arguments.as(not null)
+       var _arguments: nullable Array[PExpr]
 
        # Check the conformity of a set of arguments `raw_args' to a signature.
        private fun process_signature(v: TypingVisitor, psig: MMSignature, name: Symbol, raw_args: nullable Array[PExpr]): nullable Array[PExpr]
@@ -1142,8 +1142,7 @@ special PExpr
        end
 end
 
-class AAbsSendExpr
-special AAbsAbsSendExpr
+redef class AAbsSendExpr
        # Compute the called global property
        private fun do_typing(v: TypingVisitor, type_recv: MMType, is_implicit_self: Bool, recv_is_self: Bool, name: Symbol, raw_args: nullable Array[PExpr], closure_defs: nullable Array[PClosureDef])
        do
@@ -1198,16 +1197,16 @@ special AAbsAbsSendExpr
        end
 
        # The invoked method (once computed)
-       readable var _prop: nullable MMMethod
+       redef fun prop do return _prop.as(not null)
+       var _prop: nullable MMMethod
 
        # The return type (if any) (once computed)
-       readable var _return_type: nullable MMType
+       redef readable var _return_type: nullable MMType
 end
 
 # A possible call of constructor in a super class
 # Could be an explicit call or with the 'super' keyword
-class ASuperInitCall
-special AAbsSendExpr
+redef class ASuperInitCall
        private fun register_super_init_call(v: TypingVisitor, property: MMMethod)
        do
                if parent != v.top_block and self != v.top_block then
@@ -1245,10 +1244,9 @@ special AAbsSendExpr
 end
 
 redef class ANewExpr
-special AAbsSendExpr
        redef fun after_typing(v)
        do
-               if n_type._stype == null then return
+               if not n_type.is_typed then return
                var t = n_type.stype
                if t.local_class.global.is_abstract then
                        v.error(self, "Error: try to instantiate abstract class {t.local_class}.")
@@ -1262,7 +1260,7 @@ special AAbsSendExpr
                end
 
                do_typing(v, t, false, false, name, n_args.to_a, null)
-               if prop == null then return
+               if _prop == null then return
 
                if not prop.global.is_init then
                        v.error(self, "Error: {prop} is not a constructor.")
@@ -1275,7 +1273,6 @@ end
 
 
 redef class ASendExpr
-special ASuperInitCall
        # Name of the invoked property
        fun name: Symbol is abstract 
 
@@ -1283,7 +1280,7 @@ special ASuperInitCall
        fun raw_arguments: nullable Array[PExpr] is abstract
 
        # Closure definitions
-       fun closure_defs: nullable Array[PClosureDef] do return null
+       redef fun closure_defs: nullable Array[PClosureDef] do return null
 
        redef fun after_typing(v)
        do
@@ -1312,10 +1309,9 @@ special ASuperInitCall
        end
 end
 
-class ASendReassignExpr
-special ASendExpr
-special AReassignFormExpr
-       readable var _read_prop: nullable MMMethod
+redef class ASendReassignExpr
+       redef fun read_prop do return _read_prop.as(not null)
+       var _read_prop: nullable MMMethod
        redef fun do_all_typing(v)
        do
                if not v.check_expr(n_expr) then return
@@ -1514,7 +1510,6 @@ redef class ACallAssignExpr
 end
 
 redef class ACallReassignExpr
-special ASendReassignExpr
        redef fun variable_create(variable)
        do
                return new AVarReassignExpr.init_avarreassignexpr(n_id, n_assign_op, n_value)
@@ -1539,7 +1534,6 @@ redef class ABraAssignExpr
 end
 
 redef class ABraReassignExpr
-special ASendReassignExpr
        redef fun name do return once "[]".to_symbol
        redef fun raw_arguments do return n_args.to_a
 end
@@ -1550,7 +1544,6 @@ redef class AInitExpr
 end
 
 redef class AClosureCallExpr
-special AAbsAbsSendExpr
        var _variable: nullable ClosureVariable
        redef fun variable do return _variable.as(not null)
 
@@ -1633,6 +1626,7 @@ special PExpr
        private fun check_expr_cast(v: TypingVisitor, n_expr: PExpr, n_type: PType)
        do
                if not v.check_expr(n_expr) then return
+               if not n_type.is_typed then return
                var etype = n_expr.stype
                var ttype = n_type.stype
                if etype == ttype then
@@ -1660,6 +1654,7 @@ special ATypeCheckExpr
        redef fun after_typing(v)
        do
                check_expr_cast(v, n_expr, n_type)
+               if not n_type.is_typed then return
                var variable = n_expr.its_variable
                if variable != null then
                        _if_true_variable_ctx = v.variable_ctx.sub_with(self, variable, n_type.stype)
@@ -1674,6 +1669,7 @@ special ATypeCheckExpr
        redef fun after_typing(v)
        do
                check_expr_cast(v, n_expr, n_type)
+               if not n_type.is_typed then return
                _stype = n_type.stype
                _is_typed = _stype != null
        end