Skip to content
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

Generate Element.Id/Extension.Url as normal FHIR primitive properties, not primitives. #46

Merged
merged 3 commits into from
Dec 3, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
175 changes: 32 additions & 143 deletions src/Microsoft.Health.Fhir.CodeGen/Language/Firely/CSharpFirely2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2210,7 +2210,6 @@ void writeSetValueCase(string name, string? when, string statement)
_writer.IncreaseIndent();

_writer.WriteLineIndented(statement);
//_writer.WriteLineIndented($"return true;");
_writer.WriteLineIndented($"return this;");
_writer.DecreaseIndent();
}
Expand All @@ -2229,139 +2228,6 @@ void writeSetValueCase(string name, string? when, string statement)
void writeBaseTrySetValue() => _writer.WriteLineIndented("return base.SetValue(key, value);");
}

/// <summary>Writes the children of this item.</summary>
/// <param name="exportName">Name of the exported class.</param>
/// <param name="exportedElements">The exported elements.</param>
// private void WriteNamedChildren(string exportName,
// List<WrittenElementInfo> exportedElements)
// {
// // Base implementation differs from subclasses.
// if (exportName == "Base")
// {
// _writer.WriteIndentedComment("""
// Enumerate all child nodes.
// Return a sequence of child elements, components and/or properties.
// Child nodes are returned as tuples with the name and the node itself, in the order defined
// by the FHIR specification.
// First returns child nodes inherited from any base class(es), recursively.
// Finally returns child nodes defined by the current class.
// """);
// _writer.WriteLineIndented("[IgnoreDataMember]");
// _writer.WriteLineIndented("public virtual IEnumerable<ElementValue> NamedChildren => Enumerable.Empty<ElementValue>();");
// _writer.WriteLine(string.Empty);
// return;
// }
//
// // Don't override anything if there are no additional elements.
// if (!exportedElements.Any())
// {
// return;
// }
//
// _writer.WriteLineIndented("[IgnoreDataMember]");
// _writer.WriteLineIndented("public override IEnumerable<ElementValue> NamedChildren");
//
// OpenScope();
// _writer.WriteLineIndented("get");
// OpenScope();
// _writer.WriteLineIndented($"foreach (var item in base.NamedChildren) yield return item;");
//
// foreach (WrittenElementInfo info in exportedElements)
// {
// if (info.PropertyType is ListTypeReference)
// {
// _writer.WriteLineIndented(
// $"foreach (var elem in {info.PropertyName})" +
// $" {{ if (elem != null)" +
// $" yield return new ElementValue(\"{info.FhirElementName}\", elem);" +
// $" }}");
// }
// else
// {
// string yr = NamedChildrenFhirTypeWrapper(info);
//
// _writer.WriteLineIndented(
// $"if ({info.PropertyName} != null)" +
// $" yield return new ElementValue(\"{info.FhirElementName}\", {yr});");
// }
// }
//
// CloseScope(suppressNewline: true);
// CloseScope();
// }

// For a limited set of exceptional elements, the Children functions return a
// complex FHIR type wrapper.
// private static string NamedChildrenFhirTypeWrapper(WrittenElementInfo info)
// {
//
// return info.FhirElementPath switch
// {
// "Narrative.div" => $"new FhirString({info.PropertyName}.Value)",
// "Element.id" => $"new FhirString({info.PropertyName})",
// "Extension.url" => $"new FhirUri({info.PropertyName})",
// _ => $"{info.PropertyName}"
// };
// }

/// <summary>Writes the children of this item.</summary>
/// <param name="exportName">Name of the exported class.</param>
/// <param name="exportedElements">The exported elements.</param>
// private void WriteChildren(string exportName,
// List<WrittenElementInfo> exportedElements)
// {
// // Base implementation differs from subclasses.
// if (exportName == "Base")
// {
// _writer.WriteIndentedComment(
// """
// Enumerate all child nodes.
// Return a sequence of child elements, components and/or properties.
// Child nodes are returned in the order defined by the FHIR specification.
// First returns child nodes inherited from any base class(es), recursively.
// Finally returns child nodes defined by the current class.
// """);
// _writer.WriteLineIndented("[IgnoreDataMember]");
// _writer.WriteLineIndented("public virtual IEnumerable<Base> Children => Enumerable.Empty<Base>();");
// _writer.WriteLine(string.Empty);
// return;
// }
//
// // Don't override anything if there are no additional elements.
// if (!exportedElements.Any())
// {
// return;
// }
//
// _writer.WriteLineIndented("[IgnoreDataMember]");
// _writer.WriteLineIndented("public override IEnumerable<Base> Children");
//
// OpenScope();
// _writer.WriteLineIndented("get");
// OpenScope();
// _writer.WriteLineIndented($"foreach (var item in base.Children) yield return item;");
//
// foreach (WrittenElementInfo info in exportedElements)
// {
// if (info.PropertyType is ListTypeReference)
// {
// _writer.WriteLineIndented(
// $"foreach (var elem in {info.PropertyName})" +
// $" {{ if (elem != null) yield return elem; }}");
// }
// else
// {
// string yr = NamedChildrenFhirTypeWrapper(info);
// _writer.WriteLineIndented(
// $"if ({info.PropertyName} != null)" +
// $" yield return {yr};");
// }
// }
//
// CloseScope(suppressNewline: true);
// CloseScope();
// }

/// <summary>Writes the matches.</summary>
/// <param name="exportName">Name of the exported class.</param>
/// <param name="exportedElements">The exported elements.</param>
Expand Down Expand Up @@ -3114,6 +2980,7 @@ private void WriteElement(
};

string? xmlSerialization = path == "Narrative.div" ? "XHtml" :
path is "Extension.url" or "Element.id" ? "XmlAttr" :
ei.PropertyType is CqlTypeReference ? "XmlAttr" :
null;

Expand Down Expand Up @@ -3176,8 +3043,8 @@ private void WriteElement(
_writer.WriteLineIndented($"[Binding(\"{element.cgBindingName()}\")]");
}

if (element.cgIsSimple() && element.Type.Count == 1 && element.Type.Single().cgName() == "uri")
_writer.WriteLineIndented("[UriPattern]");
// if (element.cgIsSimple() && element.Type.Count == 1 && element.Type.Single().cgName() == "uri")
// _writer.WriteLineIndented("[UriPattern]");

bool notClsCompliant = !string.IsNullOrEmpty(allowedTypes) ||
!string.IsNullOrEmpty(resourceReferences);
Expand Down Expand Up @@ -3289,12 +3156,12 @@ TypeReference determineTypeReferenceForFhirElementName()
return PrimitiveTypeReference.GetTypeReference("uri");
}

if (element.Path is "Element.id" or "Extension.url")
{
/* these two properties formally use a CQL primitive (at least,
* that's how they are encoded in the StructureDefinition. */
return CqlTypeReference.SystemString;
}
// if (element.Path is "Element.id" or "Extension.url")
// {
// /* these two properties formally use a CQL primitive (at least,
// * that's how they are encoded in the StructureDefinition. */
// return CqlTypeReference.SystemString;
// }

var initialTypeName = getTypeNameFromElement();

Expand Down Expand Up @@ -3847,7 +3714,29 @@ private void WritePrimitiveType(
_writer.WriteLineIndented("[DataMember]");
_writer.WriteLineIndented($"public {typeName} Value");
OpenScope();
_writer.WriteLineIndented($"get {{ return ({typeName})ObjectValue; }}");

// A bit of a hack until we have a proper way to handle the primitives
// in https://github.com/FirelyTeam/firely-net-sdk/issues/2781
if (typeName == "long?")
{
_writer.WriteLineIndented(
"""
get
{
return ObjectValue switch
{
null => null,
long l => l,
_ => Convert.ToInt64(ObjectValue)
};
}
""");
}
else
{
_writer.WriteLineIndented($"get {{ return ({typeName})ObjectValue; }}");
}

_writer.WriteLineIndented("set { ObjectValue = value; OnPropertyChanged(\"Value\"); }");
CloseScope();

Expand Down