bblfsh / go-client

Babelfish Go client
https://doc.bblf.sh/using-babelfish/clients.html
Apache License 2.0
37 stars 20 forks source link

Question: How do I read data from nodes? #131

Open vonhraban opened 4 years ago

vonhraban commented 4 years ago

The example in the docs provides a code snippet to extract the imports from the file. However marshalling nodes into JSON is not a good use case, and I am trying to find a way to get the name of the import without intermediate marhsaling.

    python := "import foo"
    res, _, err := client.NewParseRequest().Context(ctx).
        Language("python").Content(python).UAST()
    if err != nil {
        panic(err)
    }

    query := "//*[self::uast:Import or self::uast:RuntimeImport]"
    it, _ := tools.Filter(res, query)
    var nodeAr nodes.Array
    for it.Next() {
        fmt.Printf(it.Node().Name()) // <---- how do I do this?
    }

It is in the node under Path/Name, but how do I access it?

 { '@type': "uast:RuntimeImport",
      '@pos': { '@type': "uast:Positions",
         start: { '@type': "uast:Position",
            offset: 0,
            line: 1,
            col: 1,
         },
      },
      All: false,
      Names: ~,
      Path: { '@type': "uast:Identifier",
         '@pos': { '@type': "uast:Positions",
         },
         Name: "foo",
      },
      Target: ~,
   },
]

Also while testing it locally with a Go file the following was the output

      Path: { '@type': "uast:QualifiedIdentifier",
         '@pos': { '@type': "uast:Positions",
            start: { '@type': "uast:Position",
               offset: 171,
               line: 17,
               col: 2,
            },
            end: { '@type': "uast:Position",
               offset: 203,
               line: 17,
               col: 34,
            },
         },
         Names: [
            { '@type': "uast:Identifier",
               '@pos': { '@type': "uast:Positions",
                  start: { '@type': "uast:Position",
                     offset: 172,
                     line: 17,
                     col: 3,
                  },
                  end: { '@type': "uast:Position",
                     offset: 189,
                     line: 17,
                     col: 20,
                  },
               },
               Name: "google.golang.org",
            },
            { '@type': "uast:Identifier",
               '@pos': { '@type': "uast:Positions",
                  start: { '@type': "uast:Position",
                     offset: 190,
                     line: 17,
                     col: 21,
                  },
                  end: { '@type': "uast:Position",
                     offset: 193,
                     line: 17,
                     col: 24,
                  },
               },
               Name: "api",
            },
            { '@type': "uast:Identifier",
               '@pos': { '@type': "uast:Positions",
                  start: { '@type': "uast:Position",
                     offset: 194,
                     line: 17,
                     col: 25,
                  },
                  end: { '@type': "uast:Position",
                     offset: 202,
                     line: 17,
                     col: 33,
                  },
               },
               Name: "iterator",
            },
         ],
      },

Somehow Path/Name became Path/Names.

I can not find docs anywhere about how to read data from nodes.

kuba-- commented 4 years ago

@vonhraban - could you try sth. like:

for it.Next() {
        node, ok := it.Node().(nodes.Object)
        if !ok {
            continue
        }
        fmt.Println(node["Name"])
    }

Btw. if you just need to extract imports then I highly recommend to use https://github.com/src-d/imports project instead. It's based on tree-sitter so it's much faster and does not require any server.