X-Git-Url: https://git.josue.xyz/?a=blobdiff_plain;f=.config%2Fcoc%2Fextensions%2Fcoc-go-data%2Ftools%2Fpkg%2Fmod%2Fgolang.org%2Fx%2Ftools%40v0.0.0-20201105173854-bc9fc8d8c4bc%2Finternal%2Flsp%2Fsource%2Fgenapijson%2Fgenerate.go;fp=.config%2Fcoc%2Fextensions%2Fcoc-go-data%2Ftools%2Fpkg%2Fmod%2Fgolang.org%2Fx%2Ftools%40v0.0.0-20201105173854-bc9fc8d8c4bc%2Finternal%2Flsp%2Fsource%2Fgenapijson%2Fgenerate.go;h=0000000000000000000000000000000000000000;hb=3ddadb3c98564791f0ac36cb39771d844a63dc91;hp=47a0af75f03990e77c5764d5bfac658dd02ea612;hpb=5f797af6612ed10887189b47a1efc2f915586e59;p=dotfiles%2F.git diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/internal/lsp/source/genapijson/generate.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/internal/lsp/source/genapijson/generate.go deleted file mode 100644 index 47a0af75..00000000 --- a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/internal/lsp/source/genapijson/generate.go +++ /dev/null @@ -1,340 +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. - -// Command genapijson generates JSON describing gopls' external-facing API, -// including user settings and commands. -package main - -import ( - "bytes" - "encoding/json" - "flag" - "fmt" - "go/ast" - "go/token" - "go/types" - "os" - "reflect" - "strings" - "time" - - "golang.org/x/tools/go/ast/astutil" - "golang.org/x/tools/go/packages" - "golang.org/x/tools/internal/lsp/mod" - "golang.org/x/tools/internal/lsp/source" -) - -var ( - output = flag.String("output", "", "output file") -) - -func main() { - flag.Parse() - if err := doMain(); err != nil { - fmt.Fprintf(os.Stderr, "Generation failed: %v\n", err) - os.Exit(1) - } -} - -func doMain() error { - out := os.Stdout - if *output != "" { - var err error - out, err = os.OpenFile(*output, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0777) - if err != nil { - return err - } - defer out.Close() - } - - content, err := generate() - if err != nil { - return err - } - if _, err := out.Write(content); err != nil { - return err - } - - return out.Close() -} - -func generate() ([]byte, error) { - pkgs, err := packages.Load( - &packages.Config{ - Mode: packages.NeedTypes | packages.NeedTypesInfo | packages.NeedSyntax | packages.NeedDeps, - }, - "golang.org/x/tools/internal/lsp/source", - ) - if err != nil { - return nil, err - } - pkg := pkgs[0] - - api := &source.APIJSON{ - Options: map[string][]*source.OptionJSON{}, - } - defaults := source.DefaultOptions() - for _, cat := range []reflect.Value{ - reflect.ValueOf(defaults.DebuggingOptions), - reflect.ValueOf(defaults.UserOptions), - reflect.ValueOf(defaults.ExperimentalOptions), - } { - opts, err := loadOptions(cat, pkg) - if err != nil { - return nil, err - } - catName := strings.TrimSuffix(cat.Type().Name(), "Options") - api.Options[catName] = opts - } - - api.Commands, err = loadCommands(pkg) - if err != nil { - return nil, err - } - api.Lenses = loadLenses(api.Commands) - - // Transform the internal command name to the external command name. - for _, c := range api.Commands { - c.Command = source.CommandPrefix + c.Command - } - - marshaled, err := json.Marshal(api) - if err != nil { - return nil, err - } - buf := bytes.NewBuffer(nil) - fmt.Fprintf(buf, "// Code generated by \"golang.org/x/tools/internal/lsp/source/genapijson\"; DO NOT EDIT.\n\npackage source\n\nconst GeneratedAPIJSON = %q\n", string(marshaled)) - return buf.Bytes(), nil -} - -func loadOptions(category reflect.Value, pkg *packages.Package) ([]*source.OptionJSON, error) { - // Find the type information and ast.File corresponding to the category. - optsType := pkg.Types.Scope().Lookup(category.Type().Name()) - if optsType == nil { - return nil, fmt.Errorf("could not find %v in scope %v", category.Type().Name(), pkg.Types.Scope()) - } - - file, err := fileForPos(pkg, optsType.Pos()) - if err != nil { - return nil, err - } - - enums, err := loadEnums(pkg) - if err != nil { - return nil, err - } - - var opts []*source.OptionJSON - optsStruct := optsType.Type().Underlying().(*types.Struct) - for i := 0; i < optsStruct.NumFields(); i++ { - // The types field gives us the type. - typesField := optsStruct.Field(i) - path, _ := astutil.PathEnclosingInterval(file, typesField.Pos(), typesField.Pos()) - if len(path) < 2 { - return nil, fmt.Errorf("could not find AST node for field %v", typesField) - } - // The AST field gives us the doc. - astField, ok := path[1].(*ast.Field) - if !ok { - return nil, fmt.Errorf("unexpected AST path %v", path) - } - - // The reflect field gives us the default value. - reflectField := category.FieldByName(typesField.Name()) - if !reflectField.IsValid() { - return nil, fmt.Errorf("could not find reflect field for %v", typesField.Name()) - } - - // Format the default value. VSCode exposes settings as JSON, so showing them as JSON is reasonable. - def := reflectField.Interface() - // Durations marshal as nanoseconds, but we want the stringy versions, e.g. "100ms". - if t, ok := def.(time.Duration); ok { - def = t.String() - } - defBytes, err := json.Marshal(def) - if err != nil { - return nil, err - } - - // Nil values format as "null" so print them as hardcoded empty values. - switch reflectField.Type().Kind() { - case reflect.Map: - if reflectField.IsNil() { - defBytes = []byte("{}") - } - case reflect.Slice: - if reflectField.IsNil() { - defBytes = []byte("[]") - } - } - - typ := typesField.Type().String() - if _, ok := enums[typesField.Type()]; ok { - typ = "enum" - } - - opts = append(opts, &source.OptionJSON{ - Name: lowerFirst(typesField.Name()), - Type: typ, - Doc: lowerFirst(astField.Doc.Text()), - Default: string(defBytes), - EnumValues: enums[typesField.Type()], - }) - } - return opts, nil -} - -func loadEnums(pkg *packages.Package) (map[types.Type][]source.EnumValue, error) { - enums := map[types.Type][]source.EnumValue{} - for _, name := range pkg.Types.Scope().Names() { - obj := pkg.Types.Scope().Lookup(name) - cnst, ok := obj.(*types.Const) - if !ok { - continue - } - f, err := fileForPos(pkg, cnst.Pos()) - if err != nil { - return nil, fmt.Errorf("finding file for %q: %v", cnst.Name(), err) - } - path, _ := astutil.PathEnclosingInterval(f, cnst.Pos(), cnst.Pos()) - spec := path[1].(*ast.ValueSpec) - value := cnst.Val().ExactString() - doc := valueDoc(cnst.Name(), value, spec.Doc.Text()) - v := source.EnumValue{ - Value: value, - Doc: doc, - } - enums[obj.Type()] = append(enums[obj.Type()], v) - } - return enums, nil -} - -// valueDoc transforms a docstring documenting an constant identifier to a -// docstring documenting its value. -// -// If doc is of the form "Foo is a bar", it returns '`"fooValue"` is a bar'. If -// doc is non-standard ("this value is a bar"), it returns '`"fooValue"`: this -// value is a bar'. -func valueDoc(name, value, doc string) string { - if doc == "" { - return "" - } - if strings.HasPrefix(doc, name) { - // docstring in standard form. Replace the subject with value. - return fmt.Sprintf("`%s`%s", value, doc[len(name):]) - } - return fmt.Sprintf("`%s`: %s", value, doc) -} - -func loadCommands(pkg *packages.Package) ([]*source.CommandJSON, error) { - // The code that defines commands is much more complicated than the - // code that defines options, so reading comments for the Doc is very - // fragile. If this causes problems, we should switch to a dynamic - // approach and put the doc in the Commands struct rather than reading - // from the source code. - - // Find the Commands slice. - typesSlice := pkg.Types.Scope().Lookup("Commands") - f, err := fileForPos(pkg, typesSlice.Pos()) - if err != nil { - return nil, err - } - path, _ := astutil.PathEnclosingInterval(f, typesSlice.Pos(), typesSlice.Pos()) - vspec := path[1].(*ast.ValueSpec) - var astSlice *ast.CompositeLit - for i, name := range vspec.Names { - if name.Name == "Commands" { - astSlice = vspec.Values[i].(*ast.CompositeLit) - } - } - - var commands []*source.CommandJSON - - // Parse the objects it contains. - for _, elt := range astSlice.Elts { - // Find the composite literal of the Command. - typesCommand := pkg.TypesInfo.ObjectOf(elt.(*ast.Ident)) - path, _ := astutil.PathEnclosingInterval(f, typesCommand.Pos(), typesCommand.Pos()) - vspec := path[1].(*ast.ValueSpec) - - var astCommand ast.Expr - for i, name := range vspec.Names { - if name.Name == typesCommand.Name() { - astCommand = vspec.Values[i] - } - } - - // Read the Name and Title fields of the literal. - var name, title string - ast.Inspect(astCommand, func(n ast.Node) bool { - kv, ok := n.(*ast.KeyValueExpr) - if ok { - k := kv.Key.(*ast.Ident).Name - switch k { - case "Name": - name = strings.Trim(kv.Value.(*ast.BasicLit).Value, `"`) - case "Title": - title = strings.Trim(kv.Value.(*ast.BasicLit).Value, `"`) - } - } - return true - }) - - if title == "" { - title = name - } - - // Conventionally, the doc starts with the name of the variable. - // Replace it with the name of the command. - doc := vspec.Doc.Text() - doc = strings.Replace(doc, typesCommand.Name(), name, 1) - - commands = append(commands, &source.CommandJSON{ - Command: name, - Title: title, - Doc: doc, - }) - } - return commands, nil -} - -func loadLenses(commands []*source.CommandJSON) []*source.LensJSON { - lensNames := map[string]struct{}{} - for k := range source.LensFuncs() { - lensNames[k] = struct{}{} - } - for k := range mod.LensFuncs() { - lensNames[k] = struct{}{} - } - - var lenses []*source.LensJSON - - for _, cmd := range commands { - if _, ok := lensNames[cmd.Command]; ok { - lenses = append(lenses, &source.LensJSON{ - Lens: cmd.Command, - Title: cmd.Title, - Doc: cmd.Doc, - }) - } - } - return lenses -} - -func lowerFirst(x string) string { - if x == "" { - return x - } - return strings.ToLower(x[:1]) + x[1:] -} - -func fileForPos(pkg *packages.Package, pos token.Pos) (*ast.File, error) { - fset := pkg.Fset - for _, f := range pkg.Syntax { - if fset.Position(f.Pos()).Filename == fset.Position(pos).Filename { - return f, nil - } - } - return nil, fmt.Errorf("no file for pos %v", pos) -}