mm: adds basic explicit imports to metamodel and typing
[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 super 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.mmmodule
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 super MMConcreteClass
87 # The first related AST node (if any)
88 fun node: nullable AClassdef do return mmmodule.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.mmmodule
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 super MMAttribute
138 redef fun node: nullable AAttrPropdef do return mmmodule.nodes(self).as(nullable AAttrPropdef)
139 init(name: Symbol, cla: MMLocalClass, n: AAttrPropdef)
140 do
141 super(name, cla)
142 cla.mmmodule.nodes(self) = n
143 end
144 end
145
146 # Concrete NIT source method
147 class MMSrcMethod
148 super MMMethod
149 redef fun is_intern do return false
150 redef fun is_abstract do return false
151 redef fun extern_name do return null
152 end
153
154 # Concrete NIT source method for an automatic accesor
155 class MMAttrImplementationMethod
156 super MMSrcMethod
157 redef fun node: nullable AAttrPropdef do return mmmodule.nodes(self).as(nullable AAttrPropdef)
158 init(name: Symbol, cla: MMLocalClass, n: AAttrPropdef)
159 do
160 super(name, cla)
161 cla.mmmodule.nodes(self) = n
162 end
163 end
164
165 # Concrete NIT source method for an automatic read accesor
166 class MMReadImplementationMethod
167 super MMAttrImplementationMethod
168 init(name: Symbol, cla: MMLocalClass, n: AAttrPropdef)
169 do
170 super(name, cla, n)
171 end
172 end
173
174 # Concrete NIT source method for an automatic write accesor
175 class MMWriteImplementationMethod
176 super MMAttrImplementationMethod
177 init(name: Symbol, cla: MMLocalClass, n: AAttrPropdef)
178 do
179 super(name, cla, n)
180 end
181 end
182
183 # Concrete NIT source method for an explicit method
184 class MMMethSrcMethod
185 super MMSrcMethod
186 redef readable var _is_init: Bool
187 redef readable var _is_intern: Bool
188 redef readable var _is_abstract: Bool
189 redef readable writable var _extern_name: nullable String # Will be computed during MMBuilder
190 redef readable var _explicit_imports : Set[MMExplicitImport] = new HashSet[MMExplicitImport]
191 redef fun node: nullable AMethPropdef do return mmmodule.nodes(self).as(nullable AMethPropdef)
192 init(name: Symbol, cla: MMLocalClass, n: nullable AMethPropdef)
193 do
194 super(name, cla)
195 cla.mmmodule.nodes(self) = n
196 _is_init = node isa AConcreteInitPropdef
197 _is_intern = node isa AInternMethPropdef
198 _is_abstract = node isa ADeferredMethPropdef
199 _extern_name = null
200 end
201 end
202
203 # Concrete NIT source virtual type
204 class MMSrcTypeProperty
205 super MMLocalProperty
206 super MMTypeProperty
207 init(name: Symbol, cla: MMLocalClass, n: ATypePropdef)
208 do
209 super(name, cla)
210 end
211 end
212
213 # Concrete NIT implicit constructor
214 class MMImplicitInit
215 super MMMethSrcMethod
216 fun super_init: nullable MMLocalProperty is abstract
217 redef fun is_init do return true
218 readable var _unassigned_attributes: Array[MMSrcAttribute]
219 readable var _super_inits: Array[MMLocalProperty]
220 init(cla: MMLocalClass, unassigned_attributes: Array[MMSrcAttribute], super_inits: Array[MMLocalProperty])
221 do
222 super(once "init".to_symbol, cla, null)
223 _unassigned_attributes = unassigned_attributes
224 _super_inits = super_inits
225 end
226 end
227
228 # Local variables
229 abstract class Variable
230 # Name of the variable
231 readable var _name: Symbol
232
233 # Declaration AST node
234 readable var _decl: nullable ANode
235
236 # Static type
237 readable writable var _stype: nullable MMType
238
239 redef fun to_s do return _name.to_s
240
241 fun kind: String is abstract
242
243 init(n: Symbol, d: nullable ANode)
244 do
245 _name = n
246 _decl = d
247 end
248 end
249
250 # Variable declared with 'var'
251 class VarVariable
252 super Variable
253 redef fun kind do return once "variable"
254 init(n: Symbol, d: ANode) do super
255 end
256
257 # Parameter of method (declared in signature)
258 class ParamVariable
259 super Variable
260 redef fun kind do return once "parameter"
261 init(n: Symbol, d: nullable ANode) do super
262 end
263
264 # Automatic variable (like in the 'for' statement)
265 class AutoVariable
266 super Variable
267 redef fun kind do return once "automatic variable"
268 init(n: Symbol, d: ANode) do super
269 end
270
271 # False variable corresponding to closures declared in signatures
272 # Lives in the same namespace than variables
273 class ClosureVariable
274 super Variable
275 redef fun kind do return once "closure"
276
277 # The signature of the closure
278 readable var _closure: MMClosure
279
280 init(n: Symbol, d: ANode, c: MMClosure)
281 do
282 super(n, d)
283 _closure = c
284 end
285 end
286
287 ###############################################################################
288
289 # Visitor used during the syntax analysis
290 class AbsSyntaxVisitor
291 super Visitor
292 fun get_type_by_name(clsname: Symbol): MMType
293 do
294 if not _mmmodule.has_global_class_named(clsname) then _tc.fatal_error(_mmmodule.location, "Missing necessary class: \"{clsname}\"")
295 var cls = _mmmodule.class_by_name(clsname)
296 return cls.get_type
297 end
298
299 fun get_instantiated_type_by_name(clsname: Symbol, vtype: Array[MMType]): MMType
300 do
301 if not _mmmodule.has_global_class_named(clsname) then _tc.fatal_error(_mmmodule.location, "Missing necessary class: \"{clsname}\"")
302 var cls = _mmmodule.class_by_name(clsname)
303 return cls.get_instantiate_type(vtype)
304 end
305
306 # The root type Object
307 fun type_object: MMType
308 do
309 return get_type_by_name(once ("Object".to_symbol))
310 end
311
312 # The primitive type Bool
313 fun type_bool: MMType
314 do
315 return get_type_by_name(once ("Bool".to_symbol))
316 end
317
318 # The primitive type Int
319 fun type_int: MMType
320 do
321 return get_type_by_name(once ("Int".to_symbol))
322 end
323
324 # The primitive type Float
325 fun type_float: MMType
326 do
327 return get_type_by_name(once ("Float".to_symbol))
328 end
329
330 # The primitive type Char
331 fun type_char: MMType
332 do
333 return get_type_by_name(once ("Char".to_symbol))
334 end
335
336 # The primitive type String
337 fun type_string: MMType
338 do
339 return get_type_by_name(once ("String".to_symbol))
340 end
341
342 # The primitive type NativeString
343 fun type_nativestring: MMType
344 do
345 return get_type_by_name(once ("NativeString".to_symbol))
346 end
347
348 # The primitive type Array[?]
349 fun type_array(stype: MMType): MMType
350 do
351 return get_instantiated_type_by_name(once ("Array".to_symbol), [stype])
352 end
353
354 # The primitive type Discrete
355 fun type_discrete: MMType
356 do
357 return get_type_by_name(once ("Discrete".to_symbol))
358 end
359
360 # The primitive type Range[?]
361 fun type_range(stype: MMType): MMType
362 do
363 return get_instantiated_type_by_name(once ("Range".to_symbol), [stype])
364 end
365
366 # The primitive type of null
367 fun type_none: MMType
368 do
369 return _mmmodule.type_none
370 end
371
372 fun get_method(recv: MMType, name: Symbol): MMMethod
373 do
374 if not recv.local_class.has_global_property_by_name(name) then
375 fatal_error(current_node, "Fatal Error: {recv} must have a property named {name}.")
376 end
377 return recv.local_class.select_method(name)
378 end
379
380 # The current module
381 readable var _mmmodule: MMSrcModule
382
383 # The current class
384 fun local_class: MMSrcLocalClass do return _local_class.as(not null)
385 writable var _local_class: nullable MMSrcLocalClass
386
387 # The current property
388 fun local_property: MMLocalProperty do return _local_property.as(not null)
389 writable var _local_property: nullable MMLocalProperty
390
391 # The current tool configuration/status
392 readable var _tc: ToolContext
393
394 # Display an error for a given syntax node
395 fun error(n: nullable ANode, s: String)
396 do
397 _tc.error(if n == null then null else n.hot_location, s)
398 end
399
400 # Add an error, show errors and quit
401 fun fatal_error(n: nullable ANode, s: String)
402 do
403 _tc.fatal_error(if n == null then null else n.hot_location, s)
404 end
405
406 # Display a warning for a given syntax node
407 fun warning(n: nullable ANode, s: String)
408 do
409 _tc.warning(if n == null then null else n.hot_location, s)
410 end
411
412 # Check conformity and display error
413 fun check_conform(n: ANode, subtype: nullable MMType, stype: nullable MMType): Bool
414 do
415 if stype == null or subtype == null then
416 return false
417 end
418 if subtype < stype then
419 return true
420 end
421 error(n, "Type error: expected {stype}, got {subtype}")
422 return false
423 end
424
425 # Check that an expression has a static type and that
426 # Display an error and return false if n is a statement
427 # Require that the static type of n is known
428 fun check_expr(n: AExpr): Bool
429 do
430 if not n.is_typed then
431 if tc.error_count == 0 then
432 print("{n.location} not typed but not error")
433 abort
434 end
435 # An error occured in a sub node,
436 # sillently cascade fail
437 return false
438 else if n.is_statement then
439 error(n, "Type error: expected expression.")
440 return false
441 end
442 return true
443 end
444
445 # Combine check_conform and check_expr
446 fun check_conform_expr(n: AExpr, stype: nullable MMType): Bool
447 do
448 if stype == null then return false
449 if check_expr(n) then return check_conform(n, n.stype, stype) else return false
450 end
451
452 # Check conformance between multiple expressions and a static type
453 # Conformance is granted if among them there is a most general type
454 # Return the most general type if a conformance is found
455 # Display an error and return null if no conformance is found
456 # The only allowed combinaison is with the nullable marker
457 # @param stype is a possible additional type (without node)
458 # Examples:
459 # Int, Int, Object => return Object
460 # Int, Float => display error, return null
461 # nullable Int, Object => return nullable Object
462 fun check_conform_multiexpr(stype: nullable MMType, nodes: Collection[AExpr]): nullable MMType
463 do
464 var node: nullable AExpr = null # candidate node
465 for n in nodes do
466 if not check_expr(n) then return null
467 var ntype = n.stype
468 if stype != null and stype.is_nullable != ntype.is_nullable then
469 # nullable combinaison: if one of them is nulable, considers that both are
470 stype = stype.as_nullable
471 ntype = ntype.as_nullable
472 end
473 if stype == null or stype < ntype then
474 stype = ntype
475 node = n
476 end
477 end
478 assert stype != null
479 for n in nodes do
480 if not n.stype < stype then
481 if node == null then
482 error(n, "Type error: no most general type. Got {n.stype} and {stype}.")
483 else
484 error(n, "Type error: no most general type. Got {n.stype} and {stype} at {node.location.relative_to(n.location)}.")
485 end
486 return null
487 end
488 end
489 return stype
490 end
491
492 protected init(tc: ToolContext, mmmodule: MMSrcModule)
493 do
494 _tc = tc
495 _mmmodule = mmmodule
496 end
497 end
498
499 ###############################################################################
500
501 redef class ANode
502 protected fun accept_abs_syntax_visitor(v: AbsSyntaxVisitor) do visit_all(v)
503 end
504
505 redef class Token
506 var _symbol_cache: nullable Symbol
507
508 # Symbol associated with the text
509 # Lazily computed
510 fun to_symbol: Symbol
511 do
512 var s = _symbol_cache
513 if s == null then
514 s = text.to_symbol
515 _symbol_cache = s
516 end
517 return s
518 end
519 end
520
521 redef class AClassdef
522 # Associated class (MM entity)
523 fun local_class: MMSrcLocalClass is abstract
524
525 # Next AClassdef of the same class (if any)
526 readable writable var _next_node: nullable AClassdef = null
527 end
528
529 redef class APropdef
530 # Associated 'self' variable
531 fun self_var: ParamVariable is abstract
532 end
533
534 redef class AAttrPropdef
535 # Associated attribute (MM entity)
536 fun prop: MMSrcAttribute is abstract
537
538 # Associated read accessor (MM entity)
539 fun readmethod: nullable MMSrcMethod is abstract
540
541 # Associated write accessor (MM entity)
542 fun writemethod: nullable MMSrcMethod is abstract
543 end
544
545 redef class AConcreteInitPropdef
546 readable var _super_init_calls: Array[MMMethod] = new Array[MMMethod]
547 readable var _explicit_super_init_calls: Array[MMMethod] = new Array[MMMethod]
548 end
549
550 redef class AMethPropdef
551 # Associated method (MM entity)
552 fun method: MMMethSrcMethod is abstract
553 end
554
555 redef class ATypePropdef
556 # Associated formal type (MM entity)
557 fun prop: MMSrcTypeProperty is abstract
558 end
559
560 redef class AParam
561 # Position in the signature
562 fun position: Int is abstract
563
564 # Associated local variable
565 fun variable: ParamVariable is abstract
566 end
567
568 redef class AClosureDecl
569 # Position in the signature
570 fun position: Int is abstract
571
572 # Associated closure variable
573 fun variable: ClosureVariable is abstract
574 end
575
576 redef class AType
577 # Is the node correcly typed
578 # Return false if typed was not yet computed or
579 # if an error occured during the typing computation
580 fun is_typed: Bool is abstract
581
582 # Return corresponding static type. (require is_typed)
583 fun stype: MMType is abstract
584
585 var _stype_cache: nullable MMType = null
586 var _stype_cached: Bool = false
587
588 # Retrieve the local class corresponding to the type.
589 # Display an error and return null if there is no class
590 # Display an error and return null if the type is not class based (formal one)
591 fun get_local_class(v: AbsSyntaxVisitor): nullable MMLocalClass
592 do
593 var name = n_id.to_symbol
594 var mod = v.mmmodule
595 var cla = v.local_class
596
597 if cla.formal_dict.has_key(name) or cla.has_global_property_by_name(name) then
598 v.error(n_id, "Type error: {name} is a formal type")
599 _stype_cached = true
600 return null
601 end
602
603 if not mod.has_global_class_named(name) then
604 v.error(n_id, "Type error: class {name} not found in module {mod}.")
605 _stype_cached = true
606 return null
607 end
608
609 var local_class = mod.class_by_name(name)
610 local_class.global.check_visibility(v, self, mod)
611 return local_class
612 end
613
614 # Retrieve corresponding static type.
615 # Display an error and return null if there is a problem
616 # But do not performs any subtype check.
617 # get_unchecked_stype should be called to check that the static type is fully valid
618 fun get_unchecked_stype(v: AbsSyntaxVisitor): nullable MMType
619 do
620 if _stype_cached then return _stype_cache
621 _stype_cached = true
622
623 var name = n_id.to_symbol
624 var mod = v.mmmodule
625 var cla = v.local_class
626 var t: nullable MMType
627
628 if cla.formal_dict.has_key(name) then
629 if n_types.length > 0 then
630 v.error(self, "Type error: formal type {name} cannot have formal parameters.")
631 return null
632 end
633 t = cla.formal_dict[name]
634 if n_kwnullable != null then t = t.as_nullable
635 _stype_cache = t
636 return t
637 end
638
639 if cla.has_global_property_by_name(name) then
640 if n_types.length > 0 then
641 v.error(self, "Type error: formal type {name} cannot have formal parameters.")
642 return null
643 end
644 t = cla.get_type.local_class.select_virtual_type(name).stype_for(cla.get_type)
645 if t == null then
646 v.error(self, "Type error: circular definition in formal type {name}.")
647 return null
648 end
649 if n_kwnullable != null then t = t.as_nullable
650 _stype_cache = t
651 return t
652 end
653
654 var local_class = get_local_class(v)
655 if local_class == null then return null
656
657 var arity = n_types.length
658 if local_class.arity != arity then
659 if arity == 0 then
660 v.error(self, "Type error: '{local_class}' is a generic class.")
661 else if local_class.arity == 0 then
662 v.error(self, "Type error: '{local_class}' is not a generic class.")
663 else
664 v.error(self, "Type error: '{local_class}' has {local_class.arity} parameters ({arity} are provided).")
665 end
666 return null
667 end
668
669 if arity > 0 then
670 var tab = new Array[MMType]
671 for p in n_types do
672 var t2 = p.get_unchecked_stype(v)
673 if t2 == null then return null
674 tab.add(t2)
675 end
676 t = local_class.get_instantiate_type(tab)
677 else
678 t = local_class.get_type
679 end
680 if n_kwnullable != null then t = t.as_nullable
681 _stype_cache = t
682 return t
683 end
684
685 # Retrieve corresponding static type.
686 # Display an error and return null if there is a problem
687 fun get_stype(v: AbsSyntaxVisitor): nullable MMType
688 do
689 var t = get_unchecked_stype(v)
690 if t == null then return null
691 if not t.is_valid then return null
692 check_conform(v)
693 return t
694 end
695
696 # Check that a static definition type is conform with regard to formal types
697 # Useful with get_unchecked_stype
698 # Remember that conformance check need that ancestors are totaly computed
699 fun check_conform(v: AbsSyntaxVisitor)
700 do
701 var st = get_unchecked_stype(v)
702 if st == null then return
703 var local_class = st.local_class
704 var arity = n_types.length
705 if arity > 0 then
706 for i in [0..arity[ do
707 var p = n_types[i]
708 var pt = p.get_stype(v)
709 var b = local_class.get_formal(i)
710 if not b.is_valid then return
711 var bt = b.bound
712 bt = bt.adapt_to(st) # We need to abapt because of F-genericity
713 v.check_conform(p, pt, bt)
714 end
715 end
716 end
717 end
718
719 redef class AExpr
720 # Is the expression node correcly typed
721 # Return false if typed was not yet computed or
722 # if an error occured during the typing computation
723 fun is_typed: Bool is abstract
724
725 # Is the expression node a statement? (ie has no return value)
726 # require: is_typed
727 fun is_statement: Bool is abstract
728
729 # The static type of the expression
730 # require: is_typed and not is_statement
731 fun stype: MMType is abstract
732 end
733
734 class AAbsAbsSendExpr
735 super AExpr
736 # The signature of the called property (require is_typed)
737 fun prop_signature: MMSignature is abstract
738
739 # The raw arguments used (without vararg transformation) (require is_typed)
740 fun raw_arguments: Array[AExpr] is abstract
741 end
742
743 class AAbsSendExpr
744 super AAbsAbsSendExpr
745 # The invoked method (require is_typed)
746 fun prop: MMMethod is abstract
747
748 # The return type (if any) (once computed)
749 fun return_type: nullable MMType is abstract
750 end
751
752 class ASuperInitCall
753 super AAbsSendExpr
754 end
755
756 redef class ASuperExpr
757 super ASuperInitCall
758 fun init_in_superclass: nullable MMMethod is abstract
759 end
760
761 redef class ANewExpr
762 super AAbsSendExpr
763 end
764
765 redef class ASendExpr
766 super ASuperInitCall
767 # Closure definitions
768 fun closure_defs: nullable Array[AClosureDef] is abstract
769 end
770
771 redef class AReassignFormExpr
772 # Method used through the reassigment operator (require is_typed)
773 fun assign_method: MMMethod is abstract
774 end
775
776 class ASendReassignExpr
777 super ASendExpr
778 super AReassignFormExpr
779 # The invoked method used to read (require is_typed)
780 # prop is the method used to write
781 fun read_prop: MMMethod is abstract
782 end
783
784 redef class ACallReassignExpr
785 super ASendReassignExpr
786 end
787
788 redef class ABraReassignExpr
789 super ASendReassignExpr
790 end
791
792 redef class AAttrFormExpr
793 # Attribute accessed (require is_typed)
794 fun prop: MMAttribute is abstract
795
796 # Attribute type of the acceded attribute (require is_typed)
797 fun attr_type: MMType is abstract
798 end
799
800 redef class ASuperstringExpr
801 fun atype: MMType is abstract
802 end
803
804 redef class AVardeclExpr
805 # Assiociated local variable
806 fun variable: VarVariable is abstract
807 #readable writable var _variable: nullable VarVariable
808 end
809
810 redef class AForExpr
811 # Associated automatic local variable
812 fun variables: Array[AutoVariable] is abstract
813 end
814
815 redef class ASelfExpr
816 # Associated local variable
817 fun variable: ParamVariable is abstract
818 end
819
820 redef class AVarFormExpr
821 # Associated local variable
822 fun variable: Variable is abstract
823 end
824
825 redef class AClosureCallExpr
826 super AAbsAbsSendExpr
827 # Associated closure variable
828 fun variable: ClosureVariable is abstract
829 end
830
831 redef class AClosureDef
832 # Associated closure
833 fun closure: MMClosure is abstract
834
835 # Automatic variables
836 readable writable var _variables: nullable Array[AutoVariable]
837 end
838
839 redef class AMethid
840 # Name of method
841 fun name: nullable Symbol is abstract
842 end