forked from fgrosse/goldi
/
type_registration_code.go
89 lines (74 loc) · 2.9 KB
/
type_registration_code.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package main
import (
"fmt"
"strings"
)
// FactoryCode returns the go code that is necessary to register this type
// To avoid any unexpected behavior you should call TypeDefinition.Validate first
func FactoryCode(t TypeDefinition, outputPackageName string) string {
var typeFactoryCode string
switch {
case t.FuncName != "" && t.FuncName[0] != '@':
typeFactoryCode = funcTypeCode(t, outputPackageName)
case t.FuncName != "" && t.FuncName[0] == '@':
typeFactoryCode = funcReferenceTypeCode(t)
case t.AliasForType != "":
typeFactoryCode = aliasTypeCode(t)
case t.FactoryMethod != "" && t.FactoryMethod[0] == '@' && strings.Contains(t.FactoryMethod, "::"):
typeFactoryCode = proxyTypeCode(t)
case t.FactoryMethod != "":
typeFactoryCode = factoryTypeCode(t, outputPackageName)
case t.TypeName != "":
typeFactoryCode = structTypeCode(t, outputPackageName)
default:
panic(fmt.Errorf("can not generate registration code for %+v", t))
}
if len(t.Configurator) == 2 {
configuratorID := t.Configurator[0][1:]
configuratorMethod := t.Configurator[1]
typeFactoryCode = fmt.Sprintf("goldi.NewConfiguredType(\n\t\t%s,\n\t\t%q, %q,\n\t)", typeFactoryCode, configuratorID, configuratorMethod)
}
return typeFactoryCode
}
func funcTypeCode(t TypeDefinition, outputPackageName string) string {
funcName := t.FuncName
if t.Package != outputPackageName {
funcName = fmt.Sprintf("%s.%s", t.PackageName(), funcName)
}
return fmt.Sprintf("goldi.NewFuncType(%s)", funcName)
}
func funcReferenceTypeCode(t TypeDefinition) string {
parts := strings.SplitN(t.FuncName, "::", 2)
return fmt.Sprintf("goldi.NewFuncReferenceType(%q, %q)", parts[0][1:], parts[1])
}
func aliasTypeCode(t TypeDefinition) string {
alias := t.AliasForType
if alias[0] == '@' {
alias = alias[1:]
}
return fmt.Sprintf("goldi.NewAliasType(%q)", alias)
}
func factoryTypeCode(t TypeDefinition, outputPackageName string) string {
factoryMethod := t.FactoryMethod
if t.Package != outputPackageName {
factoryMethod = fmt.Sprintf("%s.%s", t.PackageName(), t.FactoryMethod)
}
arguments := []string{factoryMethod}
arguments = append(arguments, t.Arguments()...)
return fmt.Sprintf("goldi.NewType(%s)", strings.Join(arguments, ", "))
}
func structTypeCode(t TypeDefinition, outputPackageName string) string {
factoryMethod := fmt.Sprintf("new(%s)", t.TypeName)
if t.Package != outputPackageName {
factoryMethod = fmt.Sprintf("new(%s.%s)", t.PackageName(), t.TypeName)
}
arguments := []string{factoryMethod}
arguments = append(arguments, t.Arguments()...)
return fmt.Sprintf("goldi.NewStructType(%s)", strings.Join(arguments, ", "))
}
func proxyTypeCode(t TypeDefinition) string {
factory := t.FactoryMethod[1:] // omit leading @
parts := strings.Split(factory, "::")
arguments := append([]string{fmt.Sprintf("%q", parts[0]), fmt.Sprintf("%q", parts[1])}, t.Arguments()...)
return fmt.Sprintf("goldi.NewProxyType(%s)", strings.Join(arguments, ", "))
}