From b466bc1588c844bbad3ab81daf461237e3fc23d5 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Tue, 21 Jan 2020 18:34:53 +0100 Subject: [PATCH] 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. --- internal/jsre/completion.go | 46 ++++++++++---------------------- internal/jsre/completion_test.go | 4 +++ 2 files changed, 18 insertions(+), 32 deletions(-) diff --git a/internal/jsre/completion.go b/internal/jsre/completion.go index cfa0933f56..2c105184cb 100644 --- a/internal/jsre/completion.go +++ b/internal/jsre/completion.go @@ -35,47 +35,29 @@ func (jsre *JSRE) CompleteKeywords(line string) []string { func getCompletions(vm *goja.Runtime, line string) (results []string) { parts := strings.Split(line, ".") - objRef := "this" - prefix := line - if len(parts) == 0 { return nil } - // Figure out which is the right-most fully named object - // in the line. e.g. if line = "x.y.z" and "x.y" is an - // object, and that its keys are "zebu" and "zebra", then - // objRef will be set to "y" and obj will reference "x.y". - v := vm.Get(parts[0]) - 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 { - return nil - } - obj = v.ToObject(vm) + // Find the right-most fully named object in the line. e.g. if line = "x.y.z" + // and "x.y" is an object, obj will reference "x.y". + obj := vm.GlobalObject() + for i := 0; i < len(parts)-1; i++ { + v := obj.Get(parts[i]) + if v == nil { + return nil // No object was found } - 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 + obj = v.ToObject(vm) } - // Go over the keys of the right-most object (which could - // be `this`) and retain those keys that are prefixed by - // `prefix`. e.g. if line = "x.y.z", that "x.y" exists - // and has keys "zebu", "zebra" and "platypus", then only - // "zebu" and "zebra" will be added to `results`. + // Go over the keys of the object and retain the keys matching prefix. + // Example: if line = "x.y.z" and "x.y" exists and has keys "zebu", "zebra" + // and "platypus", then "x.y.zebu" and "x.y.zebra" will be added to results. + prefix := parts[len(parts)-1] iterOwnAndConstructorKeys(vm, obj, func(k string) { if strings.HasPrefix(k, prefix) { - if objRef == "this" { - results = append(results, line) + if len(parts) == 1 { + results = append(results, k) } else { results = append(results, strings.Join(parts[:len(parts)-1], ".")+"."+k) } diff --git a/internal/jsre/completion_test.go b/internal/jsre/completion_test.go index 80adea5303..d458fe0975 100644 --- a/internal/jsre/completion_test.go +++ b/internal/jsre/completion_test.go @@ -41,6 +41,10 @@ func TestCompleteKeywords(t *testing.T) { input string want []string }{ + { + input: "St", + want: []string{"String"}, + }, { input: "x", want: []string{"x."},