internal/frontend: signal doc: ignore deprecated If a package is marked deprecated, don't require its symbols to be documented. Example: golang.org/x/crypto/cast5. We don't need to do that for individual symbols, because if they have a deprecation comment, then they already have a comment! For golang/go#80385. Change-Id: I5a3bde529fa01e9503236c2f9231c19ba4f2c500 Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/808740 Reviewed-by: Ethan Lee <ethanalee@google.com> LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> kokoro-CI: kokoro <noreply+kokoro@google.com>
diff --git a/internal/frontend/evals.go b/internal/frontend/evals.go index d4987d0..bc171db 100644 --- a/internal/frontend/evals.go +++ b/internal/frontend/evals.go
@@ -20,6 +20,7 @@ "golang.org/x/mod/semver" "golang.org/x/pkgsite/internal" "golang.org/x/pkgsite/internal/godoc" + "golang.org/x/pkgsite/internal/godoc/dochtml" "golang.org/x/pkgsite/internal/version" ) @@ -288,6 +289,12 @@ // API surface. It does not enforce standard Go documentation formatting // (e.g., "Name does..."). func collectSymbols(files []*ast.File, add func(name string, has bool)) { + for _, file := range files { + if file != nil && file.Doc != nil && dochtml.IsDeprecated(file.Doc.Text()) { + return + } + } + ifaceMethods := collectInterfaceMethods(files) // specDoc finds the doc comment for a spec. Typically this will be doc itself,
diff --git a/internal/frontend/evals_test.go b/internal/frontend/evals_test.go index f391e11..a6f8e48 100644 --- a/internal/frontend/evals_test.go +++ b/internal/frontend/evals_test.go
@@ -327,6 +327,56 @@ }) } } + +func TestCollectSymbolsDeprecatedPackage(t *testing.T) { + testCases := []struct { + name string + src string + want map[string]bool + }{ + { + name: "deprecated package", + src: `// Deprecated: use another package. +package foo + +// Foo does something. +func Foo() {} +`, + want: map[string]bool{}, + }, + { + name: "deprecated not at start of paragraph", + src: `// Package foo is active. +// Deprecated: this is not a new paragraph. +package foo + +// Foo does something. +func Foo() {} +`, + want: map[string]bool{"Foo": true}, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + fset := token.NewFileSet() + f, err := parser.ParseFile(fset, "foo.go", tc.src, parser.ParseComments) + if err != nil { + t.Fatalf("parser.ParseFile: %v", err) + } + + got := make(map[string]bool) + collectSymbols([]*ast.File{f}, func(name string, has bool) { + got[name] = has + }) + + if diff := cmp.Diff(tc.want, got); diff != "" { + t.Errorf("collectSymbols() mismatch (-want +got):\n%s", diff) + } + }) + } +} + func TestSigString(t *testing.T) { testCases := []struct { src string
diff --git a/internal/godoc/dochtml/deprecated.go b/internal/godoc/dochtml/deprecated.go index a732ad8..ff20b29 100644 --- a/internal/godoc/dochtml/deprecated.go +++ b/internal/godoc/dochtml/deprecated.go
@@ -12,19 +12,19 @@ // "Deprecated:" at the start of a paragraph. var deprecatedRx = regexp.MustCompile(`(^|\n\s*\n)\s*Deprecated:`) -// isDeprecated reports whether the string has a "Deprecated" line. -func isDeprecated(s string) bool { +// IsDeprecated reports whether the string has a "Deprecated" line. +func IsDeprecated(s string) bool { return deprecatedRx.MatchString(s) } func typeIsDeprecated(t *doc.Type) bool { - return isDeprecated(t.Doc) + return IsDeprecated(t.Doc) } func valueIsDeprecated(v *doc.Value) bool { - return isDeprecated(v.Doc) + return IsDeprecated(v.Doc) } func funcIsDeprecated(f *doc.Func) bool { - return isDeprecated(f.Doc) + return IsDeprecated(f.Doc) }
diff --git a/internal/godoc/dochtml/deprecated_test.go b/internal/godoc/dochtml/deprecated_test.go index 464ad41..8b6b908 100644 --- a/internal/godoc/dochtml/deprecated_test.go +++ b/internal/godoc/dochtml/deprecated_test.go
@@ -19,7 +19,7 @@ {"line 1\nDeprecated:\nline 2\n", false}, {"line 1\n\nDeprecated:\nline 2\n", true}, } { - got := isDeprecated(test.text) + got := IsDeprecated(test.text) if got != test.want { t.Errorf("%q: got %t, want %t", test.text, got, test.want) }