import typing
import modelbuilder
+import phase
+
+redef class ToolContext
+ var auto_super_init_phase: Phase = new AutoSuperInitPhase(self, [typing_phase])
+end
+
+private class AutoSuperInitPhase
+ super Phase
+ redef fun process_npropdef(npropdef) do if npropdef isa AConcreteMethPropdef then npropdef.do_auto_super_init(toolcontext.modelbuilder)
+end
private class AutoSuperInitVisitor
super Visitor
import parser
import toolcontext
import scope
+import phase
+
+redef class ToolContext
+ var flow_phase: Phase = new FlowPhase(self, [scope_phase])
+end
+
+private class FlowPhase
+ super Phase
+
+ redef fun process_npropdef(npropdef) do npropdef.do_flow(toolcontext)
+end
# The visitor that derermine flowcontext for nodes
private class FlowVisitor
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Collect and orchestration of main frontend phases
+module frontend
+
+import phase
+import simple_misc_analysis
+import literal
+import scope
+import flow
+import local_var_init
+import typing
+import auto_super_init
+import div_by_zero
+
+redef class ToolContext
+ # FIXME: there is conflict in linex in nitc, so use this trick to force invocation
+ private var dummy: Bool = do_dummy
+ fun do_dummy: Bool
+ do
+ # Force easy warnings before intraproc-errors
+ phases.add_edge(scope_phase, simple_misc_analysis_phase)
+ return true
+ end
+end
import parser
import toolcontext
+import phase
+
+import modelbuilder #FIXME useless
+
+redef class ToolContext
+ var literal_phase: Phase = new LiteralPhase(self, null)
+end
+
+private class LiteralPhase
+ super Phase
+
+ redef fun process_nmodule(nmodule) do nmodule.do_literal(toolcontext)
+end
redef class AModule
# Visit the module to compute the real value of the literal-related node of the AST.
import scope
import flow
+import phase
+
+redef class ToolContext
+ var local_var_init_phase: Phase = new LocalVarInitPhase(self, [flow_phase])
+end
+
+private class LocalVarInitPhase
+ super Phase
+
+ redef fun process_npropdef(npropdef) do npropdef.do_local_var_init(toolcontext)
+end
redef class APropdef
# Entry point of the whole local variable initialization verifier
import poset
import opts
import toolcontext
+import phase
###
# The toolcontext used to control the interaction with the user (getting options and displaying messages)
var toolcontext: ToolContext
+ fun run_phases
+ do
+ var mmodules = model.mmodules.to_a
+ model.mmodule_importation_hierarchy.sort(mmodules)
+ var nmodules = new Array[AModule]
+ for mm in mmodules do
+ nmodules.add(mmodule2nmodule[mm])
+ end
+ toolcontext.run_phases(nmodules)
+ end
+
# Instantiate a modelbuilder for a model and a toolcontext
# Important, the options of the toolcontext must be correctly set (parse_option already called)
init(model: Model, toolcontext: ToolContext)
module nit
import modelbuilder
-import exprbuilder
+import frontend
import naive_interpreter
import debugger
#import interpretor_type_test
# Here we load an process all modules passed on the command line
var mmodules = modelbuilder.parse_and_build([progname])
-modelbuilder.full_propdef_semantic_analysis
+modelbuilder.run_phases
if toolcontext.opt_only_metamodel.value then exit(0)
module nitg
import modelbuilder
-import exprbuilder
+import frontend
import rapid_type_analysis
import global_compiler
import separate_erasure_compiler
# Here we load an process all modules passed on the command line
var mmodules = modelbuilder.parse_and_build([progname])
if mmodules.is_empty then return
-modelbuilder.full_propdef_semantic_analysis
+modelbuilder.run_phases
if toolcontext.opt_only_metamodel.value then exit(0)
module nitmetrics
import modelbuilder
-import exprbuilder
+import frontend
import metrics
# Create a tool context to handle options and paths
# Here we load an process all modules passed on the command line
var mmodules = modelbuilder.parse_and_build(arguments)
-modelbuilder.full_propdef_semantic_analysis
+modelbuilder.run_phases
if mmodules.length == 0 then return
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Phases of the processing of nit programs
+module phase
+
+import toolcontext
+import parser
+import poset
+
+redef class ToolContext
+ # The various registered phases to performs
+ # The order in the poset is the dependance of phases
+ #
+ # While you can directly modify the poset (nodes and edges),
+ # it is often simpler to use the constructor in `Phase`
+ var phases = new POSet[Phase]
+
+ # Run all registered phases on a set of modules
+ fun run_phases(nmodules: Collection[AModule])
+ do
+ var time0 = get_time
+ self.info("*** SEMANTIC ANALYSIS ***", 1)
+ #phases.show_dot
+ var phases = self.phases.to_a
+ self.phases.sort(phases)
+
+ for phase in phases do
+ self.info(" registered phases: {phase.class_name}", 2)
+ end
+
+ for nmodule in nmodules do
+ self.info("Semantic analysis module {nmodule.location.file.filename}", 2)
+ for phase in phases do
+ self.info(" phase: {phase.class_name}", 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
+ for npropdef in nclassdef.n_propdefs do
+ self.info(" phase: {phase.class_name} for {npropdef.location}", 4)
+ assert phase.toolcontext == self
+ phase.process_npropdef(npropdef)
+ end
+ end
+ if errcount != self.error_count then
+ self.check_errors
+ break
+ end
+ end
+ self.check_errors
+ end
+
+ var time1 = get_time
+ self.info("*** END SEMANTIC ANALYSIS: {time1-time0} ***", 2)
+ end
+end
+
+# Abstraction of steps in the analysis/processing of Nit programs
+# Specific phases should implements either `process_nmodule` or
+# `process_npropdef`.
+abstract class Phase
+ # The toolcontext instance attached to the phase
+ var toolcontext: ToolContext
+
+ # The dependence relation of the phase with the other phases
+ var in_hierarchy: POSetElement[Phase]
+
+ # Initialize and register a phase to the toolcontext
+ init(toolcontext: ToolContext, depends: nullable Collection[Phase])
+ do
+ self.toolcontext = toolcontext
+ in_hierarchy = toolcontext.phases.add_node(self)
+ if depends != null then
+ for d in depends do
+ toolcontext.phases.add_edge(self, d)
+ end
+ end
+ end
+
+ # Specific actions to execute on the whole tree of a module
+ # @toimplement
+ fun process_nmodule(nmodule: AModule) do end
+
+ # Specific actions to execute on the tree of a property
+ # Note that the order of the visit is the one of the file
+ # @toimplement
+ fun process_npropdef(npropdef: APropdef) do end
+end
import parser
import toolcontext
+import phase
+
+import modelbuilder #FIXME useless
+
+redef class ToolContext
+ var scope_phase: Phase = new ScopePhase(self, null)
+end
+
+private class ScopePhase
+ super Phase
+ redef fun process_npropdef(npropdef) do npropdef.do_scope(toolcontext)
+end
+
# A local variable (including parameters, automatic variables and self)
class Variable
import toolcontext
import parser
+import phase
+
+import modelbuilder #FIXME useless
+
+redef class ToolContext
+ var simple_misc_analysis_phase: Phase = new SimpleMiscAnalysisPhase(self, null)
+end
+
+private class SimpleMiscAnalysisPhase
+ super Phase
+ redef fun process_nmodule(nmodule) do nmodule.do_simple_misc_analysis(toolcontext)
+end
redef class AModule
# Visit the module to detect easy warnings that does not need the metamodel or the importation
import flow
import modelbuilder
+import phase
+import local_var_init
+
+redef class ToolContext
+ var typing_phase: Phase = new TypingPhase(self, [flow_phase, local_var_init_phase])
+end
+
+private class TypingPhase
+ super Phase
+ redef fun process_npropdef(npropdef) do npropdef.do_typing(toolcontext.modelbuilder)
+end
private class TypeVisitor
var modelbuilder: ModelBuilder