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