Skip to content

Commit

Permalink
goxls.SetDebug; typesutil.Check: rec.Type
Browse files Browse the repository at this point in the history
  • Loading branch information
xushiwei committed Oct 22, 2023
1 parent e3f5d8c commit e9661e6
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 48 deletions.
2 changes: 1 addition & 1 deletion gopls/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.18

require (
github.com/google/go-cmp v0.5.9
github.com/goplus/gop v1.1.4-0.20231022032216-10fb4f7af5a6
github.com/goplus/gop v1.1.4-0.20231022165250-225a72d48b18
github.com/goplus/mod v0.11.8-0.20231019172744-da5848421263
github.com/jba/printsrc v0.2.2
github.com/jba/templatecheck v0.6.0
Expand Down
4 changes: 2 additions & 2 deletions gopls/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
github.com/google/safehtml v0.0.2/go.mod h1:L4KWwDsUJdECRAEpZoBn3O64bQaywRscowZjJAzjHnU=
github.com/google/safehtml v0.1.0 h1:EwLKo8qawTKfsi0orxcQAZzu07cICaBeFMegAU9eaT8=
github.com/google/safehtml v0.1.0/go.mod h1:L4KWwDsUJdECRAEpZoBn3O64bQaywRscowZjJAzjHnU=
github.com/goplus/gop v1.1.4-0.20231022032216-10fb4f7af5a6 h1:QAJ4wa36txYBku2V7iTdlaC6LEYbmtEdijaU3CCSgq4=
github.com/goplus/gop v1.1.4-0.20231022032216-10fb4f7af5a6/go.mod h1:jfqgaSg3PBpKcatrfL9eJTnj/wAqS1UadGAd6WZPhow=
github.com/goplus/gop v1.1.4-0.20231022165250-225a72d48b18 h1:0gBioNgh0hghd6L/lzN11aO1D97sYk4UCRMAiDTQveo=
github.com/goplus/gop v1.1.4-0.20231022165250-225a72d48b18/go.mod h1:jfqgaSg3PBpKcatrfL9eJTnj/wAqS1UadGAd6WZPhow=
github.com/goplus/gox v1.12.2-0.20231020202641-5f657ff4e754 h1:uuXDqFfg4RhmHD7slw15hzwVQtJ51CsdcZn6gQtve/E=
github.com/goplus/gox v1.12.2-0.20231020202641-5f657ff4e754/go.mod h1:Ek1YIy3wRaZ1i0DD2XG29i3r5AFdhcOradK0/GGs1YQ=
github.com/goplus/mod v0.11.8-0.20231019172744-da5848421263 h1:PE0HveOss5mai9pa52L4/ZvVqZtltogJ9rIUIsdlG/I=
Expand Down
2 changes: 2 additions & 0 deletions gopls/goxls/goxls.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"os"
"sync"

"golang.org/x/tools/gopls/internal/goxls"
"golang.org/x/tools/gopls/internal/hooks"
"golang.org/x/tools/gopls/internal/lsp/cmd"
"golang.org/x/tools/internal/event"
Expand All @@ -28,5 +29,6 @@ func Main() {
printer.WriteEvent(os.Stderr, e, m)
return ctx
})
goxls.SetDebug(goxls.DbgFlagDefault)
tool.Main(ctx, cmd.New("goxls", "", nil, hooks.Options), os.Args[1:])
}
34 changes: 34 additions & 0 deletions gopls/internal/goxls/debug.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2023 The GoPlus Authors (goplus.org). All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package goxls

import (
"github.com/goplus/gop/cl"
"github.com/goplus/gop/x/typesutil"
)

type dbgFlags int

const (
DbgFlagTypesUtil = 1 << iota
DbgFlagCompletion
DbgFlagDisableRecover
DbgFlagDefault = DbgFlagTypesUtil | DbgFlagCompletion
DbgFlagAll = DbgFlagDefault | DbgFlagDisableRecover
)

var (
DbgCompletion bool
)

func SetDebug(flags dbgFlags) {
if (flags & DbgFlagTypesUtil) != 0 {
typesutil.SetDebug(typesutil.DbgFlagDefault)
}
if (flags & DbgFlagDisableRecover) != 0 {
cl.SetDisableRecover(true)
}
DbgCompletion = (flags & DbgFlagCompletion) != 0
}
10 changes: 6 additions & 4 deletions gopls/internal/goxls/typesutil/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ import (
"github.com/goplus/mod/gopmod"
)

// Info holds result type information for a type-checked package.
// Only the information for which a map is provided is collected.
// If the package has type errors, the collected information may
// be incomplete.
type Info = typesutil.Info

// A Checker maintains the state of the type checker.
// It must be created with NewChecker.
type Checker = typesutil.Checker
Expand Down Expand Up @@ -44,7 +50,3 @@ func NewChecker(conf *types.Config, opts *Config, goInfo *types.Info, gopInfo *I
}
return typesutil.NewChecker(conf, chkOpts, goInfo, gopInfo)
}

func init() {
typesutil.SetDebug(typesutil.DbgFlagDefault)
}
15 changes: 0 additions & 15 deletions gopls/internal/goxls/typesutil/typesutil.go

This file was deleted.

42 changes: 30 additions & 12 deletions gopls/internal/lsp/source/completion/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"golang.org/x/sync/errgroup"
"golang.org/x/tools/go/ast/astutil"
goplsastutil "golang.org/x/tools/gopls/internal/astutil"
"golang.org/x/tools/gopls/internal/goxls"
"golang.org/x/tools/gopls/internal/lsp/protocol"
"golang.org/x/tools/gopls/internal/lsp/safetoken"
"golang.org/x/tools/gopls/internal/lsp/snippet"
Expand Down Expand Up @@ -435,9 +436,10 @@ func (e ErrIsDefinition) Error() string {
// the client to score the quality of the completion. For instance, some clients
// may tolerate imperfect matches as valid completion results, since users may make typos.
func Completion(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle, protoPos protocol.Position, protoContext protocol.CompletionContext) ([]CompletionItem, *Selection, error) {
log.Println("Completion:", fh.URI().Filename(), "kind:", protoContext.TriggerKind, "triggerCh:", protoContext.TriggerCharacter)
defer log.Println("Completion done:", fh.URI().Filename(), "kind:", protoContext.TriggerKind, "triggerCh:", protoContext.TriggerCharacter)

if goxls.DbgCompletion {
log.Println("Completion:", fh.URI().Filename(), "kind:", protoContext.TriggerKind, "triggerCh:", protoContext.TriggerCharacter)
defer log.Println("Completion done:", fh.URI().Filename(), "kind:", protoContext.TriggerKind, "triggerCh:", protoContext.TriggerCharacter)
}
ctx, done := event.Start(ctx, "completion.Completion")
defer done()

Expand Down Expand Up @@ -485,7 +487,9 @@ func Completion(ctx context.Context, snapshot source.Snapshot, fh source.FileHan
case *ast.Ident:
// reject defining identifiers
obj, ok := pkg.GetTypesInfo().Defs[n]
log.Println("Completion ident:", n, "obj:", obj)
if goxls.DbgCompletion {
log.Println("Completion ident:", n, "obj:", obj)
}
if ok {
if v, ok := obj.(*types.Var); ok && v.IsField() && v.Embedded() {
// An anonymous field is also a reference to a type.
Expand Down Expand Up @@ -578,12 +582,14 @@ func Completion(ctx context.Context, snapshot source.Snapshot, fh source.FileHan
defer cancel()

if surrounding := c.containingIdent(pgf.Src); surrounding != nil {
log.Println("Completion surrounding:", surrounding)
if goxls.DbgCompletion {
log.Println("Completion surrounding:", surrounding)
}
c.setSurrounding(surrounding)
}

c.inference = expectedCandidate(ctx, c)
if true {
if goxls.DbgCompletion {
infer := c.inference
log.Printf(`Completion infer:
objType: %v, convertibleTo: %v
Expand All @@ -598,31 +604,41 @@ func Completion(ctx context.Context, snapshot source.Snapshot, fh source.FileHan
if err != nil {
return nil, nil, err
}
log.Println("Completion collect: len(items) =", len(c.items))
if goxls.DbgCompletion {
log.Println("Completion collect: len(items) =", len(c.items))
}

// Deep search collected candidates and their members for more candidates.
c.deepSearch(ctx, start, deadline)
log.Println("Completion deepSearch: len(items) =", len(c.items))
if goxls.DbgCompletion {
log.Println("Completion deepSearch: len(items) =", len(c.items))
}

for _, callback := range c.completionCallbacks {
if err := c.snapshot.RunProcessEnvFunc(ctx, callback); err != nil {
return nil, nil, err
}
log.Println("Completion callbak: len(items) =", len(c.items))
if goxls.DbgCompletion {
log.Println("Completion callbak: len(items) =", len(c.items))
}
}

// Search candidates populated by expensive operations like
// unimportedMembers etc. for more completion items.
c.deepSearch(ctx, start, deadline)
log.Println("Completion deepSearch(2): len(items) =", len(c.items))
if goxls.DbgCompletion {
log.Println("Completion deepSearch(2): len(items) =", len(c.items))
}

// Statement candidates offer an entire statement in certain contexts, as
// opposed to a single object. Add statement candidates last because they
// depend on other candidates having already been collected.
c.addStatementCandidates()

c.sortItems()
log.Println("Completion ret: len(items) =", len(c.items))
if goxls.DbgCompletion {
log.Println("Completion ret: len(items) =", len(c.items))
}
return c.items, c.getSurrounding(), nil
}

Expand Down Expand Up @@ -1133,7 +1149,9 @@ func (c *completer) selector(ctx context.Context, sel *ast.SelectorExpr) error {

// True selector?
tv, ok := c.pkg.GetTypesInfo().Types[sel.X]
log.Println("completer.selector:", ok, "type:", tv.Type)
if goxls.DbgCompletion {
log.Println("completer.selector:", sel.X, ok, "type:", tv.Type)
}
if ok {
c.methodsAndFields(tv.Type, tv.Addressable(), nil, c.deepState.enqueue)
c.addPostfixSnippetCandidates(ctx, sel)
Expand Down
42 changes: 30 additions & 12 deletions gopls/internal/lsp/source/completion/completion_gox.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/goplus/gop/scanner"
"github.com/goplus/gop/token"
"golang.org/x/sync/errgroup"
"golang.org/x/tools/gopls/internal/goxls"
"golang.org/x/tools/gopls/internal/goxls/astutil"
"golang.org/x/tools/gopls/internal/goxls/typeparams"
"golang.org/x/tools/gopls/internal/goxls/typesutil"
Expand Down Expand Up @@ -278,9 +279,10 @@ func gopEnclosingFunction(path []ast.Node, info *typesutil.Info) *gopFuncInfo {
// the client to score the quality of the completion. For instance, some clients
// may tolerate imperfect matches as valid completion results, since users may make typos.
func GopCompletion(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle, protoPos protocol.Position, protoContext protocol.CompletionContext) ([]CompletionItem, *Selection, error) {
log.Println("GopCompletion:", fh.URI().Filename(), "kind:", protoContext.TriggerKind, "triggerCh:", protoContext.TriggerCharacter)
defer log.Println("GopCompletion done:", fh.URI().Filename(), "kind:", protoContext.TriggerKind, "triggerCh:", protoContext.TriggerCharacter)

if goxls.DbgCompletion {
log.Println("GopCompletion:", fh.URI().Filename(), "kind:", protoContext.TriggerKind, "triggerCh:", protoContext.TriggerCharacter)
defer log.Println("GopCompletion done:", fh.URI().Filename(), "kind:", protoContext.TriggerKind, "triggerCh:", protoContext.TriggerCharacter)
}
ctx, done := event.Start(ctx, "completion.GopCompletion")
defer done()

Expand Down Expand Up @@ -328,7 +330,9 @@ func GopCompletion(ctx context.Context, snapshot source.Snapshot, fh source.File
case *ast.Ident:
// reject defining identifiers
obj, ok := pkg.GopTypesInfo().Defs[n]
log.Println("GopCompletion ident:", n, "obj:", obj)
if goxls.DbgCompletion {
log.Println("GopCompletion ident:", n, "obj:", obj)
}
if ok {
if v, ok := obj.(*types.Var); ok && v.IsField() && v.Embedded() {
// An anonymous field is also a reference to a type.
Expand Down Expand Up @@ -421,12 +425,14 @@ func GopCompletion(ctx context.Context, snapshot source.Snapshot, fh source.File
defer cancel()

if surrounding := c.containingIdent(pgf.Src); surrounding != nil {
log.Println("GopCompletion surrounding:", surrounding)
if goxls.DbgCompletion {
log.Println("GopCompletion surrounding:", surrounding)
}
c.setSurrounding(surrounding)
}

c.inference = gopExpectedCandidate(ctx, c)
if true {
if goxls.DbgCompletion {
infer := c.inference
log.Printf(`GopCompletion infer:
objType: %v, convertibleTo: %v
Expand All @@ -441,31 +447,41 @@ func GopCompletion(ctx context.Context, snapshot source.Snapshot, fh source.File
if err != nil {
return nil, nil, err
}
log.Println("GopCompletion collect: len(items) =", len(c.items))
if goxls.DbgCompletion {
log.Println("GopCompletion collect: len(items) =", len(c.items))
}

// Deep search collected candidates and their members for more candidates.
c.deepSearch(ctx, start, deadline)
log.Println("GopCompletion deepSearch: len(items) =", len(c.items))
if goxls.DbgCompletion {
log.Println("GopCompletion deepSearch: len(items) =", len(c.items))
}

for _, callback := range c.completionCallbacks {
if err := c.snapshot.RunProcessEnvFunc(ctx, callback); err != nil {
return nil, nil, err
}
log.Println("GopCompletion callbak: len(items) =", len(c.items))
if goxls.DbgCompletion {
log.Println("GopCompletion callbak: len(items) =", len(c.items))
}
}

// Search candidates populated by expensive operations like
// unimportedMembers etc. for more completion items.
c.deepSearch(ctx, start, deadline)
log.Println("GopCompletion deepSearch(2): len(items) =", len(c.items))
if goxls.DbgCompletion {
log.Println("GopCompletion deepSearch(2): len(items) =", len(c.items))
}

// Statement candidates offer an entire statement in certain contexts, as
// opposed to a single object. Add statement candidates last because they
// depend on other candidates having already been collected.
c.addStatementCandidates()

c.sortItems()
log.Println("GopCompletion ret: len(items) =", len(c.items))
if goxls.DbgCompletion {
log.Println("GopCompletion ret: len(items) =", len(c.items))
}
return c.items, c.getSurrounding(), nil
}

Expand Down Expand Up @@ -1021,7 +1037,9 @@ func (c *gopCompleter) selector(ctx context.Context, sel *ast.SelectorExpr) erro

// True selector?
tv, ok := c.pkg.GopTypesInfo().Types[sel.X]
log.Println("gopCompleter.selector:", ok, "type:", tv.Type)
if goxls.DbgCompletion {
log.Println("gopCompleter.selector:", sel.X, ok, "type:", tv.Type)
}
if ok {
c.methodsAndFields(tv.Type, tv.Addressable(), nil, c.deepState.enqueue)
c.addPostfixSnippetCandidates(ctx, sel)
Expand Down
6 changes: 5 additions & 1 deletion gopls/internal/lsp/source/completion/deep_completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"log"
"strings"
"time"

"golang.org/x/tools/gopls/internal/goxls"
)

// MaxDeepCompletions limits deep completion results because in most cases
Expand Down Expand Up @@ -121,7 +123,9 @@ func (c *completer) deepSearch(ctx context.Context, start time.Time, deadline *t
c.deepState.thisQueue = c.deepState.thisQueue[:0]
c.deepState.nextQueue = c.deepState.nextQueue[:0]
}()
log.Println("completer.deepSearch: n =", len(c.deepState.nextQueue))
if goxls.DbgCompletion {
log.Println("completer.deepSearch: n =", len(c.deepState.nextQueue))
}

first := true // always fully process the first set of candidates
for len(c.deepState.nextQueue) > 0 && (first || deadline == nil || time.Now().Before(*deadline)) {
Expand Down
6 changes: 5 additions & 1 deletion gopls/internal/lsp/source/completion/deep_completion_gox.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"go/types"
"log"
"time"

"golang.org/x/tools/gopls/internal/goxls"
)

// deepSearch searches a candidate and its subordinate objects for completion
Expand All @@ -21,7 +23,9 @@ func (c *gopCompleter) deepSearch(ctx context.Context, start time.Time, deadline
c.deepState.thisQueue = c.deepState.thisQueue[:0]
c.deepState.nextQueue = c.deepState.nextQueue[:0]
}()
log.Println("gopCompleter.deepSearch: n =", len(c.deepState.nextQueue))
if goxls.DbgCompletion {
log.Println("gopCompleter.deepSearch: n =", len(c.deepState.nextQueue))
}

first := true // always fully process the first set of candidates
for len(c.deepState.nextQueue) > 0 && (first || deadline == nil || time.Now().Before(*deadline)) {
Expand Down

0 comments on commit e9661e6

Please sign in to comment.