-
Notifications
You must be signed in to change notification settings - Fork 274
Add improved functionality for the construction of json_arrayt and json_objectt #3862
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add improved functionality for the construction of json_arrayt and json_objectt #3862
Conversation
src/util/json.h
Outdated
@@ -283,6 +283,12 @@ class json_objectt:public jsont | |||
{ | |||
} | |||
|
|||
explicit json_objectt( | |||
std::initializer_list<typename objectt::value_type> initializer_list) | |||
: json_objectt{objectt{initializer_list}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for this further improvement! I suspect it's kind of a painful ask, but would you mind adding a commit that now removes the outermost parentheses from various bits touched in 64df79e?
@@ -16,52 +16,47 @@ Author: Martin Brain, [email protected] | |||
#include <goto-programs/goto_model.h> | |||
|
|||
#include <analyses/ai.h> | |||
#include <util/range.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please move this 5 lines up so that it becomes part of the util
block.
775e950
to
f4952c6
Compare
0ec1923
to
55051ea
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✔️
Passed Diffblue compatibility checks (cbmc commit: 55051ea).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/97979428
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the extra work!
Does this work with Visual Studio 2013? |
@kroening I wrote this PR under Debian 9 "Stretch" using gcc 6. So I haven't tried building in VS 2013 myself. However the windows CI build has passed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Love it.
/// Constructs a collection containing the values, which this range iterates | ||
/// over. | ||
template <typename containert> | ||
containert collect() const |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💚
|
||
/// A type of functor which wraps around the set of constructors of a type. | ||
/// \tparam constructedt: The type which this functor constructs. | ||
template <typename constructedt> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓ What is the use of this? Currently only used in the unit test so was thinking it should live there, but of course if it has general utility then here is fine
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is used in a later commit.
@@ -359,6 +359,12 @@ struct ranget final | |||
return containert(begin(), end()); | |||
} | |||
|
|||
template <typename containert> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💚 💚
@kroening Do you want any additional checks done around visual studio 2013 compatibility? CI passing + reviewer approval would normally be considered to be sufficient. Given that the new code is both unit tested and used, there should have been compile errors, or failing tests if any issues were introduced. This PR now touches a wide range of directories, due to the bracket removal requested by Michael Tautschnig. Which means that it seems to require review from a unknown number of reviewers. It would save time if you would merge this. |
// clang-format on | ||
source_locationt source_location; | ||
irep_idt function_id; | ||
}; | ||
|
||
/// Makes a status message string from a status. | ||
static std::string message(const static_verifier_resultt::statust &status) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest const char *
since this only ever returns constants (no need to bind our caller to necessarily go through std::string
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -152,8 +152,8 @@ static void add_to_json( | |||
|
|||
// print info for file actually with full path | |||
const source_locationt &l=it->second->source_location; | |||
json_objectt i_entry( | |||
{{"sourceLocation", json(l)}, {"statement", json_stringt(s)}}); | |||
json_objectt i_entry{{"sourceLocation", json(l)}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Surprising formatting -- break after first {
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I insert a new line, then clang format will just remove it again. I agree that left alignment of the enclosed pairs would be preferable. However I prefer the sub optimal formatting over the extra comments to switch off the formatting in this case.
@@ -172,8 +172,8 @@ json_objectt json(const typet &type, const namespacet &ns, const irep_idt &mode) | |||
to_struct_type(type).components(); | |||
for(const auto &component : components) | |||
{ | |||
json_objectt e({{"name", json_stringt(component.get_name())}, | |||
{"type", json(component.type(), ns, mode)}}); | |||
json_objectt e{{"name", json_stringt(component.get_name())}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same formatting nitpick as above
{ | ||
} | ||
|
||
template <typename begin_iteratort, typename end_iteratort> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Surely these have to be the same type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Forwarding these parameters separately means that the template can match when the two iterators have different const
or reference qualifiers. For example .begin()
on a range returns a mutable instance of the iterator by value, whereas the .end()
on a range returns a const reference to the end iterator.
I will however add a static_assert
to these constructors, in order to give a sensible error message if the types of the iterators are different once any const
or reference modifiers are removed.
@@ -90,14 +92,12 @@ const optionst::value_listt &optionst::get_list_option( | |||
/// Returns the options as JSON key value pairs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Worth noting this is now lazy, so calling this then mutating optionst
then trying to iterate over the range may be undefined behaviour
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please note that the return type of the function is still a value of type json_objectt
, not a range. So there is no laziness beyond the scope of this function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@thomasspriggs might be worth adding an explicit constructor call to make that more obvious?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(notes above, meant to approve)
a8b278c
to
a859b17
Compare
@thomasspriggs The CI uses 2015, so may still fail with 2013. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫
This PR failed Diffblue compatibility checks (cbmc commit: a8b278c).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/98067771
Status will be re-evaluated on next push.
Please contact @peterschrammel, @thk123, or @allredj for support.
Common spurious failures:
- the cbmc commit has disappeared in the mean time (e.g. in a force-push)
- the author is not in the list of contributors (e.g. first-time contributors).
The incompatibility may have been introduced by an earlier PR. In that case merging this
PR should be avoided unless it fixes the current incompatibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✔️
Passed Diffblue compatibility checks (cbmc commit: a859b17).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/98072678
@kroening I have made a cursory attempt at compiling cbmc |
This doesn't compile with VS 2013. |
Can you compile |
a859b17
to
000dfa4
Compare
This new constructor facilitates the construction of instances of `json_objectt` which are const, because it gives a tidy way to construct an entire `json_objectt`.
000dfa4
to
b99f300
Compare
I have pushed two rebases to
|
This new constructor facilitates the construction of instances of `json_arrayt` which are const, because it gives a tidy way to construct an entire `json_arrayt`.
The end result of this commit is that code like the following example can be used to construct `json_arrayt` / `json_objectt` - ``` const std::vector<std::string> input{"foo", "bar"}; const auto json_array = make_range(input) .map(constructor_of<json_stringt>()) .collect<json_arrayt>(); ``` This commit includes - * Constructors from iterators for json_arrayt and json_objectt, so that the iterators from a range can be used to construct these classes. * A `collect` member function for `ranget`, so that a chain of range operations can finish with the construction of a resulting container containing a collection of the results. * A `constructor_of` template function, which provides syntactic sugar when using `map` to call a constructor, compared to writing a new lambda function each time such an operation is carried out. * Unit tests covering all of the above functionality.
This commit is included in this PR, as a demonstration of the coding style which is enabled by the proceeding commits.
Adding `.collect` to the end of a chain of range operations can add clutter to the code, rather than improving readability, in places where the type of container being constructed is apparent from the context. This commit adds a cast operation in order to improve readability in this scenario. In addition to the operator, this commit includes a refactor of `optionst::to_json` in order to demonstrate an example usage of the proposed change.
With the new constructors, these brackets are no longer required and can be removed, in order to improve readability.
Removing this constructor simplifies the interface, by reducing the number of different ways to construct the classes and avoiding exposing the implementation detail of what type of container `json_objectt` and `json_arrayt` are backed by.
b99f300
to
2a4d8ff
Compare
Rebased to fix include of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫
This PR failed Diffblue compatibility checks (cbmc commit: 2a4d8ff).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/98867160
Status will be re-evaluated on next push.
Please contact @peterschrammel, @thk123, or @allredj for support.
Common spurious failures:
- the cbmc commit has disappeared in the mean time (e.g. in a force-push)
- the author is not in the list of contributors (e.g. first-time contributors).
The incompatibility may have been introduced by an earlier PR. In that case merging this
PR should be avoided unless it fixes the current incompatibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see a problem with my part.
Much of the existing code which constructs instances of
json_arrayt
andjson_objectt
are based around creating an empty instance as then mutating it to add the contained information. This PR adds extra functionality to enable these two types to be constructed using a coding style which no longer requires mutation and is more readable.