.gitignore added
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.1.1-0.20210319172145-bda8f5cee399 / internal / lsp / source / fix.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.1.1-0.20210319172145-bda8f5cee399/internal/lsp/source/fix.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.1.1-0.20210319172145-bda8f5cee399/internal/lsp/source/fix.go
new file mode 100644 (file)
index 0000000..3918355
--- /dev/null
@@ -0,0 +1,112 @@
+// 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 source
+
+import (
+       "context"
+       "fmt"
+       "go/ast"
+       "go/token"
+       "go/types"
+
+       "golang.org/x/tools/go/analysis"
+       "golang.org/x/tools/internal/lsp/analysis/fillstruct"
+       "golang.org/x/tools/internal/lsp/analysis/undeclaredname"
+       "golang.org/x/tools/internal/lsp/protocol"
+       "golang.org/x/tools/internal/span"
+       errors "golang.org/x/xerrors"
+)
+
+// SuggestedFixFunc is a function used to get the suggested fixes for a given
+// gopls command, some of which are provided by go/analysis.Analyzers. Some of
+// the analyzers in internal/lsp/analysis are not efficient enough to include
+// suggested fixes with their diagnostics, so we have to compute them
+// separately. Such analyzers should provide a function with a signature of
+// SuggestedFixFunc.
+type SuggestedFixFunc func(fset *token.FileSet, rng span.Range, src []byte, file *ast.File, pkg *types.Package, info *types.Info) (*analysis.SuggestedFix, error)
+
+const (
+       FillStruct      = "fill_struct"
+       UndeclaredName  = "undeclared_name"
+       ExtractVariable = "extract_variable"
+       ExtractFunction = "extract_function"
+)
+
+// suggestedFixes maps a suggested fix command id to its handler.
+var suggestedFixes = map[string]SuggestedFixFunc{
+       FillStruct:      fillstruct.SuggestedFix,
+       UndeclaredName:  undeclaredname.SuggestedFix,
+       ExtractVariable: extractVariable,
+       ExtractFunction: extractFunction,
+}
+
+func SuggestedFixFromCommand(cmd protocol.Command) SuggestedFix {
+       return SuggestedFix{
+               Title:   cmd.Title,
+               Command: &cmd,
+       }
+}
+
+// ApplyFix applies the command's suggested fix to the given file and
+// range, returning the resulting edits.
+func ApplyFix(ctx context.Context, fix string, snapshot Snapshot, fh VersionedFileHandle, pRng protocol.Range) ([]protocol.TextDocumentEdit, error) {
+       handler, ok := suggestedFixes[fix]
+       if !ok {
+               return nil, fmt.Errorf("no suggested fix function for %s", fix)
+       }
+       fset, rng, src, file, m, pkg, info, err := getAllSuggestedFixInputs(ctx, snapshot, fh, pRng)
+       if err != nil {
+               return nil, err
+       }
+       suggestion, err := handler(fset, rng, src, file, pkg, info)
+       if err != nil {
+               return nil, err
+       }
+       if suggestion == nil {
+               return nil, nil
+       }
+
+       var edits []protocol.TextDocumentEdit
+       for _, edit := range suggestion.TextEdits {
+               rng := span.NewRange(fset, edit.Pos, edit.End)
+               spn, err := rng.Span()
+               if err != nil {
+                       return nil, err
+               }
+               clRng, err := m.Range(spn)
+               if err != nil {
+                       return nil, err
+               }
+               edits = append(edits, protocol.TextDocumentEdit{
+                       TextDocument: protocol.OptionalVersionedTextDocumentIdentifier{
+                               Version: fh.Version(),
+                               TextDocumentIdentifier: protocol.TextDocumentIdentifier{
+                                       URI: protocol.URIFromSpanURI(fh.URI()),
+                               },
+                       },
+                       Edits: []protocol.TextEdit{
+                               {
+                                       Range:   clRng,
+                                       NewText: string(edit.NewText),
+                               },
+                       },
+               })
+       }
+       return edits, nil
+}
+
+// getAllSuggestedFixInputs is a helper function to collect all possible needed
+// inputs for an AppliesFunc or SuggestedFixFunc.
+func getAllSuggestedFixInputs(ctx context.Context, snapshot Snapshot, fh FileHandle, pRng protocol.Range) (*token.FileSet, span.Range, []byte, *ast.File, *protocol.ColumnMapper, *types.Package, *types.Info, error) {
+       pkg, pgf, err := GetParsedFile(ctx, snapshot, fh, NarrowestPackage)
+       if err != nil {
+               return nil, span.Range{}, nil, nil, nil, nil, nil, errors.Errorf("getting file for Identifier: %w", err)
+       }
+       rng, err := pgf.Mapper.RangeToSpanRange(pRng)
+       if err != nil {
+               return nil, span.Range{}, nil, nil, nil, nil, nil, err
+       }
+       return snapshot.FileSet(), rng, pgf.Src, pgf.File, pgf.Mapper, pkg.GetTypes(), pkg.GetTypesInfo(), nil
+}