mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
349 lines
6.7 KiB
V
349 lines
6.7 KiB
V
[has_globals]
|
|
module reflection
|
|
|
|
import arrays
|
|
|
|
__global g_reflection = Reflection{}
|
|
|
|
[heap; minify]
|
|
pub struct Reflection {
|
|
pub mut:
|
|
modules []Module
|
|
funcs []Function
|
|
types []Type
|
|
type_symbols []TypeSymbol
|
|
enums []Enum
|
|
interfaces []Interface
|
|
strings map[int]string
|
|
}
|
|
|
|
pub enum VLanguage {
|
|
v
|
|
c
|
|
js
|
|
amd64 // aka x86_64
|
|
i386
|
|
arm64 // 64-bit arm
|
|
arm32 // 32-bit arm
|
|
rv64 // 64-bit risc-v
|
|
rv32 // 32-bit risc-v
|
|
wasm32
|
|
}
|
|
|
|
type VType = u32
|
|
|
|
// max of 8
|
|
pub enum VTypeFlag {
|
|
option
|
|
result
|
|
variadic
|
|
generic
|
|
shared_f
|
|
atomic_f
|
|
}
|
|
|
|
pub enum VKind {
|
|
placeholder
|
|
void
|
|
voidptr
|
|
byteptr
|
|
charptr
|
|
i8
|
|
i16
|
|
int
|
|
i64
|
|
isize
|
|
u8
|
|
u16
|
|
u32
|
|
u64
|
|
usize
|
|
f32
|
|
f64
|
|
char
|
|
rune
|
|
bool
|
|
none_
|
|
string
|
|
array
|
|
array_fixed
|
|
map
|
|
chan
|
|
any
|
|
struct_
|
|
generic_inst
|
|
multi_return
|
|
sum_type
|
|
alias
|
|
enum_
|
|
function
|
|
interface_
|
|
float_literal
|
|
int_literal
|
|
aggregate
|
|
thread
|
|
}
|
|
|
|
// return true if `flag` is set on `t`
|
|
[inline]
|
|
pub fn (t VType) has_flag(flag VTypeFlag) bool {
|
|
return int(t) & (1 << (int(flag) + 24)) > 0
|
|
}
|
|
|
|
[inline]
|
|
pub fn (t VType) idx() int {
|
|
return u16(t) & 0xffff
|
|
}
|
|
|
|
pub fn (t VType) str() string {
|
|
return 'VType(0x${t.hex()} = ${u32(t)})'
|
|
}
|
|
|
|
// return true if `t` is a pointer (nr_muls>0)
|
|
[inline]
|
|
pub fn (t VType) is_ptr() bool {
|
|
// any normal pointer, i.e. &Type, &&Type etc;
|
|
// Note: voidptr, charptr and byteptr are NOT included!
|
|
return (int(t) >> 16) & 0xff > 0
|
|
}
|
|
|
|
pub struct ArrayFixed {
|
|
pub:
|
|
size int // array size
|
|
elem_type int // elem type idx
|
|
}
|
|
|
|
pub struct Array {
|
|
pub:
|
|
nr_dims int // nr of dimensions
|
|
elem_type int // elem type idx
|
|
}
|
|
|
|
pub struct Alias {
|
|
pub:
|
|
parent_idx int // parent type idx
|
|
language VLanguage // language
|
|
}
|
|
|
|
pub struct Interface {
|
|
pub:
|
|
name string // interface name
|
|
methods []Function // methods
|
|
fields []StructField // fields
|
|
is_generic bool // is generic?
|
|
}
|
|
|
|
pub struct None {
|
|
pub:
|
|
parent_idx int
|
|
}
|
|
|
|
pub struct Enum {
|
|
pub:
|
|
vals []string // enum values
|
|
is_flag bool // is flag?
|
|
}
|
|
|
|
pub struct StructField {
|
|
pub:
|
|
name string // field name
|
|
typ VType // type
|
|
attrs []string // field attrs
|
|
is_pub bool // is pub?
|
|
is_mut bool // is mut?
|
|
}
|
|
|
|
pub struct Struct {
|
|
pub:
|
|
parent_idx int // parent type
|
|
attrs []string // struct attrs
|
|
fields []StructField // fields
|
|
}
|
|
|
|
pub struct SumType {
|
|
pub:
|
|
parent_idx int // parent type
|
|
variants []VType // variant type
|
|
}
|
|
|
|
pub struct Map {
|
|
pub:
|
|
key_type VType // key type
|
|
value_type VType // value type
|
|
}
|
|
|
|
pub struct MultiReturn {
|
|
pub:
|
|
types []VType // types
|
|
}
|
|
|
|
pub type TypeInfo = Alias
|
|
| Array
|
|
| ArrayFixed
|
|
| Enum
|
|
| Function
|
|
| Interface
|
|
| Map
|
|
| MultiReturn
|
|
| None
|
|
| Struct
|
|
| SumType
|
|
|
|
pub struct TypeSymbol {
|
|
pub:
|
|
name string // symbol name
|
|
idx int // symbol idx
|
|
parent_idx int // symbol parent idx
|
|
language VLanguage // language
|
|
kind VKind // kind
|
|
info TypeInfo // info
|
|
methods []Function // methods
|
|
}
|
|
|
|
pub struct Type {
|
|
pub:
|
|
name string // type name
|
|
idx int // type idx
|
|
sym TypeSymbol // type symbol
|
|
}
|
|
|
|
pub struct Module {
|
|
pub:
|
|
name string // module name
|
|
}
|
|
|
|
pub struct FunctionArg {
|
|
pub:
|
|
name string // argument name
|
|
typ VType // argument type idx
|
|
is_mut bool // is mut?
|
|
}
|
|
|
|
pub struct Function {
|
|
pub:
|
|
mod_name string // module name
|
|
name string // function/method name
|
|
args []FunctionArg // function/method args
|
|
file_idx int // source file name
|
|
line_start int // decl start line
|
|
line_end int // decl end line
|
|
is_variadic bool // is variadic?
|
|
return_typ VType // return type idx
|
|
receiver_typ VType // receiver type idx (is a method)
|
|
is_pub bool // is pub?
|
|
}
|
|
|
|
// API module
|
|
|
|
pub fn get_string_by_idx(idx int) string {
|
|
return g_reflection.strings[idx]
|
|
}
|
|
|
|
// type_of returns the type info of the passed value
|
|
pub fn type_of[T](val T) Type {
|
|
return g_reflection.types.filter(it.idx == typeof[T]().idx)[0]
|
|
}
|
|
|
|
// get_modules returns the module name built with V source
|
|
pub fn get_modules() []Module {
|
|
return g_reflection.modules
|
|
}
|
|
|
|
// get_functions returns the functions built with V source
|
|
pub fn get_funcs() []Function {
|
|
mut out := g_reflection.funcs.clone()
|
|
out << arrays.flatten[Function](get_types().map(it.sym.methods).filter(it.len))
|
|
return out
|
|
}
|
|
|
|
pub fn get_structs() []Type {
|
|
struct_idxs := g_reflection.type_symbols.filter(it.kind == .struct_).map(it.idx)
|
|
return g_reflection.types.filter(it.idx in struct_idxs)
|
|
}
|
|
|
|
// get_types returns the registered types
|
|
pub fn get_types() []Type {
|
|
return g_reflection.types
|
|
}
|
|
|
|
// get_enums returns the registered enums
|
|
pub fn get_enums() []Type {
|
|
enum_idxs := g_reflection.type_symbols.filter(it.kind == .enum_).map(it.idx)
|
|
return g_reflection.types.filter(it.idx in enum_idxs)
|
|
}
|
|
|
|
// get_aliases returns the registered aliases
|
|
pub fn get_aliases() []Type {
|
|
alias_idxs := g_reflection.type_symbols.filter(it.kind == .alias).map(it.idx)
|
|
return g_reflection.types.filter(it.idx in alias_idxs)
|
|
}
|
|
|
|
// get_interfaces returns the registered aliases
|
|
pub fn get_interfaces() []Interface {
|
|
iface_idxs := g_reflection.type_symbols.filter(it.kind == .interface_).map(it.idx)
|
|
return g_reflection.types.filter(it.idx in iface_idxs).map(it.sym.info as Interface)
|
|
}
|
|
|
|
// get_sum_types returns the registered sum types
|
|
pub fn get_sum_types() []Type {
|
|
sumtype_idxs := g_reflection.type_symbols.filter(it.kind == .sum_type).map(it.idx)
|
|
return g_reflection.types.filter(it.idx in sumtype_idxs)
|
|
}
|
|
|
|
// get_type_symbol returns the registered type symbols
|
|
pub fn get_type_symbols() []TypeSymbol {
|
|
return g_reflection.type_symbols
|
|
}
|
|
|
|
// Type API
|
|
pub fn type_name(idx int) string {
|
|
t := g_reflection.types.filter(it.idx == idx)
|
|
return if t.len != 0 { t[0].name } else { '' }
|
|
}
|
|
|
|
pub fn get_type(idx int) ?Type {
|
|
t := g_reflection.types.filter(it.idx == idx)
|
|
return if t.len != 0 { t[0] } else { none }
|
|
}
|
|
|
|
// Type Symbol API
|
|
pub fn type_symbol_name(idx int) string {
|
|
t := g_reflection.type_symbols.filter(it.idx == idx)
|
|
return if t.len != 0 { t[0].name } else { '' }
|
|
}
|
|
|
|
pub fn get_type_symbol(idx int) ?TypeSymbol {
|
|
t := g_reflection.type_symbols.filter(it.idx == idx)
|
|
return if t.len != 0 { t[0] } else { none }
|
|
}
|
|
|
|
// V reflection metainfo API (called from backend to fill metadata info)
|
|
|
|
[markused]
|
|
fn add_module(mod_name string) {
|
|
g_reflection.modules << Module{mod_name}
|
|
}
|
|
|
|
[markused]
|
|
fn add_func(func Function) {
|
|
g_reflection.funcs << func
|
|
}
|
|
|
|
[markused]
|
|
fn add_type(type_ Type) {
|
|
g_reflection.types << Type{
|
|
...type_
|
|
sym: g_reflection.type_symbols.filter(it.idx == type_.idx).first()
|
|
}
|
|
}
|
|
|
|
[markused]
|
|
fn add_type_symbol(typesymbol TypeSymbol) {
|
|
g_reflection.type_symbols << typesymbol
|
|
}
|
|
|
|
[markused]
|
|
fn add_string(str string, idx int) {
|
|
g_reflection.strings[idx] = str
|
|
}
|