-
Notifications
You must be signed in to change notification settings - Fork 3
/
func.go
97 lines (80 loc) · 2.8 KB
/
func.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
package prefixer
import (
"errors"
"fmt"
"go/ast"
"strings"
)
// funcPrefixer implements Prefixer for FuncType.
type funcPrefixer struct {
*ast.FuncType
ParamsPrefixers []Prefixer
ResultsPrefixers []Prefixer
}
var _ Prefixer = &funcPrefixer{} // ensure interface is implemented
// Valid validates the prefixer and its subprefixers.
//
// An example would be a composition of a StarExpr with an ArrayType of an Ident.
// In that case, all three prefixers computed from those ast.Expr will be validated with Valid.
func (f *funcPrefixer) Valid() error {
var errs []error
editor := func(field *ast.Field) editor {
return func(stringType string, exported bool) (string, bool) {
var name string
if len(field.Names) > 0 {
name = field.Names[0].Name + " "
}
return name + stringType, exported
}
}
// retrieve prefixers associated to func parameters
if f.Params != nil {
f.ParamsPrefixers = make([]Prefixer, 0, len(f.Params.List))
for _, field := range f.Params.List {
prefixer := NewPrefixerEditor(NewPrefixer(field.Type), editor(field))
errs = append(errs, prefixer.Valid())
f.ParamsPrefixers = append(f.ParamsPrefixers, prefixer)
}
}
// retrieve prefixers associated to func outputs
if f.Results != nil {
f.ResultsPrefixers = make([]Prefixer, 0, len(f.Params.List))
for _, field := range f.Results.List {
prefixer := NewPrefixerEditor(NewPrefixer(field.Type), editor(field))
errs = append(errs, prefixer.Valid())
f.ResultsPrefixers = append(f.ResultsPrefixers, prefixer)
}
}
return errors.Join(errs...)
}
// ToString transforms a Prefixer (ast.Expr) into its string representation.
// It also returns a boolean indicating whether the type is exported.
func (f *funcPrefixer) ToString(sourcePackage string, typeParams []string, prefixes ...string) (_ string, _ bool) {
exported := true
// compute paramsTypes prefix part
paramsTypes := make([]string, 0, len(f.ParamsPrefixers))
for _, field := range f.ParamsPrefixers {
stringType, paramExported := field.ToString(sourcePackage, typeParams)
// don't affect directly because once exported is false, it should stays even if other fields are exported
if !paramExported {
exported = false
}
paramsTypes = append(paramsTypes, stringType)
}
// compute resultsTypes prefix part
resultsTypes := make([]string, 0, len(f.ResultsPrefixers))
for _, field := range f.ResultsPrefixers {
stringType, resultExported := field.ToString(sourcePackage, typeParams)
// don't affect directly because once exported is false, it should stays even if other fields are exported
if !resultExported {
exported = false
}
resultsTypes = append(resultsTypes, stringType)
}
return fmt.Sprintf(
"%sfunc(%s) (%s)",
strings.Join(prefixes, ""),
strings.Join(paramsTypes, ", "),
strings.Join(resultsTypes, ", "),
), exported
}