detached 4382b8f

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..."
1818 goimports -w v4
1919
2020 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 v418 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 {
5050 Callbacks []CallbackParam
5151 }
5252
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+
53106 func (f *funcArgsTemplate) AddAPI(t string, n string, k Kind, ns string, nullable bool, isOut bool) {
54107 c := n
55108 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
211264 // This enables the template to generate proper closure wrapping
212265 if kind == CallbackType && !isOut {
213266 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+
214274 // 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)
216277 var retRaw string
217278 if cb.ReturnValue != nil {
218- cbRet := cb.ReturnValue.Template(lns, "", kinds, cb.Throws)
279+ cbRet := cb.ReturnValue.Template(cbNs, "", kinds, cb.Throws)
219280 retRaw = cbRet.Raw
220281 }
221282
283+ qualifiedPureTypes := qualifyCallbackTypes(cbArgs.Pure.Types, cbNs, ns)
284+ qualifiedRetRaw := qualifyCallbackType(retRaw, cbNs, ns)
285+
222286 f.Callbacks = append(f.Callbacks, CallbackParam{
223287 Name: varName,
224288 TypeName: strings.TrimPrefix(goType, "*"),
225- PureTypes: cbArgs.Pure.Types,
226- RetRaw: retRaw,
289+ PureTypes: qualifiedPureTypes,
290+ RetRaw: qualifiedRetRaw,
227291 Nullable: p.Nullable,
228292 })
229293
@@ -50,6 +50,59 @@ type funcArgsTemplate struct {
50 Callbacks []CallbackParam50 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 := n107 c := n
55 cRef := n // For CallWithRefs, defaults to same as Call108 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 wrapping264 // 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 type274 // 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 string277 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.Raw280 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

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 102

↑↓ moveenter openesc close