Skip to content

Commit 7b85f5a

Browse files
committed
*: modify uast functions and session to make use of bblfsh/client-go.v3
Signed-off-by: Manuel Carmona <[email protected]>
1 parent 3f51a2c commit 7b85f5a

File tree

4 files changed

+313
-214
lines changed

4 files changed

+313
-214
lines changed

internal/function/uast.go

Lines changed: 180 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ import (
1010
"sync"
1111

1212
lru "github.com/hashicorp/golang-lru"
13-
bblfsh "gopkg.in/bblfsh/client-go.v2"
14-
"gopkg.in/bblfsh/client-go.v2/tools"
15-
"gopkg.in/bblfsh/sdk.v1/uast"
13+
bblfsh "gopkg.in/bblfsh/client-go.v3"
14+
"gopkg.in/bblfsh/sdk.v2/uast"
15+
"gopkg.in/bblfsh/sdk.v2/uast/nodes"
1616

1717
"gopkg.in/src-d/go-mysql-server.v0/sql"
1818
"gopkg.in/src-d/go-mysql-server.v0/sql/expression"
@@ -141,16 +141,9 @@ func (u *uastFunc) Eval(ctx *sql.Context, row sql.Row) (out interface{}, err err
141141
return nil, err
142142
}
143143

144-
var mode bblfsh.Mode
145-
switch m {
146-
case "semantic":
147-
mode = bblfsh.Semantic
148-
case "annotated":
149-
mode = bblfsh.Annotated
150-
case "native":
151-
mode = bblfsh.Native
152-
default:
153-
return nil, fmt.Errorf("invalid uast mode %s", m)
144+
mode, err := bblfsh.ParseMode(m)
145+
if err != nil {
146+
return nil, err
154147
}
155148

156149
blob, err := u.Blob.Eval(ctx, row)
@@ -201,10 +194,10 @@ func (u *uastFunc) getUAST(
201194
return nil, err
202195
}
203196

204-
var node *uast.Node
197+
var node nodes.Node
205198
value, ok := uastCache.Get(key)
206199
if ok {
207-
node = value.(*uast.Node)
200+
node = value.(nodes.Node)
208201
} else {
209202
var err error
210203
node, err = getUASTFromBblfsh(ctx, blob, lang, xpath, mode)
@@ -219,18 +212,18 @@ func (u *uastFunc) getUAST(
219212
uastCache.Add(key, node)
220213
}
221214

222-
var nodes []*uast.Node
215+
var nodeArray nodes.Array
223216
if xpath == "" {
224-
nodes = []*uast.Node{node}
217+
nodeArray = append(nodeArray, node)
225218
} else {
226219
var err error
227-
nodes, err = tools.Filter(node, xpath)
220+
nodeArray, err = applyXpath(node, xpath)
228221
if err != nil {
229222
return nil, err
230223
}
231224
}
232225

233-
return marshalNodes(nodes)
226+
return marshalNodes(nodeArray)
234227
}
235228

236229
// UAST returns an array of UAST nodes as blobs.
@@ -349,37 +342,37 @@ func (f *UASTXPath) Eval(ctx *sql.Context, row sql.Row) (out interface{}, err er
349342
span, ctx := ctx.Span("gitbase.UASTXPath")
350343
defer span.Finish()
351344

352-
left, err := f.Left.Eval(ctx, row)
345+
xpath, err := exprToString(ctx, f.Right, row)
353346
if err != nil {
354347
return nil, err
355348
}
356349

357-
nodes, err := getNodes(left)
358-
if err != nil {
359-
return nil, err
350+
if xpath == "" {
351+
return nil, nil
360352
}
361353

362-
if nodes == nil {
363-
return nil, nil
354+
left, err := f.Left.Eval(ctx, row)
355+
if err != nil {
356+
return nil, err
364357
}
365358

366-
xpath, err := exprToString(ctx, f.Right, row)
359+
ns, err := getNodes(left)
367360
if err != nil {
368361
return nil, err
369362
}
370363

371-
if xpath == "" {
364+
if ns == nil {
372365
return nil, nil
373366
}
374367

375-
var filtered []*uast.Node
376-
for _, n := range nodes {
377-
ns, err := tools.Filter(n, xpath)
368+
var filtered nodes.Array
369+
for _, n := range ns {
370+
partial, err := applyXpath(n, xpath)
378371
if err != nil {
379372
return nil, err
380373
}
381374

382-
filtered = append(filtered, ns...)
375+
filtered = append(filtered, partial...)
383376
}
384377

385378
return marshalNodes(filtered)
@@ -440,12 +433,12 @@ func (u *UASTExtract) Eval(ctx *sql.Context, row sql.Row) (out interface{}, err
440433
return nil, err
441434
}
442435

443-
nodes, err := getNodes(left)
436+
ns, err := getNodes(left)
444437
if err != nil {
445438
return nil, err
446439
}
447440

448-
if nodes == nil {
441+
if ns == nil {
449442
return nil, nil
450443
}
451444

@@ -459,60 +452,140 @@ func (u *UASTExtract) Eval(ctx *sql.Context, row sql.Row) (out interface{}, err
459452
}
460453

461454
extracted := []interface{}{}
462-
for _, n := range nodes {
463-
info := extractInfo(n, key)
464-
if len(info) > 0 {
465-
extracted = append(extracted, info...)
455+
for _, n := range ns {
456+
props := extractProperties(n, key)
457+
if len(props) > 0 {
458+
extracted = append(extracted, props...)
466459
}
467460
}
468461

469462
return extracted, nil
470463
}
471464

472-
const (
473-
keyType = "@type"
474-
keyToken = "@token"
475-
keyRoles = "@role"
476-
keyStartPos = "@startpos"
477-
keyEndPos = "@endpos"
478-
)
465+
func extractProperties(n nodes.Node, key string) []interface{} {
466+
node, ok := n.(nodes.Object)
467+
if !ok {
468+
return nil
469+
}
479470

480-
func extractInfo(n *uast.Node, key string) []interface{} {
481-
var info []interface{}
471+
var extracted []interface{}
472+
if isCommonProp(key) {
473+
extracted = extractCommonProp(node, key)
474+
} else {
475+
extracted = extractAnyProp(node, key)
476+
}
477+
478+
return extracted
479+
}
480+
481+
func isCommonProp(key string) bool {
482+
return key == uast.KeyType || key == uast.KeyToken ||
483+
key == uast.KeyRoles || key == uast.KeyPos
484+
}
485+
486+
func extractCommonProp(node nodes.Object, key string) []interface{} {
487+
var extracted []interface{}
482488
switch key {
483-
case keyType:
484-
if n.InternalType != "" {
485-
info = append(info, n.InternalType)
489+
case uast.KeyType:
490+
t := uast.TypeOf(node)
491+
if t != "" {
492+
extracted = append(extracted, t)
486493
}
487-
case keyToken:
488-
if n.Token != "" {
489-
info = append(info, n.Token)
494+
case uast.KeyToken:
495+
t := uast.TokenOf(node)
496+
if t != "" {
497+
extracted = append(extracted, t)
490498
}
491-
case keyRoles:
492-
if len(n.Roles) > 0 {
493-
roles := make([]interface{}, len(n.Roles))
494-
for i, rol := range n.Roles {
495-
roles[i] = rol.String()
499+
case uast.KeyRoles:
500+
r := uast.RolesOf(node)
501+
if len(r) > 0 {
502+
roles := make([]interface{}, len(r))
503+
for i, role := range r {
504+
roles[i] = role.String()
496505
}
497506

498-
info = append(info, roles...)
507+
extracted = append(extracted, roles...)
499508
}
500-
case keyStartPos:
501-
if n.StartPosition != nil {
502-
info = append(info, n.StartPosition.String())
509+
case uast.KeyPos:
510+
p := uast.PositionsOf(node)
511+
if p != nil {
512+
if s := posToString(p); s != "" {
513+
extracted = append(extracted, s)
514+
}
503515
}
504-
case keyEndPos:
505-
if n.StartPosition != nil {
506-
info = append(info, n.EndPosition.String())
516+
}
517+
518+
return extracted
519+
}
520+
521+
func posToString(pos uast.Positions) string {
522+
var b strings.Builder
523+
524+
start := pos.Start()
525+
end := pos.End()
526+
527+
if start != nil {
528+
fmt.Fprintf(&b, "Start: [Offset:%d Line:%d Col:%d]",
529+
start.Offset, start.Line, start.Col)
530+
}
531+
532+
if pos.End() != nil {
533+
if pos.Start() != nil {
534+
fmt.Fprint(&b, ", ")
507535
}
508-
default:
509-
v, ok := n.Properties[key]
510-
if ok {
511-
info = append(info, v)
536+
537+
fmt.Fprintf(&b, "End: [Offset:%d Line:%d Col:%d]",
538+
end.Offset, end.Line, end.Col)
539+
}
540+
541+
return b.String()
542+
}
543+
544+
func extractAnyProp(node nodes.Object, key string) []interface{} {
545+
v, ok := node[key]
546+
if !ok {
547+
return nil
548+
}
549+
550+
if v.Kind().In(nodes.KindsValues) {
551+
value, err := valueToString(v.(nodes.Value))
552+
if err != nil {
553+
return nil
554+
}
555+
556+
return []interface{}{value}
557+
}
558+
559+
if v.Kind() == nodes.KindArray {
560+
values, err := valuesFromNodeArray(v.(nodes.Array))
561+
if err != nil {
562+
return nil
563+
}
564+
565+
return values
566+
}
567+
568+
return nil
569+
}
570+
571+
func valuesFromNodeArray(arr nodes.Array) ([]interface{}, error) {
572+
var values []interface{}
573+
for _, n := range arr {
574+
if n.Kind().In(nodes.KindsValues) {
575+
s, err := valueToString(n.(nodes.Value))
576+
if err != nil {
577+
return nil, err
578+
}
579+
580+
values = append(values, s)
512581
}
513582
}
514583

515-
return info
584+
return values, nil
585+
}
586+
587+
func valueToString(n nodes.Value) (interface{}, error) {
588+
return sql.Text.Convert(n.Native())
516589
}
517590

518591
// TransformUp implements the sql.Expression interface.
@@ -589,11 +662,44 @@ func (u *UASTChildren) Eval(ctx *sql.Context, row sql.Row) (out interface{}, err
589662
return marshalNodes(children)
590663
}
591664

592-
func flattenChildren(nodes []*uast.Node) []*uast.Node {
593-
children := []*uast.Node{}
594-
for _, n := range nodes {
595-
if len(n.Children) > 0 {
596-
children = append(children, n.Children...)
665+
func flattenChildren(arr nodes.Array) nodes.Array {
666+
var children nodes.Array
667+
for _, n := range arr {
668+
o, ok := n.(nodes.Object)
669+
if !ok {
670+
continue
671+
}
672+
673+
c := getChildren(o)
674+
if len(c) > 0 {
675+
children = append(children, c...)
676+
}
677+
}
678+
679+
return children
680+
}
681+
682+
func getChildren(node nodes.Object) nodes.Array {
683+
var children nodes.Array
684+
for _, key := range node.Keys() {
685+
if isCommonProp(key) {
686+
continue
687+
}
688+
689+
c, ok := node[key]
690+
if !ok {
691+
continue
692+
}
693+
694+
switch c.Kind() {
695+
case nodes.KindObject:
696+
children = append(children, c)
697+
case nodes.KindArray:
698+
for _, n := range c.(nodes.Array) {
699+
if n.Kind() == nodes.KindObject {
700+
children = append(children, n)
701+
}
702+
}
597703
}
598704
}
599705

0 commit comments

Comments
 (0)