10c1db3b1f6498801221196972413ccd541df156
[nit.git] / src / ffi / header_dependency.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2013 Alexis Laferrière <alexis.laf@xymus.net>
4 #
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
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
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.
16
17 # Tracks which modules has public header code that must be imported
18 # by user modules.
19 module header_dependency
20
21 import ffi_base
22 import c
23
24 redef class ToolContext
25 var header_dependancy_phase: Phase = new HeaderDependancyPhase(self, [ffi_language_assignation_phase, modelize_class_phase])
26 end
27
28 redef class AModule
29 private fun has_public_c_header: Bool do
30 for code_block in n_extern_code_blocks do if code_block.is_c_header then return true
31 return false
32 end
33 end
34
35 redef class MModule
36 private var header_dependencies_cache: nullable Array[MModule] = null
37 fun header_dependencies: Array[MModule]
38 do
39 var cache = header_dependencies_cache
40 assert cache != null
41 return cache
42 end
43
44 private fun compute_header_dependencies(v: HeaderDependancyPhase)
45 do
46 if header_dependencies_cache != null then return
47
48 var header_dependencies = new Array[MModule]
49
50 # gather from importation
51 for m in in_importation.direct_greaters do
52 m.compute_header_dependencies(v)
53
54 # does the super module has inherited dependancies?
55 var hd = m.header_dependencies
56 if not hd.is_empty then
57 header_dependencies.add_all(hd)
58 end
59
60 # does the super module itself has extern dependancies?
61 var amodule = v.toolcontext.modelbuilder.mmodule2node(m)
62 if amodule != null and amodule.has_public_c_header then header_dependencies.add(m)
63 end
64
65 header_dependencies_cache = header_dependencies
66 end
67 end
68
69 private class HeaderDependancyPhase
70 super Phase
71
72 redef fun process_nmodule(nmodule)
73 do
74 var mmodule = nmodule.mmodule
75 mmodule.compute_header_dependencies(self)
76 end
77 end