1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2008 Jean Privat <jean@pryen.org>
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
9 # http://www.apache.org/licenses/LICENSE-2.0
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.
17 # Analysis property bodies, statements and expressions
22 redef class MMSrcModule
23 # Walk trough the module and type statments and expressions
24 # Require than supermodules are processed
25 meth do_typing
(tc
: ToolContext)
27 var tv
= new TypingVisitor(tc
, self)
33 # * Associate local variables to nodes
34 # * Distinguish method call and local variable access
35 # * Resolve call and attribute access
36 # * Check type conformance
37 private class TypingVisitor
38 special AbsSyntaxVisitor
41 if n
!= null then n
.accept_typing
(self)
44 # Current knowledge about variables names and types
45 readable writable attr _variable_ctx
: VariableContext
47 # The current reciever
48 readable writable attr _self_var
: ParamVariable
50 # Block of the current method
51 readable writable attr _top_block
: PExpr
53 # List of explicit invocation of constructors of super-classes
54 readable writable attr _explicit_super_init_calls
: Array[MMMethod]
56 # Is a other constructor of the same class invoked
57 readable writable attr _explicit_other_init_call
: Bool
59 init(tc
, module) do super
61 private meth get_default_constructor_for
(n
: PNode, c
: MMLocalClass, prop
: MMSrcMethod): MMMethod
64 #var prop = v.local_property
65 #assert prop isa MMMethod
66 var candidates
= new Array[MMMethod]
67 var false_candidates
= new Array[MMMethod]
68 var parity
= prop
.signature
.arity
69 for g
in c
.global_properties
do
70 if not g
.is_init
then continue
71 if g
.intro
.local_class
!= c
then continue
73 assert gp
isa MMSrcMethod
74 var garity
= gp
.signature
.arity
75 if prop
!= null and gp
.name
== prop
.name
then
76 if garity
== 0 or (parity
== garity
and prop
.signature
< gp
.signature
) then
79 false_candidates
.add
(gp
)
81 else if garity
== 0 and gp
.name
== once
("init".to_symbol
) then
83 false_candidates
.add
(gp
)
85 false_candidates
.add
(gp
)
88 if candidates
.length
== 1 then
89 return candidates
.first
90 else if candidates
.length
> 0 then
91 v
.error
(n
, "Error: Conflicting default constructor to call for {c}: {candidates.join(", ")}.")
93 else if false_candidates
.length
> 0 then
94 v
.error
(n
, "Error: there is no available compatible constrctor in {c}. discarded candidates are {false_candidates.join(", ")}.")
97 v
.warning
(n
, "Error: there is no available compatible constrctor in {c}.")
103 # Associate symbols to variable and variables to type
105 private class VariableContext
106 # Look for the variable from its name
107 # Return null if nothing found
108 meth
[](s
: Symbol): Variable
110 if _dico
.has_key
(s
) then
117 # Register a new variable with its name
118 meth add
(v
: Variable)
124 # The effective static type of a given variable
125 # May be different from the declaration static type
126 meth stype
(v
: Variable): MMType
131 # Variables by name (in the current context only)
132 attr _dico
: Map[Symbol, Variable]
134 # Build a new VariableContext
135 meth sub
: SubVariableContext
137 return new SubVariableContext.with_prev
(self, null, null)
140 # Build a nested VariableContext with new variable information
141 meth sub_with
(v
: Variable, t
: MMType): SubVariableContext
143 return new SubVariableContext.with_prev
(self, v
, t
)
148 _dico
= new HashMap[Symbol, Variable]
152 private class SubVariableContext
153 special VariableContext
154 readable attr _prev
: VariableContext
155 attr _variable
: Variable
156 attr _var_type
: MMType
160 if _dico
.has_key
(s
) then
169 if _variable
== v
then
175 init with_prev
(p
: VariableContext, v
: Variable, t
: MMType)
185 ###############################################################################
188 private meth accept_typing
(v
: TypingVisitor)
190 accept_abs_syntax_visitor
(v
)
193 private meth after_typing
(v
: TypingVisitor) do end
196 redef class PClassdef
197 redef meth accept_typing
(v
)
199 v
.self_var
= new ParamVariable("self".to_symbol
, self)
200 v
.self_var
.stype
= local_class
.get_type
205 redef class AAttrPropdef
206 redef meth accept_typing
(v
)
209 if n_expr
!= null then
210 v
.check_conform_expr
(n_expr
, prop
.signature
.return_type
)
215 redef class AMethPropdef
216 redef readable attr _self_var
: ParamVariable
217 redef meth accept_typing
(v
)
219 v
.variable_ctx
= new VariableContext
220 _self_var
= v
.self_var
225 redef class AConcreteInitPropdef
226 readable attr _super_init_calls
: Array[MMMethod] = new Array[MMMethod]
227 readable attr _explicit_super_init_calls
: Array[MMMethod] = new Array[MMMethod]
228 redef meth accept_typing
(v
)
230 v
.top_block
= n_block
231 v
.explicit_super_init_calls
= explicit_super_init_calls
232 v
.explicit_other_init_call
= false
234 if v
.explicit_other_init_call
then
238 var l
= explicit_super_init_calls
.length
239 var cur_m
: MMMethod = null
240 var cur_c
: MMLocalClass = null
242 cur_m
= explicit_super_init_calls
[i
]
243 cur_c
= cur_m
.global
.intro
.local_class
246 while j
< v
.local_class
.cshe
.direct_greaters
.length
do
247 var c
= v
.local_class
.cshe
.direct_greaters
[j
]
248 if c
.global
.is_interface
or c
.global
.is_universal
then
250 else if cur_c
!= null and c
.cshe
<= cur_c
then
251 if c
== cur_c
then j
+= 1
252 super_init_calls
.add
(cur_m
)
255 cur_m
= explicit_super_init_calls
[i
]
256 cur_c
= cur_m
.global
.intro
.local_class
262 var p
= v
.get_default_constructor_for
(self, c
, method
)
264 super_init_calls
.add
(p
)
274 redef meth after_typing
(v
)
276 if v
.variable_ctx
!= null then
277 v
.variable_ctx
.add
(variable
)
283 readable attr _stype
: MMType
284 redef meth after_typing
(v
)
286 _stype
= get_stype
(v
)
291 redef readable attr _stype
: MMType
293 # Is the expression the implicit receiver
294 meth is_implicit_self
: Bool do return false
296 # Is the expression the current receiver (implicit or explicit)
297 meth is_self
: Bool do return false
299 # The variable accessed is any
300 meth its_variable
: Variable do return null
302 # The variable type information if current boolean expression is true
303 readable private attr _if_true_variable_ctx
: VariableContext
306 redef class AVardeclExpr
307 redef meth after_typing
(v
)
309 var va
= new VarVariable(n_id
.to_symbol
, self)
311 v
.variable_ctx
.add
(va
)
313 if n_type
!= null then
314 va
.stype
= n_type
.stype
315 if n_expr
!= null then
316 v
.check_conform_expr
(n_expr
, va
.stype
)
320 va
.stype
= n_expr
.stype
325 redef class ABlockExpr
326 redef meth accept_typing
(v
)
328 var old_var_ctx
= v
.variable_ctx
329 v
.variable_ctx
= v
.variable_ctx
.sub
333 v
.variable_ctx
= old_var_ctx
337 redef class AReturnExpr
338 redef meth after_typing
(v
)
340 var t
= v
.local_property
.signature
.return_type
341 if n_expr
== null and t
!= null then
342 v
.error
(self, "Error: Return without value in a function.")
343 else if n_expr
!= null and t
== null then
344 v
.error
(self, "Error: Return with value in a procedure.")
345 else if n_expr
!= null and t
!= null then
346 v
.check_conform_expr
(n_expr
, t
)
352 redef meth accept_typing
(v
)
354 var old_var_ctx
= v
.variable_ctx
356 v
.check_conform_expr
(n_expr
, v
.type_bool
)
358 if n_expr
.if_true_variable_ctx
!= null then
359 v
.variable_ctx
= n_expr
.if_true_variable_ctx
363 # Restore variable ctx
364 v
.variable_ctx
= old_var_ctx
366 if n_else
!= null then
368 v
.variable_ctx
= old_var_ctx
373 redef class AWhileExpr
374 redef meth after_typing
(v
)
376 v
.check_conform_expr
(n_expr
, v
.type_bool
)
381 redef meth after_typing
(v
)
383 # pop context created in AForVardeclExpr
384 var varctx
= v
.variable_ctx
385 assert varctx
isa SubVariableContext
386 v
.variable_ctx
= varctx
.prev
390 redef class AForVardeclExpr
391 redef meth after_typing
(v
)
393 v
.variable_ctx
= v
.variable_ctx
.sub
394 var va
= new AutoVariable(n_id
.to_symbol
, self)
396 v
.variable_ctx
.add
(va
)
398 var expr_type
= n_expr
.stype
399 if not v
.check_conform_expr
(n_expr
, v
.type_collection
) then
402 var prop
= expr_type
.local_class
.select_method
(once
("iterator".to_symbol
))
404 v
.error
(self, "Error: Collection MUST have an iterate method")
407 var iter_type
= prop
.signature_for
(expr_type
).return_type
408 var prop2
= iter_type
.local_class
.select_method
(once
("item".to_symbol
))
409 if prop2
== null then
410 v
.error
(self, "Error: {iter_type} MUST have an item method")
413 var t
= prop2
.signature_for
(iter_type
).return_type
414 if not n_expr
.is_self
then t
= t
.not_for_self
419 redef class AAssertExpr
420 redef meth after_typing
(v
)
422 v
.check_conform_expr
(n_expr
, v
.type_bool
)
423 if n_expr
.if_true_variable_ctx
!= null then v
.variable_ctx
= n_expr
.if_true_variable_ctx
428 redef meth its_variable
do return variable
430 redef meth after_typing
(v
)
432 _stype
= v
.variable_ctx
.stype
(variable
)
436 redef class AVarAssignExpr
437 redef meth after_typing
(v
)
439 var t
= v
.variable_ctx
.stype
(variable
)
440 v
.check_conform_expr
(n_value
, t
)
444 redef class AReassignFormExpr
445 # Compute and check method used through the reassigment operator
446 private meth do_lvalue_typing
(v
: TypingVisitor, type_lvalue
: MMType)
448 if type_lvalue
== null then
451 var name
= n_assign_op
.method_name
452 var prop
= type_lvalue
.local_class
.select_method
(name
)
454 v
.error
(self, "Error: Method '{name}' doesn't exists in {type_lvalue}.")
457 prop
.global
.check_visibility
(v
, self, v
.module, false)
458 var psig
= prop
.signature_for
(type_lvalue
)
459 _assign_method
= prop
460 v
.check_conform_expr
(n_value
, psig
[0].not_for_self
)
461 v
.check_conform
(self, psig
.return_type
.not_for_self
, n_value
.stype
)
464 # Method used through the reassigment operator (once computed)
465 readable attr _assign_method
: MMMethod
468 redef class AVarReassignExpr
469 redef meth after_typing
(v
)
471 var t
= v
.variable_ctx
.stype
(variable
)
472 do_lvalue_typing
(v
, t
)
476 redef class PAssignOp
477 meth method_name
: Symbol is abstract
479 redef class APlusAssignOp
480 redef meth method_name
do return once
"+".to_symbol
482 redef class AMinusAssignOp
483 redef meth method_name
do return once
"-".to_symbol
486 redef class ASelfExpr
487 redef meth its_variable
do return variable
489 redef meth after_typing
(v
)
491 variable
= v
.self_var
492 _stype
= v
.variable_ctx
.stype
(variable
)
495 redef meth is_self
do return true
498 redef class AImplicitSelfExpr
499 redef meth is_implicit_self
do return true
502 redef class AIfexprExpr
503 redef meth accept_typing
(v
)
505 var old_var_ctx
= v
.variable_ctx
508 if n_expr
.if_true_variable_ctx
!= null then v
.variable_ctx
= n_expr
.if_true_variable_ctx
510 v
.variable_ctx
= old_var_ctx
513 v
.check_conform_expr
(n_expr
, v
.type_bool
)
515 if not v
.check_expr
(n_then
) or not v
.check_expr
(n_else
) then return
518 var te
= n_else
.stype
521 else if not te
< t
then
522 v
.error
(self, "Type error: {te} is not a subtype of {t}.")
530 redef class ABoolExpr
531 redef meth after_typing
(v
)
538 redef meth after_typing
(v
)
540 v
.check_conform_expr
(n_expr
, v
.type_bool
)
541 v
.check_conform_expr
(n_expr2
, v
.type_bool
)
547 redef meth accept_typing
(v
)
549 var old_var_ctx
= v
.variable_ctx
552 if n_expr
.if_true_variable_ctx
!= null then v
.variable_ctx
= n_expr
.if_true_variable_ctx
555 if n_expr2
.if_true_variable_ctx
!= null then
556 _if_true_variable_ctx
= n_expr2
.if_true_variable_ctx
558 _if_true_variable_ctx
= v
.variable_ctx
561 v
.variable_ctx
= old_var_ctx
563 v
.check_conform_expr
(n_expr
, v
.type_bool
)
564 v
.check_conform_expr
(n_expr2
, v
.type_bool
)
570 redef meth after_typing
(v
)
572 v
.check_conform_expr
(n_expr
, v
.type_bool
)
578 redef meth after_typing
(v
)
585 redef class AFloatExpr
586 redef meth after_typing
(v
)
588 _stype
= v
.type_float
592 redef class ACharExpr
593 redef meth after_typing
(v
)
599 redef class AStringFormExpr
600 redef meth after_typing
(v
)
602 _stype
= v
.type_string
606 redef class ASuperstringExpr
607 redef meth after_typing
(v
)
609 _stype
= v
.type_string
613 redef class ANullExpr
614 redef meth after_typing
(v
)
620 redef class AArrayExpr
621 private meth stype
=(t
: MMType) do _stype
= t
623 redef meth after_typing
(v
)
625 var stype
: MMType = null
628 if stype
== null or (ntype
!= null and stype
< ntype
) then
633 v
.check_conform_expr
(n
, stype
)
635 _stype
= v
.type_array
(stype
)
639 redef class ARangeExpr
640 redef meth after_typing
(v
)
642 var ntype
= n_expr
.stype
643 var ntype2
= n_expr2
.stype
644 if ntype
== null or ntype
== null then
647 if ntype
< ntype2
then
649 else if not ntype2
< ntype
then
650 v
.error
(self, "Type error: {ntype} incompatible with {ntype2}.")
653 var dtype
= v
.type_discrete
654 v
.check_conform_expr
(n_expr
, dtype
)
655 v
.check_conform_expr
(n_expr2
, dtype
)
656 _stype
= v
.type_range
(ntype
)
660 redef class ASuperExpr
661 special ASuperInitCall
662 # readable attr _prop: MMSrcMethod
663 readable attr _init_in_superclass
: MMMethod
664 redef meth after_typing
(v
)
666 var precs
: Array[MMLocalProperty] = v
.local_property
.prhe
.direct_greaters
667 if not precs
.is_empty
then
668 v
.local_property
.need_super
= true
669 else if v
.local_property
.global
.is_init
then
670 var base_precs
= v
.local_class
.super_methods_named
(v
.local_property
.name
)
671 for p
in base_precs
do
672 if not p
.global
.is_init
then
673 v
.error
(self, "Error: {p.local_class}::{p} is not a constructor.")
675 precs
.add
(v
.local_class
[p
.global
])
678 if precs
.is_empty
then
679 v
.error
(self, "Error: No contructor named {v.local_property.name} in superclasses.")
681 else if precs
.length
> 1 then
682 v
.error
(self, "Error: Conflicting contructors named {v.local_property.name} in superclasses: {precs.join(", ")}.")
685 var p
= base_precs
.first
686 assert p
isa MMMethod
687 _init_in_superclass
= p
688 register_super_init_call
(v
, p
)
689 if n_args
.length
> 0 then
690 var signature
= get_signature
(v
, v
.self_var
.stype
, p
, true)
691 _arguments
= process_signature
(v
, signature
, p
, n_args
.to_a
)
694 v
.error
(self, "Error: No super method to call for {v.local_property}.")
698 if precs
.first
.signature_for
(v
.self_var
.stype
).return_type
!= null then
699 var stypes
= new Array[MMType]
700 var stype
: MMType = null
702 assert prop
isa MMMethod
703 var t
= prop
.signature_for
(v
.self_var
.stype
).return_type
.for_module
(v
.module).adapt_to
(v
.local_property
.signature
.recv
)
705 if stype
== null or stype
< t
then
710 v
.check_conform
(self, t
, stype
)
714 var p
= v
.local_property
715 assert p
isa MMSrcMethod
720 redef class AAttrFormExpr
722 readable attr _prop
: MMAttribute
724 # Attribute type of the acceded attribute
725 readable attr _attr_type
: MMType
727 # Compute the attribute accessed
728 private meth do_typing
(v
: TypingVisitor)
730 if not v
.check_expr
(n_expr
) then return
731 var type_recv
= n_expr
.stype
732 var name
= n_id
.to_symbol
733 var prop
= type_recv
.local_class
.select_attribute
(name
)
735 v
.error
(self, "Error: Attribute {name} doesn't exists in {type_recv}.")
737 else if v
.module.visibility_for
(prop
.global
.local_class
.module) < 3 then
738 v
.error
(self, "Error: Attribute {name} from {prop.global.local_class.module} is invisible in {v.module}")
741 var at
= prop
.signature_for
(type_recv
).return_type
742 if not n_expr
.is_self
then at
= at
.not_for_self
747 redef class AAttrExpr
748 redef meth after_typing
(v
)
758 redef class AAttrAssignExpr
759 redef meth after_typing
(v
)
765 v
.check_conform_expr
(n_value
, attr_type
)
769 redef class AAttrReassignExpr
770 redef meth after_typing
(v
)
776 do_lvalue_typing
(v
, attr_type
)
782 # Compute the called global property
783 private meth do_typing
(v
: TypingVisitor, type_recv
: MMType, is_implicit_self
: Bool, recv_is_self
: Bool, name
: Symbol, raw_args
: Array[PExpr])
785 var prop
= get_property
(v
, type_recv
, is_implicit_self
, name
)
786 if prop
== null then return
787 var sig
= get_signature
(v
, type_recv
, prop
, recv_is_self
)
788 if sig
== null then return
789 var args
= process_signature
(v
, sig
, prop
, raw_args
)
790 if args
== null then return
795 private meth get_property
(v
: TypingVisitor, type_recv
: MMType, is_implicit_self
: Bool, name
: Symbol): MMMethod
797 if type_recv
== null then return null
798 var prop
= type_recv
.local_class
.select_method
(name
)
799 if prop
== null and v
.local_property
.global
.is_init
then
800 var props
= type_recv
.local_class
.super_methods_named
(name
)
801 if props
.length
> 1 then
802 v
.error
(self, "Error: Ambigous method name '{name}' for {props.join(", ")}. Use explicit designation.")
804 else if props
.length
== 1 then
805 var p
= type_recv
.local_class
[props
.first
.global
]
806 assert p
isa MMMethod
812 if is_implicit_self
then
813 v
.error
(self, "Error: Method or variable '{name}' unknown in {type_recv}.")
815 v
.error
(self, "Error: Method '{name}' doesn't exists in {type_recv}.")
822 private meth get_signature
(v
: TypingVisitor, type_recv
: MMType, prop
: MMMethod, recv_is_self
: Bool): MMSignature
824 prop
.global
.check_visibility
(v
, self, v
.module, recv_is_self
)
825 var psig
= prop
.signature_for
(type_recv
)
826 if not recv_is_self
then psig
= psig
.not_for_self
830 # Check the conformity of a set of arguments `raw_args' to a signature.
831 private meth process_signature
(v
: TypingVisitor, psig
: MMSignature, prop
: MMMethod, raw_args
: Array[PExpr]): Array[PExpr]
833 var par_vararg
= psig
.vararg_rank
834 var par_arity
= psig
.arity
836 if raw_args
== null then raw_arity
= 0 else raw_arity
= raw_args
.length
837 if par_arity
> raw_arity
or (par_arity
!= raw_arity
and par_vararg
== -1) then
838 v
.error
(self, "Error: Method '{prop}' arity missmatch.")
842 var args
= new Array[PExpr]
843 for par_idx
in [0..par_arity
[ do
845 var par_type
= psig
[par_idx
]
846 if par_idx
== par_vararg
then
847 var star
= new Array[PExpr]
848 for i
in [0..(raw_arity-par_arity
)] do
849 a
= raw_args
[arg_idx
]
850 v
.check_conform_expr
(a
, par_type
)
852 arg_idx
= arg_idx
+ 1
854 var aa
= new AArrayExpr.init_aarrayexpr
(star
)
855 aa
.stype
= v
.type_array
(par_type
)
858 a
= raw_args
[arg_idx
]
859 v
.check_conform_expr
(a
, par_type
)
860 arg_idx
= arg_idx
+ 1
867 # The invoked method (once computed)
868 readable attr _prop
: MMMethod
870 # The real arguments used (after star transformation) (once computed)
871 readable attr _arguments
: Array[PExpr]
874 # A possible call of constructor in a super class
875 # Could be an explicit call or with the 'super' keyword
878 private meth register_super_init_call
(v
: TypingVisitor, property
: MMMethod)
880 if parent
!= v
.top_block
and self != v
.top_block
then
881 v
.error
(self, "Error: Constructor invocation {property} must not be in nested block.")
883 var cla
= v
.module[property
.global
.intro
.local_class
.global
]
884 var prev_class
: MMLocalClass = null
885 if not v
.explicit_super_init_calls
.is_empty
then
886 prev_class
= v
.explicit_super_init_calls
.last
.global
.intro
.local_class
888 var order
= v
.local_class
.cshe
.reverse_linear_extension
889 if cla
== v
.local_class
then
890 v
.explicit_other_init_call
= true
891 else if not order
.has
(cla
) then
892 v
.error
(self, "Error: Constructor of class {cla} must be one in {order.join(", ")}.")
893 else if cla
== prev_class
then
894 v
.error
(self, "Error: Only one super constructor invocation of class {cla} is allowed.")
896 var last_is_found
= prev_class
== null
898 if c
== prev_class
then
900 else if c
== cla
then
901 if not last_is_found
then
902 v
.error
(self, "Error: Constructor of {c} must be invoked before constructor of {prev_class}")
904 v
.explicit_super_init_calls
.add
(property
)
915 redef meth after_typing
(v
)
918 if t
== null then return
919 if t
.local_class
.global
.is_abstract
then
920 v
.error
(self, "Error: try to instantiate abstract class {t.local_class}.")
925 name
= once
"init".to_symbol
927 name
= n_id
.to_symbol
930 do_typing
(v
, t
, false, false, name
, n_args
.to_a
)
931 if prop
== null then return
933 if not prop
.global
.is_init
then
934 v
.error
(self, "Error: {prop} is not a constructor.")
941 redef class ASendExpr
942 special ASuperInitCall
943 # Name of the invoked property
944 meth name
: Symbol is abstract
946 # Raw arguments used (withour star transformation)
947 meth raw_arguments
: Array[PExpr] is abstract
949 redef meth after_typing
(v
)
954 private meth do_all_typing
(v
: TypingVisitor)
956 if not v
.check_expr
(n_expr
) then return
957 do_typing
(v
, n_expr
.stype
, n_expr
.is_implicit_self
, n_expr
.is_self
, name
, raw_arguments
)
958 if prop
== null then return
959 if prop
.global
.is_init
then
960 if not v
.local_property
.global
.is_init
then
961 v
.error
(self, "Error: try to invoke constructor {prop} in a method.")
962 else if not n_expr
.is_self
then
963 v
.error
(self, "Error: constructor {prop} is not invoken on 'self'.")
965 register_super_init_call
(v
, prop
)
968 var t
= prop
.signature_for
(n_expr
.stype
).return_type
969 if t
!= null and not n_expr
.is_self
then t
= t
.not_for_self
974 class ASendReassignExpr
976 special AReassignFormExpr
977 readable attr _read_prop
: MMMethod
978 redef meth do_all_typing
(v
)
980 if not v
.check_expr
(n_expr
) then return
981 var raw_args
= raw_arguments
982 do_typing
(v
, n_expr
.stype
, n_expr
.is_implicit_self
, n_expr
.is_self
, name
, raw_args
)
983 if prop
== null then return
984 if prop
.global
.is_init
then
985 if not v
.local_property
.global
.is_init
then
986 v
.error
(self, "Error: try to invoke constructor {prop} in a method.")
987 else if not n_expr
.is_self
then
988 v
.error
(self, "Error: constructor {prop} is not invoken on 'self'.")
991 var t
= prop
.signature_for
(n_expr
.stype
).return_type
992 if not n_expr
.is_self
then t
= t
.not_for_self
994 do_lvalue_typing
(v
, t
)
997 var old_args
= arguments
998 raw_args
.add
(n_value
)
1000 do_typing
(v
, n_expr
.stype
, n_expr
.is_implicit_self
, n_expr
.is_self
, "{name}=".to_symbol
, raw_args
)
1001 if prop
== null then return
1002 if prop
.global
.is_init
then
1003 if not v
.local_property
.global
.is_init
then
1004 v
.error
(self, "Error: try to invoke constructor {prop} in a method.")
1005 else if not n_expr
.is_self
then
1006 v
.error
(self, "Error: constructor {prop} is not invoken on 'self'.")
1010 _arguments
= old_args
# FIXME: What if star parameters do not match betwen the two methods?
1014 redef class ABinopExpr
1015 redef meth raw_arguments
do return [n_expr2
]
1018 redef meth name
do return once
"==".to_symbol
1021 redef meth name
do return once
"!=".to_symbol
1024 redef meth name
do return once
"<".to_symbol
1027 redef meth name
do return once
"<=".to_symbol
1030 redef meth name
do return once
">".to_symbol
1033 redef meth name
do return once
">=".to_symbol
1035 redef class APlusExpr
1036 redef meth name
do return once
"+".to_symbol
1038 redef class AMinusExpr
1039 redef meth name
do return once
"-".to_symbol
1041 redef class AStarshipExpr
1042 redef meth name
do return once
"<=>".to_symbol
1044 redef class AStarExpr
1045 redef meth name
do return once
"*".to_symbol
1047 redef class ASlashExpr
1048 redef meth name
do return once
"/".to_symbol
1050 redef class APercentExpr
1051 redef meth name
do return once
"%".to_symbol
1054 redef class AUminusExpr
1055 redef meth name
do return once
"unary -".to_symbol
1056 redef meth raw_arguments
do return null
1059 redef class ACallFormExpr
1060 redef meth after_typing
(v
)
1062 if n_expr
.is_implicit_self
then
1063 var name
= n_id
.to_symbol
1064 var variable
= v
.variable_ctx
[name
]
1065 if variable
!= null then
1066 if not n_args
.is_empty
then
1067 v
.error
(self, "Error: {name} is variable, not a function.")
1069 var vform
= variable_create
(variable
)
1070 vform
.variable
= variable
1072 vform
.after_typing
(v
)
1079 # Create a variable acces corresponding to the call form
1080 meth variable_create
(variable
: Variable): AVarFormExpr is abstract
1083 redef class ACallExpr
1084 redef meth variable_create
(variable
)
1086 return new AVarExpr.init_avarexpr
(n_id
)
1089 redef meth name
do return n_id
.to_symbol
1090 redef meth raw_arguments
do return n_args
.to_a
1093 redef class ACallAssignExpr
1094 redef meth variable_create
(variable
)
1096 return new AVarAssignExpr.init_avarassignexpr
(n_id
, n_assign
, n_value
)
1099 redef meth name
do return (n_id
.text
+ "=").to_symbol
1100 redef meth raw_arguments
do
1101 var res
= n_args
.to_a
1107 redef class ACallReassignExpr
1108 special ASendReassignExpr
1109 redef meth variable_create
(variable
)
1111 return new AVarReassignExpr.init_avarreassignexpr
(n_id
, n_assign_op
, n_value
)
1114 redef meth name
do return n_id
.to_symbol
1115 redef meth raw_arguments
do return n_args
.to_a
1118 redef class ABraExpr
1119 redef meth name
do return once
"[]".to_symbol
1120 redef meth raw_arguments
do return n_args
.to_a
1123 redef class ABraAssignExpr
1124 redef meth name
do return once
"[]=".to_symbol
1125 redef meth raw_arguments
do
1126 var res
= n_args
.to_a
1132 redef class ABraReassignExpr
1133 special ASendReassignExpr
1134 redef meth name
do return once
"[]".to_symbol
1135 redef meth raw_arguments
do return n_args
.to_a
1138 redef class AInitExpr
1139 redef meth name
do return once
"init".to_symbol
1140 redef meth raw_arguments
do return n_args
.to_a
1143 redef class AIsaExpr
1144 redef meth after_typing
(v
)
1146 var variable
= n_expr
.its_variable
1147 if variable
!= null then
1148 _if_true_variable_ctx
= v
.variable_ctx
.sub_with
(variable
, n_type
.stype
)
1150 _stype
= v
.type_bool
1154 redef class AAsCastExpr
1155 redef meth after_typing
(v
)
1157 v
.check_expr
(n_expr
)
1158 _stype
= n_type
.stype
1162 redef class AProxyExpr
1163 redef meth after_typing
(v
)
1165 _stype
= n_expr
.stype