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 c
.accept_class_visitor
(mmbv1b
)
79 if tc
.error_count
> 0 then exit
(1)
81 # Check class conformity
82 var mmbv1b
= new ClassVerifierVisitor(tc
, self)
84 c
.accept_class_visitor
(mmbv1b
)
86 if tc
.error_count
> 0 then exit
(1)
88 # Property inhritance and introduction
89 var mmbv2
= new PropertyBuilderVisitor(tc
, self)
91 # Inherit global properties
92 c
.inherit_global_properties
94 # Global property introduction and redefinition
95 c
.accept_class_visitor
(mmbv2
)
96 if c
isa MMSrcLocalClass then
99 # Note that inherited unredefined property are processed on demand latter
101 if tc
.error_count
> 0 then exit
(1)
103 # Property signature analysis and inheritance conformance
104 var mmbv3
= new PropertyVerifierVisitor(tc
, self)
106 c
.accept_properties_visitor
(mmbv3
)
109 # Check inherited local properties
111 for g
in c
.global_properties
do
112 if visibility_for
(g
.intro
.module) < g
.visibility_level
then continue
117 if tc
.error_count
> 0 then exit
(1)
121 redef class MMLocalClass
122 # Accept a class visitor (on class nodes)
123 private meth accept_class_visitor
(v
: AbsSyntaxVisitor)
127 # Accept a class visitor (on class properties)
128 private meth accept_properties_visitor
(v
: AbsSyntaxVisitor)
133 redef class MMSrcLocalClass
134 redef meth accept_class_visitor
(v
)
141 # Accept a class visitor (on class properties)
142 redef meth accept_properties_visitor
(v
)
148 for p
in src_local_properties
do
149 p
.accept_property_visitor
(v
)
152 # Add a source property
153 # Register it to the class and attach it to global property
154 private meth add_src_local_property
(v
: PropertyBuilderVisitor, prop
: MMConcreteProperty)
156 var pname
= prop
.name
157 # Check double definition in the same class
158 if src_local_properties
.has_key
(pname
) then
159 v
.error
(prop
.node
, "Error: A property {pname} is already defined in class {name}.")
162 src_local_properties
[pname
] = prop
164 # Intro or redefinition ?
165 if has_global_property_by_name
(pname
) then
166 var globs
= properties_by_name
[pname
]
167 if globs
.length
> 1 then
168 v
.error
(prop
.node
, "Name error: {self} inherits {globs.length} global properties named {pname}.")
171 prop
.inherit_global
(g
)
174 if prop
.global
== null then
175 #print "{prop.full_name} is an introduction"
177 prop
.global
.is_init
= prop
.node
isa AConcreteInitPropdef
182 redef class MMConcreteProperty
183 private meth accept_property_visitor
(v
: AbsSyntaxVisitor)
187 # Concrete NIT class specialization relation
190 # The related AST node
191 readable attr _node
: ASuperclass
192 redef readable attr _local_class
: MMLocalClass
194 init(n
: ASuperclass, c
: MMLocalClass)
201 ###############################################################################
203 # A pass visitor for syntax analysis.
204 # * Build the classes and attach them to global classes
205 # * Collect generic formal parameters.
206 private class ClassBuilderVisitor
207 special AbsSyntaxVisitor
208 # Current class arity
209 readable writable attr _local_class_arity
: Int
211 # Current class formal parameters
212 readable writable attr _formals
: Map[Symbol, MMTypeFormalParameter]
214 redef meth visit
(n
) do n
.accept_class_builder
(self)
218 # Another pass visitor for syntax analysis.
219 # * Build ancertors (with only class informations not the type one)
220 private class ClassSpecializationBuilderVisitor
221 special AbsSyntaxVisitor
222 redef meth visit
(n
) do n
.accept_class_specialization_builder
(self)
226 # Another pass visitor for syntax analysis.
227 # * Compute types in ancestors
228 private class ClassAncestorBuilder
229 special AbsSyntaxVisitor
230 redef meth visit
(n
) do n
.accept_class_ancestor_builder
(self)
234 # Another pass visitor for syntax analysis.
235 # * Checks classes in regard to superclasses
236 private class ClassVerifierVisitor
237 special AbsSyntaxVisitor
238 redef meth visit
(n
) do n
.accept_class_verifier
(self)
243 # Another pass visitor for syntax analysis.
244 # * Build propertie names
245 # * Build local properties and attache them to global properties
246 # * Attach bound to formal types
247 private class PropertyBuilderVisitor
248 special AbsSyntaxVisitor
249 redef meth visit
(n
) do n
.accept_property_builder
(self)
253 # Another pass pass visitor for syntax analysis.
254 # * Check property conformance
255 private class PropertyVerifierVisitor
256 special AbsSyntaxVisitor
257 # Current visited parameter types
258 readable writable attr _params
: Array[PParam]
260 # Visited parameters without type information added
261 readable writable attr _untyped_params
: Array[PParam]
263 # Position of the current star parameter
264 readable writable attr _vararg_rank
: Int
267 readable writable attr _signature
: MMSignature
269 redef meth visit
(n
) do n
.accept_property_verifier
(self)
274 ###############################################################################
277 private meth accept_class_builder
(v
: ClassBuilderVisitor) do accept_abs_syntax_visitor
(v
)
278 private meth accept_class_specialization_builder
(v
: ClassSpecializationBuilderVisitor) do accept_abs_syntax_visitor
(v
)
279 private meth accept_class_ancestor_builder
(v
: ClassAncestorBuilder) do accept_abs_syntax_visitor
(v
)
280 private meth accept_class_verifier
(v
: ClassVerifierVisitor) do accept_abs_syntax_visitor
(v
)
281 private meth accept_property_builder
(v
: PropertyBuilderVisitor) do accept_abs_syntax_visitor
(v
)
282 private meth accept_property_verifier
(v
: PropertyVerifierVisitor) do accept_abs_syntax_visitor
(v
)
286 # Import supermodules and compute visibility
287 meth import_super_modules
(tc
: ToolContext, mod
: MMSrcModule)
289 # Import super-modules
290 var module_names_to_import
= new Array[Symbol]
291 var module_visibility
= new HashMap[Symbol, Int]
292 var no_import
: PImport
293 for i
in n_imports
do
294 var n
= i
.module_name
296 module_names_to_import
.add
(n
)
297 module_visibility
[n
] = i
.visibility_level
302 if no_import
!= null then
303 if not module_names_to_import
.is_empty
then
304 tc
.error
("{no_import.locate}: Error: Top modules cannot import other modules.")
306 else if module_names_to_import
.is_empty
then
307 var stdname
= once
"standard".to_symbol
308 module_names_to_import
.add
(stdname
)
309 module_visibility
[stdname
] = 1
312 mod
.import_supers_modules
(module_names_to_import
)
314 for mname
in module_names_to_import
do
315 var level
= module_visibility
[mname
]
316 var m
= tc
.get_module
(mname
, mod
)
317 mod
.add_super_module
(m
, level
)
322 redef class APackagedecl
323 redef meth accept_class_builder
(v
)
325 if n_id
.to_symbol
!= v
.module.name
then
326 v
.error
(n_id
, "Error: Package name missmatch between {v.module.name} and {n_id.to_symbol}")
332 # Imported module name (or null)
333 meth module_name
: Symbol is abstract
335 # Visibility level (intrude/public/private)
336 meth visibility_level
: Int is abstract
339 redef meth module_name
341 return n_id
.to_symbol
343 redef meth visibility_level
345 return n_visibility
.level
348 redef class ANoImport
349 redef meth module_name
355 redef class PVisibility
357 meth level
: Int is abstract
359 redef class APublicVisibility
360 redef meth level
do return 1
362 redef class AProtectedVisibility
363 redef meth level
do return 2
365 redef class APrivateVisibility
366 redef meth level
do return 3
368 redef class AIntrudeVisibility
369 redef meth level
do return 0
373 redef class PClassdef
374 redef readable attr _local_class
: MMSrcLocalClass
377 meth name
: Symbol is abstract
379 # Number of formal parameters
380 meth arity
: Int do return 0
382 # Visibility of the class
383 meth visibility_level
: Int do return 1
385 redef meth accept_class_builder
(v
)
387 var local_class
: MMSrcLocalClass
389 var local_classes
= mod
.src_local_classes
390 if (local_classes
.has_key
(name
)) then
391 local_class
= local_classes
[name
]
392 if self isa AClassdef then
393 # If we are not a special implicit class then rant
394 v
.error
(self, "Error: A class {name} is already defined at line {local_class.nodes.first.first_token.line}.")
397 local_class
.nodes
.add
(self)
399 local_class
= new MMSrcLocalClass(name
, self, arity
)
400 mod
.add_local_class
(local_class
)
401 local_classes
[name
] = local_class
402 var g
= mod
.global_class_named
(name
)
405 local_class
.new_global
406 g
= local_class
.global
408 local_class
.set_global
(g
)
412 _local_class
= local_class
413 v
.local_class_arity
= 0
414 v
.formals
= new HashMap[Symbol, MMTypeFormalParameter]
420 _local_class
.formal_dict
= v
.formals
424 redef meth accept_abs_syntax_visitor
(v
)
426 v
.local_class
= _local_class
432 redef class PClasskind
433 meth is_interface
: Bool do return false
434 meth is_universal
: Bool do return false
435 meth is_abstract
: Bool do return false
438 redef class AInterfaceClasskind
439 redef meth is_interface
do return true
441 redef class AUniversalClasskind
442 redef meth is_universal
do return true
444 redef class AAbstractClasskind
445 redef meth is_abstract
do return true
448 redef class AClassdef
451 return n_id
.to_symbol
455 return n_formaldefs
.length
457 redef meth accept_class_verifier
(v
)
460 var glob
= _local_class
.global
461 if glob
.intro
== _local_class
then
463 glob
.visibility_level
= visibility_level
464 glob
.is_interface
= n_classkind
.is_interface
465 glob
.is_abstract
= n_classkind
.is_abstract
466 glob
.is_universal
= n_classkind
.is_universal
467 if n_kwredef
!= null then
468 v
.error
(self, "Redef error: No class {name} is imported. Remove the redef keyword to define a new class.")
471 for c
in _local_class
.cshe
.direct_greaters
do
473 if glob
.is_interface
then
474 if cg
.is_universal
then
475 v
.error
(self, "Special error: Interface {name} try to specialise universal class {c.name}.")
476 else if not cg
.is_interface
then
477 v
.error
(self, "Special error: Interface {name} try to specialise class {c.name}.")
479 else if glob
.is_universal
then
480 if not cg
.is_interface
and not cg
.is_universal
then
481 v
.error
(self, "Special error: Universal class {name} try to specialise class {c.name}.")
484 if cg
.is_universal
then
485 v
.error
(self, "Special error: Class {name} try to specialise universal class {c.name}.")
495 glob
.check_visibility
(v
, self, v
.module)
496 if n_kwredef
== null then
497 v
.error
(self, "Redef error: {name} is an imported class. Add the redef keyword to refine it.")
501 if glob
.intro
.arity
!= _local_class
.arity
then
502 v
.error
(self, "Redef error: Formal parameter arity missmatch; got {_local_class.arity}, expected {glob.intro.arity}.")
506 not glob
.is_interface
and n_classkind
.is_interface
or
507 not glob
.is_abstract
and n_classkind
.is_abstract
or
508 not glob
.is_universal
and n_classkind
.is_universal
510 v
.error
(self, "Redef error: cannot change kind of class {name}.")
514 redef meth visibility_level
516 return n_visibility
.level
520 redef class AMainClassdef
523 return once
"Sys".to_symbol
527 redef class ATopClassdef
530 return once
"Object".to_symbol
534 class MMSrcTypeFormalParameter
535 special MMTypeFormalParameter
536 # The associated node
537 readable attr _node
: AFormaldef
539 init(name
: Symbol, pos
: Int, local_class
: MMLocalClass, n
: AFormaldef)
541 super(name
, pos
, local_class
)
546 redef class AFormaldef
547 # The associated formal generic parameter (MM entity)
548 attr _formal
: MMSrcTypeFormalParameter
550 redef meth accept_class_builder
(v
)
552 var name
= n_id
.to_symbol
553 var formal_type
= new MMSrcTypeFormalParameter(name
, v
.local_class_arity
, v
.local_class
, self)
554 _formal
= formal_type
555 v
.local_class_arity
= v
.local_class_arity
+ 1
556 v
.local_class
.register_formal
(formal_type
)
557 v
.formals
[name
] = formal_type
561 redef meth accept_class_verifier
(v
)
564 var c
= v
.local_class
565 var o
= c
.global
.intro
567 if n_type
== null then
568 _formal
.bound
= v
.module.type_any
570 _formal
.bound
= n_type
.get_stype
(v
)
573 var ob
= o
.get_formal
(_formal
.position
).bound
.for_module
(v
.module)
574 if n_type
== null then
577 _formal
.bound
= n_type
.get_stype
(v
)
578 if _formal
.bound
!= ob
then
579 v
.error
(self, "Redef error: Cannot change formal parameter type of class {c}; got {_formal.bound}, expected {ob}.")
586 redef class ASuperclass
587 readable attr _ancestor
: MMSrcAncestor
589 redef meth accept_class_specialization_builder
(v
)
592 var c
= n_type
.get_local_class
(v
)
593 var ancestor
= new MMSrcAncestor(self, c
)
595 v
.local_class
.add_direct_parent
(ancestor
)
598 redef meth accept_class_ancestor_builder
(v
)
601 _ancestor
.stype
= n_type
.get_unchecked_stype
(v
)
602 _ancestor
.inheriter
= v
.local_class
.get_type
605 redef meth accept_class_verifier
(v
)
608 n_type
.check_conform
(v
)
613 # Process and check properties of the property.
614 # * Distinguish inits and methods
615 # * Inherit or check visibility.
616 # * Check redef errors.
617 # * Check forbiden attribute definitions.
618 # * Check signature conformance.
619 private meth process_and_check
(v
: PropertyVerifierVisitor, prop
: MMConcreteProperty, has_redef
: Bool, visibility_level
: Int)
621 if prop
.global
.intro
== prop
then
622 do_and_check_intro
(v
, prop
, has_redef
, visibility_level
)
624 do_and_check_redef
(v
, prop
, has_redef
, visibility_level
)
628 # The part of process_and_check when prop is an introduction
629 private meth do_and_check_intro
(v
: PropertyVerifierVisitor, prop
: MMConcreteProperty, has_redef
: Bool, visibility_level
: Int)
631 var glob
= prop
.global
632 var gbc
= prop
.local_class
.global
633 if v
.local_class
.global
.visibility_level
>= 3 then
634 # Method of private classes are private
637 glob
.visibility_level
= visibility_level
638 if has_redef
and not glob
.is_init
then
639 v
.error
(self, "Error: No property {prop.local_class}::{prop} is inherited. Remove the redef keyword to define a new property.")
641 if glob
.is_attribute
then
642 if gbc
.is_interface
then
643 v
.error
(self, "Error: Attempt to define attribute {prop} in the interface {prop.local_class}.")
644 else if gbc
.is_universal
then
645 v
.error
(self, "Error: Attempt to define attribute {prop} in the universal class {prop.local_class}.")
647 else if glob
.is_init
then
648 if gbc
.is_interface
then
649 v
.error
(self, "Error: Attempt to define a constructor {prop} in the class {prop.local_class}.")
650 else if gbc
.is_universal
then
651 v
.error
(self, "Error: Attempt to define a constructor {prop} in the universal {prop.local_class}.")
654 if prop
.signature
== null then
656 var supers
= prop
.local_class
.super_methods_named
(prop
.name
)
657 inherit_signature
(v
, prop
, supers
)
659 if prop
.signature
!= null then
661 else if not v
.untyped_params
.is_empty
then
662 v
.error
(v
.untyped_params
.first
, "Error: Untyped parameter.")
664 prop
.signature
= new MMSignature(new Array[MMType], null, v
.local_class
.get_type
)
669 private meth inherit_signature
(v
: PropertyVerifierVisitor, prop
: MMConcreteProperty, supers
: Array[MMLocalProperty])
671 var s
= prop
.signature
673 var isig
= ip
.signature
.adaptation_to
(v
.local_class
.get_type
)
676 if v
.params
.length
!= isig
.arity
then
677 prop
.node
.printl
("v.params.length {v.params.length} != isig.arity {isig.arity} ; {prop.full_name} vs {ip.full_name}")
681 var t
= isig
[p
.position
]
683 if p
.position
== isig
.vararg_rank
then
695 # The part of process_and_check when prop is a redefinition
696 private meth do_and_check_redef
(v
: PropertyVerifierVisitor, prop
: MMConcreteProperty, has_redef
: Bool, visibility_level
: Int)
698 var is_init
= self isa AConcreteInitPropdef
699 var glob
= prop
.global
701 if not has_redef
and prop
.name
!= once
"init".to_symbol
then
702 v
.error
(self, "Redef error: {prop.local_class}::{prop} is an inherited property. To redefine it, add the redef keyword.")
705 if glob
.is_init
and not is_init
then
706 v
.error
(self, "Redef error: A method {prop.local_class}::{prop} cannot redefine a constructor.")
707 else if not glob
.is_init
and is_init
then
708 v
.error
(self, "Redef error: A constructor {prop.local_class}::{prop} cannot redefine a method.")
711 var s
= prop
.signature
712 #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}"
713 for i
in prop
.cprhe
.direct_greaters
do
714 var ip
= i
.local_class
[prop
.global
]
715 var isig
= i
.signature
.adaptation_to
(v
.local_class
.get_type
)
718 #print "{prop.full_name} inherits signature from {ip.full_name}"
719 if v
.params
.length
!= isig
.arity
then
720 v
.error
(self, "Redef error: {prop.local_class}::{prop} redefines {ip.local_class}::{ip} with {isig.arity} parameter(s).")
724 var t
= isig
[p
.position
]
726 if p
.position
== isig
.vararg_rank
then
735 #print "orig signature: {i.signature.recv} . {i.signature}"
736 #print "inh signature: {isig.recv} . {isig}"
737 #print "redef signature: {s.recv} . {s}"
739 if glob
.is_init
and i
.local_class
.global
!= prop
.local_class
.global
then
740 # Do not check signature
741 else if s
.arity
!= isig
.arity
then
742 v
.error
(self, "Redef error: {prop.local_class}::{prop} redefines {ip.local_class}::{ip} with {isig.arity} parameter(s).")
744 for i
in [0..s
.arity
[ do
745 if s
[i
] != isig
[i
] then
746 v
.error
(self, "Redef error: Expected {isig[i]} (as in {ip.local_class}::{ip}), got {s[i]} in {prop.local_class}::{prop}.")
751 var srt
= s
.return_type
752 var isrt
= isig
.return_type
753 if srt
== null and isrt
!= null then
754 v
.error
(self, "Redef error: The procedure {prop.local_class}::{prop} redefines the function {ip.local_class}::{ip}.")
755 else if srt
!= null and isrt
== null then
756 v
.error
(self, "Redef error: The function {prop.local_class}::{prop} redefines the procedure {ip.local_class}::{ip}.")
757 else if srt
!= null and isrt
!= null and not srt
< isrt
then
758 v
.error
(self, "Redef error: Expected {isrt} (as in {ip.local_class}::{ip}), got {srt} in {prop.local_class}::{prop}.")
759 else if srt
!= null and isrt
!= null and srt
!= isrt
and prop
isa MMAttribute then
761 v
.warning
(self, "Redef warning: Expected {isrt} (as in {ip.local_class}::{ip}), got {srt} in {prop.local_class}::{prop}.")
765 if visibility_level
!= 1 and glob
.visibility_level
!= visibility_level
then
766 v
.error
(self, "Redef error: {prop.local_class}::{prop} redefinition cannot change visibility.")
768 glob
.check_visibility
(v
, self, v
.module, true)
772 redef class AAttrPropdef
773 redef readable attr _readmethod
: MMSrcMethod
774 redef readable attr _writemethod
: MMSrcMethod
775 redef readable attr _prop
: MMSrcAttribute
777 redef meth accept_property_builder
(v
)
780 var name
= n_id
.to_symbol
781 var prop
= new MMSrcAttribute(name
, v
.local_class
, self)
783 v
.local_class
.add_src_local_property
(v
, prop
)
785 if n_readable
!= null then
786 name
= n_id
.text
.substring_from
(1).to_symbol
787 _readmethod
= new MMReadImplementationMethod(name
, v
.local_class
, self)
788 v
.local_class
.add_src_local_property
(v
, _readmethod
)
790 if n_writable
!= null then
791 name
= (n_id
.text
.substring_from
(1) + "=").to_symbol
792 _writemethod
= new MMWriteImplementationMethod(name
, v
.local_class
, self)
793 v
.local_class
.add_src_local_property
(v
, _writemethod
)
797 redef meth accept_property_verifier
(v
)
801 if n_type
!= null then
802 t
= n_type
.get_stype
(v
)
804 v
.error
(self, "Not yet implemented: Attribute definition {_prop.local_class}::{_prop} requires an explicit type.")
808 var signature
= new MMSignature(new Array[MMType], t
, v
.local_class
.get_type
)
809 _prop
.signature
= signature
810 var visibility_level
= n_visibility
.level
811 process_and_check
(v
, _prop
, n_kwredef
!= null, visibility_level
)
812 if n_readable
!= null then
813 _readmethod
.signature
= signature
814 process_and_check
(v
, _readmethod
, n_readable
.n_kwredef
!= null, visibility_level
)
815 n_type
.check_visibility
(v
, _readmethod
)
817 if n_writable
!= null then
818 _writemethod
.signature
= new MMSignature(new Array[MMType].with
(t
), null, v
.local_class
.get_type
)
819 process_and_check
(v
, _writemethod
, n_writable
.n_kwredef
!= null, visibility_level
)
820 n_type
.check_visibility
(v
, _writemethod
)
824 redef meth accept_abs_syntax_visitor
(v
)
826 v
.local_property
= prop
828 v
.local_property
= null
832 redef class AMethPropdef
834 readable attr _name
: Symbol
836 redef readable attr _method
: MMMethSrcMethod
838 redef meth accept_property_builder
(v
)
841 if n_methid
== null then
842 if self isa AConcreteInitPropdef then
843 _name
= once
"init".to_symbol
845 _name
= once
"main".to_symbol
848 _name
= n_methid
.name
849 # FIXME: Add the 'unary' keyword
850 if n_methid
.name
== (once
"-".to_symbol
) then
852 if ns
isa ASignature and ns
.n_params
.length
== 0 then
853 _name
= once
"unary -".to_symbol
857 var prop
= new MMMethSrcMethod(_name
, v
.local_class
, self)
859 v
.local_class
.add_src_local_property
(v
, prop
)
862 redef meth accept_property_verifier
(v
)
864 v
.params
= new Array[PParam]
865 v
.untyped_params
= new Array[PParam]
871 if v
.signature
== null then
872 #_method.signature = new MMSignature(new Array[MMType], null, v.local_class.get_type)
874 _method
.signature
= v
.signature
876 var visibility_level
= 1
877 if n_visibility
!= null and n_visibility
.level
> 1 then
878 visibility_level
= n_visibility
.level
880 process_and_check
(v
, _method
, n_kwredef
!= null, visibility_level
)
881 if n_signature
!= null then n_signature
.check_visibility
(v
, _method
)
884 redef meth accept_abs_syntax_visitor
(v
)
886 v
.local_property
= method
888 v
.local_property
= null
892 redef class AMainMethPropdef
893 redef meth process_and_check
(v
, prop
, has_redef
, visibility_level
)
895 prop
.global
.visibility_level
= visibility_level
896 prop
.signature
= new MMSignature(new Array[MMType], null, v
.local_class
.get_type
)
897 # Disable all checks for main
901 redef class ATypePropdef
902 redef readable attr _prop
: MMSrcTypeProperty
904 redef meth accept_property_builder
(v
)
907 var name
= n_id
.to_symbol
908 var prop
= new MMSrcTypeProperty(name
, v
.local_class
, self)
910 v
.local_class
.add_src_local_property
(v
, prop
)
913 redef meth accept_property_verifier
(v
)
916 var signature
= new MMSignature(new Array[MMType], n_type
.get_stype
(v
), v
.local_class
.get_type
)
917 _prop
.signature
= signature
918 var visibility_level
= n_visibility
.level
919 process_and_check
(v
, _prop
, n_kwredef
!= null, visibility_level
)
922 redef meth accept_abs_syntax_visitor
(v
)
924 v
.local_property
= prop
926 v
.local_property
= null
930 # Visitor used to build a full method name from multiple tokens
931 private class MethidAccumulator
933 readable attr _name
: String
951 readable attr _name
: Symbol
953 redef meth accept_property_builder
(v
)
955 var accumulator
= new MethidAccumulator
956 accumulator
.visit
(self)
957 _name
= accumulator
.name
.to_symbol
962 redef class PSignature
963 # Check that visibilities of types in the signature are compatible with the visibility of the property.
964 meth check_visibility
(v
: AbsSyntaxVisitor, p
: MMConcreteProperty) is abstract
967 redef class ASignature
968 redef meth accept_property_verifier
(v
)
971 if not v
.untyped_params
.is_empty
then
972 if v
.untyped_params
.first
!= v
.params
.first
or n_type
!= null then
973 v
.error
(v
.untyped_params
.first
, "Syntax error: untyped parameter.")
976 else if not v
.params
.is_empty
or n_type
!= null then
977 var pars
= new Array[MMType]
981 var ret
: MMType = null
982 if n_type
!= null then
983 ret
= n_type
.get_stype
(v
)
985 v
.signature
= new MMSignature(pars
, ret
, v
.local_class
.get_type
)
986 if v
.vararg_rank
>= 0 then
987 v
.signature
.vararg_rank
= v
.vararg_rank
992 redef meth check_visibility
(v
, p
)
994 if p
.global
.visibility_level
>= 3 then return
996 if n
.n_type
!= null then n
.n_type
.check_visibility
(v
, p
)
998 if n_type
!= null then n_type
.check_visibility
(v
, p
)
1003 redef readable attr _position
: Int
1005 redef readable attr _variable
: Variable
1007 # The type of the parameter in signature
1008 readable writable attr _stype
: MMType
1010 redef meth accept_property_verifier
(v
)
1013 _position
= v
.params
.length
1014 _variable
= new Variable(n_id
.to_symbol
, self)
1016 v
.untyped_params
.add
(self)
1017 if n_type
!= null then
1018 var stype
= n_type
.get_stype
(v
)
1019 for p
in v
.untyped_params
do
1022 if v
.vararg_rank
== -1 then
1023 v
.vararg_rank
= p
.position
1025 v
.error
(self, "Error: A vararg parameter is already defined.")
1027 stype
= v
.type_array
(stype
)
1029 p
.variable
.stype
= stype
1031 v
.untyped_params
.clear
1035 meth is_vararg
: Bool is abstract
1039 redef meth is_vararg
do return n_dotdotdot
!= null
1043 # Check that visibilities of types in the signature are compatible with the visibility of the property.
1044 private meth check_visibility
(v
: AbsSyntaxVisitor, p
: MMConcreteProperty) is abstract
1048 redef meth check_visibility
(v
, p
)
1050 if p
.global
.visibility_level
>= 3 then return
1051 var t
= get_stype
(v
)
1052 if t
== null then return
1053 var bc
= t
.local_class
1054 if bc
== null then return
1055 if bc
.global
.visibility_level
>= 3 then
1056 v
.error
(self, "Access error: Class {bc} is private and cannot be used in the signature of the non-private property {p}.")
1059 n
.check_visibility
(v
, p
)
1065 redef meth accept_class_builder
(v
) do end
1066 redef meth accept_property_builder
(v
) do end
1067 redef meth accept_property_verifier
(v
) do end