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 # Build MM entity from NIT AST and check conformance of these entities.
18 # This module introduce specific MM class (MMSrcXXX) that specialize the abstract one from metamodel
24 # Class specialization hierarchy sorter
25 private class CSHSorter
26 special AbstractSorter[MMLocalClass]
27 redef meth compare
(a
, b
)
29 return a
.cshe
.rank
<=> b
.cshe
.rank
35 redef class MMSrcModule
36 # Syntax analysis and MM construction for the module
37 # Require that supermodules are processed
38 meth do_mmbuilder
(tc
: ToolContext)
40 # Import global classes
43 # Create local classes and attach them to global classes
44 var mmbv
= new ClassBuilderVisitor(tc
, self)
46 if tc
.error_count
> 0 then exit
(1)
48 # Import unrefined local classes and attach them to global classes
51 # Resolve classes in super clauses
52 var mmbv1
= new ClassSpecializationBuilderVisitor(tc
, self)
54 if tc
.error_count
> 0 then exit
(1)
56 # Compute specialization relation
57 for c
in local_classes
do
58 if visibility_for
(c
.global
.intro
.module) < c
.global
.visibility_level
then
61 c
.compute_super_classes
64 # Class that we will process now are those in the hierarchy
65 # Its mean all the visible classes and their super-classes
66 # Note that leaves invisible classes are not in the 'classes' set
67 var classes
= class_specialization_hierarchy
.to_a
69 # Prepare class list to process the following in a right order
70 var sorter
= once
new CSHSorter
73 # Compute class ancestors types
74 var mmbv1b
= new ClassAncestorBuilder(tc
, self)
76 if c
isa MMSrcLocalClass then
83 if tc
.error_count
> 0 then exit
(1)
85 # Check class conformity
86 var mmbv1b
= new ClassVerifierVisitor(tc
, self)
88 if c
isa MMSrcLocalClass then
94 if tc
.error_count
> 0 then exit
(1)
96 # Property inhritance and introduction
97 var mmbv2
= new PropertyBuilderVisitor(tc
, self)
99 # Inherit global properties
100 c
.inherit_global_properties
102 # Global property introduction and redefinition
103 if c
isa MMSrcLocalClass then
109 # Note that inherited unredefined property are processed on demand latter
111 if tc
.error_count
> 0 then exit
(1)
113 # Property signature analysis and inheritance conformance
114 var mmbv3
= new PropertyVerifierVisitor(tc
, self)
116 if c
isa MMSrcLocalClass then
123 # Check inherited local properties
125 for g
in c
.global_properties
do
126 if visibility_for
(g
.intro
.module) < g
.visibility_level
then continue
131 if tc
.error_count
> 0 then exit
(1)
135 redef class MMSrcLocalClass
136 # Add a source property
137 # Register it to the class and attach it to global property
138 private meth add_src_local_property
(v
: PropertyBuilderVisitor, prop
: MMSrcLocalProperty)
140 var pname
= prop
.name
141 # Check double definition in the same class
142 if src_local_properties
.has_key
(pname
) then
143 v
.error
(prop
.node
, "Error: A property {pname} is already defined in class {name} at line {src_local_properties[pname].node.first_token.line}.")
146 src_local_properties
[pname
] = prop
148 # Intro or redefinition ?
149 if has_global_property_by_name
(pname
) then
150 var globs
= properties_by_name
[pname
]
151 if globs
.length
> 1 then
152 v
.error
(prop
.node
, "Name error: {self} inherits {globs.length} global properties named {pname}.")
155 prop
.inherit_global
(g
)
158 if prop
.global
== null then
159 #print "{prop.full_name} is an introduction"
161 prop
.global
.is_init
= prop
.node
isa AConcreteInitPropdef
166 # Concrete NIT class specialization relation
169 # The related AST node
170 readable attr _node
: ASuperclass
171 redef readable attr _local_class
: MMLocalClass
173 init(n
: ASuperclass, c
: MMLocalClass)
180 ###############################################################################
182 # A pass visitor for syntax analysis.
183 # * Build the classes and attach them to global classes
184 # * Collect generic formal parameters.
185 private class ClassBuilderVisitor
186 special AbsSyntaxVisitor
187 # Current class arity
188 readable writable attr _local_class_arity
: Int
190 # Current class formal parameters
191 readable writable attr _formals
: Map[Symbol, MMTypeFormalParameter]
193 redef meth visit
(n
) do n
.accept_class_builder
(self)
197 # Another pass visitor for syntax analysis.
198 # * Build ancertors (with only class informations not the type one)
199 private class ClassSpecializationBuilderVisitor
200 special AbsSyntaxVisitor
201 redef meth visit
(n
) do n
.accept_class_specialization_builder
(self)
205 # Another pass visitor for syntax analysis.
206 # * Compute types in ancestors
207 private class ClassAncestorBuilder
208 special AbsSyntaxVisitor
209 redef meth visit
(n
) do n
.accept_class_ancestor_builder
(self)
213 # Another pass visitor for syntax analysis.
214 # * Checks classes in regard to superclasses
215 private class ClassVerifierVisitor
216 special AbsSyntaxVisitor
217 redef meth visit
(n
) do n
.accept_class_verifier
(self)
222 # Another pass visitor for syntax analysis.
223 # * Build propertie names
224 # * Build local properties and attache them to global properties
225 # * Attach bound to formal types
226 private class PropertyBuilderVisitor
227 special AbsSyntaxVisitor
228 redef meth visit
(n
) do n
.accept_property_builder
(self)
232 # Another pass pass visitor for syntax analysis.
233 # * Check property conformance
234 private class PropertyVerifierVisitor
235 special AbsSyntaxVisitor
236 # Current visited parameter types
237 readable writable attr _params
: Array[PParam]
239 # Visited parameters without type information added
240 readable writable attr _untyped_params
: Array[PParam]
242 # Position of the current star parameter
243 readable writable attr _vararg_rank
: Int
246 readable writable attr _signature
: MMSignature
248 redef meth visit
(n
) do n
.accept_property_verifier
(self)
253 ###############################################################################
256 private meth accept_class_builder
(v
: ClassBuilderVisitor) do accept_abs_syntax_visitor
(v
)
257 private meth accept_class_specialization_builder
(v
: ClassSpecializationBuilderVisitor) do accept_abs_syntax_visitor
(v
)
258 private meth accept_class_ancestor_builder
(v
: ClassAncestorBuilder) do accept_abs_syntax_visitor
(v
)
259 private meth accept_class_verifier
(v
: ClassVerifierVisitor) do accept_abs_syntax_visitor
(v
)
260 private meth accept_property_builder
(v
: PropertyBuilderVisitor) do accept_abs_syntax_visitor
(v
)
261 private meth accept_property_verifier
(v
: PropertyVerifierVisitor) do accept_abs_syntax_visitor
(v
)
265 # Import supermodules and compute visibility
266 meth import_super_modules
(tc
: ToolContext, mod
: MMSrcModule)
268 # Import super-modules
269 var module_names_to_import
= new Array[Symbol]
270 var module_visibility
= new HashMap[Symbol, Int]
271 var no_import
: PImport
272 for i
in n_imports
do
273 var n
= i
.module_name
275 module_names_to_import
.add
(n
)
276 module_visibility
[n
] = i
.visibility_level
281 if no_import
!= null then
282 if not module_names_to_import
.is_empty
then
283 tc
.error
("{no_import.locate}: Error: Top modules cannot import other modules.")
285 else if module_names_to_import
.is_empty
then
286 var stdname
= once
"standard".to_symbol
287 module_names_to_import
.add
(stdname
)
288 module_visibility
[stdname
] = 1
291 mod
.import_supers_modules
(module_names_to_import
)
293 for mname
in module_names_to_import
do
294 var level
= module_visibility
[mname
]
295 var m
= tc
.get_module
(mname
, mod
)
296 mod
.add_super_module
(m
, level
)
301 redef class APackagedecl
302 redef meth accept_class_builder
(v
)
304 if n_id
.to_symbol
!= v
.module.name
then
305 v
.error
(n_id
, "Error: Package name missmatch between {v.module.name} and {n_id.to_symbol}")
311 # Imported module name (or null)
312 meth module_name
: Symbol is abstract
314 # Visibility level (intrude/public/private)
315 meth visibility_level
: Int is abstract
318 redef meth module_name
320 return n_id
.to_symbol
322 redef meth visibility_level
324 return n_visibility
.level
327 redef class ANoImport
328 redef meth module_name
334 redef class PVisibility
336 meth level
: Int is abstract
338 redef class APublicVisibility
339 redef meth level
do return 1
341 redef class AProtectedVisibility
342 redef meth level
do return 2
344 redef class APrivateVisibility
345 redef meth level
do return 3
347 redef class AIntrudeVisibility
348 redef meth level
do return 0
352 redef class PClassdef
353 redef readable attr _local_class
: MMSrcLocalClass
356 meth name
: Symbol is abstract
358 # Number of formal parameters
359 meth arity
: Int do return 0
361 # Visibility of the class
362 meth visibility_level
: Int do return 1
364 redef meth accept_class_builder
(v
)
366 var local_class
: MMSrcLocalClass
368 var local_classes
= mod
.src_local_classes
369 if (local_classes
.has_key
(name
)) then
370 local_class
= local_classes
[name
]
371 if self isa AClassdef then
372 # If we are not a special implicit class then rant
373 v
.error
(self, "Error: A class {name} is already defined at line {local_class.nodes.first.first_token.line}.")
376 local_class
.nodes
.add
(self)
378 local_class
= new MMSrcLocalClass(name
, self, arity
)
379 mod
.add_local_class
(local_class
)
380 local_classes
[name
] = local_class
381 var g
= mod
.global_class_named
(name
)
384 local_class
.new_global
385 g
= local_class
.global
387 local_class
.set_global
(g
)
391 _local_class
= local_class
392 v
.local_class_arity
= 0
393 v
.formals
= new HashMap[Symbol, MMTypeFormalParameter]
399 _local_class
.formal_dict
= v
.formals
403 redef meth accept_abs_syntax_visitor
(v
)
405 v
.local_class
= _local_class
411 redef class PClasskind
412 meth is_interface
: Bool do return false
413 meth is_universal
: Bool do return false
414 meth is_abstract
: Bool do return false
417 redef class AInterfaceClasskind
418 redef meth is_interface
do return true
420 redef class AUniversalClasskind
421 redef meth is_universal
do return true
423 redef class AAbstractClasskind
424 redef meth is_abstract
do return true
427 redef class AClassdef
430 return n_id
.to_symbol
434 return n_formaldefs
.length
436 redef meth accept_class_verifier
(v
)
439 var glob
= _local_class
.global
440 if glob
.intro
== _local_class
then
442 glob
.visibility_level
= visibility_level
443 glob
.is_interface
= n_classkind
.is_interface
444 glob
.is_abstract
= n_classkind
.is_abstract
445 glob
.is_universal
= n_classkind
.is_universal
446 if n_kwredef
!= null then
447 v
.error
(self, "Redef error: No class {name} is imported. Remove the redef keyword to define a new class.")
450 for c
in _local_class
.cshe
.direct_greaters
do
452 if glob
.is_interface
then
453 if cg
.is_universal
then
454 v
.error
(self, "Special error: Interface {name} try to specialise universal class {c.name}.")
455 else if not cg
.is_interface
then
456 v
.error
(self, "Special error: Interface {name} try to specialise class {c.name}.")
458 else if glob
.is_universal
then
459 if not cg
.is_interface
and not cg
.is_universal
then
460 v
.error
(self, "Special error: Universal class {name} try to specialise class {c.name}.")
463 if cg
.is_universal
then
464 v
.error
(self, "Special error: Class {name} try to specialise universal class {c.name}.")
474 glob
.check_visibility
(v
, self, v
.module)
475 if n_kwredef
== null then
476 v
.error
(self, "Redef error: {name} is an imported class. Add the redef keyword to refine it.")
480 if glob
.intro
.arity
!= _local_class
.arity
then
481 v
.error
(self, "Redef error: Formal parameter arity missmatch; got {_local_class.arity}, expected {glob.intro.arity}.")
485 not glob
.is_interface
and n_classkind
.is_interface
or
486 not glob
.is_abstract
and n_classkind
.is_abstract
or
487 not glob
.is_universal
and n_classkind
.is_universal
489 v
.error
(self, "Redef error: cannot change kind of class {name}.")
493 redef meth visibility_level
495 return n_visibility
.level
499 redef class AMainClassdef
502 return once
"Sys".to_symbol
506 redef class ATopClassdef
509 return once
"Object".to_symbol
513 class MMSrcTypeFormalParameter
514 special MMTypeFormalParameter
515 # The associated node
516 readable attr _node
: AFormaldef
518 init(name
: Symbol, pos
: Int, local_class
: MMLocalClass, n
: AFormaldef)
520 super(name
, pos
, local_class
)
525 redef class AFormaldef
526 # The associated formal generic parameter (MM entity)
527 attr _formal
: MMSrcTypeFormalParameter
529 redef meth accept_class_builder
(v
)
531 var name
= n_id
.to_symbol
532 var formal_type
= new MMSrcTypeFormalParameter(name
, v
.local_class_arity
, v
.local_class
, self)
533 _formal
= formal_type
534 v
.local_class_arity
= v
.local_class_arity
+ 1
535 v
.local_class
.register_formal
(formal_type
)
536 v
.formals
[name
] = formal_type
540 redef meth accept_class_verifier
(v
)
543 var c
= v
.local_class
544 var o
= c
.global
.intro
546 if n_type
== null then
547 _formal
.bound
= v
.module.type_any
549 _formal
.bound
= n_type
.get_stype
(v
)
552 var ob
= o
.get_formal
(_formal
.position
).bound
.for_module
(v
.module)
553 if n_type
== null then
556 _formal
.bound
= n_type
.get_stype
(v
)
557 if _formal
.bound
!= ob
then
558 v
.error
(self, "Redef error: Cannot change formal parameter type of class {c}; got {_formal.bound}, expected {ob}.")
565 redef class ASuperclass
566 readable attr _ancestor
: MMSrcAncestor
568 redef meth accept_class_specialization_builder
(v
)
571 var c
= n_type
.get_local_class
(v
)
572 var ancestor
= new MMSrcAncestor(self, c
)
574 v
.local_class
.add_direct_parent
(ancestor
)
577 redef meth accept_class_ancestor_builder
(v
)
580 _ancestor
.stype
= n_type
.get_unchecked_stype
(v
)
581 _ancestor
.inheriter
= v
.local_class
.get_type
584 redef meth accept_class_verifier
(v
)
587 n_type
.check_conform
(v
)
592 # Process and check properties of the property.
593 # * Distinguish inits and methods
594 # * Inherit or check visibility.
595 # * Check redef errors.
596 # * Check forbiden attribute definitions.
597 # * Check signature conformance.
598 private meth process_and_check
(v
: PropertyVerifierVisitor, prop
: MMSrcLocalProperty, has_redef
: Bool, visibility_level
: Int)
600 if prop
.global
.intro
== prop
then
601 do_and_check_intro
(v
, prop
, has_redef
, visibility_level
)
603 do_and_check_redef
(v
, prop
, has_redef
, visibility_level
)
607 # The part of process_and_check when prop is an introduction
608 private meth do_and_check_intro
(v
: PropertyVerifierVisitor, prop
: MMSrcLocalProperty, has_redef
: Bool, visibility_level
: Int)
610 var glob
= prop
.global
611 var gbc
= prop
.local_class
.global
612 if v
.local_class
.global
.visibility_level
>= 3 then
613 # Method of private classes are private
616 glob
.visibility_level
= visibility_level
617 if has_redef
and not glob
.is_init
then
618 v
.error
(self, "Error: No property {prop.local_class}::{prop} is inherited. Remove the redef keyword to define a new property.")
620 if glob
.is_attribute
then
621 if gbc
.is_interface
then
622 v
.error
(self, "Error: Attempt to define attribute {prop} in the interface {prop.local_class}.")
623 else if gbc
.is_universal
then
624 v
.error
(self, "Error: Attempt to define attribute {prop} in the universal class {prop.local_class}.")
626 else if glob
.is_init
then
627 if gbc
.is_interface
then
628 v
.error
(self, "Error: Attempt to define a constructor {prop} in the class {prop.local_class}.")
629 else if gbc
.is_universal
then
630 v
.error
(self, "Error: Attempt to define a constructor {prop} in the universal {prop.local_class}.")
633 if prop
.signature
== null then
635 var supers
= prop
.local_class
.super_methods_named
(prop
.name
)
636 inherit_signature
(v
, prop
, supers
)
638 if prop
.signature
!= null then
640 else if not v
.untyped_params
.is_empty
then
641 v
.error
(v
.untyped_params
.first
, "Error: Untyped parameter.")
643 prop
.signature
= new MMSignature(new Array[MMType], null, v
.local_class
.get_type
)
648 private meth inherit_signature
(v
: PropertyVerifierVisitor, prop
: MMSrcLocalProperty, supers
: Array[MMLocalProperty])
650 var s
= prop
.signature
652 var isig
= ip
.signature
.adaptation_to
(v
.local_class
.get_type
)
655 if v
.params
.length
!= isig
.arity
then
656 prop
.node
.printl
("v.params.length {v.params.length} != isig.arity {isig.arity} ; {prop.full_name} vs {ip.full_name}")
660 var t
= isig
[p
.position
]
662 if p
.position
== isig
.vararg_rank
then
674 # The part of process_and_check when prop is a redefinition
675 private meth do_and_check_redef
(v
: PropertyVerifierVisitor, prop
: MMSrcLocalProperty, has_redef
: Bool, visibility_level
: Int)
677 var is_init
= self isa AConcreteInitPropdef
678 var glob
= prop
.global
680 if not has_redef
and prop
.name
!= once
"init".to_symbol
then
681 v
.error
(self, "Redef error: {prop.local_class}::{prop} is an inherited property. To redefine it, add the redef keyword.")
684 if glob
.is_init
and not is_init
then
685 v
.error
(self, "Redef error: A method {prop.local_class}::{prop} cannot redefine a constructor.")
686 else if not glob
.is_init
and is_init
then
687 v
.error
(self, "Redef error: A constructor {prop.local_class}::{prop} cannot redefine a method.")
690 var s
= prop
.signature
691 #print "process {prop.local_class.module}::{prop.local_class}::{prop} from global {prop.global.local_property.local_class.module}::{prop.global.local_property.local_class}::{prop.global.local_property}"
692 for i
in prop
.cprhe
.direct_greaters
do
693 var ip
= i
.local_class
[prop
.global
]
694 var isig
= i
.signature
.adaptation_to
(v
.local_class
.get_type
)
697 #print "{prop.full_name} inherits signature from {ip.full_name}"
698 if v
.params
.length
!= isig
.arity
then
699 v
.error
(self, "Redef error: {prop.local_class}::{prop} redefines {ip.local_class}::{ip} with {isig.arity} parameter(s).")
703 var t
= isig
[p
.position
]
705 if p
.position
== isig
.vararg_rank
then
714 #print "orig signature: {i.signature.recv} . {i.signature}"
715 #print "inh signature: {isig.recv} . {isig}"
716 #print "redef signature: {s.recv} . {s}"
718 if glob
.is_init
and i
.local_class
.global
!= prop
.local_class
.global
then
719 # Do not check signature
720 else if s
.arity
!= isig
.arity
then
721 v
.error
(self, "Redef error: {prop.local_class}::{prop} redefines {ip.local_class}::{ip} with {isig.arity} parameter(s).")
723 for i
in [0..s
.arity
[ do
724 if s
[i
] != isig
[i
] then
725 v
.error
(self, "Redef error: Expected {isig[i]} (as in {ip.local_class}::{ip}), got {s[i]} in {prop.local_class}::{prop}.")
730 var srt
= s
.return_type
731 var isrt
= isig
.return_type
732 if srt
== null and isrt
!= null then
733 v
.error
(self, "Redef error: The procedure {prop.local_class}::{prop} redefines the function {ip.local_class}::{ip}.")
734 else if srt
!= null and isrt
== null then
735 v
.error
(self, "Redef error: The function {prop.local_class}::{prop} redefines the procedure {ip.local_class}::{ip}.")
736 else if srt
!= null and isrt
!= null and not srt
< isrt
then
737 v
.error
(self, "Redef error: Expected {isrt} (as in {ip.local_class}::{ip}), got {srt} in {prop.local_class}::{prop}.")
738 else if srt
!= null and isrt
!= null and srt
!= isrt
and prop
isa MMAttribute then
740 v
.warning
(self, "Redef warning: Expected {isrt} (as in {ip.local_class}::{ip}), got {srt} in {prop.local_class}::{prop}.")
744 if visibility_level
!= 1 and glob
.visibility_level
!= visibility_level
then
745 v
.error
(self, "Redef error: {prop.local_class}::{prop} redefinition cannot change visibility.")
747 glob
.check_visibility
(v
, self, v
.module, true)
751 redef class AAttrPropdef
752 redef readable attr _readmethod
: MMSrcMethod
753 redef readable attr _writemethod
: MMSrcMethod
754 redef readable attr _prop
: MMSrcAttribute
756 redef meth accept_property_builder
(v
)
759 var name
= n_id
.to_symbol
760 var prop
= new MMSrcAttribute(name
, v
.local_class
, self)
762 v
.local_class
.add_src_local_property
(v
, prop
)
764 if n_readable
!= null then
765 name
= n_id
.text
.substring_from
(1).to_symbol
766 _readmethod
= new MMReadImplementationMethod(name
, v
.local_class
, self)
767 v
.local_class
.add_src_local_property
(v
, _readmethod
)
769 if n_writable
!= null then
770 name
= (n_id
.text
.substring_from
(1) + "=").to_symbol
771 _writemethod
= new MMWriteImplementationMethod(name
, v
.local_class
, self)
772 v
.local_class
.add_src_local_property
(v
, _writemethod
)
776 redef meth accept_property_verifier
(v
)
780 if n_type
!= null then
781 t
= n_type
.get_stype
(v
)
783 v
.error
(self, "Not yet implemented: Attribute definition {_prop.local_class}::{_prop} requires an explicit type.")
787 var signature
= new MMSignature(new Array[MMType], t
, v
.local_class
.get_type
)
788 _prop
.signature
= signature
789 var visibility_level
= n_visibility
.level
790 process_and_check
(v
, _prop
, n_kwredef
!= null, visibility_level
)
791 if n_readable
!= null then
792 _readmethod
.signature
= signature
793 process_and_check
(v
, _readmethod
, n_readable
.n_kwredef
!= null, visibility_level
)
794 n_type
.check_visibility
(v
, _readmethod
)
796 if n_writable
!= null then
797 _writemethod
.signature
= new MMSignature(new Array[MMType].with
(t
), null, v
.local_class
.get_type
)
798 process_and_check
(v
, _writemethod
, n_writable
.n_kwredef
!= null, visibility_level
)
799 n_type
.check_visibility
(v
, _writemethod
)
803 redef meth accept_abs_syntax_visitor
(v
)
805 v
.local_property
= prop
807 v
.local_property
= null
811 redef class AMethPropdef
813 readable attr _name
: Symbol
815 redef readable attr _method
: MMMethSrcMethod
817 redef meth accept_property_builder
(v
)
820 if n_methid
== null then
821 if self isa AConcreteInitPropdef then
822 _name
= once
"init".to_symbol
824 _name
= once
"main".to_symbol
827 _name
= n_methid
.name
828 # FIXME: Add the 'unary' keyword
829 if n_methid
.name
== (once
"-".to_symbol
) then
831 if ns
isa ASignature and ns
.n_params
.length
== 0 then
832 _name
= once
"unary -".to_symbol
836 var prop
= new MMMethSrcMethod(_name
, v
.local_class
, self)
838 v
.local_class
.add_src_local_property
(v
, prop
)
841 redef meth accept_property_verifier
(v
)
843 v
.params
= new Array[PParam]
844 v
.untyped_params
= new Array[PParam]
850 if v
.signature
== null then
851 #_method.signature = new MMSignature(new Array[MMType], null, v.local_class.get_type)
853 _method
.signature
= v
.signature
855 var visibility_level
= 1
856 if n_visibility
!= null and n_visibility
.level
> 1 then
857 visibility_level
= n_visibility
.level
859 process_and_check
(v
, _method
, n_kwredef
!= null, visibility_level
)
860 if n_signature
!= null then n_signature
.check_visibility
(v
, _method
)
863 redef meth accept_abs_syntax_visitor
(v
)
865 v
.local_property
= method
867 v
.local_property
= null
871 redef class AMainMethPropdef
872 redef meth process_and_check
(v
, prop
, has_redef
, visibility_level
)
874 prop
.global
.visibility_level
= visibility_level
875 prop
.signature
= new MMSignature(new Array[MMType], null, v
.local_class
.get_type
)
876 # Disable all checks for main
880 redef class ATypePropdef
881 redef readable attr _prop
: MMSrcTypeProperty
883 redef meth accept_property_builder
(v
)
886 var name
= n_id
.to_symbol
887 var prop
= new MMSrcTypeProperty(name
, v
.local_class
, self)
889 v
.local_class
.add_src_local_property
(v
, prop
)
892 redef meth accept_property_verifier
(v
)
895 var signature
= new MMSignature(new Array[MMType], n_type
.get_stype
(v
), v
.local_class
.get_type
)
896 _prop
.signature
= signature
897 var visibility_level
= n_visibility
.level
898 process_and_check
(v
, _prop
, n_kwredef
!= null, visibility_level
)
901 redef meth accept_abs_syntax_visitor
(v
)
903 v
.local_property
= prop
905 v
.local_property
= null
909 # Visitor used to build a full method name from multiple tokens
910 private class MethidAccumulator
912 readable attr _name
: String
930 readable attr _name
: Symbol
932 redef meth accept_property_builder
(v
)
934 var accumulator
= new MethidAccumulator
935 accumulator
.visit
(self)
936 _name
= accumulator
.name
.to_symbol
941 redef class PSignature
942 # Check that visibilities of types in the signature are compatible with the visibility of the property.
943 meth check_visibility
(v
: AbsSyntaxVisitor, p
: MMSrcLocalProperty) is abstract
946 redef class ASignature
947 redef meth accept_property_verifier
(v
)
950 if not v
.untyped_params
.is_empty
then
951 if v
.untyped_params
.first
!= v
.params
.first
or n_type
!= null then
952 v
.error
(v
.untyped_params
.first
, "Syntax error: untyped parameter.")
955 else if not v
.params
.is_empty
or n_type
!= null then
956 var pars
= new Array[MMType]
960 var ret
: MMType = null
961 if n_type
!= null then
962 ret
= n_type
.get_stype
(v
)
964 v
.signature
= new MMSignature(pars
, ret
, v
.local_class
.get_type
)
965 if v
.vararg_rank
>= 0 then
966 v
.signature
.vararg_rank
= v
.vararg_rank
971 redef meth check_visibility
(v
, p
)
973 if p
.global
.visibility_level
>= 3 then return
975 if n
.n_type
!= null then n
.n_type
.check_visibility
(v
, p
)
977 if n_type
!= null then n_type
.check_visibility
(v
, p
)
982 redef readable attr _position
: Int
984 redef readable attr _variable
: Variable
986 # The type of the parameter in signature
987 readable writable attr _stype
: MMType
989 redef meth accept_property_verifier
(v
)
992 _position
= v
.params
.length
993 _variable
= new Variable(n_id
.to_symbol
, self)
995 v
.untyped_params
.add
(self)
996 if n_type
!= null then
997 var stype
= n_type
.get_stype
(v
)
998 for p
in v
.untyped_params
do
1001 if v
.vararg_rank
== -1 then
1002 v
.vararg_rank
= p
.position
1004 v
.error
(self, "Error: A vararg parameter is already defined.")
1006 stype
= v
.type_array
(stype
)
1008 p
.variable
.stype
= stype
1010 v
.untyped_params
.clear
1014 meth is_vararg
: Bool is abstract
1018 redef meth is_vararg
do return n_dotdotdot
!= null
1022 # Check that visibilities of types in the signature are compatible with the visibility of the property.
1023 private meth check_visibility
(v
: AbsSyntaxVisitor, p
: MMSrcLocalProperty) is abstract
1027 redef meth check_visibility
(v
, p
)
1029 if p
.global
.visibility_level
>= 3 then return
1030 var t
= get_stype
(v
)
1031 if t
== null then return
1032 var bc
= t
.local_class
1033 if bc
== null then return
1034 if bc
.global
.visibility_level
>= 3 then
1035 v
.error
(self, "Access error: Class {bc} is private and cannot be used in the signature of the non-private property {p}.")
1038 n
.check_visibility
(v
, p
)
1044 redef meth accept_class_builder
(v
) do end
1045 redef meth accept_property_builder
(v
) do end
1046 redef meth accept_property_verifier
(v
) do end