diff options
author | Rico Tzschichholz <ricotz@ubuntu.com> | 2018-11-17 22:22:03 +0100 |
---|---|---|
committer | Rico Tzschichholz <ricotz@ubuntu.com> | 2022-02-24 19:59:24 +0100 |
commit | da4ff03c5ca427cf7cc4574f52f5190dc1b0dfb9 (patch) | |
tree | 184fd1c8e207f2ee137b2d9bded274a855e4bb37 /codegen | |
parent | a1530007a7c1b829cdf5876f4090d30b502c1bc3 (diff) | |
download | vala-da4ff03c5ca427cf7cc4574f52f5190dc1b0dfb9.tar.gz |
codegen: Emit GType definition for error domains
Fixes https://gitlab.gnome.org/GNOME/vala/issues/699
Diffstat (limited to 'codegen')
-rw-r--r-- | codegen/Makefile.am | 1 | ||||
-rw-r--r-- | codegen/valaccode.vala | 2 | ||||
-rw-r--r-- | codegen/valaccodeattribute.vala | 13 | ||||
-rw-r--r-- | codegen/valaerrordomainregisterfunction.vala | 51 | ||||
-rw-r--r-- | codegen/valagerrormodule.vala | 25 | ||||
-rw-r--r-- | codegen/valagirwriter.vala | 6 | ||||
-rw-r--r-- | codegen/valagtypemodule.vala | 12 | ||||
-rw-r--r-- | codegen/valatyperegisterfunction.vala | 30 |
8 files changed, 135 insertions, 5 deletions
diff --git a/codegen/Makefile.am b/codegen/Makefile.am index c7fc91341..b786e66ec 100644 --- a/codegen/Makefile.am +++ b/codegen/Makefile.am @@ -40,6 +40,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 80e0f1c0f..25a0d11af 100644 --- a/codegen/valaccode.vala +++ b/codegen/valaccode.vala @@ -237,7 +237,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 bd4c6b29d..3c3b18ef4 100644 --- a/codegen/valaccodeattribute.vala +++ b/codegen/valaccodeattribute.vala @@ -1073,6 +1073,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_ERROR"; + } } else { return "G_TYPE_POINTER"; } @@ -1199,7 +1206,7 @@ public class Vala.CCodeAttribute : AttributeCache { return get_ccode_lower_case_name (cl, "value_get_"); } else if (cl.base_class != null) { return get_ccode_get_value_function (cl.base_class); - } else if (type_id == "G_TYPE_POINTER") { + } else if (type_id == "G_TYPE_POINTER" || cl.is_error_base) { return "g_value_get_pointer"; } else { return "g_value_get_boxed"; @@ -1257,7 +1264,7 @@ public class Vala.CCodeAttribute : AttributeCache { return get_ccode_lower_case_name (cl, "value_set_"); } else if (cl.base_class != null) { return get_ccode_set_value_function (cl.base_class); - } else if (type_id == "G_TYPE_POINTER") { + } else if (type_id == "G_TYPE_POINTER" || cl.is_error_base) { return "g_value_set_pointer"; } else { return "g_value_set_boxed"; @@ -1315,7 +1322,7 @@ public class Vala.CCodeAttribute : AttributeCache { return get_ccode_lower_case_name (cl, "value_take_"); } else if (cl.base_class != null) { return get_ccode_take_value_function (cl.base_class); - } else if (type_id == "G_TYPE_POINTER") { + } else if (type_id == "G_TYPE_POINTER" || cl.is_error_base) { return "g_value_set_pointer"; } else { return "g_value_take_boxed"; 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 a559a4d00..2b4c6cf85 100644 --- a/codegen/valagerrormodule.vala +++ b/codegen/valagerrormodule.vala @@ -56,6 +56,31 @@ public class Vala.GErrorModule : CCodeDelegateModule { requires_vala_extern = true; 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 696c6c8a6..115d4ff98 100644 --- a/codegen/valagirwriter.vala +++ b/codegen/valagirwriter.vala @@ -932,7 +932,11 @@ public class Vala.GIRWriter : CodeVisitor { write_indent (); buffer.append_printf ("<enumeration name=\"%s\"", get_gir_name (edomain)); - 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 28a29744c..7bc8eaf83 100644 --- a/codegen/valagtypemodule.vala +++ b/codegen/valagtypemodule.vala @@ -2408,6 +2408,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 a3236b94c..7502294cb 100644 --- a/codegen/valatyperegisterfunction.vala +++ b/codegen/valatyperegisterfunction.vala @@ -155,6 +155,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"))); @@ -204,6 +206,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")); if (fundamental) { |