Skip to content

Instantly share code, notes, and snippets.

@socar-dorma
Created June 8, 2021 05:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save socar-dorma/306453fafc0383869f62adf31cfaba0c to your computer and use it in GitHub Desktop.
Save socar-dorma/306453fafc0383869f62adf31cfaba0c to your computer and use it in GitHub Desktop.
kotlin psi으로 공통코드 파싱하기
val contentFromFile = """
object Codes {
// ... other codes ...
enum class SettlementType(val label: String, val value: String) {
AUTO("자동", "STLTP_AUTO"),
MANUAL("수동", "STLTP_MANUAL");
companion object {
fun getByValue(value: String): SettlementType? = values().find { it.value == value }
}
}
// ... other codes ...
}
"""
val disposable = Disposer.newDisposable()
try {
val script = contentFromFile;
val configuration = CompilerConfiguration()
val groupingCollector = GroupingMessageCollector(CodeMessageCollector(), false)
val severityCollector = GroupingMessageCollector(groupingCollector, false)
configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, severityCollector)
val env = KotlinCoreEnvironment.createForProduction(disposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
val lvFile = LightVirtualFile("Codes.kt", KotlinFileType.INSTANCE, script)
val ktFile = PsiManager.getInstance(env.project).findFile(lvFile) as KtFile
val codesObject = ktFile.findChildByClass(KtObjectDeclaration::class.java)
var codes: List<Pair<String, List<Pair<String, Map<String, String>>>>>? = null
if (codesObject is KtObjectDeclaration) {
val codeBody = codesObject.children.find { it is KtClassBody }
if (codeBody is KtClassBody) {
codes = codeBody.children.mapNotNull { enumClass ->
if (enumClass is KtClass) {
val parameterMap = mutableMapOf<Int, String>()
enumClass.getPrimaryConstructorParameterList()?.children?.forEachIndexed { index, param ->
if (param is KtParameter) {
parameterMap[index] = param.name!!
}
}
val name = enumClass.name!!.decapitalize()
val entries = enumClass.declarations.mapIndexedNotNull { index, item ->
if (item is KtEnumEntry) {
var value = ""
var label = ""
item.initializerList?.firstChild?.children?.forEach { params ->
params?.children?.forEachIndexed { i, param ->
if (param is KtValueArgument) {
// println("param.name - ${param.getArgumentName()}, param.text - ${param.text}")
when (parameterMap[i]) {
"label" -> label = param.text.trimQuotes()
"value" -> value = param.text.trimQuotes()
else -> throw IllegalStateException("unknown name - $name")
}
}
}
}
item.name!! to mapOf("value" to value, "label" to label)
} else null
}
name to entries
} else null
}
}
}
codes?.let {
// TODO: write javascript(or typescript) file
} ?: throw IllegalStateException("please check Codes.kt file.")
} catch (e: Exception) {
e.printStackTrace()
} finally {
disposable.dispose()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment