Strumenta / antlr-kotlin

Support for Kotlin as a target for ANTLR 4
Apache License 2.0
216 stars 48 forks source link

Integrate ANTLR runtime tests #170

Open lppedd opened 5 months ago

lppedd commented 5 months ago

Given we want to switch from Maven to Gradle in ANTLR 5, we could use this repository to experiment since it's already Gradle-based.

I had already started looking at how to do it in a multiplatform way.
There is a major issue into that: tests are created dynamically.

If my understanding is correct, what happens is the JUnit test factory uses test descriptors - a bunch of textual files containing various sections - to initialize grammars, inputs, and outputs for each test case.

kotlin.Test does not offer anything like that, but we could move to Kotest's test factories.
However at this time, Kotest does not support the wasmJs target, and its integration with the IDE is limited.

@ftomassetti @KvanTTT

KvanTTT commented 5 months ago

Why is it not possible to use existing descriptors with JUnit? We can just write another KotlinWasmRunner like current KotlinRunner.

lppedd commented 5 months ago

That testing code is a bit convoluted. It's been done like that to support multiple targets obviously, but if we can find a better and more integrated way of performing multiplatform tests, I guess it's something we can try here.

Also, I'm not sure how it would work with K/WASM (or even K/JS). Will it perform any DCE? Will the symbol names be retained or mangled? Will we be able to call the WASM functions using a custom JS entry point, or how will we do it?

KvanTTT commented 5 months ago

Also, I'm not sure how it would work with K/WASM (or even K/JS). Will it perform any DCE? Will the symbol names be retained or mangled? Will we be able to call the WASM functions using a custom JS entry point, or how will we do it?

I'm also not experienced in the Kotlin Wasm topic, so investigation is required.

lppedd commented 5 months ago

That's also why I'd like to use something that works out of the box.

Probably a mix of Gradle tasks to read descriptors and KotlinPoet to generate the test files/functions will do the trick. Using kotlin.Test might be enough.

K/WASM and K/JS have limited to none reflection capabilities.

lppedd commented 5 months ago

I've seen @mike-lischke published a new utility called antlr-tgen.

It looks look we could use it to run the runtime tests on this repo.

mike-lischke commented 5 months ago

I've seen @mike-lischke published a new utility called antlr-tgen.

It looks look we could use it to run the runtime tests on this repo.

Not as it is right now. The generator uses antlr4ng-cli to generate parsers from grammars (after they have been generated with antlr-tgen) and antlr4ng-cli uses a custom build of the ANTLR4 jar (with my TS support built in). So it cannot generate Kotlin code as it is. But maybe you can generate the Java variant of the tests and then convert them to Kotlin? The tests don't change often, so it's probably fine to keep the once-generated tests (I do that also for the TS runtime).

Alternatively, we can work to add an ANTLR4 jar that supports Kotlin to the generation process (by updating antlr4ng-cli). But from what I see Kotlin is not an official runtime for ANTLR4 (otherwise I could just pull the repo and regenerate the jar), so it's not clear if that's worth the effort (compared to generating the Java tests and manually convert them to Kotlin).

lppedd commented 5 months ago

@mike-lischke thanks for the clarification.

I thought that because you allow using arbitrary template files to generate the test cases, it could work with custom Kotlin ones.

The generation process is controlled by 2 template files (written in StringTemplate4 syntax), which control the grammar generation from the descriptors and how the final test file looks like

To address this

The generator uses antlr4ng-cli to generate parsers from grammars

I don't really need this step. Once antlr-tgen has outputted the .g4 files, I can run another Gradle task to generate the Kotlin classes.

mike-lischke commented 5 months ago

I thought that because you allow using arbitrary template files to generate the test cases, it could work with custom Kotlin ones.

Yes, but there are 2 steps at work here:

You can certainly use antlr-tgen for the first step, when you provide the 2 stg files (and use any known target language in the configuration file). It will still generate parsers (because that's not optimal, maybe I should allow to skip this step?), but you can ignore the generated files and generate them again with your toolchain.

lppedd commented 5 months ago

It will still generate parsers (because that's not optimal, maybe I should allow to skip this step?), but you can ignore the generated files and generate them again with your toolchain.

Looks like allowing opting out from the second step would be a good addition.
I think we can make it work with Kotlin after all.

In the config file there is a property for the language name:

"language": "Kotlin",

Is that used by antlr4ng-cli to determine how to generate parsers/lexers?

mike-lischke commented 5 months ago

In the config file there is a property for the language name:

"language": "Kotlin",

Is that used by antlr4ng-cli to determine how to generate parsers/lexers?

Yes, that's the language used for the parser generation. Use any language there or manually replace the antlr jar with yours (which supports Kotlin) and let it run with that.