Renamed CqlContextExpressions to CqlExpressions, and made it static
Renamed OperatorBinding to OperatorsBinder
Renamed CqlOperatorsBinding to CqlOperatorsBinder (the filenames still have to be changed as well)
Changed CqlOperatorsBinder dependencies from internal properties to private fields
Elements with DateTime Precision
Added interface IGetDateTimePrecision, and apply on all ELM Element types that have this
CqlOperatorsBinder
Moved the Equals method from ExpressionBuilder to CqlOperatorsBinder. It has changed from a simple method bind to checking conversions before binding.
Moved methods for converting or casting from the ExpressionBuilder to CqlOperatorsBinder: ConvertToType and CastToType
Removed following methods: Round
Methods are resolved based on whether a match is found on the arguments directly or via conversions. If multiple candidates are found, they are scored based on how closely the arguments were matched, or if there were no arguments, on the result type.
CqlOperator's that were removed:
IntervalAfterInterval, IntervalAfterElement, ElementAfterInterval (all goes through After)
IntervalBeforeInterval, IntervalBeforeElement, ElementBeforeInterval (all goes through Before)
ExpressionBuilder
Simplified and removed following methods: Round, CalculateAge, CalculateAgeAt, InValueSet, AnyInValueSet, ExpandValueSet, Equal (moved to CqlOperatorsBinder), NotEqual, After, Before, DateTimeComponentFrom, UnaryOperator, NaryOperator, DateTime, Date, LastPositionOf, PositionOf, Ratio, Round, Time
Moved IsInterval to TypeExtensions.IsCqlInterval
Since many element types implement IGetDateTimePrecision, the Precision methods was changed to take in the element, instead of the two property components.
ContextBinder
Another dependency was added for the expression builders, ContextBinder, which binds method call expressions to CqlContext
Expression Building Dependencies
Since the list of types is getting cumbersome to pass along, they have all been wrapped up inside ExpressionBuildingDependencies. This new type is created by the CqlCompilerFactory and passed to LibraryDefinitionsBuilder, then LibrarySetExpressionBuilder, LibraryExpressionBuilder and finally ExpressionBuilder. Each builder type in created by the one before, and they copy the dependencies they need into private fields. See the new service dependencies diagram below.
TypeExtensions
Some type checking utilities scattered around the codebase were consolidated into
IsNullableValueType (I added this back, because it is just a lot more readable than otherwise calling Nullable.GetUnderlyingType() then checking whether is returns null or not.
IsNullable - nullable value types, or reference types
IsEnum
IsImplementingGenericTypeDefinition
and Hl7.Cql.Compiler.Infrastructure.TypeExtensions
IsCqlInterval
Service Dependencies (excl Logger and Options)
classDiagram
direction BT
%% HACK: Mermaid doesnt support commas withing generic, so use a similar looking character (﹐)
namespace CSharpCode_Generate_And_Compile {
class AssemblyCompiler {
%% Compile(librarySet : LibrarySet,definitions : DefinitionDictionary~LambdaExpression~? = null) IDictionary~string, AssemblyData~
}
class CSharpLibrarySetToStreamsWriter {
}
class CSharpCodeStreamPostProcessor {
ProcessStream(name : string, stream : Stream) void
}
class WriteToFileCSharpCodeStreamPostProcessor {
}
}
namespace Expression_Building {
class Expression{
}
class Library{
}
class LibrarySet{
}
class ExpressionBuildingDependencies{
}
class LibraryDefinitionBuilderSettings {
}
class ExpressionBuilder{
}
class LibraryExpressionBuilder{
}
class LibrarySetExpressionBuilder{
}
class LibraryDefinitionsBuilder {
%% ProcessLibrarySet(librarySet : LibrarySet) DefinitionDictionary<LambdaExpression>
}
class OperatorsBinder {
}
class CqlOperatorsBinder {
}
class TypeConverter {
}
class ModelInspector {
}
}
namespace Fhir_Resource_Building {
class ResourcePackager {
%% PackageResources(elmDirectory : DirectoryInfo, cqlDirectory : DirectoryInfo, resourceCanonicalRootUrl : string? = null) IReadOnlyCollection~Resource~
}
class FhirResourcePostProcessor {
%% ProcessResource(resource : Resource) void
}
class WriteToFileFhirResourcePostProcessor {
}
}
namespace Cql_To_Resource_Pipeline {
class CqlToResourcePackagingPipeline {
}
}
namespace Application {
class PackagerCliProgram {
}
class OptionsConsoleDumper {
}
}
%% namespace Dependencies {
class TypeManager {
get_TypeResolver() TypeResolver
get_TupleTypes() IEnumerable~Type~
}
class TypeResolver {
}
%% }
%% Inheritance
CqlOperatorsBinder --> OperatorsBinder : inherits
WriteToFileCSharpCodeStreamPostProcessor --> CSharpCodeStreamPostProcessor : inherits
WriteToFileFhirResourcePostProcessor --> FhirResourcePostProcessor : inherits
%% Injected Dependencies
CSharpCodeStreamPostProcessor ..> AssemblyCompiler : injected\n(optional)
CSharpLibrarySetToStreamsWriter ..> AssemblyCompiler : injected
TypeManager ..> AssemblyCompiler : injected
Expression ..> ExpressionBuilder : processed by
LibrarySet ..> LibrarySetExpressionBuilder : processed by
LibraryExpressionBuilder ..> LibrarySetExpressionBuilder : created by
AssemblyCompiler ..> CqlToResourcePackagingPipeline : injected
LibraryDefinitionsBuilder ..> CqlToResourcePackagingPipeline : injected
ResourcePackager ..> CqlToResourcePackagingPipeline : injected
OptionsConsoleDumper ..> PackagerCliProgram : injected
CqlToResourcePackagingPipeline ..> PackagerCliProgram : injected
TypeResolver ..> CqlOperatorsBinder : injected
TypeConverter ..> CqlOperatorsBinder : injected
ModelInspector ..> TypeConverter : injected
ExpressionBuildingDependencies ..> LibraryDefinitionsBuilder : injected
LibrarySetExpressionBuilder ..> LibraryDefinitionsBuilder : created by
ILoggerFactory ..> ExpressionBuildingDependencies : injected
OperatorsBinder ..> ExpressionBuildingDependencies : injected
TypeManager ..> ExpressionBuildingDependencies : injected
TypeConverter ..> ExpressionBuildingDependencies : injected
TypeResolver ..> ExpressionBuildingDependencies : injected (via TypeManager)
LibraryDefinitionBuilderSettings ..> ExpressionBuildingDependencies : injected (static)
ExpressionBuilder ..> LibraryExpressionBuilder : created by
Library ..> LibraryExpressionBuilder : processed by
TypeResolver ..> TypeManager : injected
TypeResolver ..> ResourcePackager : injected
FhirResourcePostProcessor ..> ResourcePackager : injected\n(optional)
TypeResolver ..> CSharpLibrarySetToStreamsWriter : injected
ℹ️Work for issue #292 ⏭️ PR #306
Cleanup
else
keywordsChanges
CqlContextExpressions
toCqlExpressions
, and made it staticOperatorBinding
toOperatorsBinder
CqlOperatorsBinding
toCqlOperatorsBinder
(the filenames still have to be changed as well)CqlOperatorsBinder
dependencies from internal properties to private fieldsElements with DateTime Precision
IGetDateTimePrecision
, and apply on all ELM Element types that have thisCqlOperatorsBinder
Equals
method fromExpressionBuilder
toCqlOperatorsBinder
. It has changed from a simple method bind to checking conversions before binding.ExpressionBuilder
toCqlOperatorsBinder
:ConvertToType
andCastToType
Round
CqlOperator
's that were removed:IntervalAfterInterval
,IntervalAfterElement
,ElementAfterInterval
(all goes throughAfter
)IntervalBeforeInterval
,IntervalBeforeElement
,ElementBeforeInterval
(all goes throughBefore
)ExpressionBuilder
Round
,CalculateAge
,CalculateAgeAt
,InValueSet
,AnyInValueSet
,ExpandValueSet
,Equal
(moved toCqlOperatorsBinder
),NotEqual
,After
,Before
,DateTimeComponentFrom
,UnaryOperator
,NaryOperator
,DateTime
,Date
,LastPositionOf
,PositionOf
,Ratio
,Round
,Time
IsInterval
toTypeExtensions.IsCqlInterval
IGetDateTimePrecision
, thePrecision
methods was changed to take in the element, instead of the two property components.ContextBinder
Another dependency was added for the expression builders,
ContextBinder
, which binds method call expressions toCqlContext
Expression Building Dependencies
Since the list of types is getting cumbersome to pass along, they have all been wrapped up inside
ExpressionBuildingDependencies
. This new type is created by theCqlCompilerFactory
and passed toLibraryDefinitionsBuilder
, thenLibrarySetExpressionBuilder
,LibraryExpressionBuilder
and finallyExpressionBuilder
. Each builder type in created by the one before, and they copy the dependencies they need into private fields. See the new service dependencies diagram below.TypeExtensions
Some type checking utilities scattered around the codebase were consolidated into
Hl7.Cql.Abstractions.Infrastructure.TypeExtensions
IsNullableValueType
(I added this back, because it is just a lot more readable than otherwise callingNullable.GetUnderlyingType()
then checking whether is returns null or not.IsNullable
- nullable value types, or reference typesIsEnum
IsImplementingGenericTypeDefinition
Hl7.Cql.Compiler.Infrastructure.TypeExtensions
IsCqlInterval
Service Dependencies (excl Logger and Options)