src: add phase.nit & frontend.nit
[nit.git] / src / phase.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
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
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
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.
14
15 # Phases of the processing of nit programs
16 module phase
17
18 import toolcontext
19 import parser
20 import poset
21
22 redef class ToolContext
23 # The various registered phases to performs
24 # The order in the poset is the dependance of phases
25 #
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]
29
30 # Run all registered phases on a set of modules
31 fun run_phases(nmodules: Collection[AModule])
32 do
33 var time0 = get_time
34 self.info("*** SEMANTIC ANALYSIS ***", 1)
35 #phases.show_dot
36 var phases = self.phases.to_a
37 self.phases.sort(phases)
38
39 for phase in phases do
40 self.info(" registered phases: {phase.class_name}", 2)
41 end
42
43 for nmodule in nmodules do
44 self.info("Semantic analysis module {nmodule.location.file.filename}", 2)
45 for phase in phases do
46 self.info(" phase: {phase.class_name}", 3)
47 assert phase.toolcontext == self
48 var errcount = self.error_count
49 phase.process_nmodule(nmodule)
50 if errcount != self.error_count then
51 self.check_errors
52 break
53 end
54 errcount = self.error_count
55 for nclassdef in nmodule.n_classdefs do
56 for npropdef in nclassdef.n_propdefs do
57 self.info(" phase: {phase.class_name} for {npropdef.location}", 4)
58 assert phase.toolcontext == self
59 phase.process_npropdef(npropdef)
60 end
61 end
62 if errcount != self.error_count then
63 self.check_errors
64 break
65 end
66 end
67 self.check_errors
68 end
69
70 var time1 = get_time
71 self.info("*** END SEMANTIC ANALYSIS: {time1-time0} ***", 2)
72 end
73 end
74
75 # Abstraction of steps in the analysis/processing of Nit programs
76 # Specific phases should implements either `process_nmodule` or
77 # `process_npropdef`.
78 abstract class Phase
79 # The toolcontext instance attached to the phase
80 var toolcontext: ToolContext
81
82 # The dependence relation of the phase with the other phases
83 var in_hierarchy: POSetElement[Phase]
84
85 # Initialize and register a phase to the toolcontext
86 init(toolcontext: ToolContext, depends: nullable Collection[Phase])
87 do
88 self.toolcontext = toolcontext
89 in_hierarchy = toolcontext.phases.add_node(self)
90 if depends != null then
91 for d in depends do
92 toolcontext.phases.add_edge(self, d)
93 end
94 end
95 end
96
97 # Specific actions to execute on the whole tree of a module
98 # @toimplement
99 fun process_nmodule(nmodule: AModule) do end
100
101 # Specific actions to execute on the tree of a property
102 # Note that the order of the visit is the one of the file
103 # @toimplement
104 fun process_npropdef(npropdef: APropdef) do end
105 end