fix(gir): handle callback parameter types from other namespaces
- commit
- 4382b8fd2a232f4eb1d7e899c50e1db27f6cdde0
- author
- brice · · 2025-12-11 08:27 UTC
- parent
- c2d6ab6
- signature
- unsigned
2 files · +69 -5
M gen.sh +1 -1
| @@ -18,4 +18,4 @@ echo "running a second pass for goimports..." | |||
| 18 | 18 | goimports -w v4 | |
| 19 | 19 | ||
| 20 | 20 | echo "running go vet..." | |
| 21 | - | go vet ./v4/... | |
| 21 | + | go vet -unsafeptr=false -stdmethods=false ./v4/... | |
| @@ -18,4 +18,4 @@ echo "running a second pass for goimports..." | |||||
| 18 | goimports -w v4 | 18 | goimports -w v4 | ||
| 19 | 19 | ||||
| 20 | echo "running go vet..." | 20 | echo "running go vet..." | ||
| 21 | - | go vet ./v4/... | 21 | + | go vet -unsafeptr=false -stdmethods=false ./v4/... |
M internal/gir/types/template.go +68 -4
| @@ -50,6 +50,59 @@ type funcArgsTemplate struct { | |||
| 50 | 50 | Callbacks []CallbackParam | |
| 51 | 51 | } | |
| 52 | 52 | ||
| 53 | + | func qualifyCallbackType(t string, callbackNS string, currentNS string) string { | |
| 54 | + | if t == "" || callbackNS == "" || strings.EqualFold(callbackNS, currentNS) { | |
| 55 | + | return t | |
| 56 | + | } | |
| 57 | + | ||
| 58 | + | if strings.Contains(t, ".") { | |
| 59 | + | return t | |
| 60 | + | } | |
| 61 | + | ||
| 62 | + | ptrPrefix := "" | |
| 63 | + | base := t | |
| 64 | + | for strings.HasPrefix(base, "*") { | |
| 65 | + | ptrPrefix += "*" | |
| 66 | + | base = strings.TrimPrefix(base, "*") | |
| 67 | + | } | |
| 68 | + | ||
| 69 | + | slicePrefix := "" | |
| 70 | + | for strings.HasPrefix(base, "[]") { | |
| 71 | + | slicePrefix += "[]" | |
| 72 | + | base = strings.TrimPrefix(base, "[]") | |
| 73 | + | } | |
| 74 | + | ||
| 75 | + | arrayPrefix := "" | |
| 76 | + | for strings.HasPrefix(base, "[") { | |
| 77 | + | end := strings.Index(base, "]") | |
| 78 | + | if end == -1 { | |
| 79 | + | break | |
| 80 | + | } | |
| 81 | + | arrayPrefix += base[:end+1] | |
| 82 | + | base = base[end+1:] | |
| 83 | + | } | |
| 84 | + | ||
| 85 | + | switch base { | |
| 86 | + | case "bool", "byte", "complex64", "complex128", "error", "float32", "float64", "int", "int8", "int16", "int32", "int64", "rune", "string", "uint", "uint8", "uint16", "uint32", "uint64", "uintptr": | |
| 87 | + | return t | |
| 88 | + | } | |
| 89 | + | ||
| 90 | + | if base == "" { | |
| 91 | + | return t | |
| 92 | + | } | |
| 93 | + | ||
| 94 | + | qualifiedBase := callbackNS + "." + base | |
| 95 | + | return ptrPrefix + slicePrefix + arrayPrefix + qualifiedBase | |
| 96 | + | } | |
| 97 | + | ||
| 98 | + | func qualifyCallbackTypes(types []string, callbackNS string, currentNS string) []string { | |
| 99 | + | qualified := make([]string, len(types)) | |
| 100 | + | for i, t := range types { | |
| 101 | + | qualified[i] = qualifyCallbackType(t, callbackNS, currentNS) | |
| 102 | + | } | |
| 103 | + | return qualified | |
| 104 | + | } | |
| 105 | + | ||
| 53 | 106 | func (f *funcArgsTemplate) AddAPI(t string, n string, k Kind, ns string, nullable bool, isOut bool) { | |
| 54 | 107 | c := n | |
| 55 | 108 | cRef := n // For CallWithRefs, defaults to same as Call | |
| @@ -211,19 +264,30 @@ func (f *funcArgsTemplate) Add(p Parameter, ins string, ns string, kinds KindMap | |||
| 211 | 264 | // This enables the template to generate proper closure wrapping | |
| 212 | 265 | if kind == CallbackType && !isOut { | |
| 213 | 266 | if cb, ok := kinds.GetCallback(lns, originalType); ok { | |
| 267 | + | // Determine the callback's namespace from the original type name | |
| 268 | + | // e.g., "gio.AsyncReadyCallback" -> "gio", "AsyncReadyCallback" -> lns | |
| 269 | + | cbNs := lns | |
| 270 | + | if parts := strings.Split(originalType, "."); len(parts) > 1 { | |
| 271 | + | cbNs = parts[0] | |
| 272 | + | } | |
| 273 | + | ||
| 214 | 274 | // Get the callback's pure argument types and return type | |
| 215 | - | cbArgs := cb.Parameters.Template(lns, "", kinds, cb.Throws) | |
| 275 | + | // Use cbNs (callback's namespace) for proper type lookups | |
| 276 | + | cbArgs := cb.Parameters.Template(cbNs, "", kinds, cb.Throws) | |
| 216 | 277 | var retRaw string | |
| 217 | 278 | if cb.ReturnValue != nil { | |
| 218 | - | cbRet := cb.ReturnValue.Template(lns, "", kinds, cb.Throws) | |
| 279 | + | cbRet := cb.ReturnValue.Template(cbNs, "", kinds, cb.Throws) | |
| 219 | 280 | retRaw = cbRet.Raw | |
| 220 | 281 | } | |
| 221 | 282 | ||
| 283 | + | qualifiedPureTypes := qualifyCallbackTypes(cbArgs.Pure.Types, cbNs, ns) | |
| 284 | + | qualifiedRetRaw := qualifyCallbackType(retRaw, cbNs, ns) | |
| 285 | + | ||
| 222 | 286 | f.Callbacks = append(f.Callbacks, CallbackParam{ | |
| 223 | 287 | Name: varName, | |
| 224 | 288 | TypeName: strings.TrimPrefix(goType, "*"), | |
| 225 | - | PureTypes: cbArgs.Pure.Types, | |
| 226 | - | RetRaw: retRaw, | |
| 289 | + | PureTypes: qualifiedPureTypes, | |
| 290 | + | RetRaw: qualifiedRetRaw, | |
| 227 | 291 | Nullable: p.Nullable, | |
| 228 | 292 | }) | |
| 229 | 293 | ||
| @@ -50,6 +50,59 @@ type funcArgsTemplate struct { | |||||
| 50 | Callbacks []CallbackParam | 50 | Callbacks []CallbackParam | ||
| 51 | } | 51 | } | ||
| 52 | 52 | ||||
| 53 | + | func qualifyCallbackType(t string, callbackNS string, currentNS string) string { | |||
| 54 | + | if t == "" || callbackNS == "" || strings.EqualFold(callbackNS, currentNS) { | |||
| 55 | + | return t | |||
| 56 | + | } | |||
| 57 | + | ||||
| 58 | + | if strings.Contains(t, ".") { | |||
| 59 | + | return t | |||
| 60 | + | } | |||
| 61 | + | ||||
| 62 | + | ptrPrefix := "" | |||
| 63 | + | base := t | |||
| 64 | + | for strings.HasPrefix(base, "*") { | |||
| 65 | + | ptrPrefix += "*" | |||
| 66 | + | base = strings.TrimPrefix(base, "*") | |||
| 67 | + | } | |||
| 68 | + | ||||
| 69 | + | slicePrefix := "" | |||
| 70 | + | for strings.HasPrefix(base, "[]") { | |||
| 71 | + | slicePrefix += "[]" | |||
| 72 | + | base = strings.TrimPrefix(base, "[]") | |||
| 73 | + | } | |||
| 74 | + | ||||
| 75 | + | arrayPrefix := "" | |||
| 76 | + | for strings.HasPrefix(base, "[") { | |||
| 77 | + | end := strings.Index(base, "]") | |||
| 78 | + | if end == -1 { | |||
| 79 | + | break | |||
| 80 | + | } | |||
| 81 | + | arrayPrefix += base[:end+1] | |||
| 82 | + | base = base[end+1:] | |||
| 83 | + | } | |||
| 84 | + | ||||
| 85 | + | switch base { | |||
| 86 | + | case "bool", "byte", "complex64", "complex128", "error", "float32", "float64", "int", "int8", "int16", "int32", "int64", "rune", "string", "uint", "uint8", "uint16", "uint32", "uint64", "uintptr": | |||
| 87 | + | return t | |||
| 88 | + | } | |||
| 89 | + | ||||
| 90 | + | if base == "" { | |||
| 91 | + | return t | |||
| 92 | + | } | |||
| 93 | + | ||||
| 94 | + | qualifiedBase := callbackNS + "." + base | |||
| 95 | + | return ptrPrefix + slicePrefix + arrayPrefix + qualifiedBase | |||
| 96 | + | } | |||
| 97 | + | ||||
| 98 | + | func qualifyCallbackTypes(types []string, callbackNS string, currentNS string) []string { | |||
| 99 | + | qualified := make([]string, len(types)) | |||
| 100 | + | for i, t := range types { | |||
| 101 | + | qualified[i] = qualifyCallbackType(t, callbackNS, currentNS) | |||
| 102 | + | } | |||
| 103 | + | return qualified | |||
| 104 | + | } | |||
| 105 | + | ||||
| 53 | func (f *funcArgsTemplate) AddAPI(t string, n string, k Kind, ns string, nullable bool, isOut bool) { | 106 | func (f *funcArgsTemplate) AddAPI(t string, n string, k Kind, ns string, nullable bool, isOut bool) { | ||
| 54 | c := n | 107 | c := n | ||
| 55 | cRef := n // For CallWithRefs, defaults to same as Call | 108 | cRef := n // For CallWithRefs, defaults to same as Call | ||
| @@ -211,19 +264,30 @@ func (f *funcArgsTemplate) Add(p Parameter, ins string, ns string, kinds KindMap | |||||
| 211 | // This enables the template to generate proper closure wrapping | 264 | // This enables the template to generate proper closure wrapping | ||
| 212 | if kind == CallbackType && !isOut { | 265 | if kind == CallbackType && !isOut { | ||
| 213 | if cb, ok := kinds.GetCallback(lns, originalType); ok { | 266 | if cb, ok := kinds.GetCallback(lns, originalType); ok { | ||
| 267 | + | // Determine the callback's namespace from the original type name | |||
| 268 | + | // e.g., "gio.AsyncReadyCallback" -> "gio", "AsyncReadyCallback" -> lns | |||
| 269 | + | cbNs := lns | |||
| 270 | + | if parts := strings.Split(originalType, "."); len(parts) > 1 { | |||
| 271 | + | cbNs = parts[0] | |||
| 272 | + | } | |||
| 273 | + | ||||
| 214 | // Get the callback's pure argument types and return type | 274 | // Get the callback's pure argument types and return type | ||
| 215 | - | cbArgs := cb.Parameters.Template(lns, "", kinds, cb.Throws) | 275 | + | // Use cbNs (callback's namespace) for proper type lookups |
| 276 | + | cbArgs := cb.Parameters.Template(cbNs, "", kinds, cb.Throws) | |||
| 216 | var retRaw string | 277 | var retRaw string | ||
| 217 | if cb.ReturnValue != nil { | 278 | if cb.ReturnValue != nil { | ||
| 218 | - | cbRet := cb.ReturnValue.Template(lns, "", kinds, cb.Throws) | 279 | + | cbRet := cb.ReturnValue.Template(cbNs, "", kinds, cb.Throws) |
| 219 | retRaw = cbRet.Raw | 280 | retRaw = cbRet.Raw | ||
| 220 | } | 281 | } | ||
| 221 | 282 | ||||
| 283 | + | qualifiedPureTypes := qualifyCallbackTypes(cbArgs.Pure.Types, cbNs, ns) | |||
| 284 | + | qualifiedRetRaw := qualifyCallbackType(retRaw, cbNs, ns) | |||
| 285 | + | ||||
| 222 | f.Callbacks = append(f.Callbacks, CallbackParam{ | 286 | f.Callbacks = append(f.Callbacks, CallbackParam{ | ||
| 223 | Name: varName, | 287 | Name: varName, | ||
| 224 | TypeName: strings.TrimPrefix(goType, "*"), | 288 | TypeName: strings.TrimPrefix(goType, "*"), | ||
| 225 | - | PureTypes: cbArgs.Pure.Types, | 289 | + | PureTypes: qualifiedPureTypes, |
| 226 | - | RetRaw: retRaw, | 290 | + | RetRaw: qualifiedRetRaw, |
| 227 | Nullable: p.Nullable, | 291 | Nullable: p.Nullable, | ||
| 228 | }) | 292 | }) | ||
| 229 | 293 | ||||