Skip to content

Commit c36d527

Browse files
[checkapi] support generics and map keys (#1117)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent a138237 commit c36d527

File tree

3 files changed

+64
-16
lines changed

3 files changed

+64
-16
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
2+
change_type: bug_fix
3+
4+
# The name of the component, or a single word describing the area of concern, (e.g. crosslink)
5+
component: checkapi
6+
7+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
8+
note: Support detecting usage of a Struct as part of config when used as a generic type of a map key
9+
10+
# One or more tracking issues related to the change
11+
issues: [1116]
12+
13+
# (Optional) One or more lines of additional information to render under the primary note.
14+
# These lines will be padded with 2 spaces and then inserted directly into the document.
15+
# Use pipe (|) for multiline entries.
16+
subtext:

checkapi/internal/ast.go

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,37 @@ func Read(folder string, ignoredFunctions []string, excludedFiles []string) (API
121121
return *result, nil
122122
}
123123

124+
func interpretFieldType(f *ast.Field, expr ast.Expr) []APIstructField {
125+
var fieldNames []APIstructField
126+
fieldType := expr
127+
switch t := fieldType.(type) {
128+
case *ast.StarExpr:
129+
fieldType = t.X
130+
case *ast.ArrayType:
131+
fieldType = t.Elt
132+
if tt, ok := fieldType.(*ast.StarExpr); ok {
133+
fieldType = tt.X
134+
}
135+
case *ast.MapType:
136+
fieldType = t.Value
137+
if tt, ok := fieldType.(*ast.StarExpr); ok {
138+
fieldType = tt.X
139+
}
140+
fieldNames = interpretFieldType(f, t.Key)
141+
case *ast.Ident:
142+
// nothing to do
143+
case *ast.ChanType:
144+
fieldType = t.Value
145+
case *ast.StructType:
146+
// nothing to do
147+
case *ast.IndexExpr:
148+
fieldType = t.X
149+
fieldNames = interpretFieldType(f, t.Index)
150+
}
151+
fieldNames = append(fieldNames, APIstructField{Name: f.Names[0].Name, Type: ExprToString(fieldType)})
152+
return fieldNames
153+
}
154+
124155
func readFile(ignoredFunctions []string, f *ast.File, result *API) {
125156
for _, d := range f.Decls {
126157
if str, isStr := d.(*ast.GenDecl); isStr {
@@ -139,22 +170,7 @@ func readFile(ignoredFunctions []string, f *ast.File, result *API) {
139170
fieldNames = make([]APIstructField, 0, len(structType.Fields.List))
140171
for _, f := range structType.Fields.List {
141172
if len(f.Names) > 0 {
142-
fieldType := f.Names[0].Obj.Decl.(*ast.Field).Type
143-
switch t := fieldType.(type) {
144-
case *ast.StarExpr:
145-
fieldType = t.X
146-
case *ast.ArrayType:
147-
fieldType = t.Elt
148-
if tt, ok := fieldType.(*ast.StarExpr); ok {
149-
fieldType = tt.X
150-
}
151-
case *ast.MapType:
152-
fieldType = t.Value
153-
if tt, ok := fieldType.(*ast.StarExpr); ok {
154-
fieldType = tt.X
155-
}
156-
}
157-
fieldNames = append(fieldNames, APIstructField{Name: f.Names[0].Name, Type: ExprToString(fieldType)})
173+
fieldNames = append(fieldNames, interpretFieldType(f, f.Names[0].Obj.Decl.(*ast.Field).Type)...)
158174
} else {
159175
// Embedded struct
160176
fieldType := f.Type

checkapi/internal/config/receiver/configreceiver/code_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,16 @@ type Config struct {
3030
Embedded
3131
// Embedded struct pointer
3232
*EmbeddedPtr
33+
// Generic type
34+
Holder GenericHolder[GenericType]
35+
// Map holding types
36+
MapOfStructs map[Key]Value
3337
}
3438

39+
type Key struct{}
40+
41+
type Value struct{}
42+
3543
type PtrStruct struct {
3644
Field string
3745
}
@@ -53,3 +61,11 @@ type Embedded struct {
5361
type EmbeddedPtr struct {
5462
Foo string
5563
}
64+
65+
type GenericHolder[T any] struct {
66+
Value T
67+
}
68+
69+
type GenericType struct {
70+
Foo string
71+
}

0 commit comments

Comments
 (0)