1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2012 Jean Privat <jean@pryen.org>
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
22 private import more_collections
26 redef class ToolContext
27 # Option --ignore-visibility
28 var opt_ignore_visibility
= new OptionBool("Do not check, and produce errors, on visibility issues", "--ignore-visibility")
33 option_context
.add_option
(opt_ignore_visibility
)
36 # Combine module to make a single one if required.
37 fun make_main_module
(mmodules
: Array[MModule]): MModule
39 assert not mmodules
.is_empty
41 # We need a main module, so we build it by importing all modules
42 mainmodule
= new MModule(modelbuilder
.model
, null, mmodules
.first
.name
+ "-m", new Location(mmodules
.first
.location
.file
, 0, 0, 0, 0))
43 mainmodule
.is_fictive
= true
44 mainmodule
.first_real_mmodule
= mmodules
.first
.first_real_mmodule
45 mainmodule
.set_imported_mmodules
(mmodules
)
46 modelbuilder
.apply_conditional_importations
(mainmodule
)
47 if mainmodule
.in_importation
.direct_greaters
.length
== 1 and mainmodule
.in_importation
.direct_greaters
.first
== mmodules
.first
then
48 # Drop the fictive module if not needed
49 mainmodule
= mmodules
.first
51 # Or else run phases on it
52 modelbuilder
.run_phases
57 # Run `process_mainmodule` on all phases
58 fun run_global_phases
(mmodules
: Array[MModule])
60 if not mmodules
.is_empty
then
61 var mainmodule
= make_main_module
(mmodules
)
62 for phase
in phases_list
do
63 if phase
.disabled
then continue
64 phase
.process_mainmodule
(mainmodule
, mmodules
)
74 # Specific action to execute on the whole program.
75 # Called by the `ToolContext::run_global_phases`.
77 # `mainmodule` is the main module of the program.
78 # It could be an implicit module (called like the first given_mmodules).
80 # `given_modules` is the list of explicitely requested modules.
81 # from the command-line for instance.
83 # REQUIRE: `not given_modules.is_empty`
84 # REQUIRE: `(given_modules.length == 1) == (mainmodule == given_modules.first)`
87 fun process_mainmodule
(mainmodule
: MModule, given_mmodules
: SequenceRead[MModule]) do end
91 redef class ModelBuilder
92 # Run phases on all loaded modules
95 var mmodules
= parsed_modules
.to_a
96 model
.mmodule_importation_hierarchy
.sort
(mmodules
)
97 var nmodules
= new Array[AModule]
99 if mm
.is_fictive
then continue
100 nmodules
.add
(mmodule2node
(mm
).as(not null))
102 toolcontext
.run_phases
(nmodules
)
104 if toolcontext
.opt_only_metamodel
.value
then
105 self.toolcontext
.info
("*** ONLY METAMODEL", 1)
110 # Load module `filename` and add it as a conditional importation of `mmodule`.
112 # This means that current (and future) submodules of `module` will also import `filename`.
113 fun inject_module_subimportation
(mmodule
: MModule, filename
: String)
115 var am
= load_module
(filename
)
116 if am
== null then return # forward error
118 if mm
== null then return # forward error
119 # Add the new module before the existing submodules in the hierarchy
120 for subm
in mmodule
.in_importation
.direct_smallers
do
121 subm
.set_imported_mmodules
([mm
])
123 # Register the new module as a conditional_importations for future submodules
124 conditional_importations
.add
([mm
, mmodule
])
125 # Register the new amodule to be processed by `run_phases`
126 toolcontext
.todo_nmodules
.unshift am