Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201028153306-37f0764111ff / godoc / snippet.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201028153306-37f0764111ff/godoc/snippet.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201028153306-37f0764111ff/godoc/snippet.go
new file mode 100644 (file)
index 0000000..1750478
--- /dev/null
@@ -0,0 +1,123 @@
+// Copyright 2009 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.
+
+// This file contains the infrastructure to create a code
+// snippet for search results.
+//
+// Note: At the moment, this only creates HTML snippets.
+
+package godoc
+
+import (
+       "bytes"
+       "fmt"
+       "go/ast"
+       "go/token"
+)
+
+type Snippet struct {
+       Line int
+       Text string // HTML-escaped
+}
+
+func (p *Presentation) newSnippet(fset *token.FileSet, decl ast.Decl, id *ast.Ident) *Snippet {
+       // TODO instead of pretty-printing the node, should use the original source instead
+       var buf1 bytes.Buffer
+       p.writeNode(&buf1, nil, fset, decl)
+       // wrap text with <pre> tag
+       var buf2 bytes.Buffer
+       buf2.WriteString("<pre>")
+       FormatText(&buf2, buf1.Bytes(), -1, true, id.Name, nil)
+       buf2.WriteString("</pre>")
+       return &Snippet{fset.Position(id.Pos()).Line, buf2.String()}
+}
+
+func findSpec(list []ast.Spec, id *ast.Ident) ast.Spec {
+       for _, spec := range list {
+               switch s := spec.(type) {
+               case *ast.ImportSpec:
+                       if s.Name == id {
+                               return s
+                       }
+               case *ast.ValueSpec:
+                       for _, n := range s.Names {
+                               if n == id {
+                                       return s
+                               }
+                       }
+               case *ast.TypeSpec:
+                       if s.Name == id {
+                               return s
+                       }
+               }
+       }
+       return nil
+}
+
+func (p *Presentation) genSnippet(fset *token.FileSet, d *ast.GenDecl, id *ast.Ident) *Snippet {
+       s := findSpec(d.Specs, id)
+       if s == nil {
+               return nil //  declaration doesn't contain id - exit gracefully
+       }
+
+       // only use the spec containing the id for the snippet
+       dd := &ast.GenDecl{
+               Doc:    d.Doc,
+               TokPos: d.Pos(),
+               Tok:    d.Tok,
+               Lparen: d.Lparen,
+               Specs:  []ast.Spec{s},
+               Rparen: d.Rparen,
+       }
+
+       return p.newSnippet(fset, dd, id)
+}
+
+func (p *Presentation) funcSnippet(fset *token.FileSet, d *ast.FuncDecl, id *ast.Ident) *Snippet {
+       if d.Name != id {
+               return nil //  declaration doesn't contain id - exit gracefully
+       }
+
+       // only use the function signature for the snippet
+       dd := &ast.FuncDecl{
+               Doc:  d.Doc,
+               Recv: d.Recv,
+               Name: d.Name,
+               Type: d.Type,
+       }
+
+       return p.newSnippet(fset, dd, id)
+}
+
+// NewSnippet creates a text snippet from a declaration decl containing an
+// identifier id. Parts of the declaration not containing the identifier
+// may be removed for a more compact snippet.
+func NewSnippet(fset *token.FileSet, decl ast.Decl, id *ast.Ident) *Snippet {
+       // TODO(bradfitz, adg): remove this function.  But it's used by indexer, which
+       // doesn't have a *Presentation, and NewSnippet needs a TabWidth.
+       var p Presentation
+       p.TabWidth = 4
+       return p.NewSnippet(fset, decl, id)
+}
+
+// NewSnippet creates a text snippet from a declaration decl containing an
+// identifier id. Parts of the declaration not containing the identifier
+// may be removed for a more compact snippet.
+func (p *Presentation) NewSnippet(fset *token.FileSet, decl ast.Decl, id *ast.Ident) *Snippet {
+       var s *Snippet
+       switch d := decl.(type) {
+       case *ast.GenDecl:
+               s = p.genSnippet(fset, d, id)
+       case *ast.FuncDecl:
+               s = p.funcSnippet(fset, d, id)
+       }
+
+       // handle failure gracefully
+       if s == nil {
+               var buf bytes.Buffer
+               fmt.Fprintf(&buf, `<span class="alert">could not generate a snippet for <span class="highlight">%s</span></span>`, id.Name)
+               s = &Snippet{fset.Position(id.Pos()).Line, buf.String()}
+       }
+       return s
+}