| Test of local Implementation queries using function signatures. |
| |
| Assertions: |
| - Query on "func" of a function type returns the corresponding concrete functions. |
| - Query on "func" of a concrete function returns corresponding function types. |
| - Query on "(" of a dynamic function call returns corresponding function types. |
| - Different signatures (Nullary vs Handler) don't correspond. |
| |
| The @loc markers use the suffixes Func, Type, Call for the three kinds. |
| Each query maps between these two sets: {Func} <=> {Type,Call}. |
| |
| -- go.mod -- |
| module example.com |
| go 1.18 |
| |
| -- a/a.go -- |
| package a |
| |
| // R is short for Record. |
| type R struct{} |
| |
| // H is short for Handler. |
| type H func(*R) //@ loc(HType, "func"), implementation("func", aFunc, bFunc, cFunc) |
| |
| func aFunc(*R) {} //@ loc(aFunc, "func"), implementation("func", HType, hParamType, hCall) |
| |
| var bFunc = func(*R) {} //@ loc(bFunc, "func"), implementation("func", hParamType, hCall, HType) |
| |
| func nullary() { //@ loc(nullaryFunc, "func"), implementation("func", Nullary, fieldCall) |
| cFunc := func(*R) {} //@ loc(cFunc, "func"), implementation("func", hParamType, hCall, HType) |
| _ = cFunc |
| } |
| |
| type Nullary func() //@ loc(Nullary, "func") |
| |
| func _( |
| h func(*R)) { //@ loc(hParamType, "func"), implementation("func", aFunc, bFunc, cFunc) |
| |
| _ = aFunc // pacify unusedfunc |
| _ = nullary // pacify unusedfunc |
| _ = h |
| |
| h(nil) //@ loc(hCall, "("), implementation("(", aFunc, bFunc, cFunc) |
| } |
| |
| // generics: |
| |
| func _[T any](complex128) { |
| f1 := func(T) int { return 0 } //@ loc(f1Func, "func"), implementation("func", fParamType, fCall, f1Call, f2Call) |
| f2 := func(string) int { return 0 } //@ loc(f2Func, "func"), implementation("func", fParamType, fCall, f1Call, f2Call) |
| f3 := func(int) int { return 0 } //@ loc(f3Func, "func"), implementation("func", f1Call) |
| |
| f1(*new(T)) //@ loc(f1Call, "("), implementation("(", f1Func, f2Func, f3Func, f4Func) |
| f2("") //@ loc(f2Call, "("), implementation("(", f1Func, f2Func, f4Func) |
| _ = f3 // not called |
| } |
| |
| func f4[T any](T) int { return 0 } //@ loc(f4Func, "func"), implementation("func", fParamType, fCall, f1Call, f2Call) |
| |
| var _ = f4[string] // pacify unusedfunc |
| |
| func _( |
| f func(string) int, //@ loc(fParamType, "func"), implementation("func", f1Func, f2Func, f4Func) |
| err error) { |
| |
| f("") //@ loc(fCall, "("), implementation("(", f1Func, f2Func, f4Func) |
| |
| struct{x Nullary}{}.x() //@ loc(fieldCall, "("), implementation("(", nullaryFunc) |
| |
| // Calls that are not dynamic function calls: |
| _ = len("") //@ implementation("(", err="not a dynamic function call") |
| _ = int(0) //@ implementation("(", err="not a dynamic function call") |
| _ = error.Error(nil) //@ implementation("(", err="not a dynamic function call") |
| _ = err.Error() //@ implementation("(", err="not a dynamic function call") |
| _ = f4(0) //@ implementation("(", err="not a dynamic function call"), loc(f4Call, "(") |
| } |
| |
| |
| |