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

Multiplatform CQL parser #1443

Open
wants to merge 42 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
bd76188
WIP
JPercival Aug 1, 2024
97d8b38
WIP
JPercival Aug 2, 2024
380ce8a
WIP
JPercival Aug 2, 2024
d6b8c82
Working?
JPercival Aug 2, 2024
5f6df9a
Fix usage of Java 17 API
JPercival Sep 13, 2024
7f8814f
Update checkstyle rules
JPercival Sep 13, 2024
d0538b0
Fix static analysis
JPercival Sep 13, 2024
64faae3
Updates to src dirs
JPercival Sep 15, 2024
d3dd7fb
Fixing up missing test sourceSet
JPercival Sep 15, 2024
1e7806d
Try another way to specify the antlr directory
JPercival Sep 15, 2024
a35bb71
Third different way
JPercival Sep 15, 2024
e7a0edd
Add some logging
JPercival Sep 15, 2024
78070d4
merge master
JPercival Sep 16, 2024
76360e2
Change toolchain resolution
JPercival Sep 17, 2024
b66739a
Fix tests
JPercival Sep 17, 2024
92631bc
More tweaks to animalsniffer
JPercival Sep 17, 2024
f4749f2
Fix formatting
JPercival Sep 17, 2024
3a2b2cb
Trying random stuff
JPercival Sep 17, 2024
5a4035c
More random stuff
JPercival Sep 17, 2024
a37cb75
Add Kotlin static analysis and formatting
JPercival Sep 17, 2024
c78d3c5
More KT cleanup
JPercival Sep 18, 2024
a428f4c
WIP
JPercival Sep 20, 2024
1cf7a68
Fix formatting
JPercival Sep 20, 2024
59c02a6
WIP, multi-platform
JPercival Sep 20, 2024
31a19dc
Build preliminary CQL parsing library targeting JS (#1434)
antvaset Nov 4, 2024
fc0b9ec
Origin/feature kotlin conventions patch (#1437)
JPercival Nov 6, 2024
ac1be93
Merge branch 'master' into feature-kotlin-conventions
JPercival Nov 6, 2024
170c33c
Fix static app entry point, fix build dependencies
JPercival Nov 7, 2024
8dd237d
Play within memory options
JPercival Nov 7, 2024
0f3af36
Merge branch 'feature-kotlin-conventions' into feature-multiplatform-…
antvaset Nov 13, 2024
78580bd
Add demo UI for CQL parser (#1439)
antvaset Nov 15, 2024
595f9a7
merge remote-tracking branch 'origin/master' into feature-multiplatfo…
JPercival Nov 18, 2024
0a7f8f0
Remove redundant overrides in `Cql2ElmVisitor` and `CqlPreprocessor` …
antvaset Nov 19, 2024
6557f0e
Merge branch 'master' into feature-multiplatform-cql-parser
JPercival Nov 19, 2024
8a3394b
Add toolchain resolver plugins
JPercival Nov 19, 2024
f735347
Update Gradle to 8.11
JPercival Nov 19, 2024
e47aa29
Merge branch 'master' into feature-multiplatform-cql-parser
JPercival Nov 21, 2024
99b59c4
sync versions, merge master, remove unused code
JPercival Nov 21, 2024
3ef9807
Fix typo
JPercival Nov 21, 2024
afc6c02
Fix build deprecation warnings
JPercival Nov 21, 2024
916ecb3
Don't need the xjc conventions for cql-to-elm, that's upstream
JPercival Nov 21, 2024
4226a65
Merge branch 'master' into feature-multiplatform-cql-parser
JPercival Nov 21, 2024
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ node_modules
.nyc_output
coverage
gen
.kotlin

Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,3 @@ spotless {
}
}

dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl

plugins {
kotlin("multiplatform")
id("com.diffplug.spotless")
id("io.gitlab.arturbosch.detekt")
}

repositories {
mavenCentral()
}

spotless {
kotlin {
ktfmt().kotlinlangStyle()
}
}

kotlin {
jvmToolchain(17)
JPercival marked this conversation as resolved.
Show resolved Hide resolved
jvm {
withJava()
}

// This adds JavaScript as build target.
// Running the build outputs packages in the build/js/packages directory.
// These packages can e.g. be required or imported in JS or TS projects.
// If you get `Task :kotlinStoreYarnLock FAILED` during the build,
// run the `:kotlinUpgradeYarnLock` task and build again.
// Run `jsRun --continuous` to start a local development server with
// live reloading (automatic re-build on file changes). The local server serves
// <module>/src/jsMain/resources/index.html from the root.
js(IR) {

// Output ES2015 modules (.mjs files) to build/js/packages/<package>/kotlin
// instead of default UMD (.js) modules.
useEsModules()

// Set web browser environment as the target execution environment.
// This also runs webpack which bundles everything into a single
// <module>/build/dist/js/productionExecutable/<module>.js file.
// This file can be e.g. included in an HTML file and distributed
// via a CDN.
browser {
testTask {
useKarma {
useChromeHeadless()
}
}
}

// `nodejs {}` can be added here to set Node.js as the target execution
// environment. If no browser APIs are used, having just `browser {}`
// creates an isomorphic library.

// Explicitly instruct the Kotlin compiler to emit executable JS code.
// If `binaries.library()` is used instead, the
// <module>/build/dist/js/productionExecutable directory has
// un-webpacked JS.
binaries.executable()

// Generate TypeScript definitions (.d.ts files) from Kotlin code. The files are
// finally saved to build/js/packages/<package>/kotlin.
generateTypeScriptDefinitions()
}

// Add Kotlin/WASM compilation target.
// The output is in the JS packages directory.
@OptIn(ExperimentalWasmDsl::class)
wasmJs {
browser { }
binaries.executable()
generateTypeScriptDefinitions()
}

sourceSets {
commonMain {
dependencies {
implementation(kotlin("stdlib-common"))
}
}

commonTest {
dependencies {
implementation(kotlin("test"))
}
}

jvmMain {
dependencies {
implementation(kotlin("stdlib-jdk8"))
}
}

jvmTest {
dependencies {
implementation(kotlin("test-junit"))
}
}

jsMain {
dependencies {
implementation(kotlin("stdlib-js"))
}
}

jsTest {
dependencies {
implementation(kotlin("test-js"))
}
}
}
}
2 changes: 1 addition & 1 deletion Src/java/cql-to-elm/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ dependencies {
api("org.apache.commons:commons-text:1.10.0")

// TODO: This dependencies are required due the the fact that the CqlTranslatorOptionsMapper lives
// in the cql-to-elm project. Ideally, we"d factor out all serialization depedencies into common
// in the cql-to-elm project. Ideally, we"d factor out all serialization dependencies into common
// libraries such that we could swap out jackson for something else. In the meantime, these are
// "implementation" dependencies so that they are not exported downstream.
implementation("com.fasterxml.jackson.module:jackson-module-jakarta-xmlbind-annotations:${project.findProperty("jackson.version")}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.TokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.antlr.v4.kotlinruntime.*;
import org.antlr.v4.kotlinruntime.tree.*;
import org.cqframework.cql.cql2elm.LibraryBuilder.IdentifierScope;
import org.cqframework.cql.cql2elm.model.*;
import org.cqframework.cql.cql2elm.model.invocation.*;
Expand Down Expand Up @@ -1781,9 +1779,9 @@ public Object visitTerminal(TerminalNode node) {
return null;
}

if (cqlLexer.STRING == tokenType
|| cqlLexer.QUOTEDIDENTIFIER == tokenType
|| cqlLexer.DELIMITEDIDENTIFIER == tokenType) {
if (cqlLexer.Tokens.STRING == tokenType
|| cqlLexer.Tokens.QUOTEDIDENTIFIER == tokenType
|| cqlLexer.Tokens.DELIMITEDIDENTIFIER == tokenType) {
// chop off leading and trailing ', ", or `
text = text.substring(1, text.length() - 1);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.kotlinruntime.*;
import org.antlr.v4.kotlinruntime.tree.ParseTree;
import org.cqframework.cql.cql2elm.elm.ElmEdit;
import org.cqframework.cql.cql2elm.elm.ElmEditor;
import org.cqframework.cql.cql2elm.elm.IElmEdit;
Expand Down Expand Up @@ -130,7 +130,7 @@ public CqlErrorListener(LibraryBuilder builder, boolean detailedErrors) {
private VersionedIdentifier extractLibraryIdentifier(cqlParser parser) {
RuleContext context = parser.getContext();
while (context != null && !(context instanceof cqlParser.LibraryContext)) {
context = context.parent;
context = context.getParent();
}

if (context instanceof cqlParser.LibraryContext) {
Expand Down Expand Up @@ -183,15 +183,15 @@ public void syntaxError(
}

public Library run(File cqlFile) throws IOException {
return run(CharStreams.fromStream(new FileInputStream(cqlFile)));
return run(CharStreams.INSTANCE.fromStream(new FileInputStream(cqlFile)));
}

public Library run(String cqlText) {
return run(CharStreams.fromString(cqlText));
return run(CharStreams.INSTANCE.fromString(cqlText));
}

public Library run(InputStream is) throws IOException {
return run(CharStreams.fromStream(is));
return run(CharStreams.INSTANCE.fromStream(is));
}

public Library run(CharStream is) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

import java.io.*;
import java.util.*;
import org.antlr.v4.runtime.*;
import org.antlr.v4.kotlinruntime.*;
import org.antlr.v4.kotlinruntime.tree.*;
import org.cqframework.cql.cql2elm.model.CompiledLibrary;
import org.cqframework.cql.elm.serializing.ElmLibraryWriterFactory;
import org.hl7.cql.model.NamespaceInfo;
Expand All @@ -20,28 +21,28 @@ public enum Format {
private CqlCompiler compiler;

public static CqlTranslator fromText(String cqlText, LibraryManager libraryManager) {
return new CqlTranslator(null, null, CharStreams.fromString(cqlText), libraryManager);
return new CqlTranslator(null, null, CharStreams.INSTANCE.fromString(cqlText), libraryManager);
}

public static CqlTranslator fromText(NamespaceInfo namespaceInfo, String cqlText, LibraryManager libraryManager) {
return new CqlTranslator(namespaceInfo, null, CharStreams.fromString(cqlText), libraryManager);
return new CqlTranslator(namespaceInfo, null, CharStreams.INSTANCE.fromString(cqlText), libraryManager);
}

public static CqlTranslator fromText(
NamespaceInfo namespaceInfo,
VersionedIdentifier sourceInfo,
String cqlText,
LibraryManager libraryManager) {
return new CqlTranslator(namespaceInfo, sourceInfo, CharStreams.fromString(cqlText), libraryManager);
return new CqlTranslator(namespaceInfo, sourceInfo, CharStreams.INSTANCE.fromString(cqlText), libraryManager);
}

public static CqlTranslator fromStream(
NamespaceInfo namespaceInfo, InputStream cqlStream, LibraryManager libraryManager) throws IOException {
return new CqlTranslator(namespaceInfo, null, CharStreams.fromStream(cqlStream), libraryManager);
return new CqlTranslator(namespaceInfo, null, CharStreams.INSTANCE.fromStream(cqlStream), libraryManager);
}

public static CqlTranslator fromStream(InputStream cqlStream, LibraryManager libraryManager) throws IOException {
return new CqlTranslator(null, null, CharStreams.fromStream(cqlStream), libraryManager);
return new CqlTranslator(null, null, CharStreams.INSTANCE.fromStream(cqlStream), libraryManager);
}

public static CqlTranslator fromStream(
Expand All @@ -50,14 +51,14 @@ public static CqlTranslator fromStream(
InputStream cqlStream,
LibraryManager libraryManager)
throws IOException {
return new CqlTranslator(namespaceInfo, sourceInfo, CharStreams.fromStream(cqlStream), libraryManager);
return new CqlTranslator(namespaceInfo, sourceInfo, CharStreams.INSTANCE.fromStream(cqlStream), libraryManager);
}

public static CqlTranslator fromFile(String cqlFileName, LibraryManager libraryManager) throws IOException {
return new CqlTranslator(
null,
getSourceInfo(cqlFileName),
CharStreams.fromStream(new FileInputStream(cqlFileName)),
CharStreams.INSTANCE.fromStream(new FileInputStream(cqlFileName)),
libraryManager);
}

Expand All @@ -66,29 +67,35 @@ public static CqlTranslator fromFile(NamespaceInfo namespaceInfo, String cqlFile
return new CqlTranslator(
namespaceInfo,
getSourceInfo(cqlFileName),
CharStreams.fromStream(new FileInputStream(cqlFileName)),
CharStreams.INSTANCE.fromStream(new FileInputStream(cqlFileName)),
libraryManager);
}

public static CqlTranslator fromFile(File cqlFile, LibraryManager libraryManager) throws IOException {
return new CqlTranslator(
null, getSourceInfo(cqlFile), CharStreams.fromStream(new FileInputStream(cqlFile)), libraryManager);
null,
getSourceInfo(cqlFile),
CharStreams.INSTANCE.fromStream(new FileInputStream(cqlFile)),
libraryManager);
}

public static CqlTranslator fromFile(NamespaceInfo namespaceInfo, File cqlFile, LibraryManager libraryManager)
throws IOException {
return new CqlTranslator(
namespaceInfo,
getSourceInfo(cqlFile),
CharStreams.fromStream(new FileInputStream(cqlFile)),
CharStreams.INSTANCE.fromStream(new FileInputStream(cqlFile)),
libraryManager);
}

public static CqlTranslator fromFile(
NamespaceInfo namespaceInfo, VersionedIdentifier sourceInfo, File cqlFile, LibraryManager libraryManager)
throws IOException {
return new CqlTranslator(
namespaceInfo, sourceInfo, CharStreams.fromStream(new FileInputStream(cqlFile)), libraryManager);
namespaceInfo,
sourceInfo,
CharStreams.INSTANCE.fromStream(new FileInputStream(cqlFile)),
libraryManager);
}

private CqlTranslator(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import java.util.ArrayList;
import java.util.List;
import org.antlr.v4.runtime.misc.Interval;
import org.antlr.v4.kotlinruntime.misc.Interval;
import org.hl7.elm.r1.Element;

/**
Expand Down Expand Up @@ -80,7 +80,7 @@ public boolean hasChunks() {
}

public void addChunk(Chunk chunk) {
if (chunk.getInterval().a < interval.a || chunk.getInterval().b > interval.b) {
if (chunk.getInterval().getA() < interval.getA() || chunk.getInterval().getB() > interval.getB()) {
throw new IllegalArgumentException(
"Child chunk cannot be added because it is not contained within the parent chunk.");
}
Expand All @@ -89,36 +89,37 @@ public void addChunk(Chunk chunk) {
int chunkIndex = -1;
Chunk targetChunk = null;
for (int i = 0; i < chunks.size(); i++) {
if (chunk.getInterval().a >= chunks.get(i).getInterval().a
&& chunk.getInterval().a <= chunks.get(i).getInterval().b) {
if (chunk.getInterval().getA() >= chunks.get(i).getInterval().getA()
&& chunk.getInterval().getA() <= chunks.get(i).getInterval().getB()) {
chunkIndex = i;
targetChunk = chunks.get(chunkIndex);
break;
}
}

if (chunk.getInterval().a == targetChunk.getInterval().a) {
if (chunk.getInterval().getA() == targetChunk.getInterval().getA()) {
// the chunk being added starts the targetChunk
// insert the chunk at the targetChunk's index
// update the targetChunk's interval start to be the chunk's interval end + 1
chunks.add(chunkIndex, chunk);
chunkIndex++;
int newA = chunk.getInterval().b + 1;
while (newA > chunks.get(chunkIndex).getInterval().b) {
int newA = chunk.getInterval().getB() + 1;
while (newA > chunks.get(chunkIndex).getInterval().getB()) {
chunks.remove(chunkIndex);
if (chunkIndex >= chunks.size()) {
break;
}
}
if (chunkIndex < chunks.size()) {
chunks.get(chunkIndex)
.setInterval(new Interval(newA, chunks.get(chunkIndex).getInterval().b));
.setInterval(new Interval(
newA, chunks.get(chunkIndex).getInterval().getB()));
}
} else {
int newB = chunk.getInterval().a - 1;
int newA = chunk.getInterval().b + 1;
int oldA = chunks.get(chunkIndex).getInterval().a;
int oldB = chunks.get(chunkIndex).getInterval().b;
int newB = chunk.getInterval().getA() - 1;
int newA = chunk.getInterval().getB() + 1;
int oldA = chunks.get(chunkIndex).getInterval().getA();
int oldB = chunks.get(chunkIndex).getInterval().getB();
chunks.get(chunkIndex).setInterval(new Interval(oldA, newB));
chunkIndex++;
chunks.add(chunkIndex, chunk);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.cqframework.cql.cql2elm.preprocessor;

import org.antlr.v4.runtime.misc.Interval;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.kotlinruntime.misc.Interval;
import org.antlr.v4.kotlinruntime.tree.ParseTree;

@SuppressWarnings("checkstyle:abstractclassname")
public class BaseInfo {
Expand Down
Loading
Loading