github.com/goplus/gogen@v1.16.0/builtin_test.go (about)

     1  /*
     2   Copyright 2021 The GoPlus Authors (goplus.org)
     3   Licensed under the Apache License, Version 2.0 (the "License");
     4   you may not use this file except in compliance with the License.
     5   You may obtain a copy of the License at
     6       http://www.apache.org/licenses/LICENSE-2.0
     7   Unless required by applicable law or agreed to in writing, software
     8   distributed under the License is distributed on an "AS IS" BASIS,
     9   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    10   See the License for the specific language governing permissions and
    11   limitations under the License.
    12  */
    13  
    14  package gogen
    15  
    16  import (
    17  	"bytes"
    18  	"go/ast"
    19  	"go/constant"
    20  	"go/token"
    21  	"go/types"
    22  	"log"
    23  	"math/big"
    24  	"strings"
    25  	"testing"
    26  	"unsafe"
    27  
    28  	"github.com/goplus/gogen/internal"
    29  	"github.com/goplus/gogen/internal/go/format"
    30  	"github.com/goplus/gogen/packages"
    31  )
    32  
    33  var (
    34  	gblConf = getConf()
    35  )
    36  
    37  func init() {
    38  	debugImportIox = true
    39  }
    40  
    41  func getConf() *Config {
    42  	fset := token.NewFileSet()
    43  	imp := packages.NewImporter(fset)
    44  	return &Config{Fset: fset, Importer: imp}
    45  }
    46  
    47  func TestSwitchStmtThen(t *testing.T) {
    48  	pkg := NewPackage("", "foo", nil)
    49  	cb := pkg.CB()
    50  	defer func() {
    51  		if e := recover(); e != "use None() for empty switch tag" {
    52  			t.Fatal("TestSwitchStmtThen:", e)
    53  		}
    54  	}()
    55  	cb.Switch().Then()
    56  }
    57  
    58  func TestSwitchStmtThen2(t *testing.T) {
    59  	pkg := NewPackage("", "foo", nil)
    60  	cb := pkg.CB()
    61  	defer func() {
    62  		if e := recover(); e != "switch statement has too many init statements" {
    63  			t.Fatal("TestSwitchStmtThen:", e)
    64  		}
    65  	}()
    66  	cb.Switch()
    67  	cb.emitStmt(&ast.EmptyStmt{})
    68  	cb.emitStmt(&ast.EmptyStmt{})
    69  	cb.None().Then()
    70  }
    71  
    72  func TestIfStmtThen(t *testing.T) {
    73  	pkg := NewPackage("", "foo", nil)
    74  	cb := pkg.CB()
    75  	defer func() {
    76  		if e := recover(); e != "if statement has too many init statements" {
    77  			t.Fatal("TestIfStmtThen:", e)
    78  		}
    79  	}()
    80  	cb.If()
    81  	cb.emitStmt(&ast.EmptyStmt{})
    82  	cb.emitStmt(&ast.EmptyStmt{})
    83  	cb.Val(true).Then()
    84  }
    85  
    86  func TestIfStmtElse(t *testing.T) {
    87  	pkg := NewPackage("", "foo", nil)
    88  	cb := pkg.CB()
    89  	defer func() {
    90  		if e := recover(); e != "else statement already exists" {
    91  			t.Fatal("TestIfStmtThen:", e)
    92  		}
    93  	}()
    94  	cb.If().Else().Else()
    95  }
    96  
    97  func TestCommCase(t *testing.T) {
    98  	pkg := NewPackage("", "foo", nil)
    99  	cb := pkg.CB()
   100  	cb.emitStmt(&ast.EmptyStmt{})
   101  	cb.emitStmt(&ast.EmptyStmt{})
   102  	defer func() {
   103  		if e := recover(); e != "multi commStmt in comm clause?" {
   104  			t.Fatal("TestCommCase:", e)
   105  		}
   106  	}()
   107  	c := &commCase{}
   108  	c.Then(cb)
   109  }
   110  
   111  func TestCheckGopDeps(t *testing.T) {
   112  	pkg := NewPackage("", "foo", nil)
   113  	file := pkg.CurFile()
   114  	id := file.newImport("env", "github.com/goplus/gop/env")
   115  	file.forceImport("github.com/qiniu/x/errors")
   116  	file.getDecls(pkg)
   117  	if v := file.CheckGopDeps(pkg); v != FlagDepModX {
   118  		t.Fatal("CheckGopDeps:", v)
   119  	}
   120  	id.Obj.Data = importUsed(true)
   121  	if v := file.CheckGopDeps(pkg); v != FlagDepModGop|FlagDepModX {
   122  		t.Fatal("CheckGopDeps:", v)
   123  	}
   124  }
   125  
   126  func TestInitGopPkg(t *testing.T) {
   127  	pkg := NewPackage("", "foo", nil)
   128  	pkg.Types.Scope().Insert(types.NewVar(
   129  		token.NoPos, pkg.Types, "GopPackage", types.Typ[types.Bool],
   130  	))
   131  	pkg.initGopPkg(nil, pkg.Types)
   132  }
   133  
   134  func TestCheckOverloads(t *testing.T) {
   135  	defer func() {
   136  		if e := recover(); e != "checkOverloads: should be string constant - foo" {
   137  			t.Fatal("TestCheckOverloads:", e)
   138  		}
   139  	}()
   140  	scope := types.NewScope(nil, 0, 0, "")
   141  	scope.Insert(types.NewLabel(0, nil, "foo"))
   142  	checkOverloads(scope, "bar")
   143  	checkOverloads(scope, "foo")
   144  }
   145  
   146  func TestCheckGopPkgNoop(t *testing.T) {
   147  	pkg := NewPackage("", "foo", nil)
   148  	pkg.Types.Scope().Insert(types.NewConst(
   149  		token.NoPos, pkg.Types, "GopPackage", types.Typ[types.UntypedBool], constant.MakeBool(true),
   150  	))
   151  	if _, ok := checkGopPkg(pkg); ok {
   152  		t.Fatal("checkGopPkg: ok?")
   153  	}
   154  	defer func() {
   155  		if recover() == nil {
   156  			t.Fatal("expDeps.typ: no panic?")
   157  		}
   158  	}()
   159  	var ed expDeps
   160  	tyParam := types.NewTypeParam(types.NewTypeName(0, pkg.Types, "T", nil), TyEmptyInterface)
   161  	ed.typ(tyParam)
   162  	ed.typ(types.NewUnion([]*types.Term{types.NewTerm(false, tyParam)}))
   163  	ed.typ(&unboundFuncParam{})
   164  }
   165  
   166  func TestDenoted(t *testing.T) {
   167  	if denoteRecv(&ast.SelectorExpr{Sel: ast.NewIdent("foo")}) != nil {
   168  		t.Fatal("denoteRecv: not nil?")
   169  	}
   170  	id := ast.NewIdent("foo")
   171  	obj := &ast.Object{}
   172  	setDenoted(id, obj)
   173  	if getDenoted(id) != obj {
   174  		t.Fatal("setDenoted failed")
   175  	}
   176  }
   177  
   178  func TestCheckNamed(t *testing.T) {
   179  	foo := types.NewPackage("github.com/bar/foo", "foo")
   180  	tn := types.NewTypeName(0, foo, "t", nil)
   181  	typ := types.NewNamed(tn, types.Typ[types.Int], nil)
   182  	if v, ok := checkNamed(types.NewPointer(typ)); !ok || v != typ {
   183  		t.Fatal("TestCheckNamed failed:", v, ok)
   184  	}
   185  }
   186  
   187  func TestErrMethodSig(t *testing.T) {
   188  	pkg := NewPackage("", "foo", nil)
   189  	foo := types.NewPackage("github.com/bar/foo", "foo")
   190  	tn := types.NewTypeName(0, foo, "t", nil)
   191  	recv := types.NewNamed(tn, types.Typ[types.Int], nil)
   192  	t.Run("methodToFuncSig global func", func(t *testing.T) {
   193  		fnt := types.NewSignatureType(nil, nil, nil, nil, nil, false)
   194  		fn := types.NewFunc(0, foo, "bar", fnt)
   195  		if methodToFuncSig(pkg, fn, &internal.Elem{}) != fnt {
   196  			t.Fatal("methodToFuncSig failed")
   197  		}
   198  	})
   199  	t.Run("recv not pointer", func(t *testing.T) {
   200  		defer func() {
   201  			if e := recover(); e != "recv of method github.com/bar/foo.t.bar isn't a pointer\n" {
   202  				t.Fatal("TestErrMethodSigOf:", e)
   203  			}
   204  		}()
   205  		method := types.NewSignatureType(types.NewVar(0, foo, "", recv), nil, nil, nil, nil, false)
   206  		arg := &Element{
   207  			Type: &TypeType{typ: types.NewPointer(recv)},
   208  		}
   209  		ret := &Element{
   210  			Val: &ast.SelectorExpr{Sel: ast.NewIdent("bar")},
   211  		}
   212  		pkg.cb.methodSigOf(method, memberFlagMethodToFunc, arg, ret)
   213  	})
   214  }
   215  
   216  func TestMatchOverloadNamedTypeCast(t *testing.T) {
   217  	pkg := NewPackage("", "foo", nil)
   218  	foo := types.NewPackage("github.com/bar/foo", "foo")
   219  	tn := types.NewTypeName(0, foo, "t", nil)
   220  	types.NewNamed(tn, types.Typ[types.Int], nil)
   221  	_, err := matchOverloadNamedTypeCast(pkg, tn, nil, nil, 0)
   222  	if err == nil || err.Error() != "-: typecast github.com/bar/foo.t not found" {
   223  		t.Fatal("TestMatchOverloadNamedTypeCast:", err)
   224  	}
   225  }
   226  
   227  func TestSetTypeParams(t *testing.T) {
   228  	pkg := types.NewPackage("", "")
   229  	tn := types.NewTypeName(0, pkg, "foo__1", nil)
   230  	named := types.NewNamed(tn, TyByte, nil)
   231  
   232  	setTypeParams(nil, named, &ast.TypeSpec{}, nil)
   233  }
   234  
   235  func TestOverloadNameds(t *testing.T) {
   236  	pkg := types.NewPackage("", "")
   237  	tn := types.NewTypeName(0, pkg, "foo__1", nil)
   238  	named := types.NewNamed(tn, TyByte, nil)
   239  	func() {
   240  		defer func() {
   241  			if e := recover(); e != "overload type foo__1 out of range 0..0\n" {
   242  				t.Fatal("TestOverloadFuncs:", e)
   243  			}
   244  		}()
   245  		overloadNameds(5, []*types.Named{named})
   246  	}()
   247  	func() {
   248  		defer func() {
   249  			if e := recover(); e != "overload type foo__1 exists?\n" {
   250  				t.Fatal("TestOverloadFuncs:", e)
   251  			}
   252  		}()
   253  		overloadNameds(5, []*types.Named{named, named})
   254  	}()
   255  }
   256  
   257  func TestOverloadFuncs(t *testing.T) {
   258  	pkg := types.NewPackage("", "")
   259  	fn := types.NewFunc(0, pkg, "foo__1", nil)
   260  	func() {
   261  		defer func() {
   262  			if e := recover(); e != "overload func foo__1 out of range 0..0\n" {
   263  				t.Fatal("TestOverloadFuncs:", e)
   264  			}
   265  		}()
   266  		overloadFuncs(5, []types.Object{fn})
   267  	}()
   268  	func() {
   269  		defer func() {
   270  			if e := recover(); e != "overload func foo__1 exists?\n" {
   271  				t.Fatal("TestOverloadFuncs:", e)
   272  			}
   273  		}()
   274  		overloadFuncs(5, []types.Object{fn, fn})
   275  	}()
   276  }
   277  
   278  func TestCheckTypeMethod(t *testing.T) {
   279  	scope := types.NewScope(nil, 0, 0, "")
   280  	func() {
   281  		defer func() {
   282  			if e := recover(); e != "checkTypeMethod: notFound not found or not a named type\n" {
   283  				t.Fatal("TestCheckTypeMethod:", e)
   284  			}
   285  		}()
   286  		checkTypeMethod(scope, "_notFound__method")
   287  	}()
   288  }
   289  
   290  func TestNewPosNode(t *testing.T) {
   291  	if ret := NewPosNode(1); ret.Pos() != 1 || ret.End() != 1 {
   292  		t.Fatal("NewPosNode(1): end -", ret.End())
   293  	}
   294  	if ret := NewPosNode(1, 2); ret.End() != 2 {
   295  		t.Fatal("NewPosNode(1, 2): end -", ret.End())
   296  	}
   297  }
   298  
   299  func TestGetSrcPos(t *testing.T) {
   300  	if getSrcPos(nil) != token.NoPos {
   301  		t.Fatal("TestGetSrcPos: not nopos?")
   302  	}
   303  }
   304  
   305  func TestIsTypeEx(t *testing.T) {
   306  	pkg := types.NewPackage("", "foo")
   307  	o := NewInstruction(0, pkg, "bar", lenInstr{})
   308  	if !IsTypeEx(o.Type()) {
   309  		t.Fatal("IsTypeEx: not Instruction?")
   310  	}
   311  	of := NewOverloadFunc(0, pkg, "bar")
   312  	if !IsTypeEx(of.Type()) {
   313  		t.Fatal("IsTypeEx: not OverloadFunc?")
   314  	}
   315  	if IsTypeEx(tyInt) {
   316  		t.Fatal("IsTypeEx: not tyInt?")
   317  	}
   318  }
   319  
   320  func TestGetBuiltinTI(t *testing.T) {
   321  	pkg := NewPackage("", "foo", nil)
   322  	cb := &pkg.cb
   323  	if cb.getBuiltinTI(types.NewPointer(types.Typ[0])) != nil {
   324  		t.Fatal("TestGetBuiltinTI failed")
   325  	}
   326  	tiStr := cb.getBuiltinTI(types.Typ[types.String])
   327  	sig := tiStr.lookupByName("Index")
   328  	if sig == nil || sig.Params().Len() != 1 {
   329  		t.Fatal("string.Index (Params):", sig)
   330  	}
   331  	if sig == nil || sig.Results().Len() != 1 {
   332  		t.Fatal("string.Index (Results):", sig)
   333  	}
   334  	if tsig := tiStr.lookupByName("__unknown"); tsig != nil {
   335  		t.Fatal("tsig:", tsig)
   336  	}
   337  }
   338  
   339  func TestFindMethodType(t *testing.T) {
   340  	pkg := NewPackage("", "foo", nil)
   341  	tyFile := pkg.Import("os").Ref("File").Type().(*types.Named)
   342  	sig := findMethodType(&pkg.cb, tyFile, "Gop_Enum")
   343  	if sig == nil || sig.Params().Len() != 0 {
   344  		t.Fatal("os.File.GopEnum (Params):", sig)
   345  	}
   346  	if sig == nil || sig.Results().Len() != 1 {
   347  		t.Fatal("os.File.GopEnum (Results):", sig)
   348  	}
   349  }
   350  
   351  func TestContractName(t *testing.T) {
   352  	testcases := []struct {
   353  		Contract
   354  		name string
   355  	}{
   356  		{any, "any"},
   357  		{capable, "capable"},
   358  		{lenable, "lenable"},
   359  		{makable, "makable"},
   360  		{cbool, "bool"},
   361  		{ninteger, "ninteger"},
   362  		{orderable, "orderable"},
   363  		{integer, "integer"},
   364  		{number, "number"},
   365  		{addable, "addable"},
   366  		{comparable, "comparable"},
   367  	}
   368  	for _, c := range testcases {
   369  		if c.String() != c.name {
   370  			t.Fatal("Unexpected contract name:", c.name)
   371  		}
   372  	}
   373  }
   374  
   375  func TestContract(t *testing.T) {
   376  	pkg := NewPackage("", "foo", nil)
   377  	at := types.NewPackage("foo", "foo")
   378  	foo := pkg.Import("github.com/goplus/gogen/internal/foo")
   379  	tfoo := foo.Ref("Foo").Type()
   380  	tarr := types.NewArray(tyInt, 10)
   381  	testcases := []struct {
   382  		Contract
   383  		typ    types.Type
   384  		result bool
   385  	}{
   386  		{integer, tyInt, true},
   387  		{capable, types.Typ[types.String], false},
   388  		{capable, types.NewNamed(types.NewTypeName(0, at, "bar", nil), tarr, nil), true},
   389  		{capable, types.NewNamed(types.NewTypeName(0, at, "bar", nil), types.NewPointer(tarr), nil), true},
   390  		{capable, types.NewNamed(types.NewTypeName(0, at, "bar", nil), types.Typ[types.String], nil), false},
   391  		{lenable, types.Typ[types.String], true},
   392  		{lenable, types.NewMap(tyInt, tyInt), true},
   393  		{lenable, types.NewNamed(types.NewTypeName(0, at, "bar", nil), types.Typ[types.String], nil), true},
   394  		{makable, types.NewMap(tyInt, tyInt), true},
   395  		{makable, types.NewChan(0, tyInt), true},
   396  		{makable, types.NewNamed(types.NewTypeName(0, at, "bar", nil), tyInt, nil), false},
   397  		{comparable, types.NewNamed(types.NewTypeName(0, at, "bar", nil), tyInt, nil), true},
   398  		{comparable, types.NewSlice(tyInt), false},
   399  		{comparable, types.NewMap(tyInt, tyInt), false},
   400  		{comparable, types.NewChan(0, tyInt), true},
   401  		{comparable, types.NewSignatureType(nil, nil, nil, nil, nil, false), false},
   402  		{comparable, NewTemplateSignature(nil, nil, nil, nil, false), false},
   403  		{addable, types.NewNamed(types.NewTypeName(0, at, "bar", nil), types.Typ[types.Bool], nil), false},
   404  		{addable, tfoo, true},
   405  	}
   406  	for _, c := range testcases {
   407  		if c.Match(pkg, c.typ) != c.result {
   408  			t.Fatalf("%s.Match %v expect %v\n", c.String(), c.typ, c.result)
   409  		}
   410  	}
   411  }
   412  
   413  func TestComparableTo(t *testing.T) {
   414  	tyStr := types.NewNamed(types.NewTypeName(token.NoPos, nil, "str", nil), types.Typ[types.String], nil)
   415  	cases := []struct {
   416  		v, t types.Type
   417  		ret  bool
   418  	}{
   419  		{types.Typ[types.UntypedNil], types.Typ[types.Int], false},
   420  		{types.Typ[types.UntypedComplex], types.Typ[types.Int], false},
   421  		{types.Typ[types.UntypedFloat], types.Typ[types.Bool], false},
   422  		{types.Typ[types.UntypedFloat], types.Typ[types.Complex128], true},
   423  		{types.Typ[types.String], types.Typ[types.Bool], false},
   424  		{types.Typ[types.String], types.Typ[types.String], true},
   425  		{types.Typ[types.String], tyStr, true},
   426  		{types.Typ[types.UntypedBool], types.Typ[types.Bool], true},
   427  		{types.Typ[types.Bool], types.Typ[types.UntypedBool], true},
   428  		{types.Typ[types.UntypedRune], types.Typ[types.UntypedString], false},
   429  		{types.Typ[types.Rune], types.Typ[types.UntypedString], false},
   430  		{types.Typ[types.UntypedInt], types.Typ[types.Int64], true},
   431  		{types.Typ[types.Int64], types.Typ[types.UntypedInt], true},
   432  	}
   433  	pkg := NewPackage("", "foo", gblConf)
   434  	for _, a := range cases {
   435  		av := &Element{Type: a.v}
   436  		at := &Element{Type: a.t}
   437  		if ret := ComparableTo(pkg, av, at); ret != a.ret {
   438  			t.Fatalf("Failed: ComparableTo %v => %v returns %v\n", a.v, a.t, ret)
   439  		}
   440  	}
   441  }
   442  
   443  func TestComparableTo2(t *testing.T) {
   444  	pkg := NewPackage("foo", "foo", gblConf)
   445  	methods := []*types.Func{
   446  		types.NewFunc(token.NoPos, pkg.Types, "Bar", types.NewSignatureType(nil, nil, nil, nil, nil, false)),
   447  	}
   448  	methods2 := []*types.Func{
   449  		types.NewFunc(token.NoPos, pkg.Types, "F", types.NewSignatureType(nil, nil, nil, nil, nil, false)),
   450  	}
   451  	tyInterf := types.NewInterfaceType(methods, nil).Complete()
   452  	tyInterfF := types.NewInterfaceType(methods2, nil).Complete()
   453  	bar1 := pkg.NewType("bar").InitType(pkg, tyInterf)
   454  	bar2 := pkg.NewType("bar2").InitType(pkg, tyInterf)
   455  	f1 := pkg.NewType("f1").InitType(pkg, tyInterfF)
   456  	tySlice := types.NewSlice(types.Typ[types.Int])
   457  	cases := []struct {
   458  		v, t types.Type
   459  		ret  bool
   460  	}{
   461  		{bar1, bar2, true},
   462  		{bar1, types.Typ[types.Int], false},
   463  		{types.Typ[types.Int], bar2, false},
   464  		{bar1, tySlice, false},
   465  		{tySlice, bar2, false},
   466  		{f1, bar2, false},
   467  		{types.Typ[types.UntypedNil], bar2, true},
   468  		{bar1, types.Typ[types.UntypedNil], true},
   469  		{tySlice, types.Typ[types.UntypedInt], false},
   470  		{types.Typ[types.UntypedInt], tySlice, false},
   471  		{TyEmptyInterface, types.Typ[types.UntypedInt], true},
   472  		{types.Typ[types.UntypedInt], TyEmptyInterface, true},
   473  	}
   474  	for _, a := range cases {
   475  		av := &Element{Type: a.v}
   476  		at := &Element{Type: a.t}
   477  		if ret := ComparableTo(pkg, av, at); ret != a.ret {
   478  			t.Fatalf("Failed: ComparableTo %v => %v returns %v\n", a.v, a.t, ret)
   479  		}
   480  	}
   481  	av := &Element{Type: types.Typ[types.UntypedFloat], CVal: constant.MakeFromLiteral("1e1", token.FLOAT, 0)}
   482  	at := &Element{Type: types.Typ[types.Int]}
   483  	if !ComparableTo(pkg, av, at) {
   484  		t.Fatalf("Failed: ComparableTo %v => %v returns %v\n", av, at, false)
   485  	}
   486  }
   487  
   488  func TestAssignableTo(t *testing.T) {
   489  	cases := []struct {
   490  		v, t types.Type
   491  		ret  bool
   492  	}{
   493  		{types.Typ[types.UntypedInt], types.Typ[types.Int], true},
   494  		{types.Typ[types.Int], types.Typ[types.UntypedInt], false},
   495  		{types.Typ[types.UntypedFloat], types.Typ[types.UntypedComplex], true},
   496  		{types.Typ[types.UntypedComplex], types.Typ[types.UntypedFloat], false},
   497  		{types.Typ[types.UntypedInt], types.Typ[types.UntypedFloat], true},
   498  		{types.Typ[types.UntypedFloat], types.Typ[types.UntypedInt], false},
   499  		{types.Typ[types.UntypedFloat], types.Typ[types.UntypedBool], false},
   500  		{types.Typ[types.UntypedInt], types.Typ[types.UntypedRune], false},
   501  		{types.Typ[types.UntypedFloat], types.Typ[types.Int], false},
   502  		{types.Typ[types.UntypedFloat], types.Typ[types.UntypedRune], false},
   503  		{types.Typ[types.UntypedRune], types.Typ[types.UntypedInt], true},
   504  		{types.Typ[types.UntypedRune], types.Typ[types.UntypedFloat], true},
   505  	}
   506  	pkg := NewPackage("", "foo", gblConf)
   507  	for _, a := range cases {
   508  		if ret := AssignableTo(pkg, a.v, a.t); ret != a.ret {
   509  			t.Fatalf("Failed: AssignableTo %v => %v returns %v\n", a.v, a.t, ret)
   510  		}
   511  	}
   512  	if Default(pkg, types.Typ[types.UntypedInt]) != types.Typ[types.Int] {
   513  		t.Fatal("gogen.Default failed")
   514  	}
   515  }
   516  
   517  func TestToIndex(t *testing.T) {
   518  	if toIndex('b') != 11 {
   519  		t.Fatal("toIndex('b') != 11")
   520  	}
   521  	defer func() {
   522  		if recover() != "invalid character out of [0-9,a-z]" {
   523  			t.Fatal("toIndex('!') not panic?")
   524  		}
   525  	}()
   526  	toIndex('!')
   527  }
   528  
   529  func TestCheckOverloadMethod(t *testing.T) {
   530  	sig := types.NewSignatureType(nil, nil, nil, nil, nil, false)
   531  	if _, ok := CheckOverloadMethod(sig); ok {
   532  		t.Fatal("TestCheckOverloadMethod failed:")
   533  	}
   534  }
   535  
   536  func TestIsFunc(t *testing.T) {
   537  	if IsFunc(nil) {
   538  		t.Fatal("nil is func?")
   539  	}
   540  	if !IsFunc(types.NewSignatureType(nil, nil, nil, nil, nil, false)) {
   541  		t.Fatal("func() is not func?")
   542  	}
   543  }
   544  
   545  func TestCheckUdt(t *testing.T) {
   546  	o := types.NewNamed(types.NewTypeName(token.NoPos, nil, "foo", nil), types.Typ[types.Int], nil)
   547  	var frs forRangeStmt
   548  	var cb CodeBuilder
   549  	if _, ok := frs.checkUdt(&cb, o); ok {
   550  		t.Fatal("findMethod failed: bar exists?")
   551  	}
   552  }
   553  
   554  func TestNodeInterp(t *testing.T) {
   555  	interp := nodeInterp{}
   556  	if src := interp.LoadExpr(nil); src != "" {
   557  		t.Fatal("TestNodeInterp interp.LoadExpr failed:", src)
   558  	}
   559  	if caller := getCaller(&internal.Elem{}); caller != "the function call" {
   560  		t.Fatal("TestNodeInterp getCaller failed:", caller)
   561  	}
   562  	if caller, pos := getFunExpr(nil); caller != "the closure call" || pos != token.NoPos {
   563  		t.Fatal("TestNodeInterp getGoExpr failed:", caller, pos)
   564  	}
   565  }
   566  
   567  func TestInternalStack(t *testing.T) {
   568  	var cb CodeBuilder
   569  	cb.InternalStack().Push(nil)
   570  	if cb.Get(-1) != nil {
   571  		t.Fatal("InternalStack/Get failed")
   572  	}
   573  }
   574  
   575  func TestCheckInterface(t *testing.T) {
   576  	var pkg = new(Package)
   577  	var cb = &pkg.cb
   578  	if typ, ok := cb.checkInterface(types.Typ[types.Int]); typ != nil || ok {
   579  		t.Fatal("TestCheckInterface failed:", typ, ok)
   580  	}
   581  
   582  	cb.loadNamed = func(at *Package, t *types.Named) {
   583  		t.SetUnderlying(TyEmptyInterface)
   584  	}
   585  	named := types.NewNamed(types.NewTypeName(0, nil, "foo", nil), nil, nil)
   586  	if typ, ok := cb.checkInterface(named); typ == nil || !ok {
   587  		t.Fatal("TestCheckInterface failed:", typ, ok)
   588  	}
   589  }
   590  
   591  func TestEnsureLoaded(t *testing.T) {
   592  	var pkg = new(Package)
   593  	var cb = &pkg.cb
   594  	cb.loadNamed = func(at *Package, t *types.Named) {
   595  		panic("loadNamed")
   596  	}
   597  	defer func() {
   598  		if e := recover(); e != "loadNamed" {
   599  			t.Fatal("TestEnsureLoaded failed")
   600  		}
   601  	}()
   602  	named := types.NewNamed(types.NewTypeName(0, nil, "foo", nil), nil, nil)
   603  	cb.ensureLoaded(named)
   604  }
   605  
   606  func TestGetUnderlying(t *testing.T) {
   607  	var pkg = new(Package)
   608  	var cb = &pkg.cb
   609  	cb.loadNamed = func(at *Package, t *types.Named) {
   610  		panic("loadNamed")
   611  	}
   612  	defaultLoadNamed(nil, nil)
   613  	defer func() {
   614  		if e := recover(); e != "loadNamed" {
   615  			t.Fatal("TestGetUnderlying failed")
   616  		}
   617  	}()
   618  	named := types.NewNamed(types.NewTypeName(0, nil, "foo", nil), nil, nil)
   619  	cb.getUnderlying(named)
   620  }
   621  
   622  func TestGetUnderlying2(t *testing.T) {
   623  	var pkg = new(Package)
   624  	var cb = &pkg.cb
   625  	cb.pkg = pkg
   626  	cb.loadNamed = func(at *Package, t *types.Named) {
   627  		panic("loadNamed")
   628  	}
   629  	defaultLoadNamed(nil, nil)
   630  	defer func() {
   631  		if e := recover(); e != "loadNamed" {
   632  			t.Fatal("TestGetUnderlying2 failed")
   633  		}
   634  	}()
   635  	named := types.NewNamed(types.NewTypeName(0, nil, "foo", nil), nil, nil)
   636  	getUnderlying(pkg, named)
   637  }
   638  
   639  func TestWriteFile(t *testing.T) {
   640  	pkg := NewPackage("foo", "foo", gblConf)
   641  	if WriteFile("/", pkg, "") == nil {
   642  		t.Fatal("WriteFile: no error?")
   643  	}
   644  	pkg.files[""] = &File{decls: []ast.Decl{
   645  		&ast.GenDecl{Specs: []ast.Spec{
   646  			&ast.ValueSpec{Type: &ast.Ident{}},
   647  		}},
   648  		nil,
   649  	}}
   650  	defer func() {
   651  		if e := recover(); e == nil {
   652  			t.Fatal("WriteFile: no error?")
   653  		}
   654  	}()
   655  	WriteFile("_unknown.go", pkg, "")
   656  }
   657  
   658  func TestToFields(t *testing.T) {
   659  	pkg := new(Package)
   660  	pkg.Types = types.NewPackage("", "foo")
   661  	typ := types.NewNamed(types.NewTypeName(token.NoPos, pkg.Types, "bar", nil), types.Typ[types.Int], nil)
   662  	flds := []*types.Var{
   663  		types.NewField(token.NoPos, pkg.Types, "bar", typ, true),
   664  	}
   665  	struc := types.NewStruct(flds, []string{"`bar`"})
   666  	out := toFields(pkg, struc)
   667  	if !(len(out) == 1 && out[0].Names == nil) {
   668  		t.Fatal("TestToFields failed:", out)
   669  	}
   670  }
   671  
   672  func TestToVariadic(t *testing.T) {
   673  	defer func() {
   674  		if e := recover(); e == nil {
   675  			t.Fatal("TestToVariadic: no error?")
   676  		}
   677  	}()
   678  	toVariadic(&ast.Field{Type: &ast.Ident{Name: "int"}})
   679  }
   680  
   681  func TestToType(t *testing.T) {
   682  	pkg := NewPackage("", "foo", gblConf)
   683  	toType(pkg, &unboundType{tBound: tyInt})
   684  	defer func() {
   685  		if e := recover(); e == nil {
   686  			t.Fatal("TestToType: no error?")
   687  		}
   688  	}()
   689  	toType(pkg, &unboundType{})
   690  }
   691  
   692  /*
   693  func typString(pkg *Package, t types.Type) string {
   694  	v := toType(pkg, t)
   695  	var b bytes.Buffer
   696  	err := format.Node(&b, pkg.Fset, v)
   697  	if err != nil {
   698  		panic(err)
   699  	}
   700  	return b.String()
   701  }
   702  */
   703  
   704  func TestMethodAutoProperty(t *testing.T) {
   705  	pkg := types.NewPackage("", "")
   706  	typs := []types.Type{
   707  		tyInt,
   708  		sigFuncEx(nil, nil, &TyOverloadFunc{}),
   709  		sigFuncEx(nil, nil, &TyTemplateRecvMethod{types.NewParam(0, nil, "", tyInt)}),
   710  	}
   711  	for _, typ := range typs {
   712  		if methodHasAutoProperty(typ, 0) {
   713  			t.Fatal("TestMethodAutoProperty:", typ)
   714  		}
   715  		if HasAutoProperty(typ) {
   716  			t.Fatal("HasAutoProperty:", typ)
   717  		}
   718  	}
   719  	fnt := types.NewSignatureType(nil, nil, nil, nil, nil, false)
   720  	fn := types.NewFunc(0, pkg, "foo", fnt)
   721  	sig := sigFuncEx(nil, nil, &TyOverloadFunc{Funcs: []types.Object{fn}})
   722  	if !HasAutoProperty(sig) {
   723  		t.Fatal("HasAutoProperty:", sig)
   724  	}
   725  }
   726  
   727  func TestCheckSigFuncExObjects(t *testing.T) {
   728  	pkg := types.NewPackage("", "")
   729  	objs := []types.Object{
   730  		types.NewFunc(0, pkg, "foo", types.NewSignatureType(nil, nil, nil, nil, nil, false)),
   731  		types.NewFunc(0, pkg, "bar", types.NewSignatureType(nil, nil, nil, nil, nil, false)),
   732  	}
   733  	named := types.NewNamed(types.NewTypeName(0, pkg, "named", nil), types.NewSignatureType(nil, nil, nil, nil, nil, false), nil)
   734  	fn := types.NewFunc(0, pkg, "fn", sigFuncEx(nil, nil, &TyOverloadFunc{objs}))
   735  	tests := []struct {
   736  		name  string
   737  		sig   *types.Signature
   738  		count int
   739  	}{
   740  		{"TyOverloadFunc", sigFuncEx(nil, nil, &TyOverloadFunc{objs}), 2},
   741  		{"TyOverloadMethod", sigFuncEx(nil, nil, &TyOverloadMethod{objs}), 2},
   742  		{"TyTemplateRecvMethod", sigFuncEx(nil, nil, &TyTemplateRecvMethod{types.NewParam(0, nil, "", tyInt)}), 1},
   743  		{"TyTemplateRecvMethod", sigFuncEx(nil, nil, &TyTemplateRecvMethod{fn}), 2},
   744  		{"TyOverloadNamed", sigFuncEx(nil, nil, &TyOverloadNamed{Types: []*types.Named{named}}), 1},
   745  	}
   746  	for n, test := range tests {
   747  		typ, objs := CheckSigFuncExObjects(test.sig)
   748  		if typ == nil || len(objs) != test.count {
   749  			t.Fatalf("CheckSigFuncExObjects error: %v %v", n, test.name)
   750  		}
   751  	}
   752  }
   753  
   754  func TestHasAutoProperty(t *testing.T) {
   755  	if HasAutoProperty(nil) {
   756  		t.Fatal("nil has autoprop?")
   757  	}
   758  	if !HasAutoProperty(types.NewSignatureType(nil, nil, nil, nil, nil, false)) {
   759  		t.Fatal("func() has not autoprop?")
   760  	}
   761  }
   762  
   763  func TestTypeEx(t *testing.T) {
   764  	subst := &TySubst{}
   765  	pkg := NewPackage("example.com/foo", "foo", gblConf)
   766  	tyInt := types.Typ[types.Int]
   767  	typs := []types.Type{
   768  		&refType{},
   769  		subst,
   770  		&unboundType{},
   771  		&unboundMapElemType{},
   772  		&TyOverloadFunc{},
   773  		&TyOverloadMethod{},
   774  		&TyStaticMethod{},
   775  		&TyTemplateRecvMethod{},
   776  		&TyInstruction{},
   777  		&TyOverloadNamed{Obj: types.NewTypeName(0, pkg.Types, "bar", tyInt)},
   778  		&TypeType{},
   779  		&tyTypeAsParams{},
   780  		&unboundFuncParam{},
   781  		&unboundProxyParam{},
   782  		&TemplateParamType{},
   783  		&TemplateSignature{},
   784  	}
   785  	if v := subst.String(); v != "substType{real: <nil>}" {
   786  		t.Fatal("substType.String:", v)
   787  	}
   788  	for _, typ := range typs {
   789  		func() {
   790  			log.Println("type:", typ.String())
   791  			if fex, ok := typ.(TyFuncEx); ok {
   792  				fex.funcEx()
   793  			}
   794  			if fex, ok := typ.(TyTypeEx); ok {
   795  				fex.typeEx()
   796  			}
   797  			if fex, ok := typ.(iSubstType); ok {
   798  				fex.Obj()
   799  			}
   800  			if fex, ok := typ.(OverloadType); ok {
   801  				fex.Len()
   802  				func() {
   803  					defer func() {
   804  						if e := recover(); e == nil {
   805  							t.Fatal("iOverloadType.At: no error?")
   806  						}
   807  					}()
   808  					fex.At(0)
   809  				}()
   810  			}
   811  			typ.Underlying()
   812  		}()
   813  	}
   814  	bte := &boundTypeError{tyInt, TyByte}
   815  	if bte.Error() != "boundType int => byte failed" {
   816  		t.Fatal("boundTypeError:", bte)
   817  	}
   818  	ut := &unboundType{tBound: tyInt}
   819  	defer func() {
   820  		if e := recover(); e == nil {
   821  			t.Fatal("unboundType.boundTo: no error?")
   822  		}
   823  	}()
   824  	ut.boundTo(pkg, TyByte)
   825  }
   826  
   827  func TestIsNumeric(t *testing.T) {
   828  	var cb CodeBuilder
   829  	if isNumeric(&cb, nil) {
   830  		t.Fatal("TestIsNumeric: nil isNumeric?")
   831  	}
   832  	pkg := types.NewPackage("", "foo")
   833  	typ := types.NewNamed(types.NewTypeName(token.NoPos, pkg, "MyInt", nil), types.Typ[types.Int], nil)
   834  	if !isNumeric(&cb, typ) {
   835  		t.Fatal("TestIsNumeric: MyInt not isNumeric?")
   836  	}
   837  }
   838  
   839  func TestStructFieldType(t *testing.T) {
   840  	var pkg = types.NewPackage("", "foo")
   841  	var cb CodeBuilder
   842  	subFlds := []*types.Var{
   843  		types.NewField(token.NoPos, pkg, "val", types.Typ[types.Int], false),
   844  	}
   845  	subStruc := types.NewStruct(subFlds, nil)
   846  	bar := types.NewNamed(types.NewTypeName(token.NoPos, pkg, "Bar", nil), subStruc, nil)
   847  	flds := []*types.Var{
   848  		types.NewField(token.NoPos, pkg, "Bar", bar, true),
   849  	}
   850  	struc := types.NewStruct(flds, nil)
   851  	cb.Val(nil)
   852  	if !cb.fieldRef(nil, struc, "val", nil) {
   853  		t.Fatal("structFieldType failed")
   854  	}
   855  }
   856  
   857  func TestStructFieldType2(t *testing.T) {
   858  	var pkg = types.NewPackage("", "foo")
   859  	var cb CodeBuilder
   860  	subFlds := []*types.Var{
   861  		types.NewField(token.NoPos, pkg, "val", types.Typ[types.Int], false),
   862  	}
   863  	subStruc := types.NewStruct(subFlds, nil)
   864  	bar := types.NewNamed(types.NewTypeName(token.NoPos, pkg, "Bar", nil), subStruc, nil)
   865  	flds := []*types.Var{
   866  		types.NewField(token.NoPos, pkg, "Bar", types.NewPointer(bar), true),
   867  	}
   868  	struc := types.NewStruct(flds, nil)
   869  	cb.Val(nil)
   870  	if !cb.fieldRef(nil, struc, "val", nil) {
   871  		t.Fatal("structFieldType failed")
   872  	}
   873  }
   874  
   875  func TestVarDeclEnd(t *testing.T) {
   876  	var decl VarDecl
   877  	defer func() {
   878  		if e := recover(); e == nil {
   879  			t.Fatal("TestVarDeclEnd failed: no error?")
   880  		}
   881  	}()
   882  	decl.End(nil, nil)
   883  }
   884  
   885  func TestCheckParenExpr(t *testing.T) {
   886  	x := checkParenExpr(&ast.CompositeLit{})
   887  	if _, ok := x.(*ast.ParenExpr); !ok {
   888  		t.Fatal("TestCheckParenExpr failed:", x)
   889  	}
   890  	x = checkParenExpr(&ast.SelectorExpr{X: &ast.CompositeLit{}, Sel: ast.NewIdent("sel")})
   891  	if _, ok := x.(*ast.SelectorExpr).X.(*ast.ParenExpr); !ok {
   892  		t.Fatal("TestCheckParenExpr failed:", x)
   893  	}
   894  }
   895  
   896  func TestNoFuncName(t *testing.T) {
   897  	var pkg Package
   898  	defer func() {
   899  		if e := recover(); e == nil || e.(string) != "no func name" {
   900  			t.Fatal("TestNoFuncName failed:", e)
   901  		}
   902  	}()
   903  	pkg.NewFuncWith(0, "", nil, nil)
   904  }
   905  
   906  func TestGetIdxValTypes(t *testing.T) {
   907  	pkg := NewPackage("", "foo", gblConf)
   908  	cb := pkg.CB()
   909  	intArr := types.NewArray(types.Typ[types.Int], 10)
   910  	typ := types.NewNamed(types.NewTypeName(token.NoPos, pkg.Types, "intArr", nil), intArr, nil)
   911  	kv, allowTwoValue := cb.getIdxValTypes(typ, false, nil)
   912  	if allowTwoValue || kv[0] != types.Typ[types.Int] || kv[1] != types.Typ[types.Int] {
   913  		t.Fatal("TestGetIdxValTypes failed:", kv, allowTwoValue)
   914  	}
   915  }
   916  
   917  func TestGetIdxValTypes2(t *testing.T) {
   918  	pkg := NewPackage("", "foo", gblConf)
   919  	cb := pkg.CB()
   920  	intArr := types.NewArray(types.Typ[types.Int], 10)
   921  	typ := types.NewNamed(types.NewTypeName(token.NoPos, pkg.Types, "intArr", nil), intArr, nil)
   922  	kv, allowTwoValue := cb.getIdxValTypes(types.NewPointer(typ), false, nil)
   923  	if allowTwoValue || kv[0] != types.Typ[types.Int] || kv[1] != types.Typ[types.Int] {
   924  		t.Fatal("TestGetIdxValTypes2 failed:", kv, allowTwoValue)
   925  	}
   926  }
   927  
   928  func TestGetStruct(t *testing.T) {
   929  	if getStruct(nil, types.NewPointer(tyInt)) != nil {
   930  		t.Fatal("getStruct failed: not nil?")
   931  	}
   932  }
   933  
   934  func TestGetElemType(t *testing.T) {
   935  	cval := constant.MakeFromLiteral("1.1e5", token.FLOAT, 0)
   936  	arg := types.Typ[types.UntypedFloat]
   937  	typ := getElemTypeIf(arg, &internal.Elem{CVal: cval, Type: arg})
   938  	if typ != types.Typ[types.UntypedInt] {
   939  		t.Fatal("getElemTypeIf failed")
   940  	}
   941  	typ = getElemType(&internal.Elem{CVal: cval, Type: arg})
   942  	if typ != types.Typ[types.UntypedInt] {
   943  		t.Fatal("getElemType failed")
   944  	}
   945  }
   946  
   947  func getElemType(arg *internal.Elem) types.Type {
   948  	t := arg.Type
   949  	if arg.CVal != nil && t == types.Typ[types.UntypedFloat] {
   950  		if v, ok := constant.Val(arg.CVal).(*big.Rat); ok && v.IsInt() {
   951  			return types.Typ[types.UntypedInt]
   952  		}
   953  	}
   954  	return t
   955  }
   956  
   957  func TestBoundElementType(t *testing.T) {
   958  	pkg := NewPackage("", "foo", gblConf)
   959  	elts := []*internal.Elem{
   960  		{Type: types.Typ[types.String]},
   961  		{Type: types.Typ[types.Int]},
   962  	}
   963  	typ := boundElementType(pkg, elts, 0, len(elts), 1)
   964  	if typ != TyEmptyInterface {
   965  		t.Fatal("TestBoundElementType failed:", typ)
   966  	}
   967  }
   968  
   969  func TestUnaryOp(t *testing.T) {
   970  	pkg := NewPackage("foo", "foo", gblConf)
   971  	a := constant.MakeFromLiteral("1e1", token.FLOAT, 0)
   972  	args := []*internal.Elem{
   973  		{CVal: a},
   974  	}
   975  	nega := unaryOp(pkg, token.SUB, args)
   976  	ret := doBinaryOp(nega, token.NEQ, constant.MakeInt64(-10))
   977  	if constant.BoolVal(ret) {
   978  		t.Fatal("TestUnaryOp failed:", nega)
   979  	}
   980  }
   981  
   982  func TestUnaryOpXor(t *testing.T) {
   983  	pkg := NewPackage("foo", "foo", gblConf)
   984  	type testinfo struct {
   985  		typ   types.Type
   986  		value constant.Value
   987  		check constant.Value
   988  	}
   989  	namedUint8 := types.NewNamed(types.NewTypeName(0, nil, "Uint", nil), types.Typ[types.Uint8], nil)
   990  	for _, info := range []testinfo{
   991  		{types.Typ[types.Uint8], constant.MakeInt64(0), constant.MakeUint64(255)},
   992  		{types.Typ[types.Uint16], constant.MakeInt64(1), constant.MakeUint64(65534)},
   993  		{types.Typ[types.Int8], constant.MakeInt64(0), constant.MakeInt64(-1)},
   994  		{types.Typ[types.Int16], constant.MakeInt64(1), constant.MakeInt64(-2)},
   995  		{types.Typ[types.Uint8], constant.MakeInt64(0), constant.MakeUint64(255)},
   996  		{namedUint8, constant.MakeInt64(0), constant.MakeUint64(255)},
   997  	} {
   998  		args := []*internal.Elem{
   999  			{Type: info.typ, CVal: info.value},
  1000  		}
  1001  		v := unaryOp(pkg, token.XOR, args)
  1002  		if !constant.Compare(v, token.EQL, info.check) {
  1003  			t.Fatalf("test xor failed: ^%v(%v) result %v, must %v", args[0].Type, info.value, v, info.check)
  1004  		}
  1005  	}
  1006  }
  1007  
  1008  func TestBinaryOp(t *testing.T) {
  1009  	a := constant.MakeFromLiteral("1e1", token.FLOAT, 0)
  1010  	args := []*internal.Elem{
  1011  		{CVal: a},
  1012  		{CVal: constant.MakeInt64(3)},
  1013  	}
  1014  	if cval := binaryOp(nil, token.SHR, args); constant.Val(cval) != int64(1) {
  1015  		t.Fatal("binaryOp failed:", cval)
  1016  	}
  1017  	b := constant.MakeFromLiteral("1e100", token.FLOAT, 0)
  1018  	args[1] = &internal.Elem{CVal: b}
  1019  	defer func() {
  1020  		if e := recover(); e == nil {
  1021  			t.Fatal("binaryOp failed: no error?")
  1022  		}
  1023  	}()
  1024  	binaryOp(nil, token.SHR, args)
  1025  }
  1026  
  1027  func TestBinaryOp2(t *testing.T) {
  1028  	i2 := constant.MakeImag(constant.MakeInt64(2))
  1029  	j2 := makeComplex(constant.MakeInt64(0), constant.MakeInt64(2))
  1030  	ret := doBinaryOp(i2, token.EQL, j2)
  1031  	if !constant.BoolVal(ret) {
  1032  		t.Fatal("TestBinaryOp2 failed:", ret)
  1033  	}
  1034  }
  1035  
  1036  func TestBinaryOpIssue805(t *testing.T) {
  1037  	a := constant.MakeInt64(5)
  1038  	b := constant.MakeInt64(3)
  1039  	c := constant.MakeInt64(1)
  1040  	args := []*Element{
  1041  		{CVal: a, Type: types.Typ[types.UntypedInt]},
  1042  		{CVal: b, Type: types.Typ[types.UntypedInt]},
  1043  	}
  1044  	a_div_b := binaryOp(nil, token.QUO, args)
  1045  	ret := doBinaryOp(a_div_b, token.NEQ, c)
  1046  	if constant.BoolVal(ret) {
  1047  		t.Fatal("TestBinaryOp failed:", a_div_b, c)
  1048  	}
  1049  	args2 := []*Element{
  1050  		{CVal: a},
  1051  		{CVal: b},
  1052  	}
  1053  	a_div_b2 := binaryOp(nil, token.QUO, args2)
  1054  	a_div_b3 := constant.BinaryOp(a, token.QUO, b)
  1055  	ret2 := doBinaryOp(a_div_b2, token.NEQ, a_div_b3)
  1056  	if constant.BoolVal(ret2) {
  1057  		t.Fatal("TestBinaryOp failed:", a_div_b, c)
  1058  	}
  1059  }
  1060  
  1061  func TestBuiltinCall(t *testing.T) {
  1062  	defer func() {
  1063  		if e := recover(); e == nil {
  1064  			t.Fatal("TestBuiltinCall: no error?")
  1065  		}
  1066  	}()
  1067  	builtinCall(&internal.Elem{Val: ident("undefined")}, nil)
  1068  }
  1069  
  1070  func TestUnsafe(t *testing.T) {
  1071  	pkg := NewPackage("", "foo", gblConf)
  1072  	sizeof := unsafeRef("Sizeof")
  1073  	expr := toObjectExpr(pkg, sizeof)
  1074  	if v, ok := expr.(*ast.SelectorExpr); ok {
  1075  		if id, ok := v.X.(*ast.Ident); !ok || id.Name != "unsafe" || v.Sel.Name != "Sizeof" {
  1076  			t.Fatal("toObjectExpr failed:", v.X)
  1077  		}
  1078  	} else {
  1079  		t.Fatal("TestUnsafe failed:", expr)
  1080  	}
  1081  }
  1082  
  1083  func TestTryImport(t *testing.T) {
  1084  	defer func() {
  1085  		if e := recover(); e != nil {
  1086  			t.Fatal("TestTryImport: panic?")
  1087  		}
  1088  	}()
  1089  	pkg := NewPackage("foo", "foo", gblConf)
  1090  	if pkg.TryImport("not/exist").Types != nil {
  1091  		t.Fatal("TryImport: exist?")
  1092  	}
  1093  }
  1094  
  1095  func TestUntypeBig(t *testing.T) {
  1096  	pkg := NewPackage("foo", "foo", gblConf)
  1097  	big := pkg.Import("github.com/goplus/gogen/internal/builtin")
  1098  	big.EnsureImported()
  1099  	pkg.utBigInt = big.Ref("Gop_untyped_bigint").Type().(*types.Named)
  1100  	pkg.utBigRat = big.Ref("Gop_untyped_bigrat").Type().(*types.Named)
  1101  	if ret, ok := untypeBig(pkg, constant.MakeInt64(1), pkg.utBigRat); !ok || ret.Type != pkg.utBigRat {
  1102  		t.Fatal("TestUntypeBig failed:", *ret)
  1103  	}
  1104  	val := constant.Shift(constant.MakeInt64(1), token.SHL, 256)
  1105  	if ret, ok := untypeBig(pkg, val, pkg.utBigRat); !ok || ret.Type != pkg.utBigRat {
  1106  		t.Fatal("TestUntypeBig failed:", *ret)
  1107  	}
  1108  	func() {
  1109  		defer func() {
  1110  			if e := recover(); e == nil {
  1111  				t.Fatal("TestUntypeBig failed: no error?")
  1112  			}
  1113  		}()
  1114  		untypeBig(pkg, constant.MakeBool(true), pkg.utBigRat)
  1115  	}()
  1116  	func() {
  1117  		defer func() {
  1118  			if e := recover(); e == nil {
  1119  				t.Fatal("TestUntypeBig failed: no error?")
  1120  			}
  1121  		}()
  1122  		untypeBig(pkg, constant.MakeBool(true), pkg.utBigInt)
  1123  	}()
  1124  	func() {
  1125  		defer func() {
  1126  			if e := recover(); e == nil {
  1127  				t.Fatal("pkg.Import not-found: no error?")
  1128  			}
  1129  		}()
  1130  		pkg.Import("not-found").EnsureImported()
  1131  	}()
  1132  }
  1133  
  1134  func TestIsUnbound(t *testing.T) {
  1135  	if !isUnboundTuple(types.NewTuple(types.NewParam(token.NoPos, nil, "", &unboundFuncParam{}))) {
  1136  		t.Fatal("TestIsUnbound failed")
  1137  	}
  1138  }
  1139  
  1140  func TestErrImport(t *testing.T) {
  1141  	pkg := NewPackage("github.com/x/foo", "foo", gblConf)
  1142  	_, err := importPkg(pkg, "./bar", nil)
  1143  	if err == nil || !strings.HasPrefix(err.Error(), "no required module provides package github.com/x/foo/bar;") {
  1144  		t.Fatal("importPkg failed:", err)
  1145  	}
  1146  }
  1147  
  1148  func TestErrWriteFile(t *testing.T) {
  1149  	pkg := NewPackage("", "foo", gblConf)
  1150  	pkg.Types = nil
  1151  	defer func() {
  1152  		if e := recover(); e == nil {
  1153  			t.Fatal("TestErrWriteFile: no error?")
  1154  		}
  1155  	}()
  1156  	WriteFile("_gop_autogen.go", pkg)
  1157  }
  1158  
  1159  func TestLoadExpr(t *testing.T) {
  1160  	var cb CodeBuilder
  1161  	if src, pos := cb.loadExpr(nil); src != "" || pos != token.NoPos {
  1162  		t.Fatal("TestLoadExpr failed")
  1163  	}
  1164  }
  1165  
  1166  func TestRef(t *testing.T) {
  1167  	defer func() {
  1168  		if e := recover(); e == nil {
  1169  			t.Fatal("TestRef: no error?")
  1170  		}
  1171  	}()
  1172  	pkg := &PkgRef{Types: types.NewPackage("foo", "foo")}
  1173  	pkg.Ref("bar")
  1174  }
  1175  
  1176  func TestLookupLabel(t *testing.T) {
  1177  	var cb CodeBuilder
  1178  	if _, ok := cb.LookupLabel("foo"); ok {
  1179  		t.Fatal("TestLookupLabel failed")
  1180  	}
  1181  }
  1182  
  1183  func TestVarVal(t *testing.T) {
  1184  	defer func() {
  1185  		if e := recover(); !isError(e, "VarVal: variable `unknown` not found\n") {
  1186  			t.Fatal("TestVarVal:", e)
  1187  		}
  1188  	}()
  1189  	var cb CodeBuilder
  1190  	cb.VarVal("unknown")
  1191  }
  1192  
  1193  func isError(e interface{}, msg string) bool {
  1194  	if e != nil {
  1195  		if err, ok := e.(error); ok {
  1196  			return err.Error() == msg
  1197  		}
  1198  		if err, ok := e.(string); ok {
  1199  			return err == msg
  1200  		}
  1201  	}
  1202  	return false
  1203  }
  1204  
  1205  func TestImportError(t *testing.T) {
  1206  	err := &types.Error{Msg: "foo"}
  1207  	e := &ImportError{Err: err}
  1208  	if v := e.Unwrap(); v != err {
  1209  		t.Fatal("TestImportError2:", v)
  1210  	}
  1211  }
  1212  
  1213  func TestForRangeStmtPanic(t *testing.T) {
  1214  	defer func() {
  1215  		if e := recover(); e != nil {
  1216  			t.Fatal("forRangeStmt.End panic")
  1217  		}
  1218  	}()
  1219  	var s forRangeStmt
  1220  	s.End(nil, nil)
  1221  }
  1222  
  1223  func TestNewFuncDeclPanic(t *testing.T) {
  1224  	defer func() {
  1225  		if e := recover(); e == nil {
  1226  			t.Fatal("TestNewFuncDeclPanic: not panic")
  1227  		}
  1228  	}()
  1229  	pkg := NewPackage("", "foo", gblConf)
  1230  	a := types.NewParam(token.NoPos, pkg.Types, "", types.Typ[types.Int])
  1231  	sig := types.NewSignatureType(nil, nil, nil, types.NewTuple(a), nil, false)
  1232  	pkg.NewFuncDecl(token.NoPos, "init", sig)
  1233  }
  1234  
  1235  func TestNewFuncPanic(t *testing.T) {
  1236  	getRecv(nil)
  1237  	defer func() {
  1238  		if e := recover(); e == nil {
  1239  			t.Fatal("TestNewFuncPanic: not panic")
  1240  		}
  1241  	}()
  1242  	pkg := NewPackage("", "foo", gblConf)
  1243  	a := types.NewParam(token.NoPos, pkg.Types, "", types.Typ[types.Int])
  1244  	pkg.NewFunc(nil, "init", types.NewTuple(a), nil, false)
  1245  }
  1246  
  1247  func TestSwitchStmtPanic(t *testing.T) {
  1248  	defer func() {
  1249  		if e := recover(); e != nil {
  1250  			t.Fatal("siwtchStmt.End panic")
  1251  		}
  1252  	}()
  1253  	var s switchStmt
  1254  	s.End(nil, nil)
  1255  }
  1256  
  1257  func TestCallIncDec(t *testing.T) {
  1258  	defer func() {
  1259  		if e := recover(); e == nil {
  1260  			t.Fatal("TestCallIncDec not panic")
  1261  		} else if e.(error).Error() != "-: invalid operation: ++ (non-numeric type string)" {
  1262  			t.Fatal(e)
  1263  		}
  1264  	}()
  1265  	pkg := NewPackage("", "foo", gblConf)
  1266  	if uintptr(pkg.Sizeof(tyInt)) != unsafe.Sizeof(int(0)) {
  1267  		t.Fatal("pkg.Sizeof?")
  1268  	}
  1269  	if len(pkg.Offsetsof(nil)) != 0 {
  1270  		t.Fatal("pkg.Offsetsof?")
  1271  	}
  1272  	args := []*Element{
  1273  		{Type: &refType{typ: types.Typ[types.String]}},
  1274  	}
  1275  	callIncDec(pkg, args, token.INC)
  1276  }
  1277  
  1278  func TestTypeAST(t *testing.T) {
  1279  	pkg := NewPackage("", "foo", gblConf)
  1280  	fset := token.NewFileSet()
  1281  	expr := TypeAST(pkg, TyEmptyInterface)
  1282  	b := bytes.NewBuffer(nil)
  1283  	format.Node(b, fset, expr)
  1284  	if b.String() != `interface{}` {
  1285  		t.Fatal("TypeAST failed:", b.String())
  1286  	}
  1287  }
  1288  
  1289  func TestCastFromBool(t *testing.T) {
  1290  	ret, ok := CastFromBool(nil, types.Typ[types.Uint], &Element{
  1291  		Type: types.Typ[types.UntypedBool],
  1292  		CVal: constant.MakeBool(true),
  1293  	})
  1294  	if !ok || constant.Val(ret.CVal).(int64) != 1 {
  1295  		t.Fatal("CastFromBool failed:", ret.CVal, ok)
  1296  	}
  1297  	ret, ok = CastFromBool(nil, types.Typ[types.Uint], &Element{
  1298  		Type: types.Typ[types.Bool],
  1299  		CVal: constant.MakeBool(false),
  1300  	})
  1301  	if !ok || constant.Val(ret.CVal).(int64) != 0 {
  1302  		t.Fatal("CastFromBool failed:", ret.CVal, ok)
  1303  	}
  1304  }
  1305  
  1306  func TestSubstVar(t *testing.T) {
  1307  	pkg := types.NewPackage("", "foo")
  1308  	a := types.NewParam(0, pkg, "a", types.Typ[types.Int])
  1309  	scope := pkg.Scope()
  1310  	scope.Insert(NewSubst(token.NoPos, pkg, "bar", a))
  1311  	o := Lookup(scope, "bar")
  1312  	if o != a {
  1313  		t.Fatal("TestSubstVar:", o)
  1314  	}
  1315  	_, o = LookupParent(scope, "bar", token.NoPos)
  1316  	if o != a {
  1317  		t.Fatal("TestSubstVar:", o)
  1318  	}
  1319  	scope.Insert(a)
  1320  	_, o2 := LookupParent(scope, "a", token.NoPos)
  1321  	if o != o2 {
  1322  		t.Fatal("TestSubstVar:", o2)
  1323  	}
  1324  	o2 = Lookup(scope, "a")
  1325  	if o != o2 {
  1326  		t.Fatal("TestSubstVar:", o2)
  1327  	}
  1328  	LookupParent(scope, "b", token.NoPos)
  1329  	Lookup(scope, "b")
  1330  }
  1331  
  1332  func TestToTag(t *testing.T) {
  1333  	if v := toTag(`json:"mytag"`).Value; v != "`json:\"mytag\"`" {
  1334  		t.Fatal(v)
  1335  	}
  1336  	if v := toTag("json:\"mytag\"").Value; v != "`json:\"mytag\"`" {
  1337  		t.Fatal(v)
  1338  	}
  1339  	if v := toTag("json:`mytag`").Value; v != "\"json:`mytag`\"" {
  1340  		t.Fatal(v)
  1341  	}
  1342  }
  1343  
  1344  // ----------------------------------------------------------------------------