astreflect

package module
v0.0.0-...-8b04d52 Latest Latest
Warning

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

Go to latest
Published: Jan 29, 2021 License: Apache-2.0 Imports: 14 Imported by: 0

README

Golang AST reflection

Gopher

Package astreflect defines Golang ast based types reflection.

The API is expected to be simpler and less verbose than go/types package, that looks more like reflect.

Usage

This package allows reading and scanning the content of go files based on the non-runtime AST definitions.

The astreflect.PackageMap contains context of mapped packages with their structs and dependencies.

The map could get loaded by using LoadPackages function or astreflect.PackageMap method with the same name. Both of these loads provided input packages, whereas the method gets only required that doesn't already exist in itself.

Example:

package main

import (
	"fmt"
	"os"

	"github.com/kucjac/astreflect"
)

func main() {
	pkgs, err := astreflect.LoadPackages(astreflect.LoadConfig{
		// Paths should contain file system paths to related golang directories.			
		// Paths: []string{"/home/user/golang/src/github.com/kucjac/astreflect", "./../mypackage"},
		
		// PkgNames should contain full package names to get. It could be set along with the 'Paths' field.
		PkgNames:   []string{"github.com/kucjac/astreflect"},
		BuildFlags: nil,
		Verbose:    false,
	})
	if err != nil {
		fmt.Printf("Err: Loading packages failed: %s\n", err)
		os.Exit(1)
	}
}

Based on loaded packages a developer can operate on the types loaded along with these packages.

// Let's get the astreflect.Type interface and check it's content.
t, ok := pkgs.TypeOf("astreflect.Type", nil)
if !ok {
    fmt.Println("Err: getting astreflect.Type failed")
    os.Exit(1)
}

// We can get the name of given type, with or without it's identifier.
fmt.Println(t.Name(true, "")) // astreflect.Type
fmt.Println(t.Name(false, "")) // Type

// We can set up current working package context while getting the name. 
// This way the result should not contain the identifier.
// The package context could be an identifier or even better full package name.
fmt.Println(t.Name(true, "astreflect")) // Type

While the packages got loaded not only selected packages were provided but also all dependency imports.

mutexType, ok := pkgs.TypeOf("*sync.Mutex", nil)
if !ok {
	fmt.Println("Err: getting *sync.Mutex failed")
	os.Exit(1)
}

fmt.Println(mutexType.Name(true, "")) // *sync.Mutex
// We can dereference the pointer, slice, array, channel or wrapper by using 'Elem' method. 
mutexType = mutexType.Elem()
fmt.Println(mutexType.Name(true, "")) // sync.Mutex

The astreflect allows to easily create and operate on given types with very simple API.

structType, ok := pkgs.TypeOf("astreflect.StructType")
if !ok {
	fmt.Println("Err: getting astreflect.StructType failed")
	os.Exit(1)
}

// Let's create a chan of slices of pointers to the given StructType.
newType := astreflect.ChanOf(astreflect.RecvOnly, astreflect.SliceOf(astreflect.PointerTo(structType)))
fmt.Println(sliceType) // chan <-[]*astreflect.StructType

The package reads all methods and structure fields for loaded types along with the metadata like receiver type (methods) and name, or parameter names.

sliceType, ok := pkgs.TypeOf("astreflect.ArrayType")
if !ok {
	fmt.Println("Err: getting astreflect.StructType failed")
	os.Exit(1)
}

st := sliceType.(*astreflect.StructType)
for i, sField := range st.Fields {
	fmt.Printf("Field: %d - %s\t%s\n", i, sField.Name, sField.Type)
}

for i, method := range st.Methods {
	fmt.Printf("Method: %d - %s\n", i, method)
}

If during operation on given PackagesMap there is a need of loading more packages it is possible by using the LoadPackages files.

err = pkgs.LoadPackaes(astreflect.LoadConfig{PkgNames: []string{"github.com/username/package"}})
if err != nil {
	fmt.Printf("Err: loading new packages failed: %v\n", err)
	os.Exit(1)
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Implements

func Implements(t Type, interfaceType *InterfaceType) bool

Implements checks if the type t implements interface 'interfaceType'.

func PackageNameOfDir

func PackageNameOfDir(srcDir string) (string, error)

PackageNameOfDir get package import path via dir

Types

type ArrayType

type ArrayType struct {
	ArrayKind Kind // Could be either Slice or Array
	Type      Type
	ArraySize int
}

ArrayType is the array or slice representing type.

func ArrayOf

func ArrayOf(inner Type, size int) *ArrayType

ArrayOf creates the Array of given size with inner type.

func SliceOf

func SliceOf(inner Type) *ArrayType

SliceOf creates the Slice of given inner types.

func (ArrayType) Elem

func (a ArrayType) Elem() Type

Elem implements Type interface.

func (ArrayType) Equal

func (a ArrayType) Equal(another Type) bool

Equal implements Type interface.

func (ArrayType) FullName

func (a ArrayType) FullName() string

FullName implements Type interface.

func (ArrayType) Kind

func (a ArrayType) Kind() Kind

Kind implements Type interface.

func (ArrayType) Name

func (a ArrayType) Name(identifier bool, packageContext string) string

Name implements Type interface.

func (ArrayType) String

func (a ArrayType) String() string

String implements Type interface.

func (ArrayType) Zero

func (a ArrayType) Zero(identified bool, packageContext string) string

Zero implements Type interface.

type BuiltInType

type BuiltInType struct {
	TypeName string
	StdKind  Kind
}

BuiltInType is the built in type definition.

func (BuiltInType) Elem

func (b BuiltInType) Elem() Type

Elem implements Type interface.

func (BuiltInType) Equal

func (b BuiltInType) Equal(another Type) bool

func (BuiltInType) FullName

func (b BuiltInType) FullName() string

FullName implements Type interface.

func (BuiltInType) Kind

func (b BuiltInType) Kind() Kind

Kind implements Type interface.

func (BuiltInType) Name

func (b BuiltInType) Name(_ bool, _ string) string

Name implements Type interface.

func (BuiltInType) String

func (b BuiltInType) String() string

String implements Type interface.

func (BuiltInType) Zero

func (b BuiltInType) Zero(_ bool, _ string) string

Zero implements Type interface.

type ChanDir

type ChanDir int

A ChanDir value indicates a channel direction.

const (
	SendRecv ChanDir = iota
	SendOnly
	RecvOnly
)

The direction of a channel is indicated by one of these constants.

type ChanType

type ChanType struct {
	Type Type
	Dir  ChanDir
}

ChanType is the type representing channel.

func ChanOf

func ChanOf(dir ChanDir, chanType Type) *ChanType

ChanOf creates the channel of given type with given direction.

func (ChanType) Elem

func (c ChanType) Elem() Type

Elem gets the channel element type.

func (ChanType) Equal

func (c ChanType) Equal(another Type) bool

Equal implements Type interface.

func (ChanType) FullName

func (c ChanType) FullName() string

FullName implements Type interface.

func (ChanType) Kind

func (c ChanType) Kind() Kind

Kind gets the kind of the type.

func (ChanType) Name

func (c ChanType) Name(identified bool, packageContext string) string

Name implements Type interface.

func (ChanType) String

func (c ChanType) String() string

String implements fmt.Stringer interface.

func (ChanType) Zero

func (c ChanType) Zero(_ bool, _ string) string

Zero implements Type interface.

type FuncParam

type FuncParam struct {
	Name string
	Type Type
}

FuncParam is the input/output parameter of functions and methods.

func (FuncParam) String

func (f FuncParam) String() string

String implements fmt.Stringer interface.

type FunctionType

type FunctionType struct {
	Comment  string
	Pkg      *Package
	Receiver *Receiver
	FuncName string
	In       []FuncParam
	Out      []FuncParam
	Variadic bool
}

FunctionType is the function type used for getting.

func (FunctionType) Elem

func (f FunctionType) Elem() Type

Elem implements Type interface.

func (FunctionType) Equal

func (f FunctionType) Equal(another Type) bool

Equal implements Type interface.

func (FunctionType) FullName

func (f FunctionType) FullName() string

FullName implements Type interface.

func (FunctionType) Kind

func (f FunctionType) Kind() Kind

Kind implements Type interface.

func (FunctionType) Name

func (f FunctionType) Name(identified bool, packageContext string) string

Name implements Type interface.

func (FunctionType) Package

func (f FunctionType) Package() *Package

Package implements Type interface.

func (FunctionType) String

func (f FunctionType) String() string

String implements Type interface.

func (FunctionType) Zero

func (f FunctionType) Zero(_ bool, _ string) string

Zero implements Type interface.

type InterfaceType

type InterfaceType struct {
	Pkg           *Package
	Comment       string
	InterfaceName string
	Methods       []FunctionType
}

InterfaceType is the interface type model definition.

func (InterfaceType) Elem

func (i InterfaceType) Elem() Type

Elem implements Type interface.

func (InterfaceType) Equal

func (i InterfaceType) Equal(another Type) bool

Equal implements Type interface.

func (InterfaceType) FullName

func (i InterfaceType) FullName() string

FullName implements Type interface.

func (InterfaceType) Implements

func (i InterfaceType) Implements(another *InterfaceType) bool

Implements checks if given interface implements another interface.

func (InterfaceType) Kind

func (i InterfaceType) Kind() Kind

Kind implements Type interface.

func (InterfaceType) Name

func (i InterfaceType) Name(identified bool, packageContext string) string

Name implements Type interface.

func (InterfaceType) Package

func (i InterfaceType) Package() *Package

Package implements Type interface

func (InterfaceType) String

func (i InterfaceType) String() string

String implements Type interface.

func (InterfaceType) Zero

func (i InterfaceType) Zero(_ bool, _ string) string

Zero implements Type interface.

type Kind

type Kind uint

A Kind represents the specific kind of type that a Type represents. The zero Kind is not a valid kind.

const (
	Invalid Kind = iota
	Bool
	Int
	Int8
	Int16
	Int32
	Int64
	Uint
	Uint8
	Uint16
	Uint32
	Uint64
	Uintptr
	Float32
	Float64
	Complex64
	Complex128
	String
	Array
	Chan
	Func
	Interface
	Map
	Ptr
	Slice
	Struct
	UnsafePointer
	Wrapper
)

Enumerated kind representations.

func IsBuiltIn

func IsBuiltIn(kindName string) (Kind, bool)

IsBuiltIn checks if given name is a built in type.

func (Kind) IsBuiltin

func (k Kind) IsBuiltin() bool

IsBuiltin checks if given kind is

func (Kind) IsNumber

func (k Kind) IsNumber() bool

IsNumber checks if given kind is of number (integers, floats)

func (Kind) String

func (k Kind) String() string

String implements fmt.Stringer interface.

type LoadConfig

type LoadConfig struct {
	// Paths could be absolute or relative path to given directory.
	Paths []string
	// PkgNames should be full pkg name i.e.: 'golang.org/x/mod/modfile'
	PkgNames []string
	// BuildFlags are the flags used by the ast.
	BuildFlags []string
	// Verbose sets the loader in verbose mode.
	Verbose bool
}

LoadConfig contains configuration used while loading packages.

type MapType

type MapType struct {
	Key   Type
	Value Type
}

MapType is the type wrapper for the standar key value map type.

func MapOf

func MapOf(key, value Type) *MapType

MapOf creates a map of given key, value types.

func (MapType) Elem

func (m MapType) Elem() Type

Elem as the map has both the key and value it needs to be dereferenced manually.

func (MapType) Equal

func (m MapType) Equal(another Type) bool

Equal implements Type interface.

func (MapType) FullName

func (m MapType) FullName() string

FullName implements Type interface.

func (MapType) Kind

func (m MapType) Kind() Kind

Kind implements Type interface.

func (MapType) Name

func (m MapType) Name(identified bool, packageContext string) string

Name implements Type interface.

func (MapType) String

func (m MapType) String() string

String implements Type interface.

func (MapType) Zero

func (m MapType) Zero(_ bool, _ string) string

Zero implements Type interface.

type Package

type Package struct {
	Path         string
	Identifier   string
	Interfaces   []*InterfaceType
	Structs      []*StructType
	Functions    []*FunctionType
	WrappedTypes []*WrappedType
	Types        map[string]Type

	sync.Mutex
	// contains filtered or unexported fields
}

Package is the golang package reflection container. It contains all interfaces, structs, functions and type wrappers that are located inside of it.

func (*Package) GetFunction

func (p *Package) GetFunction(name string) (*FunctionType, bool)

GetFunction gets the function type by it's name.

func (*Package) GetInterfaceType

func (p *Package) GetInterfaceType(name string) (*InterfaceType, bool)

GetInterfaceType gets the interface by it's name.

func (*Package) GetPkgPath

func (p *Package) GetPkgPath() PkgPath

GetPkgPath gets the PkgPath for given package.

func (*Package) GetStructType

func (p *Package) GetStructType(name string) (*StructType, bool)

GetStructType gets the struct type by it's name.

func (*Package) GetType

func (p *Package) GetType(name string) (Type, bool)

GetType gets concurrently package type.

func (*Package) GetWrappedType

func (p *Package) GetWrappedType(name string) (*WrappedType, bool)

GetWrappedType gets the wrapped type by it's name.

func (*Package) IsStandard

func (p *Package) IsStandard() bool

IsStandard checks if given package is a standard package.

func (*Package) MustGetType

func (p *Package) MustGetType(name string) Type

MustGetType get the type with given 'name' from given package. If the type is not found the function panics.

type PackageMap

type PackageMap map[string]*Package

PackageMap is a slice wrapper over Package type.

func LoadPackages

func LoadPackages(cfg LoadConfig) (PackageMap, error)

LoadPackages parses Golang packages using AST.

func (PackageMap) LoadPackages

func (p PackageMap) LoadPackages(cfg LoadConfig) error

LoadPackages updates the packages in the given PackageMap. The function would get and parse only packages that doesn't currently exists in given map.

func (PackageMap) MustGetByPath

func (p PackageMap) MustGetByPath(path string) *Package

func (PackageMap) PackageByIdentifier

func (p PackageMap) PackageByIdentifier(identifier string) (*Package, bool)

PackageByIdentifier gets the package by provided identifier. If there is more than one package with given identifier The function would return the first matching package.

func (PackageMap) PackageByPath

func (p PackageMap) PackageByPath(path string) (*Package, bool)

PackageByPath gets the package by provided path.

func (*PackageMap) TypeOf

func (p *PackageMap) TypeOf(typeOf string, packageContext *Package) (Type, bool)

TypeOf gets the resulting type for provided 'typeOf'. If the packageContext is defined the values without identifier would be found within given package also.

type Packager

type Packager interface {
	// Package gets the Package for given type.
	Package() *Package
}

Packager is the interface that allows to get Type packages. Only the Types that contains the name stores the Package i.e.: StructType, InterfaceType, WrappedType, FunctionType.

type PkgPath

type PkgPath string

PkgPath is the string package that contains full package name.

func (PkgPath) FullName

func (p PkgPath) FullName() string

FullName gets the full name of given PkgPath in a string type.

func (PkgPath) Identifier

func (p PkgPath) Identifier() string

Identifier gets package identifier.

func (PkgPath) IsStandard

func (p PkgPath) IsStandard() bool

IsStandard checks if the package is standard.

type PointerType

type PointerType struct {
	PointedType Type
}

PointerType is the type implementation that defines pointer type.

func PointerTo

func PointerTo(pointsTo Type) *PointerType

PointerTo creates a pointer of given type.

func (PointerType) Elem

func (p PointerType) Elem() Type

Elem implements Type interface.

func (PointerType) Equal

func (p PointerType) Equal(another Type) bool

Equal implements Type interface.

func (PointerType) FullName

func (p PointerType) FullName() string

FullName implements Type interface.

func (PointerType) Kind

func (p PointerType) Kind() Kind

Kind implements Type interface.

func (PointerType) Name

func (p PointerType) Name(identified bool, pkgContext string) string

Name implements Type interface.

func (PointerType) String

func (p PointerType) String() string

String implements Type interface.

func (PointerType) Zero

func (p PointerType) Zero(_ bool, _ string) string

Zero implements Type interface.

type Receiver

type Receiver struct {
	Name string
	Type Type
}

Receiver is the function (method) receiver with the name and a pointer flag.

func (*Receiver) IsPointer

func (r *Receiver) IsPointer() bool

IsPointer checks if the receiver type is a pointer.

func (*Receiver) String

func (r *Receiver) String() string

type StructField

type StructField struct {
	Name      string
	Comment   string
	Type      Type
	Tag       StructTag
	Index     []int
	Embedded  bool
	Anonymous bool
}

StructField is a structure field model.

func (StructField) String

func (s StructField) String() string

String implements fmt.Stringer interface.

type StructTag

type StructTag string

A StructTag is the tag string in a struct field.

By convention, tag strings are a concatenation of optionally space-separated key:"value" pairs. Each key is a non-empty string consisting of non-control characters other than space (U+0020 ' '), quote (U+0022 '"'), and colon (U+003A ':'). Each value is quoted using U+0022 '"' characters and Go string literal syntax.

func (StructTag) Get

func (tag StructTag) Get(key string) string

Get returns the value associated with key in the tag string. If there is no such key in the tag, Get returns the empty string. If the tag does not have the conventional format, the value returned by Get is unspecified. To determine whether a tag is explicitly set to the empty string, use Lookup.

func (StructTag) Lookup

func (tag StructTag) Lookup(key string) (value string, ok bool)

Lookup returns the value associated with key in the tag string. If the key is present in the tag the value (which may be empty) is returned. Otherwise the returned value will be the empty string. The ok return value reports whether the value was explicitly set in the tag string. If the tag does not have the conventional format, the value returned by Lookup is unspecified.

type StructType

type StructType struct {
	Pkg      *Package
	Comment  string
	TypeName string
	Fields   []StructField
	Methods  []FunctionType
}

StructType is the struct type reflection.

func (*StructType) Elem

func (s *StructType) Elem() Type

Elem implements Type interface.

func (*StructType) Equal

func (s *StructType) Equal(another Type) bool

Equal implements Type interface.

func (*StructType) FullName

func (s *StructType) FullName() string

FullName implements Type interface.

func (*StructType) Implements

func (s *StructType) Implements(interfaceType *InterfaceType, pointer bool) bool

Implements checks if given structure implements provided interface.

func (*StructType) Kind

func (s *StructType) Kind() Kind

Kind implements Type interface.

func (*StructType) Name

func (s *StructType) Name(identifier bool, packageContext string) string

Name implements Type interface.

func (*StructType) Package

func (s *StructType) Package() *Package

PkgPath implements Type interface.

func (*StructType) String

func (s *StructType) String() string

String implements Type interface.

func (*StructType) Zero

func (s *StructType) Zero(identified bool, packageContext string) string

Zero implements Type interface.

type Type

type Type interface {
	// Name gets the type name with or without package identifier.
	// An optional packageContext parameter defines the name of the package (full package name) that is expected to be
	// within given context of search. This could be used to get the chain of names with respect to some package.
	// Example:
	//	Developer wants to generate some additional method for the type 'X' within package 'my.com/testing/pkg'.
	//	In order to generate valid names for the imported types the identity needs to be set to 'true'.
	//	But current package context ('my.com/testing/pkg') should not be used be prefixed with the identifier.
	//	Thus an optional 'packageContext' parameter needs to be set to 'my.com/testing/pkg'.
	Name(identified bool, packageContext string) string
	// FullName gets the full name of given type with the full package name and a type.
	FullName() string
	// Kind gets the Kind of given type.
	Kind() Kind
	// Elem gets the wrapped, pointed, base of
	Elem() Type
	// String gets the full name string representation of given type.
	String() string
	// Zero gets zero value string of given type.
	Zero(identified bool, packageContext string) string
	// Equal checks if the types matches exact.
	Equal(another Type) bool
}

Type is the interface used by all golang type reflections in package.

func Dereference

func Dereference(t Type) Type

Dereference is getting Type dereferenced basic value. If the value is basic returns nil.

func GetBuiltInType

func GetBuiltInType(name string) (Type, bool)

GetBuiltInType gets the built in type with given name.

func MustGetBuiltInType

func MustGetBuiltInType(name string) Type

MustGetBuiltInType gets the built in type with given name. If the type is not found the function panics.

type WrappedType

type WrappedType struct {
	Comment     string
	Pkg         *Package
	WrapperName string
	Type        Type
}

WrappedType is the type that represents wrapped and named another type. I.e.: 'type Custom int' would be a WrappedType over BuiltIn(int) type.

func (WrappedType) Elem

func (w WrappedType) Elem() Type

Elem implements Type interface.

func (WrappedType) Equal

func (w WrappedType) Equal(another Type) bool

Equal implements Type interface.

func (WrappedType) FullName

func (w WrappedType) FullName() string

FullName implements Type interface.

func (WrappedType) Kind

func (w WrappedType) Kind() Kind

Kind implements Type interface.

func (WrappedType) Name

func (w WrappedType) Name(identified bool, packageContext string) string

Name implements Type interface.

func (WrappedType) Package

func (w WrappedType) Package() *Package

PkgPath implements Type interface.

func (WrappedType) String

func (w WrappedType) String() string

String implements Type interface.

func (WrappedType) Zero

func (w WrappedType) Zero(identified bool, packageContext string) string

Zero implements Type interface.

Jump to

Keyboard shortcuts

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