package dev.fileworkbench.testing import com.intellij.openapi.util.Disposer import com.intellij.psi.PsiErrorElement import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.psi.KtPsiFactory import java.io.File /** Syntax only. This deliberately does not claim Android/Compose symbol or Gradle verification. */ fun main(args: Array) { val root = File(args.firstOrNull() ?: ".").canonicalFile val disposable = Disposer.newDisposable() try { val environment = KotlinCoreEnvironment.createForProduction(disposable, CompilerConfiguration(), EnvironmentConfigFiles.JVM_CONFIG_FILES) val factory = KtPsiFactory(environment.project, false) var files = 0 var errors = 0 root.walkTopDown().onEnter { it.name !in setOf("build", "out", ".gradle", ".git") } .filter { it.isFile && (it.extension == "kt" || it.extension == "kts") }.forEach { source -> files++ val text = source.readText() val parsed = factory.createFile(source.name, text) PsiTreeUtil.findChildrenOfType(parsed, PsiErrorElement::class.java).forEach { errors++ val line = text.take(it.textOffset).count { c -> c == '\n' } + 1 println("FAIL ${source.relativeTo(root)}:$line ${it.errorDescription}") } } println("Kotlin PSI syntax: $files files, $errors parse errors. Android/Compose type resolution is NOT tested.") check(errors == 0) } finally { Disposer.dispose(disposable) } }