xreflect

package
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 22, 2026 License: Apache-2.0 Imports: 5 Imported by: 1

Documentation

Overview

Package xreflect provides a reflect-based loader that builds a model.Package or model.Module from reflect.Type values. It complements the AST-based loader by enabling runtime discovery via registries or aggregator variables (e.g., a slice of types exported by a package).

Entry points

  • LoadPackage(rType reflect.Type, opts ...LoadOption): Builds a single package using a seed type (for default pkg path/name) and additional types provided through options.
  • LoadModule(opts ...ModuleOption): Builds a module from multiple sources (names+provider, explicit package→types, or seed types grouped by their reflect package).

Typical usage

// Single package derived from a seed type, plus extras:
//   pkg, _ := xreflect.LoadPackage(reflect.TypeOf(MyType{}), xreflect.WithTypes(reflect.TypeOf(Other{})))

// Module from a registry that exposes package names and a provider:
//   mod, _ := xreflect.LoadModule(
//       xreflect.WithModuleNamesAndProvider(xunsafe.PackageNames(), xunsafe.PackageTypesFor),
//   )

Options overview

LoadOption:
  - WithPackagePath(string), WithPackageName(string)
  - WithTypes(...reflect.Type), WithValues(...any), WithTypesFrom(func() []reflect.Type)
  - WithAllowCrossPackage() // suppress errors for cross-package types (skipped)
  - WithOnUnnamedRecursion(func(reflect.Type) error)
  - WithNamePolicy(func(reflect.Type) (declName string, ok bool))

ModuleOption:
  - WithModuleNamesAndProvider([]string, func(pkg string) []reflect.Type)
  - WithModulePackageTypes(pkgPath string, types ...reflect.Type)
  - WithModulePackageName(pkgPath, name string)
  - WithModuleSeedTypes(...reflect.Type) // grouped by reflect package
  - WithModuleAllowCrossPackage(), WithModuleOnUnnamedRecursion(...), WithModuleNamePolicy(...)

Limitations

  • Reflection cannot enumerate all types in a package by itself; callers must provide at least one seed type and/or a registry/provider.
  • Generic type parameters and union constraints are not exposed by reflect and therefore are not populated in the model. Use the AST loader for complete generic fidelity.
  • Free functions, consts, and vars are not discoverable via reflect.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func BuildType

func BuildType(rt reflect.Type, opts ...LoadOption) (*model.Type, error)

BuildType constructs a single model.Type from the provided reflect.Type. Options such as WithPackagePath/WithPackageName/WithNamePolicy and WithOnUnnamedRecursion are honoured. Cross-package checks are not applied for single-type conversion.

func LoadModule

func LoadModule(opts ...ModuleOption) (*model.Module, error)

LoadModule constructs a model.Module from sources specified via ModuleOption. Sources can include named package lists with a provider, explicit package→types mappings, and raw seed types that will be grouped by their reflect package.

Example

ExampleLoadModule demonstrates loading multiple packages by name using a provider that returns types for a given import path. In real life, provider could be xunsafe.PackageTypesFor, and names from xunsafe.PackageNames().

package main

import (
	"fmt"
	"reflect"

	xr "github.com/viant/x/loader/xreflect"
)

func main() {
	// Fake registry of package -> types for example purposes.
	type A struct{}
	type B struct{}
	type C struct{}
	registry := map[string][]reflect.Type{
		"example.org/pkg/a": {reflect.TypeOf(A{})},
		"example.org/pkg/b": {reflect.TypeOf(B{}), reflect.TypeOf(C{})},
	}
	names := []string{"example.org/pkg/a", "example.org/pkg/b"}
	mod, err := xr.LoadModuleByNames(names, func(pkg string) []reflect.Type { return registry[pkg] }, xr.WithModuleAllowCrossPackage())
	if err != nil {
		panic(err)
	}
	fmt.Println(mod.HasPackage("example.org/pkg/a") && mod.HasPackage("example.org/pkg/b"))
}
Output:
true

func LoadModuleByNames

func LoadModuleByNames(pkgNames []string, provider func(pkgPath string) []reflect.Type, opts ...ModuleOption) (*model.Module, error)

LoadModuleByNames builds a model.Module given package import paths and a provider that returns the reflect.Type list for each package. pkgNames are import paths (e.g., "github.com/acme/p").

Typical usage with an external registry:

names := xunsafe.PackageNames()
mod, _ := xreflect.LoadModuleByNames(names, xunsafe.PackageTypesFor)

func LoadModuleFromMap

func LoadModuleFromMap(typeMap map[string][]reflect.Type, opts ...ModuleOption) (*model.Module, error)

LoadModuleFromMap is a convenience that accepts a map of pkgPath -> []reflect.Type.

func LoadPackage

func LoadPackage(rType reflect.Type, opts ...LoadOption) (*model.Package, error)

LoadPackage constructs a model.Package from the seed reflect.Type rType and optional types supplied via LoadOption. The package path and name default to rType.PkgPath() and its last segment unless overridden via options.

Notes:

  • Only named types are emitted as top-level declarations.
  • Types from other packages are skipped by default; enable WithAllowCrossPackage to suppress errors about such types (they are still skipped to keep a coherent package output).
Example

ExampleLoadPackage shows building a package from reflect types and printing rendered source for the default file.

package main

import (
	"fmt"
	"reflect"

	xr "github.com/viant/x/loader/xreflect"
)

func main() {
	type Person struct{ Name string }
	type Team struct{ Members []Person }

	// Derive pkg path/name from seed type and include additional types.
	pkg, err := xr.LoadPackage(reflect.TypeOf(Person{}), xr.WithTypes(reflect.TypeOf(Team{})))
	if err != nil {
		panic(err)
	}
	gf := pkg.DefaultFile("xreflect_example")
	for _, t := range pkg.Types {
		gf.AddType(t)
	}
	src, _ := gf.Render()
	fmt.Println(len(src) > 0)
}
Output:
true

func ToModelNode

func ToModelNode(rt reflect.Type) (model.Node, error)

ToModelNode converts a reflect.Type into a syntetic/model.Node using the xtype intermediate representation. It propagates xtype.ErrUnnamedRecursion and returns (nil, nil) for reflect kinds that xtype does not model (for example, unsafe.Pointer).

Types

type A

type A struct{ B *B }

type B

type B struct{ A *A }

type BasicStruct

type BasicStruct struct {
	Int   int
	Str   string
	Named NamedInt
	Ptr   *int
	Slice []string
	Array [2]bool
	Map   map[string]int
	Recv  chan<- int
	Send  <-chan string
	Both  chan bool
}

type E

type E struct {
	ID int `json:"id"`
}

type EmbeddedA

type EmbeddedA struct {
	ID int `json:"id"`
}

type EmbeddedB

type EmbeddedB struct {
	EmbeddedA
	Name string `yaml:"name"`
}

type FuncSimple

type FuncSimple func(int) string

Func types covering parameters, results, and variadic flag.

type FuncVariadic

type FuncVariadic func(prefix string, values ...int) (int, error)

type InterfaceMixed

type InterfaceMixed interface {
	Exported(a int) string
	// contains filtered or unexported methods
}

Interfaces with exported and unexported methods.

type K

type K string

Additional types for extended coverage

type LoadOption

type LoadOption func(*cfg)

LoadOption configures LoadPackage behaviour.

func WithAllowCrossPackage

func WithAllowCrossPackage() LoadOption

WithAllowCrossPackage disables errors on types from other packages. Such types are skipped by default; with this option they are still skipped but no error is returned. This keeps the output package consistent.

func WithNamePolicy

func WithNamePolicy(fn func(reflect.Type) (string, bool)) LoadOption

WithNamePolicy customises the declared name for a reflect.Type. The boolean return value is reserved for future alias handling and is currently ignored.

func WithOnUnnamedRecursion

func WithOnUnnamedRecursion(fn func(reflect.Type) error) LoadOption

WithOnUnnamedRecursion installs a callback to handle unnamed recursive composites reported by the xtype reflection bridge.

func WithPackageName

func WithPackageName(n string) LoadOption

WithPackageName overrides the derived package name.

func WithPackagePath

func WithPackagePath(p string) LoadOption

WithPackagePath overrides the derived package path.

func WithTypes

func WithTypes(ts ...reflect.Type) LoadOption

WithTypes adds additional reflect.Type values to include.

func WithTypesFrom

func WithTypesFrom(provider func() []reflect.Type) LoadOption

WithTypesFrom registers a provider that returns additional types to include.

func WithValues

func WithValues(vs ...any) LoadOption

WithValues adds values whose reflect.Type should be included.

type ModuleOption

type ModuleOption func(*mcfg)

ModuleOption configures LoadModuleByNames behaviour.

func WithModuleAllowCrossPackage

func WithModuleAllowCrossPackage() ModuleOption

WithModuleAllowCrossPackage suppresses errors about cross-package types.

func WithModuleNamePolicy

func WithModuleNamePolicy(fn func(reflect.Type) (string, bool)) ModuleOption

WithModuleNamePolicy customises declared names for types.

func WithModuleNamesAndProvider

func WithModuleNamesAndProvider(names []string, provider func(pkgPath string) []reflect.Type) ModuleOption

WithModuleNamesAndProvider sets a list of package import paths and a provider returning reflect types for each package.

func WithModuleOnUnnamedRecursion

func WithModuleOnUnnamedRecursion(fn func(reflect.Type) error) ModuleOption

WithModuleOnUnnamedRecursion installs a callback for unnamed recursive composites.

func WithModulePackageName

func WithModulePackageName(pkgPath, name string) ModuleOption

WithModulePackageName overrides the package name for the given import path.

func WithModulePackageTypes

func WithModulePackageTypes(pkgPath string, types ...reflect.Type) ModuleOption

WithModulePackageTypes adds types for the specified package import path.

func WithModuleSeedTypes

func WithModuleSeedTypes(types ...reflect.Type) ModuleOption

WithModuleSeedTypes groups the provided types by their reflect package and includes them in the resulting module.

type NamedInt

type NamedInt int

type NamedRecursive

type NamedRecursive struct {
	Next *NamedRecursive
}

Named recursive type; FromReflect may treat deep unnamed recursion as unsupported. We still include a simple self-referential named struct to cover the basic case that is representable.

type R

type R interface{ Error() string }

Named interface for coverage

type V

type V struct{ N int }

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL