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