Skip to content

Commit

Permalink
#1475: Fixed mapping expansions for profile-informed authoring not re…
Browse files Browse the repository at this point in the history
…specting signature level
  • Loading branch information
brynrhodes committed Dec 17, 2024
1 parent b4b0701 commit 4542157
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2743,6 +2743,22 @@ public Expression applyTargetMap(Expression source, String targetMap) {
String functionArgument = targetMap.substring(invocationStart + 1, targetMap.lastIndexOf(')'));
Expression argumentSource =
functionArgument.equals("%value") ? source : applyTargetMap(source, functionArgument);

// NOTE: This is needed to work around the mapping for ToInterval
// FHIRHelpers defines multiple overloads of ToInterval, but the type mapping
// does not have the type of the source data type.
// All the mappings for ToInterval use FHIR.Period, so this is safe to assume
// In addition, no other FHIRHelpers functions use overloads (except ToString and ToDateTime,
// but those mappings expand the value element directly, rather than invoking the FHIRHelpers function)
TypeSpecifier argumentSignature = null;
if (this.options.getSignatureLevel() != SignatureLevel.None) {
if (qualifiedFunctionName.equals("FHIRHelpers.ToInterval")) {
NamedTypeSpecifier namedTypeSpecifier =
new NamedTypeSpecifier().withName(dataTypeToQName(resolveTypeName("FHIR", "Period")));
argumentSignature = namedTypeSpecifier;
}
}

if (argumentSource.getResultType() instanceof ListType) {
Query query = of.createQuery()
.withSource(of.createAliasedQuerySource()
Expand All @@ -2752,6 +2768,11 @@ public Expression applyTargetMap(Expression source, String targetMap) {
.withLibraryName(libraryName)
.withName(functionName)
.withOperand(of.createAliasRef().withName("$this"));

if (argumentSignature != null) {
fr.getSignature().add(argumentSignature);
}

// This doesn't quite work because the US.Core types aren't subtypes of FHIR types.
// resolveCall(libraryName, functionName, new FunctionRefInvocation(fr), false, false);
query.setReturn(of.createReturnClause().withDistinct(false).withExpression(fr));
Expand All @@ -2763,6 +2784,11 @@ public Expression applyTargetMap(Expression source, String targetMap) {
.withName(functionName)
.withOperand(argumentSource);
fr.setResultType(source.getResultType());

if (argumentSignature != null) {
fr.getSignature().add(argumentSignature);
}

return fr;
// This doesn't quite work because the US.Core types aren't subtypes of FHIR types,
// or they are defined as System types and not FHIR types
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -467,4 +467,38 @@ void abstractClassNotRetrievable() throws IOException {
errors.stream().map(Throwable::getMessage).collect(Collectors.toList());
assertThat(errorMessages, contains("Specified data type DomainResource does not support retrieval."));
}

@Test
void mappingExpansionsRespectSignatureLevel() throws IOException {
// See: https://github.com/cqframework/clinical_quality_language/issues/1475
final CqlTranslator translator = TestUtils.runSemanticTest(
"MappingExpansionsRespectSignatureLevel.cql", 0, LibraryBuilder.SignatureLevel.Overloads);
/*
ExpressionDef: EncounterPeriod
expression is Query
return
expression is FunctionRef
name FHIRHelpers.ToInterval
signature is NamedTypeSpecifier FHIR.Period
*/

Library compiledLibrary = translator.getTranslatedLibrary().getLibrary();
List<ExpressionDef> statements = compiledLibrary.getStatements().getDef();

assertThat(statements.size(), is(2));
ExpressionDef encounterPeriod = statements.get(1);
assertThat(encounterPeriod.getName(), is("EncounterPeriod"));
assertThat(encounterPeriod.getExpression(), instanceOf(Query.class));
Query query = (Query) encounterPeriod.getExpression();
assertThat(query.getReturn().getExpression(), instanceOf(FunctionRef.class));
FunctionRef functionRef = (FunctionRef) query.getReturn().getExpression();
assertThat(functionRef.getLibraryName(), is("FHIRHelpers"));
assertThat(functionRef.getName(), is("ToInterval"));
assertThat(functionRef.getSignature(), notNullValue());
assertThat(functionRef.getSignature().size(), is(1));
assertThat(functionRef.getSignature().get(0), instanceOf(NamedTypeSpecifier.class));
NamedTypeSpecifier namedTypeSpecifier =
(NamedTypeSpecifier) functionRef.getSignature().get(0);
assertThat(namedTypeSpecifier.getName().getLocalPart(), is("Period"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
library MappingExpansionsRespectSignatureLevel

// https://github.com/cqframework/clinical_quality_language/issues/1475

using QICore version '4.1.1'

include FHIRHelpers version '4.0.1'

parameter "Measurement Period" Interval<DateTime> default Interval[@2024-01-01T00:00:00.0Z, @2025-01-01T00:00:00.0Z)

context Patient

define EncounterPeriod:
[Encounter] E
return E.period

0 comments on commit 4542157

Please sign in to comment.