1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 # Simple visitor framework for Nit models.
17 # This module provides the `ModelVisitor` abstract class and
18 # refines the classes of the `MEntity` hierarchy to add visiting related methods.
20 # A standard approach on complex visitor is to dispatch the `ModelVisitor::visit` on the
21 # entities to do specific things.
26 # redef fun visit(e) do e.foo_visit(self)
31 # fun foo_vist(v: FooVisitor) do visit_all(v)
36 # redef fun foo_visit(v) do
46 # The abstract model visitor template.
48 # Specific visitor must implement the `visit` method to perform the work.
49 abstract class ModelVisitor
51 # Visit the entity `e`.
53 # This method setups `current_entity` and call `visit`.
54 # If `e` is null, nothing is done.
55 fun enter_visit
(e
: nullable MEntity) do
56 if e
== null then return
57 if not accept_mentity
(e
) then return
58 var old_entity
= current_entity
61 current_entity
= old_entity
64 # The current visited entity
65 var current_entity
: nullable MEntity = null
67 # Method to define in specific visitor.
69 # It should not be called directly but used by `enter_visit`
70 protected fun visit
(e
: MEntity) is abstract
72 # Filters to apply when visiting the model.
74 # See ModelFilters for configuration.
75 var filter
: ModelFilter is lazy
, writable, optional
do
76 return new ModelFilter(
77 min_visibility
= protected_visibility
,
78 accept_fictive
= false,
80 accept_example
= false,
83 accept_attribute
= true,
84 accept_empty_doc
= true
88 # Should we accept this `mentity` from the view?
90 # If no `override_filter` is passed then use `self.filter`.
91 fun accept_mentity
(mentity
: MEntity, override_filter
: nullable ModelFilter): Bool do
92 if override_filter
!= null then
93 return override_filter
.accept_mentity
(mentity
)
95 return filter
.accept_mentity
(mentity
)
100 # Call `v.enter_visit` on all nested entities.
102 # See the specific implementation in the subclasses.
103 fun visit_all
(v
: ModelVisitor) do end
107 # Visit all the packages of the model.
108 redef fun visit_all
(v
) do
109 for x
in mpackages
do v
.enter_visit
(x
)
114 # Visit the root group of the package.
115 redef fun visit_all
(v
) do
121 # Visit all the subgroups and modules of the group.
122 redef fun visit_all
(v
) do
123 for x
in in_nesting
.direct_smallers
do v
.enter_visit
(x
)
124 for x
in mmodules
do v
.enter_visit
(x
)
129 # Visit all the classes and class definitions of the module.
131 # On class introduction, the `MClass` then the `MClassDef` are visited.
132 # On class refinement, only the `MClassDef` is visited (the `MClass` is visited in an imported module).
133 # On class importation, nothing is visited (the `MClass` and the `MClassDef` are visited in imported modules).
134 redef fun visit_all
(v
) do
135 for x
in mclassdefs
do
136 if x
.is_intro
then v
.enter_visit
(x
.mclass
)
142 redef class MClassDef
143 # Visit all the classes and class definitions of the module.
145 # On property introduction, the `MProperty` then the `MPropDef` are visited.
146 # On property redefinition, only the `MPropDef` is visited (the `MProperty` is visited in an inherited class).
147 # On property inheritance, nothing is visited (the `MProperty` and the `MPropDef` are visited in inherited classes).
148 redef fun visit_all
(v
) do
149 for x
in mpropdefs
do
150 if x
.is_intro
then v
.enter_visit
(x
.mproperty
)