[vala/wip/error-gtype: 78/80] codegen: Emit GType definition for error domains
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/wip/error-gtype: 78/80] codegen: Emit GType definition for error domains
- Date: Mon, 14 Jan 2019 07:45:42 +0000 (UTC)
commit 1e6ae55a0657f67b698e4d7f9b3e1fecb13632c1
Author: Rico Tzschichholz <ricotz ubuntu com>
Date: Sat Nov 17 22:22:03 2018 +0100
codegen: Emit GType definition for error domains
Fixes https://gitlab.gnome.org/GNOME/vala/issues/699
codegen/Makefile.am | 1 +
codegen/valaccode.vala | 2 +-
codegen/valaccodeattribute.vala | 7 ++++
codegen/valaerrordomainregisterfunction.vala | 51 ++++++++++++++++++++++++++++
codegen/valagerrormodule.vala | 25 ++++++++++++++
codegen/valagirwriter.vala | 6 +++-
codegen/valagtypemodule.vala | 12 +++++++
codegen/valatyperegisterfunction.vala | 30 ++++++++++++++++
tests/girwriter/GirTest-1.0.gir-expected | 7 +++-
tests/girwriter/girtest.vala | 7 ++++
tests/girwriter/girtest.vapi-expected | 6 ++++
vala/valaerrorcode.vala | 16 +++++++++
12 files changed, 167 insertions(+), 3 deletions(-)
---
diff --git a/codegen/Makefile.am b/codegen/Makefile.am
index 036652ef3..64f5444f3 100644
--- a/codegen/Makefile.am
+++ b/codegen/Makefile.am
@@ -38,6 +38,7 @@ libvalaccodegen_la_VALASOURCES = \
valaclassregisterfunction.vala \
valactype.vala \
valaenumregisterfunction.vala \
+ valaerrordomainregisterfunction.vala \
valagasyncmodule.vala \
valagdbusclientmodule.vala \
valagdbusmodule.vala \
diff --git a/codegen/valaccode.vala b/codegen/valaccode.vala
index 8e6b6b4a3..012fcad70 100644
--- a/codegen/valaccode.vala
+++ b/codegen/valaccode.vala
@@ -211,7 +211,7 @@ namespace Vala {
}
public static string get_ccode_type_function (TypeSymbol sym) {
- assert (!((sym is Class && ((Class) sym).is_compact) || sym is ErrorCode || sym is
ErrorDomain || sym is Delegate));
+ assert (!((sym is Class && ((Class) sym).is_compact) || sym is ErrorCode || sym is Delegate));
return "%s_get_type".printf (get_ccode_lower_case_name (sym));
}
diff --git a/codegen/valaccodeattribute.vala b/codegen/valaccodeattribute.vala
index 1c3665f80..2e593172e 100644
--- a/codegen/valaccodeattribute.vala
+++ b/codegen/valaccodeattribute.vala
@@ -962,6 +962,13 @@ public class Vala.CCodeAttribute : AttributeCache {
} else {
return en.is_flags ? "G_TYPE_UINT" : "G_TYPE_INT";
}
+ } else if (sym is ErrorDomain) {
+ unowned ErrorDomain edomain = (ErrorDomain) sym;
+ if (get_ccode_has_type_id (edomain)) {
+ return get_ccode_upper_case_name (edomain, "TYPE_");
+ } else {
+ return "G_TYPE_INT";
+ }
} else {
return "G_TYPE_POINTER";
}
diff --git a/codegen/valaerrordomainregisterfunction.vala b/codegen/valaerrordomainregisterfunction.vala
new file mode 100644
index 000000000..b4be3295e
--- /dev/null
+++ b/codegen/valaerrordomainregisterfunction.vala
@@ -0,0 +1,51 @@
+/* valaerrordomainregisterfunction.vala
+ *
+ * Copyright (C) 2018 Rico Tzschichholz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Rico Tzschichholz <ricotz ubuntu com>
+ */
+
+using GLib;
+
+/**
+ * C function to register an error domain at runtime.
+ */
+public class Vala.ErrorDomainRegisterFunction : TypeRegisterFunction {
+ /**
+ * Specifies the error domain to be registered.
+ */
+ public weak ErrorDomain error_domain_reference { get; set; }
+
+ /**
+ * Creates a new C function to register the specified error domain at runtime.
+ *
+ * @param edomain an error domain
+ * @return newly created error domain register function
+ */
+ public ErrorDomainRegisterFunction (ErrorDomain edomain) {
+ error_domain_reference = edomain;
+ }
+
+ public override TypeSymbol get_type_declaration () {
+ return error_domain_reference;
+ }
+
+ public override SymbolAccessibility get_accessibility () {
+ return error_domain_reference.access;
+ }
+}
diff --git a/codegen/valagerrormodule.vala b/codegen/valagerrormodule.vala
index d29d09ca1..c01865168 100644
--- a/codegen/valagerrormodule.vala
+++ b/codegen/valagerrormodule.vala
@@ -56,6 +56,31 @@ public class Vala.GErrorModule : CCodeDelegateModule {
var cquark_fun = new CCodeFunction (quark_fun_name, get_ccode_name (gquark_type.data_type));
decl_space.add_function_declaration (cquark_fun);
+ decl_space.add_type_definition (new CCodeNewline ());
+
+ if (!get_ccode_has_type_id (edomain)) {
+ return;
+ }
+
+ decl_space.add_include ("glib-object.h");
+ decl_space.add_type_declaration (new CCodeNewline ());
+
+ var fun_name = get_ccode_type_function (edomain);
+
+ var macro = "(%s ())".printf (fun_name);
+ decl_space.add_type_declaration (new CCodeMacroReplacement (get_ccode_type_id (edomain),
macro));
+
+ var regfun = new CCodeFunction (fun_name, "GType");
+ regfun.modifiers = CCodeModifiers.CONST;
+
+ if (edomain.is_private_symbol ()) {
+ // avoid C warning as this function is not always used
+ regfun.modifiers |= CCodeModifiers.STATIC | CCodeModifiers.UNUSED;
+ } else if (context.hide_internal && edomain.is_internal_symbol ()) {
+ regfun.modifiers |= CCodeModifiers.INTERNAL;
+ }
+
+ decl_space.add_function_declaration (regfun);
}
public override void visit_error_domain (ErrorDomain edomain) {
diff --git a/codegen/valagirwriter.vala b/codegen/valagirwriter.vala
index c01912167..cb869fe2f 100644
--- a/codegen/valagirwriter.vala
+++ b/codegen/valagirwriter.vala
@@ -736,7 +736,11 @@ public class Vala.GIRWriter : CodeVisitor {
write_indent ();
buffer.append_printf ("<enumeration name=\"%s\"", edomain.name);
- write_ctype_attributes (edomain);
+ if (get_ccode_has_type_id (edomain)) {
+ write_gtype_attributes (edomain);
+ } else {
+ write_ctype_attributes (edomain);
+ }
buffer.append_printf (" glib:error-domain=\"%s\"", get_ccode_quark_name (edomain));
write_symbol_attributes (edomain);
buffer.append_printf (">\n");
diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala
index 9bb8a3052..bf2e7d924 100644
--- a/codegen/valagtypemodule.vala
+++ b/codegen/valagtypemodule.vala
@@ -2366,6 +2366,18 @@ public class Vala.GTypeModule : GErrorModule {
}
}
+ public override void visit_error_domain (ErrorDomain edomain) {
+ base.visit_error_domain (edomain);
+
+ if (get_ccode_has_type_id (edomain)) {
+ push_line (edomain.source_reference);
+ var type_fun = new ErrorDomainRegisterFunction (edomain);
+ type_fun.init_from_type (context, false, false);
+ cfile.add_type_member_definition (type_fun.get_definition ());
+ pop_line ();
+ }
+ }
+
public override void visit_method_call (MethodCall expr) {
var ma = expr.call as MemberAccess;
var mtype = expr.call.value_type as MethodType;
diff --git a/codegen/valatyperegisterfunction.vala b/codegen/valatyperegisterfunction.vala
index 394295f9b..54b81b22b 100644
--- a/codegen/valatyperegisterfunction.vala
+++ b/codegen/valatyperegisterfunction.vala
@@ -143,6 +143,8 @@ public abstract class Vala.TypeRegisterFunction {
} else {
reg_call = new CCodeFunctionCall (new CCodeIdentifier
("g_enum_register_static"));
}
+ } else if (type_symbol is ErrorDomain) {
+ reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_enum_register_static"));
} else if (fundamental) {
reg_call = new CCodeFunctionCall (new CCodeIdentifier
("g_type_register_fundamental"));
reg_call.add_argument (new CCodeFunctionCall (new CCodeIdentifier
("g_type_fundamental_next")));
@@ -191,6 +193,34 @@ public abstract class Vala.TypeRegisterFunction {
type_init.add_statement (cdecl);
+ reg_call.add_argument (new CCodeIdentifier ("values"));
+ } else if (type_symbol is ErrorDomain) {
+ unowned ErrorDomain edomain = (ErrorDomain) type_symbol;
+ var clist = new CCodeInitializerList (); /* or during visit time? */
+
+ CCodeInitializerList clist_ec = null;
+ foreach (ErrorCode ec in edomain.get_codes ()) {
+ clist_ec = new CCodeInitializerList ();
+ clist_ec.append (new CCodeConstant (get_ccode_name (ec)));
+ clist_ec.append (new CCodeConstant ("\"%s\"".printf (get_ccode_name (ec))));
+ clist_ec.append (new CCodeConstant ("\"%s\"".printf (ec.nick)));
+ clist.append (clist_ec);
+ }
+
+ clist_ec = new CCodeInitializerList ();
+ clist_ec.append (new CCodeConstant ("0"));
+ clist_ec.append (new CCodeConstant ("NULL"));
+ clist_ec.append (new CCodeConstant ("NULL"));
+ clist.append (clist_ec);
+
+ var edomain_decl = new CCodeVariableDeclarator ("values[]", clist);
+
+ cdecl = new CCodeDeclaration ("const GEnumValue");
+ cdecl.add_declarator (edomain_decl);
+ cdecl.modifiers = CCodeModifiers.STATIC;
+
+ type_init.add_statement (cdecl);
+
reg_call.add_argument (new CCodeIdentifier ("values"));
} else {
reg_call.add_argument (new CCodeIdentifier ("&g_define_type_info"));
diff --git a/tests/girwriter/GirTest-1.0.gir-expected b/tests/girwriter/GirTest-1.0.gir-expected
index 72705c6fd..0a14bd7d2 100644
--- a/tests/girwriter/GirTest-1.0.gir-expected
+++ b/tests/girwriter/GirTest-1.0.gir-expected
@@ -27,11 +27,16 @@
<enumeration name="SkippedFlags" c:type="GirTestSkippedFlags" glib:type-name="GirTestSkippedFlags"
glib:get-type="gir_test_skipped_flags_get_type" introspectable="0">
<member name="value1" c:identifier="GIR_TEST_SKIPPED_FLAGS_VALUE1" value="0"/>
</enumeration>
- <enumeration name="ErrorTest" c:type="GirTestErrorTest" glib:error-domain="gir-test-error-test-quark">
+ <enumeration name="ErrorTest" c:type="GirTestErrorTest" glib:type-name="GirTestErrorTest"
glib:get-type="gir_test_error_test_get_type" glib:error-domain="gir-test-error-test-quark">
<member name="failed" c:identifier="GIR_TEST_ERROR_TEST_FAILED" value="0"/>
<member name="smelly" c:identifier="GIR_TEST_ERROR_TEST_SMELLY" value="1"/>
<member name="fishy" c:identifier="GIR_TEST_ERROR_TEST_FISHY" value="23"/>
</enumeration>
+ <enumeration name="PlainErrorTest" c:type="GirTestPlainErrorTest"
glib:error-domain="gir-test-plain-error-test-quark">
+ <member name="failed" c:identifier="GIR_TEST_PLAIN_ERROR_TEST_FAILED" value="0"/>
+ <member name="smelly" c:identifier="GIR_TEST_PLAIN_ERROR_TEST_SMELLY" value="1"/>
+ <member name="fishy" c:identifier="GIR_TEST_PLAIN_ERROR_TEST_FISHY" value="23"/>
+ </enumeration>
<record name="SkippedStruct" introspectable="0">
<constructor name="new" c:identifier="gir_test_skipped_struct_new">
<return-value transfer-ownership="full">
diff --git a/tests/girwriter/girtest.vala b/tests/girwriter/girtest.vala
index 4f04d9296..06aa400c8 100644
--- a/tests/girwriter/girtest.vala
+++ b/tests/girwriter/girtest.vala
@@ -64,6 +64,13 @@ namespace GirTest {
FISHY = 23
}
+ [CCode (has_type_id = false)]
+ public errordomain PlainErrorTest {
+ FAILED,
+ SMELLY,
+ FISHY = 23
+ }
+
public interface InterfaceTest : Object {
public abstract int property { get; construct set; }
public virtual void int8_in (int8 param) {
diff --git a/tests/girwriter/girtest.vapi-expected b/tests/girwriter/girtest.vapi-expected
index d89338f8e..2ecd79a35 100644
--- a/tests/girwriter/girtest.vapi-expected
+++ b/tests/girwriter/girtest.vapi-expected
@@ -134,6 +134,12 @@ namespace GirTest {
SMELLY,
FISHY
}
+ [CCode (cheader_filename = "girtest.h", has_type_id = false)]
+ public errordomain PlainErrorTest {
+ FAILED,
+ SMELLY,
+ FISHY
+ }
[CCode (cheader_filename = "girtest.h")]
public delegate bool DelegateTest (void* a, void* b);
[CCode (cheader_filename = "girtest.h")]
diff --git a/vala/valaerrorcode.vala b/vala/valaerrorcode.vala
index 3e3c57b37..18812d254 100644
--- a/vala/valaerrorcode.vala
+++ b/vala/valaerrorcode.vala
@@ -54,8 +54,24 @@ public class Vala.ErrorCode : TypeSymbol {
}
}
+ /**
+ * The nick of this error code
+ */
+ public string nick {
+ get {
+ if (_nick == null) {
+ _nick = get_attribute_string ("Description", "nick");
+ if (_nick == null) {
+ _nick = name.down ().replace ("_", "-");
+ }
+ }
+ return _nick;
+ }
+ }
+
private Expression _value;
private Constant _code;
+ private string? _nick = null;
/**
* Creates a new enum value.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]