github.com/gopherjs/gopherjs@v1.19.0-beta1.0.20240506212314-27071a8796e4/compiler/analysis/info_test.go (about) 1 package analysis 2 3 import ( 4 "go/ast" 5 "go/types" 6 "testing" 7 8 "github.com/gopherjs/gopherjs/internal/srctesting" 9 ) 10 11 // See: https://github.com/gopherjs/gopherjs/issues/955. 12 func TestBlockingFunctionLiteral(t *testing.T) { 13 src := ` 14 package test 15 16 func blocking() { 17 c := make(chan bool) 18 <-c 19 } 20 21 func indirectlyBlocking() { 22 func() { blocking() }() 23 } 24 25 func directlyBlocking() { 26 func() { 27 c := make(chan bool) 28 <-c 29 }() 30 } 31 32 func notBlocking() { 33 func() { println() } () 34 } 35 ` 36 f := srctesting.New(t) 37 file := f.Parse("test.go", src) 38 typesInfo, typesPkg := f.Check("pkg/test", file) 39 40 pkgInfo := AnalyzePkg([]*ast.File{file}, f.FileSet, typesInfo, typesPkg, func(f *types.Func) bool { 41 panic("isBlocking() should be never called for imported functions in this test.") 42 }) 43 44 assertBlocking(t, file, pkgInfo, "blocking") 45 assertBlocking(t, file, pkgInfo, "indirectlyBlocking") 46 assertBlocking(t, file, pkgInfo, "directlyBlocking") 47 assertNotBlocking(t, file, pkgInfo, "notBlocking") 48 } 49 50 func assertBlocking(t *testing.T, file *ast.File, pkgInfo *Info, funcName string) { 51 typesFunc := getTypesFunc(t, file, pkgInfo, funcName) 52 if !pkgInfo.IsBlocking(typesFunc) { 53 t.Errorf("Got: %q is not blocking. Want: %q is blocking.", typesFunc, typesFunc) 54 } 55 } 56 57 func assertNotBlocking(t *testing.T, file *ast.File, pkgInfo *Info, funcName string) { 58 typesFunc := getTypesFunc(t, file, pkgInfo, funcName) 59 if pkgInfo.IsBlocking(typesFunc) { 60 t.Errorf("Got: %q is blocking. Want: %q is not blocking.", typesFunc, typesFunc) 61 } 62 } 63 64 func getTypesFunc(t *testing.T, file *ast.File, pkgInfo *Info, funcName string) *types.Func { 65 obj := file.Scope.Lookup(funcName) 66 if obj == nil { 67 t.Fatalf("Declaration of %q is not found in the AST.", funcName) 68 } 69 decl, ok := obj.Decl.(*ast.FuncDecl) 70 if !ok { 71 t.Fatalf("Got: %q is %v. Want: a function declaration.", funcName, obj.Kind) 72 } 73 blockingType, ok := pkgInfo.Defs[decl.Name] 74 if !ok { 75 t.Fatalf("No type information is found for %v.", decl.Name) 76 } 77 return blockingType.(*types.Func) 78 }