ni_nitdoc: added fast copy past utility to signatures.
[nit.git] / src / syntax / extern_type_inheritance.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 # This module manages the C type of extern classes
18 module extern_type_inheritance
19
20 import primitive_info
21 intrude import extern_inline
22
23 redef class MMLocalClass
24 redef fun extern_c_type : String
25 do
26 return extern_type.code
27 end
28
29 fun extern_type_origin : MMLocalClass
30 do
31 extern_type
32 return extern_type_origin_cache.as(not null)
33 end
34
35 # where was the extern type explicitly declared
36 private var extern_type_origin_cache : nullable MMLocalClass = null
37
38 # extern type of an extern class
39 private var extern_type_cache : nullable ExternCode = null
40
41 redef fun extern_type
42 do
43 assert global.is_extern
44
45 if extern_type_cache != null then return extern_type_cache
46
47 if global.intro != self then
48 if global.intro.extern_type_cache != null then
49 extern_type_cache = global.intro.extern_type_cache
50 extern_type_origin_cache = self
51 return extern_type_cache
52 end
53 end
54
55 if name == once "Pointer".to_symbol then
56 extern_type_cache = new ExternCode( "C", "void*", null )
57 extern_type_origin_cache = self
58 return extern_type_cache
59 end
60
61 # find all extern types in direct parents
62 var extern_types = new HashSet[MMLocalClass]
63 var local_class = self # global.class_refinement_hierarchy .first
64 for c in local_class.cshe.direct_greaters do
65 if c.global.is_extern then
66 extern_types.add( c.extern_type_origin )
67 end
68 end
69 #end
70
71 if extern_types.length > 1 then
72 stderr.write("Error: Extern class {mmmodule}::{name} has ambiguous extern type, found in super classes: \n")
73 for c in extern_types do stderr.write( "{c.extern_type.code} from {c}\n" )
74 exit(1)
75 else if extern_types.length == 1 then
76 var source = extern_types.first
77 extern_type_cache = source.extern_type
78 extern_type_origin_cache = source
79 else
80 # Extern class has unknown extern type. This should never happen.
81 abort
82 end
83
84 return extern_type_cache
85 end
86
87 redef fun extern_type=( v )
88 do
89 extern_type_cache = v
90 extern_type_origin_cache = self
91 end
92 end
93