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