0f1440bd721bec61baeb9c2484872df1b73bb9cc
[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 error(n, "Type error: no most general type. Got {n.stype} and {stype} at {node.locate}.")
452 end
453 return null
454 end
455 end
456 return stype
457 end
458
459 protected init(tc: ToolContext, module: MMSrcModule)
460 do
461 _tc = tc
462 _module = module
463 end
464 end
465
466 ###############################################################################
467
468 redef class PNode
469 protected fun accept_abs_syntax_visitor(v: AbsSyntaxVisitor) do visit_all(v)
470 end
471
472 redef class Token
473 var _symbol_cache: nullable Symbol
474
475 # Symbol associated with the text
476 # Lazily computed
477 fun to_symbol: Symbol
478 do
479 var s = _symbol_cache
480 if s == null then
481 s = text.to_symbol
482 _symbol_cache = s
483 end
484 return s
485 end
486 end
487
488 redef class PClassdef
489 # Associated class (MM entity)
490 fun local_class: MMSrcLocalClass is abstract
491 end
492
493 redef class AAttrPropdef
494 # Associated attribute (MM entity)
495 fun prop: MMSrcAttribute is abstract
496
497 # Associated read accessor (MM entity)
498 fun readmethod: nullable MMSrcMethod is abstract
499
500 # Associated write accessor (MM entity)
501 fun writemethod: nullable MMSrcMethod is abstract
502 end
503
504 redef class AConcreteInitPropdef
505 readable var _super_init_calls: Array[MMMethod] = new Array[MMMethod]
506 readable var _explicit_super_init_calls: Array[MMMethod] = new Array[MMMethod]
507 end
508
509 redef class AMethPropdef
510 # Associated method (MM entity)
511 fun method: MMMethSrcMethod is abstract
512
513 # Associated 'self' variable
514 fun self_var: ParamVariable is abstract
515 end
516
517 redef class ATypePropdef
518 # Associated formal type (MM entity)
519 fun prop: MMSrcTypeProperty is abstract
520 end
521
522 redef class PParam
523 # Position in the signature
524 fun position: Int is abstract
525
526 # Associated local variable
527 fun variable: ParamVariable is abstract
528 end
529
530 redef class PClosureDecl
531 # Position in the signature
532 fun position: Int is abstract
533
534 # Associated closure variable
535 fun variable: ClosureVariable is abstract
536 end
537
538 redef class PType
539 # Retrieve the local class corresponding to the type.
540 # Display an error and return null if there is no class
541 # Display an error and return null if the type is not class based (formal one)
542 fun get_local_class(v: AbsSyntaxVisitor): nullable MMLocalClass is abstract
543
544 # Retrieve corresponding static type.
545 # Display an error and return null if there is a problem
546 fun get_stype(v: AbsSyntaxVisitor): nullable MMType is abstract
547
548 # Retrieve corresponding static type.
549 # Display an error and return null if there is a problem
550 # But do not performs any subtype check.
551 # get_unchecked_stype should be called to check that the static type is fully valid
552 fun get_unchecked_stype(v: AbsSyntaxVisitor): nullable MMType is abstract
553
554 # Check that a static definition type is conform with regard to formal types
555 # Useful with get_unchecked_stype
556 # Remember that conformance check need that ancestors are totaly computed
557 fun check_conform(v: AbsSyntaxVisitor) is abstract
558
559 # Is the node correcly typed
560 # Return false if typed was not yet computed or
561 # if an error occured during the typing computation
562 fun is_typed: Bool is abstract
563
564 # Return corresponding static type. (require is_typed)
565 fun stype: MMType is abstract
566 end
567
568 redef class AType
569 var _stype_cache: nullable MMType = null
570 var _stype_cached: Bool = false
571
572 redef fun get_local_class(v)
573 do
574 var name = n_id.to_symbol
575 var mod = v.module
576 var cla = v.local_class
577
578 if cla.formal_dict.has_key(name) or cla.has_global_property_by_name(name) then
579 v.error(n_id, "Type error: {name} is a formal type")
580 _stype_cached = true
581 return null
582 end
583
584 if not mod.has_global_class_named(name) then
585 v.error(n_id, "Type error: class {name} not found in module {mod}.")
586 _stype_cached = true
587 return null
588 end
589
590 var local_class = mod.class_by_name(name)
591 local_class.global.check_visibility(v, self, mod)
592 return local_class
593 end
594
595 redef fun get_unchecked_stype(v)
596 do
597 if _stype_cached then return _stype_cache
598 _stype_cached = true
599
600 var name = n_id.to_symbol
601 var mod = v.module
602 var cla = v.local_class
603 var t: nullable MMType
604
605 if cla.formal_dict.has_key(name) then
606 if n_types.length > 0 then
607 v.error(self, "Type error: formal type {name} cannot have formal parameters.")
608 return null
609 end
610 t = cla.formal_dict[name]
611 if n_kwnullable != null then t = t.as_nullable
612 _stype_cache = t
613 return t
614 end
615
616 if cla.has_global_property_by_name(name) then
617 if n_types.length > 0 then
618 v.error(self, "Type error: formal type {name} cannot have formal parameters.")
619 return null
620 end
621 t = cla.get_type.local_class.select_virtual_type(name).stype_for(cla.get_type)
622 if t == null then
623 v.error(self, "Type error: circular definition in formal type {name}.")
624 return null
625 end
626 if n_kwnullable != null then t = t.as_nullable
627 _stype_cache = t
628 return t
629 end
630
631 var local_class = get_local_class(v)
632 if local_class == null then return null
633
634 var arity = n_types.length
635 if local_class.arity != arity then
636 if arity == 0 then
637 v.error(self, "Type error: '{local_class}' is a generic class.")
638 else if local_class.arity == 0 then
639 v.error(self, "Type error: '{local_class}' is not a generic class.")
640 else
641 v.error(self, "Type error: '{local_class}' has {local_class.arity} parameters ({arity} are provided).")
642 end
643 return null
644 end
645
646 if arity > 0 then
647 var tab = new Array[MMType]
648 for p in n_types do
649 var t2 = p.get_unchecked_stype(v)
650 if t2 == null then return null
651 tab.add(t2)
652 end
653 t = local_class.get_instantiate_type(tab)
654 else
655 t = local_class.get_type
656 end
657 if n_kwnullable != null then t = t.as_nullable
658 _stype_cache = t
659 return t
660 end
661
662 redef fun get_stype(v)
663 do
664 var t = get_unchecked_stype(v)
665 if t == null then return null
666 if not t.is_valid then return null
667 check_conform(v)
668 return t
669 end
670
671 redef fun check_conform(v)
672 do
673 var st = get_unchecked_stype(v)
674 if st == null then return
675 var local_class = st.local_class
676 var arity = n_types.length
677 if arity > 0 then
678 for i in [0..arity[ do
679 var p = n_types[i]
680 var pt = p.get_stype(v)
681 var b = local_class.get_formal(i)
682 if not b.is_valid then return
683 var bt = b.bound
684 bt = bt.adapt_to(st) # We need to abapt because of F-genericity
685 v.check_conform(p, pt, bt)
686 end
687 end
688 end
689 end
690
691 redef class PExpr
692 # Is the expression node correcly typed
693 # Return false if typed was not yet computed or
694 # if an error occured during the typing computation
695 fun is_typed: Bool is abstract
696
697 # Is the expression node a statement? (ie has no return value)
698 # require: is_typed
699 fun is_statement: Bool is abstract
700
701 # The static type of the expression
702 # require: is_typed and not is_statement
703 fun stype: MMType is abstract
704 end
705
706 class AAbsAbsSendExpr
707 special PExpr
708 # The signature of the called property (require is_typed)
709 fun prop_signature: MMSignature is abstract
710
711 # The real arguments used (after star transformation) (require is_typed)
712 fun arguments: Array[PExpr] is abstract
713 end
714
715 class AAbsSendExpr
716 special AAbsAbsSendExpr
717 # The invoked method (require is_typed)
718 fun prop: MMMethod is abstract
719
720 # The return type (if any) (once computed)
721 fun return_type: nullable MMType is abstract
722 end
723
724 class ASuperInitCall
725 special AAbsSendExpr
726 end
727
728 redef class ASuperExpr
729 special ASuperInitCall
730 fun init_in_superclass: nullable MMMethod is abstract
731 end
732
733 redef class ANewExpr
734 special AAbsSendExpr
735 end
736
737 redef class ASendExpr
738 special ASuperInitCall
739 # Closure definitions
740 fun closure_defs: nullable Array[PClosureDef] is abstract
741 end
742
743 redef class AReassignFormExpr
744 # Method used through the reassigment operator (require is_typed)
745 fun assign_method: MMMethod is abstract
746 end
747
748 class ASendReassignExpr
749 special ASendExpr
750 special AReassignFormExpr
751 # The invoked method used to read (require is_typed)
752 # prop is the method used to write
753 fun read_prop: MMMethod is abstract
754 end
755
756 redef class ACallReassignExpr
757 special ASendReassignExpr
758 end
759
760 redef class ABraReassignExpr
761 special ASendReassignExpr
762 end
763
764 redef class AAttrFormExpr
765 # Attribute accessed (require is_typed)
766 fun prop: MMAttribute is abstract
767
768 # Attribute type of the acceded attribute (require is_typed)
769 fun attr_type: MMType is abstract
770 end
771
772 redef class AStringFormExpr
773 fun meth_with_native: MMMethod is abstract
774 end
775
776 redef class ASuperstringExpr
777 fun meth_with_capacity: MMMethod is abstract
778 fun meth_add: MMMethod is abstract
779 fun meth_to_s: MMMethod is abstract
780 fun atype: MMType is abstract
781 end
782
783 redef class AArrayExpr
784 fun meth_with_capacity: MMMethod is abstract
785 fun meth_add: MMMethod is abstract
786 end
787
788 redef class ARangeExpr
789 fun meth_init: MMMethod is abstract
790 end
791
792 redef class AVardeclExpr
793 # Assiociated local variable
794 fun variable: VarVariable is abstract
795 #readable writable var _variable: nullable VarVariable
796 end
797
798 redef class AForExpr
799 # Associated automatic local variable
800 fun variable: AutoVariable is abstract
801 fun meth_iterator: MMMethod is abstract
802 fun meth_is_ok: MMMethod is abstract
803 fun meth_item: MMMethod is abstract
804 fun meth_next: MMMethod is abstract
805 end
806
807 redef class ASelfExpr
808 # Associated local variable
809 fun variable: ParamVariable is abstract
810 #readable writable var _variable: nullable ParamVariable
811 end
812
813 redef class AVarFormExpr
814 # Associated local variable
815 fun variable: Variable is abstract
816 #readable writable var _variable: nullable Variable
817 end
818
819 redef class AClosureCallExpr
820 special AAbsAbsSendExpr
821 # Associated closure variable
822 fun variable: ClosureVariable is abstract
823 #readable writable var _variable: nullable ClosureVariable
824 end
825
826 redef class PClosureDef
827 # Associated closure
828 #readable writable var _closure: nullable MMClosure
829 fun closure: MMClosure is abstract
830
831 # Automatic variables
832 readable writable var _variables: nullable Array[AutoVariable]
833 end