From ead98a3249f32481dd31ffaedb1ccfe65c961171 Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Thu, 10 Apr 2025 15:46:07 +0200 Subject: [PATCH] IJPL-162853 introduce a script for converting a message bundle to a kotlin class GitOrigin-RevId: d00ed622cc312ca6f37ebc3ab043b4eed170a191 --- .idea/modules.xml | 1 + .../syntax-scripts/api-dump-experimental.txt | 3 + platform/syntax/syntax-scripts/api-dump.txt | 0 .../intellij.platform.syntax.scripts.iml | 13 +++ .../syntax/scripts/generateBundleMapping.kt | 88 +++++++++++++++++++ 5 files changed, 105 insertions(+) create mode 100644 platform/syntax/syntax-scripts/api-dump-experimental.txt create mode 100644 platform/syntax/syntax-scripts/api-dump.txt create mode 100644 platform/syntax/syntax-scripts/intellij.platform.syntax.scripts.iml create mode 100644 platform/syntax/syntax-scripts/src/com/intellij/platform/syntax/scripts/generateBundleMapping.kt diff --git a/.idea/modules.xml b/.idea/modules.xml index 7043736145a7..a48076ea4f3f 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -894,6 +894,7 @@ + diff --git a/platform/syntax/syntax-scripts/api-dump-experimental.txt b/platform/syntax/syntax-scripts/api-dump-experimental.txt new file mode 100644 index 000000000000..75e04b903bbf --- /dev/null +++ b/platform/syntax/syntax-scripts/api-dump-experimental.txt @@ -0,0 +1,3 @@ +*f:com.intellij.platform.syntax.scripts.GenerateBundleMappingKt +- sf:generateMapping(java.lang.String,java.lang.String,java.lang.String):V +- sf:main(java.lang.String[]):V diff --git a/platform/syntax/syntax-scripts/api-dump.txt b/platform/syntax/syntax-scripts/api-dump.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/platform/syntax/syntax-scripts/intellij.platform.syntax.scripts.iml b/platform/syntax/syntax-scripts/intellij.platform.syntax.scripts.iml new file mode 100644 index 000000000000..122f4d43124d --- /dev/null +++ b/platform/syntax/syntax-scripts/intellij.platform.syntax.scripts.iml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/platform/syntax/syntax-scripts/src/com/intellij/platform/syntax/scripts/generateBundleMapping.kt b/platform/syntax/syntax-scripts/src/com/intellij/platform/syntax/scripts/generateBundleMapping.kt new file mode 100644 index 000000000000..08b77a5db67a --- /dev/null +++ b/platform/syntax/syntax-scripts/src/com/intellij/platform/syntax/scripts/generateBundleMapping.kt @@ -0,0 +1,88 @@ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +@file: ApiStatus.Experimental + +package com.intellij.platform.syntax.scripts + +import org.jetbrains.annotations.ApiStatus +import java.io.OutputStreamWriter +import java.nio.file.Path +import java.util.* +import kotlin.io.path.* +import kotlin.system.exitProcess + +/** + * Generates a Kotlin class from your .properties file. This file is necessary for non-JVM targets where Java PropertyResourceBundles are not available. + */ +fun main(args: Array) { + if (args.size != 3) { + println(""" + |Please pass 3 arguments: + | 1. the path to .properties file + | 2. the path to the output file as arguments + | 3. the package name to use + |""".trimMargin()) + exitProcess(-1) + } + + generateMapping(args[0], args[1], args[2]) +} + +fun generateMapping( + properties: String, + output: String, + packageName: String, +) { + val propertiesPath = Path(properties) + if (!propertiesPath.exists()) { + println(".properties file does not exist! Path: $propertiesPath") + exitProcess(-1) + } + + val outputPath = Path(output) + if (!outputPath.exists()) { + outputPath.createFile() + } + + val mappings = loadMappings(propertiesPath) + + val fileName = outputPath.nameWithoutExtension + outputPath.writer().use { writer -> + writer.printClass(fileName, packageName, mappings, "$properties $output $packageName") + } +} + +private fun OutputStreamWriter.printClass( + className: String, + packageName: String, + mappings: Map, + parametersString: String, +) { + appendLine("package $packageName") + appendLine() + appendLine("// Generated by generateBundleMapping.kt") + appendLine("// To regenerate the file, please run `GenerateBundleMapping` run configuration with the following parameters: ") + appendLine("// $parametersString ") + appendLine("internal object $className {") + appendLine(" val mappings: Map = mapOf(") + for ((key, value) in mappings.entries) { + val escapedValue = value + .replace("\\", "\\\\") + .replace("\n", "\\n") + .replace("\r", "\\r") + .replace("\t", "\\t") + appendLine(" \"$key\" to \"$escapedValue\",") + } + appendLine(" )") + appendLine('}') +} + +private fun loadMappings(propertiesPath: Path): Map { + val properties = Properties() + propertiesPath.inputStream().use { stream -> + properties.load(stream) + } + + return properties.entries.associate { (key, value) -> + (key as String) to (value as String) + } +}