8
8
"io"
9
9
"os"
10
10
"strings"
11
+ "unicode"
11
12
12
13
a "testsuites/annotations"
13
14
c "testsuites/collector"
@@ -26,6 +27,7 @@ const (
26
27
BLOCK NodeType = "block"
27
28
CALL_EXPRESSION NodeType = "call_expression"
28
29
IDENTIFIER NodeType = "identifier"
30
+ METHOD_DECLARATION NodeType = "method_declaration"
29
31
)
30
32
31
33
type Metadata struct {
@@ -81,6 +83,29 @@ func ExtractInfo(file c.TestFile, ctx context.Context, fileID c.FileID) (*FileDa
81
83
return fileData , hasNoTests (! checkForExistanceOfTests (fData )), nil
82
84
}
83
85
86
+ func GetExportedFunctions (ctx context.Context , filePath string ) ([]c.FunctionAnnotation , error ) {
87
+ content , err := getFileContent (filePath )
88
+ if err != nil {
89
+ return nil , err
90
+ }
91
+
92
+ parser := sitter .NewParser ()
93
+ parser .SetLanguage (golang .GetLanguage ())
94
+
95
+ tree , err := parser .ParseCtx (ctx , nil , []byte (content ))
96
+ if err != nil {
97
+ return nil , err
98
+ }
99
+
100
+ cursor := sitter .NewTreeCursor (tree .RootNode ())
101
+ fnsAnno , err := parseContentForPublicFunctions (content , cursor )
102
+ if err != nil {
103
+ return nil , err
104
+ }
105
+
106
+ return fnsAnno , nil
107
+ }
108
+
84
109
func getFileContent (filePath string ) (content string , err error ) {
85
110
86
111
file , err := os .Open (filePath )
@@ -103,17 +128,17 @@ func parseContent(content string, treeCursor *sitter.TreeCursor, filePath string
103
128
var annotationParser a.Parser
104
129
105
130
fileData .Metadata = getMetadata (content , treeCursor , & annotationParser )
106
- functions := getFunctionNodes (content , treeCursor , & annotationParser )
131
+ funcNodes := getFunctionNodes (content , treeCursor , & annotationParser )
107
132
108
- for _ , function := range functions {
133
+ for _ , function := range funcNodes {
109
134
110
135
behaviors := findBehaviorsFromNode (content , function .Node )
111
136
var callExpressions []string = nil
112
137
if len (behaviors ) > 0 {
113
138
callExpressions = findCallExprFromNode (content , function .Node )
114
139
}
115
140
116
- fileData .Functions = append (fileData .Functions , makeCollectorScenario (filePath , function .Name , behaviors , callExpressions ))
141
+ fileData .Functions = append (fileData .Functions , makeCollectorScenario (filePath , function .Function . Name , behaviors , callExpressions ))
117
142
118
143
}
119
144
@@ -163,9 +188,12 @@ func getMetadata(content string, treeCursor *sitter.TreeCursor, parser *a.Parser
163
188
return & meta
164
189
}
165
190
191
+ // this method extracts functions and methods.
192
+ // Function can have 2 types: function_declaration (for example contructor)
193
+ // and method_declaration (can be exported and unexported)
166
194
func getFunctionNodes (content string , treeCursor * sitter.TreeCursor , parser * a.Parser ) (funcAnnoPair []struct {
167
- Node * sitter.Node
168
- Name string
195
+ Node * sitter.Node
196
+ Function c. FunctionAnnotation
169
197
}) {
170
198
171
199
numChildsRootNode := treeCursor .CurrentNode ().ChildCount ()
@@ -204,17 +232,41 @@ func getFunctionNodes(content string, treeCursor *sitter.TreeCursor, parser *a.P
204
232
}
205
233
206
234
funcAnnoPair = append (funcAnnoPair , struct {
207
- Node * sitter.Node
208
- Name string
235
+ Node * sitter.Node
236
+ Function c. FunctionAnnotation
209
237
}{
210
238
Node : node ,
211
- Name : funcName ,
239
+ Function : c.FunctionAnnotation {
240
+ Name : funcName ,
241
+ },
212
242
})
213
243
214
244
node = nil
215
245
funcName = ""
216
246
isIgnored = false
217
247
}
248
+ if child .Type () == string (METHOD_DECLARATION ) {
249
+ funcName = content [child .Child (2 ).StartByte ():child .Child (2 ).EndByte ()]
250
+ public := unicode .IsUpper (rune (funcName [0 ]))
251
+ params := ""
252
+ returnValues := ""
253
+ if child .Child (1 ).Type () == string (PARAMETER_LIST ) {
254
+ params = content [child .Child (3 ).StartByte ():child .Child (3 ).EndByte ()]
255
+ returnValues = content [child .Child (4 ).StartByte ():child .Child (4 ).EndByte ()]
256
+ }
257
+ funcAnnoPair = append (funcAnnoPair , struct {
258
+ Node * sitter.Node
259
+ Function c.FunctionAnnotation
260
+ }{
261
+ Node : child ,
262
+ Function : c.FunctionAnnotation {
263
+ Name : funcName ,
264
+ Public : public ,
265
+ InputParams : params ,
266
+ ReturnValues : returnValues ,
267
+ },
268
+ })
269
+ }
218
270
prevNode = child
219
271
}
220
272
}
@@ -301,3 +353,15 @@ func makeID(filePath string, funcName string, behavior string) string {
301
353
hash := md5 .Sum ([]byte (fmt .Sprintf ("%s_%s_%s" , filePath , funcName , behavior )))
302
354
return string (hex .EncodeToString (hash [:]))
303
355
}
356
+
357
+ func parseContentForPublicFunctions (content string , cursor * sitter.TreeCursor ) ([]c.FunctionAnnotation , error ) {
358
+ var annotationParser a.Parser
359
+
360
+ var fnsAnno []c.FunctionAnnotation
361
+ functions := getFunctionNodes (content , cursor , & annotationParser )
362
+ for _ , f := range functions {
363
+ fnsAnno = append (fnsAnno , f .Function )
364
+ }
365
+
366
+ return fnsAnno , nil
367
+ }
0 commit comments