diff --git a/src/Hl7.Fhir.Conformance/Specification/Snapshot/SnapshotGeneratorExtensions.cs b/src/Hl7.Fhir.Base/Specification/Snapshot/SnapshotGeneratorExtensions.cs
similarity index 68%
rename from src/Hl7.Fhir.Conformance/Specification/Snapshot/SnapshotGeneratorExtensions.cs
rename to src/Hl7.Fhir.Base/Specification/Snapshot/SnapshotGeneratorExtensions.cs
index b1b8688e5c..3cd2cb0abb 100644
--- a/src/Hl7.Fhir.Conformance/Specification/Snapshot/SnapshotGeneratorExtensions.cs
+++ b/src/Hl7.Fhir.Base/Specification/Snapshot/SnapshotGeneratorExtensions.cs
@@ -7,7 +7,7 @@
*/
using Hl7.Fhir.Model;
-using Hl7.Fhir.Support;
+using Hl7.Fhir.Rest;
using Hl7.Fhir.Utility;
using System;
using System.Collections.Generic;
@@ -19,7 +19,7 @@ namespace Hl7.Fhir.Specification.Snapshot
// This extension indicates snapshot elements with associated differential constraints in the profile.
// Note: extensions are persisted to XML/JSON, whereas annotations are ephemeral (in-memory only)
- /// Helper methods for the class to generate and inspect custom extensions.
+ /// Helper methods for the SnapshotGenerator class to generate and inspect custom extensions.
public static class SnapshotGeneratorExtensions
{
/// The canonical url of the extension definition that marks snapshot elements with associated differential constraints.
@@ -54,6 +54,7 @@ public static void RemoveConstrainedByDiffExtension(this IExtendable element)
}
/// Recursively removes all instances of the extension from the specified element definition and all it's child objects.
+ [Obsolete("Use RemoveAllNonInheritableExtensions(this Element element) instead.")]
public static void RemoveAllConstrainedByDiffExtensions(this Element element)
{
if (element == null) { throw Error.ArgumentNull(nameof(element)); }
@@ -65,6 +66,7 @@ public static void RemoveAllConstrainedByDiffExtensions(this Element element)
}
/// Recursively removes all instances of the extension from all the elements and their respective child objects.
+ [Obsolete("Use RemoveAllNonInheritableExtensions(this IEnumerable elements) instead.")]
public static void RemoveAllConstrainedByDiffExtensions(this IEnumerable elements) where T : Element
{
if (elements == null) { throw Error.ArgumentNull(nameof(elements)); }
@@ -74,6 +76,47 @@ public static void RemoveAllConstrainedByDiffExtensions(this IEnumerable e
}
}
+
+ internal static void RemoveAllNonInheritableExtensions(this Element element)
+ {
+ if (element == null) { throw Error.ArgumentNull(nameof(element)); }
+ element.RemoveNonInheritableExtensions();
+ foreach (var child in element.Children.OfType())
+ {
+ child.RemoveAllNonInheritableExtensions();
+ }
+ }
+
+ internal static void RemoveNonInheritableExtensions(this IExtendable element)
+ {
+ if (element == null) { throw Error.ArgumentNull(nameof(element)); }
+ foreach (var ext in _nonInheritableExtensions)
+ {
+ element.RemoveExtension(ext);
+ }
+ }
+
+ private static readonly List _nonInheritableExtensions = [
+ ResourceIdentity.CORE_BASE_URL + "elementdefinition-isCommonBinding",
+ ResourceIdentity.CORE_BASE_URL + "structuredefinition-fmm",
+ ResourceIdentity.CORE_BASE_URL + "structuredefinition-fmm-no-warnings",
+ ResourceIdentity.CORE_BASE_URL + "structuredefinition-hierarchy",
+ ResourceIdentity.CORE_BASE_URL + "structuredefinition-interface",
+ ResourceIdentity.CORE_BASE_URL + "structuredefinition-normative-version",
+ ResourceIdentity.CORE_BASE_URL + "structuredefinition-applicable-version",
+ ResourceIdentity.CORE_BASE_URL + "structuredefinition-category",
+ ResourceIdentity.CORE_BASE_URL + "structuredefinition-codegen-super",
+ ResourceIdentity.CORE_BASE_URL + "structuredefinition-security-category",
+ ResourceIdentity.CORE_BASE_URL + "structuredefinition-standards-status",
+ ResourceIdentity.CORE_BASE_URL + "structuredefinition-summary",
+ ResourceIdentity.CORE_BASE_URL + "structuredefinition-wg",
+ ResourceIdentity.CORE_BASE_URL + "replaces",
+ ResourceIdentity.CORE_BASE_URL + "resource-approvalDate",
+ ResourceIdentity.CORE_BASE_URL + "resource-effectivePeriod",
+ ResourceIdentity.CORE_BASE_URL + "resource-lastReviewDate",
+ CONSTRAINED_BY_DIFF_EXT //this is our own extension to define differences compared to the base, this can't be inherited from the base profile
+ ];
+
// ========== For internal use only ==========
// [WMR 20170209] OBSOLETE
#if false
diff --git a/src/Hl7.Fhir.Conformance/CompatibilitySuppressions.xml b/src/Hl7.Fhir.Conformance/CompatibilitySuppressions.xml
new file mode 100644
index 0000000000..50df2e8381
--- /dev/null
+++ b/src/Hl7.Fhir.Conformance/CompatibilitySuppressions.xml
@@ -0,0 +1,18 @@
+
+
+
+
+ CP0001
+ T:Hl7.Fhir.Specification.Snapshot.SnapshotGeneratorExtensions
+ lib/net8.0/Hl7.Fhir.Conformance.dll
+ lib/net8.0/Hl7.Fhir.Conformance.dll
+ true
+
+
+ CP0001
+ T:Hl7.Fhir.Specification.Snapshot.SnapshotGeneratorExtensions
+ lib/netstandard2.0/Hl7.Fhir.Conformance.dll
+ lib/netstandard2.0/Hl7.Fhir.Conformance.dll
+ true
+
+
\ No newline at end of file
diff --git a/src/Hl7.Fhir.Conformance/Specification/Snapshot/SnapshotGenerator.cs b/src/Hl7.Fhir.Conformance/Specification/Snapshot/SnapshotGenerator.cs
index e34c273918..87d34e30b7 100644
--- a/src/Hl7.Fhir.Conformance/Specification/Snapshot/SnapshotGenerator.cs
+++ b/src/Hl7.Fhir.Conformance/Specification/Snapshot/SnapshotGenerator.cs
@@ -465,7 +465,7 @@ private async Tasks.Task> generate(StructureDefinition s
// [WMR 20170208] Moved to *AFTER* ensureBaseComponents - emits annotations...
// [WMR 20160915] Derived profiles should never inherit the ChangedByDiff extension from the base structure
- snapshot.Element.RemoveAllConstrainedByDiffExtensions();
+ snapshot.RemoveAllNonInheritableExtensions();
snapshot.Element.RemoveAllConstrainedByDiffAnnotations();
// Notify observers
@@ -1487,7 +1487,7 @@ private static bool copyChildren(ElementDefinitionNavigator nav, ElementDefiniti
var elem = elems[pos];
// [WMR 20160826] Never inherit Changed extension from base profile!
- elem.RemoveAllConstrainedByDiffExtensions();
+ elem.RemoveAllNonInheritableExtensions();
elem.RemoveAllConstrainedByDiffAnnotations();
// [WMR 20160902] Initialize empty ElementDefinition.Base components if necessary
diff --git a/src/Hl7.Fhir.STU3/CompatibilitySuppressions.xml b/src/Hl7.Fhir.STU3/CompatibilitySuppressions.xml
new file mode 100644
index 0000000000..4c6b9c5302
--- /dev/null
+++ b/src/Hl7.Fhir.STU3/CompatibilitySuppressions.xml
@@ -0,0 +1,18 @@
+
+
+
+
+ CP0001
+ T:Hl7.Fhir.Specification.Snapshot.SnapshotGeneratorExtensions
+ lib/net8.0/Hl7.Fhir.STU3.dll
+ lib/net8.0/Hl7.Fhir.STU3.dll
+ true
+
+
+ CP0001
+ T:Hl7.Fhir.Specification.Snapshot.SnapshotGeneratorExtensions
+ lib/netstandard2.0/Hl7.Fhir.STU3.dll
+ lib/netstandard2.0/Hl7.Fhir.STU3.dll
+ true
+
+
\ No newline at end of file
diff --git a/src/Hl7.Fhir.STU3/Specification/Snapshot/SnapshotGenerator.cs b/src/Hl7.Fhir.STU3/Specification/Snapshot/SnapshotGenerator.cs
index 80dab2d014..8b2616a871 100644
--- a/src/Hl7.Fhir.STU3/Specification/Snapshot/SnapshotGenerator.cs
+++ b/src/Hl7.Fhir.STU3/Specification/Snapshot/SnapshotGenerator.cs
@@ -399,7 +399,8 @@ private async Tasks.Task> generate(StructureDefinition s
// [WMR 20170208] Moved to *AFTER* ensureBaseComponents - emits annotations...
// [WMR 20160915] Derived profiles should never inherit the ChangedByDiff extension from the base structure
- snapshot.Element.RemoveAllConstrainedByDiffExtensions();
+ // Also remove core extensions that are not supposed to be inherited by derived profiles
+ snapshot.RemoveAllNonInheritableExtensions();
snapshot.Element.RemoveAllConstrainedByDiffAnnotations();
// Notify observers
@@ -1309,7 +1310,7 @@ private static bool copyChildren(ElementDefinitionNavigator nav, ElementDefiniti
var elem = elems[pos];
// [WMR 20160826] Never inherit Changed extension from base profile!
- elem.RemoveAllConstrainedByDiffExtensions();
+ elem.RemoveAllNonInheritableExtensions();
elem.RemoveAllConstrainedByDiffAnnotations();
// [WMR 20160902] Initialize empty ElementDefinition.Base components if necessary
diff --git a/src/Hl7.Fhir.STU3/Specification/Snapshot/SnapshotGeneratorExtensions.cs b/src/Hl7.Fhir.STU3/Specification/Snapshot/SnapshotGeneratorExtensions.cs
deleted file mode 100644
index 2c13de5f28..0000000000
--- a/src/Hl7.Fhir.STU3/Specification/Snapshot/SnapshotGeneratorExtensions.cs
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (c) 2017, Firely (info@fire.ly) and contributors
- * See the file CONTRIBUTORS for details.
- *
- * This file is licensed under the BSD 3-Clause license
- * available at https://raw.githubusercontent.com/FirelyTeam/firely-net-sdk/master/LICENSE
- */
-
-using Hl7.Fhir.Model;
-using Hl7.Fhir.Support;
-using Hl7.Fhir.Utility;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Hl7.Fhir.Specification.Snapshot
-{
- // [WMR 20170209] cf. ConstrainedByDifferentialAnnotation
- // This extension indicates snapshot elements with associated differential constraints in the profile.
- // Note: extensions are persisted to XML/JSON, whereas annotations are ephemeral (in-memory only)
-
- /// Helper methods for the class to generate and inspect custom extensions.
- public static class SnapshotGeneratorExtensions
- {
- /// The canonical url of the extension definition that marks snapshot elements with associated differential constraints.
- // public static readonly string CHANGED_BY_DIFF_EXT = "http://hl7.org/fhir/StructureDefinition/changedByDifferential";
- public static readonly string CONSTRAINED_BY_DIFF_EXT = "http://hl7.org/fhir/StructureDefinition/constrainedByDifferentialExtension";
-
- ///
- /// Decorate the specified snapshot element definition with a special extension
- /// to indicate that the element is constrained by the differential.
- ///
- /// An instance.
- /// An optional boolean value (default true).
- /// Sets the extension to store the boolean flag.
- internal static void SetConstrainedByDiffExtension(this IExtendable element, bool value = true)
- {
- if (element == null) { throw Error.ArgumentNull(nameof(element)); }
- element.SetBoolExtension(CONSTRAINED_BY_DIFF_EXT, value);
- }
-
- /// Determines if the snapshot element was decorated with an extension indicating the element is constrained by the differential.
- /// An instance.
- /// A boolean value, or null.
- /// Gets the boolean flag from the extension, if it exists.
- public static bool? GetConstrainedByDiffExtension(this IExtendable element) => element.GetBoolExtension(CONSTRAINED_BY_DIFF_EXT);
-
- /// Removes the extension from the specified element definition.
- public static void RemoveConstrainedByDiffExtension(this IExtendable element)
- {
- if (element == null) { throw Error.ArgumentNull(nameof(element)); }
- element.RemoveExtension(CONSTRAINED_BY_DIFF_EXT);
- }
-
- /// Recursively removes all instances of the extension from the specified element definition and all it's child objects.
- public static void RemoveAllConstrainedByDiffExtensions(this Element element)
- {
- if (element == null) { throw Error.ArgumentNull(nameof(element)); }
- element.RemoveConstrainedByDiffExtension();
- foreach (var child in element.Children.OfType())
- {
- child.RemoveAllConstrainedByDiffExtensions();
- }
- }
-
- /// Recursively removes all instances of the extension from all the elements and their respective child objects.
- public static void RemoveAllConstrainedByDiffExtensions(this IEnumerable elements) where T : Element
- {
- if (elements == null) { throw Error.ArgumentNull(nameof(elements)); }
- foreach (var elem in elements)
- {
- elem.RemoveAllConstrainedByDiffExtensions();
- }
- }
-
- // ========== For internal use only ==========
- // [WMR 20170209] OBSOLETE
-#if false
-
- /// Removes a specific extension from the snapshot element definition and it's descendant elements, recursively.
- /// An instance.
- /// The canonical url of the extension.
- static void ClearAllExtensions(this ElementDefinition elemDef, string uri)
- {
- if (elemDef != null)
- {
- ClearExtensions(elemDef, uri);
- }
- }
-
- static void ClearExtensions(this IEnumerable elements, string uri) where T : Base
- {
- if (elements != null)
- {
- foreach (var child in elements)
- {
- ClearExtensions(child, uri);
- }
- }
- }
-
- static void ClearExtensions(this T element, string uri) where T : Base
- {
- if (element != null)
- {
- ClearExtension(element as IExtendable, uri);
- ClearExtensions(element.Children, uri);
- }
- }
-
- static void ClearExtension(this IExtendable extendable, string uri)
- {
- extendable?.RemoveExtension(uri);
- }
-#endif
-
- }
-}
diff --git a/src/Hl7.Fhir.Specification.STU3.Tests/Snapshot/SnapshotGeneratorTest.cs b/src/Hl7.Fhir.Specification.STU3.Tests/Snapshot/SnapshotGeneratorTest.cs
index 987dce7f65..13814b8cfd 100644
--- a/src/Hl7.Fhir.Specification.STU3.Tests/Snapshot/SnapshotGeneratorTest.cs
+++ b/src/Hl7.Fhir.Specification.STU3.Tests/Snapshot/SnapshotGeneratorTest.cs
@@ -21,8 +21,8 @@
using Hl7.Fhir.Support;
using Hl7.Fhir.Utility;
using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
using NSubstitute;
+using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
@@ -2433,8 +2433,8 @@ private static bool isAlmostExactly(ElementDefinition elem, ElementDefinition ba
}
// Also ignore any Changed extensions on base and diff
- elemClone.RemoveAllConstrainedByDiffExtensions();
- baseClone.RemoveAllConstrainedByDiffExtensions();
+ elemClone.RemoveAllNonInheritableExtensions();
+ baseClone.RemoveAllNonInheritableExtensions();
elemClone.RemoveAllConstrainedByDiffAnnotations();
baseClone.RemoveAllConstrainedByDiffAnnotations();
diff --git a/src/Hl7.Fhir.Specification.Shared.Tests/Snapshot/SnapshotGeneratorTest.cs b/src/Hl7.Fhir.Specification.Shared.Tests/Snapshot/SnapshotGeneratorTest.cs
index 01215cc363..dab716a337 100644
--- a/src/Hl7.Fhir.Specification.Shared.Tests/Snapshot/SnapshotGeneratorTest.cs
+++ b/src/Hl7.Fhir.Specification.Shared.Tests/Snapshot/SnapshotGeneratorTest.cs
@@ -2562,8 +2562,8 @@ private static bool isAlmostExactly(ElementDefinition elem, ElementDefinition ba
}
// Also ignore any Changed extensions on base and diff
- elemClone.RemoveAllConstrainedByDiffExtensions();
- baseClone.RemoveAllConstrainedByDiffExtensions();
+ elemClone.RemoveAllNonInheritableExtensions();
+ baseClone.RemoveAllNonInheritableExtensions();
elemClone.RemoveAllConstrainedByDiffAnnotations();
baseClone.RemoveAllConstrainedByDiffAnnotations();
@@ -10155,6 +10155,37 @@ private StructureDefinition createVeryNestedExtension()
}
+ [TestMethod]
+ public void RemoveNonInhertitableSnapshotsTest()
+ {
+ var profile = new StructureDefinition
+ {
+ Url = "http://fire.ly/StructureDefinition/example",
+ Snapshot = new()
+ {
+ Element = new() {
+ new("Example")
+ {
+ Binding = new()
+ {
+ Strength = BindingStrength.Required,
+ ValueSet = "http://fire.ly/ValueSet/example"
+ }
+ },
+ }
+ }
+ };
+
+ profile.Snapshot.Element[0].AddExtension(ResourceIdentity.CORE_BASE_URL + "structuredefinition-hierarchy", new FhirString("foo"));
+ profile.Snapshot.Element[0].Binding.AddExtension(ResourceIdentity.CORE_BASE_URL + "elementdefinition-isCommonBinding", new FhirBoolean(true));
+
+ profile.Snapshot.RemoveAllNonInheritableExtensions();
+
+ profile.Snapshot.Element[0].Extension.Should().BeEmpty();
+ profile.Snapshot.Element[0].Binding.Extension.Should().BeEmpty();
+ }
+
+
[TestMethod]
public async Tasks.Task TestNewR5Elements()
{