• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

yyle88 / syntaxgo / 18836268722

27 Oct 2025 07:06AM UTC coverage: 52.137% (-7.3%) from 59.469%
18836268722

push

github

yyle88
Remove deprecated AST merge functions and upgrade dependencies

  - Remove merge_package.go using deprecated ast.MergePackageFiles API
  - Clean up syntaxgo_ast package to use modern Go AST APIs
  - Upgrade Go version from 1.22.8 to 1.24.0

13 of 122 new or added lines in 8 files covered. (10.66%)

20 existing lines in 2 files now uncovered.

622 of 1193 relevant lines covered (52.14%)

7.46 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

41.04
/syntaxgo_astnorm/norm_name_type.go
1
// Package syntaxgo_astnorm provides function signature processing utilities
2
// Extract and process function params and return values from AST
3
// Generate code for function calls, variable definitions, and type conversions
4
//
5
// syntaxgo_astnorm 包提供函数签名处理工具
6
// 从 AST 提取和处理函数参数和返回值
7
// 生成函数调用、变量定义和类型转换的代码
8
package syntaxgo_astnorm
9

10
import (
11
        "go/ast"
12
        "strings"
13

14
        "github.com/yyle88/must"
15
        "github.com/yyle88/syntaxgo/internal/utils"
16
        "github.com/yyle88/syntaxgo/syntaxgo_astnode"
17
)
18

19
// NameTypeElement represents a single element with a name, type, and associated information.
20
// NameTypeElement 代表一个包含名称、类型和相关信息的元素
21
type NameTypeElement struct {
22
        Name       string   // Field name / 字段名称
23
        Kind       string   // Type description (e.g., int, string, A, utils.A, *B, *pkg.B) / 类型描述 (例如: int, string, A, utils.A, *B, *pkg.B)
24
        Type       ast.Expr // Go's type representation / Go 的类型表示
25
        IsEllipsis bool     // Indicates if the type is a variadic (e.g., ...int, ...string) / 是否是变参类型 (例如: ...int, ...string)
26
}
27

28
// NewNameTypeElement creates a new NameTypeElement with parsed source code info and normalized data
29
// Parses param/return information and prepares it to use in code generation
30
//
31
// NewNameTypeElement 创建新的 NameTypeElement,包含已解析的源代码信息和规范化数据
32
// 解析参数/返回信息并准备用于代码生成
33
func NewNameTypeElement(
34
        field *ast.Field, // AST field with param/return info / AST 字段包含参数/返回值信息
35
        paramName string, // Name of the param / 参数名称
36
        paramType string, // Type of the param / 参数类型
37
        isEllipsis bool, // Indicates if param is a variadic / 是否为变参
38
        packageName string, // Package name to use with outside types / 外部类型使用的包名
39
        genericTypeParams map[string]ast.Expr, // Map with generic type params / 泛型类型参数的映射
40
) *NameTypeElement {
24✔
41
        elem := &NameTypeElement{
24✔
42
                Name:       paramName,
24✔
43
                Kind:       paramType,
24✔
44
                Type:       field.Type,
24✔
45
                IsEllipsis: isEllipsis,
24✔
46
        }
24✔
47
        if packageName != "" {
39✔
48
                elem.AdjustTypeWithPackage(packageName, genericTypeParams)
15✔
49
        }
15✔
50
        return elem
24✔
51
}
52

53
// AdjustTypeWithPackage adjusts the type to include the package name if needed (when using outside types).
54
// AdjustTypeWithPackage 如果需要(对于外部类型),将类型调整为包含包名。
55
func (element *NameTypeElement) AdjustTypeWithPackage(
56
        packageName string, // The package name / 包名
57
        genericTypeParams map[string]ast.Expr, // Map of generic type parameters / 泛型类型参数的映射
58
) {
15✔
59
        shortKind, adjusted := adjustKindWithPackage(strings.TrimSpace(element.Kind), packageName, genericTypeParams, element.IsEllipsis)
15✔
60
        if !adjusted {
30✔
61
                return
15✔
62
        }
15✔
63
        element.Kind = shortKind
×
64
}
65

66
func adjustKindWithPackage(shortKind string, packageName string, genericTypeParams map[string]ast.Expr, isVariadic bool) (string, bool) {
15✔
67
        if isVariadic {
15✔
68
                must.True(strings.HasPrefix(shortKind, "..."))
×
69
                shortKind = strings.TrimPrefix(shortKind, "...")
×
70
                shortKind = strings.TrimSpace(shortKind)
×
71
        }
×
72

73
        if strings.Contains(shortKind, ".") {
21✔
74
                return "", false // contains package name / 已经包含包名
6✔
75
        }
6✔
76

77
        if s := shortKind[0]; string(s) == "*" {
9✔
78
                if vcc := shortKind[1]; vcc >= 'A' && vcc <= 'Z' {
×
79
                        className := shortKind[1:]
×
80
                        if _, ok := genericTypeParams[className]; ok {
×
81
                                return "", false // It's a generic type / 是泛型类型
×
82
                        }
×
83
                        shortKind = "*" + packageName + "." + className
×
84
                } else {
×
85
                        return "", false // basic-type(int string float64) || // not-exportable-type
×
86
                }
×
87
        } else {
9✔
88
                if s := shortKind[0]; s >= 'A' && s <= 'Z' {
9✔
89
                        className := shortKind
×
90
                        if _, ok := genericTypeParams[className]; ok {
×
91
                                return "", false // It's a generic type / 是泛型类型
×
92
                        }
×
93
                        shortKind = packageName + "." + className
×
94
                } else {
9✔
95
                        return "", false // basic-type(int string float64) || // not-exportable-type
9✔
96
                }
9✔
97
        }
98

99
        if isVariadic {
×
100
                shortKind = "..." + shortKind
×
101
        }
×
102
        return shortKind, true
×
103
}
104

105
// MakeNameFunction generates a name when processing function params and return values.
106
// MakeNameFunction 用于为参数或返回值生成名称。
107
type MakeNameFunction func(name *ast.Ident, kind string, idx int, anonymousIdx int) string
108

109
// NameTypeElements is a collection of NameTypeElement.
110
// NameTypeElements 是 NameTypeElement 的集合。
111
type NameTypeElements []*NameTypeElement
112

113
// NewNameTypeElements creates a list of NameTypeElements based on AST field list.
114
// NewNameTypeElements 根据 AST 字段列表创建 NameTypeElements 的列表。
115
func NewNameTypeElements(
116
        fieldList *ast.FieldList, // AST field list with function params / AST 字段列表,表示函数参数
117
        nameFunc MakeNameFunction, // Function to generate param names / 用于生成参数名称的函数
118
        source []byte, // Source code to extract information / 用于提取信息的源代码
119
        packageName string, // Package name when using outside types / 外部类型的包名
120
        genericTypeParams map[string]ast.Expr, // Map of generic type params / 泛型类型参数的映射
121
) NameTypeElements {
3✔
122
        if fieldList == nil {
3✔
NEW
123
                return make(NameTypeElements, 0) // No fields, new list / 返回一个空列表
×
124
        }
×
125
        return ExtractNameTypeElements(fieldList.List, nameFunc, source, packageName, genericTypeParams)
3✔
126
}
127

128
// ExtractNameTypeElements extracts NameTypeElements from the AST fields.
129
// ExtractNameTypeElements 从 AST 字段中提取 NameTypeElements。
130
func ExtractNameTypeElements(
131
        fields []*ast.Field, // List of AST fields / AST 字段列表
132
        nameFunc MakeNameFunction, // Function to generate names / 用于生成名称的函数
133
        source []byte, // Source code / 源代码
134
        packageName string, // Package name / 包名
135
        genericTypeParams map[string]ast.Expr, // Map of generic type params / 泛型类型参数的映射
136
) NameTypeElements {
9✔
137
        var elements = make(NameTypeElements, 0) // New elements list / 创建一个空的元素列表
9✔
138
        var anonymousCount = 0                   // Count of anonymous fields / 匿名字段计数器
9✔
139
        for _, field := range fields {
33✔
140
                var stringType string
24✔
141
                var isVariadic bool
24✔
142
                if ellipsis, ok := field.Type.(*ast.Ellipsis); ok {
24✔
143
                        stringType = string(source[ellipsis.Ellipsis-1 : field.Type.End()-1]) // Extract ellipsis type / 提取变参类型
×
144
                        isVariadic = true
×
145
                } else {
24✔
146
                        stringType = strings.TrimSpace(string(syntaxgo_astnode.GetCode(source, field.Type))) // Extract normal type / 提取常规类型
24✔
147
                }
24✔
148
                if len(field.Names) > 0 { // Params have names, but returns often don't / 参数有名称,但返回值通常没有
45✔
149
                        for _, fieldName := range field.Names {
42✔
150
                                count := len(elements)
21✔
151
                                paramName := nameFunc(fieldName, stringType, count, 0) // Generate name when processing param / 为参数生成名称
21✔
152
                                elem := NewNameTypeElement(field, paramName, stringType, isVariadic, packageName, genericTypeParams)
21✔
153
                                elements = append(elements, elem)
21✔
154
                        }
21✔
155
                } else {
3✔
156
                        count := len(elements)
3✔
157
                        paramName := nameFunc(nil, stringType, count, anonymousCount) // Generate name for anonymous field / 为匿名字段生成名称
3✔
158
                        elem := NewNameTypeElement(field, paramName, stringType, isVariadic, packageName, genericTypeParams)
3✔
159
                        elements = append(elements, elem)
3✔
160
                        anonymousCount++
3✔
161
                }
3✔
162
        }
163
        return elements
9✔
164
}
165

166
// Names returns a list of names of the elements.
167
// Names 返回元素名称的列表。
168
func (elements NameTypeElements) Names() StatementParts {
×
169
        var names = make([]string, 0, len(elements))
×
170
        for _, element := range elements {
×
171
                names = append(names, element.Name)
×
172
        }
×
173
        return names
×
174
}
175

176
// Kinds returns a list of types of the elements.
177
// Kinds 返回元素类型的列表。
178
func (elements NameTypeElements) Kinds() []string {
×
179
        var kinds = make([]string, 0, len(elements))
×
180
        for _, node := range elements {
×
181
                kinds = append(kinds, node.Kind)
×
182
        }
×
183
        return kinds
×
184
}
185

186
// FormatAddressableNames returns the names prefixed with "&" (addressable names).
187
// FormatAddressableNames 返回带有 "&" 前缀的名称(可寻址名称)。
188
func (elements NameTypeElements) FormatAddressableNames() StatementParts {
×
189
        return utils.SetPrefix2Strings("&", elements.Names()) // Add '&' to each name for addressable types / 为每个名称添加 "&" 使其可寻址
×
190
}
×
191

192
// GenerateFunctionParams generates the function parameters list.
193
// GenerateFunctionParams 生成函数参数列表。
194
func (elements NameTypeElements) GenerateFunctionParams() StatementParts {
×
195
        var params = make([]string, 0, len(elements))
×
196
        for _, element := range elements {
×
197
                if element.IsEllipsis {
×
198
                        params = append(params, element.Name+"...")
×
199
                } else {
×
200
                        params = append(params, element.Name)
×
201
                }
×
202
        }
203
        return params
×
204
}
205

206
// FormatNamesWithKinds returns the names with associated types (e.g., "a int").
207
// FormatNamesWithKinds 返回名称及其类型(例如:"a int")。
208
func (elements NameTypeElements) FormatNamesWithKinds() StatementParts {
×
209
        var results = make([]string, 0, len(elements)) // Initialize a slice for the results / 初始化一个切片来存放结果
×
210
        for _, element := range elements {
×
211
                results = append(results, element.Name+" "+element.Kind) // Combine name and type / 合并名称和类型
×
212
        }
×
213
        return results
×
214
}
215

216
// GenerateVarDefinitions generates variable definitions (e.g., "var a int").
217
// GenerateVarDefinitions 生成变量定义(例如:"var a int")。
218
func (elements NameTypeElements) GenerateVarDefinitions() StatementLines {
×
219
        return utils.SetPrefix2Strings("var ", elements.FormatNamesWithKinds()) // Add "var" to each definition / 为每个定义添加 "var"
×
220
}
×
221

222
// GroupVarsByKindToLines groups variables based on type and generates the definition lines.
223
// GroupVarsByKindToLines 按类型分组变量,并生成相应的定义行。
224
func (elements NameTypeElements) GroupVarsByKindToLines() StatementLines {
×
225
        var typeToNamesMap = map[string][]string{} // Mapping of type to variable names / 类型到名称的映射
×
226
        var uniqueTypes []string                   // Store unique types / 存储唯一的类型
×
227

×
NEW
228
        // Process elements and group based on type / 遍历所有元素,按类型分组
×
229
        for _, element := range elements {
×
230
                if names, exists := typeToNamesMap[element.Kind]; exists {
×
231
                        typeToNamesMap[element.Kind] = append(names, element.Name)
×
232
                } else {
×
233
                        typeToNamesMap[element.Kind] = []string{element.Name}
×
NEW
234
                        uniqueTypes = append(uniqueTypes, element.Kind) // Record type as encountered / 按照出现顺序记录类型
×
235
                }
×
236
        }
237

238
        // Generate variable definition lines / 生成变量定义行
239
        var definitionLines = make([]string, 0, len(uniqueTypes))
×
240
        for _, kind := range uniqueTypes {
×
241
                names := typeToNamesMap[kind]
×
242
                parts := strings.Join(names, ", ") // Join names with commas / 用逗号连接名称
×
243
                definitionLines = append(definitionLines, "var "+parts+" "+kind)
×
244
        }
×
245

246
        return definitionLines
×
247
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc