about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlexey Yerin <yyp@disroot.org>2025-07-02 22:13:11 +0300
committerAlexey Yerin <yyp@disroot.org>2025-07-02 22:13:11 +0300
commit88e9de918413e10086455bc08946b6f9d979f735 (patch)
tree57c90d8e62694da42c59766e60f6d632a1caaada
parent15f28a82dfd3e1c469ed3aa77aa9f431ba16908b (diff)
Attempt to fix subtyping issues in Gtk 4
-rw-r--r--cmd/hare-gi/emit.ha33
1 files changed, 31 insertions, 2 deletions
diff --git a/cmd/hare-gi/emit.ha b/cmd/hare-gi/emit.ha
index 5f137ed..f0b513e 100644
--- a/cmd/hare-gi/emit.ha
+++ b/cmd/hare-gi/emit.ha
@@ -100,8 +100,37 @@ fn emit_class(ctx: *context, class: *gir::class) (void | io::error) = {
 	fmt::fprintf(ctx.current.output, "export type {} = ",
 		fix_identifier(class.name))?;
 	if (len(class.entries) == 0) {
-		// opaque
-		fmt::fprintln(ctx.current.output, "*opaque;")?;
+		if (len(class.parent) != 0) {
+			fmt::fprint(ctx.current.output, "struct { parent: ")?;
+			let (first, second) = strings::cut(class.parent, ".");
+			let (ns, objname): (nullable *namespace, str) =
+				if (len(second) == 0) {
+					yield (ctx.current, first);
+				} else {
+					yield (get_namespace(ctx, first), second);
+				};
+			match (ns) {
+			case let ns: *namespace =>
+				match (lookup_type_in_namespace(ns, objname)) {
+				case let obj: (str, object_type) =>
+					assert(obj.1 == object_type::CLASS);
+					emit_object(ctx, ns, obj.0)?;
+				case =>
+					fmt::fprintf(ctx.current.output,
+						"#unresolved type {}#",
+						class.parent)?;
+				};
+			case null =>
+				fmt::fprintf(ctx.current.output,
+					"#unresolved type {}#", class.parent)?;
+			};
+			fmt::fprintln(ctx.current.output, " };")?;
+		} else {
+			// Note: this is completely wrong but using an undefined
+			// size type causes gdk::Event subclasses to fail
+			// compilation
+			fmt::fprintln(ctx.current.output, "*opaque;")?;
+		};
 	} else {
 		fmt::fprintln(ctx.current.output, "struct {")?;
 		for (let i = 0z; i < len(class.entries); i += 1) {