1package types
2
3import (
4 "fmt"
5 "strings"
6
7 "github.com/bnema/puregotk/internal/gir/util"
8)
9
10type argsTemplate struct {
11 // Names are the variables but just the names
12 Names []string
13
14 // Types are the variables but just the types
15 Types []string
16
17 // Call are the variables as given in a function call
18 Call []string
19
20 // CallWithRefs is like Call but with callback parameters using {name}Ref
21 // for use in contexts that generate closure wrappers
22 CallWithRefs []string
23
24 Full []string
25}
26
27// CallbackParam holds metadata for callback parameters to enable proper closure generation
28type CallbackParam struct {
29 // Name is the parameter name (e.g., "CallbackVar")
30 Name string
31 // TypeName is the callback type name (e.g., "TickCallback")
32 TypeName string
33 // PureTypes are the pure argument types for the closure
34 PureTypes []string
35 // CallArgs are expressions used when invoking cbFn from closure args
36 CallArgs []string
37 // RetRaw is the return type for the closure (e.g., "bool")
38 RetRaw string
39 // Nullable indicates if the callback can be nil
40 Nullable bool
41}
42
43// NullableStringParam holds metadata for nullable string parameters that need
44// temporary C-owned string allocation with g_strdup/g_free.
45type NullableStringParam struct {
46 // Name is the parameter name (e.g., "DataDirectoryVar")
47 Name string
48}
49
50// GErrorParam tracks a signal/callback parameter that is a GLib.Error record.
51// The Pure type stays uintptr (purego ABI), but the API type is *glib.Error
52// and the signal closure converts via unsafe.Pointer.
53type GErrorParam struct {
54 // Index is the position in the Pure args slice.
55 Index int
56 // GoType is the qualified Go type for the cast (e.g., "glib.Error" or "Error").
57 GoType string
58}
59
60type funcArgsTemplate struct {
61 // Pure are the arguments as passed directly to PureGo
62 // The pure Call is a special case that contains the arguments for a callback call
63 Pure argsTemplate
64
65 // API are the arguments as suitable for a Go API
66 API argsTemplate
67
68 // Callbacks tracks callback parameters for proper closure generation
69 Callbacks []CallbackParam
70
71 // NullableStrings tracks nullable string parameters that need temporary C strings
72 NullableStrings []NullableStringParam
73
74 // GErrors tracks GError record parameters in signal/callback contexts
75 // so PuregoSignalCall can emit unsafe.Pointer casts.
76 GErrors []GErrorParam
77
78 // UsesNullableHelper indicates nullable string handling that needs core import.
79 UsesNullableHelper bool
80
81 // UsesGStrdup indicates transfer-full string handling that needs core import.
82 UsesGStrdup bool
83}
84
85// ArgContext indicates where the arguments are flowing so we can handle
86// direction-sensitive cases (e.g. nullable strings) differently.
87type ArgContext int
88
89const (
90 // ArgsFromGoToC covers regular functions/methods where Go calls into C.
91 ArgsFromGoToC ArgContext = iota
92 // ArgsFromCToGo covers callbacks/signals where C calls into Go.
93 ArgsFromCToGo
94)
95
96func isStringType(t string) bool {
97 if strings.HasPrefix(t, "[]") {
98 return false
99 }
100 return strings.TrimLeft(t, "*") == "string"
101}
102
103// isGErrorType reports whether a GIR type name refers to GLib.Error.
104// Within the GLib namespace the name is just "Error"; elsewhere it is "GLib.Error".
105func isGErrorType(girName string) bool {
106 return girName == "GLib.Error" || girName == "Error"
107}
108
109// NeedsCore reports whether this argument set requires core helpers.
110func (f funcArgsTemplate) NeedsCore() bool {
111 return f.UsesNullableHelper || f.UsesGStrdup
112}
113
114// HasPureStrings reports whether any Pure parameter is a string type.
115// Signal closures with string parameters need core.GoString() conversion.
116func (f funcArgsTemplate) HasPureStrings() bool {
117 for _, t := range f.Pure.Types {
118 if t == "string" {
119 return true
120 }
121 }
122 return false
123}
124
125// PuregoSignalFull returns Pure.Full with string types replaced by uintptr.
126// Used for signal fcb closures passed to purego.NewCallback, which cannot
127// handle Go string parameters (C passes const char* as a pointer).
128func (f funcArgsTemplate) PuregoSignalFull() []string {
129 out := make([]string, len(f.Pure.Full))
130 copy(out, f.Pure.Full)
131 for i, t := range f.Pure.Types {
132 if t == "string" {
133 out[i] = f.Pure.Names[i] + " uintptr"
134 }
135 }
136 return out
137}
138
139// PuregoSignalCall returns Pure.Call with string variables wrapped in
140// core.GoString() for C char* → Go string conversion in signal closures,
141// and GError parameters wrapped in (*glib.Error)(unsafe.Pointer(...)).
142func (f funcArgsTemplate) PuregoSignalCall() []string {
143 out := make([]string, len(f.Pure.Call))
144 copy(out, f.Pure.Call)
145 for i, t := range f.Pure.Types {
146 if t == "string" {
147 out[i] = "core.GoString(" + f.Pure.Names[i] + ")"
148 }
149 }
150 for _, ge := range f.GErrors {
151 out[ge.Index] = "(*" + ge.GoType + ")(unsafe.Pointer(" + f.Pure.Names[ge.Index] + "))"
152 }
153 return out
154}
155
156// HasGErrors reports whether any parameter is a GError that needs
157// an unsafe.Pointer cast in the signal closure.
158func (f funcArgsTemplate) HasGErrors() bool {
159 return len(f.GErrors) > 0
160}
161
162func qualifyCallbackType(t string, callbackNS string, currentNS string) string {
163 if t == "" || callbackNS == "" || strings.EqualFold(callbackNS, currentNS) {
164 return t
165 }
166
167 if strings.Contains(t, ".") {
168 return t
169 }
170
171 ptrPrefix := ""
172 base := t
173 for strings.HasPrefix(base, "*") {
174 ptrPrefix += "*"
175 base = strings.TrimPrefix(base, "*")
176 }
177
178 slicePrefix := ""
179 for strings.HasPrefix(base, "[]") {
180 slicePrefix += "[]"
181 base = strings.TrimPrefix(base, "[]")
182 }
183
184 arrayPrefix := ""
185 for strings.HasPrefix(base, "[") {
186 end := strings.Index(base, "]")
187 if end == -1 {
188 break
189 }
190 arrayPrefix += base[:end+1]
191 base = base[end+1:]
192 }
193
194 switch base {
195 case "bool", "byte", "complex64", "complex128", "error", "float32", "float64", "int", "int8", "int16", "int32", "int64", "rune", "string", "uint", "uint8", "uint16", "uint32", "uint64", "uintptr":
196 return t
197 }
198
199 if base == "" {
200 return t
201 }
202
203 qualifiedBase := callbackNS + "." + base
204 return ptrPrefix + slicePrefix + arrayPrefix + qualifiedBase
205}
206
207func qualifyCallbackTypes(types []string, callbackNS string, currentNS string) []string {
208 qualified := make([]string, len(types))
209 for i, t := range types {
210 qualified[i] = qualifyCallbackType(t, callbackNS, currentNS)
211 }
212 return qualified
213}
214
215func (f *funcArgsTemplate) AddAPI(t string, n string, k Kind, ns string, nullable bool, isOut bool, ctx ArgContext, transferFull bool) {
216 c := n
217 cRef := n // For CallWithRefs, defaults to same as Call
218 stars := strings.Count(t, "*")
219 gobjectNs := "gobject."
220 glibNs := "glib."
221 if strings.ToLower(ns) == "gobject" {
222 gobjectNs = ""
223 }
224 if strings.ToLower(ns) == "glib" {
225 glibNs = ""
226 }
227
228 if isOut {
229 if stars == 0 {
230 // For out parameters, the C type already has a pointer, and so do non-primitive Go types.
231 // For primitive Go types we need to manually add the *
232 t = "*" + t
233 }
234 c = n
235 cRef = n
236 } else {
237 // For transfer-full strings, use g_strdup so GTK can safely g_free() the copy.
238 // This must be checked before nullable handling to avoid conflicting conversions.
239 if ctx == ArgsFromGoToC && transferFull && isStringType(t) {
240 f.UsesGStrdup = true
241 if nullable {
242 // Nullable transfer-full: API type is *string, call uses GStrdupNullable
243 t = "*string"
244 c = fmt.Sprintf("core.GStrdupNullable(%s)", n)
245 cRef = c
246 } else {
247 c = fmt.Sprintf("core.GStrdup(%s)", n)
248 cRef = c
249 }
250 } else if ctx == ArgsFromGoToC && nullable && isStringType(t) {
251 // Nullable strings differ based on direction. For Go->C we need a *string API type
252 // and pass a nullable C pointer to C. For C->Go we keep the string as-is.
253 // We track these parameters so templates can allocate/free a temporary
254 // C-owned copy via g_strdup/g_free around each call.
255 f.UsesNullableHelper = true
256 t = "*string"
257 c = fmt.Sprintf("%sPtr", n)
258 cRef = c
259 // Track this parameter for temp C allocation/free generation
260 f.NullableStrings = append(f.NullableStrings, NullableStringParam{Name: n})
261 }
262
263 switch k {
264 case CallbackType:
265 // Call uses glib.NewCallback for contexts like callback accessor getters
266 if nullable {
267 c = fmt.Sprintf("%sNewCallbackNullable(%s)", glibNs, n)
268 } else {
269 c = fmt.Sprintf("%sNewCallback(%s)", glibNs, n)
270 }
271 // For CallWithRefs, start with the same value as Call
272 // It will be updated to {name}Ref in Add() if the callback lookup succeeds
273 cRef = c
274 t = "*" + t
275 case ClassesType:
276 if stars == 0 {
277 c = n
278 t = "uintptr"
279 } else if stars > 1 {
280 c = fmt.Sprintf("%sConvertPtr(%s)", gobjectNs, n)
281 } else if stars == 1 {
282 c = n + ".GoPointer()"
283 }
284 cRef = c
285 case InterfacesType:
286 t = strings.TrimPrefix(t, "*")
287 if stars == 0 {
288 c = n
289 t = "uintptr"
290 } else if stars > 1 {
291 c = fmt.Sprintf("%sConvertPtr(%s)", gobjectNs, n)
292 } else if stars == 1 {
293 c = n + ".GoPointer()"
294 }
295 cRef = c
296 default:
297 cRef = c
298 }
299
300 // special case for varargs
301 if n == "varArgs" {
302 c = n + "..."
303 cRef = c
304 }
305 }
306
307 f.API.Names = append(f.API.Names, n)
308 f.API.Types = append(f.API.Types, t)
309 f.API.Call = append(f.API.Call, c)
310 f.API.CallWithRefs = append(f.API.CallWithRefs, cRef)
311 f.API.Full = append(f.API.Full, n+" "+t)
312}
313
314func (f *funcArgsTemplate) AddPure(t string, n string, k Kind, isOut bool, nullable bool, ctx ArgContext, transferFull bool) {
315 n += "p"
316 c := n
317 stars := strings.Count(t, "*")
318
319 if isOut {
320 // Out parameters are always pointers in C
321 if stars == 0 {
322 // For primitive Go types we need to manually add the *
323 t = "*" + t
324 }
325 c = n
326 } else {
327 // For transfer-full strings, the pure type must be uintptr to accept
328 // the g_strdup'd pointer from the API call
329 if ctx == ArgsFromGoToC && transferFull && isStringType(t) {
330 t = "uintptr"
331 } else if ctx == ArgsFromGoToC && nullable && isStringType(t) {
332 f.UsesNullableHelper = true
333 t = "uintptr"
334 // Use the pointer variable that will be set up by the template
335 c = fmt.Sprintf("%sPtr", strings.TrimSuffix(n, "p"))
336 }
337
338 switch k {
339 case RecordsType:
340 if stars == 0 {
341 t = "uintptr"
342 }
343 case CallbackType:
344 c = fmt.Sprintf("(*%s)(unsafe.Pointer(%s))", strings.TrimPrefix(t, "*"), n)
345 t = "uintptr"
346 case ClassesType:
347 if stars == 0 {
348 c = n
349 t = "uintptr"
350 } else {
351 // Remove all dereference operators to get the base class name
352 baseName := strings.TrimPrefix(t, strings.Repeat("*", stars))
353 if stars > 1 {
354 // For double pointers like **ParamSpec, we need to pass the double pointer directly
355 c = fmt.Sprintf("(**%s)(unsafe.Pointer(%s))", baseName, n)
356 } else {
357 c = fmt.Sprintf("%sNewFromInternalPtr(%s)", baseName, n)
358 }
359 t = "uintptr"
360 }
361 case InterfacesType:
362 if stars == 0 {
363 c = n
364 t = "uintptr"
365 } else {
366 c = fmt.Sprintf("%s{Ptr: %s}", t+"Base", n)
367 t = strings.Repeat("*", stars-1) + "uintptr"
368 }
369 }
370 }
371 f.Pure.Names = append(f.Pure.Names, n)
372 f.Pure.Types = append(f.Pure.Types, t)
373 f.Pure.Call = append(f.Pure.Call, c)
374 f.Pure.Full = append(f.Pure.Full, n+" "+t)
375}
376
377func (f *funcArgsTemplate) Add(p Parameter, ins string, ns string, kinds KindMap, ctx ArgContext) {
378 // get the lookup namespace
379 // as if the interface namespace is non-empty
380 // means we can also lookup in the namespace of the interface
381 lns := ns
382 if ins != "" {
383 lns = ins
384 }
385 goType := p.Translate(lns, kinds)
386 kind := kinds.Kind(lns, goType)
387
388 // Save the original type name before normalization for callback lookup
389 originalType := goType
390
391 stars := strings.Count(goType, "*")
392 goType = util.NormalizeNamespace(ns, goType, true)
393
394 if kind != OtherType && kind != UnknownType {
395 goType = util.AddNamespace(goType, ins)
396 }
397 if stars > 0 {
398 goType = util.StarsInFront(strings.ReplaceAll(goType, "*", ""), stars)
399 }
400
401 // Get a suitable variable name
402 varName := p.VarName()
403
404 isOut := p.Direction == "out"
405
406 transferFull := p.TransferOwnership.TransferOwnership == "full"
407 f.AddAPI(goType, varName, kind, ns, p.Nullable, isOut, ctx, transferFull)
408 f.AddPure(goType, varName, kind, isOut, p.Nullable, ctx, transferFull)
409
410 // For GError record parameters in signal/callback contexts (C→Go), the type
411 // is collapsed to uintptr by Type.Template(). Override the API type to
412 // *glib.Error so consumers get a proper Go error, and track the Pure index
413 // so PuregoSignalCall() can emit the unsafe.Pointer cast.
414 if ctx == ArgsFromCToGo && !isOut && goType == "uintptr" && p.Type != nil && isGErrorType(p.Type.Name) {
415 gerrorGoType := "glib.Error"
416 if strings.ToLower(ns) == "glib" {
417 gerrorGoType = "Error"
418 }
419 // Override API type from uintptr to *glib.Error
420 apiIdx := len(f.API.Types) - 1
421 f.API.Types[apiIdx] = "*" + gerrorGoType
422 f.API.Full[apiIdx] = varName + " *" + gerrorGoType
423 // Pure stays uintptr; record the index for signal call casting
424 pureIdx := len(f.Pure.Types) - 1
425 f.GErrors = append(f.GErrors, GErrorParam{
426 Index: pureIdx,
427 GoType: gerrorGoType,
428 })
429 }
430
431 // Upstream purego does not support direct array parameters (reflect.Array kind).
432 // Fixed-size C arrays like "int fds[2]" are pointer params at the ABI level.
433 // For non-out fixed-size array params, change the pure signature to *[N]T and
434 // pass ¶m from the API wrapper so purego sees a pointer.
435 if p.Array != nil && p.Array.FixedSize > 0 && !isOut {
436 idx := len(f.Pure.Types) - 1
437 f.Pure.Types[idx] = "*" + f.Pure.Types[idx]
438 f.Pure.Full[idx] = f.Pure.Names[idx] + " " + f.Pure.Types[idx]
439 apiIdx := len(f.API.Call) - 1
440 f.API.Call[apiIdx] = "&" + f.API.Call[apiIdx]
441 f.API.CallWithRefs[apiIdx] = "&" + f.API.CallWithRefs[apiIdx]
442 }
443
444 // For callback parameters (not out parameters), populate callback metadata
445 // This enables the template to generate proper closure wrapping
446 if kind == CallbackType && !isOut {
447 if cb, ok := kinds.GetCallback(lns, originalType); ok {
448 // Determine the callback's namespace from the original type name
449 // e.g., "gio.AsyncReadyCallback" -> "gio", "AsyncReadyCallback" -> lns
450 cbNs := lns
451 if parts := strings.Split(originalType, "."); len(parts) > 1 {
452 cbNs = parts[0]
453 }
454
455 // Get the callback's pure argument types and return type
456 // Use cbNs (callback's namespace) for proper type lookups
457 cbArgs := cb.Parameters.Template(cbNs, "", kinds, cb.Throws, ArgsFromCToGo)
458 var retRaw string
459 if cb.ReturnValue != nil {
460 cbRet := cb.ReturnValue.Template(cbNs, "", kinds, cb.Throws)
461 retRaw = cbRet.Raw
462 }
463
464 qualifiedPureTypes := qualifyCallbackTypes(cbArgs.Pure.Types, cbNs, ns)
465 callArgs := make([]string, len(qualifiedPureTypes))
466 for i := range qualifiedPureTypes {
467 callArgs[i] = fmt.Sprintf("arg%d", i)
468 if qualifiedPureTypes[i] == "string" {
469 // C callback string parameters are char* pointers in ABI.
470 qualifiedPureTypes[i] = "uintptr"
471 callArgs[i] = fmt.Sprintf("core.GoString(arg%d)", i)
472 }
473 }
474 qualifiedRetRaw := qualifyCallbackType(retRaw, cbNs, ns)
475
476 f.Callbacks = append(f.Callbacks, CallbackParam{
477 Name: varName,
478 TypeName: strings.TrimPrefix(goType, "*"),
479 PureTypes: qualifiedPureTypes,
480 CallArgs: callArgs,
481 RetRaw: qualifiedRetRaw,
482 Nullable: p.Nullable,
483 })
484
485 // Update CallWithRefs to use {name}Ref since we have the callback info
486 // for generating the closure wrapper
487 lastIdx := len(f.API.CallWithRefs) - 1
488 f.API.CallWithRefs[lastIdx] = varName + "Ref"
489 }
490 }
491}
492
493func (f *funcArgsTemplate) AddThrows(ns string) {
494 f.API.Call = append(f.API.Call, "&cerr")
495 f.API.CallWithRefs = append(f.API.CallWithRefs, "&cerr")
496 if strings.ToLower(ns) != "glib" {
497 f.Pure.Types = append(f.Pure.Types, "**glib.Error")
498 } else {
499 f.Pure.Types = append(f.Pure.Types, "**Error")
500 }
501}
502
503type CallbackTemplate struct {
504 Doc string
505 Name string
506 Args funcArgsTemplate
507 Ret funcRetTemplate
508}
509
510type AliasTemplate struct {
511 // Name is the name of the alias given to the Go type declaration
512 Name string
513
514 // Doc is the documentation of the alias
515 Doc string
516
517 // Value is the value for the alias as a Go type
518 Value string
519
520 // TypeGetter is the function to get the GLib type
521 TypeGetter string
522}
523
524type RecordField struct {
525 // Name is the Go name of the field
526 Name string
527
528 // Type is the Go type of the field
529 Type string
530}
531
532type CallbackAccessor struct {
533 // Name is the Go name of the callback field (without x prefix)
534 Name string
535
536 // CName is the raw c name
537 CName string
538
539 // Doc is the documentation for the callback
540 Doc string
541
542 // CallbackType is the name of the callback function type
543 CallbackType string
544
545 // Args are the callback function arguments template
546 Args funcArgsTemplate
547
548 // Ret is the callback function return template
549 Ret funcRetTemplate
550}
551
552type RecordTemplate struct {
553 // Name is the name of the record given to the Go type declaration
554 Name string
555
556 // Doc is the documentation of the alias
557 Doc string
558
559 // Constructors is the slice of functions that create the class struct
560 Constructors []FuncTemplate
561
562 // Receivers is the slice of functions that have value receivers to the struct
563 Receivers []FuncTemplate
564
565 // Fields is the list of record fields
566 Fields []RecordField
567
568 // CallbackAccessors are the setter/getter methods for callback fields
569 CallbackAccessors []CallbackAccessor
570
571 // TypeGetter is the function to get the GLib type
572 TypeGetter string
573}
574
575type enumValues struct {
576 // Doc is the documentation for the value
577 Doc string
578 // Name is the name of the enumeration value
579 Name string
580 // Value is the actual underlying value
581 Value int
582}
583
584type EnumTemplate struct {
585 // Name is the name of the enumeration declared as the Go type for the int
586 Name string
587 // Doc is the documentation for the enumeration
588 Doc string
589 // Values are the list of values for the enumeration
590 Values []enumValues
591 // TypeGetter is the function to get the GLib type
592 TypeGetter string
593}
594
595type ConstantTemplate struct {
596 // Name is the name of the constant
597 Name string
598 // Doc is the documentation for the constant
599 Doc string
600 // Type is the Go type for the constant
601 Type string
602 // Values are the list of values for the constant
603 Value string
604}
605
606type funcRetTemplate struct {
607 // Raw is the raw value for the underlying purego function
608 Raw string
609 // Value is the underlying return value as a Go type
610 Value string
611 // Class indicates whether or not the return value is a class
612 Class bool
613 // RefSink indicates whether or not we should increase the reference count using obj.RefSink()
614 RefSink bool
615 // Throws indicates whether or not this function throws
616 Throws bool
617}
618
619func (fr *funcRetTemplate) Instance() string {
620 val := fr.Value + "{}"
621 if strings.HasPrefix(fr.Value, "*") {
622 return "&" + val[1:]
623 }
624 return val
625}
626
627func (fr *funcRetTemplate) Return() string {
628 if fr.Throws {
629 if fr.Value == "" {
630 return "error"
631 }
632 return fmt.Sprintf("(%s, error)", fr.Value)
633 }
634 return fr.Value
635}
636
637func (fr *funcRetTemplate) HasReturn() bool {
638 return fr.Value != "" || fr.Throws
639}
640
641func (fr *funcRetTemplate) Preamble(nglib bool) string {
642 preamb := strings.Builder{}
643 if fr.Class {
644 preamb.WriteString("var cls ")
645 preamb.WriteString(fr.Value)
646 preamb.WriteString("\n")
647 }
648 if fr.Throws {
649 preamb.WriteString("var cerr *")
650 if nglib {
651 preamb.WriteString("glib.")
652 }
653 preamb.WriteString("Error\n")
654 }
655 return preamb.String()
656}
657
658func (fr *funcRetTemplate) Fmt(ngo bool) string {
659 if !fr.HasReturn() {
660 return ""
661 }
662 after := strings.Builder{}
663 val := "cret"
664 if fr.Class {
665 if fr.Throws {
666 after.WriteString(`
667 if cret == 0 {
668 return nil, cerr
669 }
670`)
671 } else {
672 after.WriteString(`
673 if cret == 0 {
674 return nil
675 }
676`)
677 }
678 if fr.RefSink {
679 if ngo {
680 after.WriteString("gobject.")
681 }
682 after.WriteString("IncreaseRef(cret)\n")
683 }
684 after.WriteString("cls = ")
685 after.WriteString(fr.Instance())
686 after.WriteString("\n")
687 after.WriteString("cls.Ptr = cret\n")
688 val = "cls"
689 }
690 if fr.Throws {
691 after.WriteString("if cerr == nil {\n")
692 after.WriteString("return ")
693 if fr.Value != "" {
694 after.WriteString(val)
695 after.WriteString(",")
696 }
697 after.WriteString("nil\n")
698 after.WriteString("}\n")
699 after.WriteString("return ")
700 if fr.Value != "" {
701 after.WriteString(val)
702 after.WriteString(",")
703 }
704 after.WriteString("cerr\n")
705 return after.String()
706 }
707 after.WriteString("return ")
708 after.WriteString(val)
709 return after.String()
710}
711
712type FuncTemplate struct {
713 // Name is the name of the function declared as the Go function variable and public exposed API
714 Name string
715 // CName is the raw c name to be passed to purego register
716 CName string
717 // Doc is the documentation for the function
718 Doc string
719 // Args are the arguments
720 Args funcArgsTemplate
721 // Ret is the return argument
722 Ret funcRetTemplate
723}
724
725type InterfaceFuncTemplate struct {
726 Namespace string
727 FullName string
728 FuncTemplate
729}
730
731type SignalsTemplate struct {
732 Doc string
733 Name string
734 CName string
735 Args funcArgsTemplate
736 Ret funcRetTemplate
737 Detailed bool
738}
739
740type PropertyTemplate struct {
741 // Doc is the documentation for the property
742 Doc string
743 // Name is the Go name for the property
744 Name string
745 // CName is the raw c name
746 CName string
747 // GoType is the Go type for the property
748 GoType string
749 // GValueType is the GObject Type constant (e.g. "TypeBooleanVal")
750 GValueType string
751 // SetMethod is the Value setter method name (e.g. "SetBoolean")
752 SetMethod string
753 // GetMethod is the Value getter method name (e.g. "GetBoolean")
754 GetMethod string
755 // Readable indicates if this property can be read
756 Readable bool
757 // Writable indicates if this property can be written
758 Writable bool
759}
760
761type ClassTemplate struct {
762 // Doc is the documentation for the class
763 Doc string
764 // Name is the name of the class that is given to the Go struct
765 Name string
766 // Parent is a non-empty string of the embedded parent struct
767 Parent string
768 // Constructors is the slice of functions that create the class struct
769 Constructors []FuncTemplate
770 // Receivers is the slice of functions that have value receivers to the struct
771 Receivers []FuncTemplate
772 // Interfaces are receiver methods that are implemented because it needs to satisfy a certain interface
773 Interfaces []InterfaceTemplate
774 // Functions are the Go function declarations
775 Functions []FuncTemplate
776 // Properties are the property getters and setters
777 Properties []PropertyTemplate
778 // Signals are helpers for ConnectX receivers
779 Signals []SignalsTemplate
780 // TypeGetter is the function to get the GLib type
781 TypeGetter string
782}
783
784type InterfaceTemplate struct {
785 Doc string
786 Name string
787 // Methods is the methods that this interface defines
788 Methods []InterfaceFuncTemplate
789 // Properties are the property getters and setters
790 Properties []PropertyTemplate
791 // TypeGetter is the function to get the GLib type
792 TypeGetter string
793}
794
795type TemplateArg struct {
796 // PkgName is the name of the package, declared at the top-level
797 PkgName string
798 // PkgEnv is the name of the package in the load environment variable
799 PkgEnv string
800 // PkgConfigName is the pkg-config package name from the GIR file
801 PkgConfigName string
802 // SharedLibraries is the list of shared library names from the GIR file
803 SharedLibraries []string
804 // NeedsInit declares whether or not this file needs an init code to register functions with purego
805 NeedsInit bool
806 // NeedsCore indicates if core helpers are required even without init.
807 NeedsCore bool
808 // HasReceiverCallbacks indicates if any receiver method has callback parameters
809 // This is used to conditionally import unsafe and purego
810 HasReceiverCallbacks bool
811 // HasFunctionCallbacks indicates if any standalone function has callback parameters
812 HasFunctionCallbacks bool
813 // HasSignalStrings indicates if any signal has string parameters that need
814 // core.GoString() conversion in the purego callback closure.
815 HasSignalStrings bool
816 // HasTypeGetters indicates if any record, class, interface, alias, or enum
817 // in this file has a GLib type getter that uses types.GType.
818 HasTypeGetters bool
819 // NeedsGLib indicates if the generated file uses glib.* symbols.
820 NeedsGLib bool
821 // NeedsGObject indicates if the generated file uses gobject.* symbols.
822 NeedsGObject bool
823 // CrossPkgImports are fully qualified import paths for cross-package
824 // references detected in the generated code (e.g. gio.*, cairo.*, pango.*).
825 CrossPkgImports []string
826 // Imports defines the package imports that we need
827 // This does not include purego
828 // As the template already includes that if `NeedsInit` is set to true
829 Imports []string
830 // Aliases are type aliases declared as type ... = ...
831 Aliases []AliasTemplate
832 // Aliases are structs that are not classes
833 Records []RecordTemplate
834 // Callbacks are functions that will be converted with purego to uintptr
835 Callbacks []CallbackTemplate
836 // Enums are enumerations declared as const ... .... = ....
837 Enums []EnumTemplate
838 // Constants are declared as const ... .... = ....
839 Constants []ConstantTemplate
840 // Functions are the Go function declarations
841 Functions []FuncTemplate
842 // Interfaces is the list of interfaces that this package implements
843 Interfaces []InterfaceTemplate
844 // Classes are the Go struct with receiver declarations
845 Classes []ClassTemplate
846}