parser: locate errors with locations in ANode
[nit.git] / src / syntax / syntax_base.nit
index 0f1440b..127163d 100644 (file)
@@ -22,9 +22,17 @@ import mmloader
 
 # Concrete NIT source module
 class MMSrcModule
-special MMModule
+       super MMModule
+       # A source module can locate AST nodes of related MM entities
+       # Once a source module AST is no more needed, _nodes is set to null
+       # See ToolContext::keep_ast property in syntax.nit for details
+       var _nodes: nullable HashMap[Object, nullable ANode] = new HashMap[Object, nullable ANode]
+
+       # Release the AST
+       fun clear_ast do _nodes = null
+
        # The related AST node
-       readable var _node: AModule
+       fun node: AModule do return nodes(self).as(AModule)
 
        # Concrete NIT source local classs by name
        readable var _src_local_classes: Map[Symbol, MMSrcLocalClass]
@@ -32,15 +40,32 @@ special MMModule
        init(c: MMContext, source: AModule, dir: MMDirectory, name: Symbol, loc: Location)
        do
                super(name, dir, c, loc)
-               _node = source
+               nodes(self) = source
                _src_local_classes = new HashMap[Symbol, MMSrcLocalClass]
        end
+
+       redef fun nodes(o: Object): nullable ANode
+       do
+               if _nodes != null and _nodes.has_key(o) then return _nodes[o] else return null
+       end
+       redef fun nodes=(o: Object, n: nullable ANode)
+       do
+               assert not _nodes.has_key(o)
+               _nodes[o] = n
+       end
+end
+
+redef class MMModule
+       # The AST node of some entity
+       private fun nodes(o: Object): nullable ANode do return null
+       # The AST node of some entity
+       private fun nodes=(o: Object, n: nullable ANode) do abort
 end
 
 redef class MMGlobalClass
        # Check that a module can access a class
-       fun check_visibility(v: AbsSyntaxVisitor, n: PNode, cm: MMSrcModule): Bool do
-               var pm = intro.module
+       fun check_visibility(v: AbsSyntaxVisitor, n: ANode, cm: MMSrcModule): Bool do
+               var pm = intro.mmmodule
                assert pm isa MMSrcModule
                var vpm = cm.visibility_for(pm)
                if vpm == 3 then
@@ -58,9 +83,9 @@ end
 
 # Concrete NIT source local classes
 class MMSrcLocalClass
-special MMConcreteClass
-       # The related AST nodes
-       readable var _nodes: Array[PClassdef]
+       super MMConcreteClass
+       # The first related AST node (if any)
+       fun node: nullable AClassdef do return mmmodule.nodes(self).as(nullable AClassdef)
 
        # Concrete NIT source generic formal parameter by name
        readable var _formal_dict: Map[Symbol, MMTypeFormalParameter] = new HashMap[Symbol, MMTypeFormalParameter]
@@ -68,22 +93,18 @@ special MMConcreteClass
        # Concrete NIT source properties by name
        readable var _src_local_properties: Map[Symbol, MMLocalProperty]
 
-       init(mod: MMSrcModule, n: Symbol, cla: nullable PClassdef, a: Int)
+       init(mod: MMSrcModule, n: Symbol, cla: nullable AClassdef, a: Int)
        do
                super(mod, n, a)
-               if cla == null then
-                       _nodes = new Array[PClassdef]
-               else
-                       _nodes = [cla]
-               end
+               mod.nodes(self) = cla
                _src_local_properties = new HashMap[Symbol, MMLocalProperty]
        end
 end
 
 redef class MMGlobalProperty
        # Check that a module can access a property
-       fun check_visibility(v: AbsSyntaxVisitor, n: PNode, cm: MMSrcModule, allows_protected: Bool): Bool do
-               var pm = local_class.module
+       fun check_visibility(v: AbsSyntaxVisitor, n: ANode, cm: MMSrcModule, allows_protected: Bool): Bool do
+               var pm = local_class.mmmodule
                assert pm isa MMSrcModule
                var vpm = cm.visibility_for(pm)
                if vpm == 3 then
@@ -105,7 +126,7 @@ end
 
 redef class MMLocalProperty
        # The attached node (if any)
-       fun node: nullable PNode do return null
+       fun node: nullable ANode do return null
 
        # Is the concrete method defined as init
        fun is_init: Bool do return false
@@ -113,36 +134,37 @@ end
 
 # Concrete NIT source attribute
 class MMSrcAttribute
-special MMAttribute
-       redef readable var _node: AAttrPropdef
+       super MMAttribute
+       redef fun node: nullable AAttrPropdef do return mmmodule.nodes(self).as(nullable AAttrPropdef)
        init(name: Symbol, cla: MMLocalClass, n: AAttrPropdef)
        do
                super(name, cla)
-               _node = n
+               cla.mmmodule.nodes(self) = n
        end
 end
 
 # Concrete NIT source method
 class MMSrcMethod
-special MMMethod
+       super MMMethod
        redef fun is_intern do return false
        redef fun is_abstract do return false
+       redef fun extern_name do return null
 end
 
 # Concrete NIT source method for an automatic accesor
 class MMAttrImplementationMethod
-special MMSrcMethod
-       redef readable var _node: AAttrPropdef
+       super MMSrcMethod
+       redef fun node: nullable AAttrPropdef do return mmmodule.nodes(self).as(nullable AAttrPropdef)
        init(name: Symbol, cla: MMLocalClass, n: AAttrPropdef)
        do
                super(name, cla)
-               _node = n
+               cla.mmmodule.nodes(self) = n
        end
 end
 
 # Concrete NIT source method for an automatic read accesor
 class MMReadImplementationMethod
-special MMAttrImplementationMethod
+       super MMAttrImplementationMethod
        init(name: Symbol, cla: MMLocalClass, n: AAttrPropdef)
        do
                super(name, cla, n)
@@ -151,7 +173,7 @@ end
 
 # Concrete NIT source method for an automatic write accesor
 class MMWriteImplementationMethod
-special MMAttrImplementationMethod
+       super MMAttrImplementationMethod
        init(name: Symbol, cla: MMLocalClass, n: AAttrPropdef)
        do
                super(name, cla, n)
@@ -160,36 +182,36 @@ end
 
 # Concrete NIT source method for an explicit method
 class MMMethSrcMethod
-special MMSrcMethod
+       super MMSrcMethod
        redef readable var _is_init: Bool
        redef readable var _is_intern: Bool
        redef readable var _is_abstract: Bool
-       redef readable var _node: nullable AMethPropdef
+       redef readable writable var _extern_name: nullable String # Will be computed during MMBuilder
+       redef fun node: nullable AMethPropdef do return mmmodule.nodes(self).as(nullable AMethPropdef)
        init(name: Symbol, cla: MMLocalClass, n: nullable AMethPropdef)
        do
                super(name, cla)
-               _node = n
+               cla.mmmodule.nodes(self) = n
                _is_init = node isa AConcreteInitPropdef
                _is_intern = node isa AInternMethPropdef
                _is_abstract = node isa ADeferredMethPropdef
+               _extern_name = null
        end
 end
 
 # Concrete NIT source virtual type
 class MMSrcTypeProperty
-special MMLocalProperty
-special MMTypeProperty
-       redef readable var _node: ATypePropdef
+       super MMLocalProperty
+       super MMTypeProperty
        init(name: Symbol, cla: MMLocalClass, n: ATypePropdef)
        do
                super(name, cla)
-               _node = n
        end
 end
 
 # Concrete NIT implicit constructor
 class MMImplicitInit
-special MMMethSrcMethod
+       super MMMethSrcMethod
        fun super_init: nullable MMLocalProperty is abstract
        redef fun is_init do return true
        readable var _unassigned_attributes: Array[MMSrcAttribute]
@@ -208,7 +230,7 @@ abstract class Variable
        readable var _name: Symbol
 
        # Declaration AST node
-       readable var _decl: nullable PNode
+       readable var _decl: nullable ANode
 
        # Static type
        readable writable var _stype: nullable MMType
@@ -217,7 +239,7 @@ abstract class Variable
 
        fun kind: String is abstract
 
-       init(n: Symbol, d: nullable PNode)
+       init(n: Symbol, d: nullable ANode)
        do
                _name = n
                _decl = d
@@ -226,35 +248,35 @@ end
 
 # Variable declared with 'var'
 class VarVariable
-special Variable
+       super Variable
        redef fun kind do return once "variable"
-       init(n: Symbol, d: PNode) do super
+       init(n: Symbol, d: ANode) do super
 end
 
 # Parameter of method (declared in signature)
 class ParamVariable
-special Variable
+       super Variable
        redef fun kind do return once "parameter"
-       init(n: Symbol, d: nullable PNode) do super
+       init(n: Symbol, d: nullable ANode) do super
 end
 
 # Automatic variable (like in the 'for' statement)
 class AutoVariable
-special Variable
+       super Variable
        redef fun kind do return once "automatic variable"
-       init(n: Symbol, d: PNode) do super
+       init(n: Symbol, d: ANode) do super
 end
 
 # False variable corresponding to closures declared in signatures
 # Lives in the same namespace than variables
 class ClosureVariable
-special Variable
+       super Variable
        redef fun kind do return once "closure"
 
        # The signature of the closure
        readable var _closure: MMClosure
 
-       init(n: Symbol, d: PNode, c: MMClosure)
+       init(n: Symbol, d: ANode, c: MMClosure)
        do
                super(n, d)
                _closure = c
@@ -265,81 +287,97 @@ end
 
 # Visitor used during the syntax analysis
 class AbsSyntaxVisitor
-special Visitor
+       super Visitor
+       fun get_type_by_name(clsname: Symbol): MMType
+       do
+               if not _mmmodule.has_global_class_named(clsname) then _tc.fatal_error(_mmmodule.location, "Missing necessary class: \"{clsname}\"")
+               var cls = _mmmodule.class_by_name(clsname)
+               return cls.get_type
+       end
+
+       fun get_instantiated_type_by_name(clsname: Symbol, vtype: Array[MMType]): MMType
+       do
+               if not _mmmodule.has_global_class_named(clsname) then _tc.fatal_error(_mmmodule.location, "Missing necessary class: \"{clsname}\"")
+               var cls = _mmmodule.class_by_name(clsname)
+               return cls.get_instantiate_type(vtype)
+       end
+
        # The root type Object
        fun type_object: MMType
        do
-               return _module.class_by_name(once ("Object".to_symbol)).get_type
+               return get_type_by_name(once ("Object".to_symbol))
        end
 
        # The primitive type Bool
        fun type_bool: MMType
        do
-               return _module.class_by_name(once ("Bool".to_symbol)).get_type
+               return get_type_by_name(once ("Bool".to_symbol))
        end
        
        # The primitive type Int 
        fun type_int: MMType
        do
-               return _module.class_by_name(once ("Int".to_symbol)).get_type
+               return get_type_by_name(once ("Int".to_symbol))
        end
 
        # The primitive type Float
        fun type_float: MMType
        do
-               return _module.class_by_name(once ("Float".to_symbol)).get_type
+               return get_type_by_name(once ("Float".to_symbol))
        end
 
        # The primitive type Char
        fun type_char: MMType
        do
-               return _module.class_by_name(once ("Char".to_symbol)).get_type
+               return get_type_by_name(once ("Char".to_symbol))
        end
 
        # The primitive type String
        fun type_string: MMType
        do
-               return _module.class_by_name(once ("String".to_symbol)).get_type
-       end
-
-       # The primitive type Collection[nullable Object]
-       fun type_collection: MMType
-       do
-               return _module.class_by_name(once ("Collection".to_symbol)).get_instantiate_type([type_object.as_nullable])
+               return get_type_by_name(once ("String".to_symbol))
        end
 
        # The primitive type NativeString
        fun type_nativestring: MMType
        do
-               return _module.class_by_name(once ("NativeString".to_symbol)).get_type
+               return get_type_by_name(once ("NativeString".to_symbol))
        end
 
        # The primitive type Array[?]
        fun type_array(stype: MMType): MMType
        do
-               return _module.class_by_name(once ("Array".to_symbol)).get_instantiate_type([stype])
+               return get_instantiated_type_by_name(once ("Array".to_symbol), [stype])
        end
 
        # The primitive type Discrete
        fun type_discrete: MMType
        do
-               return _module.class_by_name(once ("Discrete".to_symbol)).get_type
+               return get_type_by_name(once ("Discrete".to_symbol))
        end
 
        # The primitive type Range[?]
        fun type_range(stype: MMType): MMType
        do
-               return _module.class_by_name(once ("Range".to_symbol)).get_instantiate_type([stype])
+               return get_instantiated_type_by_name(once ("Range".to_symbol), [stype])
        end
 
        # The primitive type of null
        fun type_none: MMType
        do
-               return _module.type_none
+               return _mmmodule.type_none
+       end
+
+       fun get_method(recv: MMType, name: Symbol): MMMethod
+       do
+               if not recv.local_class.has_global_property_by_name(name) then
+                       fatal_error(current_node, "Fatal Error: {recv} must have a property named {name}.")
+               end
+               return recv.local_class.select_method(name)
        end
 
        # The current module
-       readable var _module: MMSrcModule
+       readable var _mmmodule: MMSrcModule
 
        # The current class
        fun local_class: MMSrcLocalClass do return _local_class.as(not null)
@@ -353,32 +391,25 @@ special Visitor
        readable var _tc: ToolContext 
 
        # Display an error for a given syntax node
-       fun error(n: nullable PNode, s: String)
+       fun error(n: nullable ANode, s: String)
        do
-               _tc.error(n.location, "{locate(n)}: {s}")
+               _tc.error(if n == null then null else n.hot_location, s)
        end
 
        # Add an error, show errors and quit
-       fun fatal_error(n: nullable PNode, s: String)
+       fun fatal_error(n: nullable ANode, s: String)
        do
-               _tc.fatal_error(n.location, "{locate(n)}: {s}")
+               _tc.fatal_error(if n == null then null else n.hot_location, s)
        end
 
        # Display a warning for a given syntax node
-       fun warning(n: nullable PNode, s: String)
+       fun warning(n: nullable ANode, s: String)
        do
-               _tc.warning(n.location, "{locate(n)}: {s}")
-       end
-
-       #
-       fun locate(n: nullable PNode): String
-       do
-               if n != null then return n.locate
-               return _module.location.file
+               _tc.warning(if n == null then null else n.hot_location, s)
        end
 
        # Check conformity and display error
-       fun check_conform(n: PNode, subtype: nullable MMType, stype: nullable MMType): Bool
+       fun check_conform(n: ANode, subtype: nullable MMType, stype: nullable MMType): Bool
        do
                if stype == null or subtype == null then
                        return false
@@ -393,11 +424,11 @@ special Visitor
        # Check that an expression has a static type and that 
        # Display an error and return false if n is a statement
        # Require that the static type of n is known
-       fun check_expr(n: PExpr): Bool
+       fun check_expr(n: AExpr): Bool
        do
                if not n.is_typed then
                        if tc.error_count == 0 then
-                               print("{n.locate} not typed but not error")
+                               print("{n.location} not typed but not error")
                                abort
                        end
                        # An error occured in a sub node,
@@ -411,7 +442,7 @@ special Visitor
        end
 
        # Combine check_conform and check_expr
-       fun check_conform_expr(n: PExpr, stype: nullable MMType): Bool
+       fun check_conform_expr(n: AExpr, stype: nullable MMType): Bool
        do
                if stype == null then return false
                if check_expr(n) then return check_conform(n, n.stype, stype) else return false
@@ -427,9 +458,9 @@ special Visitor
        #   Int, Int, Object => return Object
        #   Int, Float => display error, return null
        #   nullable Int, Object => return nullable Object
-       fun check_conform_multiexpr(stype: nullable MMType, nodes: Collection[PExpr]): nullable MMType
+       fun check_conform_multiexpr(stype: nullable MMType, nodes: Collection[AExpr]): nullable MMType
        do
-               var node: nullable PExpr = null # candidate node
+               var node: nullable AExpr = null # candidate node
                for n in nodes do
                        if not check_expr(n) then return null
                        var ntype = n.stype
@@ -443,12 +474,13 @@ special Visitor
                                node = n
                        end
                end
+               assert stype != null
                for n in nodes do
-                       if not n.stype < stype.as(not null) then
+                       if not n.stype < stype then
                                if node == null then
                                        error(n, "Type error: no most general type. Got {n.stype} and {stype}.")
                                else
-                                       error(n, "Type error: no most general type. Got {n.stype} and {stype} at {node.locate}.")
+                                       error(n, "Type error: no most general type. Got {n.stype} and {stype} at {node.location.relative_to(n.location)}.")
                                end
                                return null
                        end
@@ -456,16 +488,16 @@ special Visitor
                return stype
        end
 
-       protected init(tc: ToolContext, module: MMSrcModule)
+       protected init(tc: ToolContext, mmmodule: MMSrcModule)
        do
                _tc = tc
-               _module = module
+               _mmmodule = mmmodule
        end
 end
 
 ###############################################################################
 
-redef class PNode
+redef class ANode
        protected fun accept_abs_syntax_visitor(v: AbsSyntaxVisitor) do visit_all(v)
 end
 
@@ -485,9 +517,17 @@ redef class Token
        end
 end
 
-redef class PClassdef
+redef class AClassdef
        # Associated class (MM entity)
        fun local_class: MMSrcLocalClass is abstract
+
+       # Next AClassdef of the same class (if any)
+       readable writable var _next_node: nullable AClassdef = null
+end
+
+redef class APropdef
+       # Associated 'self' variable
+       fun self_var: ParamVariable is abstract
 end
 
 redef class AAttrPropdef
@@ -509,9 +549,6 @@ end
 redef class AMethPropdef
        # Associated method (MM entity)
        fun method: MMMethSrcMethod is abstract
-
-       # Associated 'self' variable
-       fun self_var: ParamVariable is abstract
 end
 
 redef class ATypePropdef
@@ -519,7 +556,7 @@ redef class ATypePropdef
        fun prop: MMSrcTypeProperty is abstract
 end
 
-redef class PParam
+redef class AParam
        # Position in the signature
        fun position: Int is abstract
 
@@ -527,7 +564,7 @@ redef class PParam
        fun variable: ParamVariable is abstract 
 end
 
-redef class PClosureDecl
+redef class AClosureDecl
        # Position in the signature
        fun position: Int is abstract
 
@@ -535,27 +572,7 @@ redef class PClosureDecl
        fun variable: ClosureVariable is abstract
 end
 
-redef class PType
-       # Retrieve the local class corresponding to the type.
-       # Display an error and return null if there is no class
-       # Display an error and return null if the type is not class based (formal one)
-       fun get_local_class(v: AbsSyntaxVisitor): nullable MMLocalClass is abstract
-
-       # Retrieve corresponding static type.
-       # Display an error and return null if there is a problem
-       fun get_stype(v: AbsSyntaxVisitor): nullable MMType is abstract
-
-       # Retrieve corresponding static type.
-       # Display an error and return null if there is a problem
-       # But do not performs any subtype check.
-       # get_unchecked_stype should be called to check that the static type is fully valid
-       fun get_unchecked_stype(v: AbsSyntaxVisitor): nullable MMType is abstract
-
-       # Check that a static definition type is conform with regard to formal types
-       # Useful with get_unchecked_stype
-       # Remember that conformance check need that ancestors are totaly computed
-       fun check_conform(v: AbsSyntaxVisitor) is abstract
-
+redef class AType
        # Is the node correcly typed
        # Return false if typed was not yet computed or
        # if an error occured during the typing computation
@@ -563,16 +580,17 @@ redef class PType
 
        # Return corresponding static type. (require is_typed)
        fun stype: MMType is abstract
-end
 
-redef class AType
        var _stype_cache: nullable MMType = null
        var _stype_cached: Bool = false
 
-       redef fun get_local_class(v)
+       # Retrieve the local class corresponding to the type.
+       # Display an error and return null if there is no class
+       # Display an error and return null if the type is not class based (formal one)
+       fun get_local_class(v: AbsSyntaxVisitor): nullable MMLocalClass
        do
                var name = n_id.to_symbol
-               var mod = v.module
+               var mod = v.mmmodule
                var cla = v.local_class
 
                if cla.formal_dict.has_key(name) or cla.has_global_property_by_name(name) then
@@ -592,13 +610,17 @@ redef class AType
                return local_class
        end
 
-       redef fun get_unchecked_stype(v)
+       # Retrieve corresponding static type.
+       # Display an error and return null if there is a problem
+       # But do not performs any subtype check.
+       # get_unchecked_stype should be called to check that the static type is fully valid
+       fun get_unchecked_stype(v: AbsSyntaxVisitor): nullable MMType
        do
                if _stype_cached then return _stype_cache
                _stype_cached = true
 
                var name = n_id.to_symbol
-               var mod = v.module
+               var mod = v.mmmodule
                var cla = v.local_class
                var t: nullable MMType
 
@@ -658,8 +680,10 @@ redef class AType
                _stype_cache = t
                return t
        end
-       
-       redef fun get_stype(v)
+
+       # Retrieve corresponding static type.
+       # Display an error and return null if there is a problem
+       fun get_stype(v: AbsSyntaxVisitor): nullable MMType
        do
                var t = get_unchecked_stype(v)
                if t == null then return null
@@ -668,7 +692,10 @@ redef class AType
                return t
        end
 
-       redef fun check_conform(v)
+       # Check that a static definition type is conform with regard to formal types
+       # Useful with get_unchecked_stype
+       # Remember that conformance check need that ancestors are totaly computed
+       fun check_conform(v: AbsSyntaxVisitor)
        do
                var st = get_unchecked_stype(v)
                if st == null then return 
@@ -688,7 +715,7 @@ redef class AType
        end
 end
 
-redef class PExpr
+redef class AExpr
        # Is the expression node correcly typed
        # Return false if typed was not yet computed or
        # if an error occured during the typing computation
@@ -704,16 +731,16 @@ redef class PExpr
 end
 
 class AAbsAbsSendExpr
-special PExpr
+       super AExpr
        # The signature of the called property (require is_typed)
        fun prop_signature: MMSignature is abstract
 
-       # The real arguments used (after star transformation) (require is_typed)
-       fun arguments: Array[PExpr] is abstract
+       # The raw arguments used (without vararg transformation) (require is_typed)
+       fun raw_arguments: Array[AExpr] is abstract
 end
 
 class AAbsSendExpr
-special AAbsAbsSendExpr
+       super AAbsAbsSendExpr
        # The invoked method (require is_typed)
        fun prop: MMMethod is abstract
 
@@ -722,22 +749,22 @@ special AAbsAbsSendExpr
 end
 
 class ASuperInitCall
-special AAbsSendExpr
+       super AAbsSendExpr
 end
 
 redef class ASuperExpr
-special ASuperInitCall
+       super ASuperInitCall
        fun init_in_superclass: nullable MMMethod is abstract
 end
 
 redef class ANewExpr
-special AAbsSendExpr
+       super AAbsSendExpr
 end
 
 redef class ASendExpr
-special ASuperInitCall
+       super ASuperInitCall
        # Closure definitions
-       fun closure_defs: nullable Array[PClosureDef] is abstract
+       fun closure_defs: nullable Array[AClosureDef] is abstract
 end
 
 redef class AReassignFormExpr
@@ -746,19 +773,19 @@ redef class AReassignFormExpr
 end
 
 class ASendReassignExpr
-special ASendExpr
-special AReassignFormExpr
+       super ASendExpr
+       super AReassignFormExpr
        # The invoked method used to read (require is_typed)
        # prop is the method used to write
        fun read_prop: MMMethod is abstract
 end
 
 redef class ACallReassignExpr
-special ASendReassignExpr
+       super ASendReassignExpr
 end
 
 redef class ABraReassignExpr
-special ASendReassignExpr
+       super ASendReassignExpr
 end
 
 redef class AAttrFormExpr
@@ -769,26 +796,10 @@ redef class AAttrFormExpr
        fun attr_type: MMType is abstract
 end
 
-redef class AStringFormExpr
-       fun meth_with_native: MMMethod is abstract
-end
-
 redef class ASuperstringExpr
-       fun meth_with_capacity: MMMethod is abstract
-       fun meth_add: MMMethod is abstract
-       fun meth_to_s: MMMethod is abstract
        fun atype: MMType is abstract
 end
 
-redef class AArrayExpr
-       fun meth_with_capacity: MMMethod is abstract
-       fun meth_add: MMMethod is abstract
-end
-
-redef class ARangeExpr
-       fun meth_init: MMMethod is abstract
-end
-
 redef class AVardeclExpr
        # Assiociated local variable
        fun variable: VarVariable is abstract
@@ -797,35 +808,27 @@ end
 
 redef class AForExpr
        # Associated automatic local variable
-       fun variable: AutoVariable is abstract
-       fun meth_iterator: MMMethod is abstract
-       fun meth_is_ok: MMMethod is abstract
-       fun meth_item: MMMethod is abstract
-       fun meth_next: MMMethod is abstract
+       fun variables: Array[AutoVariable] is abstract
 end
 
 redef class ASelfExpr
        # Associated local variable
        fun variable: ParamVariable is abstract
-       #readable writable var _variable: nullable ParamVariable
 end
 
 redef class AVarFormExpr
        # Associated local variable
        fun variable: Variable is abstract
-       #readable writable var _variable: nullable Variable
 end
 
 redef class AClosureCallExpr
-special AAbsAbsSendExpr
+       super AAbsAbsSendExpr
        # Associated closure variable
        fun variable: ClosureVariable is abstract
-       #readable writable var _variable: nullable ClosureVariable
 end
 
-redef class PClosureDef
+redef class AClosureDef
        # Associated closure
-       #readable writable var _closure: nullable MMClosure
        fun closure: MMClosure is abstract
 
        # Automatic variables