1// +build ignore
2
3package main
4
5import (
6	"bytes"
7	"go/format"
8	"io"
9	"log"
10	"os"
11	"text/template"
12)
13
14type types struct {
15	BasicKinds []string
16	BasicProps []string
17	Types      []string
18}
19
20func main() {
21	typesList := types{
22		BasicKinds: []string{
23			"Bool",
24			"Int",
25			"Int8",
26			"Int16",
27			"Int32",
28			"Int64",
29			"Uint",
30			"Uint8",
31			"Uint16",
32			"Uint32",
33			"Uint64",
34			"Uintptr",
35			"Float32",
36			"Float64",
37			"Complex64",
38			"Complex128",
39			"String",
40			"UnsafePointer",
41			"UntypedBool",
42			"UntypedInt",
43			"UntypedRune",
44			"UntypedFloat",
45			"UntypedComplex",
46			"UntypedString",
47			"UntypedNil",
48		},
49
50		BasicProps: []string{
51			"Boolean",
52			"Integer",
53			"Unsigned",
54			"Float",
55			"Complex",
56			"String",
57			"Untyped",
58			"Ordered",
59			"Numeric",
60			"ConstType",
61		},
62
63		Types: []string{
64			"Basic",
65			"Array",
66			"Slice",
67			"Struct",
68			"Pointer",
69			"Tuple",
70			"Signature",
71			"Interface",
72			"Map",
73			"Chan",
74			"Named",
75		},
76	}
77
78	simplePredicateFile, err := os.Create("simplePredicates.go")
79	if err != nil {
80		log.Fatal(err)
81	}
82	writeCode(simplePredicateFile, typesList)
83}
84
85func generateCode(tmplText string, typeList types) []byte {
86	tmpl := template.Must(template.New("code").Parse(tmplText))
87	var code bytes.Buffer
88	tmpl.Execute(&code, typeList)
89	prettyCode, err := format.Source(code.Bytes())
90	if err != nil {
91		panic(err)
92	}
93	return prettyCode
94}
95
96func writeCode(output io.Writer, typeList types) {
97	code := generateCode(`// Code generated by simplePredicates_generate.go; DO NOT EDIT
98
99package typep
100
101import (
102	"go/types"
103)
104
105// Simple 1-to-1 type predicates via type assertion.
106
107{{ range .Types }}
108// Is{{.}} reports whether a given type has *types.{{.}} type.
109func Is{{.}}(typ types.Type) bool {
110	_, ok := typ.(*types.{{.}})
111	return ok
112}
113{{ end }}
114
115// *types.Basic predicates for the info field.
116
117{{ range .BasicProps }}
118// Has{{.}}Prop reports whether typ is a *types.Basic has Is{{.}} property.
119func Has{{.}}Prop(typ types.Type) bool {
120	if typ, ok := typ.(*types.Basic); ok {
121		return typ.Info()&types.Is{{.}} != 0
122	}
123	return false
124}
125{{ end }}
126
127// *types.Basic predicates for the kind field.
128
129{{ range .BasicKinds }}
130// Has{{.}}Kind reports whether typ is a *types.Basic with its kind set to types.{{.}}.
131func Has{{.}}Kind(typ types.Type) bool {
132	if typ, ok := typ.(*types.Basic); ok {
133		return typ.Kind() == types.{{.}}
134	}
135	return false
136}
137{{ end }}
138`, typeList)
139	output.Write(code)
140}
141