/
gen_filter_op.go
142 lines (119 loc) · 5.86 KB
/
gen_filter_op.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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// +build generate
package main
import (
"bytes"
"fmt"
"go/format"
"io/ioutil"
"strings"
)
type opInfo struct {
name string
comment string
valueType string
flags uint64
}
const (
flagIsBinaryExpr uint64 = 1 << iota
flagIsBasicLit
flagHasVar
)
func main() {
ops := []opInfo{
{name: "Invalid"},
{name: "Not", comment: "!$Args[0]"},
// Binary expressions.
{name: "And", comment: "$Args[0] && $Args[1]", flags: flagIsBinaryExpr},
{name: "Or", comment: "$Args[0] || $Args[1]", flags: flagIsBinaryExpr},
{name: "Eq", comment: "$Args[0] == $Args[1]", flags: flagIsBinaryExpr},
{name: "Neq", comment: "$Args[0] != $Args[1]", flags: flagIsBinaryExpr},
{name: "Gt", comment: "$Args[0] > $Args[1]", flags: flagIsBinaryExpr},
{name: "Lt", comment: "$Args[0] < $Args[1]", flags: flagIsBinaryExpr},
{name: "GtEq", comment: "$Args[0] >= $Args[1]", flags: flagIsBinaryExpr},
{name: "LtEq", comment: "$Args[0] <= $Args[1]", flags: flagIsBinaryExpr},
{name: "VarAddressable", comment: "m[$Value].Addressable", valueType: "string", flags: flagHasVar},
{name: "VarPure", comment: "m[$Value].Pure", valueType: "string", flags: flagHasVar},
{name: "VarConst", comment: "m[$Value].Const", valueType: "string", flags: flagHasVar},
{name: "VarConstSlice", comment: "m[$Value].ConstSlice", valueType: "string", flags: flagHasVar},
{name: "VarText", comment: "m[$Value].Text", valueType: "string", flags: flagHasVar},
{name: "VarLine", comment: "m[$Value].Line", valueType: "string", flags: flagHasVar},
{name: "VarValueInt", comment: "m[$Value].Value.Int()", valueType: "string", flags: flagHasVar},
{name: "VarTypeSize", comment: "m[$Value].Type.Size", valueType: "string", flags: flagHasVar},
{name: "VarTypeHasPointers", comment: "m[$Value].Type.HasPointers()", valueType: "string", flags: flagHasVar},
{name: "VarFilter", comment: "m[$Value].Filter($Args[0])", valueType: "string", flags: flagHasVar},
{name: "VarNodeIs", comment: "m[$Value].Node.Is($Args[0])", valueType: "string", flags: flagHasVar},
{name: "VarObjectIs", comment: "m[$Value].Object.Is($Args[0])", valueType: "string", flags: flagHasVar},
{name: "VarTypeIs", comment: "m[$Value].Type.Is($Args[0])", valueType: "string", flags: flagHasVar},
{name: "VarTypeUnderlyingIs", comment: "m[$Value].Type.Underlying().Is($Args[0])", valueType: "string", flags: flagHasVar},
{name: "VarTypeOfKind", comment: "m[$Value].Type.OfKind($Args[0])", valueType: "string", flags: flagHasVar},
{name: "VarTypeUnderlyingOfKind", comment: "m[$Value].Type.Underlying().OfKind($Args[0])", valueType: "string", flags: flagHasVar},
{name: "VarTypeConvertibleTo", comment: "m[$Value].Type.ConvertibleTo($Args[0])", valueType: "string", flags: flagHasVar},
{name: "VarTypeAssignableTo", comment: "m[$Value].Type.AssignableTo($Args[0])", valueType: "string", flags: flagHasVar},
{name: "VarTypeImplements", comment: "m[$Value].Type.Implements($Args[0])", valueType: "string", flags: flagHasVar},
{name: "VarTypeHasMethod", comment: "m[$Value].Type.HasMethod($Args[0])", valueType: "string", flags: flagHasVar},
{name: "VarTextMatches", comment: "m[$Value].Text.Matches($Args[0])", valueType: "string", flags: flagHasVar},
{name: "VarContains", comment: "m[$Value].Contains($Args[0])", valueType: "string", flags: flagHasVar},
{name: "Deadcode", comment: "m.Deadcode()"},
{name: "GoVersionEq", comment: "m.GoVersion().Eq($Value)", valueType: "string"},
{name: "GoVersionLessThan", comment: "m.GoVersion().LessThan($Value)", valueType: "string"},
{name: "GoVersionGreaterThan", comment: "m.GoVersion().GreaterThan($Value)", valueType: "string"},
{name: "GoVersionLessEqThan", comment: "m.GoVersion().LessEqThan($Value)", valueType: "string"},
{name: "GoVersionGreaterEqThan", comment: "m.GoVersion().GreaterEqThan($Value)", valueType: "string"},
{name: "FileImports", comment: "m.File.Imports($Value)", valueType: "string"},
{name: "FilePkgPathMatches", comment: "m.File.PkgPath.Matches($Value)", valueType: "string"},
{name: "FileNameMatches", comment: "m.File.Name.Matches($Value)", valueType: "string"},
{name: "FilterFuncRef", comment: "$Value holds a function name", valueType: "string"},
{name: "String", comment: "$Value holds a string constant", valueType: "string", flags: flagIsBasicLit},
{name: "Int", comment: "$Value holds an int64 constant", valueType: "int64", flags: flagIsBasicLit},
{name: "RootNodeParentIs", comment: "m[`$$`].Node.Parent().Is($Args[0])"},
}
var buf bytes.Buffer
buf.WriteString(`// Code generated "gen_filter_op.go"; DO NOT EDIT.` + "\n")
buf.WriteString("\n")
buf.WriteString("package ir\n")
buf.WriteString("const (\n")
for i, op := range ops {
if strings.Contains(op.comment, "$Value") && op.valueType == "" {
fmt.Printf("missing %s valueType\n", op.name)
}
if op.comment != "" {
buf.WriteString("// " + op.comment + "\n")
}
if op.valueType != "" {
buf.WriteString("// $Value type: " + op.valueType + "\n")
}
fmt.Fprintf(&buf, "Filter%sOp FilterOp = %d\n", op.name, i)
buf.WriteString("\n")
}
buf.WriteString(")\n")
buf.WriteString("var filterOpNames = map[FilterOp]string{\n")
for _, op := range ops {
fmt.Fprintf(&buf, "Filter%sOp: `%s`,\n", op.name, op.name)
}
buf.WriteString("}\n")
buf.WriteString("var filterOpFlags = map[FilterOp]uint64{\n")
for _, op := range ops {
if op.flags == 0 {
continue
}
parts := make([]string, 0, 1)
if op.flags&flagIsBinaryExpr != 0 {
parts = append(parts, "flagIsBinaryExpr")
}
if op.flags&flagIsBasicLit != 0 {
parts = append(parts, "flagIsBasicLit")
}
if op.flags&flagHasVar != 0 {
parts = append(parts, "flagHasVar")
}
fmt.Fprintf(&buf, "Filter%sOp: %s,\n", op.name, strings.Join(parts, " | "))
}
buf.WriteString("}\n")
pretty, err := format.Source(buf.Bytes())
if err != nil {
panic(err)
}
if err := ioutil.WriteFile("filter_op.gen.go", pretty, 0644); err != nil {
panic(err)
}
}