-
Notifications
You must be signed in to change notification settings - Fork 154
/
complete.go
109 lines (85 loc) · 2.41 KB
/
complete.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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// Package complete provides types to aid with auto-completion of Flux scripts in editors.
package complete
import (
"errors"
"fmt"
"sort"
"github.com/influxdata/flux"
"github.com/influxdata/flux/interpreter"
"github.com/influxdata/flux/semantic"
"github.com/influxdata/flux/values"
)
type functionType interface {
Signature() semantic.FunctionPolySignature
}
// FunctionSuggestion provides suggestion information about a function.
type FunctionSuggestion struct {
Params map[string]string
}
// Completer provides methods for suggestions in Flux queries.
type Completer struct {
scope interpreter.Scope
}
// NewCompleter creates a new completer from scope.
func NewCompleter(scope interpreter.Scope) Completer {
return Completer{scope: scope}
}
// Names returns the slice of names in scope.
func (c Completer) Names() []string {
names := make([]string, 0, c.scope.Size())
c.scope.Range(func(k string, v values.Value) {
names = append(names, k)
})
sort.Strings(names)
return names
}
// Value returns a value based on the expression name, if one exists.
func (c Completer) Value(name string) (values.Value, error) {
v, ok := c.scope.Lookup(name)
if !ok {
return nil, errors.New("could not find value")
}
return v, nil
}
// FunctionNames returns the names of all function.
func (c Completer) FunctionNames() []string {
funcs := []string{}
c.scope.Range(func(name string, v values.Value) {
if isFunction(v) {
funcs = append(funcs, name)
}
})
sort.Strings(funcs)
return funcs
}
// FunctionSuggestion returns information needed for autocomplete suggestions for the function with the given name.
func (c Completer) FunctionSuggestion(name string) (FunctionSuggestion, error) {
var s FunctionSuggestion
v, err := c.Value(name)
if err != nil {
return s, err
}
if !isFunction(v) {
return s, fmt.Errorf("name ( %s ) is not a function", name)
}
funcType, ok := v.PolyType().(functionType)
if !ok {
return s, errors.New("could not cast function type")
}
sig := funcType.Signature()
params := make(map[string]string, len(sig.Parameters))
for k, v := range sig.Parameters {
params[k] = v.Nature().String()
}
s = FunctionSuggestion{
Params: params,
}
return s, nil
}
// DefaultCompleter creates a completer with builtin scope
func DefaultCompleter() Completer {
return NewCompleter(flux.Prelude())
}
func isFunction(v values.Value) bool {
return v.PolyType().Nature() == semantic.Function
}