X-Git-Url: http://nitlanguage.org diff --git a/src/phase.nit b/src/phase.nit index 1a10cf2..2a9d7b8 100644 --- a/src/phase.nit +++ b/src/phase.nit @@ -28,10 +28,10 @@ redef class ToolContext var phases = new POSet[Phase] # --disable-phase - var opt_disable_phase = new OptionArray("DEBUG: Disable a specific phase; use `list` to get the list.", "--disable-phase") + var opt_disable_phase = new OptionArray("Disable a specific phase; use `list` to get the list (debug)", "--disable-phase") - # --disable-phase - var opt_sloppy = new OptionBool("DEBUG: force lazy semantic analysis of the source-code", "--sloppy") + # --sloppy + var opt_sloppy = new OptionBool("Force lazy semantic analysis of the source-code (debug)", "--sloppy") redef init do @@ -86,6 +86,11 @@ redef class ToolContext # Set of already analyzed modules. private var phased_modules = new HashSet[AModule] + # List of module to process according to `run_phases` + # + # This allow some new modules to be found and added while analysing the code. + var todo_nmodules: Sequence[AModule] + # Run all registered phases on a set of modules fun run_phases(nmodules: Collection[AModule]) do @@ -99,7 +104,11 @@ redef class ToolContext self.info(" registered phases: {phase}", 2) end - for nmodule in nmodules do + var todo_nmodules = nmodules.to_a + self.todo_nmodules = todo_nmodules + + while not todo_nmodules.is_empty do + var nmodule = todo_nmodules.shift if phased_modules.has(nmodule) then continue phased_modules.add nmodule @@ -110,13 +119,11 @@ redef class ToolContext for phase in phases do if phase.disabled then continue - self.info(" phase: {phase}", 3) assert phase.toolcontext == self var errcount = self.error_count phase.process_nmodule(nmodule) if errcount != self.error_count then self.check_errors - break end errcount = self.error_count for nclassdef in nmodule.n_classdefs do @@ -129,15 +136,17 @@ redef class ToolContext end if errcount != self.error_count then self.check_errors - break end for na in vannot.annotations do - phase.process_annotated_node(na.parent.parent.as(not null), na) + var p = na.parent + if p isa AAnnotations then p = p.parent + assert p != null + phase.process_annotated_node(p, na) end if errcount != self.error_count then self.check_errors - break end + phase.process_nmodule_after(nmodule) end self.check_errors end @@ -145,7 +154,7 @@ redef class ToolContext var time1 = get_time self.info("*** END SEMANTIC ANALYSIS: {time1-time0} ***", 2) - errors_info + self.check_errors end # Process the given `phase` on the `npropdef` @@ -220,7 +229,7 @@ abstract class Phase end # By default, the name is the lowercased prefix of the classname - redef fun to_s do return class_name.strip_extension("Phase").to_lower + redef fun to_s do return class_name.strip_extension("Phase").to_snake_case # Is the phase globally disabled? # A disabled phase is not called automatically called by `ToolContext::run_phases` and cie. @@ -246,4 +255,10 @@ abstract class Phase # Note that the order of the visit is the one of the file # @toimplement fun process_annotated_node(node: ANode, nat: AAnnotation) do end + + # Specific actions to execute on the whole tree of a module + # Called at the end of a phase on a module + # Last called hook + # @toimplement + fun process_nmodule_after(nmodule: AModule) do end end