some deletions
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201028153306-37f0764111ff / internal / lsp / semantic.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201028153306-37f0764111ff/internal/lsp/semantic.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201028153306-37f0764111ff/internal/lsp/semantic.go
deleted file mode 100644 (file)
index b0f42d6..0000000
+++ /dev/null
@@ -1,634 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package lsp
-
-import (
-       "bytes"
-       "context"
-       "fmt"
-       "go/ast"
-       "go/token"
-       "go/types"
-       "log"
-       "sort"
-       "strings"
-       "time"
-
-       "golang.org/x/tools/internal/event"
-       "golang.org/x/tools/internal/lsp/protocol"
-       "golang.org/x/tools/internal/lsp/source"
-       errors "golang.org/x/xerrors"
-)
-
-func (s *Server) semanticTokensFull(ctx context.Context, p *protocol.SemanticTokensParams) (*protocol.SemanticTokens, error) {
-       ret, err := s.computeSemanticTokens(ctx, p.TextDocument, nil)
-       return ret, err
-}
-
-func (s *Server) semanticTokensFullDelta(ctx context.Context, p *protocol.SemanticTokensDeltaParams) (interface{}, error) {
-       return nil, errors.Errorf("implement SemanticTokensFullDelta")
-}
-
-func (s *Server) semanticTokensRange(ctx context.Context, p *protocol.SemanticTokensRangeParams) (*protocol.SemanticTokens, error) {
-       ret, err := s.computeSemanticTokens(ctx, p.TextDocument, &p.Range)
-       return ret, err
-}
-
-func (s *Server) semanticTokensRefresh(ctx context.Context) error {
-       // in the code, but not in the protocol spec
-       return errors.Errorf("implement SemanticTokensRefresh")
-}
-
-func (s *Server) computeSemanticTokens(ctx context.Context, td protocol.TextDocumentIdentifier, rng *protocol.Range) (*protocol.SemanticTokens, error) {
-       ans := protocol.SemanticTokens{
-               Data: []float64{},
-       }
-       snapshot, _, ok, release, err := s.beginFileRequest(ctx, td.URI, source.Go)
-       defer release()
-       if !ok {
-               return nil, err
-       }
-       vv := snapshot.View()
-       if !vv.Options().SemanticTokens {
-               // return an error, so if the option changes
-               // the client won't remember the wrong answer
-               return nil, errors.Errorf("semantictokens are disabled")
-       }
-       pkg, err := snapshot.PackageForFile(ctx, td.URI.SpanURI(), source.TypecheckFull, source.WidestPackage)
-       if err != nil {
-               return nil, err
-       }
-       info := pkg.GetTypesInfo()
-       pgf, err := pkg.File(td.URI.SpanURI())
-       if err != nil {
-               return nil, err
-       }
-       if pgf.ParseErr != nil {
-               return nil, pgf.ParseErr
-       }
-       e := &encoded{
-               ctx:  ctx,
-               pgf:  pgf,
-               rng:  rng,
-               ti:   info,
-               fset: snapshot.FileSet(),
-       }
-       if err := e.init(); err != nil {
-               return nil, err
-       }
-       e.semantics()
-       ans.Data, err = e.Data()
-       if err != nil {
-               // this is an internal error, likely caused by a typo
-               // for a token or modifier
-               return nil, err
-       }
-       // for small cache, some day. for now, the client ignores this
-       ans.ResultID = fmt.Sprintf("%v", time.Now())
-       return &ans, nil
-}
-
-func (e *encoded) semantics() {
-       f := e.pgf.File
-       e.token(f.Package, len("package"), tokKeyword, nil)
-       e.token(f.Name.NamePos, len(f.Name.Name), tokNamespace, nil)
-       inspect := func(n ast.Node) bool {
-               return e.inspector(n)
-       }
-       for _, d := range f.Decls {
-               // only look at the decls that overlap the range
-               start, end := d.Pos(), d.End()
-               if end <= e.start || start >= e.end {
-                       continue
-               }
-               ast.Inspect(d, inspect)
-       }
-}
-
-type tokenType string
-
-const (
-       tokNamespace tokenType = "namespace"
-       tokType      tokenType = "type"
-       tokInterface tokenType = "interface"
-       tokParameter tokenType = "parameter"
-       tokVariable  tokenType = "variable"
-       tokMember    tokenType = "member"
-       tokFunction  tokenType = "function"
-       tokKeyword   tokenType = "keyword"
-       tokComment   tokenType = "comment"
-       tokString    tokenType = "string"
-       tokNumber    tokenType = "number"
-       tokOperator  tokenType = "operator"
-)
-
-var lastPosition token.Position
-
-func (e *encoded) token(start token.Pos, leng int, typ tokenType, mods []string) {
-       if start == 0 {
-               e.unexpected("token at token.NoPos")
-       }
-       if start >= e.end || start+token.Pos(leng) <= e.start {
-               return
-       }
-       // want a line and column from start (in LSP coordinates)
-       // [//line directives should be ignored]
-       rng := source.NewMappedRange(e.fset, e.pgf.Mapper, start, start+token.Pos(leng))
-       lspRange, err := rng.Range()
-       if err != nil {
-               // possibly a //line directive. TODO(pjw): fix this somehow
-               // "column mapper is for file...instead of..."
-               // "line is beyond end of file..."
-               // see line 116 of internal/span/token.go which uses Position not PositionFor
-               event.Error(e.ctx, "failed to convert to range", err)
-               return
-       }
-       if lspRange.End.Line != lspRange.Start.Line {
-               // abrupt end of file, without \n. TODO(pjw): fix?
-               pos := e.fset.PositionFor(start, false)
-               msg := fmt.Sprintf("token at %s:%d.%d overflows", pos.Filename, pos.Line, pos.Column)
-               event.Log(e.ctx, msg)
-               return
-       }
-       // token is all on one line
-       length := lspRange.End.Character - lspRange.Start.Character
-       e.add(lspRange.Start.Line, lspRange.Start.Character, length, typ, mods)
-}
-
-func (e *encoded) add(line, start float64, len float64, tok tokenType, mod []string) {
-       x := semItem{line, start, len, tok, mod}
-       e.items = append(e.items, x)
-}
-
-// semItem represents a token found walking the parse tree
-type semItem struct {
-       line, start float64
-       len         float64
-       typeStr     tokenType
-       mods        []string
-}
-
-type encoded struct {
-       // the generated data
-       items []semItem
-
-       ctx  context.Context
-       pgf  *source.ParsedGoFile
-       rng  *protocol.Range
-       ti   *types.Info
-       fset *token.FileSet
-       // allowed starting and ending token.Pos, set by init
-       // used to avoid looking at declarations not in range
-       start, end token.Pos
-       // path from the root of the parse tree, used for debugging
-       stack []ast.Node
-}
-
-// convert the stack to a string, for debugging
-func (e *encoded) strStack() string {
-       msg := []string{"["}
-       for _, s := range e.stack {
-               msg = append(msg, fmt.Sprintf("%T", s)[5:])
-       }
-       if len(e.stack) > 0 {
-               loc := e.stack[len(e.stack)-1].Pos()
-               add := e.pgf.Tok.PositionFor(loc, false)
-               msg = append(msg, fmt.Sprintf("(%d:%d)", add.Line, add.Column))
-       }
-       msg = append(msg, "]")
-       return strings.Join(msg, " ")
-}
-
-func (e *encoded) inspector(n ast.Node) bool {
-       pop := func() {
-               e.stack = e.stack[:len(e.stack)-1]
-       }
-       if n == nil {
-               pop()
-               return true
-       }
-       e.stack = append(e.stack, n)
-       switch x := n.(type) {
-       case *ast.ArrayType:
-       case *ast.AssignStmt:
-               e.token(x.TokPos, len(x.Tok.String()), tokOperator, nil)
-       case *ast.BasicLit:
-               // if it extends across a line, skip it
-               // better would be to mark each line as string TODO(pjw)
-               if strings.Contains(x.Value, "\n") {
-                       break
-               }
-               ln := len(x.Value)
-               what := tokNumber
-               if x.Kind == token.STRING {
-                       what = tokString
-                       if _, ok := e.stack[len(e.stack)-2].(*ast.Field); ok {
-                               // struct tags (this is probably pointless, as the
-                               // TextMate grammar will treat all the other comments the same)
-                               what = tokComment
-                       }
-               }
-               e.token(x.Pos(), ln, what, nil)
-       case *ast.BinaryExpr:
-               e.token(x.OpPos, len(x.Op.String()), tokOperator, nil)
-       case *ast.BlockStmt:
-       case *ast.BranchStmt:
-               e.token(x.TokPos, len(x.Tok.String()), tokKeyword, nil)
-               // There's no semantic encoding for labels
-       case *ast.CallExpr:
-               if x.Ellipsis != token.NoPos {
-                       e.token(x.Ellipsis, len("..."), tokOperator, nil)
-               }
-       case *ast.CaseClause:
-               iam := "case"
-               if x.List == nil {
-                       iam = "default"
-               }
-               e.token(x.Case, len(iam), tokKeyword, nil)
-       case *ast.ChanType:
-               // chan | chan <- | <- chan
-               if x.Arrow == token.NoPos || x.Arrow != x.Begin {
-                       e.token(x.Begin, len("chan"), tokKeyword, nil)
-                       break
-               }
-               pos := e.findKeyword("chan", x.Begin+2, x.Value.Pos())
-               e.token(pos, len("chan"), tokKeyword, nil)
-       case *ast.CommClause:
-               iam := len("case")
-               if x.Comm == nil {
-                       iam = len("default")
-               }
-               e.token(x.Case, iam, tokKeyword, nil)
-       case *ast.CompositeLit:
-       case *ast.DeclStmt:
-       case *ast.DeferStmt:
-               e.token(x.Defer, len("defer"), tokKeyword, nil)
-       case *ast.Ellipsis:
-               e.token(x.Ellipsis, len("..."), tokOperator, nil)
-       case *ast.EmptyStmt:
-       case *ast.ExprStmt:
-       case *ast.Field:
-       case *ast.FieldList:
-       case *ast.ForStmt:
-               e.token(x.For, len("for"), tokKeyword, nil)
-       case *ast.FuncDecl:
-       case *ast.FuncLit:
-       case *ast.FuncType:
-               if x.Func != token.NoPos {
-                       e.token(x.Func, len("func"), tokKeyword, nil)
-               }
-       case *ast.GenDecl:
-               e.token(x.TokPos, len(x.Tok.String()), tokKeyword, nil)
-       case *ast.GoStmt:
-               e.token(x.Go, len("go"), tokKeyword, nil)
-       case *ast.Ident:
-               e.ident(x)
-       case *ast.IfStmt:
-               e.token(x.If, len("if"), tokKeyword, nil)
-               if x.Else != nil {
-                       // x.Body.End() or x.Body.End()+1, not that it matters
-                       pos := e.findKeyword("else", x.Body.End(), x.Else.Pos())
-                       e.token(pos, len("else"), tokKeyword, nil)
-               }
-       case *ast.ImportSpec:
-               e.importSpec(x)
-               pop()
-               return false
-       case *ast.IncDecStmt:
-               e.token(x.TokPos, len(x.Tok.String()), tokOperator, nil)
-       case *ast.IndexExpr:
-       case *ast.InterfaceType:
-               e.token(x.Interface, len("interface"), tokKeyword, nil)
-       case *ast.KeyValueExpr:
-       case *ast.LabeledStmt:
-       case *ast.MapType:
-               e.token(x.Map, len("map"), tokKeyword, nil)
-       case *ast.ParenExpr:
-       case *ast.RangeStmt:
-               e.token(x.For, len("for"), tokKeyword, nil)
-               // x.TokPos == token.NoPos is legal (for range foo {})
-               offset := x.TokPos
-               if offset == token.NoPos {
-                       offset = x.For
-               }
-               pos := e.findKeyword("range", offset, x.X.Pos())
-               e.token(pos, len("range"), tokKeyword, nil)
-       case *ast.ReturnStmt:
-               e.token(x.Return, len("return"), tokKeyword, nil)
-       case *ast.SelectStmt:
-               e.token(x.Select, len("select"), tokKeyword, nil)
-       case *ast.SelectorExpr:
-       case *ast.SendStmt:
-               e.token(x.Arrow, len("<-"), tokOperator, nil)
-       case *ast.SliceExpr:
-       case *ast.StarExpr:
-               e.token(x.Star, len("*"), tokOperator, nil)
-       case *ast.StructType:
-               e.token(x.Struct, len("struct"), tokKeyword, nil)
-       case *ast.SwitchStmt:
-               e.token(x.Switch, len("switch"), tokKeyword, nil)
-       case *ast.TypeAssertExpr:
-               if x.Type == nil {
-                       pos := e.findKeyword("type", x.Lparen, x.Rparen)
-                       e.token(pos, len("type"), tokKeyword, nil)
-               }
-       case *ast.TypeSpec:
-       case *ast.TypeSwitchStmt:
-               e.token(x.Switch, len("switch"), tokKeyword, nil)
-       case *ast.UnaryExpr:
-               e.token(x.OpPos, len(x.Op.String()), tokOperator, nil)
-       case *ast.ValueSpec:
-       // things we won't see
-       case *ast.BadDecl, *ast.BadExpr, *ast.BadStmt,
-               *ast.File, *ast.Package:
-               log.Printf("implement %T %s", x, e.pgf.Tok.PositionFor(x.Pos(), false))
-       // things we knowingly ignore
-       case *ast.Comment, *ast.CommentGroup:
-               pop()
-               return false
-       default: // just to be super safe.
-               e.unexpected(fmt.Sprintf("failed to implement %T", x))
-       }
-       return true
-}
-func (e *encoded) ident(x *ast.Ident) {
-       def := e.ti.Defs[x]
-       if def != nil {
-               what, mods := e.definitionFor(x)
-               if what != "" {
-                       e.token(x.Pos(), len(x.String()), what, mods)
-               }
-               return
-       }
-       use := e.ti.Uses[x]
-       switch y := use.(type) {
-       case nil:
-               e.token(x.NamePos, len(x.Name), tokVariable, []string{"definition"})
-       case *types.Builtin:
-               e.token(x.NamePos, len(x.Name), tokFunction, []string{"defaultLibrary"})
-       case *types.Const:
-               mods := []string{"readonly"}
-               tt := y.Type()
-               if ttx, ok := tt.(*types.Basic); ok {
-                       switch bi := ttx.Info(); {
-                       case bi&types.IsNumeric != 0:
-                               me := tokVariable
-                               if x.String() == "iota" {
-                                       me = tokKeyword
-                                       mods = []string{}
-                               }
-                               e.token(x.Pos(), len(x.String()), me, mods)
-                       case bi&types.IsString != 0:
-                               e.token(x.Pos(), len(x.String()), tokString, mods)
-                       case bi&types.IsBoolean != 0:
-                               e.token(x.Pos(), len(x.Name), tokKeyword, nil)
-                       case bi == 0:
-                               e.token(x.Pos(), len(x.String()), tokVariable, mods)
-                       default:
-                               msg := fmt.Sprintf("unexpected %x at %s", bi, e.pgf.Tok.PositionFor(x.Pos(), false))
-                               e.unexpected(msg)
-                       }
-                       break
-               }
-               if ttx, ok := tt.(*types.Named); ok {
-                       if x.String() == "iota" {
-                               e.unexpected(fmt.Sprintf("iota:%T", ttx))
-                       }
-                       if _, ok := ttx.Underlying().(*types.Basic); ok {
-                               e.token(x.Pos(), len(x.String()), tokVariable, mods)
-                               break
-                       }
-                       e.unexpected(fmt.Sprintf("%q/%T", x.String(), tt))
-               }
-               // can this happen? Don't think so
-               e.unexpected(fmt.Sprintf("%s %T %#v", x.String(), tt, tt))
-       case *types.Func:
-               e.token(x.Pos(), len(x.Name), tokFunction, nil)
-       case *types.Label:
-               // nothing to map it to
-       case *types.Nil:
-               // nil is a predeclared identifier
-               e.token(x.Pos(), len("nil"), tokKeyword, []string{"readonly"})
-       case *types.PkgName:
-               e.token(x.Pos(), len(x.Name), tokNamespace, nil)
-       case *types.TypeName:
-               e.token(x.Pos(), len(x.String()), tokType, nil)
-       case *types.Var:
-               e.token(x.Pos(), len(x.Name), tokVariable, nil)
-       default:
-               // replace with panic after extensive testing
-               if use == nil {
-                       msg := fmt.Sprintf("%#v/%#v %#v %#v", x, x.Obj, e.ti.Defs[x], e.ti.Uses[x])
-                       e.unexpected(msg)
-               }
-               if use.Type() != nil {
-                       e.unexpected(fmt.Sprintf("%s %T/%T,%#v", x.String(), use, use.Type(), use))
-               } else {
-                       e.unexpected(fmt.Sprintf("%s %T", x.String(), use))
-               }
-       }
-}
-
-func (e *encoded) definitionFor(x *ast.Ident) (tokenType, []string) {
-       mods := []string{"definition"}
-       for i := len(e.stack) - 1; i >= 0; i-- {
-               s := e.stack[i]
-               switch y := s.(type) {
-               case *ast.AssignStmt, *ast.RangeStmt:
-                       if x.Name == "_" {
-                               return "", nil // not really a variable
-                       }
-                       return "variable", mods
-               case *ast.GenDecl:
-                       if y.Tok == token.CONST {
-                               mods = append(mods, "readonly")
-                       }
-                       return tokVariable, mods
-               case *ast.FuncDecl:
-                       // If x is immediately under a FuncDecl, it is a function or method
-                       if i == len(e.stack)-2 {
-                               if y.Recv != nil {
-                                       return tokMember, mods
-                               }
-                               return tokFunction, mods
-                       }
-                       // if x < ... < FieldList < FuncDecl, this is the receiver, a variable
-                       if _, ok := e.stack[i+1].(*ast.FieldList); ok {
-                               return tokVariable, nil
-                       }
-                       // if x < ... < FieldList < FuncType < FuncDecl, this is a param
-                       return tokParameter, mods
-               case *ast.InterfaceType:
-                       return tokMember, mods
-               case *ast.TypeSpec:
-                       return tokType, mods
-               }
-       }
-       // panic after extensive testing
-       msg := fmt.Sprintf("failed to find the decl for %s", e.pgf.Tok.PositionFor(x.Pos(), false))
-       e.unexpected(msg)
-       return "", []string{""}
-}
-
-// findKeyword finds a keyword rather than guessing its location
-func (e *encoded) findKeyword(keyword string, start, end token.Pos) token.Pos {
-       offset := int(start) - e.pgf.Tok.Base()
-       last := int(end) - e.pgf.Tok.Base()
-       buf := e.pgf.Src
-       idx := bytes.Index(buf[offset:last], []byte(keyword))
-       if idx != -1 {
-               return start + token.Pos(idx)
-       }
-       // can't happen
-       e.unexpected(fmt.Sprintf("not found:%s %v", keyword, e.fset.PositionFor(start, false)))
-       return token.NoPos
-}
-
-func (e *encoded) init() error {
-       e.start = token.Pos(e.pgf.Tok.Base())
-       e.end = e.start + token.Pos(e.pgf.Tok.Size())
-       if e.rng == nil {
-               return nil
-       }
-       span, err := e.pgf.Mapper.RangeSpan(*e.rng)
-       if err != nil {
-               return errors.Errorf("range span error for %s", e.pgf.File.Name)
-       }
-       e.end = e.start + token.Pos(span.End().Offset())
-       e.start += token.Pos(span.Start().Offset())
-       return nil
-}
-
-func (e *encoded) Data() ([]float64, error) {
-       // binary operators, at least, will be out of order
-       sort.Slice(e.items, func(i, j int) bool {
-               if e.items[i].line != e.items[j].line {
-                       return e.items[i].line < e.items[j].line
-               }
-               return e.items[i].start < e.items[j].start
-       })
-       // each semantic token needs five values
-       // (see Integer Encoding for Tokens in the LSP spec)
-       x := make([]float64, 5*len(e.items))
-       for i := 0; i < len(e.items); i++ {
-               j := 5 * i
-               if i == 0 {
-                       x[0] = e.items[0].line
-               } else {
-                       x[j] = e.items[i].line - e.items[i-1].line
-               }
-               x[j+1] = e.items[i].start
-               if i > 0 && e.items[i].line == e.items[i-1].line {
-                       x[j+1] = e.items[i].start - e.items[i-1].start
-               }
-               x[j+2] = e.items[i].len
-               x[j+3] = float64(SemanticMemo.TypeMap[e.items[i].typeStr])
-               mask := 0
-               for _, s := range e.items[i].mods {
-                       mask |= SemanticMemo.ModMap[s]
-               }
-               x[j+4] = float64(mask)
-       }
-       return x, nil
-}
-
-func (e *encoded) importSpec(d *ast.ImportSpec) {
-       // a local package name or the last component of the Path
-       if d.Name != nil {
-               nm := d.Name.String()
-               // import . x => x is not a namespace
-               // import _ x => x is a namespace
-               if nm != "_" && nm != "." {
-                       e.token(d.Name.Pos(), len(nm), tokNamespace, nil)
-                       return
-               }
-               if nm == "." {
-                       return
-               }
-               // and fall through for _
-       }
-       nm := d.Path.Value[1 : len(d.Path.Value)-1] // trailing "
-       v := strings.LastIndex(nm, "/")
-       if v != -1 {
-               nm = nm[v+1:]
-       }
-       start := d.Path.End() - token.Pos(1+len(nm))
-       e.token(start, len(nm), tokNamespace, nil)
-}
-
-// panic on unexpected state
-func (e *encoded) unexpected(msg string) {
-       log.Print(msg)
-       log.Print(e.strStack())
-       panic(msg)
-}
-
-// SemMemo supports semantic token translations between numbers and strings
-type SemMemo struct {
-       tokTypes, tokMods []string
-       // these exported fields are used in the 'gopls semtok' command
-       TypeMap map[tokenType]int
-       ModMap  map[string]int
-}
-
-var SemanticMemo *SemMemo
-
-// Type returns a string equivalent of the type, for gopls semtok
-func (m *SemMemo) Type(n int) string {
-       if n >= 0 && n < len(m.tokTypes) {
-               return m.tokTypes[n]
-       }
-       return fmt.Sprintf("?%d[%d,%d]?", n, len(m.tokTypes), len(m.tokMods))
-}
-
-// Mods returns the []string equivalent of the mods, for gopls semtok.
-func (m *SemMemo) Mods(n int) []string {
-       mods := []string{}
-       for i := 0; i < len(m.tokMods); i++ {
-               if (n & (1 << uint(i))) != 0 {
-                       mods = append(mods, m.tokMods[i])
-               }
-       }
-       return mods
-}
-
-// save what the client sent
-func rememberToks(toks []string, mods []string) {
-       SemanticMemo = &SemMemo{
-               tokTypes: toks,
-               tokMods:  mods,
-               TypeMap:  make(map[tokenType]int),
-               ModMap:   make(map[string]int),
-       }
-       for i, t := range toks {
-               SemanticMemo.TypeMap[tokenType(t)] = i
-       }
-       for i, m := range mods {
-               SemanticMemo.ModMap[m] = 1 << uint(i)
-       }
-       // we could have pruned or rearranged them.
-       // But then change the list in cmd.go too
-}
-
-// SemanticTypes to use in case there is no client, as in the command line, or tests
-func SemanticTypes() []string {
-       return semanticTypes[:]
-}
-
-// SemanticModifiers to use in case there is no client.
-func SemanticModifiers() []string {
-       return semanticModifiers[:]
-}
-
-var (
-       semanticTypes = [...]string{
-               "namespace", "type", "class", "enum", "interface",
-               "struct", "typeParameter", "parameter", "variable", "property", "enumMember",
-               "event", "function", "member", "macro", "keyword", "modifier", "comment",
-               "string", "number", "regexp", "operator"}
-       semanticModifiers = [...]string{
-               "declaration", "definition", "readonly", "static",
-               "deprecated", "abstract", "async", "modification", "documentation", "defaultLibrary"}
-)