v0.2.2 9100209

types.go RawHistoryFolder

1// package types implements types as found in gir XML files
2// NOTE: This was copied largely from (the type definitions) from https://github.com/diamondburned/gotk4
3package types
4
5import (
6	"encoding/xml"
7	"fmt"
8	"strconv"
9	"strings"
10
11	"github.com/bnema/puregotk/internal/gir/util"
12)
13
14// convList maps the given GIR primitive type to a Go builtin type.
15// See https://github.com/diamondburned/gotk4/blob/fd960d20b525a07580938d10a214336bafb47d12/gir/girgen/types/types.go#LL483C1-L512C2
16var convList = map[string]string{
17	"none":     "",
18	"gboolean": "bool",
19	"gfloat":   "float32",
20	"gdouble":  "float64",
21	"gint":     "int",
22	"gssize":   "int",
23	"gint8":    "int8",
24	"gint16":   "int16",
25	"gshort":   "int16",
26	"gint32":   "int32",
27	"glong":    "int",
28	"int32":    "int32",
29	"gint64":   "int64",
30	"guint":    "uint",
31	"gsize":    "uint",
32	"guchar":   "byte",
33	"gchar":    "byte",
34	"guint8":   "byte", // some weird cases
35	"guint16":  "uint16",
36	"gushort":  "uint16",
37	"guint32":  "uint32",
38	"gulong":   "uint",
39	"gunichar": "uint32",
40	"guint64":  "uint64",
41	"guintptr": "uintptr",
42	"utf8":     "string",
43	"filename": "string",
44	"GType":    "types.GType",
45	"uid_t":    "uint",
46	"pid_t":    "int",
47	"time_t":   "int",
48	"gintptr":  "int",
49
50	// these are probably not correct but needed to compile
51	"_Value__data__union": "uint64",
52	"long double":         "float64",
53	"va_list":             "[]interface{}",
54	"gpointer":            "uintptr",
55	"const char*":         "string",
56	"const char**":        "[]string",
57	"char**":              "[]string",
58	// not exported
59	"HarfBuzz.feature_t": "uintptr",
60	"HarfBuzz.font_t":    "uintptr",
61	//"GLib.Quark": "byte",
62	//"Allocation": "uintptr",
63}
64
65// Repository represents a GObject Introspection Repository, which contains the
66// includes, C includes and namespaces of a single gir file.
67type Repository struct {
68	XMLName xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 repository"`
69
70	Version             string `xml:"version,attr"`
71	CIdentifierPrefixes string `xml:"http://www.gtk.org/introspection/c/1.0 identifier-prefixes,attr"`
72	CSymbolPrefixes     string `xml:"http://www.gtk.org/introspection/c/1.0 symbol-prefixes,attr"`
73
74	Includes   []Include   `xml:"http://www.gtk.org/introspection/core/1.0 include"`
75	CIncludes  []CInclude  `xml:"http://www.gtk.org/introspection/c/1.0 include"`
76	Packages   []Package   `xml:"http://www.gtk.org/introspection/core/1.0 package"`
77	Namespaces []Namespace `xml:"http://www.gtk.org/introspection/core/1.0 namespace"`
78}
79
80// https://gitlab.gnome.org/GNOME/gobject-introspection/-/blob/master/docs/gir-1.2.rnc
81
82type Alias struct {
83	XMLName xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 alias"`
84
85	Name  string `xml:"name,attr"`
86	CType string `xml:"http://www.gtk.org/introspection/c/1.0 type,attr"`
87
88	InfoAttrs
89	InfoElements
90
91	Type Type `xml:"http://www.gtk.org/introspection/core/1.0 type"`
92}
93
94func (a *Alias) Template(ns string, kinds KindMap) string {
95	if v, ok := convList[a.CType]; ok {
96		return util.NormalizeNamespace(ns, v, true)
97	}
98	return a.Type.Template(ns, kinds, false)
99}
100
101type AnyType struct {
102	// Possible variants.
103	Type  *Type  `xml:"http://www.gtk.org/introspection/core/1.0 type"`
104	Array *Array `xml:"http://www.gtk.org/introspection/core/1.0 array"`
105}
106
107func (a *AnyType) Translate(ns string, kinds KindMap) string {
108	if a == nil {
109		panic("unknown type found")
110	}
111	t := a.Type
112	if t == nil {
113		if a.Array == nil {
114			// no type information available
115			return ""
116		}
117		return a.Array.Template(ns, kinds)
118	}
119	return a.Type.Template(ns, kinds, false)
120}
121
122type Annotation struct {
123	XMLName xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 attribute"`
124	Name    string   `xml:"name,attr"`
125	Value   string   `xml:"value,attr"`
126}
127
128type Array struct {
129	XMLName        xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 array"`
130	Name           string   `xml:"name,attr"`
131	CType          string   `xml:"http://www.gtk.org/introspection/c/1.0 type,attr"`
132	Length         *int     `xml:"length,attr"` // ix of .Parameters
133	ZeroTerminated *bool    `xml:"zero-terminated,attr"`
134	FixedSize      int      `xml:"fixed-size,attr"`
135	Introspectable bool     `xml:"introspectable,attr"`
136	// Type is the array's inner type.
137	Type *Type `xml:"http://www.gtk.org/introspection/core/1.0 type"`
138}
139
140func (a *Array) Size() int {
141	// there is a Length property
142	// but it seems that GTK doesn't really use this
143	// see e.g. gtk_css_provider_load_from_data
144	//if a.Length != nil {
145	//	return *a.Length
146	//}
147	return a.FixedSize
148}
149
150func ReplaceSize(str string, n int) string {
151	trimmed := strings.TrimPrefix(str, "*")
152	if trimmed == str {
153		trimmed = strings.TrimPrefix(str, "[]")
154	}
155	return fmt.Sprintf("[%d]%s", n, trimmed)
156}
157
158func (a *Array) Template(ns string, kinds KindMap) string {
159	// Does the c type exist in our little hacky conversion rule?
160	if v, ok := convList[a.CType]; ok {
161		return v
162	}
163	// default case of an array is just a pointer
164	ret := "uintptr"
165
166	if a.Type != nil {
167		t := a.Type.Template(ns, kinds, true)
168		if strings.Count(t, "*") > 0 {
169			return "uintptr"
170		}
171		ret = "[]" + t
172	}
173
174	// Check if there is a fixed size
175	n := a.Size()
176	if n > 0 {
177		return ReplaceSize(ret, n)
178	}
179	return ret
180}
181
182// IsZeroTerminated returns true if the Array is zero-terminated. It accounts
183// for edge cases of the structure.
184func (a Array) IsZeroTerminated() bool {
185	return a.Name == "" && (a.ZeroTerminated == nil || *a.ZeroTerminated)
186}
187
188type Bitfield struct {
189	XMLName xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 bitfield"`
190
191	Name         string `xml:"name,attr"` // Go case
192	CType        string `xml:"http://www.gtk.org/introspection/c/1.0 type,attr"`
193	GLibTypeName string `xml:"http://www.gtk.org/introspection/glib/1.0 type-name,attr"`
194	GLibGetType  string `xml:"http://www.gtk.org/introspection/glib/1.0 get-type,attr"`
195
196	Members   []Member   `xml:"http://www.gtk.org/introspection/core/1.0 member"`
197	Functions []Function `xml:"http://www.gtk.org/introspection/core/1.0 function"`
198
199	InfoAttrs
200	InfoElements
201}
202
203func (b *Bitfield) Template(ns string) EnumTemplate {
204	els := make([]enumValues, len(b.Members))
205	for i, m := range b.Members {
206		v, err := strconv.Atoi(m.Value)
207		if err != nil {
208			panic(err)
209		}
210		// + Value needed to get rid of duplicates
211		els[i] = enumValues{
212			Doc:   m.Doc.StringSafe(),
213			Name:  util.SnakeToCamel(util.RemoveSnakePrefix(strings.ToLower(m.CIdentifier), ns)) + "Value",
214			Value: v,
215		}
216	}
217	return EnumTemplate{
218		Name:       util.SnakeToCamel(b.Name),
219		Doc:        b.Doc.StringSafe(),
220		Values:     els,
221		TypeGetter: b.GLibGetType,
222	}
223}
224
225type Signal struct {
226	XMLName   xml.Name   `xml:"http://www.gtk.org/introspection/glib/1.0 signal"`
227	Name      string     `xml:"name,attr"`
228	Detailed  bool       `xml:"detailed,attr"`
229	When      SignalWhen `xml:"when,attr"`
230	Action    bool       `xml:"action,attr"`
231	NoHooks   bool       `xml:"no-hooks,attr"`
232	NoRecurse bool       `xml:"no-recurse,attr"`
233	InfoElements
234	Parameters  *Parameters  `xml:"http://www.gtk.org/introspection/core/1.0 parameters"`
235	ReturnValue *ReturnValue `xml:"http://www.gtk.org/introspection/core/1.0 return-value"`
236}
237
238type SignalWhen string
239
240const (
241	SignalWhenFirst   = "first"
242	SignalWhenLast    = "last"
243	SignalWhenCleanup = "cleanup"
244)
245
246type SourcePosition struct {
247	XMLName  xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 source-position"`
248	Filename string   `xml:"filename,attr"`
249	Line     int      `xml:"line,attr"`
250	Column   int      `xml:"column,attr"`
251}
252
253type TransferOwnership struct {
254	TransferOwnership string `xml:"transfer-ownership,attr"`
255}
256
257type Type struct {
258	XMLName xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 type"`
259
260	Name           string `xml:"name,attr"`
261	CType          string `xml:"http://www.gtk.org/introspection/c/1.0 type,attr"`
262	Introspectable *bool  `xml:"introspectable,attr"`
263
264	DocElements
265	// Types is the type's inner types.
266	Types []Type `xml:"http://www.gtk.org/introspection/core/1.0 type"`
267}
268
269func (typ *Type) IsIntrospectable() bool {
270	return typ.Introspectable == nil || *typ.Introspectable
271}
272
273func (t *Type) Template(ns string, kinds KindMap, array bool) string {
274	if v, ok := convList[t.Name]; ok {
275		return v
276	}
277
278	_type := util.NormalizeNamespace(ns, t.Name, true)
279
280	kind := kinds.Kind(ns, _type)
281	// find the total pointer count
282	count := strings.Count(t.CType, "*")
283	w := strings.Trim(t.CType, "*")
284	if w == "gpointer" {
285		count += 1
286	}
287	// set the same pointer types on the name
288	if count > 0 && kind != CallbackType {
289		_type = strings.Repeat("*", count) + _type
290	} else if kind == RecordsType {
291		if array {
292			return _type
293		}
294		// if it's not a pointer
295		// then purego doesn't support it (struct by value is not supported
296		// so return uintptr
297		_type = "uintptr"
298	}
299	return _type
300}
301
302type Union struct {
303	XMLName xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 union"`
304
305	Name          string `xml:"name,attr"` // Go case
306	CType         string `xml:"http://www.gtk.org/introspection/c/1.0 type,attr"`
307	CSymbolPrefix string `xml:"http://www.gtk.org/introspection/c/1.0 symbol-prefix,attr"`
308	GLibTypeName  string `xml:"http://www.gtk.org/introspection/glib/1.0 type-name,attr"`
309	GLibGetType   string `xml:"http://www.gtk.org/introspection/glib/1.0 get-type,attr"`
310
311	InfoAttrs
312	InfoElements
313
314	Fields       []Field       `xml:"http://www.gtk.org/introspection/core/1.0 field"`
315	Constructors []Constructor `xml:"http://www.gtk.org/introspection/core/1.0 constructor"`
316	Methods      []Method      `xml:"http://www.gtk.org/introspection/core/1.0 method"`
317	Functions    []Function    `xml:"http://www.gtk.org/introspection/core/1.0 function"`
318	Records      []Record      `xml:"http://www.gtk.org/introspection/core/1.0 record"`
319}
320
321type VarArgs struct {
322	XMLName xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 varargs"`
323}
324
325type VirtualMethod struct {
326	XMLName xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 virtual-method"`
327
328	Invoker string `xml:"invoker,attr"`
329	CallableAttrs
330}
331
332type Boxed struct{}
333
334type CInclude struct {
335	XMLName xml.Name `xml:"http://www.gtk.org/introspection/c/1.0 include"`
336	Name    string   `xml:"name,attr"`
337}
338
339type CallableAttrs struct {
340	Name        string       `xml:"name,attr"`
341	CIdentifier string       `xml:"http://www.gtk.org/introspection/c/1.0 identifier,attr"`
342	ShadowedBy  string       `xml:"shadowed-by,attr"`
343	Shadows     string       `xml:"shadows,attr"`
344	Throws      bool         `xml:"throws,attr"`
345	MovedTo     string       `xml:"moved-to,attr"`
346	Parameters  *Parameters  `xml:"http://www.gtk.org/introspection/core/1.0 parameters"`
347	ReturnValue *ReturnValue `xml:"http://www.gtk.org/introspection/core/1.0 return-value"`
348	InfoAttrs
349	InfoElements
350}
351
352type Callback struct {
353	XMLName xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 callback"`
354	CallableAttrs
355}
356
357type Class struct {
358	XMLName  xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 class"`
359	Name     string   `xml:"name,attr"`
360	Parent   string   `xml:"parent,attr"`
361	Abstract bool     `xml:"abstract,attr"`
362
363	CType         string `xml:"http://www.gtk.org/introspection/c/1.0 type,attr"`
364	CSymbolPrefix string `xml:"http://www.gtk.org/introspection/c/1.0 symbol-prefix,attr"`
365
366	GLibTypeName   string `xml:"http://www.gtk.org/introspection/glib/1.0 type-name,attr"`
367	GLibGetType    string `xml:"http://www.gtk.org/introspection/glib/1.0 get-type,attr"`
368	GLibTypeStruct string `xml:"http://www.gtk.org/introspection/glib/1.0 type-struct,attr"`
369
370	InfoAttrs
371	InfoElements
372
373	Functions      []Function      `xml:"http://www.gtk.org/introspection/core/1.0 function"`
374	Implements     []Implements    `xml:"http://www.gtk.org/introspection/core/1.0 implements"`
375	Constructors   []Constructor   `xml:"http://www.gtk.org/introspection/core/1.0 constructor"`
376	Methods        []Method        `xml:"http://www.gtk.org/introspection/core/1.0 method"`
377	VirtualMethods []VirtualMethod `xml:"http://www.gtk.org/introspection/core/1.0 virtual-method"`
378	Fields         []Field         `xml:"http://www.gtk.org/introspection/core/1.0 field"`
379	Properties     []Property      `xml:"http://www.gtk.org/introspection/core/1.0 property"`
380	Signals        []Signal        `xml:"http://www.gtk.org/introspection/glib/1.0 signal"`
381}
382
383type Constant struct {
384	XMLName xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 constant"`
385	Name    string   `xml:"name,attr"`
386	Value   string   `xml:"value,attr"`
387	CType   string   `xml:"http://www.gtk.org/introspection/c/1.0 type,attr"`
388
389	Type Type `xml:"http://www.gtk.org/introspection/core/1.0 type"`
390
391	InfoAttrs
392	InfoElements
393}
394
395func (c *Constant) Template(ns string, kinds KindMap) ConstantTemplate {
396	t := c.Type.Template(ns, kinds, false)
397	v := c.Value
398
399	switch t {
400	case "string":
401		v = fmt.Sprintf(`"%s"`, v)
402	}
403
404	return ConstantTemplate{
405		Name:  c.Name,
406		Doc:   c.Doc.StringSafe(),
407		Type:  t,
408		Value: v,
409	}
410}
411
412type Constructor struct {
413	XMLName xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 constructor"`
414	CallableAttrs
415}
416
417type Doc struct {
418	XMLName  xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 doc"`
419	Filename string   `xml:"filename,attr"`
420	String   string   `xml:",innerxml"`
421	Line     int      `xml:"line,attr"`
422}
423
424func (d *Doc) StringSafe() string {
425	if d == nil {
426		return ""
427	}
428	lines := strings.Split(d.String, "\n")
429	for i, l := range lines {
430		lines[i] = "// " + l
431	}
432	return strings.Join(lines, "\n")
433}
434
435type DocDeprecated struct {
436	XMLName xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 doc-deprecated"`
437	String  string   `xml:",innerxml"`
438}
439
440type DocElements struct {
441	Doc            *Doc
442	DocDeprecated  *DocDeprecated
443	SourcePosition *SourcePosition
444}
445
446func (d *DocElements) FilenameSafe() string {
447	if d == nil || (d.SourcePosition == nil && d.Doc == nil) {
448		return "main.go"
449	}
450	if d.SourcePosition != nil {
451		return util.TranslateFilename(d.SourcePosition.Filename)
452	}
453	return util.TranslateFilename(d.Doc.Filename)
454}
455
456type Enum struct {
457	XMLName xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 enumeration"`
458
459	Name            string `xml:"name,attr"` // Go case
460	CType           string `xml:"http://www.gtk.org/introspection/c/1.0 type,attr"`
461	GLibTypeName    string `xml:"http://www.gtk.org/introspection/glib/1.0 type-name,attr"`
462	GLibGetType     string `xml:"http://www.gtk.org/introspection/glib/1.0 get-type,attr"`
463	GLibErrorDomain string `xml:"http://www.gtk.org/introspection/glib/1.0 error-domain,attr"`
464
465	Members   []Member   `xml:"http://www.gtk.org/introspection/core/1.0 member"`
466	Functions []Function `xml:"http://www.gtk.org/introspection/core/1.0 function"`
467
468	InfoAttrs
469	InfoElements
470}
471
472func (e *Enum) Template(ns string) EnumTemplate {
473	els := make([]enumValues, len(e.Members))
474
475	for i, m := range e.Members {
476		v, err := strconv.Atoi(m.Value)
477		if err != nil {
478			panic(err)
479		}
480		id := strings.ToLower(m.CIdentifier)
481		sID := util.RemoveSnakePrefix(id, ns)
482		els[i] = enumValues{
483			Doc: m.Doc.StringSafe(),
484			// + Value needed to get rid of duplicates
485			Name:  util.SnakeToCamel(sID) + "Value",
486			Value: v,
487		}
488	}
489	return EnumTemplate{
490		Name:       util.SnakeToCamel(e.Name),
491		Doc:        e.Doc.StringSafe(),
492		Values:     els,
493		TypeGetter: e.GLibGetType,
494	}
495}
496
497type Field struct {
498	XMLName  xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 field"`
499	Name     string   `xml:"name,attr"`
500	Bits     int      `xml:"bits,attr"`
501	Private  bool     `xml:"private,attr"`
502	Writable bool     `xml:"writable,attr"` // default false
503	Readable *bool    `xml:"readable,attr"` // default true
504	AnyType
505	Callback *Callback
506	Doc      *Doc
507}
508
509// IsReadable returns true if the field is readable.
510func (f Field) IsReadable() bool {
511	return f.Readable == nil || *f.Readable
512}
513
514type Function struct {
515	XMLName xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 function"`
516	CallableAttrs
517}
518
519type Implements struct {
520	XMLName xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 implements"`
521	Name    string   `xml:"name,attr"`
522}
523
524type Include struct {
525	XMLName xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 include"`
526	Name    string   `xml:"name,attr"`
527	Version string   `xml:"version,attr"`
528}
529
530type InfoAttrs struct {
531	Introspectable    *bool  `xml:"introspectable,attr"` // default true
532	Deprecated        bool   `xml:"deprecated,attr"`
533	DeprecatedVersion string `xml:"deprecated-version,attr"`
534	Version           string `xml:"version,attr"`
535	Stability         string `xml:"stability,attr"`
536}
537
538// IsIntrospectable returns true if the InfoAttrs indicates that the type is
539// introspectable.
540func (inf InfoAttrs) IsIntrospectable() bool {
541	return inf.Introspectable == nil || *inf.Introspectable
542}
543
544type InfoElements struct {
545	DocElements
546	Annotations []Annotation `xml:"http://www.gtk.org/introspection/core/1.0 attribute"`
547}
548
549type InstanceParameter struct {
550	XMLName xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 instance-parameter"`
551	ParameterAttrs
552}
553
554type Interface struct {
555	XMLName xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 interface"`
556	Name    string   `xml:"name,attr"`
557
558	CType         string `xml:"http://www.gtk.org/introspection/c/1.0 type,attr"`
559	CSymbolPrefix string `xml:"http://www.gtk.org/introspection/c/1.0 symbol-prefix,attr"`
560
561	GLibTypeName   string `xml:"http://www.gtk.org/introspection/glib/1.0 type-name,attr"`
562	GLibGetType    string `xml:"http://www.gtk.org/introspection/glib/1.0 get-type,attr"`
563	GLibTypeStruct string `xml:"http://www.gtk.org/introspection/glib/1.0 type-struct,attr"`
564
565	Functions      []Function      `xml:"http://www.gtk.org/introspection/core/1.0 function"`
566	Methods        []Method        `xml:"http://www.gtk.org/introspection/core/1.0 method"`
567	VirtualMethods []VirtualMethod `xml:"http://www.gtk.org/introspection/core/1.0 virtual-method"`
568	Prerequisites  []Prerequisite  `xml:"http://www.gtk.org/introspection/core/1.0 prerequisite"`
569	Properties     []Property      `xml:"http://www.gtk.org/introspection/core/1.0 property"`
570	Signals        []Signal        `xml:"http://www.gtk.org/introspection/glib/1.0 signal"`
571
572	InfoAttrs
573	InfoElements
574}
575
576type Member struct {
577	XMLName xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 member"`
578
579	Names       []xml.Attr `xml:"name,attr"`
580	Value       string     `xml:"value,attr"`
581	CIdentifier string     `xml:"http://www.gtk.org/introspection/c/1.0 identifier,attr"`
582	GLibNick    string     `xml:"http://www.gtk.org/introspection/glib/1.0 nick,attr"`
583
584	InfoAttrs
585	InfoElements
586}
587
588func (m Member) Name() string {
589	return m.nameAttr(xml.Name{Local: "name"})
590}
591
592func (m Member) GLibName() string {
593	return m.nameAttr(xml.Name{Space: "http://www.gtk.org/introspection/glib/1.0", Local: "name"})
594}
595
596func (m Member) nameAttr(name xml.Name) string {
597	for _, attr := range m.Names {
598		if attr.Name == name {
599			return attr.Value
600		}
601	}
602	return ""
603}
604
605type Method struct {
606	XMLName xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 method"`
607	CallableAttrs
608}
609
610type Namespace struct {
611	XMLName xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 namespace"`
612
613	Name                string `xml:"name,attr"`
614	Version             string `xml:"version,attr"`
615	CIdentifierPrefixes string `xml:"http://www.gtk.org/introspection/c/1.0 identifier-prefixes,attr"`
616	CSymbolPrefixes     string `xml:"http://www.gtk.org/introspection/c/1.0 symbol-prefixes,attr"`
617	Prefix              string `xml:"http://www.gtk.org/introspection/c/1.0 prefix,attr"`
618	SharedLibrary       string `xml:"shared-library,attr"`
619
620	Aliases     []Alias      `xml:"http://www.gtk.org/introspection/core/1.0 alias"`
621	Classes     []Class      `xml:"http://www.gtk.org/introspection/core/1.0 class"`
622	Interfaces  []Interface  `xml:"http://www.gtk.org/introspection/core/1.0 interface"`
623	Records     []Record     `xml:"http://www.gtk.org/introspection/core/1.0 record"`
624	Enums       []Enum       `xml:"http://www.gtk.org/introspection/core/1.0 enumeration"`
625	Functions   []Function   `xml:"http://www.gtk.org/introspection/core/1.0 function"`
626	Unions      []Union      `xml:"http://www.gtk.org/introspection/core/1.0 union"`
627	Bitfields   []Bitfield   `xml:"http://www.gtk.org/introspection/core/1.0 bitfield"`
628	Callbacks   []Callback   `xml:"http://www.gtk.org/introspection/core/1.0 callback"`
629	Constants   []Constant   `xml:"http://www.gtk.org/introspection/core/1.0 constant"`
630	Annotations []Annotation `xml:"http://www.gtk.org/introspection/core/1.0 attribute"`
631	Boxeds      []Boxed      `xml:"http://www.gtk.org/introspection/core/1.0 boxed"`
632}
633
634type Package struct {
635	XMLName xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 package"`
636	Name    string   `xml:"name,attr"`
637}
638
639type Parameter struct {
640	XMLName xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 parameter"`
641	ParameterAttrs
642}
643
644func (p *Parameter) Translate(ns string, kinds KindMap) string {
645	if p.Name == "..." {
646		return "...interface{}"
647	}
648	return p.AnyType.Translate(ns, kinds)
649}
650
651func (p *Parameter) VarName() string {
652	snaked := util.SnakeToCamel(p.Name)
653	if snaked == "..." {
654		return "varArgs"
655	}
656	// avoid clash between same name of type and var
657	// could also do first letter to lower?
658	return snaked + "Var"
659}
660
661func (p *Parameters) Template(ns string, ifacens string, kinds KindMap, throws bool, ctx ArgContext) funcArgsTemplate {
662	if p == nil {
663		return funcArgsTemplate{}
664	}
665	params := p.Parameters
666	if len(params) == 0 {
667		return funcArgsTemplate{}
668	}
669	args := funcArgsTemplate{}
670	for _, par := range params {
671		args.Add(par, ifacens, ns, kinds, ctx)
672	}
673	if throws {
674		args.AddThrows(ns)
675	}
676	return args
677}
678
679type ParameterAttrs struct {
680	Name            string `xml:"name,attr"`
681	Direction       string `xml:"direction,attr"`
682	Scope           string `xml:"scope,attr"`
683	Closure         *int   `xml:"closure,attr"`
684	Destroy         *int   `xml:"destroy,attr"`
685	CallerAllocates bool   `xml:"caller-allocates,attr"`
686	Skip            bool   `xml:"skip,attr"`
687	Optional        bool   `xml:"optional,attr"`
688	Nullable        bool   `xml:"nullable,attr"`
689
690	TransferOwnership
691	AnyType
692	Doc *Doc
693}
694
695type Parameters struct {
696	XMLName           xml.Name           `xml:"http://www.gtk.org/introspection/core/1.0 parameters"`
697	InstanceParameter *InstanceParameter `xml:"http://www.gtk.org/introspection/core/1.0 instance-parameter"`
698	Parameters        []Parameter        `xml:"http://www.gtk.org/introspection/core/1.0 parameter"`
699}
700
701type Prerequisite struct {
702	XMLName xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 prerequisite"`
703	Name    string   `xml:"name,attr"`
704}
705
706type Property struct {
707	XMLName           xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 property"`
708	Name              string   `xml:"name,attr"`
709	Writable          bool     `xml:"writable,attr"`
710	Readable          *bool    `xml:"readable,attr"` // default true
711	Construct         bool     `xml:"construct,attr"`
712	ConstructOnly     bool     `xml:"construct-only,attr"`
713	DefaultValue      string   `xml:"default-value,attr"`
714	Getter            string   `xml:"getter,attr"`
715	Setter            string   `xml:"setter,attr"`
716	TransferOwnership string   `xml:"transfer-ownership,attr"`
717
718	AnyType
719	InfoElements
720}
721
722func (p Property) IsReadable() bool {
723	return p.Readable == nil || *p.Readable
724}
725
726func (p *Property) Template(ns string, kinds KindMap) PropertyTemplate {
727	var (
728		goType                           = p.AnyType.Translate(ns, kinds)
729		cName                            = p.Name
730		gvalueType, setMethod, getMethod = mapGoTypeToGValue(goType)
731	)
732
733	return PropertyTemplate{
734		Doc:        p.Doc.StringSafe(),
735		Name:       util.DashToCamel(cName),
736		CName:      cName,
737		GoType:     goType,
738		GValueType: gvalueType,
739		SetMethod:  setMethod,
740		GetMethod:  getMethod,
741		Readable:   p.IsReadable(),
742		Writable:   p.Writable,
743	}
744}
745
746func mapGoTypeToGValue(goType string) (gvalueType, setMethod, getMethod string) {
747	switch strings.TrimPrefix(goType, "*") {
748	case "bool":
749		return "TypeBooleanVal", "SetBoolean", "GetBoolean"
750	case "byte":
751		return "TypeUcharVal", "SetUchar", "GetUchar"
752	case "int8":
753		return "TypeCharVal", "SetSchar", "GetSchar"
754	case "int":
755		return "TypeIntVal", "SetInt", "GetInt"
756	case "uint":
757		return "TypeUintVal", "SetUint", "GetUint"
758	case "int32":
759		return "TypeLongVal", "SetLong", "GetLong"
760	case "uint32":
761		return "TypeUlongVal", "SetUlong", "GetUlong"
762	case "int64":
763		return "TypeInt64Val", "SetInt64", "GetInt64"
764	case "uint64":
765		return "TypeUint64Val", "SetUint64", "GetUint64"
766	case "float32":
767		return "TypeFloatVal", "SetFloat", "GetFloat"
768	case "float64":
769		return "TypeDoubleVal", "SetDouble", "GetDouble"
770	case "string":
771		return "TypeStringVal", "SetString", "GetString"
772	case "uintptr":
773		return "TypePointerVal", "SetPointer", "GetPointer"
774	case "[]string":
775		return "BoxedStrv", "SetBoxed", "GetBoxed"
776	case "[]byte":
777		return "BoxedByteArray", "SetBoxed", "GetBoxed"
778	case "[]uintptr":
779		return "BoxedPtrArray", "SetBoxed", "GetBoxed"
780	default:
781		return "", "", ""
782	}
783}
784
785type Record struct {
786	XMLName              xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 record"`
787	Name                 string   `xml:"name,attr"`
788	CType                string   `xml:"http://www.gtk.org/introspection/c/1.0 type,attr"`
789	GLibTypeName         string   `xml:"http://www.gtk.org/introspection/glib/1.0 type-name,attr"`
790	GLibGetType          string   `xml:"http://www.gtk.org/introspection/glib/1.0 get-type,attr"`
791	CSymbolPrefix        string   `xml:"http://www.gtk.org/introspection/c/1.0 symbol-prefix,attr"`
792	GLibIsGTypeStructFor string   `xml:"http://www.gtk.org/introspection/glib/1.0 is-gtype-struct-for,attr"`
793	Disguised            bool     `xml:"disguised,attr"`
794	Foreign              bool     `xml:"foreign,attr"`
795
796	Fields       []Field       `xml:"http://www.gtk.org/introspection/core/1.0 field"`
797	Functions    []Function    `xml:"http://www.gtk.org/introspection/core/1.0 function"`
798	Unions       []Union       `xml:"http://www.gtk.org/introspection/core/1.0 union"`
799	Methods      []Method      `xml:"http://www.gtk.org/introspection/core/1.0 method"`
800	Constructors []Constructor `xml:"http://www.gtk.org/introspection/core/1.0 constructor"`
801	Properties   []Property    `xml:"http://www.gtk.org/introspection/core/1.0 property"`
802
803	InfoAttrs
804	InfoElements
805}
806
807type ReturnValue struct {
808	XMLName        xml.Name `xml:"http://www.gtk.org/introspection/core/1.0 return-value"`
809	Scope          string   `xml:"scope,attr"`
810	Closure        *int     `xml:"closure,attr"`
811	Destroy        *int     `xml:"destroy,attr"`
812	Introspectable bool     `xml:"introspectable,attr"`
813	Nullable       bool     `xml:"nullable,attr"`
814	Skip           bool     `xml:"skip,attr"`
815	AllowNone      bool     `xml:"allow-none,attr"`
816	TransferOwnership
817	DocElements
818	AnyType
819}
820
821func (r *ReturnValue) Template(ns string, ins string, kinds KindMap, throws bool) funcRetTemplate {
822	val := r.AnyType.Translate(ns, kinds)
823	raw := val
824	class := false
825	lns := ns
826	if ins != "" {
827		lns = ins
828	}
829	kind := kinds.Kind(lns, raw)
830	stars := strings.Count(val, "*")
831
832	if kind != OtherType && kind != UnknownType && kind != SliceType {
833		val = util.AddNamespace(val, ins)
834	}
835	if stars > 0 {
836		val = util.StarsInFront(strings.ReplaceAll(val, "*", ""), stars)
837	}
838	switch kind {
839	case ClassesType:
840		raw = "uintptr"
841		class = true
842		// TODO: why does this happen?
843		if strings.HasPrefix(val, "[]") {
844			class = false
845			val = "uintptr"
846		}
847	case InterfacesType:
848		raw = "uintptr"
849		val += "Base"
850		class = true
851	// callback returns should always be uintptr
852	// I needed this for glib.LogSetDefaultHandler
853	// Otherwise I got 'panic: reflect.MakeFunc: value of type *glib.LogFunc is not assignable to type glib.LogFunc'
854	case CallbackType:
855		raw = "uintptr"
856		val = "uintptr"
857	case SliceType:
858		// our purego fork supports string slices as return values
859		if val != "[]string" {
860			raw = "uintptr"
861			val = "uintptr"
862		}
863	}
864	return funcRetTemplate{
865		Raw:     raw,
866		Value:   val,
867		Class:   class,
868		RefSink: r.TransferOwnership.TransferOwnership == "none",
869		Throws:  throws,
870	}
871}

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