Skip to content

Commit

Permalink
internal/lsp: don't deep complete struct field names
Browse files Browse the repository at this point in the history
When it is certain we are completing a struct field name, we don't
want deep completions. The only possible completions are the remaining
field names.

I also silenced the log spam in tests by disabling the go/packages
logger and the lsp logger.

Fixes golang/go#33614

Change-Id: Icec8d92112b1674fa7a6a21145ab710d054919b4
Reviewed-on: https://go-review.googlesource.com/c/tools/+/190097
Reviewed-by: Rebecca Stambler <[email protected]>
Run-TryBot: Rebecca Stambler <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
  • Loading branch information
muirdm authored and stamblerre committed Aug 13, 2019
1 parent 97f12d7 commit 41f3357
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 3 deletions.
3 changes: 3 additions & 0 deletions internal/lsp/lsp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"golang.org/x/tools/internal/lsp/diff"
"golang.org/x/tools/internal/lsp/protocol"
"golang.org/x/tools/internal/lsp/source"
"golang.org/x/tools/internal/lsp/telemetry/log"
"golang.org/x/tools/internal/lsp/tests"
"golang.org/x/tools/internal/span"
)
Expand All @@ -41,6 +42,8 @@ func testLSP(t *testing.T, exporter packagestest.Exporter) {
data := tests.Load(t, exporter, "testdata")
defer data.Exported.Cleanup()

log.AddLogger(log.NullLogger)

cache := cache.New()
session := cache.NewSession(ctx)
view := session.NewView(ctx, viewName, span.FileURI(data.Config.Dir))
Expand Down
6 changes: 6 additions & 0 deletions internal/lsp/source/deep_completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ func (c *completer) deepSearch(obj types.Object) {
return
}

// If we are definitely completing a struct field name, deep completions
// don't make sense.
if c.wantStructFieldCompletions() && c.enclosingCompositeLiteral.inKey {
return
}

// Don't search into type names.
if isTypeName(obj) {
return
Expand Down
3 changes: 3 additions & 0 deletions internal/lsp/source/source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"golang.org/x/tools/internal/lsp/cache"
"golang.org/x/tools/internal/lsp/diff"
"golang.org/x/tools/internal/lsp/source"
"golang.org/x/tools/internal/lsp/telemetry/log"
"golang.org/x/tools/internal/lsp/tests"
"golang.org/x/tools/internal/span"
)
Expand All @@ -37,6 +38,8 @@ func testSource(t *testing.T, exporter packagestest.Exporter) {
data := tests.Load(t, exporter, "../testdata")
defer data.Exported.Cleanup()

log.AddLogger(log.NullLogger)

cache := cache.New()
session := cache.NewSession(ctx)
r := &runner{
Expand Down
6 changes: 6 additions & 0 deletions internal/lsp/telemetry/log/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,9 @@ func Stderr(ctx context.Context, at time.Time, tags tag.List) bool {
fmt.Fprintf(os.Stderr, "%v\n", ToEntry(ctx, at, tags))
return true
}

// NullLogger is a logger that throws away log messages and reports
// success so that the fallback stderr logging does not happen.
var NullLogger = func(context.Context, time.Time, tag.List) bool {
return true
}
11 changes: 11 additions & 0 deletions internal/lsp/testdata/deepcomplete/deep_complete.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,14 @@ func _() {
a.deepEmbedC //@item(deepEmbedC, "a.deepEmbedC", "deepEmbedC", "field")
wantsC(a) //@complete(")", deepEmbedC, deepEmbedA, deepEmbedB)
}

func _() {
type nested struct {
a int
n *nested //@item(deepNestedField, "n", "*nested", "field")
}

nested{
a: 123, //@complete(" //", deepNestedField)
}
}
6 changes: 3 additions & 3 deletions internal/lsp/tests/tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (
// We hardcode the expected number of test cases to ensure that all tests
// are being executed. If a test is added, this number must be changed.
const (
ExpectedCompletionsCount = 144
ExpectedCompletionsCount = 145
ExpectedCompletionSnippetCount = 15
ExpectedDiagnosticsCount = 21
ExpectedFormatCount = 6
Expand Down Expand Up @@ -195,12 +195,12 @@ func Load(t testing.TB, exporter packagestest.Exporter, dir string) *Data {
filename := data.Exported.File(testModule, fragment)
data.fragments[filename] = fragment
}
data.Exported.Config.Logf = t.Logf
data.Exported.Config.Logf = nil

// Merge the exported.Config with the view.Config.
data.Config = *data.Exported.Config
data.Config.Fset = token.NewFileSet()
data.Config.Logf = t.Logf
data.Config.Logf = nil
data.Config.Context = Context(nil)
data.Config.ParseFile = func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) {
panic("ParseFile should not be called")
Expand Down

0 comments on commit 41f3357

Please sign in to comment.