Strumenta / antlr-kotlin

Support for Kotlin as a target for ANTLR 4
Apache License 2.0
222 stars 47 forks source link

Running the js unit tests fails when builded by kotlin mpp #105

Closed radish001 closed 8 months ago

radish001 commented 11 months ago

Hello, I created a kotlin mpp project and used antlr-kotlin to generate lexer and parser. I implemented an addition expression using the visitor, and the jvm unit tests worked, but the js unit tests throw an exception。 build.gradle:

 plugins {
    kotlin("multiplatform") version "1.7.21"
    //id("kotlin2js") version "1.3.21"

}

val antlr_kotlin_version = "master-SNAPSHOT"

buildscript {
    val antlr_kotlin_version = "master-SNAPSHOT"
    dependencies {
        // add the plugin to the classpath
        classpath("com.strumenta.antlr-kotlin:antlr-kotlin-gradle-plugin:$antlr_kotlin_version")
    }
}

group = "me.goal"
version = "1.0-SNAPSHOT"

repositories {
    mavenLocal()
    jcenter()

    maven {
        setUrl("https://jitpack.io")
    }
    maven {
        setUrl("https://maven.aliyun.com/repository/public")
    }
    maven {
        setUrl("https://maven.aliyun.com/repository/central")
    }
    maven {
        setUrl("https://maven.aliyun.com/repository/gradle-plugin")
    }
    maven {
        setUrl("https://plugins.gradle.org/m2/")
    }
    mavenCentral()
}

kotlin {
    jvm {
        compilations.all {
            kotlinOptions.jvmTarget = "1.8"
        }
        withJava()
        testRuns["test"].executionTask.configure {
            useJUnitPlatform()
        }
    }
    js(IR) {
        binaries.executable()
        browser {
            commonWebpackConfig {
                // cssSupport.enabled = true
            }
        }
        nodejs {

        }

    }

    sourceSets {
        val commonAntlr by creating {
            dependencies {
                api(kotlin("stdlib-common"))
                api("com.strumenta.antlr-kotlin:antlr-kotlin-runtime:$antlr_kotlin_version")

            }
            //kotlin.srcDir("build/generated-src/commonAntlr/kotlin")
        }

        val commonMain by getting {
            dependsOn(commonAntlr)
        }
        val commonTest by getting {

            dependencies {
                implementation(kotlin("test"))
            }
        }
        val jvmMain by getting {
            dependencies {
                api(kotlin("stdlib-jdk8"))
                api(kotlin("reflect"))
            }
        }
        val jvmTest by getting {
            dependencies {
                implementation(kotlin("test"))
            }
        }
        val jsMain by getting {
            dependencies {
                implementation(npm("base-64", "1.0.0"))
                implementation("com.strumenta.antlr-kotlin:antlr-kotlin-runtime-js:$antlr_kotlin_version")
                implementation("org.jetbrains.kotlin:kotlin-stdlib-common:1.7.21")
                implementation("org.jetbrains.kotlin:kotlin-stdlib-js:1.7.21")
            }
        }
        val jsTest by getting
    }
}

tasks.register<com.strumenta.antlrkotlin.gradleplugin.AntlrKotlinTask>("generateKotlinCommonGrammarSource") {

    antlrClasspath = configurations.detachedConfiguration(
        project.dependencies.create("com.strumenta.antlr-kotlin:antlr-kotlin-target:$antlr_kotlin_version")
    )
    maxHeapSize = "1024m"
    packageName = "com.strumenta.antlrkotlin.examples"
    //arguments = listOf("-no-visitor", "-no-listener")
    source = project.objects
        .sourceDirectorySet("antlr", "antlr")
        .srcDir("src/commonAntlr/resources").apply {
            include("*.g4")
        }

    outputDirectory = File("build/generated-src/commonAntlr/kotlin")

}

my unit test:

   @Test
    fun test(){
        val expr = "1+2"
        val inputStream : CharStream = ANTLRInputStream(expr)
        val lexer: CalculatorLexer = CalculatorLexer(inputStream)
        val tokenStream : CommonTokenStream = CommonTokenStream(lexer)
        val parser: CalculatorParser = CalculatorParser(tokenStream)
        parser.buildParseTree = true
        val root: CalculatorParser.ProgContext = parser.prog()
        val vistor: CalculatorBaseVisitor<Int> = CalculatorVistorImp()
        val res: Int? = vistor.visit(root)
        println(res)
    }

exception thrown by a js unit test as follow:

ClassCastException
    at <global>.THROW_CCE(/var/folders/qj/hf2rrhzn1fn3tfx_1tmnyd0r0000gn/T/_karma_webpack_631229/commons.js:34724)
    at Lexer.readInputStream_cn8ozw(/var/folders/qj/hf2rrhzn1fn3tfx_1tmnyd0r0000gn/T/_karma_webpack_631229/commons.js:1870)
    at Lexer.nextToken_jykgjq(/var/folders/qj/hf2rrhzn1fn3tfx_1tmnyd0r0000gn/T/_karma_webpack_631229/commons.js:2029)
    at BufferedTokenStream.fetch_es1drt(/var/folders/qj/hf2rrhzn1fn3tfx_1tmnyd0r0000gn/T/_karma_webpack_631229/commons.js:843)
    at BufferedTokenStream.sync_o63rt2(/var/folders/qj/hf2rrhzn1fn3tfx_1tmnyd0r0000gn/T/_karma_webpack_631229/commons.js:829)
    at BufferedTokenStream.setup_2uql04(/var/folders/qj/hf2rrhzn1fn3tfx_1tmnyd0r0000gn/T/_karma_webpack_631229/commons.js:915)
    at BufferedTokenStream.lazyInit_ml29bh(/var/folders/qj/hf2rrhzn1fn3tfx_1tmnyd0r0000gn/T/_karma_webpack_631229/commons.js:911)
    at CommonTokenStream.LT_6crwc9(/var/folders/qj/hf2rrhzn1fn3tfx_1tmnyd0r0000gn/T/_karma_webpack_631229/commons.js:1397)
    at Parser.enterRule_khu8i(/var/folders/qj/hf2rrhzn1fn3tfx_1tmnyd0r0000gn/T/_karma_webpack_631229/commons.js:2491)
    at CalculatorParser.prog_21xsq(/var/folders/qj/hf2rrhzn1fn3tfx_1tmnyd0r0000gn/T/_karma_webpack_631229/commons.js:15996)

It looks like the following code throw the exception:

Lexer.prototype.readInputStream_cn8ozw_k$ = function () {
    var tmp = this.inputStream_1;
    return (tmp == null ? true : isInterface(tmp, CharStream)) ? tmp : THROW_CCE();
  };

The "isInterface(tmp, CharStream)" function throw the exception.

How do I fix this, since this is my first time using kotlin mpp and antlr. @ftomassetti

ftomassetti commented 11 months ago

hi @radish001 sorry but at the moment I am unable to help on this

lppedd commented 9 months ago

Once the runtime cleanup PR is merged and a new version is published, be sure to update Kotlin to 1.9.21. The issue should be gone entirely.

ftomassetti commented 8 months ago

As pointed out by @lppedd the problem should now be solved