-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathfunction.go
134 lines (112 loc) · 2.97 KB
/
function.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
package gen
import (
"fmt"
"strings"
"github.com/go-clang/bootstrap/clang"
)
// Function represents a generation function.
type Function struct {
IncludeFiles IncludeFiles
Name string
CName string
Comment string
Parameters []FunctionParameter
ReturnType Type
Receiver Receiver
Member *FunctionParameter
}
// FunctionParameter represents a generation function parameter.
type FunctionParameter struct {
Name string
CName string
Type Type
}
// NewFunction returns the initialized *Function.
func NewFunction(name, cname, comment, member string, typ Type) *Function {
functionName := UpperFirstCharacter(name)
receiverType := TrimLanguagePrefix(cname)
receiverName := CommonReceiverName(receiverType)
f := &Function{
IncludeFiles: NewIncludeFiles(),
Name: functionName,
CName: cname,
Comment: comment,
Parameters: []FunctionParameter{ // TODO(go-clang): this might not be needed if the receiver code is refactored: https://github.com/go-clang/gen/issues/52
{
Name: receiverName,
CName: cname,
Type: Type{
GoName: receiverType,
},
},
},
ReturnType: typ,
Receiver: Receiver{
Name: receiverName,
Type: Type{
GoName: receiverType,
},
},
Member: &FunctionParameter{
Name: member,
Type: typ,
},
}
return f
}
// HandleFunctionCursor handles function cursor.
func HandleFunctionCursor(cursor clang.Cursor) *Function {
fname := cursor.Spelling()
f := Function{
IncludeFiles: NewIncludeFiles(),
Name: fname,
CName: fname,
}
typ, err := TypeFromClangType(cursor.ResultType())
if err != nil {
panic(fmt.Errorf("unexpected cursor.ResultType: %#v: %w", cursor.ResultType(), err))
}
f.ReturnType = typ
numParam := int(cursor.NumArguments())
f.Parameters = make([]FunctionParameter, 0, numParam)
for i := 0; i < numParam; i++ {
param := cursor.Argument(uint32(i))
p := FunctionParameter{
CName: param.DisplayName(),
}
typ, err := TypeFromClangType(param.Type())
if err != nil {
panic(fmt.Errorf("unexpected error: %w, param.Type(): %#v", err, param.Type()))
}
p.Type = typ
p.Name = p.CName
if p.Name == "" {
p.Name = CommonReceiverName(p.Type.GoName)
} else {
pns := strings.Split(p.Name, "_")
for i := range pns {
pns[i] = UpperFirstCharacter(pns[i])
}
p.Name = LowerFirstCharacter(strings.Join(pns, ""))
}
if r := ReplaceGoKeywords(p.Name); r != "" {
p.Name = r
}
f.Parameters = append(f.Parameters, p)
}
commentFname := UpperFirstCharacter(strings.TrimPrefix(f.Name, "clang_"))
f.Comment = CleanDoxygenComment(commentFname, cursor.RawCommentText())
return &f
}
// Generate generates the function.
func (f *Function) Generate() string {
fa := NewASTFunc(f)
fa.Generate()
fStr := GenerateFunctionString(fa)
// TODO(go-clang): find out how to position the comment correctly and do this using the AST
// https://github.com/go-clang/gen/issues/54
if f.Comment != "" {
fStr = f.Comment + "\n" + fStr
}
return fStr
}