tools/gen: Add flags for explicit output

`-o` will emit the files to the given root output directory
`--verbose` will print what's going on, to help with debugging

Omitting these flags will behave as before.

Also consolidate the utils package into fileutils. These were two packages with near identical functionality.

Change-Id: I855dd4b57807fb9239a52e7f357842d4ba2517ee
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/107687
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
Ben Clayton 2022-10-31 18:28:22 +00:00 committed by Dawn LUCI CQ
parent 6dbb463f1d
commit 68ed8d92d3
17 changed files with 192 additions and 234 deletions

View File

@ -39,7 +39,7 @@ import (
"time" "time"
"unicode/utf8" "unicode/utf8"
"dawn.googlesource.com/dawn/tools/src/utils" "dawn.googlesource.com/dawn/tools/src/fileutils"
"github.com/mattn/go-colorable" "github.com/mattn/go-colorable"
"github.com/mattn/go-isatty" "github.com/mattn/go-isatty"
) )
@ -1174,7 +1174,7 @@ func saveExpectations(path string, ex testcaseStatuses) error {
// directory, falling back to PATH. This is used as the default for the --node // directory, falling back to PATH. This is used as the default for the --node
// command line flag. // command line flag.
func defaultNodePath() string { func defaultNodePath() string {
if dawnRoot := utils.DawnRoot(); dawnRoot != "" { if dawnRoot := fileutils.DawnRoot(); dawnRoot != "" {
node := filepath.Join(dawnRoot, "third_party/node") node := filepath.Join(dawnRoot, "third_party/node")
if info, err := os.Stat(node); err == nil && info.IsDir() { if info, err := os.Stat(node); err == nil && info.IsDir() {
path := "" path := ""
@ -1204,7 +1204,7 @@ func defaultNodePath() string {
// defaultCtsPath looks for the webgpu-cts directory in dawn's third_party // defaultCtsPath looks for the webgpu-cts directory in dawn's third_party
// directory. This is used as the default for the --cts command line flag. // directory. This is used as the default for the --cts command line flag.
func defaultCtsPath() string { func defaultCtsPath() string {
if dawnRoot := utils.DawnRoot(); dawnRoot != "" { if dawnRoot := fileutils.DawnRoot(); dawnRoot != "" {
cts := filepath.Join(dawnRoot, "third_party/webgpu-cts") cts := filepath.Join(dawnRoot, "third_party/webgpu-cts")
if info, err := os.Stat(cts); err == nil && info.IsDir() { if info, err := os.Stat(cts); err == nil && info.IsDir() {
return cts return cts

View File

@ -15,7 +15,7 @@
package common package common
import ( import (
"dawn.googlesource.com/dawn/tools/src/utils" "dawn.googlesource.com/dawn/tools/src/fileutils"
"go.chromium.org/luci/auth" "go.chromium.org/luci/auth"
"go.chromium.org/luci/hardcoded/chromeinfra" "go.chromium.org/luci/hardcoded/chromeinfra"
) )
@ -32,6 +32,6 @@ const (
// command line arguments. // command line arguments.
func DefaultAuthOptions() auth.Options { func DefaultAuthOptions() auth.Options {
def := chromeinfra.DefaultAuthOptions() def := chromeinfra.DefaultAuthOptions()
def.SecretsDir = utils.ExpandHome("~/.config/dawn-cts") def.SecretsDir = fileutils.ExpandHome("~/.config/dawn-cts")
return def return def
} }

View File

@ -18,7 +18,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"dawn.googlesource.com/dawn/tools/src/utils" "dawn.googlesource.com/dawn/tools/src/fileutils"
) )
const ( const (
@ -34,7 +34,7 @@ const (
// DefaultExpectationsPath returns the default path to the expectations.txt // DefaultExpectationsPath returns the default path to the expectations.txt
// file. Returns an empty string if the file cannot be found. // file. Returns an empty string if the file cannot be found.
func DefaultExpectationsPath() string { func DefaultExpectationsPath() string {
path := filepath.Join(utils.DawnRoot(), RelativeExpectationsPath) path := filepath.Join(fileutils.DawnRoot(), RelativeExpectationsPath)
if _, err := os.Stat(path); err != nil { if _, err := os.Stat(path); err != nil {
return "" return ""
} }
@ -44,7 +44,7 @@ func DefaultExpectationsPath() string {
// DefaultTestListPath returns the default path to the test_list.txt // DefaultTestListPath returns the default path to the test_list.txt
// file. Returns an empty string if the file cannot be found. // file. Returns an empty string if the file cannot be found.
func DefaultTestListPath() string { func DefaultTestListPath() string {
path := filepath.Join(utils.DawnRoot(), RelativeTestListPath) path := filepath.Join(fileutils.DawnRoot(), RelativeTestListPath)
if _, err := os.Stat(path); err != nil { if _, err := os.Stat(path); err != nil {
return "" return ""
} }

View File

@ -29,10 +29,10 @@ import (
"dawn.googlesource.com/dawn/tools/src/buildbucket" "dawn.googlesource.com/dawn/tools/src/buildbucket"
"dawn.googlesource.com/dawn/tools/src/cts/query" "dawn.googlesource.com/dawn/tools/src/cts/query"
"dawn.googlesource.com/dawn/tools/src/cts/result" "dawn.googlesource.com/dawn/tools/src/cts/result"
"dawn.googlesource.com/dawn/tools/src/fileutils"
"dawn.googlesource.com/dawn/tools/src/gerrit" "dawn.googlesource.com/dawn/tools/src/gerrit"
"dawn.googlesource.com/dawn/tools/src/resultsdb" "dawn.googlesource.com/dawn/tools/src/resultsdb"
"dawn.googlesource.com/dawn/tools/src/subcmd" "dawn.googlesource.com/dawn/tools/src/subcmd"
"dawn.googlesource.com/dawn/tools/src/utils"
"go.chromium.org/luci/auth" "go.chromium.org/luci/auth"
rdbpb "go.chromium.org/luci/resultdb/proto/v1" rdbpb "go.chromium.org/luci/resultdb/proto/v1"
) )
@ -154,7 +154,7 @@ func CacheResults(
var cachePath string var cachePath string
if cacheDir != "" { if cacheDir != "" {
dir := utils.ExpandHome(cacheDir) dir := fileutils.ExpandHome(cacheDir)
path := filepath.Join(dir, strconv.Itoa(ps.Change), fmt.Sprintf("ps-%v.txt", ps.Patchset)) path := filepath.Join(dir, strconv.Itoa(ps.Change), fmt.Sprintf("ps-%v.txt", ps.Patchset))
if _, err := os.Stat(path); err == nil { if _, err := os.Stat(path); err == nil {
return result.Load(path) return result.Load(path)

View File

@ -28,9 +28,9 @@ import (
"dawn.googlesource.com/dawn/tools/src/cmd/cts/common" "dawn.googlesource.com/dawn/tools/src/cmd/cts/common"
"dawn.googlesource.com/dawn/tools/src/cts/result" "dawn.googlesource.com/dawn/tools/src/cts/result"
"dawn.googlesource.com/dawn/tools/src/fileutils"
"dawn.googlesource.com/dawn/tools/src/git" "dawn.googlesource.com/dawn/tools/src/git"
"dawn.googlesource.com/dawn/tools/src/gitiles" "dawn.googlesource.com/dawn/tools/src/gitiles"
"dawn.googlesource.com/dawn/tools/src/utils"
"go.chromium.org/luci/auth/client/authcli" "go.chromium.org/luci/auth/client/authcli"
"golang.org/x/oauth2" "golang.org/x/oauth2"
"golang.org/x/oauth2/google" "golang.org/x/oauth2/google"
@ -70,7 +70,7 @@ func (c *cmd) Run(ctx context.Context, cfg common.Config) error {
} }
// Load the credentials used for accessing the sheets document // Load the credentials used for accessing the sheets document
authdir := utils.ExpandHome(os.ExpandEnv(auth.SecretsDir)) authdir := fileutils.ExpandHome(os.ExpandEnv(auth.SecretsDir))
credentialsPath := filepath.Join(authdir, "credentials.json") credentialsPath := filepath.Join(authdir, "credentials.json")
b, err := ioutil.ReadFile(credentialsPath) b, err := ioutil.ReadFile(credentialsPath)
if err != nil { if err != nil {

View File

@ -24,8 +24,8 @@ import (
"path/filepath" "path/filepath"
"dawn.googlesource.com/dawn/tools/src/cmd/cts/common" "dawn.googlesource.com/dawn/tools/src/cmd/cts/common"
"dawn.googlesource.com/dawn/tools/src/fileutils"
"dawn.googlesource.com/dawn/tools/src/subcmd" "dawn.googlesource.com/dawn/tools/src/subcmd"
"dawn.googlesource.com/dawn/tools/src/utils"
// Register sub-commands // Register sub-commands
_ "dawn.googlesource.com/dawn/tools/src/cmd/cts/export" _ "dawn.googlesource.com/dawn/tools/src/cmd/cts/export"
@ -41,7 +41,7 @@ import (
func main() { func main() {
ctx := context.Background() ctx := context.Background()
cfg, err := common.LoadConfig(filepath.Join(utils.ThisDir(), "config.json")) cfg, err := common.LoadConfig(filepath.Join(fileutils.ThisDir(), "config.json"))
if err != nil { if err != nil {
fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr, err)
os.Exit(1) os.Exit(1)

View File

@ -56,14 +56,15 @@ func showUsage() {
fmt.Println(` fmt.Println(`
gen generates the templated code for the Tint compiler gen generates the templated code for the Tint compiler
gen scans the project directory for '<file>.tmpl' files, to produce source code gen accepts a list of file paths to the templates to generate. If no templates
files. are explicitly specified, then gen scans the '<dawn>/src/tint' and
'<dawn>/test/tint' directories for '<file>.tmpl' files.
If the templates use the 'IntrinsicTable' function then gen will parse and If the templates use the 'IntrinsicTable' function then gen will parse and
resolve the <tint>/src/tint/intrinsics.def file. resolve the <tint>/src/tint/intrinsics.def file.
usage: usage:
gen gen [flags] [template files]
optional flags:`) optional flags:`)
flag.PrintDefaults() flag.PrintDefaults()
@ -72,7 +73,13 @@ optional flags:`)
} }
func run() error { func run() error {
projectRoot := fileutils.ProjectRoot() outputDir := ""
verbose := false
flag.StringVar(&outputDir, "o", "", "custom output directory (optional)")
flag.BoolVar(&verbose, "verbose", false, "print verbose output")
flag.Parse()
projectRoot := fileutils.DawnRoot()
// Find clang-format // Find clang-format
clangFormatPath := findClangFormat(projectRoot) clangFormatPath := findClangFormat(projectRoot)
@ -80,8 +87,12 @@ func run() error {
return fmt.Errorf("cannot find clang-format in <dawn>/buildtools nor PATH") return fmt.Errorf("cannot find clang-format in <dawn>/buildtools nor PATH")
} }
// Recursively find all the template files in the <tint>/src directory files := flag.Args()
files, err := glob.Scan(projectRoot, glob.MustParseConfig(`{ if len(files) == 0 {
// Recursively find all the template files in the <dawn>/src/tint and
// <dawn>/test/tint and directories
var err error
files, err = glob.Scan(projectRoot, glob.MustParseConfig(`{
"paths": [{"include": [ "paths": [{"include": [
"src/tint/**.tmpl", "src/tint/**.tmpl",
"test/tint/**.tmpl" "test/tint/**.tmpl"
@ -90,13 +101,34 @@ func run() error {
if err != nil { if err != nil {
return err return err
} }
} else {
// Make all template file paths project-relative
for i, f := range files {
abs, err := filepath.Abs(f)
if err != nil {
return fmt.Errorf("failed to get absolute file path for '%v': %w", f, err)
}
if !strings.HasPrefix(abs, projectRoot) {
return fmt.Errorf("template '%v' is not under project root '%v'", abs, projectRoot)
}
rel, err := filepath.Rel(projectRoot, abs)
if err != nil {
return fmt.Errorf("failed to get project relative file path for '%v': %w", f, err)
}
files[i] = rel
}
}
cache := &genCache{} cache := &genCache{}
// For each template file... // For each template file...
for _, relTmplPath := range files { for _, relTmplPath := range files { // relative to project root
if verbose {
fmt.Println("processing", relTmplPath)
}
// Make tmplPath absolute // Make tmplPath absolute
tmplPath := filepath.Join(projectRoot, relTmplPath) tmplPath := filepath.Join(projectRoot, relTmplPath)
tmplDir := filepath.Dir(tmplPath)
// Read the template file // Read the template file
tmpl, err := ioutil.ReadFile(tmplPath) tmpl, err := ioutil.ReadFile(tmplPath)
@ -104,16 +136,22 @@ func run() error {
return fmt.Errorf("failed to open '%v': %w", tmplPath, err) return fmt.Errorf("failed to open '%v': %w", tmplPath, err)
} }
// Create or update the file at relpath if the file content has changed, // Create or update the file at relPath if the file content has changed,
// preserving the copyright year in the header. // preserving the copyright year in the header.
// relpath is a path relative to the template // relPath is a path relative to the template
writeFile := func(relpath, body string) error { writeFile := func(relPath, body string) error {
abspath := filepath.Join(filepath.Dir(tmplPath), relpath) var outPath string
if outputDir != "" {
relTmplDir := filepath.Dir(relTmplPath)
outPath = filepath.Join(outputDir, relTmplDir, relPath)
} else {
outPath = filepath.Join(tmplDir, relPath)
}
copyrightYear := time.Now().Year() copyrightYear := time.Now().Year()
// Load the old file // Load the old file
existing, err := ioutil.ReadFile(abspath) existing, err := ioutil.ReadFile(outPath)
if err == nil { if err == nil {
// Look for the existing copyright year // Look for the existing copyright year
if match := copyrightRegex.FindStringSubmatch(string(existing)); len(match) == 2 { if match := copyrightRegex.FindStringSubmatch(string(existing)); len(match) == 2 {
@ -124,11 +162,14 @@ func run() error {
} }
// Write the common file header // Write the common file header
if verbose {
fmt.Println(" writing", outPath)
}
sb := strings.Builder{} sb := strings.Builder{}
sb.WriteString(fmt.Sprintf(header, copyrightYear, filepath.ToSlash(relTmplPath))) sb.WriteString(fmt.Sprintf(header, copyrightYear, filepath.ToSlash(relTmplPath)))
sb.WriteString(body) sb.WriteString(body)
content := sb.String() content := sb.String()
return writeFileIfChanged(abspath, content, string(existing)) return writeFileIfChanged(outPath, content, string(existing))
} }
// Write the content generated using the template and semantic info // Write the content generated using the template and semantic info
@ -171,7 +212,7 @@ type genCache struct {
func (g *genCache) sem() (*sem.Sem, error) { func (g *genCache) sem() (*sem.Sem, error) {
if g.cached.sem == nil { if g.cached.sem == nil {
// Load the builtins definition file // Load the builtins definition file
defPath := filepath.Join(fileutils.ProjectRoot(), defProjectRelPath) defPath := filepath.Join(fileutils.DawnRoot(), defProjectRelPath)
defSource, err := ioutil.ReadFile(defPath) defSource, err := ioutil.ReadFile(defPath)
if err != nil { if err != nil {
@ -276,9 +317,9 @@ type generator struct {
// WriteFile is a function that Generate() may call to emit a new file from a // WriteFile is a function that Generate() may call to emit a new file from a
// template. // template.
// relpath is the relative path from the currently executing template. // relPath is the relative path from the currently executing template.
// content is the file content to write. // content is the file content to write.
type WriteFile func(relpath, content string) error type WriteFile func(relPath, content string) error
// generate executes the template tmpl, writing the output to w. // generate executes the template tmpl, writing the output to w.
// See https://golang.org/pkg/text/template/ for documentation on the template // See https://golang.org/pkg/text/template/ for documentation on the template
@ -332,7 +373,7 @@ func (g *generator) bindAndParse(t *template.Template, text string) error {
"Permute": g.cache.permute, "Permute": g.cache.permute,
"Eval": g.eval, "Eval": g.eval,
"Import": g.importTmpl, "Import": g.importTmpl,
"WriteFile": func(relpath, content string) (string, error) { return "", g.writeFile(relpath, content) }, "WriteFile": func(relPath, content string) (string, error) { return "", g.writeFile(relPath, content) },
}).Option("missingkey=error").Parse(text) }).Option("missingkey=error").Parse(text)
return err return err
} }
@ -377,7 +418,7 @@ func (g *generator) importTmpl(path string) (string, error) {
if strings.Contains(path, "..") { if strings.Contains(path, "..") {
return "", fmt.Errorf("import path must not contain '..'") return "", fmt.Errorf("import path must not contain '..'")
} }
path = filepath.Join(fileutils.ProjectRoot(), path) path = filepath.Join(fileutils.DawnRoot(), path)
data, err := ioutil.ReadFile(path) data, err := ioutil.ReadFile(path)
if err != nil { if err != nil {
return "", fmt.Errorf("failed to open '%v': %w", path, err) return "", fmt.Errorf("failed to open '%v': %w", path, err)

View File

@ -99,7 +99,7 @@ func run() error {
} }
fmt.Println("Scanning for files...") fmt.Println("Scanning for files...")
paths, err := glob.Scan(fileutils.ProjectRoot(), cfg) paths, err := glob.Scan(fileutils.DawnRoot(), cfg)
if err != nil { if err != nil {
return err return err
} }
@ -230,7 +230,7 @@ func (f *file) format() error {
// Runs git add on the file // Runs git add on the file
func (f *file) stage() error { func (f *file) stage() error {
err := exec.Command("git", "-C", fileutils.ProjectRoot(), "add", f.path).Run() err := exec.Command("git", "-C", fileutils.DawnRoot(), "add", f.path).Run()
if err != nil { if err != nil {
return fmt.Errorf("Couldn't stage file '%v': %w", f.path, err) return fmt.Errorf("Couldn't stage file '%v': %w", f.path, err)
} }
@ -245,7 +245,7 @@ func loadFiles(paths []string) ([]file, error) {
files := make([]file, len(paths)) files := make([]file, len(paths))
errs := make([]error, len(paths)) errs := make([]error, len(paths))
for i, path := range paths { for i, path := range paths {
i, path := i, filepath.Join(fileutils.ProjectRoot(), path) i, path := i, filepath.Join(fileutils.DawnRoot(), path)
go func() { go func() {
defer wg.Done() defer wg.Done()
body, err := ioutil.ReadFile(path) body, err := ioutil.ReadFile(path)

View File

@ -6,7 +6,7 @@ import (
"dawn.googlesource.com/dawn/tools/src/container" "dawn.googlesource.com/dawn/tools/src/container"
"dawn.googlesource.com/dawn/tools/src/cts/query" "dawn.googlesource.com/dawn/tools/src/cts/query"
"dawn.googlesource.com/dawn/tools/src/utils" "dawn.googlesource.com/dawn/tools/src/fileutils"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
) )
@ -735,7 +735,7 @@ func TestReduceUnder(t *testing.T) {
} }
for _, test := range []Test{ for _, test := range []Test{
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
to: Q(`suite:a,b,*`), to: Q(`suite:a,b,*`),
in: []QueryData{ in: []QueryData{
{Query: Q(`suite:a,b,*`), Data: failure}, {Query: Q(`suite:a,b,*`), Data: failure},
@ -745,7 +745,7 @@ func TestReduceUnder(t *testing.T) {
}, },
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
to: Q(`suite:a,*`), to: Q(`suite:a,*`),
in: []QueryData{ in: []QueryData{
{Query: Q(`suite:a,b,*`), Data: failure}, {Query: Q(`suite:a,b,*`), Data: failure},
@ -755,7 +755,7 @@ func TestReduceUnder(t *testing.T) {
}, },
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
to: Q(`suite:*`), to: Q(`suite:*`),
in: []QueryData{ in: []QueryData{
{Query: Q(`suite:a,b:*`), Data: failure}, {Query: Q(`suite:a,b:*`), Data: failure},
@ -765,7 +765,7 @@ func TestReduceUnder(t *testing.T) {
}, },
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
to: Q(`suite:a,*`), to: Q(`suite:a,*`),
in: []QueryData{ in: []QueryData{
{Query: Q(`suite:a,b,*`), Data: failure}, {Query: Q(`suite:a,b,*`), Data: failure},
@ -777,7 +777,7 @@ func TestReduceUnder(t *testing.T) {
}, },
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
to: Q(`suite:a,*`), to: Q(`suite:a,*`),
in: []QueryData{ in: []QueryData{
{Query: Q(`suite:a,b,*`), Data: pass}, {Query: Q(`suite:a,b,*`), Data: pass},
@ -788,7 +788,7 @@ func TestReduceUnder(t *testing.T) {
}, },
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
to: Q(`suite:a`), to: Q(`suite:a`),
in: []QueryData{ in: []QueryData{
{Query: Q(`suite:a,b,*`), Data: pass}, {Query: Q(`suite:a,b,*`), Data: pass},
@ -799,7 +799,7 @@ func TestReduceUnder(t *testing.T) {
}, },
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
to: Q(`suite:x`), to: Q(`suite:x`),
in: []QueryData{ in: []QueryData{
{Query: Q(`suite:a,b,*`), Data: pass}, {Query: Q(`suite:a,b,*`), Data: pass},
@ -814,7 +814,7 @@ func TestReduceUnder(t *testing.T) {
}, },
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
to: Q(`suite:a,b,c,*`), to: Q(`suite:a,b,c,*`),
in: []QueryData{ in: []QueryData{
{Query: Q(`suite:a,b,*`), Data: pass}, {Query: Q(`suite:a,b,*`), Data: pass},

View File

@ -19,7 +19,7 @@ import (
"testing" "testing"
"dawn.googlesource.com/dawn/tools/src/cts/result" "dawn.googlesource.com/dawn/tools/src/cts/result"
"dawn.googlesource.com/dawn/tools/src/utils" "dawn.googlesource.com/dawn/tools/src/fileutils"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
) )
@ -31,12 +31,12 @@ func TestMinimalVariantTags(t *testing.T) {
} }
for _, test := range []Test{ for _, test := range []Test{
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
results: result.List{}, results: result.List{},
expect: []result.Variant{}, expect: []result.Variant{},
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
// Single variant, that can be entirely optimized away // Single variant, that can be entirely optimized away
location: utils.ThisLine(), location: fileutils.ThisLine(),
results: result.List{ results: result.List{
{Query: Q("a:b,c:d,*"), Tags: T("a0", "b1", "c2"), Status: result.Pass}, {Query: Q("a:b,c:d,*"), Tags: T("a0", "b1", "c2"), Status: result.Pass},
}, },
@ -44,7 +44,7 @@ func TestMinimalVariantTags(t *testing.T) {
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
// Multiple variants on the same query. // Multiple variants on the same query.
// Can also be entirely optimized away. // Can also be entirely optimized away.
location: utils.ThisLine(), location: fileutils.ThisLine(),
results: result.List{ results: result.List{
{Query: Q("a:b,c:d,*"), Tags: T("a0", "b1", "c2"), Status: result.Pass}, {Query: Q("a:b,c:d,*"), Tags: T("a0", "b1", "c2"), Status: result.Pass},
{Query: Q("a:b,c:d,*"), Tags: T("a1", "b2", "c0"), Status: result.Pass}, {Query: Q("a:b,c:d,*"), Tags: T("a1", "b2", "c0"), Status: result.Pass},
@ -53,7 +53,7 @@ func TestMinimalVariantTags(t *testing.T) {
expect: []result.Variant{T()}, expect: []result.Variant{T()},
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
// Two variants where the 1st and 2nd tag-sets are redundant. // Two variants where the 1st and 2nd tag-sets are redundant.
location: utils.ThisLine(), location: fileutils.ThisLine(),
results: result.List{ results: result.List{
{Query: Q("a:b,c:d,*"), Tags: T("a0", "b0", "c0"), Status: result.Pass}, {Query: Q("a:b,c:d,*"), Tags: T("a0", "b0", "c0"), Status: result.Pass},
{Query: Q("a:b,c:d,*"), Tags: T("a1", "b1", "c1"), Status: result.Failure}, {Query: Q("a:b,c:d,*"), Tags: T("a1", "b1", "c1"), Status: result.Failure},
@ -61,7 +61,7 @@ func TestMinimalVariantTags(t *testing.T) {
expect: []result.Variant{T("c0"), T("c1")}, expect: []result.Variant{T("c0"), T("c1")},
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
// Two variants where the 1st and 3rd tag-sets are redundant. // Two variants where the 1st and 3rd tag-sets are redundant.
location: utils.ThisLine(), location: fileutils.ThisLine(),
results: result.List{ results: result.List{
{Query: Q("a:b,c:d,*"), Tags: T("a0", "b0", "c0"), Status: result.Pass}, {Query: Q("a:b,c:d,*"), Tags: T("a0", "b0", "c0"), Status: result.Pass},
{Query: Q("a:b,c:d,*"), Tags: T("a1", "b1", "c1"), Status: result.Failure}, {Query: Q("a:b,c:d,*"), Tags: T("a1", "b1", "c1"), Status: result.Failure},
@ -71,7 +71,7 @@ func TestMinimalVariantTags(t *testing.T) {
expect: []result.Variant{T("b0"), T("b1")}, expect: []result.Variant{T("b0"), T("b1")},
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
// Two variants where the 2nd and 3rd tag-sets are redundant. // Two variants where the 2nd and 3rd tag-sets are redundant.
location: utils.ThisLine(), location: fileutils.ThisLine(),
results: result.List{ results: result.List{
{Query: Q("a:b,c:d,*"), Tags: T("a0", "b0", "c0"), Status: result.Pass}, {Query: Q("a:b,c:d,*"), Tags: T("a0", "b0", "c0"), Status: result.Pass},
{Query: Q("a:b,c:d,*"), Tags: T("a1", "b1", "c1"), Status: result.Failure}, {Query: Q("a:b,c:d,*"), Tags: T("a1", "b1", "c1"), Status: result.Failure},
@ -82,7 +82,7 @@ func TestMinimalVariantTags(t *testing.T) {
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
// Check that variants aren't optimized to expand the set of results // Check that variants aren't optimized to expand the set of results
// they target, even if results are uniform // they target, even if results are uniform
location: utils.ThisLine(), location: fileutils.ThisLine(),
results: result.List{ results: result.List{
{Query: Q("a:b,c:d0,*"), Tags: T("a0", "b0", "c0"), Status: result.Pass}, {Query: Q("a:b,c:d0,*"), Tags: T("a0", "b0", "c0"), Status: result.Pass},
{Query: Q("a:b,c:d1,*"), Tags: T("a1", "b1", "c1"), Status: result.Pass}, {Query: Q("a:b,c:d1,*"), Tags: T("a1", "b1", "c1"), Status: result.Pass},
@ -91,7 +91,7 @@ func TestMinimalVariantTags(t *testing.T) {
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
// Exercise the optimizations to skip checks on tag removals that // Exercise the optimizations to skip checks on tag removals that
// aren't found in all variants // aren't found in all variants
location: utils.ThisLine(), location: fileutils.ThisLine(),
results: result.List{ results: result.List{
{Query: Q("a:b,c:d0,*"), Tags: T("a0"), Status: result.Pass}, {Query: Q("a:b,c:d0,*"), Tags: T("a0"), Status: result.Pass},
{Query: Q("a:b,c:d1,*"), Tags: T("b0"), Status: result.Pass}, {Query: Q("a:b,c:d1,*"), Tags: T("b0"), Status: result.Pass},

View File

@ -22,7 +22,7 @@ import (
"dawn.googlesource.com/dawn/tools/src/container" "dawn.googlesource.com/dawn/tools/src/container"
"dawn.googlesource.com/dawn/tools/src/cts/query" "dawn.googlesource.com/dawn/tools/src/cts/query"
"dawn.googlesource.com/dawn/tools/src/cts/result" "dawn.googlesource.com/dawn/tools/src/cts/result"
"dawn.googlesource.com/dawn/tools/src/utils" "dawn.googlesource.com/dawn/tools/src/fileutils"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
) )
@ -325,7 +325,7 @@ func TestReplaceDuplicates(t *testing.T) {
} }
for _, test := range []Test{ for _, test := range []Test{
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
results: result.List{ results: result.List{
result.Result{Query: Q(`a`), Status: result.Pass, Duration: 1}, result.Result{Query: Q(`a`), Status: result.Pass, Duration: 1},
}, },
@ -337,7 +337,7 @@ func TestReplaceDuplicates(t *testing.T) {
}, },
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
results: result.List{ results: result.List{
result.Result{Query: Q(`a`), Status: result.Pass, Duration: 1}, result.Result{Query: Q(`a`), Status: result.Pass, Duration: 1},
result.Result{Query: Q(`a`), Status: result.Pass, Duration: 3}, result.Result{Query: Q(`a`), Status: result.Pass, Duration: 3},
@ -350,7 +350,7 @@ func TestReplaceDuplicates(t *testing.T) {
}, },
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
results: result.List{ results: result.List{
result.Result{Query: Q(`a`), Status: result.Pass}, result.Result{Query: Q(`a`), Status: result.Pass},
result.Result{Query: Q(`b`), Status: result.Pass}, result.Result{Query: Q(`b`), Status: result.Pass},
@ -364,7 +364,7 @@ func TestReplaceDuplicates(t *testing.T) {
}, },
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
results: result.List{ results: result.List{
result.Result{Query: Q(`a`), Status: result.Pass}, result.Result{Query: Q(`a`), Status: result.Pass},
result.Result{Query: Q(`b`), Status: result.Pass}, result.Result{Query: Q(`b`), Status: result.Pass},
@ -383,7 +383,7 @@ func TestReplaceDuplicates(t *testing.T) {
}, },
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
results: result.List{ results: result.List{
result.Result{Query: Q(`a`), Status: result.Failure, Duration: 1, MayExonerate: true}, result.Result{Query: Q(`a`), Status: result.Failure, Duration: 1, MayExonerate: true},
result.Result{Query: Q(`a`), Status: result.Failure, Duration: 3, MayExonerate: true}, result.Result{Query: Q(`a`), Status: result.Failure, Duration: 3, MayExonerate: true},
@ -1070,13 +1070,13 @@ func TestMerge(t *testing.T) {
} }
for _, test := range []Test{ for _, test := range []Test{
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
a: result.List{}, a: result.List{},
b: result.List{}, b: result.List{},
expect: result.List{}, expect: result.List{},
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
a: result.List{ a: result.List{
{Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Pass}, {Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Pass},
}, },
@ -1086,7 +1086,7 @@ func TestMerge(t *testing.T) {
}, },
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
a: result.List{}, a: result.List{},
b: result.List{ b: result.List{
{Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Pass}, {Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Pass},
@ -1096,7 +1096,7 @@ func TestMerge(t *testing.T) {
}, },
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
a: result.List{ a: result.List{
{Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Pass}, {Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Pass},
}, },
@ -1109,7 +1109,7 @@ func TestMerge(t *testing.T) {
}, },
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
a: result.List{ a: result.List{
{Query: Q(`suite:b:*`), Tags: T(`x`), Status: result.Pass}, {Query: Q(`suite:b:*`), Tags: T(`x`), Status: result.Pass},
}, },
@ -1122,7 +1122,7 @@ func TestMerge(t *testing.T) {
}, },
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
a: result.List{ a: result.List{
{Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Pass}, {Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Pass},
}, },
@ -1135,7 +1135,7 @@ func TestMerge(t *testing.T) {
}, },
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
a: result.List{ a: result.List{
{Query: Q(`suite:a:*`), Status: result.Pass}, {Query: Q(`suite:a:*`), Status: result.Pass},
}, },
@ -1147,7 +1147,7 @@ func TestMerge(t *testing.T) {
}, },
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
a: result.List{ a: result.List{
{Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Pass}, {Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Pass},
}, },
@ -1159,7 +1159,7 @@ func TestMerge(t *testing.T) {
}, },
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
a: result.List{ a: result.List{
{Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Crash}, {Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Crash},
}, },
@ -1171,7 +1171,7 @@ func TestMerge(t *testing.T) {
}, },
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
a: result.List{ a: result.List{
{Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Pass}, {Query: Q(`suite:a:*`), Tags: T(`x`), Status: result.Pass},
{Query: Q(`suite:b:*`), Tags: T(`x`), Status: result.Pass}, {Query: Q(`suite:b:*`), Tags: T(`x`), Status: result.Pass},
@ -1211,82 +1211,82 @@ func TestDeduplicate(t *testing.T) {
} }
for _, test := range []Test{ for _, test := range []Test{
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Pass), statuses: result.NewStatuses(result.Pass),
expect: result.Pass, expect: result.Pass,
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Abort), statuses: result.NewStatuses(result.Abort),
expect: result.Abort, expect: result.Abort,
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Failure), statuses: result.NewStatuses(result.Failure),
expect: result.Failure, expect: result.Failure,
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Skip), statuses: result.NewStatuses(result.Skip),
expect: result.Skip, expect: result.Skip,
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Crash), statuses: result.NewStatuses(result.Crash),
expect: result.Crash, expect: result.Crash,
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Slow), statuses: result.NewStatuses(result.Slow),
expect: result.Slow, expect: result.Slow,
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Unknown), statuses: result.NewStatuses(result.Unknown),
expect: result.Unknown, expect: result.Unknown,
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.RetryOnFailure), statuses: result.NewStatuses(result.RetryOnFailure),
expect: result.RetryOnFailure, expect: result.RetryOnFailure,
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Pass, result.Failure), statuses: result.NewStatuses(result.Pass, result.Failure),
expect: result.RetryOnFailure, expect: result.RetryOnFailure,
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Pass, result.Abort), statuses: result.NewStatuses(result.Pass, result.Abort),
expect: result.Abort, expect: result.Abort,
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Pass, result.Skip), statuses: result.NewStatuses(result.Pass, result.Skip),
expect: result.RetryOnFailure, expect: result.RetryOnFailure,
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Pass, result.Crash), statuses: result.NewStatuses(result.Pass, result.Crash),
expect: result.Crash, expect: result.Crash,
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Pass, result.Slow), statuses: result.NewStatuses(result.Pass, result.Slow),
expect: result.RetryOnFailure, expect: result.RetryOnFailure,
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Pass, result.Unknown), statuses: result.NewStatuses(result.Pass, result.Unknown),
expect: result.Unknown, expect: result.Unknown,
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Pass, result.RetryOnFailure), statuses: result.NewStatuses(result.Pass, result.RetryOnFailure),
expect: result.RetryOnFailure, expect: result.RetryOnFailure,
}, },
{ ////////////////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////////////////
location: utils.ThisLine(), location: fileutils.ThisLine(),
statuses: result.NewStatuses(result.Status("??"), result.Status("?!")), statuses: result.NewStatuses(result.Status("??"), result.Status("?!")),
expect: result.Unknown, expect: result.Unknown,
}, },

View File

@ -1,45 +0,0 @@
// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package fileutils contains utility functions for files
package fileutils
import (
"path/filepath"
"runtime"
)
// GoSourcePath returns the absolute path to the .go file that calls the
// function
func GoSourcePath() string {
_, filename, _, ok := runtime.Caller(1)
if !ok {
panic("No caller information")
}
path, err := filepath.Abs(filename)
if err != nil {
panic(err)
}
return path
}
// ProjectRoot returns the path to the tint project root
func ProjectRoot() string {
toolRoot := filepath.Dir(GoSourcePath())
root, err := filepath.Abs(filepath.Join(toolRoot, "../../.."))
if err != nil {
panic(err)
}
return root
}

View File

@ -1,38 +0,0 @@
// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package fileutils_test
import (
"os"
"path/filepath"
"strings"
"testing"
"dawn.googlesource.com/dawn/tools/src/fileutils"
)
func TestGoSourcePath(t *testing.T) {
p := fileutils.GoSourcePath()
if !strings.HasSuffix(p, "fileutils/fileutils_test.go") {
t.Errorf("GoSourcePath() returned %v", p)
}
}
func TestProjectRoot(t *testing.T) {
p := filepath.Join(fileutils.ProjectRoot(), "tint_overrides_with_defaults.gni")
if _, err := os.Stat(p); os.IsNotExist(err) {
t.Errorf("ProjectRoot() returned %v", p)
}
}

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package utils package fileutils
import ( import (
"fmt" "fmt"

View File

@ -12,39 +12,39 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package utils_test package fileutils_test
import ( import (
"path/filepath" "path/filepath"
"strings" "strings"
"testing" "testing"
"dawn.googlesource.com/dawn/tools/src/utils" "dawn.googlesource.com/dawn/tools/src/fileutils"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
) )
func TestThisLine(t *testing.T) { func TestThisLine(t *testing.T) {
td := utils.ThisLine() td := fileutils.ThisLine()
if !strings.HasSuffix(td, "paths_test.go:27") { if !strings.HasSuffix(td, "paths_test.go:27") {
t.Errorf("TestThisLine() returned %v", td) t.Errorf("TestThisLine() returned %v", td)
} }
} }
func TestThisDir(t *testing.T) { func TestThisDir(t *testing.T) {
td := utils.ThisDir() td := fileutils.ThisDir()
if !strings.HasSuffix(td, "utils") { if !strings.HasSuffix(td, "utils") {
t.Errorf("ThisDir() returned %v", td) t.Errorf("ThisDir() returned %v", td)
} }
} }
func TestDawnRoot(t *testing.T) { func TestDawnRoot(t *testing.T) {
dr := utils.DawnRoot() dr := fileutils.DawnRoot()
rel, err := filepath.Rel(dr, utils.ThisDir()) rel, err := filepath.Rel(dr, fileutils.ThisDir())
if err != nil { if err != nil {
t.Fatalf("%v", err) t.Fatalf("%v", err)
} }
got := filepath.ToSlash(rel) got := filepath.ToSlash(rel)
expect := `tools/src/utils` expect := `tools/src/fileutils`
if diff := cmp.Diff(got, expect); diff != "" { if diff := cmp.Diff(got, expect); diff != "" {
t.Errorf("DawnRoot() returned %v.\n%v", dr, diff) t.Errorf("DawnRoot() returned %v.\n%v", dr, diff)
} }

View File

@ -112,7 +112,7 @@ func (p *Permuter) Permute(overload *sem.Overload) ([]Permutation, error) {
// Check for hash collisions // Check for hash collisions
if existing, collision := hashes[shortHash]; collision { if existing, collision := hashes[shortHash]; collision {
return fmt.Errorf("hash '%v' collision between %v and %v\nIncrease hashLength in %v", return fmt.Errorf("hash '%v' collision between %v and %v\nIncrease hashLength in %v",
shortHash, existing, desc, fileutils.GoSourcePath()) shortHash, existing, desc, fileutils.ThisLine())
} }
hashes[shortHash] = desc hashes[shortHash] = desc
return nil return nil

View File

@ -17,9 +17,9 @@ package parser_test
import ( import (
"testing" "testing"
"dawn.googlesource.com/dawn/tools/src/fileutils"
"dawn.googlesource.com/dawn/tools/src/tint/intrinsic/ast" "dawn.googlesource.com/dawn/tools/src/tint/intrinsic/ast"
"dawn.googlesource.com/dawn/tools/src/tint/intrinsic/parser" "dawn.googlesource.com/dawn/tools/src/tint/intrinsic/parser"
"dawn.googlesource.com/dawn/tools/src/utils"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
) )
@ -36,13 +36,13 @@ func TestParser(t *testing.T) {
for _, test := range []test{ for _, test := range []test{
{ {
utils.ThisLine(), fileutils.ThisLine(),
"enum E {}", "enum E {}",
ast.AST{ ast.AST{
Enums: []ast.EnumDecl{{Name: "E"}}, Enums: []ast.EnumDecl{{Name: "E"}},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"enum E { A @attr B C }", "enum E { A @attr B C }",
ast.AST{ ast.AST{
Enums: []ast.EnumDecl{{ Enums: []ast.EnumDecl{{
@ -61,13 +61,13 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"type T", "type T",
ast.AST{ ast.AST{
Types: []ast.TypeDecl{{Name: "T"}}, Types: []ast.TypeDecl{{Name: "T"}},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"type T<A, B, C>", "type T<A, B, C>",
ast.AST{ ast.AST{
Types: []ast.TypeDecl{{ Types: []ast.TypeDecl{{
@ -80,7 +80,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"@attr type T", "@attr type T",
ast.AST{ ast.AST{
Types: []ast.TypeDecl{{ Types: []ast.TypeDecl{{
@ -91,7 +91,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"@attr_a @attr_b type T", "@attr_a @attr_b type T",
ast.AST{ ast.AST{
Types: []ast.TypeDecl{{ Types: []ast.TypeDecl{{
@ -103,7 +103,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
`@attr("a", "b") type T`, ast.AST{ `@attr("a", "b") type T`, ast.AST{
Types: []ast.TypeDecl{{ Types: []ast.TypeDecl{{
Attributes: ast.Attributes{ Attributes: ast.Attributes{
@ -113,7 +113,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
`@attr(1, "x", 2.0) type T`, ast.AST{ `@attr(1, "x", 2.0) type T`, ast.AST{
Types: []ast.TypeDecl{{ Types: []ast.TypeDecl{{
Attributes: ast.Attributes{ Attributes: ast.Attributes{
@ -123,7 +123,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"match M : A", "match M : A",
ast.AST{ ast.AST{
Matchers: []ast.MatcherDecl{{ Matchers: []ast.MatcherDecl{{
@ -136,7 +136,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"match M : A | B", "match M : A | B",
ast.AST{ ast.AST{
Matchers: []ast.MatcherDecl{{ Matchers: []ast.MatcherDecl{{
@ -150,7 +150,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"match M : A.B", "match M : A.B",
ast.AST{ ast.AST{
Matchers: []ast.MatcherDecl{{ Matchers: []ast.MatcherDecl{{
@ -163,7 +163,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"match M : A.B | B.C", "match M : A.B | B.C",
ast.AST{ ast.AST{
Matchers: []ast.MatcherDecl{{ Matchers: []ast.MatcherDecl{{
@ -177,7 +177,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"fn F()", "fn F()",
ast.AST{ ast.AST{
Builtins: []ast.IntrinsicDecl{{ Builtins: []ast.IntrinsicDecl{{
@ -187,7 +187,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"@attr fn F()", "@attr fn F()",
ast.AST{ ast.AST{
Builtins: []ast.IntrinsicDecl{{ Builtins: []ast.IntrinsicDecl{{
@ -200,7 +200,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"fn F(a)", "fn F(a)",
ast.AST{ ast.AST{
Builtins: []ast.IntrinsicDecl{{ Builtins: []ast.IntrinsicDecl{{
@ -212,7 +212,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"fn F(a: T)", "fn F(a: T)",
ast.AST{ ast.AST{
Builtins: []ast.IntrinsicDecl{{ Builtins: []ast.IntrinsicDecl{{
@ -224,7 +224,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"fn F(a, b)", "fn F(a, b)",
ast.AST{ ast.AST{
Builtins: []ast.IntrinsicDecl{{ Builtins: []ast.IntrinsicDecl{{
@ -237,7 +237,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"fn F<A : B<C> >()", "fn F<A : B<C> >()",
ast.AST{ ast.AST{
Builtins: []ast.IntrinsicDecl{{ Builtins: []ast.IntrinsicDecl{{
@ -257,7 +257,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"fn F<T>(a: X, b: Y<T>)", "fn F<T>(a: X, b: Y<T>)",
ast.AST{ ast.AST{
Builtins: []ast.IntrinsicDecl{{ Builtins: []ast.IntrinsicDecl{{
@ -276,7 +276,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"fn F() -> X", "fn F() -> X",
ast.AST{ ast.AST{
Builtins: []ast.IntrinsicDecl{{ Builtins: []ast.IntrinsicDecl{{
@ -287,7 +287,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"fn F() -> X<T>", "fn F() -> X<T>",
ast.AST{ ast.AST{
Builtins: []ast.IntrinsicDecl{{ Builtins: []ast.IntrinsicDecl{{
@ -301,7 +301,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"op F()", "op F()",
ast.AST{ ast.AST{
Operators: []ast.IntrinsicDecl{{ Operators: []ast.IntrinsicDecl{{
@ -311,7 +311,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"@attr op F()", "@attr op F()",
ast.AST{ ast.AST{
Operators: []ast.IntrinsicDecl{{ Operators: []ast.IntrinsicDecl{{
@ -324,7 +324,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"op F(a)", "op F(a)",
ast.AST{ ast.AST{
Operators: []ast.IntrinsicDecl{{ Operators: []ast.IntrinsicDecl{{
@ -336,7 +336,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"op F(@blah a)", "op F(@blah a)",
ast.AST{ ast.AST{
Operators: []ast.IntrinsicDecl{{ Operators: []ast.IntrinsicDecl{{
@ -350,7 +350,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"op F(a: T)", "op F(a: T)",
ast.AST{ ast.AST{
Operators: []ast.IntrinsicDecl{{ Operators: []ast.IntrinsicDecl{{
@ -362,7 +362,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"op F(a, b)", "op F(a, b)",
ast.AST{ ast.AST{
Operators: []ast.IntrinsicDecl{{ Operators: []ast.IntrinsicDecl{{
@ -375,7 +375,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"op F<A : B<C> >()", "op F<A : B<C> >()",
ast.AST{ ast.AST{
Operators: []ast.IntrinsicDecl{{ Operators: []ast.IntrinsicDecl{{
@ -395,7 +395,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"op F<T>(a: X, b: Y<T>)", "op F<T>(a: X, b: Y<T>)",
ast.AST{ ast.AST{
Operators: []ast.IntrinsicDecl{{ Operators: []ast.IntrinsicDecl{{
@ -414,7 +414,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"op F() -> X", "op F() -> X",
ast.AST{ ast.AST{
Operators: []ast.IntrinsicDecl{{ Operators: []ast.IntrinsicDecl{{
@ -425,7 +425,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"op F() -> X<T>", "op F() -> X<T>",
ast.AST{ ast.AST{
Operators: []ast.IntrinsicDecl{{ Operators: []ast.IntrinsicDecl{{
@ -439,7 +439,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"init F()", "init F()",
ast.AST{ ast.AST{
Initializers: []ast.IntrinsicDecl{{ Initializers: []ast.IntrinsicDecl{{
@ -449,7 +449,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"@attr init F()", "@attr init F()",
ast.AST{ ast.AST{
Initializers: []ast.IntrinsicDecl{{ Initializers: []ast.IntrinsicDecl{{
@ -462,7 +462,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"init F(a)", "init F(a)",
ast.AST{ ast.AST{
Initializers: []ast.IntrinsicDecl{{ Initializers: []ast.IntrinsicDecl{{
@ -474,7 +474,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"init F(a: T)", "init F(a: T)",
ast.AST{ ast.AST{
Initializers: []ast.IntrinsicDecl{{ Initializers: []ast.IntrinsicDecl{{
@ -486,7 +486,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"init F(a, b)", "init F(a, b)",
ast.AST{ ast.AST{
Initializers: []ast.IntrinsicDecl{{ Initializers: []ast.IntrinsicDecl{{
@ -499,7 +499,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"init F<A : B<C> >()", "init F<A : B<C> >()",
ast.AST{ ast.AST{
Initializers: []ast.IntrinsicDecl{{ Initializers: []ast.IntrinsicDecl{{
@ -519,7 +519,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"init F<T>(a: X, b: Y<T>)", "init F<T>(a: X, b: Y<T>)",
ast.AST{ ast.AST{
Initializers: []ast.IntrinsicDecl{{ Initializers: []ast.IntrinsicDecl{{
@ -538,7 +538,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"init F() -> X", "init F() -> X",
ast.AST{ ast.AST{
Initializers: []ast.IntrinsicDecl{{ Initializers: []ast.IntrinsicDecl{{
@ -549,7 +549,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"init F() -> X<T>", "init F() -> X<T>",
ast.AST{ ast.AST{
Initializers: []ast.IntrinsicDecl{{ Initializers: []ast.IntrinsicDecl{{
@ -563,7 +563,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"conv F()", "conv F()",
ast.AST{ ast.AST{
Converters: []ast.IntrinsicDecl{{ Converters: []ast.IntrinsicDecl{{
@ -573,7 +573,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"@attr conv F()", "@attr conv F()",
ast.AST{ ast.AST{
Converters: []ast.IntrinsicDecl{{ Converters: []ast.IntrinsicDecl{{
@ -586,7 +586,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"conv F(a)", "conv F(a)",
ast.AST{ ast.AST{
Converters: []ast.IntrinsicDecl{{ Converters: []ast.IntrinsicDecl{{
@ -598,7 +598,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"conv F(a: T)", "conv F(a: T)",
ast.AST{ ast.AST{
Converters: []ast.IntrinsicDecl{{ Converters: []ast.IntrinsicDecl{{
@ -610,7 +610,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"conv F(a, b)", "conv F(a, b)",
ast.AST{ ast.AST{
Converters: []ast.IntrinsicDecl{{ Converters: []ast.IntrinsicDecl{{
@ -623,7 +623,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"conv F<A : B<C> >()", "conv F<A : B<C> >()",
ast.AST{ ast.AST{
Converters: []ast.IntrinsicDecl{{ Converters: []ast.IntrinsicDecl{{
@ -643,7 +643,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"conv F<T>(a: X, b: Y<T>)", "conv F<T>(a: X, b: Y<T>)",
ast.AST{ ast.AST{
Converters: []ast.IntrinsicDecl{{ Converters: []ast.IntrinsicDecl{{
@ -662,7 +662,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"conv F() -> X", "conv F() -> X",
ast.AST{ ast.AST{
Converters: []ast.IntrinsicDecl{{ Converters: []ast.IntrinsicDecl{{
@ -673,7 +673,7 @@ func TestParser(t *testing.T) {
}}, }},
}, },
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), fileutils.ThisLine(),
"conv F() -> X<T>", "conv F() -> X<T>",
ast.AST{ ast.AST{
Converters: []ast.IntrinsicDecl{{ Converters: []ast.IntrinsicDecl{{