github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/go/ssa/parameterized_test.go (about)

     1  // Copyright 2022 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 ssa
     6  
     7  import (
     8  	"go/ast"
     9  	"go/parser"
    10  	"go/token"
    11  	"go/types"
    12  	"testing"
    13  
    14  	"github.com/powerman/golang-tools/internal/typeparams"
    15  )
    16  
    17  func TestIsParameterized(t *testing.T) {
    18  	if !typeparams.Enabled {
    19  		return
    20  	}
    21  
    22  	const source = `
    23  package P
    24  type A int
    25  func (A) f()
    26  func (*A) g()
    27  
    28  type fer interface { f() }
    29  
    30  func Apply[T fer](x T) T {
    31  	x.f()
    32  	return x
    33  }
    34  
    35  type V[T any] []T
    36  func (v *V[T]) Push(x T) { *v = append(*v, x) }
    37  `
    38  
    39  	fset := token.NewFileSet()
    40  	f, err := parser.ParseFile(fset, "hello.go", source, 0)
    41  	if err != nil {
    42  		t.Fatal(err)
    43  	}
    44  
    45  	var conf types.Config
    46  	pkg, err := conf.Check("P", fset, []*ast.File{f}, nil)
    47  	if err != nil {
    48  		t.Fatal(err)
    49  	}
    50  
    51  	for _, test := range []struct {
    52  		expr string // type expression
    53  		want bool   // expected isParameterized value
    54  	}{
    55  		{"A", false},
    56  		{"*A", false},
    57  		{"error", false},
    58  		{"*error", false},
    59  		{"struct{A}", false},
    60  		{"*struct{A}", false},
    61  		{"fer", false},
    62  		{"Apply", true},
    63  		{"Apply[A]", false},
    64  		{"V", true},
    65  		{"V[A]", false},
    66  		{"*V[A]", false},
    67  		{"(*V[A]).Push", false},
    68  	} {
    69  		tv, err := types.Eval(fset, pkg, 0, test.expr)
    70  		if err != nil {
    71  			t.Errorf("Eval(%s) failed: %v", test.expr, err)
    72  		}
    73  
    74  		param := tpWalker{seen: make(map[types.Type]bool)}
    75  		if got := param.isParameterized(tv.Type); got != test.want {
    76  			t.Logf("Eval(%s) returned the type %s", test.expr, tv.Type)
    77  			t.Errorf("isParameterized(%s) = %v, want %v", test.expr, got, test.want)
    78  		}
    79  	}
    80  }