This repository has been archived by the owner on Mar 8, 2020. It is now read-only.
/
impl.go
79 lines (67 loc) · 2.08 KB
/
impl.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package driver
import (
"context"
"fmt"
"github.com/opentracing/opentracing-go"
"gopkg.in/bblfsh/sdk.v2/driver/manifest"
"gopkg.in/bblfsh/sdk.v2/uast/nodes"
)
// NewDriver returns a new Driver instance based on the given ObjectToNode and list of transformers.
func NewDriverFrom(d Native, m *manifest.Manifest, t Transforms) (DriverModule, error) {
if d == nil {
return nil, fmt.Errorf("no driver implementation")
} else if m == nil {
return nil, fmt.Errorf("no manifest")
}
return &driverImpl{d: d, m: m, t: t}, nil
}
// Driver implements a bblfsh driver, a driver is on charge of transforming a
// source code into an AST and a UAST. To transform the AST into a UAST, a
// `uast.ObjectToNode`` and a series of `tranformer.Transformer` are used.
//
// The `Parse` and `NativeParse` requests block the driver until the request is
// done, since the communication with the native driver is a single-channel
// synchronous communication over stdin/stdout.
type driverImpl struct {
d Native
m *manifest.Manifest
t Transforms
}
func (d *driverImpl) Start() error {
return d.d.Start()
}
func (d *driverImpl) Close() error {
return d.d.Close()
}
// Parse process a protocol.ParseRequest, calling to the native driver. It a
// parser request is done to the internal native driver and the the returned
// native AST is transform to UAST.
func (d *driverImpl) Parse(rctx context.Context, src string, opts *ParseOptions) (nodes.Node, error) {
sp, ctx := opentracing.StartSpanFromContext(rctx, "bblfsh.driver.Parse")
defer sp.Finish()
if opts == nil {
opts = &ParseOptions{}
}
ast, err := d.d.Parse(ctx, src)
if err != nil {
if !ErrDriverFailure.Is(err) {
// all other errors are considered syntax errors
err = ErrSyntax.Wrap(err)
} else {
ast = nil
}
return ast, err
}
if opts.Language == "" {
opts.Language = d.m.Language
}
ast, err = d.t.Do(ctx, opts.Mode, src, ast)
if err != nil {
err = ErrTransformFailure.Wrap(err)
}
return ast, err
}
// Manifest returns a driver manifest.
func (d *driverImpl) Manifest() (manifest.Manifest, error) {
return *d.m, nil // TODO: clone
}