[folks] eds: Nullability fixes



commit 33f7d0564156e766c22e8637e33f6389ae110bc6
Author: Philip Withnall <philip tecnocode co uk>
Date:   Wed Dec 28 19:17:09 2011 +0000

    eds: Nullability fixes
    
    With the EDS annotation fixes in
    https://bugzilla.gnome.org/show_bug.cgi?id=667388, this fixes all of the
    nullability problems found by compiling with --enable-experimental-non-null.
    
    As mentioned in the previous commit, we canât use
    --enable-experimental-non-null by default yet, but the fixes should work by
    themselves.

 backends/eds/lib/edsf-persona-store.vala |  286 ++++++++++++++++++------------
 backends/eds/lib/edsf-persona.vala       |  247 ++++++++++++++-----------
 backends/eds/lib/memory-icon.vala        |   12 +-
 folks/persona-store.vala                 |    9 +-
 4 files changed, 324 insertions(+), 230 deletions(-)
---
diff --git a/backends/eds/lib/edsf-persona-store.vala b/backends/eds/lib/edsf-persona-store.vala
index b0b92b6..5ccae83 100644
--- a/backends/eds/lib/edsf-persona-store.vala
+++ b/backends/eds/lib/edsf-persona-store.vala
@@ -39,9 +39,9 @@ public class Edsf.PersonaStore : Folks.PersonaStore
   private bool _is_prepared = false;
   private bool _prepare_pending = false;
   private bool _is_quiescent = false;
-  private E.BookClient _addressbook;
-  private E.BookClientView _ebookview;
-  private E.SourceList? _source_list = null;
+  private E.BookClient? _addressbook = null; /* null before prepare() */
+  private E.BookClientView? _ebookview = null; /* null before prepare() */
+  private E.SourceList? _source_list = null; /* null before prepare() */
   private string _query_str;
 
   /* The timeout after which we consider a property change to have failed if we
@@ -81,7 +81,8 @@ public class Edsf.PersonaStore : Folks.PersonaStore
               return MaybeBool.FALSE;
             }
 
-          return this._addressbook.readonly ? MaybeBool.FALSE : MaybeBool.TRUE;
+          return ((!) this._addressbook).readonly
+              ? MaybeBool.FALSE : MaybeBool.TRUE;
         }
     }
 
@@ -129,7 +130,8 @@ public class Edsf.PersonaStore : Folks.PersonaStore
               return MaybeBool.FALSE;
             }
 
-          return this._addressbook.readonly ? MaybeBool.FALSE : MaybeBool.TRUE;
+          return ((!) this._addressbook).readonly
+              ? MaybeBool.FALSE : MaybeBool.TRUE;
         }
     }
 
@@ -157,7 +159,8 @@ public class Edsf.PersonaStore : Folks.PersonaStore
     {
       get
         {
-          if (this._addressbook.readonly == true)
+          if (this._addressbook == null ||
+              ((!) this._addressbook).readonly == true)
             {
               return this._always_writeable_properties_empty;
             }
@@ -232,20 +235,20 @@ public class Edsf.PersonaStore : Folks.PersonaStore
         {
           if (this._ebookview != null)
             {
-              this._ebookview.objects_added.disconnect (
+              ((!) this._ebookview).objects_added.disconnect (
                   this._contacts_added_cb);
-              this._ebookview.objects_removed.disconnect (
+              ((!) this._ebookview).objects_removed.disconnect (
                   this._contacts_removed_cb);
-              this._ebookview.objects_modified.disconnect (
+              ((!) this._ebookview).objects_modified.disconnect (
                   this._contacts_changed_cb);
-              this._ebookview.stop ();
+              ((!) this._ebookview).stop ();
 
               this._ebookview = null;
             }
 
           if (this._addressbook != null)
             {
-              this._addressbook.notify["readonly"].disconnect (
+              ((!) this._addressbook).notify["readonly"].disconnect (
                   this._address_book_notify_read_only_cb);
 
               this._addressbook = null;
@@ -253,7 +256,7 @@ public class Edsf.PersonaStore : Folks.PersonaStore
 
           if (this._source_list != null)
             {
-              this._source_list.changed.disconnect (
+              ((!) this._source_list).changed.disconnect (
                   this._source_list_changed_cb);
               this._source_list = null;
             }
@@ -291,16 +294,32 @@ public class Edsf.PersonaStore : Folks.PersonaStore
   public override async Folks.Persona? add_persona_from_details (
       HashTable<string, Value?> details) throws Folks.PersonaStoreError
     {
+      // We have to have called prepare() beforehand.
+      if (!this._is_prepared)
+        {
+          throw new PersonaStoreError.STORE_OFFLINE (
+              "Persona store has not yet been prepared.");
+        }
+
       E.Contact contact = new E.Contact ();
 
-      foreach (var k in details.get_keys ())
+      var iter = HashTableIter<string, Value?> (details);
+      unowned string k;
+      unowned Value? _v;
+
+      while (iter.next (out k, out _v) == true)
         {
-          Value? v = details.lookup (k);
+          if (_v == null)
+            {
+              continue;
+            }
+          unowned Value v = (!) _v;
+
           if (k == Folks.PersonaStore.detail_key (
                 PersonaDetail.FULL_NAME))
             {
-              var full_name = v.get_string ();
-              if (full_name == "")
+              string? full_name = v.get_string ();
+              if (full_name != null && (!) full_name == "")
                 {
                   full_name = null;
                 }
@@ -406,12 +425,14 @@ public class Edsf.PersonaStore : Folks.PersonaStore
             }
         }
 
-      Edsf.Persona? persona = null;
+      Edsf.Persona? _persona = null;
 
       try
         {
+          /* _addressbook is guaranteed to be non-null before we ensure that
+           * prepare() has already been called. */
           string added_uid;
-          var result = yield this._addressbook.add_contact (contact,
+          var result = yield ((!) this._addressbook).add_contact (contact,
               null,
               out added_uid);
 
@@ -421,15 +442,19 @@ public class Edsf.PersonaStore : Folks.PersonaStore
               lock (this._personas)
                 {
                   var iid = Edsf.Persona.build_iid (this.id, added_uid);
-                  persona = this._personas.get (iid);
-                  if (persona == null)
+                  _persona = this._personas.get (iid);
+                  if (_persona == null)
                     {
+                      Edsf.Persona persona;
+
                       contact.set (E.Contact.field_id ("id"), added_uid);
                       persona = new Persona (this, contact);
                       this._personas.set (persona.iid, persona);
                       var added_personas = new HashSet<Persona> ();
                       added_personas.add (persona);
                       this._emit_personas_changed (added_personas, null);
+
+                      _persona = persona;
                     }
                 }
             }
@@ -445,7 +470,7 @@ public class Edsf.PersonaStore : Folks.PersonaStore
               e.message);
         }
 
-      return persona;
+      return _persona;
     }
 
   /**
@@ -460,9 +485,18 @@ public class Edsf.PersonaStore : Folks.PersonaStore
   public override async void remove_persona (Folks.Persona persona)
       throws Folks.PersonaStoreError
     {
+      // We have to have called prepare() beforehand.
+      if (!this._is_prepared)
+        {
+          throw new PersonaStoreError.STORE_OFFLINE (
+              "Persona store has not yet been prepared.");
+        }
+
       try
         {
-          yield this._addressbook.remove_contact (
+          /* _addressbook is guaranteed to be non-null before we ensure that
+           * prepare() has already been called. */
+          yield ((!) this._addressbook).remove_contact (
               ((Edsf.Persona) persona).contact, null);
         }
       catch (GLib.Error e)
@@ -561,15 +595,19 @@ public class Edsf.PersonaStore : Folks.PersonaStore
                * need to check if we still exist in the list, as
                * addressbook.open() will fail if we don't. */
               E.BookClient.get_sources (out this._source_list);
-              this._source_list.changed.connect (this._source_list_changed_cb);
+
+              /* We know _source_list != null because otherwise
+               * E.BookClient.get_sources() would've thrown an error. */
+              ((!) this._source_list).changed.connect (
+                  this._source_list_changed_cb);
 
               /* Connect to the address book. */
               this._addressbook = new E.BookClient (this.source);
 
-              this._addressbook.notify["readonly"].connect (
+              ((!) this._addressbook).notify["readonly"].connect (
                   this._address_book_notify_read_only_cb);
 
-              yield this._addressbook.open (false, null);
+              yield ((!) this._addressbook).open (false, null);
 
               this._update_trust_level ();
             }
@@ -647,7 +685,8 @@ public class Edsf.PersonaStore : Folks.PersonaStore
               this._prepare_pending = false;
             }
 
-          if (this._addressbook.is_opened () == false)
+          // this._addressbook is guaranteed to be non-null by now.
+          if (((!) this._addressbook).is_opened () == false)
             {
               /* Remove the persona store on error */
               this.removed ();
@@ -663,29 +702,29 @@ public class Edsf.PersonaStore : Folks.PersonaStore
            *
            * Note: We assume this is constant over the lifetime of the address
            * book. This seems reasonable. */
-          string supported_fields;
           try
             {
-              yield this._addressbook.get_backend_property ("supported-fields",
-                  null, out supported_fields);
+              string? supported_fields = null;
+              yield ((!) this._addressbook).get_backend_property (
+                  "supported-fields", null, out supported_fields);
 
               var prop_set = new HashSet<string> ();
 
               /* We get a comma-separated list of fields back. */
               if (supported_fields != null)
                 {
-                  string[] fields = supported_fields.split (",");
+                  string[] fields = ((!) supported_fields).split (",");
 
                   /* We always support local-ids, web-service-addresses, gender
                    * and favourite because we use custom vCard attributes for
                    * them. */
-                  prop_set.add (Folks.PersonaStore.detail_key (
+                  prop_set.add ((!) Folks.PersonaStore.detail_key (
                       PersonaDetail.LOCAL_IDS));
-                  prop_set.add (Folks.PersonaStore.detail_key (
+                  prop_set.add ((!) Folks.PersonaStore.detail_key (
                       PersonaDetail.WEB_SERVICE_ADDRESSES));
-                  prop_set.add (Folks.PersonaStore.detail_key (
+                  prop_set.add ((!) Folks.PersonaStore.detail_key (
                       PersonaDetail.GENDER));
-                  prop_set.add (Folks.PersonaStore.detail_key (
+                  prop_set.add ((!) Folks.PersonaStore.detail_key (
                       PersonaDetail.IS_FAVOURITE));
 
                   foreach (unowned string field in fields)
@@ -695,20 +734,19 @@ public class Edsf.PersonaStore : Folks.PersonaStore
 
                       if (prop != null)
                         {
-                          prop_set.add ((owned) prop);
+                          prop_set.add ((!) (owned) prop);
                         }
                     }
                 }
 
               /* Convert the property set to an array. We can't use .to_array()
                * here because it fails to null-terminate the array. Sigh. */
-              this._always_writeable_properties = new string[prop_set.size + 1];
+              this._always_writeable_properties = new string[prop_set.size];
               uint i = 0;
               foreach (var final_prop in prop_set)
                 {
                   this._always_writeable_properties[i++] = final_prop;
                 }
-              this._always_writeable_properties[i] = null;
             }
           catch (GLib.Error e2)
             {
@@ -730,13 +768,13 @@ public class Edsf.PersonaStore : Folks.PersonaStore
           var do_initial_query = false;
           try
             {
-              string capabilities;
-              yield this._addressbook.get_backend_property ("capabilities",
-                  null, out capabilities);
+              string? capabilities = null;
+              yield ((!) this._addressbook).get_backend_property (
+                  "capabilities", null, out capabilities);
 
               if (capabilities != null)
                 {
-                  string[] caps = capabilities.split (",");
+                  string[] caps = ((!) capabilities).split (",");
 
                   do_initial_query = ("do-initial-query" in caps);
                 }
@@ -758,8 +796,8 @@ public class Edsf.PersonaStore : Folks.PersonaStore
           bool got_view = false;
           try
             {
-              got_view = yield this._addressbook.get_view (this._query_str,
-                  null, out this._ebookview);
+              got_view = yield ((!) this._addressbook).get_view (
+                  this._query_str, null, out this._ebookview);
 
               if (got_view == false)
                 {
@@ -769,11 +807,14 @@ public class Edsf.PersonaStore : Folks.PersonaStore
                           this.id);
                 }
 
-              this._ebookview.objects_added.connect (this._contacts_added_cb);
-              this._ebookview.objects_removed.connect (this._contacts_removed_cb);
-              this._ebookview.objects_modified.connect (this._contacts_changed_cb);
+              ((!) this._ebookview).objects_added.connect (
+                  this._contacts_added_cb);
+              ((!) this._ebookview).objects_removed.connect (
+                  this._contacts_removed_cb);
+              ((!) this._ebookview).objects_modified.connect (
+                  this._contacts_changed_cb);
 
-              this._ebookview.start ();
+              ((!) this._ebookview).start ();
             }
           catch (GLib.Error e3)
             {
@@ -1024,6 +1065,12 @@ public class Edsf.PersonaStore : Folks.PersonaStore
   private async void _commit_modified_property (Edsf.Persona persona,
       string property_name) throws PropertyError
     {
+      /* We require _addressbook to be non-null. This should be the case
+       * because we're only called from property setters, and they check whether
+       * the properties are writeable first. Properties shouldn't be writeable
+       * if _addressbook is null. */
+      assert (this._addressbook != null);
+
       var contact = persona.contact;
 
       ulong signal_id = 0;
@@ -1045,8 +1092,9 @@ public class Edsf.PersonaStore : Folks.PersonaStore
                 }
             });
 
-          /* Commit the modification. */
-          yield this._addressbook.modify_contact (contact, null);
+          /* Commit the modification. _addressbook is asserted as being non-null
+           * above. */
+          yield ((!) this._addressbook).modify_contact (contact, null);
 
           timeout_id = Timeout.add_seconds (this._property_change_timeout, () =>
             {
@@ -1093,6 +1141,15 @@ public class Edsf.PersonaStore : Folks.PersonaStore
         }
     }
 
+  private void _remove_attribute (E.Contact contact, string attr_name)
+    {
+      unowned VCardAttribute? attr = contact.get_attribute (attr_name);
+      if (attr != null)
+        {
+          contact.remove_attribute ((!) attr);
+        }
+    }
+
   internal async void _set_avatar (Edsf.Persona persona, LoadableIcon? avatar)
       throws PropertyError
     {
@@ -1104,7 +1161,7 @@ public class Edsf.PersonaStore : Folks.PersonaStore
 
       /* Return early if there will be no change */
       if ((persona.avatar == null && avatar == null) ||
-          (persona.avatar != null && persona.avatar.equal (avatar)))
+          (persona.avatar != null && ((!) persona.avatar).equal (avatar)))
         {
           return;
         }
@@ -1135,12 +1192,7 @@ public class Edsf.PersonaStore : Folks.PersonaStore
   private async void _set_contact_web_service_addresses (E.Contact contact,
       MultiMap<string, WebServiceFieldDetails> web_service_addresses)
     {
-      unowned VCardAttribute attr =
-          contact.get_attribute ("X-FOLKS-WEB-SERVICES-IDS");
-      if (attr != null)
-        {
-          contact.remove_attribute (attr);
-        }
+      this._remove_attribute (contact, "X-FOLKS-WEB-SERVICES-IDS");
 
       var attr_n = new VCardAttribute (null, "X-FOLKS-WEB-SERVICES-IDS");
       foreach (var service in web_service_addresses.get_keys ())
@@ -1249,12 +1301,7 @@ public class Edsf.PersonaStore : Folks.PersonaStore
   private async void _set_contact_local_ids (E.Contact contact,
       Set<string> local_ids)
     {
-      unowned VCardAttribute attr =
-          contact.get_attribute ("X-FOLKS-CONTACTS-IDS");
-      if (attr != null)
-        {
-          contact.remove_attribute (attr);
-        }
+      this._remove_attribute (contact, "X-FOLKS-CONTACTS-IDS");
 
       var new_attr = new VCardAttribute (null, "X-FOLKS-CONTACTS-IDS");
       foreach (var local_id in local_ids)
@@ -1281,11 +1328,7 @@ public class Edsf.PersonaStore : Folks.PersonaStore
   private async void _set_contact_is_favourite (E.Contact contact,
       bool is_favourite)
     {
-      unowned VCardAttribute attr = contact.get_attribute ("X-FOLKS-FAVOURITE");
-      if (attr != null)
-        {
-          contact.remove_attribute (attr);
-        }
+      this._remove_attribute (contact, "X-FOLKS-FAVOURITE");
 
       if (is_favourite)
         {
@@ -1300,11 +1343,7 @@ public class Edsf.PersonaStore : Folks.PersonaStore
     {
       if (avatar == null)
         {
-          unowned VCardAttribute attr = contact.get_attribute ("PHOTO");
-          if (attr != null)
-            {
-              contact.remove_attribute (attr);
-            }
+          this._remove_attribute (contact, "PHOTO");
         }
       else
         {
@@ -1313,7 +1352,7 @@ public class Edsf.PersonaStore : Folks.PersonaStore
               /* Set the avatar on the contact */
               var cp = new ContactPhoto ();
               cp.type = ContactPhotoType.INLINED;
-              var input_s = yield avatar.load_async (-1, null, null);
+              var input_s = yield ((!) avatar).load_async (-1, null, null);
 
               uint8[] image_data = new uint8[0];
               uint8[] buffer = new uint8[4096];
@@ -1334,7 +1373,7 @@ public class Edsf.PersonaStore : Folks.PersonaStore
               bool uncertain = false;
               var mime_type = ContentType.guess (null, image_data,
                   out uncertain);
-              if (mime_type != null && !uncertain)
+              if (!uncertain)
                 {
                   cp.set_mime_type (mime_type);
                 }
@@ -1455,15 +1494,16 @@ public class Edsf.PersonaStore : Folks.PersonaStore
               _("Full name is not writeable on this contact."));
         }
 
+      string? _full_name = full_name;
       if (full_name == "")
         {
-          full_name = null;
+          _full_name = null;
         }
 
-      if (persona.full_name == full_name)
+      if (persona.full_name == _full_name)
         return;
 
-      persona.contact.set (E.Contact.field_id ("full_name"), full_name);
+      persona.contact.set (E.Contact.field_id ("full_name"), _full_name);
       yield this._commit_modified_property (persona, "full-name");
     }
 
@@ -1476,15 +1516,16 @@ public class Edsf.PersonaStore : Folks.PersonaStore
               _("Nickname is not writeable on this contact."));
         }
 
+      string? _nickname = nickname;
       if (nickname == "")
         {
-          nickname = null;
+          _nickname = null;
         }
 
-      if (persona.nickname == nickname)
+      if (persona.nickname == _nickname)
         return;
 
-      persona.contact.set (E.Contact.field_id ("nickname"), nickname);
+      persona.contact.set (E.Contact.field_id ("nickname"), _nickname);
       yield this._commit_modified_property (persona, "nickname");
     }
 
@@ -1528,7 +1569,7 @@ public class Edsf.PersonaStore : Folks.PersonaStore
 
       if (persona.birthday != null &&
           bday != null &&
-          persona.birthday.equal (bday))
+          ((!) persona.birthday).equal ((!) bday))
         return;
 
       /* Maybe the current and new b-day are unset */
@@ -1541,19 +1582,24 @@ public class Edsf.PersonaStore : Folks.PersonaStore
     }
 
   private async void _set_contact_birthday (E.Contact contact,
-      DateTime? bday)
+      DateTime? _bday)
     {
-      E.ContactDate? contact_bday = null;
+      E.ContactDate? _contact_bday = null;
 
-      if (bday != null)
+      if (_bday != null)
         {
+          var bday = (!) _bday;
+          E.ContactDate contact_bday;
+
           contact_bday = new E.ContactDate ();
           contact_bday.year = (uint) bday.get_year ();
           contact_bday.month = (uint) bday.get_month ();
           contact_bday.day = (uint) bday.get_day_of_month ();
+
+          _contact_bday = contact_bday;
         }
 
-      contact.set (E.Contact.field_id ("birth_date"), contact_bday);
+      contact.set (E.Contact.field_id ("birth_date"), _contact_bday);
     }
 
   internal async void _set_roles (Edsf.Persona persona,
@@ -1601,23 +1647,23 @@ public class Edsf.PersonaStore : Folks.PersonaStore
               /* FIXME: we are swallowing the extra parameter values */
               var org_unit_values = role_fd.get_parameter_values ("org_unit");
               if (org_unit_values != null &&
-                  org_unit_values.size > 0)
-                org_unit = org_unit_values.to_array ()[0];
+                  ((!) org_unit_values).size > 0)
+                org_unit = ((!) org_unit_values).to_array ()[0];
 
               var office_values = role_fd.get_parameter_values ("office");
               if (office_values != null &&
-                  office_values.size > 0)
-                office = office_values.to_array ()[0];
+                  ((!) office_values).size > 0)
+                office = ((!) office_values).to_array ()[0];
 
               var manager_values = role_fd.get_parameter_values ("manager");
               if (manager_values != null &&
-                  manager_values.size > 0)
-                manager = manager_values.to_array ()[0];
+                  ((!) manager_values).size > 0)
+                manager = ((!) manager_values).to_array ()[0];
 
               var assistant_values = role_fd.get_parameter_values ("assistant");
               if (assistant_values != null &&
-                  assistant_values.size > 0)
-                assistant = assistant_values.to_array ()[0];
+                  ((!) assistant_values).size > 0)
+                assistant = ((!) assistant_values).to_array ()[0];
             }
           else
             {
@@ -1666,8 +1712,12 @@ public class Edsf.PersonaStore : Folks.PersonaStore
               _("Structured name is not writeable on this contact."));
         }
 
-      if (persona.structured_name != null &&
-          persona.structured_name.equal (sname))
+      if (persona.structured_name != null && sname != null &&
+          ((!) persona.structured_name).equal ((!) sname))
+        return;
+
+      /* Maybe the current and new name are unset */
+      if (persona.structured_name == null && sname == null)
         return;
 
       yield this._set_contact_name (persona.contact, sname);
@@ -1675,12 +1725,14 @@ public class Edsf.PersonaStore : Folks.PersonaStore
     }
 
   private async void _set_contact_name (E.Contact contact,
-      StructuredName? sname)
+      StructuredName? _sname)
     {
       E.ContactName contact_name = new E.ContactName ();
 
-      if (sname != null)
+      if (_sname != null)
         {
+          var sname = (!) _sname;
+
           contact_name.family = sname.family_name;
           contact_name.given = sname.given_name;
           contact_name.additional = sname.additional_names;
@@ -1787,12 +1839,7 @@ public class Edsf.PersonaStore : Folks.PersonaStore
   private async void _set_contact_gender (E.Contact contact,
       Gender gender)
     {
-      unowned VCardAttribute attr =
-          contact.get_attribute (Edsf.Persona.gender_attribute_name);
-      if (attr != null)
-        {
-          contact.remove_attribute (attr);
-        }
+      this._remove_attribute (contact, Edsf.Persona.gender_attribute_name);
 
       var new_attr =
           new VCardAttribute (null, Edsf.Persona.gender_attribute_name);
@@ -1820,10 +1867,9 @@ public class Edsf.PersonaStore : Folks.PersonaStore
           foreach (E.Contact c in contacts)
             {
               var iid = Edsf.Persona.build_iid_from_contact (this.id, c);
-              var persona = this._personas.get (iid);
-              if (persona == null)
+              if (this._personas.has_key (iid) == false)
                 {
-                  persona = new Persona (this, c);
+                  var persona = new Persona (this, c);
                   this._personas.set (persona.iid, persona);
                   added_personas.add (persona);
                 }
@@ -1849,10 +1895,10 @@ public class Edsf.PersonaStore : Folks.PersonaStore
       foreach (E.Contact c in contacts)
         {
           var iid = Edsf.Persona.build_iid_from_contact (this.id, c);
-          var persona = this._personas.get (iid);
+          Persona? persona = this._personas.get (iid);
           if (persona != null)
             {
-              persona._update (c);
+              ((!) persona)._update (c);
             }
         }
     }
@@ -1864,11 +1910,11 @@ public class Edsf.PersonaStore : Folks.PersonaStore
       foreach (string contact_id in contacts_ids)
         {
           var iid = Edsf.Persona.build_iid (this.id, contact_id);
-          var persona = _personas.get (iid);
+          Persona? persona = _personas.get (iid);
           if (persona != null)
             {
-              removed_personas.add (persona);
-              this._personas.unset (persona.iid);
+              removed_personas.add ((!) persona);
+              this._personas.unset (((!) persona).iid);
             }
         }
 
@@ -1952,8 +1998,12 @@ public class Edsf.PersonaStore : Folks.PersonaStore
 
   private bool _is_in_source_list ()
     {
+      /* Should only ever be called from a callback from the source list itself,
+       * so we can assert that the source list is non-null. */
+      assert (this._source_list != null);
+
       unowned GLib.SList<weak E.SourceGroup> groups =
-          this._source_list.peek_groups ();
+          ((!) this._source_list).peek_groups ();
 
       foreach (var g in groups)
         {
@@ -2003,19 +2053,23 @@ public class Edsf.PersonaStore : Folks.PersonaStore
    */
   private void _update_trust_level ()
     {
+      /* We may be called before prepare() has finished (and it may then fail),
+       * but _addressbook should always be non-null when we're called. */
+      assert (this._addressbook != null);
+
       unowned SourceGroup? group = (SourceGroup?) this.source.peek_group ();
       if (group != null)
         {
-          var base_uri = group.peek_base_uri ();
+          var base_uri = ((!) group).peek_base_uri ();
           /* base_uri should be ldap:// for LDAP based address books */
-          if (base_uri != null && base_uri.has_prefix("ldap"))
+          if (base_uri.has_prefix ("ldap"))
             {
               this.trust_level = PersonaStoreTrust.PARTIAL;
               return;
             }
         }
 
-      if (this._addressbook.readonly)
+      if (((!) this._addressbook).readonly)
         this.trust_level = PersonaStoreTrust.PARTIAL;
       else
         this.trust_level = PersonaStoreTrust.FULL;
@@ -2039,7 +2093,7 @@ public class Edsf.PersonaStore : Folks.PersonaStore
           E.BookClient.get_sources (out sources);
           var default_source = sources.peek_default_source ();
           if (default_source != null &&
-              this.source.peek_uid () == default_source.peek_uid ())
+              this.source.peek_uid () == ((!) default_source).peek_uid ())
             {
               is_default = true;
             }
diff --git a/backends/eds/lib/edsf-persona.vala b/backends/eds/lib/edsf-persona.vala
index bd807d4..0e1bbdb 100644
--- a/backends/eds/lib/edsf-persona.vala
+++ b/backends/eds/lib/edsf-persona.vala
@@ -128,7 +128,7 @@ public class Edsf.Persona : Folks.Persona,
   private Set<EmailFieldDetails> _email_addresses_ro;
   private HashSet<NoteFieldDetails> _notes;
   private Set<NoteFieldDetails> _notes_ro;
-  private static HashTable<string, E.ContactField> _im_eds_map = null;
+  private static HashTable<string, E.ContactField>? _im_eds_map = null;
 
   private HashSet<PostalAddressFieldDetails> _postal_addresses;
   private Set<PostalAddressFieldDetails> _postal_addresses_ro;
@@ -665,8 +665,8 @@ public class Edsf.Persona : Folks.Persona,
       E.Contact contact)
     {
       var contact_id =
-          (string) Edsf.Persona._get_property_from_contact (contact, "id");
-      return Edsf.Persona.build_iid (store_id, contact_id);
+          (string?) Edsf.Persona._get_property_from_contact (contact, "id");
+      return Edsf.Persona.build_iid (store_id, (!) (contact_id ?? ""));
     }
 
   /**
@@ -694,16 +694,17 @@ public class Edsf.Persona : Folks.Persona,
    */
   public Persona (PersonaStore store, E.Contact contact)
     {
-      var contact_id =
-        (string) Edsf.Persona._get_property_from_contact (contact, "id");
+      var _contact_id =
+        (string?) Edsf.Persona._get_property_from_contact (contact, "id");
+      var contact_id = (!) (_contact_id ?? "");
+
       var uid = this.build_uid (BACKEND_NAME, store.id, contact_id);
       var iid = Edsf.Persona.build_iid (store.id, contact_id);
       var is_user = BookClient.is_self (contact);
-      var full_name =
-          (string) Edsf.Persona._get_property_from_contact (contact,
+      var _full_name =
+          (string?) Edsf.Persona._get_property_from_contact (contact,
               "full_name");
-      if (full_name == null)
-        full_name = "";
+      var full_name = (!) (_full_name ?? "");
 
       Object (display_id: full_name,
               uid: uid,
@@ -873,15 +874,21 @@ public class Edsf.Persona : Folks.Persona,
 
       if (gender_attr != null)
         {
-          var gender_str = gender_attr.get_value ().up ();
-
-          if (gender_str == Edsf.Persona.gender_male)
-            {
-              gender = Gender.MALE;
-            }
-          else if (gender_str == Edsf.Persona.gender_female)
+          var val = ((!) gender_attr).get_value ();
+          if (val != null)
             {
-              gender = Gender.FEMALE;
+              switch (((!) val).up ())
+                {
+                  case Edsf.Persona.gender_male:
+                    gender = Gender.MALE;
+                    break;
+                  case Edsf.Persona.gender_female:
+                    gender = Gender.FEMALE;
+                    break;
+                  default:
+                    /* Unspecified, as above */
+                    break;
+                }
             }
         }
 
@@ -894,10 +901,12 @@ public class Edsf.Persona : Folks.Persona,
 
   private void _update_birthday ()
     {
-      E.ContactDate? bday = (E.ContactDate?) this._get_property ("birth_date");
+      var _bday = (E.ContactDate?) this._get_property ("birth_date");
 
-      if (bday != null)
+      if (_bday != null)
         {
+          var bday = (!) _bday;
+
           /* Since e-d-s stores birthdays as a plain date, we take the
            * given date in local time and convert it to UTC as mandated
            * by the BirthdayDetails interface.
@@ -907,7 +916,7 @@ public class Edsf.Persona : Folks.Persona,
               (int) bday.year, (int) bday.month, (int) bday.day, 0, 0, 0.0);
           if (this._birthday == null ||
               (this._birthday != null &&
-                  !this._birthday.equal (d.to_utc ())))
+                  !((!) this._birthday).equal (d.to_utc ())))
             {
               this._birthday = d.to_utc ();
               this.notify_property ("birthday");
@@ -932,7 +941,7 @@ public class Edsf.Persona : Folks.Persona,
       var default_role_fd = this._get_default_role ();
       if (default_role_fd != null)
         {
-          new_roles.add (default_role_fd);
+          new_roles.add ((!) default_role_fd);
         }
 
       var vcard = (E.VCard) this.contact;
@@ -942,13 +951,13 @@ public class Edsf.Persona : Folks.Persona,
             continue;
 
           var val = attr.get_value ();
-          if (val == null || val == "")
+          if (val == null || (!) val == "")
              {
               continue;
             }
 
           var role = new Role ("", "");
-          role.role = val;
+          role.role = (!) val;
           var role_fd = new RoleFieldDetails (role);
 
           foreach (unowned E.VCardAttributeParam param in
@@ -997,7 +1006,7 @@ public class Edsf.Persona : Folks.Persona,
 
   private RoleFieldDetails? _get_default_role ()
     {
-      RoleFieldDetails? default_role = null;
+      RoleFieldDetails? _default_role = null;
 
       var org = (string?) this._get_property ("org");
       var org_unit = (string?) this._get_property ("org_unit");
@@ -1016,29 +1025,31 @@ public class Edsf.Persona : Folks.Persona,
           assistant != null)
         {
           var new_role = new Role (title, org);
-          if (role != null && role != "")
-            new_role.role = role;
+          if (role != null && (!) role != "")
+            new_role.role = (!) role;
 
           /* Check if it's non-empty. */
           if (!new_role.is_empty ())
             {
-              default_role = new RoleFieldDetails (new_role);
+              var default_role = new RoleFieldDetails (new_role);
 
               if (org_unit != null && org_unit != "")
-                default_role.set_parameter ("org_unit", org_unit);
+                default_role.set_parameter ("org_unit", (!) org_unit);
 
               if (office != null && office != "")
-                default_role.set_parameter ("office", office);
+                default_role.set_parameter ("office", (!) office);
 
               if (manager != null && manager != "")
-                default_role.set_parameter ("manager", manager);
+                default_role.set_parameter ("manager", (!) manager);
 
               if (assistant != null && manager != "")
-                default_role.set_parameter ("assistant", assistant);
+                default_role.set_parameter ("assistant", (!) assistant);
+
+              _default_role = default_role;
             }
         }
 
-      return default_role;
+      return _default_role;
     }
 
   private void _update_web_services_addresses ()
@@ -1051,12 +1062,12 @@ public class Edsf.Persona : Folks.Persona,
       var services = this.contact.get_attribute ("X-FOLKS-WEB-SERVICES-IDS");
       if (services != null)
         {
-          foreach (var service in services.get_params ())
+          foreach (var service in ((!) services).get_params ())
             {
               var service_name = service.get_name ().down ();
               foreach (var service_id in service.get_values ())
                 {
-                  if (service_id == null || service_id == "")
+                  if (service_id == "")
                     {
                       continue;
                     }
@@ -1085,12 +1096,12 @@ public class Edsf.Persona : Folks.Persona,
       foreach (var attr in attrs)
         {
           var val = attr.get_value ();
-          if (val == null || val == "")
+          if (val == null || (!) val == "")
             {
               continue;
             }
 
-          var email_fd = new EmailFieldDetails (val);
+          var email_fd = new EmailFieldDetails ((!) val);
           this._update_params (email_fd, attr);
           new_email_addresses.add (email_fd);
         }
@@ -1110,10 +1121,10 @@ public class Edsf.Persona : Folks.Persona,
           (GLib.HashFunc) NoteFieldDetails.hash,
           (GLib.EqualFunc) NoteFieldDetails.equal);
 
-      string n = (string) this._get_property ("note");
+      var n = (string?) this._get_property ("note");
       if (n != null && n != "")
         {
-          var note = new NoteFieldDetails (n);
+          var note = new NoteFieldDetails ((!) n);
           new_notes.add (note);
         }
 
@@ -1127,26 +1138,30 @@ public class Edsf.Persona : Folks.Persona,
 
   private void _update_names ()
     {
-      string full_name = (string) this._get_property ("full_name");
+      var _full_name = (string?) this._get_property ("full_name");
 
-      if (full_name == null)
+      if (_full_name == null)
         {
-          full_name = "";
+          _full_name = "";
         }
 
+      var full_name = (!) _full_name;
+
       if (this._full_name != full_name)
         {
           this._full_name = full_name;
           this.notify_property ("full-name");
         }
 
-      string nickname = (string) this._get_property ("nickname");
+      var _nickname = (string?) this._get_property ("nickname");
 
-      if (nickname == null)
+      if (_nickname == null)
         {
-          nickname = "";
+          _nickname = "";
         }
 
+      var nickname = (!) _nickname;
+
       if (this._nickname != nickname)
         {
           this._nickname = nickname;
@@ -1154,9 +1169,11 @@ public class Edsf.Persona : Folks.Persona,
         }
 
       StructuredName? structured_name = null;
-      E.ContactName? cn = (E.ContactName) this._get_property ("name");
-      if (cn != null)
+      var _cn = (E.ContactName?) this._get_property ("name");
+      if (_cn != null)
         {
+          var cn = (!) _cn;
+
           string family_name = cn.family;
           string given_name  = cn.given;
           string additional_names = cn.additional;
@@ -1167,9 +1184,9 @@ public class Edsf.Persona : Folks.Persona,
                                                 suffixes);
         }
 
-      if (structured_name != null && !structured_name.is_empty ())
+      if (structured_name != null && !((!) structured_name).is_empty ())
         {
-          this._structured_name = structured_name;
+          this._structured_name = (!) structured_name;
           this.notify_property ("structured-name");
         }
       else if (this._structured_name != null)
@@ -1179,29 +1196,34 @@ public class Edsf.Persona : Folks.Persona,
         }
     }
 
-  private LoadableIcon? _contact_photo_to_loadable_icon (ContactPhoto? p)
+  private LoadableIcon? _contact_photo_to_loadable_icon (ContactPhoto? _p)
     {
-      if (p == null)
+      if (_p == null)
         {
           return null;
         }
 
+      var p = (!) _p;
+
       switch (p.type)
         {
           case ContactPhotoType.URI:
-            if (p.get_uri () == null)
+            var uri = p.get_uri ();
+            if (uri == null)
               {
                 return null;
               }
 
-            return new FileIcon (File.new_for_uri (p.get_uri ()));
+            return new FileIcon (File.new_for_uri ((!) uri));
           case ContactPhotoType.INLINED:
-            if (p.get_inlined () == null)
+            var data = p.get_inlined ();
+            var mime_type = p.get_mime_type ();
+            if (data == null || mime_type == null)
               {
                 return null;
               }
 
-            return new Edsf.MemoryIcon (p.get_mime_type (), p.get_inlined ());
+            return new Edsf.MemoryIcon ((!) mime_type, (!) data);
           default:
             return null;
         }
@@ -1209,7 +1231,7 @@ public class Edsf.Persona : Folks.Persona,
 
   private void _update_avatar ()
     {
-      E.ContactPhoto? p = (E.ContactPhoto) this._get_property ("photo");
+      var p = (E.ContactPhoto?) this._get_property ("photo");
 
       var cache = AvatarCache.dup ();
 
@@ -1231,12 +1253,13 @@ public class Edsf.Persona : Folks.Persona,
               this.notify_property ("avatar");
             });
         }
-      else if ((this.avatar == null && new_avatar != null) ||
-          (this.avatar != null && new_avatar != null &&
-           this._avatar.equal (new_avatar) == false))
+      else if ((this._avatar == null && new_avatar != null) ||
+          (this._avatar != null && new_avatar != null &&
+           ((!) this._avatar).equal (new_avatar) == false))
         {
-          // Store the new avatar in the cache.
-          cache.store_avatar.begin (this.uid, new_avatar, (obj, res) =>
+          /* Store the new avatar in the cache. new_avatar is guaranteed to be
+           * non-null. */
+          cache.store_avatar.begin (this.uid, (!) new_avatar, (obj, res) =>
             {
               try
                 {
@@ -1264,10 +1287,10 @@ public class Edsf.Persona : Folks.Persona,
           var url_property = mapping.vcard_field_name;
           var folks_type = mapping.folks_type;
 
-          string u = (string) this._get_property (url_property);
+          var u = (string?) this._get_property (url_property);
           if (u != null && u != "")
             {
-              var fd_u = new UrlFieldDetails (u);
+              var fd_u = new UrlFieldDetails ((!) u);
               fd_u.set_parameter (fd_u.PARAM_TYPE, folks_type);
               new_urls.add (fd_u);
             }
@@ -1280,12 +1303,12 @@ public class Edsf.Persona : Folks.Persona,
           if (attr.get_name () == "X-URIS")
             {
               var val = attr.get_value ();
-              if (val == null || val == "")
+              if (val == null || (!) val == "")
                 {
                   continue;
                 }
 
-              var url_fd = new UrlFieldDetails (val);
+              var url_fd = new UrlFieldDetails ((!) val);
               this._update_params (url_fd, attr);
               new_urls.add (url_fd);
             }
@@ -1315,13 +1338,13 @@ public class Edsf.Persona : Folks.Persona,
               try
                 {
                   var addr = attr.get_value ();
-                  if (addr == null || addr == "")
+                  if (addr == null || (!) addr == "")
                     {
                       continue;
                     }
 
                   string normalised_addr =
-                    (owned) ImDetails.normalise_im_address (addr, im_proto);
+                    (owned) ImDetails.normalise_im_address ((!) addr, im_proto);
                   var im_fd = new ImFieldDetails (normalised_addr);
                   new_im_addresses.set (im_proto, im_fd);
                 }
@@ -1345,15 +1368,18 @@ public class Edsf.Persona : Folks.Persona,
        */
       foreach (var email in this.email_addresses)
         {
-          var proto = this._im_proto_from_addr (email.value);
-          if (proto != null)
+          var _proto = this._im_proto_from_addr (email.value);
+          if (_proto != null)
             {
+              var proto = (!) _proto;
+
               /* Has this already been added? */
               var exists = false;
-              var current_im_addrs = new_im_addresses.get (proto);
+              Collection<ImFieldDetails>? current_im_addrs =
+                  new_im_addresses.get (proto);
               if (current_im_addrs != null)
                 {
-                  foreach (var cur_im in current_im_addrs)
+                  foreach (var cur_im in (!) current_im_addrs)
                     {
                       if (cur_im.value == email.value)
                         {
@@ -1444,30 +1470,31 @@ public class Edsf.Persona : Folks.Persona,
    */
   internal static HashTable<string, E.ContactField> _get_im_eds_map ()
     {
+      HashTable<string, E.ContactField> retval;
+
       lock (Edsf.Persona._im_eds_map)
         {
           if (Edsf.Persona._im_eds_map == null)
             {
-              Edsf.Persona._im_eds_map =
-                new HashTable<string, E.ContactField> (str_hash, str_equal);
-              Edsf.Persona._im_eds_map.insert ("aim", ContactField.IM_AIM);
-              Edsf.Persona._im_eds_map.insert ("yahoo", ContactField.IM_YAHOO);
-              Edsf.Persona._im_eds_map.insert ("groupwise",
-                  ContactField.IM_GROUPWISE);
-              Edsf.Persona._im_eds_map.insert ("jabber",
-                  ContactField.IM_JABBER);
-              Edsf.Persona._im_eds_map.insert ("msn",
-                  ContactField.IM_MSN);
-              Edsf.Persona._im_eds_map.insert ("icq",
-                  ContactField.IM_ICQ);
-              Edsf.Persona._im_eds_map.insert ("gadugadu",
-                  ContactField.IM_GADUGADU);
-              Edsf.Persona._im_eds_map.insert ("skype",
-                  ContactField.IM_SKYPE);
+              var table =
+                  new HashTable<string, E.ContactField> (str_hash, str_equal);
+
+              table.insert ("aim", ContactField.IM_AIM);
+              table.insert ("yahoo", ContactField.IM_YAHOO);
+              table.insert ("groupwise", ContactField.IM_GROUPWISE);
+              table.insert ("jabber", ContactField.IM_JABBER);
+              table.insert ("msn", ContactField.IM_MSN);
+              table.insert ("icq", ContactField.IM_ICQ);
+              table.insert ("gadugadu", ContactField.IM_GADUGADU);
+              table.insert ("skype", ContactField.IM_SKYPE);
+
+              Edsf.Persona._im_eds_map = table;
             }
+
+          retval = (!) Edsf.Persona._im_eds_map;
         }
 
-      return Edsf.Persona._im_eds_map;
+      return retval;
     }
 
   private void _update_phones ()
@@ -1480,12 +1507,12 @@ public class Edsf.Persona : Folks.Persona,
       foreach (var attr in attrs)
         {
           var val = attr.get_value ();
-          if (val == null || val == "")
+          if (val == null || (!) val == "")
             {
               continue;
             }
 
-          var phone_fd = new PhoneFieldDetails (val);
+          var phone_fd = new PhoneFieldDetails ((!) val);
           this._update_params (phone_fd, attr);
           new_phone_numbers.add (phone_fd);
         }
@@ -1501,8 +1528,8 @@ public class Edsf.Persona : Folks.Persona,
 
   private PostalAddress _postal_address_from_attribute (E.VCardAttribute attr)
     {
-      unowned GLib.List<string?> values = attr.get_values();
-      unowned GLib.List<string?> l = values;
+      unowned GLib.List<string>? values = attr.get_values();
+      unowned GLib.List<string>? l = values;
 
       var address_format = "";
       var po_box = "";
@@ -1515,38 +1542,38 @@ public class Edsf.Persona : Folks.Persona,
 
       if (l != null)
         {
-          po_box = l.data;
-          l = l.next;
+          po_box = ((!) l).data;
+          l = ((!) l).next;
         }
       if (l != null)
         {
-          extension = l.data;
-          l = l.next;
+          extension = ((!) l).data;
+          l = ((!) l).next;
         }
       if (l != null)
         {
-          street = l.data;
-          l = l.next;
+          street = ((!) l).data;
+          l = ((!) l).next;
         }
       if (l != null)
         {
-          locality = l.data;
-          l = l.next;
+          locality = ((!) l).data;
+          l = ((!) l).next;
         }
       if (l != null)
         {
-          region = l.data;
-          l = l.next;
+          region = ((!) l).data;
+          l = ((!) l).next;
         }
       if (l != null)
         {
-          postal_code = l.data;
-          l = l.next;
+          postal_code = ((!) l).data;
+          l = ((!) l).next;
         }
       if (l != null)
         {
-          country = l.data;
-          l = l.next;
+          country = ((!) l).data;
+          l = ((!) l).next;
         }
 
       return new PostalAddress (po_box, extension, street,
@@ -1593,11 +1620,11 @@ public class Edsf.Persona : Folks.Persona,
       var ids = this.contact.get_attribute ("X-FOLKS-CONTACTS-IDS");
       if (ids != null)
         {
-          unowned GLib.List<string> ids_v = ids.get_values ();
+          unowned GLib.List<string> ids_v = ((!) ids).get_values ();
 
           foreach (var local_id in ids_v)
             {
-              if (local_id != null && local_id != "")
+              if (local_id != "")
                 {
                   new_local_ids.add (local_id);
                 }
@@ -1622,8 +1649,8 @@ public class Edsf.Persona : Folks.Persona,
       var fav = this.contact.get_attribute ("X-FOLKS-FAVOURITE");
       if (fav != null)
         {
-          var val = fav.get_value ();
-          if (val.down () == "true")
+          var val = ((!) fav).get_value ();
+          if (val != null && ((!) val).down () == "true")
             {
               is_fav = true;
             }
@@ -1636,6 +1663,7 @@ public class Edsf.Persona : Folks.Persona,
         }
     }
 
+  // NOTE: This may return null, but Vala doesn't allow us to express that in the type system for void* types.
   internal static void * _get_property_from_contact (E.Contact contact,
       string prop_name)
     {
@@ -1644,6 +1672,7 @@ public class Edsf.Persona : Folks.Persona,
       return prop_value;
     }
 
+  // NOTE: This may return null, but Vala doesn't allow us to express that in the type system for void* types.
   private void * _get_property (string prop_name)
     {
       return Edsf.Persona._get_property_from_contact (this.contact,
diff --git a/backends/eds/lib/memory-icon.vala b/backends/eds/lib/memory-icon.vala
index 5a06e0d..07c0197 100644
--- a/backends/eds/lib/memory-icon.vala
+++ b/backends/eds/lib/memory-icon.vala
@@ -57,11 +57,15 @@ internal class Edsf.MemoryIcon : Object, Icon, LoadableIcon
    * @return `true` if the instances are equal, `false` otherwise
    * @since 0.6.0
    */
+#if VALA_0_16
+  public bool equal (Icon? icon2)
+#else
   public bool equal (Icon icon2)
+#endif
     {
-      // This type check be taken care of by the interface wrapper.
-      var icon = icon2 as MemoryIcon;
-      assert (icon != null);
+      /* These type and nullability checks are taken care of by the interface
+       * wrapper. */
+      var icon = (MemoryIcon) (!) icon2;
 
       return (this._image_data.length == icon._image_data.length &&
               Memory.cmp (this._image_data, icon._image_data,
@@ -87,7 +91,7 @@ internal class Edsf.MemoryIcon : Object, Icon, LoadableIcon
        *
        * Basically, this is just a nul-safe version of g_str_hash(). Which is
        * calculated over both the image type and image data. */
-      uint hash = this._image_type != null ? this._image_type.hash () : 0;
+      uint hash = this._image_type != null ? ((!) this._image_type).hash () : 0;
 
       for (uint i = 0; i < this._image_data.length; i++)
         {
diff --git a/folks/persona-store.vala b/folks/persona-store.vala
index fe7d2b2..118a7e7 100644
--- a/folks/persona-store.vala
+++ b/folks/persona-store.vala
@@ -619,7 +619,8 @@ public abstract class Folks.PersonaStore : Object
    * return value is purely for convenience, since it can be complicated to
    * correlate the provided details with the final Persona.
    *
-   * If the store is offline, this function will throw
+   * If the store is offline (or { link PersonaStore.prepare()} hasn't yet been
+   * called successfully), this function will throw
    * { link PersonaStoreError.STORE_OFFLINE}. It's the responsibility of the
    * caller to cache details and re-try this function if it wishes to make
    * offline adds work.
@@ -651,6 +652,12 @@ public abstract class Folks.PersonaStore : Object
    * will be signalled through emission of
    * { link PersonaStore.personas_changed}.
    *
+   * If the store is offline (or { link PersonaStore.prepare()} hasn't yet been
+   * called successfully), this function will throw
+   * { link PersonaStoreError.STORE_OFFLINE}. It's the responsibility of the
+   * caller to cache details and re-try this function if it wishes to make
+   * offline removals work.
+   *
    * @param persona the { link Persona} to remove
    * @since 0.1.11
    */



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