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 // ----------------------------------------------------------------------------