From: Rico Tzschichholz Date: Sat, 27 Apr 2019 18:18:34 +0000 (+0200) Subject: codegen: Move GObject property validity checks to SemanticAnalyzer X-Git-Tag: 0.45.1~34 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d4c9da248919d6e604d1da5a738013e73b6e8860;p=thirdparty%2Fvala.git codegen: Move GObject property validity checks to SemanticAnalyzer --- diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 2a6056ae8..f0d03ba78 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -1644,7 +1644,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { Report.error (acc.source_reference, "construct properties require GLib.Object"); acc.error = true; return; - } else if (acc.construction && !is_gobject_property (prop)) { + } else if (acc.construction && !context.analyzer.is_gobject_property (prop)) { Report.error (acc.source_reference, "construct properties not supported for specified property type"); acc.error = true; return; @@ -1868,7 +1868,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { } // notify on property changes - if (is_gobject_property (prop) && + if (context.analyzer.is_gobject_property (prop) && prop.notify && (acc.writable || acc.construction)) { var notify_call = new CCodeFunctionCall (new CCodeIdentifier ("g_object_notify_by_pspec")); @@ -6390,10 +6390,6 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { ccode.add_expression (cassert); } - public virtual bool is_gobject_property (Property prop) { - return false; - } - public DataType? get_this_type () { if (current_method != null && current_method.binding == MemberBinding.INSTANCE) { return current_method.this_parameter.variable_type; diff --git a/codegen/valagobjectmodule.vala b/codegen/valagobjectmodule.vala index b2adc9a6f..8ad676ab9 100644 --- a/codegen/valagobjectmodule.vala +++ b/codegen/valagobjectmodule.vala @@ -134,8 +134,8 @@ public class Vala.GObjectModule : GTypeModule { /* create properties */ var props = cl.get_properties (); foreach (Property prop in props) { - if (!is_gobject_property (prop)) { - if (!has_valid_gobject_property_type (prop)) { + if (!context.analyzer.is_gobject_property (prop)) { + if (!context.analyzer.is_gobject_property_type (prop.property_type)) { Report.warning (prop.source_reference, "Type `%s' can not be used for a GLib.Object property".printf (prop.property_type.to_qualified_string ())); } continue; @@ -202,7 +202,7 @@ public class Vala.GObjectModule : GTypeModule { if (prop.get_accessor == null || prop.is_abstract) { continue; } - if (!is_gobject_property (prop)) { + if (!context.analyzer.is_gobject_property (prop)) { // don't register private properties continue; } @@ -310,7 +310,7 @@ public class Vala.GObjectModule : GTypeModule { if (prop.set_accessor == null || prop.is_abstract) { continue; } - if (!is_gobject_property (prop)) { + if (!context.analyzer.is_gobject_property (prop)) { continue; } @@ -759,71 +759,11 @@ public class Vala.GObjectModule : GTypeModule { public override void visit_property (Property prop) { base.visit_property (prop); - if (is_gobject_property (prop) && prop.parent_symbol is Class) { + if (context.analyzer.is_gobject_property (prop) && prop.parent_symbol is Class) { prop_enum.add_value (new CCodeEnumValue ("%s_PROPERTY".printf (get_ccode_upper_case_name (prop)))); } } - public override bool is_gobject_property (Property prop) { - var type_sym = prop.parent_symbol as ObjectTypeSymbol; - if (type_sym == null || !type_sym.is_subtype_of (gobject_type)) { - return false; - } - - if (prop.binding != MemberBinding.INSTANCE) { - return false; - } - - if (prop.access == SymbolAccessibility.PRIVATE) { - return false; - } - - if (!has_valid_gobject_property_type (prop)) { - return false; - } - - if (type_sym is Class && prop.base_interface_property != null && - !is_gobject_property (prop.base_interface_property)) { - return false; - } - - if (!prop.name[0].isalpha ()) { - // GObject requires properties to start with a letter - return false; - } - - if (type_sym is Interface && !prop.is_abstract && !prop.external && !prop.external_package) { - // GObject does not support non-abstract interface properties, - // however we assume external properties always are GObject properties - return false; - } - - if (type_sym is Interface && type_sym.get_attribute ("DBus") != null) { - // GObject properties not currently supported in D-Bus interfaces - return false; - } - - return true; - } - - bool has_valid_gobject_property_type (Property prop) { - var st = prop.property_type.data_type as Struct; - if (st != null && (!get_ccode_has_type_id (st) || prop.property_type.nullable)) { - return false; - } - - if (prop.property_type is ArrayType && ((ArrayType)prop.property_type).element_type.data_type != string_type.data_type) { - return false; - } - - var d = prop.property_type as DelegateType; - if (d != null && d.delegate_symbol.has_target) { - return false; - } - - return true; - } - public override void visit_method_call (MethodCall expr) { if (expr.call is MemberAccess) { push_line (expr.source_reference); @@ -858,7 +798,7 @@ public class Vala.GObjectModule : GTypeModule { Report.error (arg.source_reference, "Property `%s' not found in `%s'".printf (named_argument.name, current_class.get_full_name ())); break; } - if (!is_gobject_property (prop)) { + if (!context.analyzer.is_gobject_property (prop)) { Report.error (arg.source_reference, "Property `%s' not supported in Object (property: value) constructor chain up".printf (named_argument.name)); break; } diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala index 6b0c3b310..119437cbe 100644 --- a/codegen/valagtypemodule.vala +++ b/codegen/valagtypemodule.vala @@ -2268,7 +2268,7 @@ public class Vala.GTypeModule : GErrorModule { var props = iface.get_properties (); foreach (Property prop in props) { if (prop.is_abstract) { - if (!is_gobject_property (prop)) { + if (!context.analyzer.is_gobject_property (prop)) { continue; } diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index 485ab222d..af7e63eb6 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -406,6 +406,66 @@ public class Vala.SemanticAnalyzer : CodeVisitor { return sym; } + public bool is_gobject_property (Property prop) { + var type_sym = prop.parent_symbol as ObjectTypeSymbol; + if (type_sym == null || !type_sym.is_subtype_of (object_type)) { + return false; + } + + if (prop.binding != MemberBinding.INSTANCE) { + return false; + } + + if (prop.access == SymbolAccessibility.PRIVATE) { + return false; + } + + if (!is_gobject_property_type (prop.property_type)) { + return false; + } + + if (type_sym is Class && prop.base_interface_property != null && + !is_gobject_property (prop.base_interface_property)) { + return false; + } + + if (!prop.name[0].isalpha ()) { + // GObject requires properties to start with a letter + return false; + } + + if (type_sym is Interface && !prop.is_abstract && !prop.external && !prop.external_package) { + // GObject does not support non-abstract interface properties, + // however we assume external properties always are GObject properties + return false; + } + + if (type_sym is Interface && type_sym.get_attribute ("DBus") != null) { + // GObject properties not currently supported in D-Bus interfaces + return false; + } + + return true; + } + + public bool is_gobject_property_type (DataType property_type) { + var st = property_type.data_type as Struct; + if (st != null && (!st.get_attribute_bool ("CCode", "has_type_id", true) || property_type.nullable)) { + return false; + } + + if (property_type is ArrayType && ((ArrayType) property_type).element_type.data_type != string_type.data_type) { + return false; + } + + var d = property_type as DelegateType; + if (d != null && d.delegate_symbol.has_target) { + return false; + } + + return true; + } + public bool check_arguments (Expression expr, DataType mtype, List params, List args) { bool error = false;