diff --git a/src/core/jsonschema/frame.cc b/src/core/jsonschema/frame.cc index 742c3eb1d..0557ad679 100644 --- a/src/core/jsonschema/frame.cc +++ b/src/core/jsonschema/frame.cc @@ -422,6 +422,11 @@ auto internal_analyse(const sourcemeta::core::JSON &schema, const auto bases{ find_nearest_bases(base_uris, entry.common.pointer, entry.id)}; + std::vector instance_locations; + if (!entry.common.orphan) { + instance_locations.push_back(entry.common.instance_location); + } + if (bases.first.empty()) { const auto anchor_uri{sourcemeta::core::URI::from_fragment(name)}; const auto relative_anchor_uri{anchor_uri.recompose()}; @@ -432,7 +437,7 @@ auto internal_analyse(const sourcemeta::core::JSON &schema, "", entry.common.pointer, entry.common.pointer.resolve_from(bases.second), entry.common.dialect.value(), entry.common.base_dialect.value(), - {entry.common.instance_location}); + instance_locations); } if (type == AnchorType::Dynamic || type == AnchorType::All) { @@ -441,7 +446,7 @@ auto internal_analyse(const sourcemeta::core::JSON &schema, "", entry.common.pointer, entry.common.pointer.resolve_from(bases.second), entry.common.dialect.value(), entry.common.base_dialect.value(), - {entry.common.instance_location}); + instance_locations); // Register a dynamic anchor as a static anchor if possible too if (entry.common.vocabularies.contains( @@ -451,8 +456,7 @@ auto internal_analyse(const sourcemeta::core::JSON &schema, root_id, "", entry.common.pointer, entry.common.pointer.resolve_from(bases.second), entry.common.dialect.value(), - entry.common.base_dialect.value(), - {entry.common.instance_location}, true); + entry.common.base_dialect.value(), instance_locations, true); } } } else { @@ -481,8 +485,7 @@ auto internal_analyse(const sourcemeta::core::JSON &schema, base_string, entry.common.pointer, entry.common.pointer.resolve_from(bases.second), entry.common.dialect.value(), - entry.common.base_dialect.value(), - {entry.common.instance_location}); + entry.common.base_dialect.value(), instance_locations); } if (type == AnchorType::Dynamic || type == AnchorType::All) { @@ -491,8 +494,7 @@ auto internal_analyse(const sourcemeta::core::JSON &schema, base_string, entry.common.pointer, entry.common.pointer.resolve_from(bases.second), entry.common.dialect.value(), - entry.common.base_dialect.value(), - {entry.common.instance_location}); + entry.common.base_dialect.value(), instance_locations); // Register a dynamic anchor as a static anchor if possible too if (entry.common.vocabularies.contains( @@ -502,8 +504,8 @@ auto internal_analyse(const sourcemeta::core::JSON &schema, base_string, entry.common.pointer, entry.common.pointer.resolve_from(bases.second), entry.common.dialect.value(), - entry.common.base_dialect.value(), - {entry.common.instance_location}, true); + entry.common.base_dialect.value(), instance_locations, + true); } } diff --git a/test/jsonschema/jsonschema_frame_2019_09_test.cc b/test/jsonschema/jsonschema_frame_2019_09_test.cc index ac7de1fe6..a3a27ecff 100644 --- a/test/jsonschema/jsonschema_frame_2019_09_test.cc +++ b/test/jsonschema/jsonschema_frame_2019_09_test.cc @@ -1981,7 +1981,7 @@ TEST(JSONSchema_frame_2019_09, relative_base_uri_with_ref) { // Anchors EXPECT_FRAME_STATIC_2019_09_ANCHOR(frame, "common#foo", "common", - "/$defs/foo", "common", "/$defs/foo", {""}, + "/$defs/foo", "common", "/$defs/foo", {}, 0); // JSON Pointers diff --git a/test/jsonschema/jsonschema_frame_2020_12_test.cc b/test/jsonschema/jsonschema_frame_2020_12_test.cc index 7b313e521..94fc79d2c 100644 --- a/test/jsonschema/jsonschema_frame_2020_12_test.cc +++ b/test/jsonschema/jsonschema_frame_2020_12_test.cc @@ -1226,11 +1226,11 @@ TEST(JSONSchema_frame_2020_12, EXPECT_ANONYMOUS_FRAME_DYNAMIC_ANCHOR( frame, "#test", "/$defs/test", "https://json-schema.org/draft/2020-12/schema", - "https://json-schema.org/draft/2020-12/schema", {""}, 0); + "https://json-schema.org/draft/2020-12/schema", {}, 0); EXPECT_ANONYMOUS_FRAME_STATIC_ANCHOR( frame, "#test", "/$defs/test", "https://json-schema.org/draft/2020-12/schema", - "https://json-schema.org/draft/2020-12/schema", {""}, 0); + "https://json-schema.org/draft/2020-12/schema", {}, 0); // Static frames @@ -1293,11 +1293,11 @@ TEST(JSONSchema_frame_2020_12, dynamic_ref_to_single_dynamic_anchor_external) { EXPECT_ANONYMOUS_FRAME_DYNAMIC_ANCHOR( frame, "#test", "/$defs/test", "https://json-schema.org/draft/2020-12/schema", - "https://json-schema.org/draft/2020-12/schema", {""}, 0); + "https://json-schema.org/draft/2020-12/schema", {}, 0); EXPECT_ANONYMOUS_FRAME_STATIC_ANCHOR( frame, "#test", "/$defs/test", "https://json-schema.org/draft/2020-12/schema", - "https://json-schema.org/draft/2020-12/schema", {""}, 0); + "https://json-schema.org/draft/2020-12/schema", {}, 0); // Static frames @@ -1651,7 +1651,7 @@ TEST(JSONSchema_frame_2020_12, relative_base_uri_with_ref) { // Anchors EXPECT_FRAME_STATIC_2020_12_ANCHOR(frame, "common#foo", "common", - "/$defs/foo", "common", "/$defs/foo", {""}, + "/$defs/foo", "common", "/$defs/foo", {}, 0); // JSON Pointers diff --git a/test/jsonschema/jsonschema_frame_draft4_test.cc b/test/jsonschema/jsonschema_frame_draft4_test.cc index 6d6c447bb..bcf9d971b 100644 --- a/test/jsonschema/jsonschema_frame_draft4_test.cc +++ b/test/jsonschema/jsonschema_frame_draft4_test.cc @@ -582,7 +582,7 @@ TEST(JSONSchema_frame_draft4, location_independent_identifier_anonymous) { EXPECT_ANONYMOUS_FRAME_STATIC_ANCHOR( frame, "#foo", "/definitions/foo", "http://json-schema.org/draft-04/schema#", - "http://json-schema.org/draft-04/schema#", {""}, 0); + "http://json-schema.org/draft-04/schema#", {}, 0); // References @@ -704,7 +704,7 @@ TEST(JSONSchema_frame_draft4, relative_base_uri_with_ref) { // Anchors EXPECT_FRAME_STATIC_DRAFT4_ANCHOR(frame, "common#foo", "common", "/definitions/foo", "common", - "/definitions/foo", {""}, 0); + "/definitions/foo", {}, 0); // JSON Pointers diff --git a/test/jsonschema/jsonschema_frame_draft6_test.cc b/test/jsonschema/jsonschema_frame_draft6_test.cc index 52a7114db..8cb78a947 100644 --- a/test/jsonschema/jsonschema_frame_draft6_test.cc +++ b/test/jsonschema/jsonschema_frame_draft6_test.cc @@ -582,7 +582,7 @@ TEST(JSONSchema_frame_draft6, location_independent_identifier_anonymous) { EXPECT_ANONYMOUS_FRAME_STATIC_ANCHOR( frame, "#foo", "/definitions/foo", "http://json-schema.org/draft-06/schema#", - "http://json-schema.org/draft-06/schema#", {""}, 0); + "http://json-schema.org/draft-06/schema#", {}, 0); // References @@ -704,7 +704,7 @@ TEST(JSONSchema_frame_draft6, relative_base_uri_with_ref) { // Anchors EXPECT_FRAME_STATIC_DRAFT6_ANCHOR(frame, "common#foo", "common", "/definitions/foo", "common", - "/definitions/foo", {""}, 0); + "/definitions/foo", {}, 0); // JSON Pointers diff --git a/test/jsonschema/jsonschema_frame_draft7_test.cc b/test/jsonschema/jsonschema_frame_draft7_test.cc index 9decbafad..aedd4302b 100644 --- a/test/jsonschema/jsonschema_frame_draft7_test.cc +++ b/test/jsonschema/jsonschema_frame_draft7_test.cc @@ -582,7 +582,7 @@ TEST(JSONSchema_frame_draft7, location_independent_identifier_anonymous) { EXPECT_ANONYMOUS_FRAME_STATIC_ANCHOR( frame, "#foo", "/definitions/foo", "http://json-schema.org/draft-07/schema#", - "http://json-schema.org/draft-07/schema#", {""}, 0); + "http://json-schema.org/draft-07/schema#", {}, 0); // References @@ -704,7 +704,7 @@ TEST(JSONSchema_frame_draft7, relative_base_uri_with_ref) { // Anchors EXPECT_FRAME_STATIC_DRAFT7_ANCHOR(frame, "common#foo", "common", "/definitions/foo", "common", - "/definitions/foo", {""}, 0); + "/definitions/foo", {}, 0); // JSON Pointers diff --git a/test/jsonschema/jsonschema_official_walker_2020_12_test.cc b/test/jsonschema/jsonschema_official_walker_2020_12_test.cc index 86f076e78..a102e77dd 100644 --- a/test/jsonschema/jsonschema_official_walker_2020_12_test.cc +++ b/test/jsonschema/jsonschema_official_walker_2020_12_test.cc @@ -1698,3 +1698,29 @@ TEST(JSONSchema_official_walker_2020_12, instance_locations_nested) { EXPECT_OFFICIAL_WALKER_ENTRY_2020_12( entries, 3, "/additionalProperties/properties/foo/allOf/0", "/~P~/foo"); } + +TEST(JSONSchema_official_walker_2020_12, instance_locations_defs_with_ref) { + const sourcemeta::core::JSON document = sourcemeta::core::parse_json(R"JSON({ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "common", + "allOf": [ { "$ref": "#foo" } ], + "$defs": { + "foo": { + "$anchor": "foo" + } + } + })JSON"); + + std::vector entries; + for (const auto &entry : sourcemeta::core::SchemaIterator( + document, sourcemeta::core::schema_official_walker, + sourcemeta::core::schema_official_resolver)) { + entries.push_back(entry); + } + + EXPECT_EQ(entries.size(), 3); + + EXPECT_OFFICIAL_WALKER_ENTRY_2020_12(entries, 0, "", ""); + EXPECT_OFFICIAL_WALKER_ENTRY_2020_12(entries, 1, "/allOf/0", ""); + EXPECT_OFFICIAL_WALKER_ENTRY_2020_12_ORPHAN(entries, 2, "/$defs/foo", ""); +}