All Projects → bblfsh → go-client

bblfsh / go-client

Licence: Apache-2.0 license
Babelfish Go client

Programming Languages

go
31211 projects - #10 most used programming language
Makefile
30231 projects

Projects that are alternatives of or similar to go-client

documentation
Babelfish documentation (GitBook)
Stars: ✭ 40 (+5.26%)
Mutual labels:  babelfish
sdk
Babelfish driver SDK
Stars: ✭ 22 (-42.11%)
Mutual labels:  babelfish
babelfish
Universal translater for encodings
Stars: ✭ 13 (-65.79%)
Mutual labels:  babelfish
web
Web client for Babelfish server
Stars: ✭ 22 (-42.11%)
Mutual labels:  babelfish

go-client GoDoc Build Status Build status codecov

Babelfish Go client library provides functionality to both connecting to the Babelfish server for parsing code (obtaining an UAST as a result) and for analysing UASTs with the functionality provided by libuast.

Installation

The recommended way to install go-client is:

go get -u github.com/bblfsh/go-client/v4/...

Example

CLI

Although go-client is a library, this codebase also includes an example of bblfsh-cli application at ./cmd/bblfsh-cli. When installed, it allows to parse a single file, query it with XPath and print the resulting UAST structure immediately. See $ bblfsh-cli -h for list of all available CLI options.

Code

This small example illustrates how to retrieve the UAST from a small Python script.

If you don't have a bblfsh server installed, please read the getting started guide, to learn more about how to use and deploy a bblfsh server.

Go to the quick start to discover how to run Babelfish with Docker.

package main

import (
	"context"
	"fmt"
	"time"

	"github.com/bblfsh/go-client/v4"
	"github.com/bblfsh/go-client/v4/tools"

	"github.com/bblfsh/sdk/v3/uast/nodes"
	"github.com/bblfsh/sdk/v3/uast/uastyaml"

	"google.golang.org/grpc"
	"google.golang.org/grpc/keepalive"
)

func main() {
	ctx := context.Background()
	client, err := bblfsh.NewClientContext(ctx, "0.0.0.0:9432",
		// Set an extra grpc DialOptions to avoid "transport closing" errors when client is idle.
		// Passing keepalive params here, you can overwrite defaults:
		// Time: 2 minutes, PermitWithoutStream: true
		grpc.WithKeepaliveParams(keepalive.ClientParameters{
			// Time is a duration after this if the client doesn't see any activity it
			// pings the server to see if the transport is still alive.
			Time:                2 * time.Minute,

			// PermitWithoutStream is a boolean flag.
			// If true, client sends keepalive pings even with no active RPCs.
			PermitWithoutStream: true,
		}),
	)
	if err != nil {
		panic(err)
	}

	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() {
		nodeAr = append(nodeAr, it.Node().(nodes.Node))
	}

	// The example below emits YAML.
	//
	// Alternative 1: encode UAST nodes to JSON.
	//   data, err := json.MarshalIndent(nodeAr, "", "  ")
	//
	// Alternative 2: encode UAST nodes to protobuf.
	//   import "github.com/bblfsh/sdk/v3/uast/nodes/nodesproto"
	//   ...
	//   for _, node := range nodesAr {
	//      err := nodesproto.WriteTo(os.Stdout, nodeAr) // check
	//      ...
	//   }
	//
	data, err := uastyaml.Marshal(nodeAr)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(data))
}

produces

   { '@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: ~,
   },
]
iter := tools.NewIterator(res, tools.PreOrder)
for node := range tools.Iterate(iter) {
	fmt.Println(node)
}

// For XPath expressions returning a boolean/numeric/string value, you must
// use the right typed Filter function:

boolres, err := tools.FilterBool(res, "boolean(//*[@start-offset or @end-offset])")
strres, err := tools.FilterString(res, "name(//*[1])")
numres, err := tools.FilterNumber(res, "count(//*)")

Please read the Babelfish clients guide section to learn more about babelfish clients and their query language.

License

Apache License 2.0, see LICENSE

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].