1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2012 <alexis.laf@xymus.net>
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.
17 # Manages foreign code blocks using the Nit FFI
20 intrude import mmbuilder
26 var language
: nullable String
28 var location
: nullable Location
32 # extern code blocks in module
33 var extern_code_blocks
: Set[ExternCode] = new HashSet[ExternCode]
34 redef var uses_ffi
: Bool = false
37 redef class MMLocalClass
38 # extern equivalent of class
39 var extern_type
: nullable ExternCode = null
43 # extern code bodu of extern method
44 var extern_implementation
: nullable ExternCode = null
47 redef class TExternCodeSegment
48 # removes `{ and `} and return code of interest
50 return text
.substring
( 2, text
.length-4
)
54 redef class AExternCodeBlock
55 fun to_extern_code
: ExternCode
58 if n_in_language
== null then
61 var text
= n_in_language
.n_string
.text
62 language
= text
.substring
( 1, text
.length-2
)
64 return new ExternCode( language
, n_extern_code_segment
.code
, n_extern_code_segment
.location
)
68 redef class AExternPropdef
69 redef fun accept_property_verifier
(v
)
73 # Extern method implementation
74 var n_extern_code_block
= self.n_extern_code_block
75 if n_extern_code_block
!= null then
76 if not method
.is_extern
then
77 v
.error
( n_extern_code_block
,
78 "Cannot implement the non extern method {method.full_name} with extern code" )
80 method
.extern_implementation
= n_extern_code_block
.to_extern_code
81 method
.mmmodule
.uses_ffi
= true
87 redef class AStdClassdef
88 redef fun accept_property_verifier
(v
)
92 # Extern type of extern classes
93 var extern_code_block
= self.n_extern_code_block
94 if extern_code_block
!= null then
95 if not local_class
.global
.is_extern
then
96 v
.error
( extern_code_block
,
97 "Cannot define an extern equivalent in the non extern class {local_class.name}" )
99 local_class
.extern_type
= extern_code_block
.to_extern_code
100 local_class
.mmmodule
.uses_ffi
= true
106 redef class MMSrcModule
107 # Syntax analysis and MM construction for the module
108 # Require that supermodules are processed
109 redef fun do_mmbuilder
(tc
: ToolContext)
114 if not node
.n_extern_code_blocks
.is_empty
then uses_ffi
= true
115 for n_extern_code_block
in node
.n_extern_code_blocks
do
116 extern_code_blocks
.add
( n_extern_code_block
.to_extern_code
)