Skip to content

Commit c40a2c8

Browse files
committed
Merge branch 'main' into fix-bugprone-unchecked-optional-access
2 parents 6915b6d + 8fe9063 commit c40a2c8

File tree

14 files changed

+63
-755
lines changed

14 files changed

+63
-755
lines changed

cmake/common/targets/clang-tidy.config

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ Checks: '-*,
77
clang-diagnostic-*,
88
modernize-*,
99
concurrency-*,
10-
cppcoreguidelines-*,
10+
cppcoreguidelines-*,-cppcoreguidelines-rvalue-reference-param-not-moved,
1111
performance-*,-performance-enum-size,
1212
portability-*,
1313
objc-*,
14-
misc-*,-misc-no-recursion,-misc-unused-parameters'
14+
misc-*,-misc-no-recursion,-misc-unused-parameters,-misc-const-correctness'
1515
WarningsAsErrors: '*'
1616
HeaderFilterRegex: ''
1717
FormatStyle: none

src/core/json/include/sourcemeta/core/json_auto.h

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33

44
#include <sourcemeta/core/json_value.h>
55

6-
#include <concepts> // std::same_as, std::constructible_from
7-
#include <functional> // std::function
8-
#include <optional> // std::optional
9-
#include <tuple> // std::tuple, std::apply
10-
#include <type_traits> // std::false_type, std::true_type, std::void_t, std::is_enum_v, std::underlying_type_t, std::is_same_v
6+
#include <concepts> // std::same_as, std::constructible_from
7+
#include <functional> // std::function
8+
#include <optional> // std::optional
9+
#include <tuple> // std::tuple, std::apply, std::tuple_element_t, std::tuple_size, std::tuple_size_v
10+
#include <type_traits> // std::false_type, std::true_type, std::void_t, std::is_enum_v, std::underlying_type_t, std::is_same_v, std::is_base_of_v, std::remove_cvref_t
1111
#include <utility> // std::pair
1212

1313
namespace sourcemeta::core {
@@ -203,17 +203,37 @@ auto to_json(
203203
template <typename L, typename R>
204204
auto to_json(const std::pair<L, R> &value) -> JSON {
205205
auto tuple{JSON::make_array()};
206-
tuple.push_back(to_json<L>(value.first));
207-
tuple.push_back(to_json<R>(value.second));
206+
tuple.push_back(to_json(value.first));
207+
tuple.push_back(to_json(value.second));
208208
return tuple;
209209
}
210210

211+
// Handle 1-element tuples
211212
/// @ingroup json
212-
template <typename... Args>
213-
auto to_json(const std::tuple<Args...> &value) -> JSON {
214-
auto tuple{JSON::make_array()};
213+
template <typename T>
214+
requires(std::tuple_size_v<std::remove_cvref_t<std::tuple<T>>> == 1)
215+
auto to_json(const std::tuple<T> &value) -> JSON {
216+
auto tuple = JSON::make_array();
217+
std::apply([&](const T &element) { tuple.push_back(to_json(element)); },
218+
value);
219+
return tuple;
220+
}
221+
222+
// We have to do this mess because MSVC seems confuses `std::pair`
223+
// of 2 elements with this overload
224+
/// @ingroup json
225+
template <typename TupleT>
226+
requires(requires {
227+
typename std::tuple_size<std::remove_cvref_t<TupleT>>::type;
228+
} && (std::tuple_size_v<std::remove_cvref_t<TupleT>> >= 2) &&
229+
(!std::is_base_of_v<
230+
std::pair<std::tuple_element_t<0, std::remove_cvref_t<TupleT>>,
231+
std::tuple_element_t<1, std::remove_cvref_t<TupleT>>>,
232+
std::remove_cvref_t<TupleT>>))
233+
auto to_json(const TupleT &value) -> JSON {
234+
auto tuple = JSON::make_array();
215235
std::apply(
216-
[&tuple](const Args &...elements) {
236+
[&tuple](const auto &...elements) {
217237
(tuple.push_back(to_json(elements)), ...);
218238
},
219239
value);

src/core/json/include/sourcemeta/core/json_value.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,9 +216,9 @@ class SOURCEMETA_CORE_JSON_EXPORT JSON {
216216

217217
/// Misc constructors
218218
JSON(const JSON &);
219-
JSON(JSON &&);
219+
JSON(JSON &&) noexcept;
220220
auto operator=(const JSON &) -> JSON &;
221-
auto operator=(JSON &&) -> JSON &;
221+
auto operator=(JSON &&) noexcept -> JSON &;
222222

223223
/// Destructor
224224
~JSON();

src/core/json/json_value.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ JSON::JSON(const JSON &other) : current_type{other.current_type} {
117117
}
118118
}
119119

120-
JSON::JSON(JSON &&other) : current_type{other.current_type} {
120+
JSON::JSON(JSON &&other) noexcept : current_type{other.current_type} {
121121
switch (other.current_type) {
122122
case Type::Boolean:
123123
this->data_boolean = other.data_boolean;
@@ -174,7 +174,7 @@ auto JSON::operator=(const JSON &other) -> JSON & {
174174
return *this;
175175
}
176176

177-
auto JSON::operator=(JSON &&other) -> JSON & {
177+
auto JSON::operator=(JSON &&other) noexcept -> JSON & {
178178
this->maybe_destruct_union();
179179
this->current_type = other.current_type;
180180
switch (other.current_type) {

src/core/jsonpointer/jsonpointer.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ auto set(JSON &document, const Pointer &pointer, const JSON &value) -> void {
203203

204204
JSON &current{traverse<std::allocator, JSON>(document, std::cbegin(pointer),
205205
std::prev(std::cend(pointer)))};
206-
const auto last{pointer.back()};
206+
const auto &last{pointer.back()};
207207
// Handle the hyphen as a last constant
208208
// If the currently referenced value is a JSON array, the reference
209209
// token [can be ] the single character "-", making the new referenced value
@@ -230,7 +230,7 @@ auto set(JSON &document, const Pointer &pointer, JSON &&value) -> void {
230230

231231
JSON &current{traverse<std::allocator, JSON>(document, std::cbegin(pointer),
232232
std::prev(std::cend(pointer)))};
233-
const auto last{pointer.back()};
233+
const auto &last{pointer.back()};
234234
// Handle the hyphen as a last constant
235235
// If the currently referenced value is a JSON array, the reference
236236
// token [can be ] the single character "-", making the new referenced value

src/core/jsonschema/frame.cc

Lines changed: 9 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,8 @@ auto store(
224224
instances[pointer_from_root] = instance_locations;
225225
}
226226

227+
// Check misunderstood struct to be a function
228+
// NOLINTNEXTLINE(bugprone-exception-escape)
227229
struct InternalEntry {
228230
const sourcemeta::core::SchemaIteratorEntry common;
229231
const std::optional<sourcemeta::core::JSON::String> id;
@@ -259,6 +261,8 @@ auto traverse_origin_instance_locations(
259261
}
260262
}
261263

264+
// Check misunderstood struct to be a function
265+
// NOLINTNEXTLINE(bugprone-exception-escape)
262266
struct CacheSubschema {
263267
const sourcemeta::core::PointerTemplate instance_location{};
264268
const sourcemeta::core::PointerTemplate relative_instance_location{};
@@ -415,121 +419,6 @@ auto SchemaFrame::to_json() const -> JSON {
415419
return root;
416420
}
417421

418-
auto operator<<(std::ostream &stream, const SchemaFrame &frame)
419-
-> std::ostream & {
420-
if (frame.locations().empty()) {
421-
return stream;
422-
}
423-
424-
for (auto iterator = frame.locations().cbegin();
425-
iterator != frame.locations().cend(); iterator++) {
426-
const auto &location{*iterator};
427-
428-
switch (location.second.type) {
429-
case SchemaFrame::LocationType::Resource:
430-
stream << "(RESOURCE)";
431-
break;
432-
case SchemaFrame::LocationType::Anchor:
433-
stream << "(ANCHOR)";
434-
break;
435-
case SchemaFrame::LocationType::Pointer:
436-
stream << "(POINTER)";
437-
break;
438-
case SchemaFrame::LocationType::Subschema:
439-
stream << "(SUBSCHEMA)";
440-
break;
441-
default:
442-
assert(false);
443-
}
444-
445-
stream << " URI: " << location.first.second << "\n";
446-
447-
if (location.first.first == SchemaReferenceType::Static) {
448-
stream << " Type : Static\n";
449-
} else {
450-
stream << " Type : Dynamic\n";
451-
}
452-
453-
stream << " Root : "
454-
<< location.second.root.value_or("<ANONYMOUS>") << "\n";
455-
456-
if (location.second.pointer.empty()) {
457-
stream << " Pointer :\n";
458-
} else {
459-
stream << " Pointer : ";
460-
sourcemeta::core::stringify(location.second.pointer, stream);
461-
stream << "\n";
462-
}
463-
464-
stream << " Base : " << location.second.base << "\n";
465-
466-
if (location.second.relative_pointer.empty()) {
467-
stream << " Relative Pointer :\n";
468-
} else {
469-
stream << " Relative Pointer : ";
470-
sourcemeta::core::stringify(location.second.relative_pointer, stream);
471-
stream << "\n";
472-
}
473-
474-
stream << " Dialect : " << location.second.dialect << "\n";
475-
stream << " Base Dialect : " << location.second.base_dialect
476-
<< "\n";
477-
478-
if (location.second.parent.has_value()) {
479-
if (location.second.parent.value().empty()) {
480-
stream << " Parent :\n";
481-
} else {
482-
stream << " Parent : ";
483-
sourcemeta::core::stringify(location.second.parent.value(), stream);
484-
stream << "\n";
485-
}
486-
} else {
487-
stream << " Parent : <NONE>\n";
488-
}
489-
490-
const auto &instance_locations{frame.instance_locations(location.second)};
491-
if (!instance_locations.empty()) {
492-
for (const auto &instance_location : instance_locations) {
493-
if (instance_location.empty()) {
494-
stream << " Instance Location :\n";
495-
} else {
496-
stream << " Instance Location : ";
497-
sourcemeta::core::stringify(instance_location, stream);
498-
stream << "\n";
499-
}
500-
}
501-
}
502-
503-
if (std::next(iterator) != frame.locations().cend()) {
504-
stream << "\n";
505-
}
506-
}
507-
508-
for (auto iterator = frame.references().cbegin();
509-
iterator != frame.references().cend(); iterator++) {
510-
stream << "\n";
511-
const auto &reference{*iterator};
512-
stream << "(REFERENCE) ORIGIN: ";
513-
sourcemeta::core::stringify(reference.first.second, stream);
514-
stream << "\n";
515-
516-
if (reference.first.first == SchemaReferenceType::Static) {
517-
stream << " Type : Static\n";
518-
} else {
519-
stream << " Type : Dynamic\n";
520-
}
521-
522-
stream << " Destination : " << reference.second.destination
523-
<< "\n";
524-
stream << " - (w/o fragment) : "
525-
<< reference.second.base.value_or("<NONE>") << "\n";
526-
stream << " - (fragment) : "
527-
<< reference.second.fragment.value_or("<NONE>") << "\n";
528-
}
529-
530-
return stream;
531-
}
532-
533422
auto SchemaFrame::analyse(const JSON &root, const SchemaWalker &walker,
534423
const SchemaResolver &resolver,
535424
const std::optional<JSON::String> &default_dialect,
@@ -671,16 +560,9 @@ auto SchemaFrame::analyse(const JSON &root, const SchemaWalker &walker,
671560
if (!maybe_relative_is_absolute ||
672561
maybe_match == this->locations_.cend()) {
673562
assert(entry.common.base_dialect.has_value());
674-
if (entry.common.orphan) {
675-
store(this->locations_, this->instances_,
676-
SchemaReferenceType::Static,
677-
SchemaFrame::LocationType::Resource, new_id, root_id,
678-
new_id, entry.common.pointer,
679-
sourcemeta::core::empty_pointer,
680-
entry.common.dialect.value(),
681-
entry.common.base_dialect.value(), {},
682-
entry.common.parent);
683-
} else if (this->mode_ == SchemaFrame::Mode::Instances) {
563+
564+
if (!(entry.common.orphan) &&
565+
this->mode_ == SchemaFrame::Mode::Instances) {
684566
store(this->locations_, this->instances_,
685567
SchemaReferenceType::Static,
686568
SchemaFrame::LocationType::Resource, new_id, root_id,
@@ -882,15 +764,8 @@ auto SchemaFrame::analyse(const JSON &root, const SchemaWalker &walker,
882764
const auto subschema{subschemas.find(pointer)};
883765
if (subschema != subschemas.cend()) {
884766
// Handle orphan schemas
885-
if (subschema->second.orphan) {
886-
store(this->locations_, this->instances_,
887-
SchemaReferenceType::Static,
888-
SchemaFrame::LocationType::Subschema, result, root_id,
889-
current_base, pointer,
890-
pointer.resolve_from(nearest_bases.second),
891-
dialects.first.front(), current_base_dialect, {},
892-
subschema->second.parent);
893-
} else if (this->mode_ == SchemaFrame::Mode::Instances) {
767+
if (!(subschema->second.orphan) &&
768+
this->mode_ == SchemaFrame::Mode::Instances) {
894769
store(this->locations_, this->instances_,
895770
SchemaReferenceType::Static,
896771
SchemaFrame::LocationType::Subschema, result, root_id,

src/core/jsonschema/include/sourcemeta/core/jsonschema_frame.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -252,12 +252,6 @@ class SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaFrame {
252252
#endif
253253
};
254254

255-
/// @ingroup jsonschema
256-
/// Pretty print the contents of a schema frame
257-
SOURCEMETA_CORE_JSONSCHEMA_EXPORT
258-
auto operator<<(std::ostream &stream, const SchemaFrame &frame)
259-
-> std::ostream &;
260-
261255
} // namespace sourcemeta::core
262256

263257
#endif

src/core/jsonschema/jsonschema.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ auto sourcemeta::core::identify(
100100
return default_id;
101101
}
102102

103-
const auto result{identify(schema, maybe_base_dialect.value(), default_id)};
103+
auto result{identify(schema, maybe_base_dialect.value(), default_id)};
104104

105105
// A last shot supporting identifiers alongside `$ref` in loose mode
106106
if (!result.has_value() && strategy == SchemaIdentificationStrategy::Loose) {

src/core/jsonschema/walker.cc

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -379,15 +379,10 @@ auto walk(const std::optional<sourcemeta::core::Pointer> &parent,
379379

380380
break;
381381
case sourcemeta::core::SchemaKeywordType::Assertion:
382-
break;
383382
case sourcemeta::core::SchemaKeywordType::Annotation:
384-
break;
385383
case sourcemeta::core::SchemaKeywordType::Reference:
386-
break;
387384
case sourcemeta::core::SchemaKeywordType::Other:
388-
break;
389385
case sourcemeta::core::SchemaKeywordType::Comment:
390-
break;
391386
case sourcemeta::core::SchemaKeywordType::Unknown:
392387
break;
393388
}

0 commit comments

Comments
 (0)