github.com/goplus/gox@v1.14.13-0.20240308130321-6ff7f61cfae8/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 gox
    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/gox/internal"
    29  	"github.com/goplus/gox/internal/go/format"
    30  	"github.com/goplus/gox/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  		methodSigOf(method, memberFlagMethodToFunc, arg, &ast.SelectorExpr{Sel: ast.NewIdent("bar")})
   210  	})
   211  }
   212  
   213  func TestMatchOverloadNamedTypeCast(t *testing.T) {
   214  	pkg := NewPackage("", "foo", nil)
   215  	foo := types.NewPackage("github.com/bar/foo", "foo")
   216  	tn := types.NewTypeName(0, foo, "t", nil)
   217  	types.NewNamed(tn, types.Typ[types.Int], nil)
   218  	_, err := matchOverloadNamedTypeCast(pkg, tn, nil, nil, 0)
   219  	if err == nil || err.Error() != "-: typecast github.com/bar/foo.t not found" {
   220  		t.Fatal("TestMatchOverloadNamedTypeCast:", err)
   221  	}
   222  }
   223  
   224  func TestSetTypeParams(t *testing.T) {
   225  	pkg := types.NewPackage("", "")
   226  	tn := types.NewTypeName(0, pkg, "foo__1", nil)
   227  	named := types.NewNamed(tn, TyByte, nil)
   228  
   229  	setTypeParams(nil, named, &ast.TypeSpec{}, nil)
   230  }
   231  
   232  func TestOverloadNameds(t *testing.T) {
   233  	pkg := types.NewPackage("", "")
   234  	tn := types.NewTypeName(0, pkg, "foo__1", nil)
   235  	named := types.NewNamed(tn, TyByte, nil)
   236  	func() {
   237  		defer func() {
   238  			if e := recover(); e != "overload type foo__1 out of range 0..0\n" {
   239  				t.Fatal("TestOverloadFuncs:", e)
   240  			}
   241  		}()
   242  		overloadNameds(5, []*types.Named{named})
   243  	}()
   244  	func() {
   245  		defer func() {
   246  			if e := recover(); e != "overload type foo__1 exists?\n" {
   247  				t.Fatal("TestOverloadFuncs:", e)
   248  			}
   249  		}()
   250  		overloadNameds(5, []*types.Named{named, named})
   251  	}()
   252  }
   253  
   254  func TestOverloadFuncs(t *testing.T) {
   255  	pkg := types.NewPackage("", "")
   256  	fn := types.NewFunc(0, pkg, "foo__1", nil)
   257  	func() {
   258  		defer func() {
   259  			if e := recover(); e != "overload func foo__1 out of range 0..0\n" {
   260  				t.Fatal("TestOverloadFuncs:", e)
   261  			}
   262  		}()
   263  		overloadFuncs(5, []types.Object{fn})
   264  	}()
   265  	func() {
   266  		defer func() {
   267  			if e := recover(); e != "overload func foo__1 exists?\n" {
   268  				t.Fatal("TestOverloadFuncs:", e)
   269  			}
   270  		}()
   271  		overloadFuncs(5, []types.Object{fn, fn})
   272  	}()
   273  }
   274  
   275  func TestCheckTypeMethod(t *testing.T) {
   276  	scope := types.NewScope(nil, 0, 0, "")
   277  	func() {
   278  		defer func() {
   279  			if e := recover(); e != "checkTypeMethod: notFound not found or not a named type\n" {
   280  				t.Fatal("TestCheckTypeMethod:", e)
   281  			}
   282  		}()
   283  		checkTypeMethod(scope, "_notFound__method")
   284  	}()
   285  }
   286  
   287  func TestLookupFunc(t *testing.T) {
   288  	scope := types.NewScope(nil, 0, 0, "")
   289  	func() {
   290  		defer func() {
   291  			if e := recover(); e != "lookupFunc: (T not a valid method, use `(T).method` please\n" {
   292  				t.Fatal("TestLookupFunc:", e)
   293  			}
   294  		}()
   295  		lookupFunc(scope, "(T", "")
   296  	}()
   297  	func() {
   298  		defer func() {
   299  			if e := recover(); e != "lookupFunc: notFound not found\n" {
   300  				t.Fatal("TestLookupFunc:", e)
   301  			}
   302  		}()
   303  		lookupFunc(scope, "notFound", "")
   304  	}()
   305  }
   306  
   307  func TestNewPosNode(t *testing.T) {
   308  	if ret := NewPosNode(1); ret.Pos() != 1 || ret.End() != 1 {
   309  		t.Fatal("NewPosNode(1): end -", ret.End())
   310  	}
   311  	if ret := NewPosNode(1, 2); ret.End() != 2 {
   312  		t.Fatal("NewPosNode(1, 2): end -", ret.End())
   313  	}
   314  }
   315  
   316  func TestGetSrcPos(t *testing.T) {
   317  	if getSrcPos(nil) != token.NoPos {
   318  		t.Fatal("TestGetSrcPos: not nopos?")
   319  	}
   320  }
   321  
   322  func TestExportFields(t *testing.T) {
   323  	pkg := NewPackage("", "foo", nil)
   324  	fields := []*types.Var{
   325  		types.NewField(token.NoPos, pkg.Types, "Y", types.Typ[types.Int], false),
   326  		types.NewField(token.NoPos, pkg.Types, "X__u", types.Typ[types.String], false),
   327  	}
   328  	tyT := pkg.NewType("T").InitType(pkg, types.NewStruct(fields, nil))
   329  	pkg.ExportFields(tyT)
   330  	if name := pkg.cb.getFieldName(tyT, "y"); name != "Y" {
   331  		t.Fatal("getFieldName y:", name)
   332  	}
   333  	if name := pkg.cb.getFieldName(tyT, "__u"); name != "X__u" {
   334  		t.Fatal("getFieldName __u:", name)
   335  	}
   336  	if CPubName("123") != "123" {
   337  		t.Fatal("CPubName(123) failed")
   338  	}
   339  }
   340  
   341  func TestIsTypeEx(t *testing.T) {
   342  	pkg := types.NewPackage("", "foo")
   343  	o := NewInstruction(0, pkg, "bar", lenInstr{})
   344  	if !IsTypeEx(o.Type()) {
   345  		t.Fatal("IsTypeEx: not Instruction?")
   346  	}
   347  	of := NewOverloadFunc(0, pkg, "bar")
   348  	if !IsTypeEx(of.Type()) {
   349  		t.Fatal("IsTypeEx: not OverloadFunc?")
   350  	}
   351  	if IsTypeEx(tyInt) {
   352  		t.Fatal("IsTypeEx: not tyInt?")
   353  	}
   354  }
   355  
   356  func TestGetBuiltinTI(t *testing.T) {
   357  	pkg := NewPackage("", "foo", nil)
   358  	cb := &pkg.cb
   359  	if cb.getBuiltinTI(types.NewPointer(types.Typ[0])) != nil {
   360  		t.Fatal("TestGetBuiltinTI failed")
   361  	}
   362  	tiStr := cb.getBuiltinTI(types.Typ[types.String])
   363  	sig := tiStr.lookupByName("Index")
   364  	if sig == nil || sig.Params().Len() != 1 {
   365  		t.Fatal("string.Index (Params):", sig)
   366  	}
   367  	if sig == nil || sig.Results().Len() != 1 {
   368  		t.Fatal("string.Index (Results):", sig)
   369  	}
   370  	if tsig := tiStr.lookupByName("__unknown"); tsig != nil {
   371  		t.Fatal("tsig:", tsig)
   372  	}
   373  }
   374  
   375  func TestFindMethodType(t *testing.T) {
   376  	pkg := NewPackage("", "foo", nil)
   377  	tyFile := pkg.Import("os").Ref("File").Type().(*types.Named)
   378  	sig := findMethodType(&pkg.cb, tyFile, "Gop_Enum")
   379  	if sig == nil || sig.Params().Len() != 0 {
   380  		t.Fatal("os.File.GopEnum (Params):", sig)
   381  	}
   382  	if sig == nil || sig.Results().Len() != 1 {
   383  		t.Fatal("os.File.GopEnum (Results):", sig)
   384  	}
   385  }
   386  
   387  func TestContractName(t *testing.T) {
   388  	testcases := []struct {
   389  		Contract
   390  		name string
   391  	}{
   392  		{any, "any"},
   393  		{capable, "capable"},
   394  		{lenable, "lenable"},
   395  		{makable, "makable"},
   396  		{cbool, "bool"},
   397  		{ninteger, "ninteger"},
   398  		{orderable, "orderable"},
   399  		{integer, "integer"},
   400  		{number, "number"},
   401  		{addable, "addable"},
   402  		{comparable, "comparable"},
   403  	}
   404  	for _, c := range testcases {
   405  		if c.String() != c.name {
   406  			t.Fatal("Unexpected contract name:", c.name)
   407  		}
   408  	}
   409  }
   410  
   411  func TestContract(t *testing.T) {
   412  	pkg := NewPackage("", "foo", nil)
   413  	at := types.NewPackage("foo", "foo")
   414  	foo := pkg.Import("github.com/goplus/gox/internal/foo")
   415  	tfoo := foo.Ref("Foo").Type()
   416  	tarr := types.NewArray(tyInt, 10)
   417  	testcases := []struct {
   418  		Contract
   419  		typ    types.Type
   420  		result bool
   421  	}{
   422  		{integer, tyInt, true},
   423  		{capable, types.Typ[types.String], false},
   424  		{capable, types.NewNamed(types.NewTypeName(0, at, "bar", nil), tarr, nil), true},
   425  		{capable, types.NewNamed(types.NewTypeName(0, at, "bar", nil), types.NewPointer(tarr), nil), true},
   426  		{capable, types.NewNamed(types.NewTypeName(0, at, "bar", nil), types.Typ[types.String], nil), false},
   427  		{lenable, types.Typ[types.String], true},
   428  		{lenable, types.NewMap(tyInt, tyInt), true},
   429  		{lenable, types.NewNamed(types.NewTypeName(0, at, "bar", nil), types.Typ[types.String], nil), true},
   430  		{makable, types.NewMap(tyInt, tyInt), true},
   431  		{makable, types.NewChan(0, tyInt), true},
   432  		{makable, types.NewNamed(types.NewTypeName(0, at, "bar", nil), tyInt, nil), false},
   433  		{comparable, types.NewNamed(types.NewTypeName(0, at, "bar", nil), tyInt, nil), true},
   434  		{comparable, types.NewSlice(tyInt), false},
   435  		{comparable, types.NewMap(tyInt, tyInt), false},
   436  		{comparable, types.NewChan(0, tyInt), true},
   437  		{comparable, types.NewSignatureType(nil, nil, nil, nil, nil, false), false},
   438  		{comparable, NewTemplateSignature(nil, nil, nil, nil, false), false},
   439  		{addable, types.NewNamed(types.NewTypeName(0, at, "bar", nil), types.Typ[types.Bool], nil), false},
   440  		{addable, tfoo, true},
   441  	}
   442  	for _, c := range testcases {
   443  		if c.Match(pkg, c.typ) != c.result {
   444  			t.Fatalf("%s.Match %v expect %v\n", c.String(), c.typ, c.result)
   445  		}
   446  	}
   447  }
   448  
   449  func TestComparableTo(t *testing.T) {
   450  	tyStr := types.NewNamed(types.NewTypeName(token.NoPos, nil, "str", nil), types.Typ[types.String], nil)
   451  	cases := []struct {
   452  		v, t types.Type
   453  		ret  bool
   454  	}{
   455  		{types.Typ[types.UntypedNil], types.Typ[types.Int], false},
   456  		{types.Typ[types.UntypedComplex], types.Typ[types.Int], false},
   457  		{types.Typ[types.UntypedFloat], types.Typ[types.Bool], false},
   458  		{types.Typ[types.UntypedFloat], types.Typ[types.Complex128], true},
   459  		{types.Typ[types.String], types.Typ[types.Bool], false},
   460  		{types.Typ[types.String], types.Typ[types.String], true},
   461  		{types.Typ[types.String], tyStr, true},
   462  		{types.Typ[types.UntypedBool], types.Typ[types.Bool], true},
   463  		{types.Typ[types.Bool], types.Typ[types.UntypedBool], true},
   464  		{types.Typ[types.UntypedRune], types.Typ[types.UntypedString], false},
   465  		{types.Typ[types.Rune], types.Typ[types.UntypedString], false},
   466  		{types.Typ[types.UntypedInt], types.Typ[types.Int64], true},
   467  		{types.Typ[types.Int64], types.Typ[types.UntypedInt], true},
   468  	}
   469  	pkg := NewPackage("", "foo", gblConf)
   470  	for _, a := range cases {
   471  		av := &Element{Type: a.v}
   472  		at := &Element{Type: a.t}
   473  		if ret := ComparableTo(pkg, av, at); ret != a.ret {
   474  			t.Fatalf("Failed: ComparableTo %v => %v returns %v\n", a.v, a.t, ret)
   475  		}
   476  	}
   477  }
   478  
   479  func TestComparableTo2(t *testing.T) {
   480  	pkg := NewPackage("foo", "foo", gblConf)
   481  	methods := []*types.Func{
   482  		types.NewFunc(token.NoPos, pkg.Types, "Bar", types.NewSignatureType(nil, nil, nil, nil, nil, false)),
   483  	}
   484  	methods2 := []*types.Func{
   485  		types.NewFunc(token.NoPos, pkg.Types, "F", types.NewSignatureType(nil, nil, nil, nil, nil, false)),
   486  	}
   487  	tyInterf := types.NewInterfaceType(methods, nil).Complete()
   488  	tyInterfF := types.NewInterfaceType(methods2, nil).Complete()
   489  	bar1 := pkg.NewType("bar").InitType(pkg, tyInterf)
   490  	bar2 := pkg.NewType("bar2").InitType(pkg, tyInterf)
   491  	f1 := pkg.NewType("f1").InitType(pkg, tyInterfF)
   492  	tySlice := types.NewSlice(types.Typ[types.Int])
   493  	cases := []struct {
   494  		v, t types.Type
   495  		ret  bool
   496  	}{
   497  		{bar1, bar2, true},
   498  		{bar1, types.Typ[types.Int], false},
   499  		{types.Typ[types.Int], bar2, false},
   500  		{bar1, tySlice, false},
   501  		{tySlice, bar2, false},
   502  		{f1, bar2, false},
   503  		{types.Typ[types.UntypedNil], bar2, true},
   504  		{bar1, types.Typ[types.UntypedNil], true},
   505  		{tySlice, types.Typ[types.UntypedInt], false},
   506  		{types.Typ[types.UntypedInt], tySlice, false},
   507  		{TyEmptyInterface, types.Typ[types.UntypedInt], true},
   508  		{types.Typ[types.UntypedInt], TyEmptyInterface, true},
   509  	}
   510  	for _, a := range cases {
   511  		av := &Element{Type: a.v}
   512  		at := &Element{Type: a.t}
   513  		if ret := ComparableTo(pkg, av, at); ret != a.ret {
   514  			t.Fatalf("Failed: ComparableTo %v => %v returns %v\n", a.v, a.t, ret)
   515  		}
   516  	}
   517  	av := &Element{Type: types.Typ[types.UntypedFloat], CVal: constant.MakeFromLiteral("1e1", token.FLOAT, 0)}
   518  	at := &Element{Type: types.Typ[types.Int]}
   519  	if !ComparableTo(pkg, av, at) {
   520  		t.Fatalf("Failed: ComparableTo %v => %v returns %v\n", av, at, false)
   521  	}
   522  }
   523  
   524  func TestAssignableTo(t *testing.T) {
   525  	cases := []struct {
   526  		v, t types.Type
   527  		ret  bool
   528  	}{
   529  		{types.Typ[types.UntypedInt], types.Typ[types.Int], true},
   530  		{types.Typ[types.Int], types.Typ[types.UntypedInt], false},
   531  		{types.Typ[types.UntypedFloat], types.Typ[types.UntypedComplex], true},
   532  		{types.Typ[types.UntypedComplex], types.Typ[types.UntypedFloat], false},
   533  		{types.Typ[types.UntypedInt], types.Typ[types.UntypedFloat], true},
   534  		{types.Typ[types.UntypedFloat], types.Typ[types.UntypedInt], false},
   535  		{types.Typ[types.UntypedFloat], types.Typ[types.UntypedBool], false},
   536  		{types.Typ[types.UntypedInt], types.Typ[types.UntypedRune], false},
   537  		{types.Typ[types.UntypedFloat], types.Typ[types.Int], false},
   538  		{types.Typ[types.UntypedFloat], types.Typ[types.UntypedRune], false},
   539  		{types.Typ[types.UntypedRune], types.Typ[types.UntypedInt], true},
   540  		{types.Typ[types.UntypedRune], types.Typ[types.UntypedFloat], true},
   541  	}
   542  	pkg := NewPackage("", "foo", gblConf)
   543  	for _, a := range cases {
   544  		if ret := AssignableTo(pkg, a.v, a.t); ret != a.ret {
   545  			t.Fatalf("Failed: AssignableTo %v => %v returns %v\n", a.v, a.t, ret)
   546  		}
   547  	}
   548  	if Default(pkg, types.Typ[types.UntypedInt]) != types.Typ[types.Int] {
   549  		t.Fatal("gox.Default failed")
   550  	}
   551  }
   552  
   553  func TestToIndex(t *testing.T) {
   554  	if toIndex('b') != 11 {
   555  		t.Fatal("toIndex('b') != 11")
   556  	}
   557  	defer func() {
   558  		if recover() != "invalid character out of [0-9,a-z]" {
   559  			t.Fatal("toIndex('!') not panic?")
   560  		}
   561  	}()
   562  	toIndex('!')
   563  }
   564  
   565  func TestCheckOverloadMethod(t *testing.T) {
   566  	sig := types.NewSignatureType(nil, nil, nil, nil, nil, false)
   567  	if _, ok := CheckOverloadMethod(sig); ok {
   568  		t.Fatal("TestCheckOverloadMethod failed:")
   569  	}
   570  }
   571  
   572  func TestIsFunc(t *testing.T) {
   573  	if IsFunc(nil) {
   574  		t.Fatal("nil is func?")
   575  	}
   576  	if !IsFunc(types.NewSignatureType(nil, nil, nil, nil, nil, false)) {
   577  		t.Fatal("func() is not func?")
   578  	}
   579  }
   580  
   581  func TestCheckUdt(t *testing.T) {
   582  	o := types.NewNamed(types.NewTypeName(token.NoPos, nil, "foo", nil), types.Typ[types.Int], nil)
   583  	var frs forRangeStmt
   584  	var cb CodeBuilder
   585  	if _, ok := frs.checkUdt(&cb, o); ok {
   586  		t.Fatal("findMethod failed: bar exists?")
   587  	}
   588  }
   589  
   590  func TestNodeInterp(t *testing.T) {
   591  	interp := nodeInterp{}
   592  	if src := interp.LoadExpr(nil); src != "" {
   593  		t.Fatal("TestNodeInterp interp.LoadExpr failed:", src)
   594  	}
   595  	if caller := getCaller(&internal.Elem{}); caller != "the function call" {
   596  		t.Fatal("TestNodeInterp getCaller failed:", caller)
   597  	}
   598  	if caller, pos := getFunExpr(nil); caller != "the closure call" || pos != token.NoPos {
   599  		t.Fatal("TestNodeInterp getGoExpr failed:", caller, pos)
   600  	}
   601  }
   602  
   603  func TestInternalStack(t *testing.T) {
   604  	var cb CodeBuilder
   605  	cb.InternalStack().Push(nil)
   606  	if cb.Get(-1) != nil {
   607  		t.Fatal("InternalStack/Get failed")
   608  	}
   609  }
   610  
   611  func TestCheckInterface(t *testing.T) {
   612  	var pkg = new(Package)
   613  	var cb = &pkg.cb
   614  	if typ, ok := cb.checkInterface(types.Typ[types.Int]); typ != nil || ok {
   615  		t.Fatal("TestCheckInterface failed:", typ, ok)
   616  	}
   617  
   618  	cb.loadNamed = func(at *Package, t *types.Named) {
   619  		t.SetUnderlying(TyEmptyInterface)
   620  	}
   621  	named := types.NewNamed(types.NewTypeName(0, nil, "foo", nil), nil, nil)
   622  	if typ, ok := cb.checkInterface(named); typ == nil || !ok {
   623  		t.Fatal("TestCheckInterface failed:", typ, ok)
   624  	}
   625  }
   626  
   627  func TestEnsureLoaded(t *testing.T) {
   628  	var pkg = new(Package)
   629  	var cb = &pkg.cb
   630  	cb.loadNamed = func(at *Package, t *types.Named) {
   631  		panic("loadNamed")
   632  	}
   633  	defer func() {
   634  		if e := recover(); e != "loadNamed" {
   635  			t.Fatal("TestEnsureLoaded failed")
   636  		}
   637  	}()
   638  	named := types.NewNamed(types.NewTypeName(0, nil, "foo", nil), nil, nil)
   639  	cb.ensureLoaded(named)
   640  }
   641  
   642  func TestGetUnderlying(t *testing.T) {
   643  	var pkg = new(Package)
   644  	var cb = &pkg.cb
   645  	cb.loadNamed = func(at *Package, t *types.Named) {
   646  		panic("loadNamed")
   647  	}
   648  	defaultLoadNamed(nil, nil)
   649  	defer func() {
   650  		if e := recover(); e != "loadNamed" {
   651  			t.Fatal("TestGetUnderlying failed")
   652  		}
   653  	}()
   654  	named := types.NewNamed(types.NewTypeName(0, nil, "foo", nil), nil, nil)
   655  	cb.getUnderlying(named)
   656  }
   657  
   658  func TestGetUnderlying2(t *testing.T) {
   659  	var pkg = new(Package)
   660  	var cb = &pkg.cb
   661  	cb.pkg = pkg
   662  	cb.loadNamed = func(at *Package, t *types.Named) {
   663  		panic("loadNamed")
   664  	}
   665  	defaultLoadNamed(nil, nil)
   666  	defer func() {
   667  		if e := recover(); e != "loadNamed" {
   668  			t.Fatal("TestGetUnderlying2 failed")
   669  		}
   670  	}()
   671  	named := types.NewNamed(types.NewTypeName(0, nil, "foo", nil), nil, nil)
   672  	getUnderlying(pkg, named)
   673  }
   674  
   675  func TestWriteFile(t *testing.T) {
   676  	pkg := NewPackage("foo", "foo", gblConf)
   677  	if WriteFile("/", pkg, "") == nil {
   678  		t.Fatal("WriteFile: no error?")
   679  	}
   680  	pkg.files[""] = &File{decls: []ast.Decl{
   681  		&ast.GenDecl{Specs: []ast.Spec{
   682  			&ast.ValueSpec{Type: &ast.Ident{}},
   683  		}},
   684  		nil,
   685  	}}
   686  	defer func() {
   687  		if e := recover(); e == nil {
   688  			t.Fatal("WriteFile: no error?")
   689  		}
   690  	}()
   691  	WriteFile("_unknown.go", pkg, "")
   692  }
   693  
   694  func TestToFields(t *testing.T) {
   695  	pkg := new(Package)
   696  	pkg.Types = types.NewPackage("", "foo")
   697  	typ := types.NewNamed(types.NewTypeName(token.NoPos, pkg.Types, "bar", nil), types.Typ[types.Int], nil)
   698  	flds := []*types.Var{
   699  		types.NewField(token.NoPos, pkg.Types, "bar", typ, true),
   700  	}
   701  	struc := types.NewStruct(flds, []string{"`bar`"})
   702  	out := toFields(pkg, struc)
   703  	if !(len(out) == 1 && out[0].Names == nil) {
   704  		t.Fatal("TestToFields failed:", out)
   705  	}
   706  }
   707  
   708  func TestToVariadic(t *testing.T) {
   709  	defer func() {
   710  		if e := recover(); e == nil {
   711  			t.Fatal("TestToVariadic: no error?")
   712  		}
   713  	}()
   714  	toVariadic(&ast.Field{Type: &ast.Ident{Name: "int"}})
   715  }
   716  
   717  func TestToType(t *testing.T) {
   718  	pkg := NewPackage("", "foo", gblConf)
   719  	cf := NewCSignature(nil, nil, false)
   720  	if !IsCSignature(cf) {
   721  		t.Fatal("IsCSignature failed: not c function?")
   722  	}
   723  	if v := typString(pkg, cf); v != "func()" {
   724  		t.Fatal("toType failed:", v)
   725  	}
   726  	toType(pkg, &unboundType{tBound: tyInt})
   727  	defer func() {
   728  		if e := recover(); e == nil {
   729  			t.Fatal("TestToType: no error?")
   730  		}
   731  	}()
   732  	toType(pkg, &unboundType{})
   733  }
   734  
   735  func typString(pkg *Package, t types.Type) string {
   736  	v := toType(pkg, t)
   737  	var b bytes.Buffer
   738  	err := format.Node(&b, pkg.Fset, v)
   739  	if err != nil {
   740  		panic(err)
   741  	}
   742  	return b.String()
   743  }
   744  
   745  func TestMethodAutoProperty(t *testing.T) {
   746  	pkg := types.NewPackage("", "")
   747  	typs := []types.Type{
   748  		tyInt,
   749  		sigFuncEx(nil, nil, &TyOverloadFunc{}),
   750  		sigFuncEx(nil, nil, &TyTemplateRecvMethod{types.NewParam(0, nil, "", tyInt)}),
   751  	}
   752  	for _, typ := range typs {
   753  		if methodHasAutoProperty(typ, 0) {
   754  			t.Fatal("TestMethodAutoProperty:", typ)
   755  		}
   756  		if HasAutoProperty(typ) {
   757  			t.Fatal("HasAutoProperty:", typ)
   758  		}
   759  	}
   760  	fnt := types.NewSignatureType(nil, nil, nil, nil, nil, false)
   761  	fn := types.NewFunc(0, pkg, "foo", fnt)
   762  	sig := sigFuncEx(nil, nil, &TyOverloadFunc{Funcs: []types.Object{fn}})
   763  	if !HasAutoProperty(sig) {
   764  		t.Fatal("HasAutoProperty:", sig)
   765  	}
   766  }
   767  
   768  func TestCheckSigFuncExObjects(t *testing.T) {
   769  	pkg := types.NewPackage("", "")
   770  	objs := []types.Object{
   771  		types.NewFunc(0, pkg, "foo", types.NewSignatureType(nil, nil, nil, nil, nil, false)),
   772  		types.NewFunc(0, pkg, "bar", types.NewSignatureType(nil, nil, nil, nil, nil, false)),
   773  	}
   774  	named := types.NewNamed(types.NewTypeName(0, pkg, "named", nil), types.NewSignatureType(nil, nil, nil, nil, nil, false), nil)
   775  	fn := types.NewFunc(0, pkg, "fn", sigFuncEx(nil, nil, &TyOverloadFunc{objs}))
   776  	tests := []struct {
   777  		name  string
   778  		sig   *types.Signature
   779  		count int
   780  	}{
   781  		{"TyOverloadFunc", sigFuncEx(nil, nil, &TyOverloadFunc{objs}), 2},
   782  		{"TyOverloadMethod", sigFuncEx(nil, nil, &TyOverloadMethod{objs}), 2},
   783  		{"TyTemplateRecvMethod", sigFuncEx(nil, nil, &TyTemplateRecvMethod{types.NewParam(0, nil, "", tyInt)}), 1},
   784  		{"TyTemplateRecvMethod", sigFuncEx(nil, nil, &TyTemplateRecvMethod{fn}), 2},
   785  		{"TyOverloadNamed", sigFuncEx(nil, nil, &TyOverloadNamed{Types: []*types.Named{named}}), 1},
   786  	}
   787  	for n, test := range tests {
   788  		typ, objs := CheckSigFuncExObjects(test.sig)
   789  		if typ == nil || len(objs) != test.count {
   790  			t.Fatalf("CheckSigFuncExObjects error: %v %v", n, test.name)
   791  		}
   792  	}
   793  }
   794  
   795  func TestHasAutoProperty(t *testing.T) {
   796  	if HasAutoProperty(nil) {
   797  		t.Fatal("nil has autoprop?")
   798  	}
   799  	if !HasAutoProperty(types.NewSignatureType(nil, nil, nil, nil, nil, false)) {
   800  		t.Fatal("func() has not autoprop?")
   801  	}
   802  }
   803  
   804  func TestTypeEx(t *testing.T) {
   805  	subst := &TySubst{}
   806  	bfReft := &bfRefType{typ: tyInt}
   807  	if typ, ok := DerefType(bfReft); !ok || typ != tyInt {
   808  		t.Fatal("TestDerefType failed")
   809  	}
   810  	pkg := NewPackage("example.com/foo", "foo", gblConf)
   811  	tyInt := types.Typ[types.Int]
   812  	typs := []types.Type{
   813  		&refType{},
   814  		subst,
   815  		bfReft,
   816  		&unboundType{},
   817  		&unboundMapElemType{},
   818  		&TyOverloadFunc{},
   819  		&TyOverloadMethod{},
   820  		&TyTemplateRecvMethod{},
   821  		&TyInstruction{},
   822  		&TyOverloadNamed{Obj: types.NewTypeName(0, pkg.Types, "bar", tyInt)},
   823  		&TypeType{},
   824  		&tyTypeAsParams{},
   825  		&unboundFuncParam{},
   826  		&unboundProxyParam{},
   827  		&TemplateParamType{},
   828  		&TemplateSignature{},
   829  	}
   830  	if v := bfReft.String(); v != "bfRefType{typ: int:0 off: 0}" {
   831  		t.Fatal("bfRefType.String:", v)
   832  	}
   833  	if v := subst.String(); v != "substType{real: <nil>}" {
   834  		t.Fatal("substType.String:", v)
   835  	}
   836  	for _, typ := range typs {
   837  		func() {
   838  			log.Println("type:", typ.String())
   839  			if fex, ok := typ.(TyFuncEx); ok {
   840  				fex.funcEx()
   841  			}
   842  			if fex, ok := typ.(TyTypeEx); ok {
   843  				fex.typeEx()
   844  			}
   845  			if fex, ok := typ.(iSubstType); ok {
   846  				fex.Obj()
   847  			}
   848  			if fex, ok := typ.(OverloadType); ok {
   849  				fex.Len()
   850  				func() {
   851  					defer func() {
   852  						if e := recover(); e == nil {
   853  							t.Fatal("iOverloadType.At: no error?")
   854  						}
   855  					}()
   856  					fex.At(0)
   857  				}()
   858  			}
   859  			typ.Underlying()
   860  		}()
   861  	}
   862  	bte := &boundTypeError{tyInt, TyByte}
   863  	if bte.Error() != "boundType int => byte failed" {
   864  		t.Fatal("boundTypeError:", bte)
   865  	}
   866  	ut := &unboundType{tBound: tyInt}
   867  	defer func() {
   868  		if e := recover(); e == nil {
   869  			t.Fatal("unboundType.boundTo: no error?")
   870  		}
   871  	}()
   872  	ut.boundTo(pkg, TyByte)
   873  }
   874  
   875  func TestIsNumeric(t *testing.T) {
   876  	var cb CodeBuilder
   877  	if isNumeric(&cb, nil) {
   878  		t.Fatal("TestIsNumeric: nil isNumeric?")
   879  	}
   880  	pkg := types.NewPackage("", "foo")
   881  	typ := types.NewNamed(types.NewTypeName(token.NoPos, pkg, "MyInt", nil), types.Typ[types.Int], nil)
   882  	if !isNumeric(&cb, typ) {
   883  		t.Fatal("TestIsNumeric: MyInt not isNumeric?")
   884  	}
   885  }
   886  
   887  func TestStructFieldType(t *testing.T) {
   888  	var pkg = types.NewPackage("", "foo")
   889  	var cb CodeBuilder
   890  	subFlds := []*types.Var{
   891  		types.NewField(token.NoPos, pkg, "val", types.Typ[types.Int], false),
   892  	}
   893  	subStruc := types.NewStruct(subFlds, nil)
   894  	bar := types.NewNamed(types.NewTypeName(token.NoPos, pkg, "Bar", nil), subStruc, nil)
   895  	flds := []*types.Var{
   896  		types.NewField(token.NoPos, pkg, "Bar", bar, true),
   897  	}
   898  	struc := types.NewStruct(flds, nil)
   899  	cb.Val(nil)
   900  	if !cb.fieldRef(nil, struc, "val", nil) {
   901  		t.Fatal("structFieldType failed")
   902  	}
   903  }
   904  
   905  func TestStructFieldType2(t *testing.T) {
   906  	var pkg = types.NewPackage("", "foo")
   907  	var cb CodeBuilder
   908  	subFlds := []*types.Var{
   909  		types.NewField(token.NoPos, pkg, "val", types.Typ[types.Int], false),
   910  	}
   911  	subStruc := types.NewStruct(subFlds, nil)
   912  	bar := types.NewNamed(types.NewTypeName(token.NoPos, pkg, "Bar", nil), subStruc, nil)
   913  	flds := []*types.Var{
   914  		types.NewField(token.NoPos, pkg, "Bar", types.NewPointer(bar), true),
   915  	}
   916  	struc := types.NewStruct(flds, nil)
   917  	cb.Val(nil)
   918  	if !cb.fieldRef(nil, struc, "val", nil) {
   919  		t.Fatal("structFieldType failed")
   920  	}
   921  }
   922  
   923  func TestVarDeclEnd(t *testing.T) {
   924  	var decl VarDecl
   925  	defer func() {
   926  		if e := recover(); e == nil {
   927  			t.Fatal("TestVarDeclEnd failed: no error?")
   928  		}
   929  	}()
   930  	decl.End(nil, nil)
   931  }
   932  
   933  func TestCheckParenExpr(t *testing.T) {
   934  	x := checkParenExpr(&ast.CompositeLit{})
   935  	if _, ok := x.(*ast.ParenExpr); !ok {
   936  		t.Fatal("TestCheckParenExpr failed:", x)
   937  	}
   938  	x = checkParenExpr(&ast.SelectorExpr{X: &ast.CompositeLit{}, Sel: ast.NewIdent("sel")})
   939  	if _, ok := x.(*ast.SelectorExpr).X.(*ast.ParenExpr); !ok {
   940  		t.Fatal("TestCheckParenExpr failed:", x)
   941  	}
   942  }
   943  
   944  func TestNoFuncName(t *testing.T) {
   945  	var pkg Package
   946  	defer func() {
   947  		if e := recover(); e == nil || e.(string) != "no func name" {
   948  			t.Fatal("TestNoFuncName failed:", e)
   949  		}
   950  	}()
   951  	pkg.NewFuncWith(0, "", nil, nil)
   952  }
   953  
   954  func TestGetIdxValTypes(t *testing.T) {
   955  	pkg := NewPackage("", "foo", gblConf)
   956  	cb := pkg.CB()
   957  	intArr := types.NewArray(types.Typ[types.Int], 10)
   958  	typ := types.NewNamed(types.NewTypeName(token.NoPos, pkg.Types, "intArr", nil), intArr, nil)
   959  	kv, allowTwoValue := cb.getIdxValTypes(typ, false, nil)
   960  	if allowTwoValue || kv[0] != types.Typ[types.Int] || kv[1] != types.Typ[types.Int] {
   961  		t.Fatal("TestGetIdxValTypes failed:", kv, allowTwoValue)
   962  	}
   963  }
   964  
   965  func TestGetIdxValTypes2(t *testing.T) {
   966  	pkg := NewPackage("", "foo", gblConf)
   967  	cb := pkg.CB()
   968  	intArr := types.NewArray(types.Typ[types.Int], 10)
   969  	typ := types.NewNamed(types.NewTypeName(token.NoPos, pkg.Types, "intArr", nil), intArr, nil)
   970  	kv, allowTwoValue := cb.getIdxValTypes(types.NewPointer(typ), false, nil)
   971  	if allowTwoValue || kv[0] != types.Typ[types.Int] || kv[1] != types.Typ[types.Int] {
   972  		t.Fatal("TestGetIdxValTypes2 failed:", kv, allowTwoValue)
   973  	}
   974  }
   975  
   976  func TestGetStruct(t *testing.T) {
   977  	if getStruct(nil, types.NewPointer(tyInt)) != nil {
   978  		t.Fatal("getStruct failed: not nil?")
   979  	}
   980  }
   981  
   982  func TestGetElemType(t *testing.T) {
   983  	cval := constant.MakeFromLiteral("1.1e5", token.FLOAT, 0)
   984  	arg := types.Typ[types.UntypedFloat]
   985  	typ := getElemTypeIf(arg, &internal.Elem{CVal: cval, Type: arg})
   986  	if typ != types.Typ[types.UntypedInt] {
   987  		t.Fatal("getElemTypeIf failed")
   988  	}
   989  	typ = getElemType(&internal.Elem{CVal: cval, Type: arg})
   990  	if typ != types.Typ[types.UntypedInt] {
   991  		t.Fatal("getElemType failed")
   992  	}
   993  }
   994  
   995  func getElemType(arg *internal.Elem) types.Type {
   996  	t := arg.Type
   997  	if arg.CVal != nil && t == types.Typ[types.UntypedFloat] {
   998  		if v, ok := constant.Val(arg.CVal).(*big.Rat); ok && v.IsInt() {
   999  			return types.Typ[types.UntypedInt]
  1000  		}
  1001  	}
  1002  	return t
  1003  }
  1004  
  1005  func TestBoundElementType(t *testing.T) {
  1006  	pkg := NewPackage("", "foo", gblConf)
  1007  	elts := []*internal.Elem{
  1008  		{Type: types.Typ[types.String]},
  1009  		{Type: types.Typ[types.Int]},
  1010  	}
  1011  	typ := boundElementType(pkg, elts, 0, len(elts), 1)
  1012  	if typ != TyEmptyInterface {
  1013  		t.Fatal("TestBoundElementType failed:", typ)
  1014  	}
  1015  }
  1016  
  1017  func TestUnaryOp(t *testing.T) {
  1018  	pkg := NewPackage("foo", "foo", gblConf)
  1019  	a := constant.MakeFromLiteral("1e1", token.FLOAT, 0)
  1020  	args := []*internal.Elem{
  1021  		{CVal: a},
  1022  	}
  1023  	nega := unaryOp(pkg, token.SUB, args)
  1024  	ret := doBinaryOp(nega, token.NEQ, constant.MakeInt64(-10))
  1025  	if constant.BoolVal(ret) {
  1026  		t.Fatal("TestUnaryOp failed:", nega)
  1027  	}
  1028  }
  1029  
  1030  func TestUnaryOpXor(t *testing.T) {
  1031  	pkg := NewPackage("foo", "foo", gblConf)
  1032  	type testinfo struct {
  1033  		typ   types.Type
  1034  		value constant.Value
  1035  		check constant.Value
  1036  	}
  1037  	namedUint8 := types.NewNamed(types.NewTypeName(0, nil, "Uint", nil), types.Typ[types.Uint8], nil)
  1038  	for _, info := range []testinfo{
  1039  		{types.Typ[types.Uint8], constant.MakeInt64(0), constant.MakeUint64(255)},
  1040  		{types.Typ[types.Uint16], constant.MakeInt64(1), constant.MakeUint64(65534)},
  1041  		{types.Typ[types.Int8], constant.MakeInt64(0), constant.MakeInt64(-1)},
  1042  		{types.Typ[types.Int16], constant.MakeInt64(1), constant.MakeInt64(-2)},
  1043  		{types.Typ[types.Uint8], constant.MakeInt64(0), constant.MakeUint64(255)},
  1044  		{namedUint8, constant.MakeInt64(0), constant.MakeUint64(255)},
  1045  	} {
  1046  		args := []*internal.Elem{
  1047  			{Type: info.typ, CVal: info.value},
  1048  		}
  1049  		v := unaryOp(pkg, token.XOR, args)
  1050  		if !constant.Compare(v, token.EQL, info.check) {
  1051  			t.Fatalf("test xor failed: ^%v(%v) result %v, must %v", args[0].Type, info.value, v, info.check)
  1052  		}
  1053  	}
  1054  }
  1055  
  1056  func TestBinaryOp(t *testing.T) {
  1057  	a := constant.MakeFromLiteral("1e1", token.FLOAT, 0)
  1058  	args := []*internal.Elem{
  1059  		{CVal: a},
  1060  		{CVal: constant.MakeInt64(3)},
  1061  	}
  1062  	if cval := binaryOp(nil, token.SHR, args); constant.Val(cval) != int64(1) {
  1063  		t.Fatal("binaryOp failed:", cval)
  1064  	}
  1065  	b := constant.MakeFromLiteral("1e100", token.FLOAT, 0)
  1066  	args[1] = &internal.Elem{CVal: b}
  1067  	defer func() {
  1068  		if e := recover(); e == nil {
  1069  			t.Fatal("binaryOp failed: no error?")
  1070  		}
  1071  	}()
  1072  	binaryOp(nil, token.SHR, args)
  1073  }
  1074  
  1075  func TestBinaryOp2(t *testing.T) {
  1076  	i2 := constant.MakeImag(constant.MakeInt64(2))
  1077  	j2 := makeComplex(constant.MakeInt64(0), constant.MakeInt64(2))
  1078  	ret := doBinaryOp(i2, token.EQL, j2)
  1079  	if !constant.BoolVal(ret) {
  1080  		t.Fatal("TestBinaryOp2 failed:", ret)
  1081  	}
  1082  }
  1083  
  1084  func TestBinaryOpIssue805(t *testing.T) {
  1085  	a := constant.MakeInt64(5)
  1086  	b := constant.MakeInt64(3)
  1087  	c := constant.MakeInt64(1)
  1088  	args := []*Element{
  1089  		{CVal: a, Type: types.Typ[types.UntypedInt]},
  1090  		{CVal: b, Type: types.Typ[types.UntypedInt]},
  1091  	}
  1092  	a_div_b := binaryOp(nil, token.QUO, args)
  1093  	ret := doBinaryOp(a_div_b, token.NEQ, c)
  1094  	if constant.BoolVal(ret) {
  1095  		t.Fatal("TestBinaryOp failed:", a_div_b, c)
  1096  	}
  1097  	args2 := []*Element{
  1098  		{CVal: a},
  1099  		{CVal: b},
  1100  	}
  1101  	a_div_b2 := binaryOp(nil, token.QUO, args2)
  1102  	a_div_b3 := constant.BinaryOp(a, token.QUO, b)
  1103  	ret2 := doBinaryOp(a_div_b2, token.NEQ, a_div_b3)
  1104  	if constant.BoolVal(ret2) {
  1105  		t.Fatal("TestBinaryOp failed:", a_div_b, c)
  1106  	}
  1107  }
  1108  
  1109  func TestBuiltinCall(t *testing.T) {
  1110  	defer func() {
  1111  		if e := recover(); e == nil {
  1112  			t.Fatal("TestBuiltinCall: no error?")
  1113  		}
  1114  	}()
  1115  	builtinCall(&internal.Elem{Val: ident("undefined")}, nil)
  1116  }
  1117  
  1118  func TestUnsafe(t *testing.T) {
  1119  	pkg := NewPackage("", "foo", gblConf)
  1120  	sizeof := unsafeRef("Sizeof")
  1121  	expr := toObjectExpr(pkg, sizeof)
  1122  	if v, ok := expr.(*ast.SelectorExpr); ok {
  1123  		if id, ok := v.X.(*ast.Ident); !ok || id.Name != "unsafe" || v.Sel.Name != "Sizeof" {
  1124  			t.Fatal("toObjectExpr failed:", v.X)
  1125  		}
  1126  	} else {
  1127  		t.Fatal("TestUnsafe failed:", expr)
  1128  	}
  1129  }
  1130  
  1131  func TestTryImport(t *testing.T) {
  1132  	defer func() {
  1133  		if e := recover(); e != nil {
  1134  			t.Fatal("TestTryImport: panic?")
  1135  		}
  1136  	}()
  1137  	pkg := NewPackage("foo", "foo", gblConf)
  1138  	if pkg.TryImport("not/exist").Types != nil {
  1139  		t.Fatal("TryImport: exist?")
  1140  	}
  1141  }
  1142  
  1143  func TestUntypeBig(t *testing.T) {
  1144  	pkg := NewPackage("foo", "foo", gblConf)
  1145  	big := pkg.Import("github.com/goplus/gox/internal/builtin")
  1146  	big.EnsureImported()
  1147  	pkg.utBigInt = big.Ref("Gop_untyped_bigint").Type().(*types.Named)
  1148  	pkg.utBigRat = big.Ref("Gop_untyped_bigrat").Type().(*types.Named)
  1149  	if ret, ok := untypeBig(pkg, constant.MakeInt64(1), pkg.utBigRat); !ok || ret.Type != pkg.utBigRat {
  1150  		t.Fatal("TestUntypeBig failed:", *ret)
  1151  	}
  1152  	val := constant.Shift(constant.MakeInt64(1), token.SHL, 256)
  1153  	if ret, ok := untypeBig(pkg, val, pkg.utBigRat); !ok || ret.Type != pkg.utBigRat {
  1154  		t.Fatal("TestUntypeBig failed:", *ret)
  1155  	}
  1156  	func() {
  1157  		defer func() {
  1158  			if e := recover(); e == nil {
  1159  				t.Fatal("TestUntypeBig failed: no error?")
  1160  			}
  1161  		}()
  1162  		untypeBig(pkg, constant.MakeBool(true), pkg.utBigRat)
  1163  	}()
  1164  	func() {
  1165  		defer func() {
  1166  			if e := recover(); e == nil {
  1167  				t.Fatal("TestUntypeBig failed: no error?")
  1168  			}
  1169  		}()
  1170  		untypeBig(pkg, constant.MakeBool(true), pkg.utBigInt)
  1171  	}()
  1172  	func() {
  1173  		defer func() {
  1174  			if e := recover(); e == nil {
  1175  				t.Fatal("pkg.Import not-found: no error?")
  1176  			}
  1177  		}()
  1178  		pkg.Import("not-found").EnsureImported()
  1179  	}()
  1180  }
  1181  
  1182  func TestIsUnbound(t *testing.T) {
  1183  	if !isUnboundTuple(types.NewTuple(types.NewParam(token.NoPos, nil, "", &unboundFuncParam{}))) {
  1184  		t.Fatal("TestIsUnbound failed")
  1185  	}
  1186  }
  1187  
  1188  func TestErrImport(t *testing.T) {
  1189  	pkg := NewPackage("github.com/x/foo", "foo", gblConf)
  1190  	_, err := importPkg(pkg, "./bar", nil)
  1191  	if err == nil || !strings.HasPrefix(err.Error(), "no required module provides package github.com/x/foo/bar;") {
  1192  		t.Fatal("importPkg failed:", err)
  1193  	}
  1194  }
  1195  
  1196  func TestErrWriteFile(t *testing.T) {
  1197  	pkg := NewPackage("", "foo", gblConf)
  1198  	pkg.Types = nil
  1199  	defer func() {
  1200  		if e := recover(); e == nil {
  1201  			t.Fatal("TestErrWriteFile: no error?")
  1202  		}
  1203  	}()
  1204  	WriteFile("_gop_autogen.go", pkg)
  1205  }
  1206  
  1207  func TestLoadExpr(t *testing.T) {
  1208  	var cb CodeBuilder
  1209  	if src, pos := cb.loadExpr(nil); src != "" || pos != token.NoPos {
  1210  		t.Fatal("TestLoadExpr failed")
  1211  	}
  1212  }
  1213  
  1214  func TestRef(t *testing.T) {
  1215  	defer func() {
  1216  		if e := recover(); e == nil {
  1217  			t.Fatal("TestRef: no error?")
  1218  		}
  1219  	}()
  1220  	pkg := &PkgRef{Types: types.NewPackage("foo", "foo")}
  1221  	pkg.Ref("bar")
  1222  }
  1223  
  1224  func TestLookupLabel(t *testing.T) {
  1225  	var cb CodeBuilder
  1226  	if _, ok := cb.LookupLabel("foo"); ok {
  1227  		t.Fatal("TestLookupLabel failed")
  1228  	}
  1229  }
  1230  
  1231  func TestVarVal(t *testing.T) {
  1232  	defer func() {
  1233  		if e := recover(); !isError(e, "VarVal: variable `unknown` not found\n") {
  1234  			t.Fatal("TestVarVal:", e)
  1235  		}
  1236  	}()
  1237  	var cb CodeBuilder
  1238  	cb.VarVal("unknown")
  1239  }
  1240  
  1241  func isError(e interface{}, msg string) bool {
  1242  	if e != nil {
  1243  		if err, ok := e.(error); ok {
  1244  			return err.Error() == msg
  1245  		}
  1246  		if err, ok := e.(string); ok {
  1247  			return err == msg
  1248  		}
  1249  	}
  1250  	return false
  1251  }
  1252  
  1253  func TestImportError(t *testing.T) {
  1254  	err := &types.Error{Msg: "foo"}
  1255  	e := &ImportError{Err: err}
  1256  	if v := e.Unwrap(); v != err {
  1257  		t.Fatal("TestImportError2:", v)
  1258  	}
  1259  }
  1260  
  1261  func TestForRangeStmtPanic(t *testing.T) {
  1262  	defer func() {
  1263  		if e := recover(); e != nil {
  1264  			t.Fatal("forRangeStmt.End panic")
  1265  		}
  1266  	}()
  1267  	var s forRangeStmt
  1268  	s.End(nil, nil)
  1269  }
  1270  
  1271  func TestNewFuncDeclPanic(t *testing.T) {
  1272  	defer func() {
  1273  		if e := recover(); e == nil {
  1274  			t.Fatal("TestNewFuncDeclPanic: not panic")
  1275  		}
  1276  	}()
  1277  	pkg := NewPackage("", "foo", gblConf)
  1278  	a := types.NewParam(token.NoPos, pkg.Types, "", types.Typ[types.Int])
  1279  	sig := types.NewSignatureType(nil, nil, nil, types.NewTuple(a), nil, false)
  1280  	pkg.NewFuncDecl(token.NoPos, "init", sig)
  1281  }
  1282  
  1283  func TestNewFuncPanic(t *testing.T) {
  1284  	getRecv(nil)
  1285  	defer func() {
  1286  		if e := recover(); e == nil {
  1287  			t.Fatal("TestNewFuncPanic: not panic")
  1288  		}
  1289  	}()
  1290  	pkg := NewPackage("", "foo", gblConf)
  1291  	a := types.NewParam(token.NoPos, pkg.Types, "", types.Typ[types.Int])
  1292  	pkg.NewFunc(nil, "init", types.NewTuple(a), nil, false)
  1293  }
  1294  
  1295  func TestSwitchStmtPanic(t *testing.T) {
  1296  	defer func() {
  1297  		if e := recover(); e != nil {
  1298  			t.Fatal("siwtchStmt.End panic")
  1299  		}
  1300  	}()
  1301  	var s switchStmt
  1302  	s.End(nil, nil)
  1303  }
  1304  
  1305  func TestCallIncDec(t *testing.T) {
  1306  	defer func() {
  1307  		if e := recover(); e == nil {
  1308  			t.Fatal("TestCallIncDec not panic")
  1309  		} else if e.(error).Error() != "-: invalid operation: ++ (non-numeric type string)" {
  1310  			t.Fatal(e)
  1311  		}
  1312  	}()
  1313  	pkg := NewPackage("", "foo", gblConf)
  1314  	if uintptr(pkg.Sizeof(tyInt)) != unsafe.Sizeof(int(0)) {
  1315  		t.Fatal("pkg.Sizeof?")
  1316  	}
  1317  	if len(pkg.Offsetsof(nil)) != 0 {
  1318  		t.Fatal("pkg.Offsetsof?")
  1319  	}
  1320  	args := []*Element{
  1321  		{Type: &refType{typ: types.Typ[types.String]}},
  1322  	}
  1323  	callIncDec(pkg, args, token.INC)
  1324  }
  1325  
  1326  func TestVFields(t *testing.T) {
  1327  	pkg := NewPackage("", "foo", gblConf)
  1328  	typ := types.NewNamed(types.NewTypeName(token.NoPos, pkg.Types, "bar", nil), tyInt, nil)
  1329  	_, ok := pkg.VFields(typ)
  1330  	if ok {
  1331  		t.Fatal("VFields?")
  1332  	}
  1333  	{
  1334  		flds := NewUnionFields([]*UnionField{
  1335  			{Name: "foo"},
  1336  		})
  1337  		if flds.Len() != 1 {
  1338  			t.Fatal("UnionFields.len != 1")
  1339  		}
  1340  		if flds.At(0).Name != "foo" {
  1341  			t.Fatal("UnionField.name != foo")
  1342  		}
  1343  	}
  1344  	{
  1345  		flds := NewBitFields([]*BitField{
  1346  			{Name: "foo"},
  1347  		})
  1348  		if flds.Len() != 1 {
  1349  			t.Fatal("BitFields.len != 1")
  1350  		}
  1351  		if flds.At(0).Name != "foo" {
  1352  			t.Fatal("BitField.name != foo")
  1353  		}
  1354  	}
  1355  }
  1356  
  1357  func TestTypeAST(t *testing.T) {
  1358  	pkg := NewPackage("", "foo", gblConf)
  1359  	fset := token.NewFileSet()
  1360  	expr := TypeAST(pkg, TyEmptyInterface)
  1361  	b := bytes.NewBuffer(nil)
  1362  	format.Node(b, fset, expr)
  1363  	if b.String() != `interface{}` {
  1364  		t.Fatal("TypeAST failed:", b.String())
  1365  	}
  1366  }
  1367  
  1368  func TestCastFromBool(t *testing.T) {
  1369  	ret, ok := CastFromBool(nil, types.Typ[types.Uint], &Element{
  1370  		Type: types.Typ[types.UntypedBool],
  1371  		CVal: constant.MakeBool(true),
  1372  	})
  1373  	if !ok || constant.Val(ret.CVal).(int64) != 1 {
  1374  		t.Fatal("CastFromBool failed:", ret.CVal, ok)
  1375  	}
  1376  	ret, ok = CastFromBool(nil, types.Typ[types.Uint], &Element{
  1377  		Type: types.Typ[types.Bool],
  1378  		CVal: constant.MakeBool(false),
  1379  	})
  1380  	if !ok || constant.Val(ret.CVal).(int64) != 0 {
  1381  		t.Fatal("CastFromBool failed:", ret.CVal, ok)
  1382  	}
  1383  }
  1384  
  1385  func TestSubstVar(t *testing.T) {
  1386  	pkg := types.NewPackage("", "foo")
  1387  	a := types.NewParam(0, pkg, "a", types.Typ[types.Int])
  1388  	scope := pkg.Scope()
  1389  	scope.Insert(NewSubst(token.NoPos, pkg, "bar", a))
  1390  	o := Lookup(scope, "bar")
  1391  	if o != a {
  1392  		t.Fatal("TestSubstVar:", o)
  1393  	}
  1394  	_, o = LookupParent(scope, "bar", token.NoPos)
  1395  	if o != a {
  1396  		t.Fatal("TestSubstVar:", o)
  1397  	}
  1398  	scope.Insert(a)
  1399  	_, o2 := LookupParent(scope, "a", token.NoPos)
  1400  	if o != o2 {
  1401  		t.Fatal("TestSubstVar:", o2)
  1402  	}
  1403  	o2 = Lookup(scope, "a")
  1404  	if o != o2 {
  1405  		t.Fatal("TestSubstVar:", o2)
  1406  	}
  1407  	LookupParent(scope, "b", token.NoPos)
  1408  	Lookup(scope, "b")
  1409  }
  1410  
  1411  func TestToTag(t *testing.T) {
  1412  	if v := toTag(`json:"mytag"`).Value; v != "`json:\"mytag\"`" {
  1413  		t.Fatal(v)
  1414  	}
  1415  	if v := toTag("json:\"mytag\"").Value; v != "`json:\"mytag\"`" {
  1416  		t.Fatal(v)
  1417  	}
  1418  	if v := toTag("json:`mytag`").Value; v != "\"json:`mytag`\"" {
  1419  		t.Fatal(v)
  1420  	}
  1421  }
  1422  
  1423  // ----------------------------------------------------------------------------