redef class ToolContext
# The various registered phases to performs
- # The order in the poset is the dependance of phases
+ # The order in the poset is the dependence of phases
#
# While you can directly modify the poset (nodes and edges),
# it is often simpler to use the constructor in `Phase`
end
end
+ # The list of registered phases in the application order.
fun phases_list: Sequence[Phase]
do
var phases = self.phases.to_a
return phases
end
+ # Set of already analyzed modules.
+ private var phased_modules = new HashSet[AModule]
+
# Run all registered phases on a set of modules
fun run_phases(nmodules: Collection[AModule])
do
end
for nmodule in nmodules do
+ if phased_modules.has(nmodule) then continue
+ phased_modules.add nmodule
+
self.info("Semantic analysis module {nmodule.location.file.filename}", 2)
+
+ var vannot = new AnnotationPhaseVisitor
+ vannot.enter_visit(nmodule)
+
for phase in phases do
if phase.disabled then continue
self.info(" phase: {phase}", 3)
end
errcount = self.error_count
for nclassdef in nmodule.n_classdefs do
- self.info(" phase: {phase} for {nclassdef.location}", 3)
assert phase.toolcontext == self
phase.process_nclassdef(nclassdef)
for npropdef in nclassdef.n_propdefs do
assert phase.toolcontext == self
- phase.process_npropdef(npropdef)
+ phase_process_npropdef(phase, npropdef)
end
end
if errcount != self.error_count then
self.check_errors
break
end
- var v = new AnnotationPhaseVisitor(phase)
- v.enter_visit(nmodule)
+ for na in vannot.annotations do
+ phase.process_annotated_node(na.parent.parent.as(not null), na)
+ end
if errcount != self.error_count then
self.check_errors
break
var time1 = get_time
self.info("*** END SEMANTIC ANALYSIS: {time1-time0} ***", 2)
+
+ errors_info
+ end
+
+ # Process the given `phase` on the `npropdef`
+ # Called by `run_phases`
+ protected fun phase_process_npropdef(phase: Phase, npropdef: APropdef)
+ do
+ phase.process_npropdef(npropdef)
end
end
+# Collect all annotation
private class AnnotationPhaseVisitor
super Visitor
- var phase: Phase
-
- init(phase: Phase) do self.phase = phase
+ # The collected annotations
+ var annotations = new Array[AAnnotation]
redef fun visit(n)
do
n.visit_all(self)
- if n isa AAnnotation then phase.process_annotated_node(n.parent.parent.as(not null), n)
+ if n isa AAnnotation then annotations.add n
end
end
var toolcontext: ToolContext
# The dependence relation of the phase with the other phases
- var in_hierarchy: POSetElement[Phase]
+ var in_hierarchy: POSetElement[Phase] is noinit
+
+ # The explicit dependences, used to initialize `in_importation`
+ var depends: nullable Collection[Phase]
# Initialize and register a phase to the toolcontext
- init(toolcontext: ToolContext, depends: nullable Collection[Phase])
+ init
do
- self.toolcontext = toolcontext
in_hierarchy = toolcontext.phases.add_node(self)
+ var depends = self.depends
if depends != null then
for d in depends do
toolcontext.phases.add_edge(self, d)
# Is the phase globally disabled?
# A disabled phase is not called automatically called by `ToolContext::run_phases` and cie.
- var disabled = false
+ #
+ # Warning: disabling a phase may cause subsequent phases to work in a degraded way or to fail.
+ var disabled = false is writable
# Specific actions to execute on the whole tree of a module
# @toimplement