go.temporal.io/server/tools/parallelize/parallelize.go
198 LOC · 102 covered · 96 uncovered · 43 ranges · 13 concepts · 13 introducers · 6 tests
File neighbourhood
The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.
Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file
In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the related-file, concept, and source links on this page.
Graph controls are ready.
Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.
package parallelize
import (
"errors"
"fmt"
"go/ast"
"go/parser"
"go/token"
"os"
"path/filepath"
"sort"
"strings"
)
func Main() error {
if len(os.Args) < 2 {
return errors.New("usage: parallelize <dir> [<dir>...]")
}
var failed bool
for _, dir := range os.Args[1:] {
if err := processDir(dir); err != nil {
fmt.Fprintf(os.Stderr, "error processing %s: %v\n", dir, err)
failed = true
}
}
if failed {
return errors.New("some files failed to process")
}
return nil
}
return filepath.WalkDir(dir, func(path string, d os.DirEntry, err error) error {
if err != nil {
return err
}
return nil
}
return processFile(path)
})
}
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, path, nil, parser.ParseComments)
if err != nil {
return fmt.Errorf("parse %s: %w", path, err)
}
// Collect line numbers where we need to insert t.Parallel().
// Each entry is the line of the opening '{' of the test function body.
line int // line number of the '{' opening the function body
paramName string // name of the *testing.T parameter
}
var insertions []insertion
for _, decl := range f.Decls {
fn, ok := decl.(*ast.FuncDecl)
if !ok {
continue
}
}
if paramName == "" {
continue
}
}
}
insertions = append(insertions, insertion{line: bodyLine, paramName: paramName})
}
}
// Sort by line descending so insertions don't shift line numbers of subsequent insertions.
})
if err != nil {
return fmt.Errorf("stat %s: %w", path, err)
}
if err != nil {
return fmt.Errorf("read %s: %w", path, err)
}
for _, ins := range insertions {
// ins.line is 1-indexed, so it conveniently equals the 0-based index
// of the line right after '{', which is where we want to insert.
idx := ins.line
newLine := "\t" + ins.paramName + ".Parallel()"
lines = append(lines[:idx+1], lines[idx:]...)
lines[idx] = newLine
}
if err := os.WriteFile(path, []byte(strings.Join(lines, "\n")), fi.Mode()); err != nil {
parallelize.go ×8
return fmt.Errorf("write %s: %w", path, err)
}
return nil
}
// isTestFunc returns true for func TestXxx(t *testing.T).
if fn.Recv != nil {
}
}
return false
}
}
// testingTParamName returns the name of the *testing.T parameter, or "" if not found.
if fn.Type.Params == nil || len(fn.Type.Params.List) == 0 {
return ""
}
starExpr, ok := field.Type.(*ast.StarExpr)
if !ok {
continue
}
if !ok {
continue
}
if !ok {
continue
}
if len(field.Names) > 0 {
return field.Names[0].Name
}
}
}
return ""
}
// hasNoLintComment checks for //parallelize:ignore in the function's doc comment.
if fn.Doc == nil {
}
if strings.Contains(c.Text, "parallelize:ignore") {
return true
}
}
return false
}
// hasParallelCall checks if the function body already contains <param>.Parallel().
found := false
ast.Inspect(body, func(n ast.Node) bool {
if found {
}
if !ok {
return true
}
sel, ok := call.Fun.(*ast.SelectorExpr)
if !ok {
return true
}
if !ok {
return true
}
}
})
}