aboutsummaryrefslogtreecommitdiff
path: root/gopls/internal/lsp/protocol/generate/generate.go
diff options
context:
space:
mode:
Diffstat (limited to 'gopls/internal/lsp/protocol/generate/generate.go')
-rw-r--r--gopls/internal/lsp/protocol/generate/generate.go121
1 files changed, 121 insertions, 0 deletions
diff --git a/gopls/internal/lsp/protocol/generate/generate.go b/gopls/internal/lsp/protocol/generate/generate.go
new file mode 100644
index 000000000..0496b7d06
--- /dev/null
+++ b/gopls/internal/lsp/protocol/generate/generate.go
@@ -0,0 +1,121 @@
+// Copyright 2022 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.
+
+//go:build go1.19
+// +build go1.19
+
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "log"
+ "strings"
+)
+
+// a newType is a type that needs a name and a definition
+// These are the various types that the json specification doesn't name
+type newType struct {
+ name string
+ properties Properties // for struct/literal types
+ items []*Type // for other types ("and", "tuple")
+ line int
+ kind string // Or, And, Tuple, Lit, Map
+ typ *Type
+}
+
+func generateDoc(out *bytes.Buffer, doc string) {
+ if doc == "" {
+ return
+ }
+
+ if !strings.Contains(doc, "\n") {
+ fmt.Fprintf(out, "// %s\n", doc)
+ return
+ }
+ var list bool
+ for _, line := range strings.Split(doc, "\n") {
+ // Lists in metaModel.json start with a dash.
+ // To make a go doc list they have to be preceded
+ // by a blank line, and indented.
+ // (see type TextDccumentFilter in protocol.go)
+ if len(line) > 0 && line[0] == '-' {
+ if !list {
+ list = true
+ fmt.Fprintf(out, "//\n")
+ }
+ fmt.Fprintf(out, "// %s\n", line)
+ } else {
+ if len(line) == 0 {
+ list = false
+ }
+ fmt.Fprintf(out, "// %s\n", line)
+ }
+ }
+}
+
+// decide if a property is optional, and if it needs a *
+// return ",omitempty" if it is optional, and "*" if it needs a pointer
+func propStar(name string, t NameType, gotype string) (string, string) {
+ var opt, star string
+ if t.Optional {
+ star = "*"
+ opt = ",omitempty"
+ }
+ if strings.HasPrefix(gotype, "[]") || strings.HasPrefix(gotype, "map[") {
+ star = "" // passed by reference, so no need for *
+ } else {
+ switch gotype {
+ case "bool", "uint32", "int32", "string", "interface{}":
+ star = "" // gopls compatibility if t.Optional
+ }
+ }
+ ostar, oopt := star, opt
+ if newStar, ok := goplsStar[prop{name, t.Name}]; ok {
+ switch newStar {
+ case nothing:
+ star, opt = "", ""
+ case wantStar:
+ star, opt = "*", ""
+ case wantOpt:
+ star, opt = "", ",omitempty"
+ case wantOptStar:
+ star, opt = "*", ",omitempty"
+ }
+ if star == ostar && opt == oopt { // no change
+ log.Printf("goplsStar[ {%q, %q} ](%d) useless %s/%s %s/%s", name, t.Name, t.Line, ostar, star, oopt, opt)
+ }
+ usedGoplsStar[prop{name, t.Name}] = true
+ }
+
+ return opt, star
+}
+
+func goName(s string) string {
+ // Go naming conventions
+ if strings.HasSuffix(s, "Id") {
+ s = s[:len(s)-len("Id")] + "ID"
+ } else if strings.HasSuffix(s, "Uri") {
+ s = s[:len(s)-3] + "URI"
+ } else if s == "uri" {
+ s = "URI"
+ } else if s == "id" {
+ s = "ID"
+ }
+
+ // renames for temporary GOPLS compatibility
+ if news := goplsType[s]; news != "" {
+ usedGoplsType[s] = true
+ s = news
+ }
+ // Names beginning _ are not exported
+ if strings.HasPrefix(s, "_") {
+ s = strings.Replace(s, "_", "X", 1)
+ }
+ if s != "string" { // base types are unchanged (textDocuemnt/diagnostic)
+ // Title is deprecated, but a) s is only one word, b) replacement is too heavy-weight
+ s = strings.Title(s)
+ }
+ return s
+}