golang.org/x/tools/gopls@v0.15.3/internal/protocol/generate/generate.go (about)

     1  // Copyright 2022 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build go1.19
     6  // +build go1.19
     7  
     8  package main
     9  
    10  import (
    11  	"bytes"
    12  	"fmt"
    13  	"log"
    14  	"strings"
    15  )
    16  
    17  // a newType is a type that needs a name and a definition
    18  // These are the various types that the json specification doesn't name
    19  type newType struct {
    20  	name       string
    21  	properties Properties // for struct/literal types
    22  	items      []*Type    // for other types ("and", "tuple")
    23  	line       int
    24  	kind       string // Or, And, Tuple, Lit, Map
    25  	typ        *Type
    26  }
    27  
    28  func generateDoc(out *bytes.Buffer, doc string) {
    29  	if doc == "" {
    30  		return
    31  	}
    32  
    33  	if !strings.Contains(doc, "\n") {
    34  		fmt.Fprintf(out, "// %s\n", doc)
    35  		return
    36  	}
    37  	var list bool
    38  	for _, line := range strings.Split(doc, "\n") {
    39  		// Lists in metaModel.json start with a dash.
    40  		// To make a go doc list they have to be preceded
    41  		// by a blank line, and indented.
    42  		// (see type TextDccumentFilter in protocol.go)
    43  		if len(line) > 0 && line[0] == '-' {
    44  			if !list {
    45  				list = true
    46  				fmt.Fprintf(out, "//\n")
    47  			}
    48  			fmt.Fprintf(out, "//  %s\n", line)
    49  		} else {
    50  			if len(line) == 0 {
    51  				list = false
    52  			}
    53  			fmt.Fprintf(out, "// %s\n", line)
    54  		}
    55  	}
    56  }
    57  
    58  // decide if a property is optional, and if it needs a *
    59  // return ",omitempty" if it is optional, and "*" if it needs a pointer
    60  func propStar(name string, t NameType, gotype string) (string, string) {
    61  	var opt, star string
    62  	if t.Optional {
    63  		star = "*"
    64  		opt = ",omitempty"
    65  	}
    66  	if strings.HasPrefix(gotype, "[]") || strings.HasPrefix(gotype, "map[") {
    67  		star = "" // passed by reference, so no need for *
    68  	} else {
    69  		switch gotype {
    70  		case "bool", "uint32", "int32", "string", "interface{}":
    71  			star = "" // gopls compatibility if t.Optional
    72  		}
    73  	}
    74  	ostar, oopt := star, opt
    75  	if newStar, ok := goplsStar[prop{name, t.Name}]; ok {
    76  		switch newStar {
    77  		case nothing:
    78  			star, opt = "", ""
    79  		case wantStar:
    80  			star, opt = "*", ""
    81  		case wantOpt:
    82  			star, opt = "", ",omitempty"
    83  		case wantOptStar:
    84  			star, opt = "*", ",omitempty"
    85  		}
    86  		if star == ostar && opt == oopt { // no change
    87  			log.Printf("goplsStar[ {%q, %q} ](%d) useless %s/%s %s/%s", name, t.Name, t.Line, ostar, star, oopt, opt)
    88  		}
    89  		usedGoplsStar[prop{name, t.Name}] = true
    90  	}
    91  
    92  	return opt, star
    93  }
    94  
    95  func goName(s string) string {
    96  	// Go naming conventions
    97  	if strings.HasSuffix(s, "Id") {
    98  		s = s[:len(s)-len("Id")] + "ID"
    99  	} else if strings.HasSuffix(s, "Uri") {
   100  		s = s[:len(s)-3] + "URI"
   101  	} else if s == "uri" {
   102  		s = "URI"
   103  	} else if s == "id" {
   104  		s = "ID"
   105  	}
   106  
   107  	// renames for temporary GOPLS compatibility
   108  	if news := goplsType[s]; news != "" {
   109  		usedGoplsType[s] = true
   110  		s = news
   111  	}
   112  	// Names beginning _ are not exported
   113  	if strings.HasPrefix(s, "_") {
   114  		s = strings.Replace(s, "_", "X", 1)
   115  	}
   116  	if s != "string" { // base types are unchanged (textDocuemnt/diagnostic)
   117  		// Title is deprecated, but a) s is only one word, b) replacement is too heavy-weight
   118  		s = strings.Title(s)
   119  	}
   120  	return s
   121  }