macro

package module
v0.0.0-...-e14fb06 Latest Latest
Warning

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

Go to latest
Published: Mar 10, 2020 License: Apache-2.0 Imports: 8 Imported by: 0

README

macro wip draft

A go generate macro processor, using AST processing and go itself - inspired by rust macros. Technically, a temporary go module is created for the actual go module which is solely created based on your #[...] macro directives. It is invoked with the according AST input and output context parameters.

example

Use go get github.com/ee4g/macro in your project and create a file like gen.go:

package main

import "github.com/ee4g/macro"

//go:generate go run gen.go

func main(){
    macro.MustApply()
}

Usage is as follows

package main

import "fmt"

// Import macros should be the first macros in a file and provide the scope
// for all following macros. *import* is a reserved keyword. You need
// to also declare a
//  #[require] github.com/mycompany/mypackage 1.2.3
// within your go.mod file.
//
// #[import] github.com/mycompany/mypackage // just a normal go import


// A macro is a bunch of method calls within a comment group.
// They are executed with the current context which is the 
// directly following AST type, ignoring any comment).
// So, the following macros are applied to Entity.
//
// #[mypackage.Stringer()]
// #[mypackage.SQL("my_entity_table")

// Entity has a normal comment which is not polluted from the 
// macro declaration above. Macros are implementation specific and therefore
// unimportant to document here.
type Entity struct{
    ID string
    Name string
}

/*
 This is also a multiline macro, applied to the method hello below.
    #[
        mypackage.Get("/hello/{name}/say")
        mypackage.OpenAPI()
        // a macro comment
        mypackage.SecurityRole(&mypackage.Role{"admin}") // another comment
    ]
*/

// hello is a Rest endpoint.
func hello(name string)string{
    return "hello "+name
}

To define a custom macro, simply declare it like this:

package mypackage

// Macros is a hardcoded name and must always be present
// and is created once per macro.
type Macros struct{
    Method tbd.Method // Method is injected automatically
    Type tbd.Type // Type is injected automatically
    AST tbd.Type // AST is injected and contains the annotated tree
    Out tbd.Out // Out is injected and is used to generate code
}

// the Macro signature must be reflected here
func (m *Macros) OpenAPI(){
    // whatever
}

func (m *Macros) Get(route string){
    // whatever
}

func (m *Macros) SecurityRole(r *Role){
    // whatever
}

// you can define custom types
type Role struct{
    Name string
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Apply

func Apply() error

Apply executes all macros within the current context.

func MustApply

func MustApply()

Types

type Block

type Block struct {
	Lines     []*Line
	Annotated ast.Node
	Parent    *File
}

Block is a collection of lines

func (*Block) String

func (b *Block) String() string

type File

type File struct {
	// contains filtered or unexported fields
}

A File contains all imports and macros together

func (*File) String

func (f *File) String() string

type Import

type Import struct {
	Pos       Position
	Statement string
	SrcText   string
}

Import for packages

func (Import) String

func (i Import) String() string

type Line

type Line struct {
	Pos       Position
	Statement string
	SrcText   string
}

Line

type Position

type Position struct {
	File   *File
	Line   int
	Column int
}

A Position is the absolute line number starting at 1 and column also starting at 1, just as IDEs and the compiler does.

Jump to

Keyboard shortcuts

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