| // Copyright 2026 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. |
| |
| package main |
| |
| import ( |
| "bytes" |
| "errors" |
| "os" |
| "path/filepath" |
| "strings" |
| "testing" |
| |
| "simd/archsimd/_gen/gentools" |
| "simd/archsimd/_gen/specdoc" |
| "simd/archsimd/_gen/specgen" |
| ) |
| |
| // TestFill verifies that exported declarations in simd and archsimd match |
| // internal/spec. |
| func TestFill(t *testing.T) { |
| goroot := gentools.DefaultGOROOT() |
| specDir := specgen.MustFindSpecDir(goroot) |
| specFuncs, err := specgen.Load(specDir, nil) |
| if err != nil { |
| t.Fatalf("loading spec: %v", err) |
| } |
| specIdx := specgen.NewIndex(specFuncs) |
| |
| dirs := []string{ |
| filepath.Join(goroot, "src/simd"), |
| filepath.Join(goroot, "src/simd/archsimd"), |
| } |
| |
| for _, dir := range dirs { |
| entries, err := os.ReadDir(dir) |
| if err != nil { |
| t.Fatalf("reading %s: %v", dir, err) |
| } |
| for _, e := range entries { |
| if e.IsDir() || !strings.HasSuffix(e.Name(), ".go") || strings.HasSuffix(e.Name(), "_test.go") { |
| continue |
| } |
| filePath := filepath.Join(dir, e.Name()) |
| relPath, err := filepath.Rel(goroot, filePath) |
| if err != nil { |
| relPath = filePath |
| } |
| src, err := os.ReadFile(filePath) |
| if err != nil { |
| t.Fatalf("reading %s: %v", relPath, err) |
| } |
| |
| isGen, err := isGenerated(src) |
| if err != nil { |
| t.Fatalf("%s: %v", relPath, err) |
| } |
| |
| filled, err := specdoc.Fill(src, specIdx, specdoc.Options{ |
| Filename: filepath.ToSlash(relPath), |
| // Since we're checking generator output files, we expect there |
| // to already be spec-owned doc comments. Don't report these as |
| // errors. |
| AllowDocRewrite: true, |
| // TODO: Docs aren't yet filled by spec in the generators, so |
| // leave them alone in the check. Once they are filled by the |
| // generators and in hand-written files, drop this flag. |
| NoFillDoc: !isGen, |
| }) |
| var rep *specdoc.Report |
| if errors.As(err, &rep) { |
| t.Errorf("%s diverges from internal/spec:\n%s", relPath, rep) |
| } else if err != nil { |
| t.Errorf("checking %s: %v", relPath, err) |
| } else if !bytes.Equal(src, filled) { |
| diff := gentools.Diff(relPath, src, relPath, filled) |
| var fix string |
| switch { |
| case isGen: |
| // Just the regenerate. |
| case filepath.ToSlash(relPath) == "src/simd/simd_emulated.go": |
| // Currently the only file with spec-filled docs. |
| fix = "\tgo run ./cmd/specfill -w ../../simd_emulated.go\n" |
| default: |
| fix = "\tgo run ./cmd/specfill -no-fill-doc -w\n" |
| } |
| t.Errorf("%s diverges from internal/spec:\n%s\nTo fix:\n\tcd $GOROOT/src/simd/archsimd/_gen\n%s\tgo run . -w", relPath, diff, fix) |
| } |
| } |
| } |
| } |