Source file src/simd/archsimd/_gen/specdoc/type_test.go

     1  // Copyright 2026 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package specdoc
     6  
     7  import (
     8  	"go/ast"
     9  	"go/parser"
    10  	"go/token"
    11  	"reflect"
    12  	"strings"
    13  	"testing"
    14  
    15  	"simd/archsimd/_gen/specgen/specexpr"
    16  )
    17  
    18  func mustParseExpr(t *testing.T, s string) ast.Expr {
    19  	t.Helper()
    20  	expr, err := parser.ParseExpr(s)
    21  	if err != nil {
    22  		t.Fatalf("parser.ParseExpr(%q): %v", s, err)
    23  	}
    24  	return expr
    25  }
    26  
    27  func TestParseTypeExpr(t *testing.T) {
    28  	tests := []struct {
    29  		expr string
    30  		want specexpr.Type
    31  	}{
    32  		{"int", specexpr.Basic{Base: "int", Bits: 0}},
    33  		{"uint32", specexpr.Basic{Base: "uint", Bits: 32}},
    34  		{"float64", specexpr.Basic{Base: "float", Bits: 64}},
    35  		{"bool", specexpr.Basic{Base: "bool", Bits: 0}},
    36  		{"Int32x4", specexpr.Vector{Elem: specexpr.Basic{Base: "int", Bits: 32}, Width: specexpr.Int(128)}},
    37  		{"Float64s", specexpr.Vector{Elem: specexpr.Basic{Base: "float", Bits: 64}, Width: specexpr.VW()}},
    38  		{"*int", specexpr.Pointer{Elem: specexpr.Basic{Base: "int", Bits: 0}}},
    39  		{"*Int32x4", specexpr.Pointer{Elem: specexpr.Vector{Elem: specexpr.Basic{Base: "int", Bits: 32}, Width: specexpr.Int(128)}}},
    40  		{"[]int8", specexpr.Slice{Elem: specexpr.Basic{Base: "int", Bits: 8}}},
    41  		{"[4]int32", specexpr.Array{Elem: specexpr.Basic{Base: "int", Bits: 32}, Len: specexpr.Int(4)}},
    42  		{"(int)", specexpr.Basic{Base: "int", Bits: 0}},
    43  		{"(*Int32x4)", specexpr.Pointer{Elem: specexpr.Vector{Elem: specexpr.Basic{Base: "int", Bits: 32}, Width: specexpr.Int(128)}}},
    44  	}
    45  
    46  	for _, tc := range tests {
    47  		t.Run(tc.expr, func(t *testing.T) {
    48  			expr := mustParseExpr(t, tc.expr)
    49  			got, err := parseTypeExpr(expr)
    50  			if err != nil {
    51  				t.Fatalf("parseTypeExpr(%q) unexpected error: %v", tc.expr, err)
    52  			}
    53  			if !reflect.DeepEqual(got, tc.want) {
    54  				t.Errorf("parseTypeExpr(%q) = %+v, want %+v", tc.expr, got, tc.want)
    55  			}
    56  		})
    57  	}
    58  }
    59  
    60  func TestParseTypeExprErrors(t *testing.T) {
    61  	bad := []struct {
    62  		name string
    63  		expr string
    64  		want string
    65  	}{
    66  		{"unknown identifier", "unknown", "unknown type name"},
    67  		{"any identifier", "any", "unknown type name"},
    68  		{"Mask scalar", "Mask", "unknown type name"},
    69  		{"w width form", "Int32w128", "unknown type name"},
    70  		{"pointer to invalid", "*unknown", "unknown type name"},
    71  		{"slice of invalid", "[]unknown", "unknown type name"},
    72  		{"array non-int bound identifier", "[N]int", "array bound is not an integer literal"},
    73  		{"array non-int bound expr", "[1+2]int", "array bound is not an integer literal"},
    74  		{"array negative bound", "[-1]int", "array bound is not an integer literal"},
    75  		{"array bound overflow", "[999999999999999999999999999999999999]int", "invalid array bound"},
    76  		{"array of invalid", "[4]unknown", "unknown type name"},
    77  		{"interface type", "interface{}", "unexpected type expression"},
    78  		{"struct type", "struct{}", "unexpected type expression"},
    79  		{"map type", "map[int]int", "unexpected type expression"},
    80  		{"func type", "func()", "unexpected type expression"},
    81  		{"channel type", "chan int", "unexpected type expression"},
    82  	}
    83  
    84  	for _, tc := range bad {
    85  		t.Run(tc.name, func(t *testing.T) {
    86  			expr := mustParseExpr(t, tc.expr)
    87  			got, err := parseTypeExpr(expr)
    88  			if err == nil {
    89  				t.Fatalf("parseTypeExpr(%q) = %+v, want error containing %q", tc.expr, got, tc.want)
    90  			}
    91  			if !strings.Contains(err.Error(), tc.want) {
    92  				t.Errorf("parseTypeExpr(%q) error = %q, want containing %q", tc.expr, err.Error(), tc.want)
    93  			}
    94  		})
    95  	}
    96  }
    97  
    98  func TestFieldListArgs(t *testing.T) {
    99  	fset := token.NewFileSet()
   100  	src := `package p
   101  func f(a, b int, c *Int32x4) (Int32x4, int) {}
   102  func g() (z Int32x4, err int) {}
   103  `
   104  	file, err := parser.ParseFile(fset, "test.go", src, 0)
   105  	if err != nil {
   106  		t.Fatalf("parsing test.go: %v", err)
   107  	}
   108  	fd := file.Decls[0].(*ast.FuncDecl)
   109  
   110  	in, err := fieldListArgs(fd.Type.Params)
   111  	if err != nil {
   112  		t.Fatalf("fieldListArgs params unexpected error: %v", err)
   113  	}
   114  	if len(in) != 3 {
   115  		t.Fatalf("expected 3 params, got %d", len(in))
   116  	}
   117  	if in[0].Name != "a" || in[1].Name != "b" || in[2].Name != "c" {
   118  		t.Errorf("unexpected param names: %+v", in)
   119  	}
   120  
   121  	out, err := fieldListArgs(fd.Type.Results)
   122  	if err != nil {
   123  		t.Fatalf("fieldListArgs results unexpected error: %v", err)
   124  	}
   125  	if len(out) != 2 {
   126  		t.Fatalf("expected 2 results, got %d", len(out))
   127  	}
   128  	if out[0].Name != "" || out[1].Name != "" {
   129  		t.Errorf("unexpected result names: %+v", out)
   130  	}
   131  
   132  	fdG := file.Decls[1].(*ast.FuncDecl)
   133  	outG, err := fieldListArgs(fdG.Type.Results)
   134  	if err != nil {
   135  		t.Fatalf("fieldListArgs results unexpected error: %v", err)
   136  	}
   137  	if len(outG) != 2 {
   138  		t.Fatalf("expected 2 results, got %d", len(outG))
   139  	}
   140  	if outG[0].Name != "z" || outG[1].Name != "err" {
   141  		t.Errorf("unexpected result names: %+v", outG)
   142  	}
   143  
   144  	// Test nil FieldList
   145  	nilArgs, err := fieldListArgs(nil)
   146  	if err != nil || nilArgs != nil {
   147  		t.Errorf("fieldListArgs(nil) = (%+v, %v), want (nil, nil)", nilArgs, err)
   148  	}
   149  }
   150  

View as plain text