[vala/staging] codegen: Move GObject property validity checks to SemanticAnalyzer



commit d4c9da248919d6e604d1da5a738013e73b6e8860
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Sat Apr 27 20:18:34 2019 +0200

    codegen: Move GObject property validity checks to SemanticAnalyzer

 codegen/valaccodebasemodule.vala |  8 ++---
 codegen/valagobjectmodule.vala   | 72 ++++------------------------------------
 codegen/valagtypemodule.vala     |  2 +-
 vala/valasemanticanalyzer.vala   | 60 +++++++++++++++++++++++++++++++++
 4 files changed, 69 insertions(+), 73 deletions(-)
---
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<Parameter> params, 
List<Expression> args) {
                bool error = false;
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]