6
6
7
7
"github.com/sirupsen/logrus"
8
8
"github.com/src-d/gitbase"
9
+ bblfsh "gopkg.in/bblfsh/client-go.v2"
9
10
"gopkg.in/bblfsh/client-go.v2/tools"
10
11
"gopkg.in/bblfsh/sdk.v1/protocol"
11
12
"gopkg.in/bblfsh/sdk.v1/uast"
@@ -25,11 +26,12 @@ type UAST struct {
25
26
Blob sql.Expression
26
27
Lang sql.Expression
27
28
XPath sql.Expression
29
+ Mode sql.Expression
28
30
}
29
31
30
32
// NewUAST creates a new UAST UDF.
31
33
func NewUAST (args ... sql.Expression ) (sql.Expression , error ) {
32
- var blob , lang , xpath sql.Expression
34
+ var blob , lang , xpath , mode sql.Expression
33
35
switch len (args ) {
34
36
case 1 :
35
37
blob = args [0 ]
@@ -40,10 +42,15 @@ func NewUAST(args ...sql.Expression) (sql.Expression, error) {
40
42
blob = args [0 ]
41
43
lang = args [1 ]
42
44
xpath = args [2 ]
45
+ case 4 :
46
+ blob = args [0 ]
47
+ lang = args [1 ]
48
+ xpath = args [2 ]
49
+ mode = args [3 ]
43
50
default :
44
- return nil , sql .ErrInvalidArgumentNumber .New ("1, 2 or 3 " , len (args ))
51
+ return nil , sql .ErrInvalidArgumentNumber .New ("1, 2, 3 or 4 " , len (args ))
45
52
}
46
- return & UAST {blob , lang , xpath }, nil
53
+ return & UAST {blob , lang , xpath , mode }, nil
47
54
}
48
55
49
56
// IsNullable implements the Expression interface.
@@ -79,7 +86,7 @@ func (f UAST) Children() []sql.Expression {
79
86
80
87
// TransformUp implements the Expression interface.
81
88
func (f UAST ) TransformUp (fn sql.TransformExprFunc ) (sql.Expression , error ) {
82
- var lang , xpath sql.Expression
89
+ var lang , xpath , mode sql.Expression
83
90
blob , err := f .Blob .TransformUp (fn )
84
91
if err != nil {
85
92
return nil , err
@@ -99,10 +106,21 @@ func (f UAST) TransformUp(fn sql.TransformExprFunc) (sql.Expression, error) {
99
106
}
100
107
}
101
108
102
- return fn (& UAST {Blob : blob , Lang : lang , XPath : xpath })
109
+ if f .Mode != nil {
110
+ mode , err = f .Mode .TransformUp (fn )
111
+ if err != nil {
112
+ return nil , err
113
+ }
114
+ }
115
+
116
+ return fn (& UAST {Blob : blob , Lang : lang , XPath : xpath , Mode : mode })
103
117
}
104
118
105
119
func (f UAST ) String () string {
120
+ if f .Lang != nil && f .XPath != nil && f .Mode != nil {
121
+ return fmt .Sprintf ("uast(%s, %s, %s, %s)" , f .Blob , f .Lang , f .XPath , f .Mode )
122
+ }
123
+
106
124
if f .Lang != nil && f .XPath != nil {
107
125
return fmt .Sprintf ("uast(%s, %s, %s)" , f .Blob , f .Lang , f .XPath )
108
126
}
@@ -184,6 +202,39 @@ func (f UAST) Eval(ctx *sql.Context, row sql.Row) (out interface{}, err error) {
184
202
xpath = x .(string )
185
203
}
186
204
205
+ modeSet := false
206
+ var mode bblfsh.Mode
207
+ if f .Mode != nil {
208
+ x , err := f .Mode .Eval (ctx , row )
209
+ if err != nil {
210
+ return nil , err
211
+ }
212
+
213
+ if x == nil {
214
+ return nil , nil
215
+ }
216
+
217
+ x , err = sql .Text .Convert (x )
218
+ if err != nil {
219
+ return nil , err
220
+ }
221
+
222
+ m := x .(string )
223
+
224
+ switch m {
225
+ case "semantic" :
226
+ mode = bblfsh .Semantic
227
+ case "annotated" :
228
+ mode = bblfsh .Annotated
229
+ case "native" :
230
+ mode = bblfsh .Native
231
+ default :
232
+ return nil , fmt .Errorf ("invalid uast mode %s" , m )
233
+ }
234
+
235
+ modeSet = true
236
+ }
237
+
187
238
client , err := session .BblfshClient ()
188
239
if err != nil {
189
240
return nil , err
@@ -202,13 +253,19 @@ func (f UAST) Eval(ctx *sql.Context, row sql.Row) (out interface{}, err error) {
202
253
}
203
254
}
204
255
205
- resp , err := client .Parse (ctx , lang , bytes )
256
+ var resp * protocol.ParseResponse
257
+ if modeSet {
258
+ resp , err = client .ParseWithMode (ctx , mode , lang , bytes )
259
+ } else {
260
+ resp , err = client .Parse (ctx , lang , bytes )
261
+ }
262
+
206
263
if err != nil {
207
264
logrus .Warn (ErrParseBlob .New (err ))
208
265
return nil , nil
209
266
}
210
267
211
- if resp .Status != protocol . Ok {
268
+ if len ( resp .Errors ) > 0 {
212
269
logrus .Warn (ErrParseBlob .New (strings .Join (resp .Errors , "\n " )))
213
270
}
214
271
0 commit comments