diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2011-07-19 13:42:18 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2011-07-19 13:42:18 +0200 |
commit | 73c98a67ef4ed605cf69e0d212934c4dc1f3eb8e (patch) | |
tree | 8645cd8d06f218ff5d945b1b3b94a58a127753c4 /odb/validator.cxx | |
parent | 12d0d9bbd0f5b7295c50fd5b223e538afe1abbf7 (diff) |
New design for NULL semantics
Now, instead of being specified as part of the SQL type with the type
pragma, there are separate null and not_null pragmas. The not_null
pragma was used to control NULL-ness of object pointers. Now the two
pragmas are used consistently for object pointers and simple values
(and in the future will work for composite values and containers).
Diffstat (limited to 'odb/validator.cxx')
-rw-r--r-- | odb/validator.cxx | 83 |
1 files changed, 77 insertions, 6 deletions
diff --git a/odb/validator.cxx b/odb/validator.cxx index 487d69a..b07f5cd 100644 --- a/odb/validator.cxx +++ b/odb/validator.cxx @@ -15,6 +15,29 @@ using namespace std; namespace { + // Resolve null overrides. + // + static void + override_null (semantics::node& n, string const& prefix = "") + { + string p (prefix.empty () ? prefix : prefix + '-'); + + if (n.count (p + "null") && n.count (p + "not-null")) + { + if (n.get<location_t> (p + "null-loc") < + n.get<location_t> (p + "not-null-loc")) + { + n.remove (p + "null"); + n.remove (p + "null-loc"); + } + else + { + n.remove (p + "not-null"); + n.remove (p + "not-null-loc"); + } + } + } + struct data_member: traversal::data_member { data_member (bool& valid) @@ -42,6 +65,11 @@ namespace valid_ = false; } + + // Resolve null overrides. + // + override_null (m); + override_null (m, "value"); } bool& valid_; @@ -119,22 +147,44 @@ namespace // // + struct value_type: traversal::type + { + value_type (bool& valid): valid_ (valid) {} + + virtual void + traverse (semantics::type& t) + { + // Resolve null overrides. + // + override_null (t); + override_null (t, "value"); + } + + bool& valid_; + }; + + // + // struct class_: traversal::class_ { - class_ (bool& valid, semantics::unit& unit) - : valid_ (valid), unit_ (unit), member_ (valid) + class_ (bool& valid, semantics::unit& unit, value_type& vt) + : valid_ (valid), unit_ (unit), vt_ (vt), member_ (valid) { *this >> names_ >> member_; } - virtual void traverse (type& c) { if (c.count ("object")) traverse_object (c); - else if (context::comp_value (c)) - traverse_value (c); + else + { + if (context::comp_value (c)) + traverse_value (c); + + vt_.dispatch (c); + } } virtual void @@ -234,8 +284,23 @@ namespace } } else + { c.set ("id-member", id); + // Automatically mark the id member as not null. If we already have + // an explicit null pragma for this member, issue an error. + // + if (id->count ("null")) + { + cerr << id->file () << ":" << id->line () << ":" << id->column () + << ": error: object id member cannot be null" << endl; + + valid_ = false; + } + else + id->set ("not-null", string ()); + } + // Check members. // member_.count_ = 0; @@ -317,6 +382,7 @@ namespace bool& valid_; semantics::unit& unit_; + value_type& vt_; data_member member_; traversal::names names_; @@ -332,16 +398,21 @@ validate (options const&, traversal::unit unit; traversal::defines unit_defines; + traversal::declares unit_declares; traversal::namespace_ ns; - class_ c (valid, u); + value_type vt (valid); + class_ c (valid, u, vt); unit >> unit_defines >> ns; unit_defines >> c; + unit >> unit_declares >> vt; traversal::defines ns_defines; + traversal::declares ns_declares; ns >> ns_defines >> ns; ns_defines >> c; + ns >> ns_declares >> vt; unit.dispatch (u); |