Skip to content

Instantly share code, notes, and snippets.

@Apocryphon-X
Last active May 31, 2024 17:08
Show Gist options
  • Save Apocryphon-X/6a6c535fd968f623037b42c6c2505056 to your computer and use it in GitHub Desktop.
Save Apocryphon-X/6a6c535fd968f623037b42c6c2505056 to your computer and use it in GitHub Desktop.
Handy V module to simplify the use of compile-time reflection.

Quickstart

Functions available in this module:

  - reflection.(*)_of_type[foo]()  // Extract details from type or struct
  - reflection.(*)_of(bar)         // Extract details from type instance 
  
(*) can be `methods`, `fields` or `attributes`.

Each function returns a map[string]T where T can be FunctionData, FieldData or StructAttribute respectively.

  • More details about these types can be found in builtin.v file.

Summary

fn fields_of[T](object T) map[string]FieldData
fn fields_of_type[T]() map[string]FieldData

fn attributes_of[T](object T) map[string]StructAttribute
fn attributes_of_type[T]() map[string]StructAttribute

fn methods_of[T](object T) map[string]FunctionData
fn methods_of_type[T]() map[string]FunctionData 

Example

File: main.v

import reflection { methods_of_type }

struct Dummy {}

[example: 'Lorem Ipsum']
fn (s Dummy) foo() {
	// ...
}

fn main() {
	methods := methods_of_type[Dummy]()
	assert 'foo' in methods

	dump(methods['foo'].attrs)
	dump(methods['foo'])
}

Console output:

[main.v:15] methods['foo'].attrs: ['example: Lorem Ipsum']
[main.v:16] methods['foo']: FunctionData{
    name: 'foo'
    attrs: ['example: Lorem Ipsum']
    args: []
    return_type: 1
    typ: 0
}

Project tree:

.
├── main.v
└── reflection/
    └── reflection.v
/// Provided by: @Apocryphon-X
module reflection
pub fn methods_of[T](object T) map[string]FunctionData {
mut methods := map[string]FunctionData{}
$for method in T.methods {
methods[method.name] = method
}
return methods
}
pub fn methods_of_type[T]() map[string]FunctionData {
mut methods := map[string]FunctionData{}
$for method in T.methods {
methods[method.name] = method
}
return methods
}
pub fn fields_of[T](object T) map[string]FieldData {
mut fields := map[string]FieldData{}
$for field in T.fields {
fields[field.name] = field
}
return fields
}
pub fn fields_of_type[T]() map[string]FieldData {
mut fields := map[string]FieldData{}
$for field in T.fields {
fields[field.name] = field
}
return fields
}
pub fn attributes_of[T](object T) map[string]StructAttribute {
mut attributes := map[string]StructAttribute{}
$for attribute in T.attributes {
attributes[attribute.name] = attribute
}
return attributes
}
pub fn attributes_of_type[T]() map[string]StructAttribute {
mut attributes := map[string]StructAttribute{}
$for attribute in T.attributes {
attributes[attribute.name] = attribute
}
return attributes
}
@Apocryphon-X
Copy link
Author

Fixed. I accidentally used the wrong operator (<< instead of =).

@Apocryphon-X
Copy link
Author

<> was replaced to [] (Sudden syntax change in generics)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment