-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathastkratos.go
172 lines (152 loc) · 6.08 KB
/
astkratos.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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
package astkratos
import (
"go/ast"
"os"
"strings"
"github.com/orzkratos/astkratos/internal/utils"
"github.com/yyle88/must"
"github.com/yyle88/neatjson/neatjsons"
"github.com/yyle88/rese"
"github.com/yyle88/syntaxgo/syntaxgo_ast"
"github.com/yyle88/syntaxgo/syntaxgo_astnode"
"github.com/yyle88/syntaxgo/syntaxgo_search"
"github.com/yyle88/zaplog"
)
// GrpcTypeDefinition represents a gRPC type definition with its name and package.
type GrpcTypeDefinition struct {
Name string
Package string
}
// ListGrpcClients lists all gRPC client types in the specified root directory.
func ListGrpcClients(root string) (definitions []*GrpcTypeDefinition) {
definitions = make([]*GrpcTypeDefinition, 0)
must.Done(WalkFiles(root, NewSuffixMatcher([]string{"_grpc.pb.go"}), func(path string, info os.FileInfo) error {
// Get the package name from the file path
pkgName := syntaxgo_ast.GetPackageNameFromPath(path)
// Read and trim lines from the file
sLines := rese.V1(utils.GetTrimmedLines(path))
for _, s := range sLines {
// Check if the line defines a gRPC client interface
if strings.HasPrefix(s, "type ") && strings.HasSuffix(s, "Client interface {") {
name := utils.GetSubstringBetween(s, "type ", " interface {")
// Append the gRPC client definition to the list
definitions = append(definitions, &GrpcTypeDefinition{
Package: pkgName,
Name: name,
})
}
}
return nil
}))
return definitions
}
// ListGrpcServers lists all gRPC server types in the specified root directory.
func ListGrpcServers(root string) (definitions []*GrpcTypeDefinition) {
definitions = make([]*GrpcTypeDefinition, 0)
must.Done(WalkFiles(root, NewSuffixMatcher([]string{"_grpc.pb.go"}), func(path string, info os.FileInfo) error {
// Get the package name from the file path
pkgName := syntaxgo_ast.GetPackageNameFromPath(path)
// Read and trim lines from the file
sLines := rese.V1(utils.GetTrimmedLines(path))
for _, s := range sLines {
// Check if the line defines a gRPC server interface
if strings.HasPrefix(s, "type ") && strings.HasSuffix(s, "Server interface {") && !strings.HasPrefix(s, "type Unsafe") {
name := utils.GetSubstringBetween(s, "type ", " interface {")
// Append the gRPC server definition to the list
definitions = append(definitions, &GrpcTypeDefinition{
Package: pkgName,
Name: name,
})
}
}
return nil
}))
return definitions
}
// ListGrpcUnimplementedServers lists all unimplemented gRPC server types in the specified root directory.
func ListGrpcUnimplementedServers(root string) (definitions []*GrpcTypeDefinition) {
zaplog.SUG.Debugln("list-grpc-unimplemented-servers in path:", root)
definitions = make([]*GrpcTypeDefinition, 0)
must.Done(WalkFiles(root, NewSuffixMatcher([]string{"_grpc.pb.go"}), func(path string, info os.FileInfo) error {
zaplog.SUG.Debugln("xyz_grpc.pb.go path:", path)
// Get the package name from the file path
pkgName := syntaxgo_ast.GetPackageNameFromPath(path)
// Read and trim lines from the file
sLines := rese.V1(utils.GetTrimmedLines(path))
for _, s := range sLines {
// Check if the line defines an unimplemented gRPC server
if strings.HasPrefix(s, "type Unimplemented") {
var name string
switch {
case strings.HasSuffix(s, "Server struct {"): // Old version
name = utils.GetSubstringBetween(s, "type ", " struct {")
must.OK(name)
case strings.HasSuffix(s, "Server struct{}"): // New version
name = utils.GetSubstringBetween(s, "type ", " struct{}")
must.OK(name)
}
if name != "" { // Match old version or new version
// Append the unimplemented gRPC server definition to the list
definitions = append(definitions, &GrpcTypeDefinition{
Package: pkgName,
Name: name,
})
}
}
}
return nil
}))
zaplog.SUG.Debugln("list-grpc-unimplemented-servers definitions:", neatjsons.S(definitions))
return definitions
}
// ListGrpcServices lists all gRPC services in the specified root directory.
func ListGrpcServices(root string) (definitions []*GrpcTypeDefinition) {
zaplog.SUG.Debugln("list-grpc-services in path:", root)
definitions = make([]*GrpcTypeDefinition, 0)
// Iterate through unimplemented gRPC servers and extract service names
for _, x := range ListGrpcUnimplementedServers(root) {
zaplog.SUG.Debugln("service-name:", x.Name, "package-name:", x.Package)
one := &GrpcTypeDefinition{
Name: utils.GetSubstringBetween(x.Name, "Unimplemented", "Server"),
Package: x.Package,
}
must.OK(one.Name)
// Append the gRPC service definition to the list
definitions = append(definitions, one)
}
zaplog.SUG.Debugln("list-grpc-services definitions:", neatjsons.S(definitions))
return definitions
}
// StructDefinition represents a struct definition with its name, type, source code, and code snippet.
type StructDefinition struct {
Name string
Type *ast.StructType
FileSource []byte // The entire source code of the source file
StructCode string // The code snippet defining the struct
}
// ListStructsMap lists all struct definitions in the specified file and returns them as a map.
func ListStructsMap(path string) map[string]*StructDefinition {
zaplog.SUG.Debugln("list-structs-map in path:", path)
var structMap = map[string]*StructDefinition{}
// Read the entire source code of the file
fileSource := rese.V1(os.ReadFile(path))
// Parse the source code into an AST bundle
astBundle := rese.P1(syntaxgo_ast.NewAstBundleV1(fileSource))
astFile, _ := astBundle.GetBundle()
// Map struct types by their names
structTypes := syntaxgo_search.MapStructTypesByName(astFile)
for structName, structType := range structTypes {
// Get the code snippet defining the struct
structCode := syntaxgo_astnode.GetText(fileSource, structType)
zaplog.SUG.Debugln("struct-name:", structName, "struct-code:", structCode)
// Add the struct definition to the map
structMap[structName] = &StructDefinition{
Name: structName,
Type: structType,
FileSource: fileSource,
StructCode: structCode,
}
}
zaplog.SUG.Debugln("list-structs-map struct-map-size:", len(structMap))
return structMap
}