internal/jsre: fix completion of globals

It didn't complete 'St' to 'String' for some reason. Now it does,
and the code is much simpler.
This commit is contained in:
Felix Lange 2020-01-21 18:34:53 +01:00
parent 3fdc0937eb
commit b466bc1588
2 changed files with 18 additions and 32 deletions

View file

@ -35,47 +35,29 @@ func (jsre *JSRE) CompleteKeywords(line string) []string {
func getCompletions(vm *goja.Runtime, line string) (results []string) { func getCompletions(vm *goja.Runtime, line string) (results []string) {
parts := strings.Split(line, ".") parts := strings.Split(line, ".")
objRef := "this"
prefix := line
if len(parts) == 0 { if len(parts) == 0 {
return nil return nil
} }
// Figure out which is the right-most fully named object // Find the right-most fully named object in the line. e.g. if line = "x.y.z"
// in the line. e.g. if line = "x.y.z" and "x.y" is an // and "x.y" is an object, obj will reference "x.y".
// object, and that its keys are "zebu" and "zebra", then obj := vm.GlobalObject()
// objRef will be set to "y" and obj will reference "x.y". for i := 0; i < len(parts)-1; i++ {
v := vm.Get(parts[0]) v := obj.Get(parts[i])
var obj *goja.Object = v.ToObject(vm)
switch {
case obj != nil && len(parts) > 1: // "x.y.z" case
objRef = strings.Join(parts[0:len(parts)-1], ".")
prefix = parts[len(parts)-1]
for _, part := range parts[1 : len(parts)-1] {
v = obj.Get(part)
if v == nil { if v == nil {
return nil return nil // No object was found
} }
obj = v.ToObject(vm) obj = v.ToObject(vm)
} }
case obj != nil:
// In this case, there is no "." chain, so the
// the right-most object is assumed to be `this`.
obj = vm.GlobalObject()
default: // No object was found
return nil
}
// Go over the keys of the right-most object (which could // Go over the keys of the object and retain the keys matching prefix.
// be `this`) and retain those keys that are prefixed by // Example: if line = "x.y.z" and "x.y" exists and has keys "zebu", "zebra"
// `prefix`. e.g. if line = "x.y.z", that "x.y" exists // and "platypus", then "x.y.zebu" and "x.y.zebra" will be added to results.
// and has keys "zebu", "zebra" and "platypus", then only prefix := parts[len(parts)-1]
// "zebu" and "zebra" will be added to `results`.
iterOwnAndConstructorKeys(vm, obj, func(k string) { iterOwnAndConstructorKeys(vm, obj, func(k string) {
if strings.HasPrefix(k, prefix) { if strings.HasPrefix(k, prefix) {
if objRef == "this" { if len(parts) == 1 {
results = append(results, line) results = append(results, k)
} else { } else {
results = append(results, strings.Join(parts[:len(parts)-1], ".")+"."+k) results = append(results, strings.Join(parts[:len(parts)-1], ".")+"."+k)
} }

View file

@ -41,6 +41,10 @@ func TestCompleteKeywords(t *testing.T) {
input string input string
want []string want []string
}{ }{
{
input: "St",
want: []string{"String"},
},
{ {
input: "x", input: "x",
want: []string{"x."}, want: []string{"x."},