aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarlos Amedee <carlos@golang.org>2023-05-17 17:45:37 -0400
committerGopher Robot <gobot@golang.org>2023-05-24 03:14:42 +0000
commit626d478d828ea4c41e09830215fd6f21df9b1ccc (patch)
treea6e9b85f9044f2f331014f0bf50a54d2dd746af3 /src
parentfa50248ce6dfbe8afb18a67aa4d0d0cd3800a329 (diff)
downloadgo-626d478d828ea4c41e09830215fd6f21df9b1ccc.tar.xz
internal/types/errors: generate Markdown files for compiler errors
This change adds a generator which creates a Markdown file for each compiler error code which includes its associated documentation. The Markdown files will be added to the x/website repository and used to generate short error links on the Go website. Change-Id: Ibabc3388d6ecc7f19151f3931554f72561e30b22 Reviewed-on: https://go-review.googlesource.com/c/go/+/495858 Reviewed-by: Robert Griesemer <gri@google.com> Auto-Submit: Carlos Amedee <carlos@golang.org> Run-TryBot: Carlos Amedee <carlos@golang.org> Reviewed-by: Carlos Amedee <carlos@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src')
-rw-r--r--src/internal/types/errors/generrordocs.go117
1 files changed, 117 insertions, 0 deletions
diff --git a/src/internal/types/errors/generrordocs.go b/src/internal/types/errors/generrordocs.go
new file mode 100644
index 0000000000..46343be3ef
--- /dev/null
+++ b/src/internal/types/errors/generrordocs.go
@@ -0,0 +1,117 @@
+//go:build ignore
+
+// Copyright 2023 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.
+
+// generrordocs creates a Markdown file for each (compiler) error code
+// and its associated documentation.
+// Note: this program must be run in this directory.
+// go run generrordocs.go <dir>
+
+//go:generate go run generrordocs.go errors_markdown
+
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "go/ast"
+ "go/importer"
+ "go/parser"
+ "go/token"
+ "log"
+ "os"
+ "path"
+ "strings"
+ "text/template"
+
+ . "go/types"
+)
+
+func main() {
+ if len(os.Args) != 2 {
+ log.Fatal("missing argument: generrordocs <dir>")
+ }
+ outDir := os.Args[1]
+ if err := os.MkdirAll(outDir, 0755); err != nil {
+ log.Fatal("unable to create output directory: %s", err)
+ }
+ walkCodes(func(name string, vs *ast.ValueSpec) {
+ // ignore unused errors
+ if name == "_" {
+ return
+ }
+ // Ensure that < are represented correctly when its included in code
+ // blocks. The goldmark Markdown parser converts them to &amp;lt;
+ // when not escaped. It is the only known string with this issue.
+ desc := strings.ReplaceAll(vs.Doc.Text(), "<", `{{raw "<"}}`)
+ e := struct {
+ Name string
+ Description string
+ }{
+ Name: name,
+ Description: fmt.Sprintf("```\n%s```\n", desyc),
+ }
+ var buf bytes.Buffer
+ err := template.Must(template.New("eachError").Parse(markdownTemplate)).Execute(&buf, e)
+ if err != nil {
+ log.Fatalf("template.Must: %s", err)
+ }
+ if err := os.WriteFile(path.Join(outDir, name+".md"), buf.Bytes(), 0660); err != nil {
+ log.Fatalf("os.WriteFile: %s\n", err)
+ }
+ })
+ log.Printf("output directory: %s\n", outDir)
+}
+
+func walkCodes(f func(string, *ast.ValueSpec)) {
+ fset := token.NewFileSet()
+ file, err := parser.ParseFile(fset, "codes.go", nil, parser.ParseComments)
+ if err != nil {
+ log.Fatalf("ParseFile failed: %s", err)
+ }
+ conf := Config{Importer: importer.Default()}
+ info := &Info{
+ Types: make(map[ast.Expr]TypeAndValue),
+ Defs: make(map[*ast.Ident]Object),
+ Uses: make(map[*ast.Ident]Object),
+ }
+ _, err = conf.Check("types", fset, []*ast.File{file}, info)
+ if err != nil {
+ log.Fatalf("Check failed: %s", err)
+ }
+ for _, decl := range file.Decls {
+ decl, ok := decl.(*ast.GenDecl)
+ if !ok || decl.Tok != token.CONST {
+ continue
+ }
+ for _, spec := range decl.Specs {
+ spec, ok := spec.(*ast.ValueSpec)
+ if !ok || len(spec.Names) == 0 {
+ continue
+ }
+ obj := info.ObjectOf(spec.Names[0])
+ if named, ok := obj.Type().(*Named); ok && named.Obj().Name() == "Code" {
+ if len(spec.Names) != 1 {
+ log.Fatalf("bad Code declaration for %q: got %d names, want exactly 1", spec.Names[0].Name, len(spec.Names))
+ }
+ codename := spec.Names[0].Name
+ f(codename, spec)
+ }
+ }
+ }
+}
+
+const markdownTemplate = `---
+title: {{.Name}}
+layout: article
+---
+<!-- Copyright 2023 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. -->
+
+<!-- Code generated by generrordocs.go; DO NOT EDIT. -->
+
+{{.Description}}
+`