Verified Commit efc05310 authored by Zander Brown's avatar Zander Brown 🔲
Browse files

general: enable vala (experimental) null checker

Add more explicit casts and null checks to fix the build

Fix GNOME/gnome-clocks#106
Reinforce GNOME/gnome-clocks#91 fixes

Nice bonuses:
 - Variant unpacking is less verbose and less fragile
 - Fix warning from the dbus service
 - Probably fix other bugs we didn't even know about
parent f743ad7f
......@@ -37,26 +37,24 @@ private class Item : Object, ContentItem {
SNOOZING
}
public string title_icon { get; set; default = null; }
public bool editing { get; set; default = false; }
public string id { get; construct set; }
public string name {
public string? name {
get {
return _name;
}
set {
_name = value;
_name = (string) value;
setup_bell ();
}
}
public AlarmTime time { get; set; }
public Utils.Weekdays days { get; set; }
public Utils.Weekdays? days { get; set; }
public State state { get; private set; }
......@@ -72,9 +70,9 @@ private class Item : Object, ContentItem {
}
}
public string days_label {
public string? days_label {
owned get {
return days != null ? days.get_label () : null;
return days != null ? (string?) ((Utils.Weekdays) days).get_label () : null;
}
}
......@@ -106,7 +104,7 @@ private class Item : Object, ContentItem {
private GLib.Notification notification;
public Item (string? id = null) {
var guid = id != null ? id : GLib.DBus.generate_guid ();
var guid = id != null ? (string) id : GLib.DBus.generate_guid ();
Object (id: guid);
}
......@@ -135,7 +133,7 @@ private class Item : Object, ContentItem {
time.minute,
0);
if (days == null || days.empty) {
if (days == null || ((Utils.Weekdays) days).empty) {
// Alarm without days.
if (dt.compare (now) <= 0) {
// Time already passed, ring tomorrow.
......@@ -144,7 +142,7 @@ private class Item : Object, ContentItem {
} else {
// Alarm with at least one day set.
// Find the next possible day for ringing
while (dt.compare (now) <= 0 || ! days.get ((Utils.Weekdays.Day) (dt.get_day_of_week () - 1))) {
while (dt.compare (now) <= 0 || ! ((Utils.Weekdays) days).get ((Utils.Weekdays.Day) (dt.get_day_of_week () - 1))) {
dt = dt.add_days (1);
}
}
......@@ -157,7 +155,7 @@ private class Item : Object, ContentItem {
}
public virtual signal void ring () {
var app = GLib.Application.get_default () as Clocks.Application;
var app = (Clocks.Application) GLib.Application.get_default ();
app.send_notification ("alarm-clock-elapsed", notification);
bell.ring ();
}
......@@ -226,39 +224,43 @@ private class Item : Object, ContentItem {
public void serialize (GLib.VariantBuilder builder) {
builder.open (new GLib.VariantType ("a{sv}"));
builder.add ("{sv}", "name", new GLib.Variant.string (name));
builder.add ("{sv}", "name", new GLib.Variant.string ((string) name));
builder.add ("{sv}", "id", new GLib.Variant.string (id));
builder.add ("{sv}", "active", new GLib.Variant.boolean (active));
builder.add ("{sv}", "hour", new GLib.Variant.int32 (time.hour));
builder.add ("{sv}", "minute", new GLib.Variant.int32 (time.minute));
builder.add ("{sv}", "days", days.serialize ());
builder.add ("{sv}", "days", ((Utils.Weekdays) days).serialize ());
builder.close ();
}
public static ContentItem? deserialize (GLib.Variant alarm_variant) {
public static ContentItem? deserialize (Variant alarm_variant) {
string key;
Variant val;
string? name = null;
string? id = null;
bool active = true;
int hour = -1;
int minute = -1;
Utils.Weekdays days = null;
foreach (var v in alarm_variant) {
var key = v.get_child_value (0).get_string ();
Utils.Weekdays? days = null;
var iter = alarm_variant.iterator ();
while (iter.next ("{sv}", out key, out val)) {
if (key == "name") {
name = v.get_child_value (1).get_child_value (0).get_string ();
name = (string) val;
} else if (key == "id") {
id = v.get_child_value (1).get_child_value (0).get_string ();
id = (string) val;
} else if (key == "active") {
active = v.get_child_value (1).get_child_value (0).get_boolean ();
active = (bool) val;
} else if (key == "hour") {
hour = v.get_child_value (1).get_child_value (0).get_int32 ();
hour = (int32) val;
} else if (key == "minute") {
minute = v.get_child_value (1).get_child_value (0).get_int32 ();
minute = (int32) val;
} else if (key == "days") {
days = Utils.Weekdays.deserialize (v.get_child_value (1).get_child_value (0));
days = Utils.Weekdays.deserialize (val);
}
}
if (name != null && hour >= 0 && minute >= 0) {
if (hour >= 0 && minute >= 0) {
Item alarm = new Item (id);
alarm.name = name;
alarm.active = active;
......@@ -267,8 +269,9 @@ private class Item : Object, ContentItem {
alarm.reset ();
return alarm;
} else {
warning ("Invalid alarm %s", name != null ? name : "name missing");
warning ("Invalid alarm %s", name != null ? (string) name : "[unnamed]");
}
return null;
}
}
......@@ -308,8 +311,8 @@ private class Row : Gtk.ListBoxRow {
}
private void update_repeats () {
repeats_reveal.reveal_child = !alarm.days.empty;
repeats.label = alarm.days_label;
repeats_reveal.reveal_child = !((Utils.Weekdays) alarm.days).empty;
repeats.label = (string) alarm.days_label;
}
private void update () {
......@@ -337,17 +340,17 @@ private class Row : Gtk.ListBoxRow {
}
if (alarm.state == Item.State.SNOOZING) {
if (label != null && label.length > 0) {
if (label != null && ((string) label).length > 0) {
// Translators: The alarm for the time %s titled %s has been "snoozed"
label = _("Snoozed from %s: %s").printf (alarm.time_label, label);
label = _("Snoozed from %s: %s").printf (alarm.time_label, (string) label);
} else {
// Translators: %s is a time
label = _("Snoozed from %s").printf (alarm.time_label);
}
}
title_reveal.reveal_child = label != null && label.length > 0;
title.label = label;
title_reveal.reveal_child = label != null && ((string) label).length > 0;
title.label = (string) label;
}
[GtkCallback]
......@@ -571,9 +574,9 @@ private class SetupDialog : Hdy.Dialog {
other_alarms = new List<Item> ();
var n = all_alarms.get_n_items ();
for (int i = 0; i < n; i++) {
var item = all_alarms.get_object (i) as Item;
var item = (Item) all_alarms.get_object (i);
if (alarm != item) {
other_alarms.prepend (all_alarms.get_object (i) as Item);
other_alarms.prepend ((Item) all_alarms.get_object (i));
}
}
......@@ -603,7 +606,7 @@ private class SetupDialog : Hdy.Dialog {
// Sets up the dialog to show the values of alarm.
public void set_from_alarm (Item? alarm) {
string name;
string? name;
bool active;
int hour;
int minute;
......@@ -618,11 +621,11 @@ private class SetupDialog : Hdy.Dialog {
days = null;
active = true;
} else {
name = alarm.name;
hour = alarm.time.hour;
minute = alarm.time.minute;
days = alarm.days;
active = alarm.active;
name = ((Item) alarm).name;
hour = ((Item) alarm).time.hour;
minute = ((Item) alarm).time.minute;
days = ((Item) alarm).days;
active = ((Item) alarm).active;
}
// Set the time.
......@@ -642,10 +645,10 @@ private class SetupDialog : Hdy.Dialog {
m_spinbutton.set_value (minute);
// Set the name.
name_entry.set_text (name);
name_entry.set_text ((string) name);
if (days != null) {
repeats.load (days);
repeats.load ((Utils.Weekdays) days);
}
}
......@@ -718,20 +721,20 @@ private class SetupDialog : Hdy.Dialog {
[GtkTemplate (ui = "/org/gnome/clocks/ui/alarmringing.ui")]
private class RingingPanel : Gtk.Grid {
public Item alarm {
public Item? alarm {
get {
return _alarm;
}
set {
if (_alarm != null) {
_alarm.disconnect (alarm_state_handler);
((Item) _alarm).disconnect (alarm_state_handler);
}
_alarm = value;
if (_alarm != null) {
alarm_state_handler = _alarm.notify["state"].connect (() => {
if (alarm.state != Item.State.RINGING) {
alarm_state_handler = ((Item) _alarm).notify["state"].connect (() => {
if (((Item) _alarm).state != Item.State.RINGING) {
dismiss ();
}
});
......@@ -747,14 +750,14 @@ private class RingingPanel : Gtk.Grid {
private Gtk.Label time_label;
[GtkCallback]
private void stop_clicked () {
alarm.stop ();
private void stop_clicked () requires (alarm != null) {
((Item) alarm).stop ();
}
[GtkCallback]
private void snooze_clicked () {
if (alarm.state != Item.State.SNOOZING) {
alarm.snooze ();
private void snooze_clicked () requires (alarm != null) {
if (((Item) alarm).state != Item.State.SNOOZING) {
((Item) alarm).snooze ();
} else {
// The alarm is already snoozed, simply dismiss the panel.
dismiss ();
......@@ -767,11 +770,11 @@ private class RingingPanel : Gtk.Grid {
public void update () {
if (alarm != null) {
title_label.label = alarm.name;
if (alarm.state == Item.State.SNOOZING) {
time_label.label = alarm.snooze_time_label;
title_label.label = (string) ((Item) alarm).name;
if (((Item) alarm).state == SNOOZING) {
time_label.label = ((Item) alarm).snooze_time_label;
} else {
time_label.label = alarm.time_label;
time_label.label = ((Item) alarm).time_label;
}
} else {
title_label.label = "";
......@@ -788,7 +791,7 @@ public class Face : Gtk.Stack, Clocks.Clock {
public string title { get; set; default = _("Clocks"); }
public string subtitle { get; set; }
// Translators: Tooltip for the + button
public string new_label { get; default = _("New Alarm"); }
public string? new_label { get; default = _("New Alarm"); }
private ContentStore alarms;
private GLib.Settings settings;
......@@ -808,23 +811,25 @@ public class Face : Gtk.Stack, Clocks.Clock {
settings = new GLib.Settings ("org.gnome.clocks");
var app = GLib.Application.get_default ();
var action = app.lookup_action ("stop-alarm");
((GLib.SimpleAction)action).activate.connect ((action, param) => {
var a = (Item)alarms.find ((a) => {
return ((Item)a).id == param.get_string ();
var action = (GLib.SimpleAction) app.lookup_action ("stop-alarm");
action.activate.connect ((action, param) => {
var a = alarms.find ((a) => {
return ((Item) a).id == (string) param;
});
if (a != null) {
a.stop ();
((Item) a).stop ();
}
});
action = app.lookup_action ("snooze-alarm");
((GLib.SimpleAction)action).activate.connect ((action, param) => {
var a = (Item)alarms.find ((a) => {
return ((Item)a).id == param.get_string ();
action = (GLib.SimpleAction) app.lookup_action ("snooze-alarm");
action.activate.connect ((action, param) => {
var a = alarms.find ((a) => {
return ((Item) a).id == (string) param;
});
if (a != null) {
a.snooze ();
((Item) a).stop ();
}
});
......
......@@ -21,7 +21,7 @@ namespace Clocks {
public class Application : Gtk.Application {
const OptionEntry[] OPTION_ENTRIES = {
{ "version", 'v', 0, OptionArg.NONE, null, N_("Print version information and exit"), null },
{ null }
{ (string) null }
};
const GLib.ActionEntry[] ACTION_ENTRIES = {
......@@ -35,16 +35,17 @@ public class Application : Gtk.Application {
private uint search_provider_id = 0;
private World.ShellWorldClocks world_clocks;
private uint world_clocks_id = 0;
private Window window;
private Window? window;
private List<string> system_notifications;
private void ensure_window () {
private Window ensure_window () ensures (window != null) {
if (window == null) {
window = new Window (this);
window.delete_event.connect (() => {
return window.hide_on_delete ();
((Window) window).delete_event.connect (() => {
return ((Window) window).hide_on_delete ();
});
}
return (Window) window;
}
public Application () {
......@@ -57,9 +58,9 @@ public class Application : Gtk.Application {
search_provider = new SearchProvider ();
search_provider.activate.connect ((timestamp) => {
ensure_window ();
window.show_world ();
window.present_with_time (timestamp);
var win = ensure_window ();
win.show_world ();
win.present_with_time (timestamp);
});
system_notifications = new List<string> ();
......@@ -97,10 +98,10 @@ public class Application : Gtk.Application {
protected override void activate () {
base.activate ();
ensure_window ();
window.present ();
var win = ensure_window ();
win.present ();
window.focus_in_event.connect (() => {
win.focus_in_event.connect (() => {
withdraw_notifications ();
return false;
......@@ -124,7 +125,7 @@ public class Application : Gtk.Application {
var theme = Gtk.IconTheme.get_default ();
theme.add_resource_path ("/org/gnome/clocks/icons");
var settings = Gtk.Settings.get_default ();
var settings = (Gtk.Settings) Gtk.Settings.get_default ();
settings.notify["gtk-theme-name"].connect (() => {
update_theme (settings);
});
......@@ -139,7 +140,7 @@ public class Application : Gtk.Application {
protected override int handle_local_options (GLib.VariantDict options) {
if (options.contains ("version")) {
print ("%s %s\n", Environment.get_application_name (), Config.VERSION);
print ("%s %s\n", (string) Environment.get_application_name (), Config.VERSION);
return 0;
}
......@@ -151,14 +152,19 @@ public class Application : Gtk.Application {
return;
}
ensure_window ();
window.show_world ();
window.present ();
var win = ensure_window ();
win.show_world ();
win.present ();
var world = GWeather.Location.get_world ();
var location = world.deserialize (parameter.get_child_value (0));
if (location != null) {
window.add_world_location (location);
if (world != null) {
// The result is actually nullable
var location = (GWeather.Location?) ((GWeather.Location) world).deserialize ((Variant) parameter);
if (location != null) {
win.add_world_location ((GWeather.Location) location);
}
} else {
warning ("the world is missing");
}
}
......@@ -181,7 +187,9 @@ public class Application : Gtk.Application {
}
void on_quit_activate () {
window.destroy ();
if (window != null) {
((Window) window).destroy ();
}
quit ();
}
}
......
......@@ -30,7 +30,7 @@ public interface Clocks.Clock : GLib.Object {
public abstract ViewMode view_mode { get; set; }
public abstract string title { get; protected set; }
public abstract string subtitle { get; protected set; }
public abstract string new_label { get; }
public abstract string? new_label { get; }
public virtual void activate_new () {
}
......
......@@ -55,19 +55,20 @@ public class Info : Object {
yield seek_country_code ();
yield search_locations (GWeather.Location.get_world ());
yield search_locations ((GWeather.Location) GWeather.Location.get_world ());
if (found_location != null) {
location_changed (found_location);
location_changed ((GWeather.Location) found_location);
}
}
private async void seek_country_code () {
Geocode.Location location = new Geocode.Location (geo_location.latitude, geo_location.longitude);
Geocode.Reverse reverse = new Geocode.Reverse.for_location (location);
private async void seek_country_code () requires (geo_location != null) {
var location = new Geocode.Location (((GClue.Location) geo_location).latitude,
((GClue.Location) geo_location).longitude);
var reverse = new Geocode.Reverse.for_location (location);
try {
Geocode.Place place = yield reverse.resolve_async ();
var place = yield reverse.resolve_async ();
country_code = place.get_country_code ();
} catch (Error e) {
......@@ -91,7 +92,7 @@ public class Info : Object {
Math.sin (lat1) * Math.sin (lat2)) * EARTH_RADIUS;
}
private async void search_locations (GWeather.Location location) {
private async void search_locations (GWeather.Location location) requires (geo_location != null) {
if (this.country_code != null) {
string? loc_country_code = location.get_country ();
if (loc_country_code != null) {
......@@ -101,39 +102,40 @@ public class Info : Object {
}
}
GWeather.Location? [] locations = location.get_children ();
if (locations != null) {
for (int i = 0; i < locations.length; i++) {
if (locations[i].get_level () == GWeather.LocationLevel.CITY) {
if (locations[i].has_coords ()) {
double latitude, longitude, distance;
locations[i].get_coords (out latitude, out longitude);
distance = get_distance (geo_location.latitude, geo_location.longitude, latitude, longitude);
if (distance < minimal_distance) {
found_location = locations[i];
minimal_distance = distance;
}
var locations = location.get_children ();
for (int i = 0; i < locations.length; i++) {
if (locations[i].get_level () == GWeather.LocationLevel.CITY) {
if (locations[i].has_coords ()) {
double latitude, longitude, distance;
locations[i].get_coords (out latitude, out longitude);
distance = get_distance (((GClue.Location) geo_location).latitude,
((GClue.Location) geo_location).longitude,
latitude,
longitude);
if (distance < minimal_distance) {
found_location = locations[i];
minimal_distance = distance;
}
}
yield search_locations (locations[i]);
}
yield search_locations (locations[i]);
}
}
public bool is_location_similar (GWeather.Location location) {
if (this.found_location != null) {
string? country_code = location.get_country ();
string? found_country_code = found_location.get_country ();
var country_code = location.get_country ();
var found_country_code = ((GWeather.Location) found_location).get_country ();
if (country_code != null && country_code == found_country_code) {
GWeather.Timezone? timezone = location.get_timezone ();
GWeather.Timezone? found_timezone = found_location.get_timezone ();
var timezone = location.get_timezone ();
var found_timezone = ((GWeather.Location) found_location).get_timezone ();
if (timezone != null && found_timezone != null) {
string? tzid = timezone.get_tzid ();
string? found_tzid = found_timezone.get_tzid ();
var tzid = ((GWeather.Timezone) timezone).get_tzid ();
var found_tzid = ((GWeather.Timezone) found_timezone).get_tzid ();
if (tzid == found_tzid) {
return true;
}
......
......@@ -83,7 +83,7 @@ public class Clocks.HeaderBar : Hdy.HeaderBar {
public Gtk.Stack stack { get; set; }
public Hdy.ViewSwitcherBar switcher_bar { get; set; }
public string new_label { get; set; }
public string? new_label { get; set; }
private ViewMode _mode;
private ButtonMode _button_mode;
......@@ -103,7 +103,7 @@ public class Clocks.HeaderBar : Hdy.HeaderBar {
[GtkCallback]
private void subtitle_changed () {
reveal_subtitle.reveal_child = subtitle != null && subtitle.length > 0;
reveal_subtitle.reveal_child = ((string?) subtitle) != null && subtitle.length > 0;
}
[GtkCallback]
......
......@@ -31,9 +31,10 @@ clocks_sources = [
]
clocks_vala_args = [
'--target-glib', '2.44',
'--target-glib', '2.58',
'--vapidir', meson.current_source_dir(),
'--gresources', resource_files,
'--enable-experimental-non-null',
]
clocks_c_args = [
......
......@@ -34,15 +34,16 @@ public class SearchProvider : Object {
}
private bool location_matches (GWeather.Location location, string[] normalized_terms) {
string city = location.get_city_name ();
string country = location.get_country_name ();
var city = location.get_city_name ();
var country = location.get_country_name ();
if (city == null || country == null) {
return false;
}
foreach (string t in normalized_terms) {
if (!city.normalize ().casefold ().contains (t) &&
!country.normalize ().casefold ().contains (t)) {
if (!((string) city).normalize ().casefold ().contains (t) &&
!((string) country).normalize ().casefold ().contains (t)) {
return false;
}
}
......@@ -55,7 +56,7 @@ public class SearchProvider : Object {
}