annotation

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Nov 27, 2019 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

This package is designed to facilitate the generation of code based on annotations.

Index

Examples

Constants

View Source
const Header = "" +
	"// Generated by github.com/index0h/go-annotation\n" +
	"// DO NOT EDIT\n" +
	"// @FileIsGenerated(true)\n"

Default prefix for file rendering. Annotation FileIsGenerated is used internally to check, that file could be overwritten.

Variables

This section is empty.

Functions

This section is empty.

Types

type AnnotationParser

type AnnotationParser interface {
	SetAnnotation(name string, annotationType interface{})
	Parse(content string) (annotations []interface{})
}

type ArraySpec

type ArraySpec struct {
	// Allowed types: *SimpleSpec, *ArraySpec, *MapSpec, *StructSpec, *InterfaceSpec, *FuncSpec.
	Value Spec
	// Expression with int result, which could be calculated at compilation time, or "...".
	Length string
}

ArraySpec represents specification of array or slice type.

func (*ArraySpec) Clone

func (m *ArraySpec) Clone() interface{}

Creates deep copy of ArraySpec model.

func (*ArraySpec) FetchImports

func (m *ArraySpec) FetchImports(file *File) []*Import

Fetches list of Import models registered in file argument, which are used by Value and Length fields.

Example
file := &File{
	Name:        "file.go",
	PackageName: "packageName",
	ImportGroups: []*ImportGroup{
		{
			Imports: []*Import{
				{Namespace: "strings"},
				{Namespace: "fmt"},
			},
		},
	},
}

model := &ArraySpec{
	Value: &SimpleSpec{
		PackageName: "strings",
		TypeName:    "Builder",
	},
}

usedImports := model.FetchImports(file)

fmt.Println(usedImports[0].String())
Output:

import "strings"

func (*ArraySpec) RenameImports

func (m *ArraySpec) RenameImports(oldAlias string, newAlias string)

Renames import aliases, which are used by Value and Length fields.

Example
model := &ArraySpec{
	Value: &SimpleSpec{
		PackageName: "strings",
		TypeName:    "Builder",
	},
}

model.RenameImports("strings", "custom_strings")

fmt.Println(model.String())
Output:

[]custom_strings.Builder
Example (Length)
model := &ArraySpec{
	Value: &SimpleSpec{
		TypeName: "string",
	},
	Length: "packageName.Length",
}

model.RenameImports("packageName", "custom_packageName")

fmt.Println(model.String())
Output:

[custom_packageName.Length]string

func (*ArraySpec) String

func (m *ArraySpec) String() string

Renders ArraySpec model to string.

Example (Array)
model := &ArraySpec{
	Value: &SimpleSpec{
		PackageName: "packageName",
		TypeName:    "typeName",
		IsPointer:   true,
	},
	Length: "5",
}

fmt.Println(model.String())
Output:

[5]*packageName.typeName
Example (Slice)
model := &ArraySpec{
	Value: &SimpleSpec{
		TypeName: "string",
	},
}

fmt.Println(model.String())
Output:

[]string

func (*ArraySpec) Validate

func (m *ArraySpec) Validate()

Validates ArraySpec model fields.

type Cloner

type Cloner interface {
	Clone() interface{}
}

type Const

type Const struct {
	Name string
	// Expression with, which could be calculated in compilation time, or empty.
	Value       string
	Comment     string
	Annotations []interface{}
	Spec        *SimpleSpec
}

Const represents const declaration.

func (*Const) Clone

func (m *Const) Clone() interface{}

Creates deep copy of Const model.

func (*Const) FetchImports

func (m *Const) FetchImports(file *File) []*Import

Fetches list of Import models registered in file argument, which are used by Spec and Value fields.

Example
file := &File{
	Name:        "file.go",
	PackageName: "packageName",
	ImportGroups: []*ImportGroup{
		{
			Imports: []*Import{
				{Namespace: "time"},
				{Namespace: "fmt"},
			},
		},
	},
}

model := &Const{
	Name: "OneHour",
	Spec: &SimpleSpec{
		PackageName: "time",
		TypeName:    "Duration",
	},
	Value: "60*60*time.Second",
}

usedImports := model.FetchImports(file)

fmt.Println(usedImports[0].String())
Output:

import "time"
Example (Value)
file := &File{
	Name:        "file.go",
	PackageName: "packageName",
	ImportGroups: []*ImportGroup{
		{
			Imports: []*Import{
				{Namespace: "time"},
				{Namespace: "fmt"},
			},
		},
	},
}

model := &Const{
	Name:  "OneHour",
	Value: "60*60*time.Second",
}

usedImports := model.FetchImports(file)

fmt.Println(usedImports[0].String())
Output:

import "time"

func (*Const) RenameImports

func (m *Const) RenameImports(oldAlias string, newAlias string)

Renames import aliases, which are used by Spec and Value fields.

Example
model := &Const{
	Name: "OneHour",
	Spec: &SimpleSpec{
		PackageName: "time",
		TypeName:    "Duration",
	},
	Value: "60*60*time.Second",
}

model.RenameImports("time", "custom_time")

fmt.Println(model.String())
Output:

const OneHour custom_time.Duration = 60*60*custom_time.Second
Example (Value)
model := &Const{
	Name:  "OneHour",
	Value: "60*60*time.Second",
}

model.RenameImports("time", "custom_time")

fmt.Println(model.String())
Output:

const OneHour = 60*60*custom_time.Second

func (*Const) String

func (m *Const) String() string

Renders Const model to string. Const inside ConstGroup could be without Value, but single const requires Value field.

Example
model := &Const{
	Name:    "SecondsInDay",
	Value:   "24*60*60",
	Comment: "Count of seconds in one day",
}

fmt.Println(model.String())
Output:

// Count of seconds in one day
const SecondsInDay = 24*60*60
Example (Spec)
model := &Const{
	Name:    "SecondsInDay",
	Value:   "24*60*60*time.Second",
	Comment: "Count of seconds in one day",
	Spec: &SimpleSpec{
		PackageName: "time",
		TypeName:    "Duration",
	},
}

fmt.Println(model.String())
Output:

// Count of seconds in one day
const SecondsInDay time.Duration = 24*60*60*time.Second

func (*Const) Validate

func (m *Const) Validate()

Validates Const model fields.

type ConstGroup

type ConstGroup struct {
	Comment     string
	Annotations []interface{}
	Consts      []*Const
}

ConstGroup represents list of const declaration.

func (*ConstGroup) Clone

func (m *ConstGroup) Clone() interface{}

Creates deep copy of ConstGroup model.

func (*ConstGroup) FetchImports

func (m *ConstGroup) FetchImports(file *File) []*Import

Fetches list of Import models registered in file argument, which are used by Consts field.

Example
file := &File{
	Name:        "file.go",
	PackageName: "packageName",
	ImportGroups: []*ImportGroup{
		{
			Imports: []*Import{
				{Namespace: "time"},
				{Namespace: "fmt"},
			},
		},
	},
}

model := &ConstGroup{
	Consts: []*Const{
		{
			Name: "OneHour",
			Spec: &SimpleSpec{
				PackageName: "time",
				TypeName:    "Duration",
			},
			Value: "60*60*time.Second",
		},
	},
}

usedImports := model.FetchImports(file)

fmt.Println(usedImports[0].String())
Output:

import "time"

func (*ConstGroup) RenameImports

func (m *ConstGroup) RenameImports(oldAlias string, newAlias string)

Renames import aliases, which are used by Consts field.

Example
model := &ConstGroup{
	Consts: []*Const{
		{
			Name: "OneHour",
			Spec: &SimpleSpec{
				PackageName: "time",
				TypeName:    "Duration",
			},
			Value: "60*60*time.Second",
		},
		{
			Name: "TwoHours",
			Spec: &SimpleSpec{
				PackageName: "time",
				TypeName:    "Duration",
			},
			Value: "2*60*60*time.Second",
		},
	},
}

model.RenameImports("time", "custom_time")

fmt.Println(model.String())
Output:

const (
OneHour custom_time.Duration = 60*60*custom_time.Second
TwoHours custom_time.Duration = 2*60*60*custom_time.Second
)

func (*ConstGroup) String

func (m *ConstGroup) String() string

Renders ConstGroup model to string. If ConstGroup contain only one const, without own comment, it will be rendered as single const, without braces.

Example
model := &ConstGroup{
	Comment: "Some seconds constants",
	Consts: []*Const{
		{
			Name:    "SecondsInDay",
			Value:   "24*60*60",
			Comment: "Count of seconds in one day",
		},
		{
			Name:  "SecondsInWeek",
			Value: "SecondsInDay*7",
		},
		{
			Name: "CopyOfPreviousConstant",
		},
	},
}

fmt.Println(model.String())
Output:

// Some seconds constants
const (
// Count of seconds in one day
SecondsInDay = 24*60*60
SecondsInWeek = SecondsInDay*7
CopyOfPreviousConstant
)
Example (OneConst)
model := &ConstGroup{
	Consts: []*Const{
		{
			Name:  "SecondsInDay",
			Value: "24*60*60",
		},
	},
}

fmt.Println(model.String())
Output:

const SecondsInDay = 24*60*60

func (*ConstGroup) Validate

func (m *ConstGroup) Validate()

Validates ConstGroup model fields.

type Field

type Field struct {
	Name string
	// Used for render *StructSpec
	Tag         string
	Comment     string
	Annotations []interface{}
	// Allowed types: *SimpleSpec, *ArraySpec, *MapSpec, *StructSpec, *InterfaceSpec, *FuncSpec.
	Spec Spec
}

Field represents field of struct, interface, func param, func result or func related field.

func (*Field) Clone

func (m *Field) Clone() interface{}

Creates deep copy of Field model.

func (*Field) FetchImports

func (m *Field) FetchImports(file *File) []*Import

Fetches list of Import models registered in file argument, which are used by Spec field.

func (*Field) RenameImports

func (m *Field) RenameImports(oldAlias string, newAlias string)

Renames import aliases, which are used by Spec field.

func (*Field) Validate

func (m *Field) Validate()

Validates Field model fields.

type File

type File struct {
	Name         string
	Content      string
	PackageName  string
	Comment      string
	Annotations  []interface{}
	ImportGroups []*ImportGroup
	ConstGroups  []*ConstGroup
	VarGroups    []*VarGroup
	TypeGroups   []*TypeGroup
	Funcs        []*Func
}

func (*File) Clone

func (m *File) Clone() interface{}

Creates deep copy of File model.

func (*File) RenameImports

func (m *File) RenameImports(oldAlias string, newAlias string)

Renames import aliases, which are used by any field of File, including Content.

Example
model := &File{
	PackageName: "main",
	ImportGroups: []*ImportGroup{
		{
			Imports: []*Import{
				{
					Namespace: "fmt",
				},
			},
		},
	},
	Funcs: []*Func{
		{
			Name:    "main",
			Content: "fmt.Println(\"Hello world\")",
		},
	},
}

model.RenameImports("fmt", "custom_fmt")

fmt.Println(model.String())
Output:

// Generated by github.com/index0h/go-annotation
// DO NOT EDIT
// @FileIsGenerated(true)
package main

import custom_fmt "fmt"

func main() {
	custom_fmt.Println("Hello world")
}

func (*File) String

func (m *File) String() string

Renders File model to string. By default String method adds prefix from Header constant.

Example
model := &File{
	Comment:     "Hello world",
	PackageName: "main",
	ImportGroups: []*ImportGroup{
		{
			Imports: []*Import{
				{
					Namespace: "fmt",
				},
			},
		},
	},
	Funcs: []*Func{
		{
			Name:    "main",
			Content: "fmt.Println(\"Hello world\")",
		},
	},
}

fmt.Println(model.String())
Output:

// Generated by github.com/index0h/go-annotation
// DO NOT EDIT
// @FileIsGenerated(true)
// Hello world
package main

import "fmt"

func main() {
	fmt.Println("Hello world")
}

func (*File) Validate

func (m *File) Validate()

Validates File model fields.

type FileIsGeneratedAnnotation

type FileIsGeneratedAnnotation bool

type Func

type Func struct {
	Name        string
	Content     string
	Comment     string
	Annotations []interface{}
	Spec        *FuncSpec
	Related     *Field
}

Func represents declaration of function.

func (*Func) Clone

func (m *Func) Clone() interface{}

Creates deep copy of Func model.

func (*Func) FetchImports

func (m *Func) FetchImports(file *File) []*Import

Fetches list of Import models registered in file argument, which are used by Spec, Content and Related fields.

Example
file := &File{
	Name:        "file.go",
	PackageName: "packageName",
	ImportGroups: []*ImportGroup{
		{
			Imports: []*Import{
				{Namespace: "json"},
			},
		},
	},
}

model := &Func{
	Name:    "ToJSON",
	Content: "result, _ := json.Marshal(r)\nreturn result",
	Related: &Field{
		Name: "r",
		Spec: &SimpleSpec{
			TypeName:  "Related",
			IsPointer: true,
		},
	},
	Spec: &FuncSpec{
		Results: []*Field{
			{
				Spec: &SimpleSpec{
					TypeName: "string",
				},
			},
		},
	},
}

usedImports := model.FetchImports(file)

fmt.Println(usedImports[0].String())
Output:

import "json"

func (*Func) RenameImports

func (m *Func) RenameImports(oldAlias string, newAlias string)

Renames import aliases, which are used by Spec, Content and Related fields.

Example
model := &Func{
	Name:    "ToJSON",
	Content: "result, _ := json.Marshal(r)\nreturn result",
	Related: &Field{
		Name: "r",
		Spec: &SimpleSpec{
			TypeName:  "Related",
			IsPointer: true,
		},
	},
	Spec: &FuncSpec{
		Results: []*Field{
			{
				Spec: &SimpleSpec{
					TypeName: "string",
				},
			},
		},
	},
}

model.RenameImports("json", "custom_json")

fmt.Println(model.String())
Output:

func (r *Related) ToJSON() (string) {
result, _ := custom_json.Marshal(r)
return result
}

func (*Func) String

func (m *Func) String() string

Renders Func model to string.

Example
model := &Func{
	Name:    "Sum",
	Content: "return x + y",
	Spec: &FuncSpec{
		Params: []*Field{
			{
				Name: "x",
				Spec: &SimpleSpec{
					TypeName: "int",
				},
			},
			{
				Name: "y",
				Spec: &SimpleSpec{
					TypeName: "int",
				},
			},
		},
		Results: []*Field{
			{
				Spec: &SimpleSpec{
					TypeName: "int",
				},
			},
		},
	},
}

fmt.Println(model.String())
Output:

func Sum(x int, y int) (int) {
return x + y
}
Example (Variadic)
model := &Func{
	Name:    "Join",
	Content: "return strings.Join(\", \", parts...)",
	Spec: &FuncSpec{
		Params: []*Field{
			{
				Name: "parts",
				Spec: &ArraySpec{
					Value: &SimpleSpec{
						TypeName: "string",
					},
				},
			},
		},
		Results: []*Field{
			{
				Name: "result",
				Spec: &SimpleSpec{
					TypeName: "string",
				},
			},
		},
		IsVariadic: true,
	},
}

fmt.Println(model.String())
Output:

func Join(parts ...string) (result string) {
return strings.Join(", ", parts...)
}

func (*Func) Validate

func (m *Func) Validate()

Validates Func model fields.

type FuncSpec

type FuncSpec struct {
	Params     []*Field
	Results    []*Field
	IsVariadic bool
}

FuncSpec represents specification of func.

func (*FuncSpec) Clone

func (m *FuncSpec) Clone() interface{}

Creates deep copy of FuncSpec model.

func (*FuncSpec) FetchImports

func (m *FuncSpec) FetchImports(file *File) []*Import

Fetches list of Import models registered in file argument, which are used by Params and Results fields.

Example
file := &File{
	Name:        "file.go",
	PackageName: "packageName",
	ImportGroups: []*ImportGroup{
		{
			Imports: []*Import{
				{Namespace: "log"},
			},
		},
	},
}

model := &FuncSpec{
	Params: []*Field{
		{
			Spec: &SimpleSpec{
				PackageName: "log",
				TypeName:    "Logger",
				IsPointer:   true,
			},
		},
	},
}

usedImports := model.FetchImports(file)

fmt.Println(usedImports[0].String())
Output:

import "log"

func (*FuncSpec) RenameImports

func (m *FuncSpec) RenameImports(oldAlias string, newAlias string)

Renames import aliases, which are used by Params and Results fields.

Example
model := &FuncSpec{
	Params: []*Field{
		{
			Spec: &SimpleSpec{
				PackageName: "log",
				TypeName:    "Logger",
				IsPointer:   true,
			},
		},
	},
}

model.RenameImports("log", "custom_log")

fmt.Println(model.String())
Output:

(*custom_log.Logger)

func (*FuncSpec) String

func (m *FuncSpec) String() string

Renders FuncSpec model to string.

Example
model := &FuncSpec{
	Params: []*Field{
		{
			Name: "x",
			Spec: &SimpleSpec{
				TypeName: "int",
			},
		},
		{
			Name: "y",
			Spec: &SimpleSpec{
				TypeName: "int",
			},
		},
	},
	Results: []*Field{
		{
			Spec: &SimpleSpec{
				TypeName: "int",
			},
		},
	},
}

fmt.Println(model.String())
Output:

(x int, y int) (int)

func (*FuncSpec) Validate

func (m *FuncSpec) Validate()

Validates FuncSpec model fields.

type GoSourceParser

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

Parses golang sources and build File models.

func NewGoSourceParser

func NewGoSourceParser(annotationParser AnnotationParser) *GoSourceParser

Creates new instance of GoSourceParser.

func (*GoSourceParser) Parse

func (p *GoSourceParser) Parse(fileName string, content string) *File

Generates File model by golang source.

Example
fileName := "file.go"
content := `// Hello world
package main

import "fmt"

func main() {
	fmt.Println("Hello world")
}`

file := NewGoSourceParser(NewJSONAnnotationParser()).Parse(fileName, content)
// Clean content to use File rendering
file.Content = ""

fmt.Println(file.String())
Output:

// Generated by github.com/index0h/go-annotation
// DO NOT EDIT
// @FileIsGenerated(true)
// Hello world
package main

import "fmt"

func main() {
	fmt.Println("Hello world")
}

type Import

type Import struct {
	Alias       string
	Namespace   string
	Comment     string
	Annotations []interface{}
}

Import represents import declaration.

func (*Import) Clone

func (m *Import) Clone() interface{}

Creates deep copy of Import model.

func (*Import) RealAlias

func (m *Import) RealAlias() string

Returns Alias field if it's not empty, otherwise base path of Namespace field.

func (*Import) RenameImports

func (m *Import) RenameImports(oldAlias string, newAlias string)

Renames import Alias field if it is equal to oldAlias argument.

Example
model := &Import{
	Alias:     "alias",
	Namespace: "vendor/project/namespace",
}

model.RenameImports("alias", "custom_alias")

fmt.Println(model.String())
Output:

import custom_alias "vendor/project/namespace"

func (*Import) String

func (m *Import) String() string

Renders Import model to string.

Example
model := &Import{
	Alias:     "alias",
	Namespace: "vendor/project/namespace",
	Comment:   "Import comment",
}

fmt.Println(model.String())
Output:

// Import comment
import alias "vendor/project/namespace"
Example (WithoutAlias)
model := &Import{
	Namespace: "vendor/project/namespace",
	Comment:   "Import comment",
}

fmt.Println(model.String())
Output:

// Import comment
import "vendor/project/namespace"

func (*Import) Validate

func (m *Import) Validate()

Validates Import model fields.

type ImportGroup

type ImportGroup struct {
	Comment     string
	Annotations []interface{}
	Imports     []*Import
}

ImportGroup represents list of import declaration.

func (*ImportGroup) Clone

func (m *ImportGroup) Clone() interface{}

Creates deep copy of ImportGroup model.

func (*ImportGroup) RenameImports

func (m *ImportGroup) RenameImports(oldAlias string, newAlias string)

Renames import aliases, which are used in Imports field.

Example
model := &ImportGroup{
	Imports: []*Import{
		{
			Alias:     "alias",
			Namespace: "vendor/project/namespace",
			Comment:   "Import comment",
		},
		{
			Namespace: "vendor/project/namespace/another",
		},
	},
}

model.RenameImports("another", "custom_another")

fmt.Println(model.String())
Output:

import (
// Import comment
alias "vendor/project/namespace"
custom_another "vendor/project/namespace/another"
)

func (*ImportGroup) String

func (m *ImportGroup) String() string

Renders ImportGroup model to string. If ImportGroup contain only one import, without own comment, it will be rendered as single import, without braces.

Example
model := &ImportGroup{
	Comment: "Some imports",
	Imports: []*Import{
		{
			Alias:     "alias",
			Namespace: "vendor/project/namespace",
			Comment:   "Import comment",
		},
		{
			Namespace: "vendor/project/namespace/another",
		},
	},
}

fmt.Println(model.String())
Output:

// Some imports
import (
// Import comment
alias "vendor/project/namespace"
"vendor/project/namespace/another"
)
Example (OneImport)
model := &ImportGroup{
	Imports: []*Import{
		{
			Alias:     "alias",
			Namespace: "vendor/project/namespace",
		},
	},
}

fmt.Println(model.String())
Output:

import alias "vendor/project/namespace"

func (*ImportGroup) Validate

func (m *ImportGroup) Validate()

Validates ImportGroup model fields.

type ImportsFetcher

type ImportsFetcher interface {
	FetchImports(*File) []*Import
}

type ImportsRenamer

type ImportsRenamer interface {
	RenameImports(oldAlias string, newAlias string)
}

type InterfaceSpec

type InterfaceSpec struct {
	Fields []*Field
}

InterfaceSpec represents specification of an interface type.

func (*InterfaceSpec) Clone

func (m *InterfaceSpec) Clone() interface{}

Creates deep copy of InterfaceSpec model.

func (*InterfaceSpec) FetchImports

func (m *InterfaceSpec) FetchImports(file *File) []*Import

Fetches list of Import models registered in file argument, which are used by Fields field.

Example
file := &File{
	Name:        "file.go",
	PackageName: "packageName",
	ImportGroups: []*ImportGroup{
		{
			Imports: []*Import{
				{Namespace: "strings"},
				{Namespace: "fmt"},
			},
		},
	},
}

model := &InterfaceSpec{
	Fields: []*Field{
		{
			Spec: &SimpleSpec{
				PackageName: "fmt",
				TypeName:    "Stringer",
			},
		},
	},
}

usedImports := model.FetchImports(file)

fmt.Println(usedImports[0].String())
Output:

import "fmt"

func (*InterfaceSpec) RenameImports

func (m *InterfaceSpec) RenameImports(oldAlias string, newAlias string)

Renames import aliases, which are used by Fields field.

Example
model := &InterfaceSpec{
	Fields: []*Field{
		{
			Spec: &SimpleSpec{
				PackageName: "fmt",
				TypeName:    "Stringer",
			},
		},
	},
}

model.RenameImports("fmt", "custom_fmt")

fmt.Println(model.String())
Output:

interface{
custom_fmt.Stringer
}

func (*InterfaceSpec) String

func (m *InterfaceSpec) String() string

Renders InterfaceSpec model to string.

Example
model := &InterfaceSpec{
	Fields: []*Field{
		{
			Comment: "Include another interface",
			Spec: &SimpleSpec{
				PackageName: "fmt",
				TypeName:    "Stringer",
			},
		},
		{
			Name: "Clone",
			Spec: &FuncSpec{
				Results: []*Field{
					{
						Spec: &InterfaceSpec{},
					},
				},
			},
		},
	},
}

fmt.Println(model.String())
Output:

interface{
// Include another interface
fmt.Stringer
Clone() (interface{})
}

func (*InterfaceSpec) Validate

func (m *InterfaceSpec) Validate()

Validates InterfaceSpec model fields.

type JSONAnnotationParser

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

Parsers comment and creates list of annotations.

func NewJSONAnnotationParser

func NewJSONAnnotationParser() *JSONAnnotationParser

Creates new instance of JSONAnnotationParser.

func (*JSONAnnotationParser) Parse

func (p *JSONAnnotationParser) Parse(content string) []interface{}

Parsers comment and creates list of annotations.

Example
type annotationType struct {
	Data string
}
content := `Comment start text
@example({"Data": "Example"})
Comment end text`

parser := NewJSONAnnotationParser()
parser.SetAnnotation("example", annotationType{})

annotations := parser.Parse(content)

fmt.Printf("%+v", annotations)
Output:

[{Data:Example}]

func (*JSONAnnotationParser) SetAnnotation

func (p *JSONAnnotationParser) SetAnnotation(name string, annotationType interface{})

Registers new or updates old annotation by name and its type.

type MapSpec

type MapSpec struct {
	// Allowed types: *SimpleSpec, *ArraySpec, *MapSpec, *StructSpec, *InterfaceSpec, *FuncSpec.
	Key Spec
	// Allowed types: *SimpleSpec, *ArraySpec, *MapSpec, *StructSpec, *InterfaceSpec, *FuncSpec.
	Value Spec
}

MapSpec represents specification of map type.

func (*MapSpec) Clone

func (m *MapSpec) Clone() interface{}

Creates deep copy of MapSpec model.

func (*MapSpec) FetchImports

func (m *MapSpec) FetchImports(file *File) []*Import

Fetches list of Import models registered in file argument, which are used by Key and Value fields.

Example
file := &File{
	Name:        "file.go",
	PackageName: "packageName",
	ImportGroups: []*ImportGroup{
		{
			Imports: []*Import{
				{Namespace: "strings"},
				{Namespace: "fmt"},
			},
		},
	},
}

model := &MapSpec{
	Key: &SimpleSpec{
		TypeName: "string",
	},
	Value: &SimpleSpec{
		PackageName: "strings",
		TypeName:    "Builder",
	},
}

usedImports := model.FetchImports(file)

fmt.Println(usedImports[0].String())
Output:

import "strings"

func (*MapSpec) RenameImports

func (m *MapSpec) RenameImports(oldAlias string, newAlias string)

Renames import aliases, which are used by Key and Value fields.

Example
model := &MapSpec{
	Key: &SimpleSpec{
		TypeName: "keyType",
	},
	Value: &SimpleSpec{
		PackageName: "strings",
		TypeName:    "Builder",
	},
}

model.RenameImports("strings", "custom_strings")

fmt.Println(model.String())
Output:

map[keyType]custom_strings.Builder

func (*MapSpec) String

func (m *MapSpec) String() string

Renders MapSpec model to string.

Example
model := &MapSpec{
	Key: &SimpleSpec{
		TypeName: "keyType",
	},
	Value: &SimpleSpec{
		PackageName: "packageName",
		TypeName:    "valueType",
		IsPointer:   true,
	},
}

fmt.Println(model.String())
Output:

map[keyType]*packageName.valueType

func (*MapSpec) Validate

func (m *MapSpec) Validate()

Validates MapSpec model fields.

type Namespace

type Namespace struct {
	Name string
	Path string
	// Ignored namespace must have no files.
	// It could be useful to search declarations, imported with "." alias.
	IsIgnored bool
	Files     []*File
}

func (*Namespace) Clone

func (m *Namespace) Clone() interface{}

Creates deep copy of Namespace model.

func (*Namespace) FindFileByName

func (m *Namespace) FindFileByName(name string) *File

Returns file be its name.

func (*Namespace) PackageName

func (m *Namespace) PackageName() string

Returns package name from first file, ok base of Name field.

Example
model := &Namespace{
	Name: "vendor/project/namespace",
	Path: "/path/to/project",
}

packageName := model.PackageName()

fmt.Println(packageName)
Output:

namespace
Example (FromFile)
model := &Namespace{
	Name: "vendor/project/namespace",
	Path: "/path/to/project",
	Files: []*File{
		{
			Name:        "file.go",
			PackageName: "packageName",
		},
	},
}

packageName := model.PackageName()

fmt.Println(packageName)
Output:

packageName

func (*Namespace) Validate

func (m *Namespace) Validate()

Validates Namespace model fields.

type SimpleSpec

type SimpleSpec struct {
	PackageName string
	TypeName    string
	IsPointer   bool
}

SimpleSpec model represents an identifier of type.

func (*SimpleSpec) Clone

func (m *SimpleSpec) Clone() interface{}

Creates copy of SimpleSpec model.

func (*SimpleSpec) FetchImports

func (m *SimpleSpec) FetchImports(file *File) []*Import

Fetches list of Import models registered in file argument, which are used by PackageName field.

Example
file := &File{
	Name:        "file.go",
	PackageName: "packageName",
	ImportGroups: []*ImportGroup{
		{
			Imports: []*Import{
				{Namespace: "strings"},
				{Namespace: "fmt"},
			},
		},
	},
}

model := &SimpleSpec{
	PackageName: "strings",
	TypeName:    "Builder",
}

usedImports := model.FetchImports(file)

fmt.Println(usedImports[0].String())
Output:

import "strings"

func (*SimpleSpec) RenameImports

func (m *SimpleSpec) RenameImports(oldAlias string, newAlias string)

Renames PackageName field if its same as oldAlias argument.

Example
model := &SimpleSpec{
	PackageName: "strings",
	TypeName:    "Builder",
}

model.RenameImports("strings", "custom_strings")

fmt.Println(model.String())
Output:

custom_strings.Builder

func (*SimpleSpec) String

func (m *SimpleSpec) String() string

Renders SimpleSpec model to string.

Example
model := &SimpleSpec{
	TypeName: "string",
}

fmt.Println(model.String())
Output:

string
Example (Pointer)
model := &SimpleSpec{
	PackageName: "packageName",
	TypeName:    "typeName",
	IsPointer:   true,
}

fmt.Println(model.String())
Output:

*packageName.typeName

func (*SimpleSpec) Validate

func (m *SimpleSpec) Validate()

Validates SimpleSpec model fields.

type SourceParser

type SourceParser interface {
	Parse(fileName string, content string) *File
}

type Storage

type Storage struct {
	AnnotationParser AnnotationParser
	SourceParser     SourceParser
	Namespaces       []*Namespace
}

func NewStorage

func NewStorage() *Storage

Creates new instance of Storage.

func (*Storage) Clone

func (m *Storage) Clone() interface{}

Creates deep copy of Storage model.

func (*Storage) FindNamespaceByName

func (m *Storage) FindNamespaceByName(name string) *Namespace

Returns namespace be its name.

func (*Storage) RemoveOldGeneratedFiles

func (m *Storage) RemoveOldGeneratedFiles()

Removes old generated files with content and FileIsGeneratedAnnotation annotation.

func (*Storage) ScanFiles

func (m *Storage) ScanFiles(path string) []*File

Creates list of File models by *.go files stored in path argument.

func (*Storage) ScanRecursive

func (m *Storage) ScanRecursive(rootNamespace string, rootPath string, ignores ...string)

Scans all golang sources recursively inside of rootPath argument. If rootNamespace is empty rootPath will be ignored, and Namespace models will be created only for children folders. Argument may contain part of path, or absolute path to folder, which must be ignored.

Example
rootPath, err := ioutil.TempDir("", "example-storage")
defer func() {
	if err := os.RemoveAll(rootPath); err != nil {
		panic(err)
	}
}()

if err != nil {
	panic(err)
}

if err := os.Mkdir(filepath.Join(rootPath, "child"), 0777); err != nil {
	panic(err)
}

if err := ioutil.WriteFile(filepath.Join(rootPath, "root.go"), []byte("package root"), 0666); err != nil {
	panic(err)
}

if err := ioutil.WriteFile(filepath.Join(rootPath, "child", "child.go"), []byte("package child"), 0666); err != nil {
	panic(err)
}

storage := NewStorage()
storage.ScanRecursive("namespace/root", rootPath)

fmt.Printf("Namespace[0].Name:             %s\n", storage.Namespaces[0].Name)
fmt.Printf("Namespace[0].Files[0].Content: %s\n", storage.Namespaces[0].Files[0].Content)
fmt.Printf("Namespace[1].Name:             %s\n", storage.Namespaces[1].Name)
fmt.Printf("Namespace[1].Files[0].Content: %s\n", storage.Namespaces[1].Files[0].Content)
Output:

Namespace[0].Name:             namespace/root
Namespace[0].Files[0].Content: package root
Namespace[1].Name:             namespace/root/child
Namespace[1].Files[0].Content: package child
Example (Ignore)
rootPath, err := ioutil.TempDir("", "example-storage")
defer func() {
	if err := os.RemoveAll(rootPath); err != nil {
		panic(err)
	}
}()

if err != nil {
	panic(err)
}

if err := os.Mkdir(filepath.Join(rootPath, "child"), 0777); err != nil {
	panic(err)
}

if err := ioutil.WriteFile(filepath.Join(rootPath, "root.go"), []byte("package root"), 0666); err != nil {
	panic(err)
}

if err := ioutil.WriteFile(filepath.Join(rootPath, "child", "child.go"), []byte("package child"), 0666); err != nil {
	panic(err)
}

storage := NewStorage()
storage.ScanRecursive("namespace/root", rootPath, "child")

fmt.Printf("Namespace[0].Name:             %s\n", storage.Namespaces[0].Name)
fmt.Printf("Namespace[0].Files[0].Content: %s\n", storage.Namespaces[0].Files[0].Content)
fmt.Printf("Namespace[1].Name:             %s\n", storage.Namespaces[1].Name)
fmt.Printf("Namespace[1].IsIgnored:        %t\n", storage.Namespaces[1].IsIgnored)
fmt.Printf("len(Namespace[1].Files):       %d\n", len(storage.Namespaces[1].Files))
Output:

Namespace[0].Name:             namespace/root
Namespace[0].Files[0].Content: package root
Namespace[1].Name:             namespace/root/child
Namespace[1].IsIgnored:        true
len(Namespace[1].Files):       0

func (*Storage) Validate

func (m *Storage) Validate()

Validates Storage model Namespace field.

func (*Storage) WriteGeneratedFiles

func (m *Storage) WriteGeneratedFiles()

Renders and writes File models without content.

type Stringer

type Stringer interface {
	String() string
}

type StructSpec

type StructSpec struct {
	Fields []*Field
}

InterfaceSpec represents specification of struct type.

func (*StructSpec) Clone

func (m *StructSpec) Clone() interface{}

Creates deep copy of StructSpec model.

func (*StructSpec) FetchImports

func (m *StructSpec) FetchImports(file *File) []*Import

Fetches list of Import models registered in file argument, which are used by Fields field.

Example
file := &File{
	Name:        "file.go",
	PackageName: "packageName",
	ImportGroups: []*ImportGroup{
		{
			Imports: []*Import{
				{Namespace: "strings"},
				{Namespace: "fmt"},
			},
		},
	},
}

model := &StructSpec{
	Fields: []*Field{
		{
			Name: "ToString",
			Spec: &SimpleSpec{
				PackageName: "fmt",
				TypeName:    "Stringer",
			},
		},
	},
}

usedImports := model.FetchImports(file)

fmt.Println(usedImports[0].String())
Output:

import "fmt"

func (*StructSpec) RenameImports

func (m *StructSpec) RenameImports(oldAlias string, newAlias string)

Renames import aliases, which are used by Fields field.

Example
model := &StructSpec{
	Fields: []*Field{
		{
			Name: "ToString",
			Spec: &SimpleSpec{
				PackageName: "fmt",
				TypeName:    "Stringer",
			},
		},
	},
}

model.RenameImports("fmt", "custom_fmt")

fmt.Println(model.String())
Output:

struct{
ToString custom_fmt.Stringer
}

func (*StructSpec) String

func (m *StructSpec) String() string

Renders StructSpec model to string.

Example
model := &StructSpec{
	Fields: []*Field{
		{
			Comment: "Include another struct",
			Tag:     "builderTag",
			Spec: &SimpleSpec{
				PackageName: "strings",
				TypeName:    "Builder",
			},
		},
		{
			Name: "Clone",
			Spec: &FuncSpec{
				Results: []*Field{
					{
						Spec: &StructSpec{},
					},
				},
			},
		},
	},
}

fmt.Println(model.String())
Output:

struct{
// Include another struct
 strings.Builder "builderTag"
Clone func () (struct{})
}

func (*StructSpec) Validate

func (m *StructSpec) Validate()

Validates StructSpec model fields.

type Type

type Type struct {
	Name        string
	Comment     string
	Annotations []interface{}
	// Allowed types: *SimpleSpec, *ArraySpec, *MapSpec, *StructSpec, *InterfaceSpec, *FuncSpec.
	Spec Spec
}

Type represents type declaration.

func (*Type) Clone

func (m *Type) Clone() interface{}

Creates deep copy of Type model.

func (*Type) FetchImports

func (m *Type) FetchImports(file *File) []*Import

Fetches list of Import models registered in file argument, which are used by Spec field.

Example
file := &File{
	Name:        "file.go",
	PackageName: "packageName",
	ImportGroups: []*ImportGroup{
		{
			Imports: []*Import{
				{Namespace: "time"},
				{Namespace: "fmt"},
			},
		},
	},
}

model := &Type{
	Name: "OneHour",
	Spec: &SimpleSpec{
		PackageName: "time",
		TypeName:    "Duration",
	},
}

usedImports := model.FetchImports(file)

fmt.Println(usedImports[0].String())
Output:

import "time"

func (*Type) RenameImports

func (m *Type) RenameImports(oldAlias string, newAlias string)

Renames import aliases, which are used by Spec field.

Example
model := &Type{
	Name: "OneHour",
	Spec: &SimpleSpec{
		PackageName: "time",
		TypeName:    "Duration",
	},
}

model.RenameImports("time", "custom_time")

fmt.Println(model.String())
Output:

type OneHour custom_time.Duration

func (*Type) String

func (m *Type) String() string

Renders Type model to string.

Example
model := &Type{
	Name:    "Stringer",
	Comment: "Stringer interface",
	Spec: &InterfaceSpec{
		Fields: []*Field{
			{
				Name: "String",
				Spec: &FuncSpec{
					Results: []*Field{
						{
							Spec: &SimpleSpec{
								TypeName: "string",
							},
						},
					},
				},
			},
		},
	},
}

fmt.Println(model.String())
Output:

// Stringer interface
type Stringer interface{
String() (string)
}

func (*Type) Validate

func (m *Type) Validate()

Validates Type model fields.

type TypeGroup

type TypeGroup struct {
	Comment     string
	Annotations []interface{}
	Types       []*Type
}

TypeGroup represents list of type declaration.

func (*TypeGroup) Clone

func (m *TypeGroup) Clone() interface{}

Creates deep copy of TypeGroup model.

func (*TypeGroup) FetchImports

func (m *TypeGroup) FetchImports(file *File) []*Import

Fetches list of Import models registered in file argument, which are used by Types field.

Example
file := &File{
	Name:        "file.go",
	PackageName: "packageName",
	ImportGroups: []*ImportGroup{
		{
			Imports: []*Import{
				{Namespace: "time"},
				{Namespace: "fmt"},
			},
		},
	},
}

model := &TypeGroup{
	Types: []*Type{
		{
			Name: "Hour",
			Spec: &SimpleSpec{
				PackageName: "time",
				TypeName:    "Duration",
			},
		},
	},
}

usedImports := model.FetchImports(file)

fmt.Println(usedImports[0].String())
Output:

import "time"

func (*TypeGroup) RenameImports

func (m *TypeGroup) RenameImports(oldAlias string, newAlias string)

Renames import aliases, which are used by Types field.

Example
model := &TypeGroup{
	Types: []*Type{
		{
			Name: "Hour",
			Spec: &SimpleSpec{
				PackageName: "time",
				TypeName:    "Duration",
			},
		},
	},
}

model.RenameImports("time", "custom_time")

fmt.Println(model.String())
Output:

type Hour custom_time.Duration

func (*TypeGroup) String

func (m *TypeGroup) String() string

Renders TypeGroup model to string. If TypeGroup contain only one type, without own comment, it will be rendered as single type, without braces.

Example
model := &TypeGroup{
	Comment: "Some types",
	Types: []*Type{
		{
			Name: "Duration",
			Spec: &SimpleSpec{
				PackageName: "time",
				TypeName:    "Duration",
			},
		},
		{
			Name:    "Stringer",
			Comment: "Stringer interface",
			Spec: &InterfaceSpec{
				Fields: []*Field{
					{
						Name: "String",
						Spec: &FuncSpec{
							Results: []*Field{
								{
									Spec: &SimpleSpec{
										TypeName: "string",
									},
								},
							},
						},
					},
				},
			},
		},
	},
}

fmt.Println(model.String())
Output:

// Some types
type (
Duration time.Duration
// Stringer interface
Stringer interface{
String() (string)
}
)
Example (OneType)
model := &TypeGroup{
	Types: []*Type{
		{
			Name: "Stringer",
			Spec: &InterfaceSpec{
				Fields: []*Field{
					{
						Name: "String",
						Spec: &FuncSpec{
							Results: []*Field{
								{
									Spec: &SimpleSpec{
										TypeName: "string",
									},
								},
							},
						},
					},
				},
			},
		},
	},
}

fmt.Println(model.String())
Output:

type Stringer interface{
String() (string)
}

func (*TypeGroup) Validate

func (m *TypeGroup) Validate()

Validates TypeGroup model fields.

type Validator

type Validator interface {
	Validate()
}

type Var

type Var struct {
	Name        string
	Value       string
	Comment     string
	Annotations []interface{}
	// Allowed types: *SimpleSpec, *ArraySpec, *MapSpec, *StructSpec, *InterfaceSpec, *FuncSpec.
	Spec Spec
}

Var represents var declaration.

func (*Var) Clone

func (m *Var) Clone() interface{}

Creates deep copy of Var model.

func (*Var) FetchImports

func (m *Var) FetchImports(file *File) []*Import

Fetches list of Import models registered in file argument, which are used by Spec and Value fields.

Example
file := &File{
	Name:        "file.go",
	PackageName: "packageName",
	ImportGroups: []*ImportGroup{
		{
			Imports: []*Import{
				{Namespace: "time"},
				{Namespace: "fmt"},
			},
		},
	},
}

model := &Var{
	Name: "OneHour",
	Spec: &SimpleSpec{
		PackageName: "time",
		TypeName:    "Duration",
	},
}

usedImports := model.FetchImports(file)

fmt.Println(usedImports[0].String())
Output:

import "time"

func (*Var) RenameImports

func (m *Var) RenameImports(oldAlias string, newAlias string)

Renames import aliases, which are used by Spec and Value fields.

Example
model := &Var{
	Name: "OneHour",
	Spec: &SimpleSpec{
		PackageName: "time",
		TypeName:    "Duration",
	},
	Value: "60*60*time.Second",
}

model.RenameImports("time", "custom_time")

fmt.Println(model.String())
Output:

var OneHour custom_time.Duration = 60*60*custom_time.Second

func (*Var) String

func (m *Var) String() string

Renders Var model to string.

Example
model := &Var{
	Name:    "SecondsInDay",
	Comment: "Count of seconds in one day",
}

fmt.Println(model.String())
Output:

// Count of seconds in one day
var SecondsInDay
Example (Spec)
model := &Var{
	Name:    "SecondsInDay",
	Value:   "24*60*60*time.Second",
	Comment: "Count of seconds in one day",
	Spec: &SimpleSpec{
		PackageName: "time",
		TypeName:    "Duration",
	},
}

fmt.Println(model.String())
Output:

// Count of seconds in one day
var SecondsInDay time.Duration = 24*60*60*time.Second

func (*Var) Validate

func (m *Var) Validate()

Validates Var model fields.

type VarGroup

type VarGroup struct {
	Comment     string
	Annotations []interface{}
	Vars        []*Var
}

VarGroup represents list of var declaration.

func (*VarGroup) Clone

func (m *VarGroup) Clone() interface{}

Creates deep copy of VarGroup model.

func (*VarGroup) FetchImports

func (m *VarGroup) FetchImports(file *File) []*Import

Fetches list of Import models registered in file argument, which are used by Vars field.

Example
file := &File{
	Name:        "file.go",
	PackageName: "packageName",
	ImportGroups: []*ImportGroup{
		{
			Imports: []*Import{
				{Namespace: "time"},
				{Namespace: "fmt"},
			},
		},
	},
}

model := &VarGroup{
	Vars: []*Var{
		{
			Name: "OneHour",
			Spec: &SimpleSpec{
				PackageName: "time",
				TypeName:    "Duration",
			},
			Value: "60*60*time.Second",
		},
	},
}

usedImports := model.FetchImports(file)

fmt.Println(usedImports[0].String())
Output:

import "time"

func (*VarGroup) RenameImports

func (m *VarGroup) RenameImports(oldAlias string, newAlias string)

Renames import aliases, which are used by Vars field.

Example
model := &VarGroup{
	Vars: []*Var{
		{
			Name: "OneHour",
			Spec: &SimpleSpec{
				PackageName: "time",
				TypeName:    "Duration",
			},
			Value: "60*60*time.Second",
		},
		{
			Name: "TwoHours",
			Spec: &SimpleSpec{
				PackageName: "time",
				TypeName:    "Duration",
			},
			Value: "2*60*60*time.Second",
		},
	},
}

model.RenameImports("time", "custom_time")

fmt.Println(model.String())
Output:

var (
OneHour custom_time.Duration = 60*60*custom_time.Second
TwoHours custom_time.Duration = 2*60*60*custom_time.Second
)

func (*VarGroup) String

func (m *VarGroup) String() string

Renders VarGroup model to string. If VarGroup contain only one var, without own comment, it will be rendered as single var, without braces.

Example
model := &VarGroup{
	Comment: "Some seconds variables",
	Vars: []*Var{
		{
			Name:    "SecondsInDay",
			Value:   "24*60*60",
			Comment: "Count of seconds in one day",
		},
		{
			Name:  "SecondsInWeek",
			Value: "SecondsInDay*7",
		},
	},
}

fmt.Println(model.String())
Output:

// Some seconds variables
var (
// Count of seconds in one day
SecondsInDay = 24*60*60
SecondsInWeek = SecondsInDay*7
)
Example (OneVar)
model := &VarGroup{
	Vars: []*Var{
		{
			Name:  "SecondsInDay",
			Value: "24*60*60",
		},
	},
}

fmt.Println(model.String())
Output:

var SecondsInDay = 24*60*60

func (*VarGroup) Validate

func (m *VarGroup) Validate()

Validates VarGroup model fields.

Jump to

Keyboard shortcuts

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