diff --git a/src/DOM.cpp b/src/DOM.cpp index 53f59b00b..a0b65a2fb 100644 --- a/src/DOM.cpp +++ b/src/DOM.cpp @@ -245,14 +245,16 @@ bool getDOM (const std::string& name, const Task& task, Variant& value) if (name == "") return false; + auto have_task = !task.is_empty(); + // Quickly deal with the most common cases. - if (task.data_removeme ().size () && name == "id") + if (have_task && name == "id") { value = Variant (static_cast (task.id)); return true; } - if (task.data_removeme ().size () && name == "urgency") + if (have_task && name == "urgency") { value = Variant (task.urgency_c ()); return true; @@ -310,6 +312,7 @@ bool getDOM (const std::string& name, const Task& task, Variant& value) return task; } (); + auto have_ref = !ref.is_empty(); auto size = elements.size (); @@ -318,13 +321,13 @@ bool getDOM (const std::string& name, const Task& task, Variant& value) { // Now that 'ref' is the contextual task, and any ID/UUID is chopped off the // elements vector, DOM resolution is now simple. - if (ref.data_removeme ().size () && size == 1 && canonical == "id") + if (have_ref && size == 1 && canonical == "id") { value = Variant (static_cast (ref.id)); return true; } - if (ref.data_removeme ().size () && size == 1 && canonical == "urgency") + if (have_ref && size == 1 && canonical == "urgency") { value = Variant (ref.urgency_c ()); return true; @@ -332,7 +335,7 @@ bool getDOM (const std::string& name, const Task& task, Variant& value) // Special handling of status required for virtual waiting status // implementation. Remove in 3.0.0. - if (ref.data_removeme ().size () && size == 1 && canonical == "status") + if (have_ref && size == 1 && canonical == "status") { value = Variant (ref.statusToText (ref.getStatus ())); return true; @@ -340,7 +343,7 @@ bool getDOM (const std::string& name, const Task& task, Variant& value) Column* column = Context::getContext ().columns[canonical]; - if (ref.data_removeme ().size () && size == 1 && column) + if (have_ref && size == 1 && column) { if (column->is_uda () && ! ref.has (canonical)) { @@ -375,13 +378,13 @@ bool getDOM (const std::string& name, const Task& task, Variant& value) return true; } - if (ref.data_removeme ().size () && size == 2 && canonical == "tags") + if (have_ref && size == 2 && canonical == "tags") { value = Variant (ref.hasTag (elements[1]) ? elements[1] : ""); return true; } - if (ref.data_removeme ().size () && size == 2 && column && column->type () == "date") + if (have_ref && size == 2 && column && column->type () == "date") { Datetime date (ref.get_date (canonical)); if (elements[1] == "year") { value = Variant (static_cast (date.year ())); return true; } @@ -396,13 +399,13 @@ bool getDOM (const std::string& name, const Task& task, Variant& value) } } - if (ref.data_removeme ().size () && size == 2 && elements[0] == "annotations" && elements[1] == "count") + if (have_ref && size == 2 && elements[0] == "annotations" && elements[1] == "count") { value = Variant (static_cast (ref.getAnnotationCount ())); return true; } - if (ref.data_removeme ().size () && size == 3 && elements[0] == "annotations") + if (have_ref && size == 3 && elements[0] == "annotations") { auto annos = ref.getAnnotations (); @@ -430,7 +433,7 @@ bool getDOM (const std::string& name, const Task& task, Variant& value) } } - if (ref.data_removeme ().size () && size == 4 && elements[0] == "annotations" && elements[2] == "entry") + if (have_ref && size == 4 && elements[0] == "annotations" && elements[2] == "entry") { auto annos = ref.getAnnotations (); diff --git a/src/Task.cpp b/src/Task.cpp index ec7e4a8eb..f0ddf833a 100644 --- a/src/Task.cpp +++ b/src/Task.cpp @@ -363,6 +363,14 @@ Task::dateState Task::getDateState (const std::string& name) const return dateNotDue; } +//////////////////////////////////////////////////////////////////////////////// +// An empty task is typically a "dummy", such as in DOM evaluation, which may or +// may not occur in the context of a task. +bool Task::is_empty () const +{ + return data.size () == 0; +} + //////////////////////////////////////////////////////////////////////////////// // Ready means pending, not blocked and either not scheduled or scheduled before // now. diff --git a/src/Task.h b/src/Task.h index 120c89c23..13ec396fa 100644 --- a/src/Task.h +++ b/src/Task.h @@ -100,6 +100,8 @@ public: void set (const std::string&, long long); void remove (const std::string&); + bool is_empty () const; + #ifdef PRODUCT_TASKWARRIOR bool is_ready () const; bool is_due () const;