tests: fix sav file for test_for_times
[nit.git] / src / ffi / ffi_base.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2012-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 module ffi_base
18
19 import native_interface
20 import syntax # TODO move extern_implementation to MM
21 import c_tools
22
23 interface FFIVisited
24 fun accept_ffi_visitor( v : FFIVisitor ) do end
25 end
26
27 redef class ExternCode
28 super FFIVisited
29
30 # last resort for extern method
31 # assumes this is a code block in the root of a module
32 # should never be called if the extern method is implemented inline by a known language
33 redef fun accept_ffi_visitor( v )
34 do
35 var language = self.language
36 if language != null then
37 v.tc.warning( null, "language \"{language}\" used to implement a code block in {v.mmmodule} is unknown." )
38 else
39 v.tc.warning( null, "please specify a language to implement code blocks in {v.mmmodule}." ) # is ok with spec as of now, won't be raised
40 end
41 end
42
43 var language_lowered : nullable String = null
44
45 redef init ( language, code, loc )
46 do
47 super
48 if language != null then language_lowered = language.to_lower
49 end
50 end
51
52 redef class MMMethod
53 super FFIVisited
54
55 # last resort for extern method
56 # should never be called if the extern method is implemented inline by a known language
57 redef fun accept_ffi_visitor( v )
58 do
59 if extern_implementation != null then
60 var language = extern_implementation.language
61 if language != null then
62 v.tc.warning( null, "language \"{language}\" used to implement {full_name} is unknown." )
63 else
64 v.tc.warning( null, "please specify a language to implement {full_name}." ) # is ok with spec as of now, won't be raised
65 end
66 end
67 end
68 end
69
70 # set of extern imports in a language to be used by a module
71 # FIXME move to native_interface or MM?
72 class ExternImportSet
73 # set of imported functions, cached to avoid repetitions
74 var callbacks : Set[ MMExplicitImport ] = new HashSet[ MMExplicitImport ]
75
76 # set of imported functions, cached to avoid repetitions
77 var supers : Set[ MMExplicitImport ] = new HashSet[ MMExplicitImport ]
78
79 # set of relevant types, cached to avoid repetitions
80 var types : Set[ MMType ] = new HashSet[ MMType ]
81
82 # set of imported casts and as, cached to avoid repetitions
83 var casts : Set[ MMImportedCast ] = new HashSet[ MMImportedCast ]
84 end
85
86 redef class MMLocalClass
87 super FFIVisited
88
89 fun c_type : nullable String do return null
90 end
91
92 redef class MMModule
93 super FFIVisited
94
95 redef fun accept_ffi_visitor( v )
96 do
97 for local_class in local_classes do
98 # if class is extern and defined here first
99 if local_class.global.intro == local_class and
100 local_class.global.is_extern then
101 local_class.accept_ffi_visitor( v )
102 end
103
104 for prop in local_class.local_local_properties do
105 # if defined of redefined in this module and is extern
106 if prop.mmmodule == self and prop isa MMMethod and prop.is_extern and
107 prop.extern_implementation != null then
108 prop.accept_ffi_visitor( v )
109 end
110 end
111
112 end
113
114 for block in extern_code_blocks do block.accept_ffi_visitor( v )
115 end
116 end
117
118 class FFIVisitor
119 var tc : ToolContext
120
121 # module being visited
122 var mmmodule : MMModule
123
124 var compilation_unit = new CCompilationUnit
125 end
126