metago

package module
v0.0.0-...-570ac5d Latest Latest
Warning

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

Go to latest
Published: Aug 23, 2019 License: MIT Imports: 17 Imported by: 0

README

metago

🚧 this project is under construction 🚧

metago is a meta programming library for go.

This idea is based on wire and V.

What is metago?

metago is work with markers.

Below code is a example about print field name & field value.

//+build metago

package main

import (
	"fmt"

	"github.com/vvakame/til/go/metago"
)

type Foo struct {
	ID   int64
	Name string
}

func main() {
	obj := &Foo{1, "vvakame"}
	mv := metago.ValueOf(obj)
	for _, mf := range mv.Fields() {
		fmt.Println(mf.Name(), mf.Value())
	}
}

This template code will be processed and generate below code. This code work actually.

// Code generated by metago. DO NOT EDIT.

//+build !metago

package main

import (
	"fmt"
)

type Foo struct {
	ID   int64
	Name string
}

func main() {
	obj := &Foo{1, "vvakame"}

	{
		fmt.Println("ID", obj.ID)
	}
	{
		fmt.Println("Name", obj.Name)
	}
}

metago package looks like reflect package. If you want to check example. see testbed directory.

Main function is ...

  • get metago.Value typed value by mv := metago.ValueOf(obj)
  • expand processes to each fields by for _, mf := range mv.Fields()
  • get field name by mf.Name()
  • get field value by mf.Value()
  • get field struct tag by something likes mf.StructTagGet("json")
  • eliminate statement by type assertion ( mf.Value().(time.Time) ) and condition statement
    • type switch support
  • define inline template. it has 1st argument is metago.Value types

How to install metago

$ go get -u github.com/vvakame/metago/cmd/metago
$ metago -v .

Motivation

Go is not much flexible for type and code. We must write a lot of boiler plate code. so, We want to generate code automatically.

Ideas ✨

  1. construct AST by code and convert it to source code.

It is terrible ideas. AST is a data, not code. We want to write a code. not AST. It is very painful and not easy & convenience.

  1. construct go code by text.

It is common way to generate code. for example, jwg uses own Printf function to construct code. gqlgen uses text/template package.

It is easy way, but We can't get support from IDE. IDE can't understand some text is go code or not. We must required that run & compile to find some errors.

  1. translate go code to other go code.

metago uses some "meta" go code. It is a valid go code, but it is template. parse template code to AST. and AST will be convert to another go code.

TODO

  • improve test cases
  • generate new struct types
  • generate method definitions

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	TargetPackages []string
}

type ErrorLevel

type ErrorLevel int
const (
	ErrorLevelError ErrorLevel = iota
	ErrorLevelWarning
	ErrorLevelNotice
	ErrorLevelDebug
)

func (ErrorLevel) String

func (lvl ErrorLevel) String() string

type Field

type Field interface {
	Name() string
	StructTagGet(string) string
	Value() interface{}
}

type FileResult

type FileResult struct {
	Package           *packages.Package
	File              *ast.File
	BaseFilePath      string
	GeneratedFilePath string
	GeneratedCode     string
	Errors            NodeErrors
}

type NodeError

type NodeError struct {
	ErrorLevel ErrorLevel
	Pkg        *packages.Package
	Node       ast.Node `json:"-"`
	Message    string
}

func (*NodeError) Error

func (nErr *NodeError) Error() string

func (*NodeError) MarshalJSON

func (nErr *NodeError) MarshalJSON() ([]byte, error)

type NodeErrors

type NodeErrors []*NodeError

func (NodeErrors) Error

func (nErrs NodeErrors) Error() string

func (NodeErrors) MarshalJSON

func (nErrs NodeErrors) MarshalJSON() ([]byte, error)

type Processor

type Processor interface {
	Process(cfg *Config) (*Result, error)
}

func NewProcessor

func NewProcessor() (Processor, error)

type Result

type Result struct {
	CompileErrors []packages.Error
	Results       []*FileResult
}

type Value

type Value interface {
	Fields() []Field
}

func ValueOf

func ValueOf(interface{}) Value

Jump to

Keyboard shortcuts

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