Skip to content

Commit

Permalink
Follow-up items for 3.0.0-SNAPSHOT (cqframework#1178)
Browse files Browse the repository at this point in the history
* State refactor WIP

* WIP

* WIP

* WIP

* Fixes for Options serialization

* WIP

* WIP

* WIP

* WIP

* Sort statement list

* Fix failing tests

* Fix failing tests
  • Loading branch information
JPercival committed Jul 12, 2023
1 parent 761b314 commit 69a7cd8
Show file tree
Hide file tree
Showing 185 changed files with 7,435 additions and 3,334 deletions.
12 changes: 11 additions & 1 deletion Src/java/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
{
"java.configuration.updateBuildConfiguration": "automatic",
"java.compile.nullAnalysis.mode": "automatic",
"java.jdt.ls.vmargs": "-noverify -Xmx4G -XX:+UseG1GC -XX:+UseStringDeduplication"
"java.jdt.ls.vmargs": "-noverify -Xmx4G -XX:+UseG1GC -XX:+UseStringDeduplication",
"cSpell.words": [
"bools",
"datumedge",
"fhirpath",
"hamcrest",
"Inferencing",
"qicore",
"testng",
"trackback"
]
}
2 changes: 1 addition & 1 deletion Src/java/cql-to-elm-cli/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {
}

application {
mainClass = 'org.cqframework.cql.cql2elm.cli.CqlTranslator'
mainClass = 'org.cqframework.cql.cql2elm.cli.Main'
}

dependencies {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@
import org.cqframework.cql.cql2elm.*;
import org.cqframework.cql.cql2elm.quick.FhirLibrarySourceProvider;
import org.cqframework.cql.elm.tracking.TrackBack;
import org.fhir.ucum.UcumEssenceService;
import org.fhir.ucum.UcumException;
import org.fhir.ucum.UcumService;
import org.hl7.cql.model.ModelIdentifier;
import org.hl7.cql.model.ModelInfoProvider;
import org.hl7.elm_modelinfo.r1.ModelInfo;
Expand All @@ -28,11 +25,10 @@
import static java.nio.file.FileVisitResult.CONTINUE;
import static org.cqframework.cql.cql2elm.CqlTranslator.fromFile;

public class CqlTranslator {
public class Main {
public static ModelInfoProvider getModelInfoProvider(File modelInfoXML) {
try {
final ModelInfo modelInfo = ModelInfoReaderFactory.getReader("application/xml").read(modelInfoXML);
final ModelIdentifier modelId = new ModelIdentifier().withId(modelInfo.getName()).withVersion(modelInfo.getVersion());
return (ModelIdentifier modelIdentifier) -> modelInfo;
} catch (IOException e) {
System.err.printf("Could not load model-info XML: %s%n", modelInfoXML);
Expand All @@ -51,13 +47,13 @@ private static void outputExceptions(Iterable<CqlCompilerException> exceptions)
}
}

private static void writeELM(Path inPath, Path outPath, org.cqframework.cql.cql2elm.CqlTranslator.Format format, ModelInfoProvider modelProvider, CqlTranslatorOptions options) throws IOException {
private static void writeELM(Path inPath, Path outPath, org.cqframework.cql.cql2elm.CqlTranslator.Format format, ModelInfoProvider modelProvider, CqlCompilerOptions options) throws IOException {

System.err.println("================================================================================");
System.err.printf("TRANSLATE %s%n", inPath);

ModelManager modelManager;
if(options.getOptions().contains(CqlTranslatorOptions.Options.DisableDefaultModelInfoLoad)) {
if(options.getOptions().contains(CqlCompilerOptions.Options.DisableDefaultModelInfoLoad)) {
modelManager = new ModelManager(false);
} else {
modelManager = new ModelManager();
Expand All @@ -67,27 +63,18 @@ private static void writeELM(Path inPath, Path outPath, org.cqframework.cql.cql2
modelManager.getModelInfoLoader().registerModelInfoProvider(modelProvider);
}

LibraryManager libraryManager = new LibraryManager(modelManager);
UcumService ucumService = null;
if (options.getValidateUnits()) {
try {
ucumService = new UcumEssenceService(UcumEssenceService.class.getResourceAsStream("/ucum-essence.xml"));
} catch (UcumException e) {
System.err.println("Could not create UCUM validation service:");
e.printStackTrace();
}
}
LibraryManager libraryManager = new LibraryManager(modelManager, options);
modelManager.getModelInfoLoader().registerModelInfoProvider(new DefaultModelInfoProvider(inPath.getParent()), true);
libraryManager.getLibrarySourceLoader().registerProvider(new DefaultLibrarySourceProvider(inPath.getParent()));
libraryManager.getLibrarySourceLoader().registerProvider(new FhirLibrarySourceProvider());
org.cqframework.cql.cql2elm.CqlTranslator translator = fromFile(inPath.toFile(), modelManager, libraryManager, ucumService, options);
org.cqframework.cql.cql2elm.CqlTranslator translator = fromFile(inPath.toFile(), libraryManager);
libraryManager.getLibrarySourceLoader().clearProviders();

if (translator.getErrors().size() > 0) {
if (!translator.getErrors().isEmpty()) {
System.err.println("Translation failed due to errors:");
outputExceptions(translator.getExceptions());
} else if (!options.getVerifyOnly()) {
if (translator.getExceptions().size() == 0) {
if (translator.getExceptions().isEmpty()) {
System.err.println("Translation completed successfully.");
}
else {
Expand Down Expand Up @@ -214,7 +201,7 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
modelProvider = getModelInfoProvider(modelFile);
}

writeELM(in, out, outputFormat, modelProvider, new CqlTranslatorOptions(outputFormat, options.has(optimization),
writeELM(in, out, outputFormat, modelProvider, new CqlCompilerOptions(options.has(optimization),
options.has(debug) || options.has(annotations),
options.has(debug) || options.has(locators),
options.has(debug) || options.has(resultTypes),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package org.cqframework.cql.cql2elm;

import org.hl7.cql_annotations.r1.CqlToElmBase;
import org.hl7.cql_annotations.r1.CqlToElmInfo;
import org.hl7.elm.r1.Library;

import java.util.EnumSet;
import java.util.List;
import java.util.Set;

import static java.util.Objects.requireNonNull;

/**
* This class provides functions for extracting and parsing CQL Compiler
* Options from
* a Library
*/
public class CompilerOptions {

private CompilerOptions() {
// intentionally empty
}

/**
* Gets the compiler options used to generate an elm Library.
*
* Returns null if the compiler options could not be determined.
* (for example, the Library was translated without annotations)
*
* @param library The library to extracts the options from.
* @return The set of options used to translate the library.
*/
public static Set<CqlCompilerOptions.Options> getCompilerOptions(Library library) {
requireNonNull(library, "library can not be null");
if (library.getAnnotation() == null || library.getAnnotation().isEmpty()) {
return null;
}

String compilerOptions = getCompilerOptions(library.getAnnotation());
return parseCompilerOptions(compilerOptions);
}

private static String getCompilerOptions(List<CqlToElmBase> annotations) {
for (CqlToElmBase base : annotations) {
if (base instanceof CqlToElmInfo) {
if (((CqlToElmInfo) base).getTranslatorOptions() != null) {
return ((CqlToElmInfo) base).getTranslatorOptions();
}
}
}

return null;
}

/**
* Parses a string representing CQL compiler Options into an EnumSet. The
* string is expected
* to be a comma delimited list of values from the CqlCompiler.Options
* enumeration.
* For example "EnableListPromotion, EnableListDemotion".
*
* @param compilerOptions the string to parse
* @return the set of options
*/
public static Set<CqlCompilerOptions.Options> parseCompilerOptions(String compilerOptions) {
if (compilerOptions == null || compilerOptions.isEmpty()) {
return null;
}

EnumSet<CqlCompilerOptions.Options> optionSet = EnumSet.noneOf(CqlCompilerOptions.Options.class);
String[] options = compilerOptions.trim().split(",");

for (String option : options) {
optionSet.add(CqlCompilerOptions.Options.valueOf(option));
}

return optionSet;
}

/**
* Gets the compiler version used to generate an elm Library.
*
* Returns null if the compiled version could not be determined. (for example,
* the Library was
* compiled without annotations)
*
* @param library The library to extracts the compiler version from.
* @return The version of compiler used to compiler the library.
*/
public static String getCompilerVersion(Library library) {
requireNonNull(library, "library can not be null");
if (library.getAnnotation() == null || library.getAnnotation().isEmpty()) {
return null;
}

return getCompilerVersion(library.getAnnotation());
}

private static String getCompilerVersion(List<CqlToElmBase> annotations) {
for (CqlToElmBase o : annotations) {
if (o instanceof CqlToElmInfo) {
CqlToElmInfo c = (CqlToElmInfo) o;
return c.getTranslatorVersion();
}
}

return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,26 +149,26 @@ public void disableFromKeywordRequired() {
fromKeywordRequired = false;
}

public void setTranslatorOptions(CqlTranslatorOptions options) {
if (options.getOptions().contains(CqlTranslatorOptions.Options.EnableDateRangeOptimization)) {
public void setTranslatorOptions(CqlCompilerOptions options) {
if (options.getOptions().contains(CqlCompilerOptions.Options.EnableDateRangeOptimization)) {
this.enableDateRangeOptimization();
}
if (options.getOptions().contains(CqlTranslatorOptions.Options.EnableAnnotations)) {
if (options.getOptions().contains(CqlCompilerOptions.Options.EnableAnnotations)) {
this.enableAnnotations();
}
if (options.getOptions().contains(CqlTranslatorOptions.Options.EnableLocators)) {
if (options.getOptions().contains(CqlCompilerOptions.Options.EnableLocators)) {
this.enableLocators();
}
if (options.getOptions().contains(CqlTranslatorOptions.Options.EnableResultTypes)) {
if (options.getOptions().contains(CqlCompilerOptions.Options.EnableResultTypes)) {
this.enableResultTypes();
}
if (options.getOptions().contains(CqlTranslatorOptions.Options.EnableDetailedErrors)) {
if (options.getOptions().contains(CqlCompilerOptions.Options.EnableDetailedErrors)) {
this.enableDetailedErrors();
}
if (options.getOptions().contains(CqlTranslatorOptions.Options.DisableMethodInvocation)) {
if (options.getOptions().contains(CqlCompilerOptions.Options.DisableMethodInvocation)) {
this.disableMethodInvocation();
}
if (options.getOptions().contains(CqlTranslatorOptions.Options.RequireFromKeyword)) {
if (options.getOptions().contains(CqlCompilerOptions.Options.RequireFromKeyword)) {
this.enableFromKeywordRequired();
}
libraryBuilder.setCompatibilityLevel(options.getCompatibilityLevel());
Expand Down Expand Up @@ -647,7 +647,7 @@ public Object visit(ParseTree tree) {
// ERROR:
try {
o = super.visit(tree);
} catch (CqlTranslatorIncludeException e) {
} catch (CqlIncludeException e) {
CqlCompilerException translatorException = new CqlCompilerException(e.getMessage(), getTrackBack(tree), e);
if (translatorException.getLocator() == null) {
throw translatorException;
Expand Down Expand Up @@ -746,7 +746,7 @@ public VersionedIdentifier visitLibraryDefinition(cqlParser.LibraryDefinitionCon
VersionedIdentifier vid = of.createVersionedIdentifier()
.withId(identifiers.remove(identifiers.size() - 1))
.withVersion(parseString(ctx.versionSpecifier()));
if (identifiers.size() > 0) {
if (!identifiers.isEmpty()) {
vid.setSystem(libraryBuilder.resolveNamespaceUri(String.join(".", identifiers), true));
}
else if (libraryBuilder.getNamespaceInfo() != null) {
Expand All @@ -762,7 +762,7 @@ else if (libraryBuilder.getNamespaceInfo() != null) {
public UsingDef visitUsingDefinition(cqlParser.UsingDefinitionContext ctx) {
List<String> identifiers = (List<String>)visit(ctx.qualifiedIdentifier());
String unqualifiedIdentifier = identifiers.remove(identifiers.size() - 1);
String namespaceName = identifiers.size() > 0 ? String.join(".", identifiers) :
String namespaceName = !identifiers.isEmpty() ? String.join(".", identifiers) :
libraryBuilder.isWellKnownModelName(unqualifiedIdentifier) ? null :
(libraryBuilder.getNamespaceInfo() != null ? libraryBuilder.getNamespaceInfo().getName() : null);

Expand Down Expand Up @@ -824,7 +824,7 @@ private String getLibraryPath(String namespaceName, String unqualifiedIdentifier
public Object visitIncludeDefinition(cqlParser.IncludeDefinitionContext ctx) {
List<String> identifiers = (List<String>)visit(ctx.qualifiedIdentifier());
String unqualifiedIdentifier = identifiers.remove(identifiers.size() - 1);
String namespaceName = identifiers.size() > 0 ? String.join(".", identifiers) :
String namespaceName = !identifiers.isEmpty() ? String.join(".", identifiers) :
(libraryBuilder.getNamespaceInfo() != null ? libraryBuilder.getNamespaceInfo().getName() : null);
String path = getLibraryPath(namespaceName, unqualifiedIdentifier);
IncludeDef library = of.createIncludeDef()
Expand Down
Loading

0 comments on commit 69a7cd8

Please sign in to comment.