Skip to content

code.codemodel #

Code Model

A set of models that represent code structures, such as structs, functions, imports, and constants. The motivation behind this module is to provide a more generic and lighter alternative to v.ast code models, that can be used for code parsing and code generation across multiple languages.

Features

  • Struct Modeling: Complete struct representation including:

  • Fields with types, visibility, and mutability

  • Embedded structs

  • Generic type support

  • Attributes

  • Documentation comments

  • Function Modeling: Comprehensive function support with:

  • Parameters and return types

  • Receiver methods

  • Optional and result types

  • Function body content

  • Visibility modifiers

  • Type System: Rich type representation including:

  • Basic types

  • Reference types

  • Arrays and maps

  • Optional and result types

  • Mutable and shared types

  • Code Organization:

  • Import statements with module and type specifications

  • Constants (both single and grouped)

  • Custom code blocks for specialized content

  • Documentation through single and multi-line comments

Using Codemodel

The codemodel module provides a set of types and utilities for working with code structures. Here are some examples of how to use the module:

Working with Functions

// Parse a function definition
fn_def := 'pub fn (mut app App) process() !string'
function := codemodel.parse_function(fn_def)!
println(function.name) // prints: process
println(function.receiver.name) // prints: app
println(function.result.typ.symbol) // prints: string

// Create a function model
my_fn := Function{
    name: 'add'
    is_pub: true
    params: [
        Param{
            name: 'x'
            typ: Type{symbol: 'int'}
        },
        Param{
            name: 'y'
            typ: Type{symbol: 'int'}
        }
    ]
    result: Result{
        typ: Type{symbol: 'int'}
    }
    body: 'return x + y'
}

Working with Imports

// Parse an import statement
import_def := 'import os { exists }'
imp := codemodel.parse_import(import_def)
println(imp.mod) // prints: os
println(imp.types) // prints: ['exists']

// Create an import model
my_import := Import{
    mod: 'json'
    types: ['encode', 'decode']
}

Working with Constants

// Parse constant definitions
const_def := 'const max_size = 1000'
constant := codemodel.parse_const(const_def)!
println(constant.name) // prints: max_size
println(constant.value) // prints: 1000

// Parse grouped constants
const_block := 'const (
    pi = 3.14
    e = 2.718
)'
constants := codemodel.parse_consts(const_block)!

Working with Types

The module provides rich type modeling capabilities:

// Basic type
basic := Type{
    symbol: 'string'
}

// Array type
array := Type{
    symbol: 'string'
    is_array: true
}

// Optional type
optional := Type{
    symbol: 'int'
    is_optional: true
}

// Result type
result := Type{
    symbol: 'string'
    is_result: true
}

Code Generation

The codemodel types can be used as intermediate structures for code generation. For example, generating documentation:

mut doc := ''

// Document a struct
for field in my_struct.fields {
    doc +='- ${field.name}: ${field.typ.symbol}'
    if field.description != '' {
        doc +=' // ${field.description}'
    }
    doc += '\n'
}

The codemodel module provides a foundation for building tools that need to work with code structures, whether for analysis, transformation, or generation purposes.

fn get_struct #

fn get_struct(params GetStruct) ?Struct

fn inflate_struct_fields #

fn inflate_struct_fields(code []CodeItem, mut struct_ CodeItem)

fn inflate_types #

fn inflate_types(mut code []CodeItem)

fn new_file #

fn new_file(config CodeFile) CodeFile

fn parse_const #

fn parse_const(code_ string) !Const

fn parse_consts #

fn parse_consts(code_ string) ![]Const

fn parse_function #

fn parse_function(code_ string) !Function

fn parse_import #

fn parse_import(code_ string) Import

fn parse_param #

fn parse_param(code_ string) !Param

fn parse_result #

fn parse_result(code_ string) !Result

fn vgen #

fn vgen(code []CodeItem) string

fn vgen_generics #

fn vgen_generics(generics map[string]string) string

type CodeItem #

type CodeItem = Alias | Comment | CustomCode | Function | Import | Struct | Sumtype

type Value #

type Value = string

struct Alias #

struct Alias {
pub:
	name        string
	description string
	typ         Type
}

struct Attribute #

struct Attribute {
pub:
	name    string // [name]
	has_arg bool
	arg     string // [name: arg]
}

struct CodeFile #

struct CodeFile {
pub mut:
	name    string
	mod     string
	imports []Import
	consts  []Const
	items   []CodeItem
	content string
}

fn (CodeFile) add_import #

fn (mut file CodeFile) add_import(import_ Import) !

fn (CodeFile) write_v #

fn (code CodeFile) write_v(path string, options WriteOptions) !

fn (CodeFile) get_function #

fn (file CodeFile) get_function(name string) ?Function

fn (CodeFile) set_function #

fn (mut file CodeFile) set_function(function Function) !

fn (CodeFile) functions #

fn (file CodeFile) functions() []Function

fn (CodeFile) structs #

fn (file CodeFile) structs() []Struct

struct Comment #

struct Comment {
pub:
	text     string
	is_multi bool
}

struct Const #

struct Const {
	name  string
	value string
}

struct CustomCode #

struct CustomCode {
pub:
	text string
}

item for adding custom code in

fn (CustomCode) vgen #

fn (custom CustomCode) vgen() string

struct Example #

struct Example {
	function Function
	values   map[string]Value
	result   Value
}

struct File #

struct File {
pub mut:
	name      string
	extension string
	content   string
}

fn (File) write #

fn (f File) write(path string) !

struct Function #

struct Function {
pub:
	name     string
	receiver Param
	is_pub   bool
	mod      string
pub mut:
	description string
	params      []Param
	body        string
	result      Result
	has_return  bool
}

fn (Function) generate_call #

fn (func Function) generate_call(params GenerateCallParams) !string

fn (Function) vgen #

fn (function Function) vgen(options WriteOptions) string

vgen_function generates a function statement for a function

struct GenerateCallParams #

@[params]
struct GenerateCallParams {
pub:
	receiver string
}

struct GenerateValueParams #

@[params]
struct GenerateValueParams {
}

struct GetStruct #

struct GetStruct {
pub:
	code []CodeItem
	mod  string
	name string
}

struct Import #

struct Import {
pub mut:
	mod   string
	types []string
}

fn (Import) add_types #

fn (mut i Import) add_types(types []string)

fn (Import) vgen #

fn (import_ Import) vgen() string

vgen_import generates an import statement for a given type

struct Module #

struct Module {
pub mut:
	name       string
	files      []CodeFile
	misc_files []File
	// model   CodeFile
	// methods CodeFile
}

fn (Module) write_v #

fn (mod Module) write_v(path string, options WriteOptions) !

struct Param #

struct Param {
pub:
	required    bool
	mutable     bool
	is_shared   bool
	is_optional bool
	description string
	name        string
	typ         Type
	struct_     Struct
}

fn (Param) generate_value #

fn (param Param) generate_value() !string

fn (Param) vgen #

fn (param Param) vgen() string

struct Result #

struct Result {
pub mut:
	typ         Type
	description string
	name        string
	result      bool // whether is result type
	optional    bool // whether is result type
	structure   Struct
}

fn (Result) vgen #

fn (result Result) vgen() string

vgen_function generates a function statement for a function

struct Struct #

struct Struct {
pub mut:
	name        string
	description string
	mod         string
	is_pub      bool
	embeds      []Struct          @[str: skip]
	generics    map[string]string @[str: skip]
	attrs       []Attribute
	fields      []StructField
}

fn (Struct) get_type_symbol #

fn (structure Struct) get_type_symbol() string

fn (Struct) vgen #

fn (struct_ Struct) vgen() string

vgen_function generates a function statement for a function

struct StructField #

struct StructField {
pub mut:
	comments    []Comment
	attrs       []Attribute
	name        string
	description string
	default     string
	is_pub      bool
	is_mut      bool
	is_ref      bool
	anon_struct Struct @[str: skip] // sometimes fields may hold anonymous structs
	typ         Type
	structure   Struct @[str: skip]
}

fn (StructField) get_type_symbol #

fn (field StructField) get_type_symbol() string

fn (StructField) vgen #

fn (field StructField) vgen() string

struct Sumtype #

struct Sumtype {
pub:
	name        string
	description string
	types       []Type
}

struct Type #

struct Type {
pub mut:
	is_reference bool @[str: skip]
	is_map       bool @[str: skip]
	is_array     bool
	is_mutable   bool @[str: skip]
	is_shared    bool @[str: skip]
	is_optional  bool @[str: skip]
	is_result    bool @[str: skip]
	symbol       string
	mod          string @[str: skip]
}

Todo: maybe make 'is_' fields methods?

fn (Type) vgen #

fn (type_ Type) vgen() string

Todo: enfore that cant be both mutable and shared

struct VGenerator #

struct VGenerator {
	format bool
}

fn (VGenerator) generate_struct #

fn (gen VGenerator) generate_struct(struct_ Struct) !string

fn (VGenerator) generate_struct_field #

fn (gen VGenerator) generate_struct_field(field StructField) string

struct WriteCode #

struct WriteCode {
	destination string
}

struct WriteOptions #

@[params]
struct WriteOptions {
pub:
	format    bool
	overwrite bool
	document  bool
	prefix    string
}