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 # Phases of the processing of nit programs
22 redef class ToolContext
23 # The various registered phases to performs
24 # The order in the poset is the dependance of phases
26 # While you can directly modify the poset (nodes and edges),
27 # it is often simpler to use the constructor in `Phase`
28 var phases
= new POSet[Phase]
31 var opt_disable_phase
= new OptionArray("DEBUG: Disable a specific phase; use `list` to get the list.", "--disable-phase")
37 option_context
.add_option
(opt_disable_phase
)
40 redef fun process_options
(args
)
44 for v
in opt_disable_phase
.value
do
46 for p
in phases_list
do
47 var deps
= p
.in_hierarchy
.direct_greaters
51 print
"{p} (dep: {deps.join(", ")})"
59 if v
!= p
.to_s
then continue
63 if not found
then fatal_error
(null, "Error: no phase named `{v}`. Use `list` to list all phases.")
67 fun phases_list
: Sequence[Phase]
69 var phases
= self.phases
.to_a
70 self.phases
.sort
(phases
)
74 # Run all registered phases on a set of modules
75 fun run_phases
(nmodules
: Collection[AModule])
78 self.info
("*** SEMANTIC ANALYSIS ***", 1)
81 var phases
= phases_list
83 for phase
in phases
do
84 self.info
(" registered phases: {phase}", 2)
87 for nmodule
in nmodules
do
88 self.info
("Semantic analysis module {nmodule.location.file.filename}", 2)
89 for phase
in phases
do
90 if phase
.disabled
then continue
91 self.info
(" phase: {phase}", 3)
92 assert phase
.toolcontext
== self
93 var errcount
= self.error_count
94 phase
.process_nmodule
(nmodule
)
95 if errcount
!= self.error_count
then
99 errcount
= self.error_count
100 for nclassdef
in nmodule
.n_classdefs
do
101 self.info
(" phase: {phase} for {nclassdef.location}", 3)
102 assert phase
.toolcontext
== self
103 phase
.process_nclassdef
(nclassdef
)
104 for npropdef
in nclassdef
.n_propdefs
do
105 assert phase
.toolcontext
== self
106 phase
.process_npropdef
(npropdef
)
109 if errcount
!= self.error_count
then
113 var v
= new AnnotationPhaseVisitor(phase
)
114 v
.enter_visit
(nmodule
)
115 if errcount
!= self.error_count
then
124 self.info
("*** END SEMANTIC ANALYSIS: {time1-time0} ***", 2)
128 private class AnnotationPhaseVisitor
133 init(phase
: Phase) do self.phase
= phase
138 if n
isa AAnnotation then phase
.process_annotated_node
(n
.parent
.parent
.as(not null), n
)
142 # Abstraction of steps in the analysis/processing of Nit programs
143 # Specific phases should implements one of the `process_*` method
145 # The toolcontext instance attached to the phase
146 var toolcontext
: ToolContext
148 # The dependence relation of the phase with the other phases
149 var in_hierarchy
: POSetElement[Phase]
151 # Initialize and register a phase to the toolcontext
152 init(toolcontext
: ToolContext, depends
: nullable Collection[Phase])
154 self.toolcontext
= toolcontext
155 in_hierarchy
= toolcontext
.phases
.add_node
(self)
156 if depends
!= null then
158 toolcontext
.phases
.add_edge
(self, d
)
163 # By default, the name is the lowercased prefix of the classname
164 redef fun to_s
do return class_name
.strip_extension
("Phase").to_lower
166 # Is the phase globally disabled?
167 # A disabled phase is not called automatically called by `ToolContext::run_phases` and cie.
170 # Specific actions to execute on the whole tree of a module
172 fun process_nmodule
(nmodule
: AModule) do end
174 # Specific actions to execute on the tree of a class definition
175 # Note that the order of the visit is the one of the file
177 fun process_nclassdef
(nclassdef
: AClassdef) do end
179 # Specific actions to execute on the tree of a property
180 # Note that the order of the visit is the one of the file
182 fun process_npropdef
(npropdef
: APropdef) do end
184 # Specific actions to execute on annotated nodes
185 # Note that the order of the visit is the one of the file
187 fun process_annotated_node
(node
: ANode, nat
: AAnnotation) do end