[codegen/docs] Fix the generation of Function names, args, and result type names (#4490)

* Add a new DocLangHelper interface method to generate function names per language. Use the functionNames override map in Go to correctly generate a function name.

* Add kong to the title lookup map.

* Check if item was found in map.

* Use title case for the nodejs Function args type name. Use title case for the function name in the index page.

* Also fix the result name for a Function in nodejs to use title case.

* Use the module name to lookup the package.

* Use the title-case name for the Function name in the index page. Fix the language value passed to the lang chooser in function.tmpl.

* Use title case for nested type titles.

* Add title lookup for GitHub.
This commit is contained in:
Praneet Loke 2020-04-27 17:47:01 -07:00 committed by GitHub
parent 0a65bb620c
commit 7b17463031
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 89 additions and 49 deletions

View file

@ -50,9 +50,11 @@ type DocLanguageHelper interface {
GetDocLinkForFunctionInputOrOutputType(pkg *schema.Package, moduleName, typeName string, input bool) string
GetDocLinkForBuiltInType(typeName string) string
GetLanguageTypeString(pkg *schema.Package, moduleName string, t schema.Type, input, optional bool) string
GetFunctionName(modName string, f *schema.Function) string
// GetResourceFunctionResultName returns the name of the result type when a static resource function is used to lookup
// an existing resource.
GetResourceFunctionResultName(resourceName string) string
GetResourceFunctionResultName(modName string, f *schema.Function) string
}
type exampleParts struct {

View file

@ -80,9 +80,11 @@ var (
"f5bigip": "f5 BIG-IP",
"fastly": "Fastly",
"gcp": "GCP",
"github": "GitHub",
"gitlab": "GitLab",
"kafka": "Kafka",
"keycloak": "Keycloak",
"kong": "Kong",
"kubernetes": "Kubernetes",
"linode": "Linode",
"mailgun": "Mailgun",
@ -298,7 +300,7 @@ func resourceName(r *schema.Resource) string {
if r.IsProvider {
return "Provider"
}
return tokenToName(r.Token)
return strings.Title(tokenToName(r.Token))
}
func getLanguageDocHelper(lang string) codegen.DocLanguageHelper {
@ -741,7 +743,7 @@ func (mod *modContext) genNestedTypes(member interface{}, resourceType bool) []d
props[lang] = mod.getProperties(obj.Properties, lang, true, true)
}
name := tokenToName(obj.Token)
name := strings.Title(tokenToName(obj.Token))
objs = append(objs, docNestedType{
Name: wbr(name),
AnchorID: strings.ToLower(name),
@ -1533,7 +1535,7 @@ func (mod *modContext) genIndex() indexData {
name := tokenToName(f.Token)
functions = append(functions, indexEntry{
Link: strings.ToLower(name),
DisplayName: name,
DisplayName: strings.Title(name),
})
}
sortIndexEntries(functions)

View file

@ -34,10 +34,11 @@ type functionDocArgs struct {
Tool string
ResourceName string
DeprecationMessage string
Comment string
// FunctionName is a map of the language and the function name in that language.
FunctionName map[string]string
// FunctionArgs is map per language view of the parameters
// in the Function.
FunctionArgs map[string]string
@ -59,7 +60,7 @@ type functionDocArgs struct {
// getFunctionResourceInfo returns a map of per-language information about
// the resource being looked-up using a static "getter" function.
func (mod *modContext) getFunctionResourceInfo(resourceTypeName string) map[string]propertyType {
func (mod *modContext) getFunctionResourceInfo(f *schema.Function) map[string]propertyType {
resourceMap := make(map[string]propertyType)
var resultTypeName string
@ -67,11 +68,11 @@ func (mod *modContext) getFunctionResourceInfo(resourceTypeName string) map[stri
docLangHelper := getLanguageDocHelper(lang)
switch lang {
case "nodejs":
resultTypeName = docLangHelper.GetResourceFunctionResultName(resourceTypeName)
resultTypeName = docLangHelper.GetResourceFunctionResultName(mod.mod, f)
case "go":
resultTypeName = docLangHelper.GetResourceFunctionResultName(resourceTypeName)
resultTypeName = docLangHelper.GetResourceFunctionResultName(mod.mod, f)
case "csharp":
resultTypeName = docLangHelper.GetResourceFunctionResultName(resourceTypeName)
resultTypeName = docLangHelper.GetResourceFunctionResultName(mod.mod, f)
if mod.mod == "" {
resultTypeName = fmt.Sprintf("Pulumi.%s.%s", strings.Title(mod.pkg.Name), resultTypeName)
} else {
@ -97,8 +98,8 @@ func (mod *modContext) getFunctionResourceInfo(resourceTypeName string) map[stri
return resourceMap
}
func (mod *modContext) genFunctionTS(f *schema.Function, resourceName string) []formalParam {
argsType := "Get" + resourceName + "Args"
func (mod *modContext) genFunctionTS(f *schema.Function, funcName string) []formalParam {
argsType := title(funcName+"Args", "nodejs")
docLangHelper := getLanguageDocHelper("nodejs")
var params []formalParam
@ -125,13 +126,8 @@ func (mod *modContext) genFunctionTS(f *schema.Function, resourceName string) []
return params
}
func (mod *modContext) genFunctionGo(f *schema.Function, resourceName string) []formalParam {
argsType := resourceName + "Args"
if mod.mod == "" {
argsType = "Get" + argsType
} else {
argsType = "Lookup" + argsType
}
func (mod *modContext) genFunctionGo(f *schema.Function, funcName string) []formalParam {
argsType := funcName + "Args"
docLangHelper := getLanguageDocHelper("go")
params := []formalParam{
@ -139,7 +135,7 @@ func (mod *modContext) genFunctionGo(f *schema.Function, resourceName string) []
Name: "ctx",
OptionalFlag: "*",
Type: propertyType{
Name: "pulumi.Context",
Name: "Context",
Link: "https://pkg.go.dev/github.com/pulumi/pulumi/sdk/v2/go/pulumi?tab=doc#Context",
},
},
@ -160,15 +156,15 @@ func (mod *modContext) genFunctionGo(f *schema.Function, resourceName string) []
Name: "opts",
OptionalFlag: "...",
Type: propertyType{
Name: "pulumi.InvokeOption",
Name: "InvokeOption",
Link: "https://pkg.go.dev/github.com/pulumi/pulumi/sdk/v2/go/pulumi?tab=doc#InvokeOption",
},
})
return params
}
func (mod *modContext) genFunctionCS(f *schema.Function, resourceName string) []formalParam {
argsType := "Get" + resourceName + "Args"
func (mod *modContext) genFunctionCS(f *schema.Function, funcName string) []formalParam {
argsType := funcName + "Args"
argsSchemaType := &schema.ObjectType{
Token: f.Token,
}
@ -236,7 +232,7 @@ func (mod *modContext) genFunctionPython(f *schema.Function, resourceName string
// genFunctionArgs generates the arguments string for a given Function that can be
// rendered directly into a template.
func (mod *modContext) genFunctionArgs(f *schema.Function, resourceName string) map[string]string {
func (mod *modContext) genFunctionArgs(f *schema.Function, funcNameMap map[string]string) map[string]string {
functionParams := make(map[string]string)
for _, lang := range supportedLanguages {
@ -248,16 +244,16 @@ func (mod *modContext) genFunctionArgs(f *schema.Function, resourceName string)
switch lang {
case "nodejs":
params = mod.genFunctionTS(f, resourceName)
params = mod.genFunctionTS(f, funcNameMap["nodejs"])
paramTemplate = "ts_formal_param"
case "go":
params = mod.genFunctionGo(f, resourceName)
params = mod.genFunctionGo(f, funcNameMap["go"])
paramTemplate = "go_formal_param"
case "csharp":
params = mod.genFunctionCS(f, resourceName)
params = mod.genFunctionCS(f, funcNameMap["csharp"])
paramTemplate = "csharp_formal_param"
case "python":
params = mod.genFunctionPython(f, resourceName)
params = mod.genFunctionPython(f, funcNameMap["python"])
paramTemplate = "py_formal_param"
}
@ -282,7 +278,7 @@ func (mod *modContext) genFunctionArgs(f *schema.Function, resourceName string)
}
func (mod *modContext) genFunctionHeader(f *schema.Function) header {
funcName := tokenToName(f.Token)
funcName := strings.Title(tokenToName(f.Token))
packageName := formatTitleText(mod.pkg.Name)
var baseDescription string
var titleTag string
@ -308,9 +304,6 @@ func (mod *modContext) genFunctionHeader(f *schema.Function) header {
// genFunction is the main entrypoint for generating docs for a Function.
// Returns args type that can be used to execute the `function.tmpl` doc template.
func (mod *modContext) genFunction(f *schema.Function) functionDocArgs {
name := tokenToName(f.Token)
resourceName := strings.ReplaceAll(name, "Get", "")
inputProps := make(map[string][]property)
outputProps := make(map[string][]property)
for _, lang := range supportedLanguages {
@ -324,14 +317,21 @@ func (mod *modContext) genFunction(f *schema.Function) functionDocArgs {
nestedTypes := mod.genNestedTypes(f, false /*resourceType*/)
// Generate the per-language map for the function name.
funcNameMap := map[string]string{}
for _, lang := range supportedLanguages {
docHelper := getLanguageDocHelper(lang)
funcNameMap[lang] = docHelper.GetFunctionName(mod.mod, f)
}
args := functionDocArgs{
Header: mod.genFunctionHeader(f),
Tool: mod.tool,
ResourceName: resourceName,
FunctionArgs: mod.genFunctionArgs(f, resourceName),
FunctionResult: mod.getFunctionResourceInfo(resourceName),
FunctionName: funcNameMap,
FunctionArgs: mod.genFunctionArgs(f, funcNameMap),
FunctionResult: mod.getFunctionResourceInfo(f),
Comment: f.Comment,
DeprecationMessage: f.DeprecationMessage,

View file

@ -15,23 +15,23 @@
{{ htmlSafe "{{< chooser language \"javascript,typescript,python,go,csharp\" / >}}" }}
<!-- TS/JS -->
{{ print "{{% choosable language typescript %}}" }}
<div class="highlight"><pre class="chroma"><code class="language-typescript" data-lang="typescript"><span class="k">function </span>get{{ .ResourceName }}<span class="p">(</span>{{ htmlSafe .FunctionArgs.nodejs }}<span class="p">): Promise<{{ template "linkify_param" .FunctionResult.nodejs }}></span></code></pre></div>
{{ print "{{% choosable language nodejs %}}" }}
<div class="highlight"><pre class="chroma"><code class="language-typescript" data-lang="typescript"><span class="k">function </span>{{ .FunctionName.nodejs }}<span class="p">(</span>{{ htmlSafe .FunctionArgs.nodejs }}<span class="p">): Promise<{{ template "linkify_param" .FunctionResult.nodejs }}></span></code></pre></div>
{{ print "{{% /choosable %}}" }}
<!-- Python -->
{{ print "{{% choosable language python %}}" }}
<div class="highlight"><pre class="chroma"><code class="language-python" data-lang="python"><span class="k">function </span> get_{{ pyName .ResourceName }}(</span>{{ htmlSafe .FunctionArgs.python }}<span class="p">)</span></code></pre></div>
<div class="highlight"><pre class="chroma"><code class="language-python" data-lang="python"><span class="k">function </span> {{ .FunctionName.python }}(</span>{{ htmlSafe .FunctionArgs.python }}<span class="p">)</span></code></pre></div>
{{ print "{{% /choosable %}}" }}
<!-- Go -->
{{ print "{{% choosable language go %}}" }}
<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="k">func </span>Lookup{{ .ResourceName }}<span class="p">(</span>{{ htmlSafe .FunctionArgs.go }}<span class="p">) (*{{ template "linkify_param" .FunctionResult.go }}, error)</span></code></pre></div>
<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="k">func </span>{{ .FunctionName.go }}<span class="p">(</span>{{ htmlSafe .FunctionArgs.go }}<span class="p">) (*{{ template "linkify_param" .FunctionResult.go }}, error)</span></code></pre></div>
{{ print "{{% /choosable %}}" }}
<!-- C# -->
{{ print "{{% choosable language csharp %}}" }}
<div class="highlight"><pre class="chroma"><code class="language-csharp" data-lang="csharp"><span class="k">public static class </span><span class="nx">Get{{ .ResourceName }} </span><span class="p">{</span><span class="k">
<div class="highlight"><pre class="chroma"><code class="language-csharp" data-lang="csharp"><span class="k">public static class </span><span class="nx">{{ .FunctionName.csharp }} </span><span class="p">{</span><span class="k">
public static </span>Task<{{ template "linkify_param" .FunctionResult.csharp }}> <span class="p">InvokeAsync(</span>{{ htmlSafe .FunctionArgs.csharp }}<span class="p">)</span><span class="p">
}</span></code></pre></div>
{{ print "{{% /choosable %}}" }}

View file

@ -59,7 +59,7 @@ func wbr(s string) string {
func tokenToName(tok string) string {
components := strings.Split(tok, ":")
contract.Assertf(len(components) == 3, "malformed token %v", tok)
return strings.Title(components[2])
return components[2]
}
func title(s, lang string) string {

View file

@ -84,10 +84,15 @@ func (d DocLanguageHelper) GetLanguageTypeString(pkg *schema.Package, moduleName
return mod.typeString(t, qualifier, input, false /*state*/, false /*wrapInput*/, true /*requireInitializers*/, optional)
}
func (d DocLanguageHelper) GetFunctionName(modName string, f *schema.Function) string {
return tokenToFunctionName(f.Token)
}
// GetResourceFunctionResultName returns the name of the result type when a function is used to lookup
// an existing resource.
func (d DocLanguageHelper) GetResourceFunctionResultName(resourceName string) string {
return "Get" + resourceName + "Result"
func (d DocLanguageHelper) GetResourceFunctionResultName(modName string, f *schema.Function) string {
funcName := d.GetFunctionName(modName, f)
return funcName + "Result"
}
// GetPropertyName uses the property's csharp-specific language info, if available, to generate

View file

@ -160,6 +160,10 @@ func resourceName(r *schema.Resource) string {
return tokenToName(r.Token)
}
func tokenToFunctionName(tok string) string {
return tokenToName(tok)
}
func (mod *modContext) tokenToNamespace(tok string) string {
components := strings.Split(tok, ":")
contract.Assertf(len(components) == 3, "malformed token %v", tok)
@ -744,7 +748,7 @@ func (mod *modContext) genResource(w io.Writer, r *schema.Resource) error {
}
func (mod *modContext) genFunction(w io.Writer, fun *schema.Function) error {
className := tokenToName(fun.Token)
className := tokenToFunctionName(fun.Token)
fmt.Fprintf(w, "namespace %s\n", mod.tokenToNamespace(fun.Token))
fmt.Fprintf(w, "{\n")

View file

@ -109,8 +109,22 @@ func (d DocLanguageHelper) GetPropertyName(p *schema.Property) (string, error) {
return strings.Title(p.Name), nil
}
func (d DocLanguageHelper) GetFunctionName(modName string, f *schema.Function) string {
funcName := tokenToName(f.Token)
pkg, ok := d.packages[modName]
if !ok {
return funcName
}
if override, ok := pkg.functionNames[f]; ok {
funcName = override
}
return funcName
}
// GetResourceFunctionResultName returns the name of the result type when a function is used to lookup
// an existing resource.
func (d DocLanguageHelper) GetResourceFunctionResultName(resourceName string) string {
return "Lookup" + resourceName + "Result"
func (d DocLanguageHelper) GetResourceFunctionResultName(modName string, f *schema.Function) string {
funcName := d.GetFunctionName(modName, f)
return funcName + "Result"
}

View file

@ -96,10 +96,15 @@ func (d DocLanguageHelper) GetLanguageTypeString(pkg *schema.Package, moduleName
return typeName
}
func (d DocLanguageHelper) GetFunctionName(modName string, f *schema.Function) string {
return tokenToFunctionName(f.Token)
}
// GetResourceFunctionResultName returns the name of the result type when a function is used to lookup
// an existing resource.
func (d DocLanguageHelper) GetResourceFunctionResultName(resourceName string) string {
return "Get" + resourceName + "Result"
func (d DocLanguageHelper) GetResourceFunctionResultName(modName string, f *schema.Function) string {
funcName := d.GetFunctionName(modName, f)
return title(funcName) + "Result"
}
// GetPropertyName returns the property name specific to NodeJS.

View file

@ -135,6 +135,10 @@ func resourceName(r *schema.Resource) string {
return tokenToName(r.Token)
}
func tokenToFunctionName(tok string) string {
return camel(tokenToName(tok))
}
func (mod *modContext) typeString(t schema.Type, input, wrapInput, optional bool) string {
var typ string
switch t := t.(type) {
@ -541,7 +545,7 @@ func (mod *modContext) genResource(w io.Writer, r *schema.Resource) error {
}
func (mod *modContext) genFunction(w io.Writer, fun *schema.Function) {
name := camel(tokenToName(fun.Token))
name := tokenToFunctionName(fun.Token)
// Write the TypeDoc/JSDoc for the data source function.
printComment(w, codegen.StripNonRelevantExamples(fun.Comment, "typescript"), "", "")

View file

@ -100,8 +100,12 @@ func (d DocLanguageHelper) GetLanguageTypeString(pkg *schema.Package, moduleName
return name
}
func (d DocLanguageHelper) GetFunctionName(modName string, f *schema.Function) string {
return PyName(tokenToName(f.Token))
}
// GetResourceFunctionResultName is not implemented for Python and returns an empty string.
func (d DocLanguageHelper) GetResourceFunctionResultName(resourceName string) string {
func (d DocLanguageHelper) GetResourceFunctionResultName(modName string, f *schema.Function) string {
return ""
}