v2 / vlib / v / reflection / reflection.v
351 lines · 301 sloc · 6.86 KB · 5dcfbf927b272bfcc843633363cc2b63638caad7
Raw
1@[has_globals]
2module reflection
3
4import arrays
5
6__global g_reflection = Reflection{}
7
8@[heap; minify]
9pub struct Reflection {
10pub mut:
11 modules []Module
12 funcs []Function
13 types []Type
14 type_symbols []TypeSymbol
15 enums []Enum
16 interfaces []Interface
17 strings map[int]string
18}
19
20pub enum VLanguage {
21 v
22 c
23 js
24 amd64 // aka x86_64
25 i386
26 arm64 // 64-bit arm
27 arm32 // 32-bit arm
28 rv64 // 64-bit risc-v
29 rv32 // 32-bit risc-v
30 wasm32
31}
32
33type VType = u32
34
35// max of 8
36pub enum VTypeFlag {
37 option
38 result
39 variadic
40 generic
41 shared_f
42 atomic_f
43}
44
45pub enum VKind {
46 placeholder
47 void
48 voidptr
49 byteptr
50 charptr
51 i8
52 i16
53 i32
54 i64
55 int
56 isize
57 u8
58 u16
59 u32
60 u64
61 usize
62 f32
63 f64
64 char
65 rune
66 bool
67 none
68 string
69 array
70 array_fixed
71 map
72 chan
73 any
74 struct
75 generic_inst
76 multi_return
77 sum_type
78 alias
79 enum
80 function
81 interface
82 float_literal
83 int_literal
84 aggregate
85 thread
86}
87
88// return true if `flag` is set on `t`
89@[inline]
90pub fn (t VType) has_flag(flag VTypeFlag) bool {
91 return int(t) & (1 << (int(flag) + 24)) > 0
92}
93
94@[inline]
95pub fn (t VType) idx() int {
96 return u16(t) & 0xffff
97}
98
99pub fn (t VType) str() string {
100 return 'VType(0x${t.hex()} = ${u32(t)})'
101}
102
103// return true if `t` is a pointer (nr_muls>0)
104@[inline]
105pub fn (t VType) is_ptr() bool {
106 // any normal pointer, i.e. &Type, &&Type etc;
107 // Note: voidptr, charptr and byteptr are NOT included!
108 return (int(t) >> 16) & 0xff > 0
109}
110
111pub struct ArrayFixed {
112pub:
113 size int // array size
114 elem_type int // elem type idx
115}
116
117pub struct Array {
118pub:
119 nr_dims int // nr of dimensions
120 elem_type int // elem type idx
121}
122
123pub struct Alias {
124pub:
125 parent_idx int // parent type idx
126 language VLanguage // language
127}
128
129pub struct Interface {
130pub:
131 name string // interface name
132 methods []Function // methods
133 fields []StructField // fields
134 is_generic bool // is generic?
135}
136
137pub struct None {
138pub:
139 parent_idx int
140}
141
142pub struct Enum {
143pub:
144 vals []string // enum values
145 is_flag bool // is flag?
146}
147
148pub struct StructField {
149pub:
150 name string // field name
151 typ VType // type
152 attrs []VAttribute // field attrs
153 is_pub bool // is pub?
154 is_mut bool // is mut?
155}
156
157pub struct Struct {
158pub:
159 parent_idx int // parent type
160 attrs []VAttribute // struct attrs
161 fields []StructField // fields
162}
163
164pub struct SumType {
165pub:
166 parent_idx int // parent type
167 variants []VType // variant type
168}
169
170pub struct Map {
171pub:
172 key_type VType // key type
173 value_type VType // value type
174}
175
176pub struct MultiReturn {
177pub:
178 types []VType // types
179}
180
181pub type TypeInfo = Alias
182 | Array
183 | ArrayFixed
184 | Enum
185 | Function
186 | Interface
187 | Map
188 | MultiReturn
189 | None
190 | Struct
191 | SumType
192
193pub struct TypeSymbol {
194pub:
195 name string // symbol name
196 mod string // mod name
197 idx int // symbol idx
198 parent_idx int // symbol parent idx
199 language VLanguage // language
200 kind VKind // kind
201 info TypeInfo // info
202 methods []Function // methods
203}
204
205pub struct Type {
206pub:
207 name string // type name
208 idx int // type idx
209 sym TypeSymbol // type symbol
210}
211
212pub struct Module {
213pub:
214 name string // module name
215}
216
217pub struct FunctionArg {
218pub:
219 name string // argument name
220 typ VType // argument type idx
221 is_mut bool // is mut?
222}
223
224pub struct Function {
225pub:
226 mod_name string // module name
227 name string // function/method name
228 attrs []VAttribute // function/method attrs
229 args []FunctionArg // function/method args
230 file_idx int // source file name
231 line_start int // decl start line
232 line_end int // decl end line
233 is_variadic bool // is variadic?
234 return_typ VType // return type idx
235 receiver_typ VType // receiver type idx (is a method)
236 is_pub bool // is pub?
237}
238
239// API module
240
241pub fn get_string_by_idx(idx int) string {
242 return g_reflection.strings[idx]
243}
244
245// type_of returns the type info of the passed value
246pub fn type_of[T](val T) Type {
247 return g_reflection.types.filter(it.idx == typeof[T]().idx & 0xff00ffff)[0]
248}
249
250// get_modules returns the module name built with V source
251pub fn get_modules() []Module {
252 return g_reflection.modules
253}
254
255// get_functions returns the functions built with V source
256pub fn get_funcs() []Function {
257 mut out := g_reflection.funcs.clone()
258 out << arrays.flatten[Function](get_types().map(it.sym.methods).filter(it.len != 0))
259 return out
260}
261
262pub fn get_structs() []Type {
263 struct_idxs := g_reflection.type_symbols.filter(it.kind == .struct).map(it.idx)
264 return g_reflection.types.filter(it.idx in struct_idxs)
265}
266
267// get_types returns the registered types
268pub fn get_types() []Type {
269 return g_reflection.types
270}
271
272// get_enums returns the registered enums
273pub fn get_enums() []Type {
274 enum_idxs := g_reflection.type_symbols.filter(it.kind == .enum).map(it.idx)
275 return g_reflection.types.filter(it.idx in enum_idxs)
276}
277
278// get_aliases returns the registered aliases
279pub fn get_aliases() []Type {
280 alias_idxs := g_reflection.type_symbols.filter(it.kind == .alias).map(it.idx)
281 return g_reflection.types.filter(it.idx in alias_idxs)
282}
283
284// get_interfaces returns the registered aliases
285pub fn get_interfaces() []Interface {
286 iface_idxs := g_reflection.type_symbols.filter(it.kind == .interface).map(it.idx)
287 return g_reflection.types.filter(it.idx in iface_idxs).map(it.sym.info as Interface)
288}
289
290// get_sum_types returns the registered sum types
291pub fn get_sum_types() []Type {
292 sumtype_idxs := g_reflection.type_symbols.filter(it.kind == .sum_type).map(it.idx)
293 return g_reflection.types.filter(it.idx in sumtype_idxs)
294}
295
296// get_type_symbol returns the registered type symbols
297pub fn get_type_symbols() []TypeSymbol {
298 return g_reflection.type_symbols
299}
300
301// Type API
302pub fn type_name(idx int) string {
303 t := g_reflection.types.filter(it.idx == idx)
304 return if t.len != 0 { t[0].name } else { '' }
305}
306
307pub fn get_type(idx int) ?Type {
308 t := g_reflection.types.filter(it.idx == idx)
309 return if t.len != 0 { t[0] } else { none }
310}
311
312// Type Symbol API
313pub fn type_symbol_name(idx int) string {
314 t := g_reflection.type_symbols.filter(it.idx == idx)
315 return if t.len != 0 { t[0].name } else { '' }
316}
317
318pub fn get_type_symbol(idx int) ?TypeSymbol {
319 t := g_reflection.type_symbols.filter(it.idx == idx)
320 return if t.len != 0 { t[0] } else { none }
321}
322
323// V reflection metainfo API (called from backend to fill metadata info)
324
325@[markused]
326fn add_module(mod_name string) {
327 g_reflection.modules << Module{mod_name}
328}
329
330@[markused]
331fn add_func(func Function) {
332 g_reflection.funcs << func
333}
334
335@[markused]
336fn add_type(type_ Type) {
337 g_reflection.types << Type{
338 ...type_
339 sym: g_reflection.type_symbols.filter(it.idx == type_.idx).first()
340 }
341}
342
343@[markused]
344fn add_type_symbol(typesymbol TypeSymbol) {
345 g_reflection.type_symbols << typesymbol
346}
347
348@[markused]
349fn add_string(str string, idx int) {
350 g_reflection.strings[idx] = str
351}
352