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