diff --git a/build.gradle.kts b/build.gradle.kts index 082cfb6..1efe6b7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -25,6 +25,7 @@ repositories { // Dependencies are managed with Gradle version catalog - read more: https://docs.gradle.org/current/userguide/platforms.html#sub:version-catalog dependencies { + implementation(libs.serialization) } // Set the JVM language level used to build the project. diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 49f30b4..d2b7cf1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,10 +1,14 @@ [versions] kotlin = "1.9.24" +serialization = "1.6.3" changelog = "2.2.0" gradleIntelliJPlugin = "1.17.3" qodana = "2024.1.5" kover = "0.8.0" +[libraries] +serialization = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "serialization" } + [plugins] changelog = { id = "org.jetbrains.changelog", version.ref = "changelog" } gradleIntelliJPlugin = { id = "org.jetbrains.intellij", version.ref = "gradleIntelliJPlugin" } diff --git a/src/main/kotlin/com/github/warningimhack3r/intellijshadcnplugin/backend/sources/Source.kt b/src/main/kotlin/com/github/warningimhack3r/intellijshadcnplugin/backend/sources/Source.kt index 31023c0..e4dd978 100644 --- a/src/main/kotlin/com/github/warningimhack3r/intellijshadcnplugin/backend/sources/Source.kt +++ b/src/main/kotlin/com/github/warningimhack3r/intellijshadcnplugin/backend/sources/Source.kt @@ -22,6 +22,17 @@ import java.net.URI import java.nio.file.NoSuchFileException abstract class Source(val project: Project, private val serializer: KSerializer) { + companion object { + private val tsConfigJson = Json { + // Lax parsing (unquoted keys, formatting, etc.) + isLenient = true + // Allow trailing commas +// allowTrailingCommas = true + // Allow comments +// allowComments = true + } + } + private val log = logger>() private var config: C? = null @@ -94,6 +105,21 @@ abstract class Source(val project: Project, private val serializer: protected open fun adaptFileExtensionToConfig(extension: String): String = extension + protected fun parseTsConfig(config: String): JsonElement { + // Temporary workaround until kotlinx.serialization is upgraded + val cleanConfig = config + // Remove /* */ comments + .replace(Regex("/\\*.*?\\*/", RegexOption.DOT_MATCHES_ALL), "") + .split("\n").joinToString("\n") { line -> + // Remove // comments + line.substringBefore("//").trim() + } + // Remove trailing commas + .replace(Regex(",\\s*}"), "\n}") + .replace(Regex(",\\s*]"), "\n]") + return tsConfigJson.parseToJsonElement(cleanConfig) + } + protected abstract fun adaptFileToConfig(file: PsiFile) protected open fun fetchComponent(componentName: String): ComponentWithContents { diff --git a/src/main/kotlin/com/github/warningimhack3r/intellijshadcnplugin/backend/sources/impl/ReactSource.kt b/src/main/kotlin/com/github/warningimhack3r/intellijshadcnplugin/backend/sources/impl/ReactSource.kt index 81fae49..b5a53a7 100644 --- a/src/main/kotlin/com/github/warningimhack3r/intellijshadcnplugin/backend/sources/impl/ReactSource.kt +++ b/src/main/kotlin/com/github/warningimhack3r/intellijshadcnplugin/backend/sources/impl/ReactSource.kt @@ -39,7 +39,7 @@ open class ReactSource(project: Project) : Source(project, ReactCon val configFile = if (getLocalConfig().tsx) "tsconfig.json" else "jsconfig.json" val tsConfig = FileManager(project).getFileContentsAtPath(configFile) ?: throw NoSuchFileException("$configFile not found") - val aliasPath = Json.parseToJsonElement(tsConfig) + val aliasPath = parseTsConfig(tsConfig) .jsonObject["compilerOptions"] ?.jsonObject?.get("paths") ?.jsonObject?.get("${alias.substringBefore("/")}/*") diff --git a/src/main/kotlin/com/github/warningimhack3r/intellijshadcnplugin/backend/sources/impl/SolidSource.kt b/src/main/kotlin/com/github/warningimhack3r/intellijshadcnplugin/backend/sources/impl/SolidSource.kt index eea851f..b0b31ae 100644 --- a/src/main/kotlin/com/github/warningimhack3r/intellijshadcnplugin/backend/sources/impl/SolidSource.kt +++ b/src/main/kotlin/com/github/warningimhack3r/intellijshadcnplugin/backend/sources/impl/SolidSource.kt @@ -44,7 +44,7 @@ open class SolidSource(project: Project) : Source(project, SolidCon val configFile = "tsconfig.json" val tsConfig = FileManager(project).getFileContentsAtPath(configFile) ?: throw NoSuchFileException("$configFile not found") - val aliasPath = Json.parseToJsonElement(tsConfig) + val aliasPath = parseTsConfig(tsConfig) .jsonObject["compilerOptions"] ?.jsonObject?.get("paths") ?.jsonObject?.get("${alias.substringBefore("/")}/*") diff --git a/src/main/kotlin/com/github/warningimhack3r/intellijshadcnplugin/backend/sources/impl/SolidUISource.kt b/src/main/kotlin/com/github/warningimhack3r/intellijshadcnplugin/backend/sources/impl/SolidUISource.kt index 531b0f3..a621321 100644 --- a/src/main/kotlin/com/github/warningimhack3r/intellijshadcnplugin/backend/sources/impl/SolidUISource.kt +++ b/src/main/kotlin/com/github/warningimhack3r/intellijshadcnplugin/backend/sources/impl/SolidUISource.kt @@ -10,7 +10,6 @@ import com.intellij.openapi.application.runReadAction import com.intellij.openapi.diagnostic.logger import com.intellij.openapi.project.Project import com.intellij.psi.PsiFile -import kotlinx.serialization.json.Json import kotlinx.serialization.json.jsonArray import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonPrimitive @@ -40,7 +39,7 @@ open class SolidUISource(project: Project) : Source(project, Soli val configFile = if (getLocalConfig().tsx) "tsconfig.json" else "jsconfig.json" val tsConfig = FileManager(project).getFileContentsAtPath(configFile) ?: throw NoSuchFileException("$configFile not found") - val aliasPath = Json.parseToJsonElement(tsConfig) + val aliasPath = parseTsConfig(tsConfig) .jsonObject["compilerOptions"] ?.jsonObject?.get("paths") ?.jsonObject?.get("${alias.substringBefore("/")}/*") diff --git a/src/main/kotlin/com/github/warningimhack3r/intellijshadcnplugin/backend/sources/impl/SvelteSource.kt b/src/main/kotlin/com/github/warningimhack3r/intellijshadcnplugin/backend/sources/impl/SvelteSource.kt index 2ec676f..75b4bb6 100644 --- a/src/main/kotlin/com/github/warningimhack3r/intellijshadcnplugin/backend/sources/impl/SvelteSource.kt +++ b/src/main/kotlin/com/github/warningimhack3r/intellijshadcnplugin/backend/sources/impl/SvelteSource.kt @@ -57,7 +57,7 @@ open class SvelteSource(project: Project) : Source(project, Svelte tsConfig = fileManager.getFileContentsAtPath(configFile) ?: throw NoSuchFileException("Cannot get $configFile") } - val aliasPath = Json.parseToJsonElement(tsConfig) + val aliasPath = parseTsConfig(tsConfig) .jsonObject["compilerOptions"] ?.jsonObject?.get("paths") ?.jsonObject?.get(alias.substringBefore("/")) diff --git a/src/main/kotlin/com/github/warningimhack3r/intellijshadcnplugin/backend/sources/impl/VueSource.kt b/src/main/kotlin/com/github/warningimhack3r/intellijshadcnplugin/backend/sources/impl/VueSource.kt index c21e202..1c40d1f 100644 --- a/src/main/kotlin/com/github/warningimhack3r/intellijshadcnplugin/backend/sources/impl/VueSource.kt +++ b/src/main/kotlin/com/github/warningimhack3r/intellijshadcnplugin/backend/sources/impl/VueSource.kt @@ -38,11 +38,7 @@ open class VueSource(project: Project) : Source(project, VueConfig.se } fun resolvePath(configFile: String): String? { - return Json.parseToJsonElement(configFile - .split("\n") - .filterNot { it.trim().startsWith("//") } // remove comments - .joinToString("\n") - ) + return parseTsConfig(configFile) .jsonObject["compilerOptions"] ?.jsonObject?.get("paths") ?.jsonObject?.get("${alias.substringBefore("/")}/*")