From 4fc138b21c789aea0347cff8dc0564a9c229f6d5 Mon Sep 17 00:00:00 2001 From: Apehum Date: Sat, 6 Apr 2024 21:49:47 +0800 Subject: [PATCH] feat: java field parsing in annotations --- .../plugin/GenerateLoadersEntryPointsTask.kt | 4 +-- .../su/plo/voice/plugin/parser/AddonParser.kt | 2 +- .../su/plo/voice/plugin/parser/FieldParser.kt | 30 +++++++++++++++++++ .../voice/plugin/parser/JavaAddonParser.kt | 13 ++++++-- .../voice/plugin/parser/KotlinAddonParser.kt | 13 ++++++-- .../kotlin/su/plo/voice/plugin/util/addon.kt | 8 ++--- 6 files changed, 57 insertions(+), 13 deletions(-) create mode 100644 src/main/kotlin/su/plo/voice/plugin/parser/FieldParser.kt diff --git a/src/main/kotlin/su/plo/voice/plugin/GenerateLoadersEntryPointsTask.kt b/src/main/kotlin/su/plo/voice/plugin/GenerateLoadersEntryPointsTask.kt index 7d667fa..b5aac7c 100644 --- a/src/main/kotlin/su/plo/voice/plugin/GenerateLoadersEntryPointsTask.kt +++ b/src/main/kotlin/su/plo/voice/plugin/GenerateLoadersEntryPointsTask.kt @@ -31,11 +31,11 @@ open class GenerateLoadersEntryPointsTask : DefaultTask() { val sourceFiles = HashSet(mainSourceSet.java.sourceDirectories.asFileTree.files) .plus(kotlinMainSourceSet.kotlin.sourceDirectories.asFileTree.files) - val addons = sourceFiles.mapNotNull { it.parseAddonMeta() } + val addons = sourceFiles.mapNotNull { it.parseAddonMeta(sourceFiles) } if (addons.isEmpty()) return AddonEntryPoint.processAddons(project, addons) - File(project.buildDir, CACHE_FILE_PATH).writeText("") +// File(project.buildDir, CACHE_FILE_PATH).writeText("") } companion object { diff --git a/src/main/kotlin/su/plo/voice/plugin/parser/AddonParser.kt b/src/main/kotlin/su/plo/voice/plugin/parser/AddonParser.kt index a120d6a..405c962 100644 --- a/src/main/kotlin/su/plo/voice/plugin/parser/AddonParser.kt +++ b/src/main/kotlin/su/plo/voice/plugin/parser/AddonParser.kt @@ -5,5 +5,5 @@ import java.io.File interface AddonParser { - fun parseAddon(file: File): AddonMeta? + fun parseAddon(sourceFiles: Collection, file: File): AddonMeta? } diff --git a/src/main/kotlin/su/plo/voice/plugin/parser/FieldParser.kt b/src/main/kotlin/su/plo/voice/plugin/parser/FieldParser.kt new file mode 100644 index 0000000..a43bd0e --- /dev/null +++ b/src/main/kotlin/su/plo/voice/plugin/parser/FieldParser.kt @@ -0,0 +1,30 @@ +package su.plo.voice.plugin.parser + +import com.github.javaparser.StaticJavaParser +import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration +import java.io.File +import kotlin.jvm.optionals.getOrNull + +fun parseStringField(sourceFiles: Collection, className: String, fieldName: String): String { + sourceFiles.forEach { file -> + val fileName = file.name + + if (fileName.endsWith(".java")) { + val parsedFile = StaticJavaParser.parse(file) + + val foundClass = parsedFile.childNodes + .filterIsInstance() + .firstOrNull { it.nameAsString == className } + ?: return@forEach + + val field = foundClass.getFieldByName(fieldName).getOrNull() ?: return@forEach + + return field.getVariable(0).initializer.get().asStringLiteralExpr().asString() + } +// else if (fileName.endsWith(".kt")) { +// +// } + } + + throw IllegalStateException("Field $fieldName in $className not found") +} diff --git a/src/main/kotlin/su/plo/voice/plugin/parser/JavaAddonParser.kt b/src/main/kotlin/su/plo/voice/plugin/parser/JavaAddonParser.kt index 7efb6f7..903b559 100644 --- a/src/main/kotlin/su/plo/voice/plugin/parser/JavaAddonParser.kt +++ b/src/main/kotlin/su/plo/voice/plugin/parser/JavaAddonParser.kt @@ -10,7 +10,7 @@ import java.io.File object JavaAddonParser : AddonParser { - override fun parseAddon(file: File): AddonMeta? { + override fun parseAddon(sourceFiles: Collection, file: File): AddonMeta? { val parsedFile = try { StaticJavaParser.parse(file) // todo: "Text Block Literals are not supported." Just skip for now, but it can be a problem with modern java code @@ -25,6 +25,7 @@ object JavaAddonParser : AddonParser { .getOrNull(0) ?: return@forEach return parseAddon( + sourceFiles, addonAnnotation, parsedFile.packageDeclaration.get().nameAsString + "." + node.nameAsString ) @@ -34,7 +35,7 @@ object JavaAddonParser : AddonParser { } } -private fun parseAddon(addonAnnotation: AnnotationExpr, entryPoint: String): AddonMeta { +private fun parseAddon(sourceFiles: Collection, addonAnnotation: AnnotationExpr, entryPoint: String): AddonMeta { var id: String? = null var name: String? = null var loaderScope: AddonLoaderScope? = null @@ -62,7 +63,13 @@ private fun parseAddon(addonAnnotation: AnnotationExpr, entryPoint: String): Add } "version" -> { - version = (annotationNode.value as StringLiteralExpr).asString() + version = if (annotationNode.value.isFieldAccessExpr) { + val fieldAccess = annotationNode.value.asFieldAccessExpr() + + parseStringField(sourceFiles, fieldAccess.scope.toString(), fieldAccess.nameAsString) + } else { + (annotationNode.value as StringLiteralExpr).asString() + } } "license" -> { diff --git a/src/main/kotlin/su/plo/voice/plugin/parser/KotlinAddonParser.kt b/src/main/kotlin/su/plo/voice/plugin/parser/KotlinAddonParser.kt index 4286cc5..ee8010b 100644 --- a/src/main/kotlin/su/plo/voice/plugin/parser/KotlinAddonParser.kt +++ b/src/main/kotlin/su/plo/voice/plugin/parser/KotlinAddonParser.kt @@ -16,7 +16,7 @@ import java.io.File object KotlinAddonParser : AddonParser { - override fun parseAddon(file: File): AddonMeta? { + override fun parseAddon(sourceFiles: Collection, file: File): AddonMeta? { val source = AstSource.File(file.absolutePath.toString()) val ast = KotlinGrammarAntlrKotlinParser.parseKotlinFile(source) @@ -40,6 +40,7 @@ object KotlinAddonParser : AddonParser { .getOrNull(0) ?: return@forEach return parseAddon( + sourceFiles, addonAnnotation, packageName!! + "." + astFile.identifier!!.identifier ) @@ -48,7 +49,7 @@ object KotlinAddonParser : AddonParser { return null } - private fun parseAddon(addonAnnotation: KlassAnnotation, entryPoint: String): AddonMeta? { + private fun parseAddon(sourceFiles: Collection, addonAnnotation: KlassAnnotation, entryPoint: String): AddonMeta? { var id: String? = null var name: String? = null var loaderScope: AddonLoaderScope? = null @@ -78,7 +79,13 @@ object KotlinAddonParser : AddonParser { } "version" -> { - version = getString(expression) + version = if (expression is KlassIdentifier) { + val terminals = findChild(expression, DefaultAstTerminal::class.java) + + parseStringField(sourceFiles, expression.identifier, terminals[1].text) + } else { + getString(expression) + } } "license" -> { diff --git a/src/main/kotlin/su/plo/voice/plugin/util/addon.kt b/src/main/kotlin/su/plo/voice/plugin/util/addon.kt index ae1befa..0f00543 100644 --- a/src/main/kotlin/su/plo/voice/plugin/util/addon.kt +++ b/src/main/kotlin/su/plo/voice/plugin/util/addon.kt @@ -5,15 +5,15 @@ import su.plo.voice.plugin.parser.JavaAddonParser import su.plo.voice.plugin.parser.KotlinAddonParser import java.io.File -fun File.parseAddonMeta() = parseAddon(this) +fun File.parseAddonMeta(sourceFiles: Collection) = parseAddon(sourceFiles, this) -private fun parseAddon(file: File): AddonMeta? { +private fun parseAddon(sourceFiles: Collection, file: File): AddonMeta? { val fileName = file.name if (fileName.endsWith(".java")) { - return JavaAddonParser.parseAddon(file) + return JavaAddonParser.parseAddon(sourceFiles, file) } else if (fileName.endsWith(".kt")) { - return KotlinAddonParser.parseAddon(file) + return KotlinAddonParser.parseAddon(sourceFiles, file) } return null