f693dd46fa3050039c7ec7e448d3a344e6a72183
[nit.git] / src / syntax / syntax_base.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2008 Jean Privat <jean@pryen.org>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 # Common syntax structures for syntax analysis of NIT AST.
18 package syntax_base
19
20 import parser
21 import mmloader
22
23 # Concrete NIT source module
24 class MMSrcModule
25 special MMModule
26 # A source module can locate AST nodes of related MM entities
27 # Once a source module AST is no more needed, _nodes is set to null
28 # See ToolContext::keep_ast property in syntax.nit for details
29 var _nodes: nullable HashMap[Object, nullable ANode] = new HashMap[Object, nullable ANode]
30
31 # Release the AST
32 fun clear_ast do _nodes = null
33
34 # The related AST node
35 fun node: AModule do return nodes(self).as(AModule)
36
37 # Concrete NIT source local classs by name
38 readable var _src_local_classes: Map[Symbol, MMSrcLocalClass]
39
40 init(c: MMContext, source: AModule, dir: MMDirectory, name: Symbol, loc: Location)
41 do
42 super(name, dir, c, loc)
43 nodes(self) = source
44 _src_local_classes = new HashMap[Symbol, MMSrcLocalClass]
45 end
46
47 redef fun nodes(o: Object): nullable ANode
48 do
49 if _nodes != null and _nodes.has_key(o) then return _nodes[o] else return null
50 end
51 redef fun nodes=(o: Object, n: nullable ANode)
52 do
53 assert not _nodes.has_key(o)
54 _nodes[o] = n
55 end
56 end
57
58 redef class MMModule
59 # The AST node of some entity
60 private fun nodes(o: Object): nullable ANode do return null
61 # The AST node of some entity
62 private fun nodes=(o: Object, n: nullable ANode) do abort
63 end
64
65 redef class MMGlobalClass
66 # Check that a module can access a class
67 fun check_visibility(v: AbsSyntaxVisitor, n: ANode, cm: MMSrcModule): Bool do
68 var pm = intro.module
69 assert pm isa MMSrcModule
70 var vpm = cm.visibility_for(pm)
71 if vpm == 3 then
72 return true
73 else if vpm == 0 then
74 v.error(n, "Visibility error: Class {self} comes from the hidden module {cm}.") # TODO: should not occur
75 return false
76 else if visibility_level >= 3 then
77 v.error(n, "Visibility error: Class {self} is private.")
78 return false
79 end
80 return true
81 end
82 end
83
84 # Concrete NIT source local classes
85 class MMSrcLocalClass
86 special MMConcreteClass
87 # The first related AST node (if any)
88 fun node: nullable AClassdef do return module.nodes(self).as(nullable AClassdef)
89
90 # Concrete NIT source generic formal parameter by name
91 readable var _formal_dict: Map[Symbol, MMTypeFormalParameter] = new HashMap[Symbol, MMTypeFormalParameter]
92
93 # Concrete NIT source properties by name
94 readable var _src_local_properties: Map[Symbol, MMLocalProperty]
95
96 init(mod: MMSrcModule, n: Symbol, cla: nullable AClassdef, a: Int)
97 do
98 super(mod, n, a)
99 mod.nodes(self) = cla
100 _src_local_properties = new HashMap[Symbol, MMLocalProperty]
101 end
102 end
103
104 redef class MMGlobalProperty
105 # Check that a module can access a property
106 fun check_visibility(v: AbsSyntaxVisitor, n: ANode, cm: MMSrcModule, allows_protected: Bool): Bool do
107 var pm = local_class.module
108 assert pm isa MMSrcModule
109 var vpm = cm.visibility_for(pm)
110 if vpm == 3 then
111 return true
112 else if vpm == 0 then
113 # TODO: should not occurs
114 v.error(n, "Visibility error: Property {self} comes from the hidden module {cm}.")
115 return false
116 else if visibility_level >= 3 then
117 v.error(n, "Visibility error: Property {self} is private.")
118 return false
119 else if visibility_level >= 2 and not allows_protected then
120 v.error(n, "Visibility error: Property {self} is protected and can only acceded by self.")
121 return false
122 end
123 return true
124 end
125 end
126
127 redef class MMLocalProperty
128 # The attached node (if any)
129 fun node: nullable ANode do return null
130
131 # Is the concrete method defined as init
132 fun is_init: Bool do return false
133 end
134
135 # Concrete NIT source attribute
136 class MMSrcAttribute
137 special MMAttribute
138 redef fun node: nullable AAttrPropdef do return module.nodes(self).as(nullable AAttrPropdef)
139 init(name: Symbol, cla: MMLocalClass, n: AAttrPropdef)
140 do
141 super(name, cla)
142 cla.module.nodes(self) = n
143 end
144 end
145
146 # Concrete NIT source method
147 class MMSrcMethod
148 special MMMethod
149 redef fun is_intern do return false
150 redef fun is_abstract do return false
151 end
152
153 # Concrete NIT source method for an automatic accesor
154 class MMAttrImplementationMethod
155 special MMSrcMethod
156 redef fun node: nullable AAttrPropdef do return module.nodes(self).as(nullable AAttrPropdef)
157 init(name: Symbol, cla: MMLocalClass, n: AAttrPropdef)
158 do
159 super(name, cla)
160 cla.module.nodes(self) = n
161 end
162 end
163
164 # Concrete NIT source method for an automatic read accesor
165 class MMReadImplementationMethod
166 special MMAttrImplementationMethod
167 init(name: Symbol, cla: MMLocalClass, n: AAttrPropdef)
168 do
169 super(name, cla, n)
170 end
171 end
172
173 # Concrete NIT source method for an automatic write accesor
174 class MMWriteImplementationMethod
175 special MMAttrImplementationMethod
176 init(name: Symbol, cla: MMLocalClass, n: AAttrPropdef)
177 do
178 super(name, cla, n)
179 end
180 end
181
182 # Concrete NIT source method for an explicit method
183 class MMMethSrcMethod
184 special MMSrcMethod
185 redef readable var _is_init: Bool
186 redef readable var _is_intern: Bool
187 redef readable var _is_abstract: Bool
188 redef fun node: nullable AMethPropdef do return module.nodes(self).as(nullable AMethPropdef)
189 init(name: Symbol, cla: MMLocalClass, n: nullable AMethPropdef)
190 do
191 super(name, cla)
192 cla.module.nodes(self) = n
193 _is_init = node isa AConcreteInitPropdef
194 _is_intern = node isa AInternMethPropdef
195 _is_abstract = node isa ADeferredMethPropdef
196 end
197 end
198
199 # Concrete NIT source virtual type
200 class MMSrcTypeProperty
201 special MMLocalProperty
202 special MMTypeProperty
203 init(name: Symbol, cla: MMLocalClass, n: ATypePropdef)
204 do
205 super(name, cla)
206 end
207 end
208
209 # Concrete NIT implicit constructor
210 class MMImplicitInit
211 special MMMethSrcMethod
212 fun super_init: nullable MMLocalProperty is abstract
213 redef fun is_init do return true
214 readable var _unassigned_attributes: Array[MMSrcAttribute]
215 readable var _super_inits: Array[MMLocalProperty]
216 init(cla: MMLocalClass, unassigned_attributes: Array[MMSrcAttribute], super_inits: Array[MMLocalProperty])
217 do
218 super(once "init".to_symbol, cla, null)
219 _unassigned_attributes = unassigned_attributes
220 _super_inits = super_inits
221 end
222 end
223
224 # Local variables
225 abstract class Variable
226 # Name of the variable
227 readable var _name: Symbol
228
229 # Declaration AST node
230 readable var _decl: nullable ANode
231
232 # Static type
233 readable writable var _stype: nullable MMType
234
235 redef fun to_s do return _name.to_s
236
237 fun kind: String is abstract
238
239 init(n: Symbol, d: nullable ANode)
240 do
241 _name = n
242 _decl = d
243 end
244 end
245
246 # Variable declared with 'var'
247 class VarVariable
248 special Variable
249 redef fun kind do return once "variable"
250 init(n: Symbol, d: ANode) do super
251 end
252
253 # Parameter of method (declared in signature)
254 class ParamVariable
255 special Variable
256 redef fun kind do return once "parameter"
257 init(n: Symbol, d: nullable ANode) do super
258 end
259
260 # Automatic variable (like in the 'for' statement)
261 class AutoVariable
262 special Variable
263 redef fun kind do return once "automatic variable"
264 init(n: Symbol, d: ANode) do super
265 end
266
267 # False variable corresponding to closures declared in signatures
268 # Lives in the same namespace than variables
269 class ClosureVariable
270 special Variable
271 redef fun kind do return once "closure"
272
273 # The signature of the closure
274 readable var _closure: MMClosure
275
276 init(n: Symbol, d: ANode, c: MMClosure)
277 do
278 super(n, d)
279 _closure = c
280 end
281 end
282
283 ###############################################################################
284
285 # Visitor used during the syntax analysis
286 class AbsSyntaxVisitor
287 special Visitor
288 # The root type Object
289 fun type_object: MMType
290 do
291 return _module.class_by_name(once ("Object".to_symbol)).get_type
292 end
293
294 # The primitive type Bool
295 fun type_bool: MMType
296 do
297 return _module.class_by_name(once ("Bool".to_symbol)).get_type
298 end
299
300 # The primitive type Int
301 fun type_int: MMType
302 do
303 return _module.class_by_name(once ("Int".to_symbol)).get_type
304 end
305
306 # The primitive type Float
307 fun type_float: MMType
308 do
309 return _module.class_by_name(once ("Float".to_symbol)).get_type
310 end
311
312 # The primitive type Char
313 fun type_char: MMType
314 do
315 return _module.class_by_name(once ("Char".to_symbol)).get_type
316 end
317
318 # The primitive type String
319 fun type_string: MMType
320 do
321 return _module.class_by_name(once ("String".to_symbol)).get_type
322 end
323
324 # The primitive type Collection[nullable Object]
325 fun type_collection: MMType
326 do
327 return _module.class_by_name(once ("Collection".to_symbol)).get_instantiate_type([type_object.as_nullable])
328 end
329
330 # The primitive type NativeString
331 fun type_nativestring: MMType
332 do
333 return _module.class_by_name(once ("NativeString".to_symbol)).get_type
334 end
335
336 # The primitive type Array[?]
337 fun type_array(stype: MMType): MMType
338 do
339 return _module.class_by_name(once ("Array".to_symbol)).get_instantiate_type([stype])
340 end
341
342 # The primitive type Discrete
343 fun type_discrete: MMType
344 do
345 return _module.class_by_name(once ("Discrete".to_symbol)).get_type
346 end
347
348 # The primitive type Range[?]
349 fun type_range(stype: MMType): MMType
350 do
351 return _module.class_by_name(once ("Range".to_symbol)).get_instantiate_type([stype])
352 end
353
354 # The primitive type of null
355 fun type_none: MMType
356 do
357 return _module.type_none
358 end
359
360 fun get_method(recv: MMType, name: Symbol): MMMethod
361 do
362 if not recv.local_class.has_global_property_by_name(name) then
363 error(current_node, "Fatal Error: {recv} must have a property named {name}.")
364 exit(1)
365 end
366 return recv.local_class.select_method(name)
367 end
368
369 # The current module
370 readable var _module: MMSrcModule
371
372 # The current class
373 fun local_class: MMSrcLocalClass do return _local_class.as(not null)
374 writable var _local_class: nullable MMSrcLocalClass
375
376 # The current property
377 fun local_property: MMLocalProperty do return _local_property.as(not null)
378 writable var _local_property: nullable MMLocalProperty
379
380 # The current tool configuration/status
381 readable var _tc: ToolContext
382
383 # Display an error for a given syntax node
384 fun error(n: nullable ANode, s: String)
385 do
386 _tc.error(if n == null then null else n.location, s)
387 end
388
389 # Add an error, show errors and quit
390 fun fatal_error(n: nullable ANode, s: String)
391 do
392 _tc.fatal_error(if n == null then null else n.location, s)
393 end
394
395 # Display a warning for a given syntax node
396 fun warning(n: nullable ANode, s: String)
397 do
398 _tc.warning(if n == null then null else n.location, s)
399 end
400
401 # Check conformity and display error
402 fun check_conform(n: ANode, subtype: nullable MMType, stype: nullable MMType): Bool
403 do
404 if stype == null or subtype == null then
405 return false
406 end
407 if subtype < stype then
408 return true
409 end
410 error(n, "Type error: expected {stype}, got {subtype}")
411 return false
412 end
413
414 # Check that an expression has a static type and that
415 # Display an error and return false if n is a statement
416 # Require that the static type of n is known
417 fun check_expr(n: AExpr): Bool
418 do
419 if not n.is_typed then
420 if tc.error_count == 0 then
421 var loc = n.location
422 if loc == null then
423 print("Unknown node not typed but not error")
424 else
425 print("{loc} not typed but not error")
426 end
427 abort
428 end
429 # An error occured in a sub node,
430 # sillently cascade fail
431 return false
432 else if n.is_statement then
433 error(n, "Type error: expected expression.")
434 return false
435 end
436 return true
437 end
438
439 # Combine check_conform and check_expr
440 fun check_conform_expr(n: AExpr, stype: nullable MMType): Bool
441 do
442 if stype == null then return false
443 if check_expr(n) then return check_conform(n, n.stype, stype) else return false
444 end
445
446 # Check conformance between multiple expressions and a static type
447 # Conformance is granted if among them there is a most general type
448 # Return the most general type if a conformance is found
449 # Display an error and return null if no conformance is found
450 # The only allowed combinaison is with the nullable marker
451 # @param stype is a possible additional type (without node)
452 # Examples:
453 # Int, Int, Object => return Object
454 # Int, Float => display error, return null
455 # nullable Int, Object => return nullable Object
456 fun check_conform_multiexpr(stype: nullable MMType, nodes: Collection[AExpr]): nullable MMType
457 do
458 var node: nullable AExpr = null # candidate node
459 for n in nodes do
460 if not check_expr(n) then return null
461 var ntype = n.stype
462 if stype != null and stype.is_nullable != ntype.is_nullable then
463 # nullable combinaison: if one of them is nulable, considers that both are
464 stype = stype.as_nullable
465 ntype = ntype.as_nullable
466 end
467 if stype == null or stype < ntype then
468 stype = ntype
469 node = n
470 end
471 end
472 for n in nodes do
473 if not n.stype < stype.as(not null) then
474 if node == null then
475 error(n, "Type error: no most general type. Got {n.stype} and {stype}.")
476 else
477 var loc = node.location
478 if loc == null then
479 error(n, "Type error: no most general type. Got {n.stype} and {stype} at ????.")
480 else
481 error(n, "Type error: no most general type. Got {n.stype} and {stype} at {loc.relative_to(n.location)}.")
482 end
483 end
484 return null
485 end
486 end
487 return stype
488 end
489
490 protected init(tc: ToolContext, module: MMSrcModule)
491 do
492 _tc = tc
493 _module = module
494 end
495 end
496
497 ###############################################################################
498
499 redef class ANode
500 protected fun accept_abs_syntax_visitor(v: AbsSyntaxVisitor) do visit_all(v)
501 end
502
503 redef class Token
504 var _symbol_cache: nullable Symbol
505
506 # Symbol associated with the text
507 # Lazily computed
508 fun to_symbol: Symbol
509 do
510 var s = _symbol_cache
511 if s == null then
512 s = text.to_symbol
513 _symbol_cache = s
514 end
515 return s
516 end
517 end
518
519 redef class AClassdef
520 # Associated class (MM entity)
521 fun local_class: MMSrcLocalClass is abstract
522
523 # Next AClassdef of the same class (if any)
524 readable writable var _next_node: nullable AClassdef = null
525 end
526
527 redef class APropdef
528 # Associated 'self' variable
529 fun self_var: ParamVariable is abstract
530 end
531
532 redef class AAttrPropdef
533 # Associated attribute (MM entity)
534 fun prop: MMSrcAttribute is abstract
535
536 # Associated read accessor (MM entity)
537 fun readmethod: nullable MMSrcMethod is abstract
538
539 # Associated write accessor (MM entity)
540 fun writemethod: nullable MMSrcMethod is abstract
541 end
542
543 redef class AConcreteInitPropdef
544 readable var _super_init_calls: Array[MMMethod] = new Array[MMMethod]
545 readable var _explicit_super_init_calls: Array[MMMethod] = new Array[MMMethod]
546 end
547
548 redef class AMethPropdef
549 # Associated method (MM entity)
550 fun method: MMMethSrcMethod is abstract
551 end
552
553 redef class ATypePropdef
554 # Associated formal type (MM entity)
555 fun prop: MMSrcTypeProperty is abstract
556 end
557
558 redef class AParam
559 # Position in the signature
560 fun position: Int is abstract
561
562 # Associated local variable
563 fun variable: ParamVariable is abstract
564 end
565
566 redef class AClosureDecl
567 # Position in the signature
568 fun position: Int is abstract
569
570 # Associated closure variable
571 fun variable: ClosureVariable is abstract
572 end
573
574 redef class AType
575 # Is the node correcly typed
576 # Return false if typed was not yet computed or
577 # if an error occured during the typing computation
578 fun is_typed: Bool is abstract
579
580 # Return corresponding static type. (require is_typed)
581 fun stype: MMType is abstract
582
583 var _stype_cache: nullable MMType = null
584 var _stype_cached: Bool = false
585
586 # Retrieve the local class corresponding to the type.
587 # Display an error and return null if there is no class
588 # Display an error and return null if the type is not class based (formal one)
589 fun get_local_class(v: AbsSyntaxVisitor): nullable MMLocalClass
590 do
591 var name = n_id.to_symbol
592 var mod = v.module
593 var cla = v.local_class
594
595 if cla.formal_dict.has_key(name) or cla.has_global_property_by_name(name) then
596 v.error(n_id, "Type error: {name} is a formal type")
597 _stype_cached = true
598 return null
599 end
600
601 if not mod.has_global_class_named(name) then
602 v.error(n_id, "Type error: class {name} not found in module {mod}.")
603 _stype_cached = true
604 return null
605 end
606
607 var local_class = mod.class_by_name(name)
608 local_class.global.check_visibility(v, self, mod)
609 return local_class
610 end
611
612 # Retrieve corresponding static type.
613 # Display an error and return null if there is a problem
614 # But do not performs any subtype check.
615 # get_unchecked_stype should be called to check that the static type is fully valid
616 fun get_unchecked_stype(v: AbsSyntaxVisitor): nullable MMType
617 do
618 if _stype_cached then return _stype_cache
619 _stype_cached = true
620
621 var name = n_id.to_symbol
622 var mod = v.module
623 var cla = v.local_class
624 var t: nullable MMType
625
626 if cla.formal_dict.has_key(name) then
627 if n_types.length > 0 then
628 v.error(self, "Type error: formal type {name} cannot have formal parameters.")
629 return null
630 end
631 t = cla.formal_dict[name]
632 if n_kwnullable != null then t = t.as_nullable
633 _stype_cache = t
634 return t
635 end
636
637 if cla.has_global_property_by_name(name) then
638 if n_types.length > 0 then
639 v.error(self, "Type error: formal type {name} cannot have formal parameters.")
640 return null
641 end
642 t = cla.get_type.local_class.select_virtual_type(name).stype_for(cla.get_type)
643 if t == null then
644 v.error(self, "Type error: circular definition in formal type {name}.")
645 return null
646 end
647 if n_kwnullable != null then t = t.as_nullable
648 _stype_cache = t
649 return t
650 end
651
652 var local_class = get_local_class(v)
653 if local_class == null then return null
654
655 var arity = n_types.length
656 if local_class.arity != arity then
657 if arity == 0 then
658 v.error(self, "Type error: '{local_class}' is a generic class.")
659 else if local_class.arity == 0 then
660 v.error(self, "Type error: '{local_class}' is not a generic class.")
661 else
662 v.error(self, "Type error: '{local_class}' has {local_class.arity} parameters ({arity} are provided).")
663 end
664 return null
665 end
666
667 if arity > 0 then
668 var tab = new Array[MMType]
669 for p in n_types do
670 var t2 = p.get_unchecked_stype(v)
671 if t2 == null then return null
672 tab.add(t2)
673 end
674 t = local_class.get_instantiate_type(tab)
675 else
676 t = local_class.get_type
677 end
678 if n_kwnullable != null then t = t.as_nullable
679 _stype_cache = t
680 return t
681 end
682
683 # Retrieve corresponding static type.
684 # Display an error and return null if there is a problem
685 fun get_stype(v: AbsSyntaxVisitor): nullable MMType
686 do
687 var t = get_unchecked_stype(v)
688 if t == null then return null
689 if not t.is_valid then return null
690 check_conform(v)
691 return t
692 end
693
694 # Check that a static definition type is conform with regard to formal types
695 # Useful with get_unchecked_stype
696 # Remember that conformance check need that ancestors are totaly computed
697 fun check_conform(v: AbsSyntaxVisitor)
698 do
699 var st = get_unchecked_stype(v)
700 if st == null then return
701 var local_class = st.local_class
702 var arity = n_types.length
703 if arity > 0 then
704 for i in [0..arity[ do
705 var p = n_types[i]
706 var pt = p.get_stype(v)
707 var b = local_class.get_formal(i)
708 if not b.is_valid then return
709 var bt = b.bound
710 bt = bt.adapt_to(st) # We need to abapt because of F-genericity
711 v.check_conform(p, pt, bt)
712 end
713 end
714 end
715 end
716
717 redef class AExpr
718 # Is the expression node correcly typed
719 # Return false if typed was not yet computed or
720 # if an error occured during the typing computation
721 fun is_typed: Bool is abstract
722
723 # Is the expression node a statement? (ie has no return value)
724 # require: is_typed
725 fun is_statement: Bool is abstract
726
727 # The static type of the expression
728 # require: is_typed and not is_statement
729 fun stype: MMType is abstract
730 end
731
732 class AAbsAbsSendExpr
733 special AExpr
734 # The signature of the called property (require is_typed)
735 fun prop_signature: MMSignature is abstract
736
737 # The real arguments used (after star transformation) (require is_typed)
738 fun arguments: Array[AExpr] is abstract
739 end
740
741 class AAbsSendExpr
742 special AAbsAbsSendExpr
743 # The invoked method (require is_typed)
744 fun prop: MMMethod is abstract
745
746 # The return type (if any) (once computed)
747 fun return_type: nullable MMType is abstract
748 end
749
750 class ASuperInitCall
751 special AAbsSendExpr
752 end
753
754 redef class ASuperExpr
755 special ASuperInitCall
756 fun init_in_superclass: nullable MMMethod is abstract
757 end
758
759 redef class ANewExpr
760 special AAbsSendExpr
761 end
762
763 redef class ASendExpr
764 special ASuperInitCall
765 # Closure definitions
766 fun closure_defs: nullable Array[AClosureDef] is abstract
767 end
768
769 redef class AReassignFormExpr
770 # Method used through the reassigment operator (require is_typed)
771 fun assign_method: MMMethod is abstract
772 end
773
774 class ASendReassignExpr
775 special ASendExpr
776 special AReassignFormExpr
777 # The invoked method used to read (require is_typed)
778 # prop is the method used to write
779 fun read_prop: MMMethod is abstract
780 end
781
782 redef class ACallReassignExpr
783 special ASendReassignExpr
784 end
785
786 redef class ABraReassignExpr
787 special ASendReassignExpr
788 end
789
790 redef class AAttrFormExpr
791 # Attribute accessed (require is_typed)
792 fun prop: MMAttribute is abstract
793
794 # Attribute type of the acceded attribute (require is_typed)
795 fun attr_type: MMType is abstract
796 end
797
798 redef class ASuperstringExpr
799 fun atype: MMType is abstract
800 end
801
802 redef class AVardeclExpr
803 # Assiociated local variable
804 fun variable: VarVariable is abstract
805 #readable writable var _variable: nullable VarVariable
806 end
807
808 redef class AForExpr
809 # Associated automatic local variable
810 fun variable: AutoVariable is abstract
811 end
812
813 redef class ASelfExpr
814 # Associated local variable
815 fun variable: ParamVariable is abstract
816 end
817
818 redef class AVarFormExpr
819 # Associated local variable
820 fun variable: Variable is abstract
821 end
822
823 redef class AClosureCallExpr
824 special AAbsAbsSendExpr
825 # Associated closure variable
826 fun variable: ClosureVariable is abstract
827 end
828
829 redef class AClosureDef
830 # Associated closure
831 fun closure: MMClosure is abstract
832
833 # Automatic variables
834 readable writable var _variables: nullable Array[AutoVariable]
835 end