From 4bfe0571994b7bdd884d118539b68b8bbbe48319 Mon Sep 17 00:00:00 2001 From: Cal Date: Sat, 8 Jun 2024 15:09:42 +1000 Subject: [PATCH 1/6] Backend: Make build fail on wrong annotation --- .../skyhannimodule/ModuleProcessor.kt | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/annotation-processors/src/main/kotlin/at/hannibal2/skyhanni/skyhannimodule/ModuleProcessor.kt b/annotation-processors/src/main/kotlin/at/hannibal2/skyhanni/skyhannimodule/ModuleProcessor.kt index bc7d262b49d5..9bbc2b3f8560 100644 --- a/annotation-processors/src/main/kotlin/at/hannibal2/skyhanni/skyhannimodule/ModuleProcessor.kt +++ b/annotation-processors/src/main/kotlin/at/hannibal2/skyhanni/skyhannimodule/ModuleProcessor.kt @@ -1,5 +1,6 @@ package at.hannibal2.skyhanni.skyhannimodule +import com.google.devtools.ksp.getDeclaredFunctions import com.google.devtools.ksp.processing.CodeGenerator import com.google.devtools.ksp.processing.Dependencies import com.google.devtools.ksp.processing.KSPLogger @@ -8,13 +9,25 @@ import com.google.devtools.ksp.processing.SymbolProcessor import com.google.devtools.ksp.symbol.ClassKind import com.google.devtools.ksp.symbol.KSAnnotated import com.google.devtools.ksp.symbol.KSClassDeclaration +import com.google.devtools.ksp.symbol.KSType import com.google.devtools.ksp.validate import java.io.OutputStreamWriter class ModuleProcessor(private val codeGenerator: CodeGenerator, private val logger: KSPLogger) : SymbolProcessor { + // TODO remove once all events are migrated to SkyHanniEvent + private var skyHanniEvent: KSType? = null + private var minecraftForgeEvent: KSType? = null + override fun process(resolver: Resolver): List { + skyHanniEvent = + resolver.getClassDeclarationByName(resolver.getKSNameFromString("at.hannibal2.skyhanni.api.event.SkyHanniEvent")) + ?.asStarProjectedType() + minecraftForgeEvent = + resolver.getClassDeclarationByName(resolver.getKSNameFromString("net.minecraftforge.fml.common.eventhandler.Event")) + ?.asStarProjectedType() + val symbols = resolver.getSymbolsWithAnnotation(SkyHanniModule::class.qualifiedName!!).toList() val validSymbols = symbols.mapNotNull { validateSymbol(it) } @@ -41,9 +54,12 @@ class ModuleProcessor(private val codeGenerator: CodeGenerator, private val logg return null } + checkCorrectEventAnnotations(symbol) + return symbol } + // TODO use Kotlin Poet once KMixins is merged private fun generateFile(symbols: List) { val dependencies = symbols.mapNotNull { it.containingFile }.toTypedArray() val deps = Dependencies(true, *dependencies) @@ -65,4 +81,26 @@ class ModuleProcessor(private val codeGenerator: CodeGenerator, private val logg logger.warn("Generated LoadedModules file with ${symbols.size} modules") } + + // TODO remove once all events are migrated to SkyHanniEvent + private fun checkCorrectEventAnnotations(symbol: KSClassDeclaration) { + + for (function in symbol.getDeclaredFunctions()) { + if (function.annotations.any { it.shortName.asString() == "SubscribeEvent" }) { + val firstParameter = function.parameters.firstOrNull()?.type?.resolve() + isDeclarable(firstParameter!!, minecraftForgeEvent!!, "SubscribeEvent") + } + + if (function.annotations.any { it.shortName.asString() == "HandleEvent" }) { + val firstParameter = function.parameters.firstOrNull()?.type?.resolve() + isDeclarable(firstParameter!!, skyHanniEvent!!, "HandleEvent") + } + } + } + + private fun isDeclarable(parameterType: KSType, targetType: KSType, annotationType: String) { + if (!targetType.isAssignableFrom(parameterType)) { + error("Function parameter must be assignable from $targetType because it is annotated with @$annotationType") + } + } } From c7e770ef8ae4db96d066c6906363252f5f5a8372 Mon Sep 17 00:00:00 2001 From: Cal Date: Sat, 8 Jun 2024 15:15:41 +1000 Subject: [PATCH 2/6] test wrong annotation --- .../at/hannibal2/skyhanni/features/inventory/HarpFeatures.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/HarpFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/HarpFeatures.kt index 75b1d6ad3cd3..aaf41ac19fe3 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/HarpFeatures.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/HarpFeatures.kt @@ -1,7 +1,6 @@ package at.hannibal2.skyhanni.features.inventory import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.api.event.HandleEvent import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.events.GuiContainerEvent import at.hannibal2.skyhanni.events.GuiKeyPressEvent @@ -131,7 +130,7 @@ object HarpFeatures { unSetGUIScale() } - @HandleEvent + @SubscribeEvent fun onDisconnect(event: ClientDisconnectEvent) { if (!config.guiScale) return unSetGUIScale() From b8fdfb65b6075e8c4fcc70937fac4446ab4d22d5 Mon Sep 17 00:00:00 2001 From: Cal Date: Sat, 8 Jun 2024 15:24:33 +1000 Subject: [PATCH 3/6] improve error message --- .../skyhannimodule/ModuleProcessor.kt | 21 +++++++++++++++---- .../features/inventory/HarpFeatures.kt | 15 ++++++------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/annotation-processors/src/main/kotlin/at/hannibal2/skyhanni/skyhannimodule/ModuleProcessor.kt b/annotation-processors/src/main/kotlin/at/hannibal2/skyhanni/skyhannimodule/ModuleProcessor.kt index 9bbc2b3f8560..8a31af33724b 100644 --- a/annotation-processors/src/main/kotlin/at/hannibal2/skyhanni/skyhannimodule/ModuleProcessor.kt +++ b/annotation-processors/src/main/kotlin/at/hannibal2/skyhanni/skyhannimodule/ModuleProcessor.kt @@ -18,6 +18,7 @@ class ModuleProcessor(private val codeGenerator: CodeGenerator, private val logg // TODO remove once all events are migrated to SkyHanniEvent private var skyHanniEvent: KSType? = null private var minecraftForgeEvent: KSType? = null + private val warnings = mutableListOf() override fun process(resolver: Resolver): List { @@ -61,6 +62,12 @@ class ModuleProcessor(private val codeGenerator: CodeGenerator, private val logg // TODO use Kotlin Poet once KMixins is merged private fun generateFile(symbols: List) { + + if (warnings.isNotEmpty()) { + warnings.forEach { logger.warn(it) } + error("${warnings.size} errors related to event annotations found, please fix them before continuing") + } + val dependencies = symbols.mapNotNull { it.containingFile }.toTypedArray() val deps = Dependencies(true, *dependencies) @@ -88,19 +95,25 @@ class ModuleProcessor(private val codeGenerator: CodeGenerator, private val logg for (function in symbol.getDeclaredFunctions()) { if (function.annotations.any { it.shortName.asString() == "SubscribeEvent" }) { val firstParameter = function.parameters.firstOrNull()?.type?.resolve() - isDeclarable(firstParameter!!, minecraftForgeEvent!!, "SubscribeEvent") + isDeclarable(symbol, firstParameter!!, minecraftForgeEvent!!, "SubscribeEvent") } if (function.annotations.any { it.shortName.asString() == "HandleEvent" }) { val firstParameter = function.parameters.firstOrNull()?.type?.resolve() - isDeclarable(firstParameter!!, skyHanniEvent!!, "HandleEvent") + isDeclarable(symbol, firstParameter!!, skyHanniEvent!!, "HandleEvent") } } } - private fun isDeclarable(parameterType: KSType, targetType: KSType, annotationType: String) { + private fun isDeclarable( + clazz: KSClassDeclaration, + parameterType: KSType, + targetType: KSType, + annotationType: String + ) { if (!targetType.isAssignableFrom(parameterType)) { - error("Function parameter must be assignable from $targetType because it is annotated with @$annotationType") + val className = clazz.qualifiedName?.asString() ?: "unknown" + warnings.add("Function in $className must have the first parameter assignable from $targetType because it is annotated with @$annotationType") } } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/HarpFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/HarpFeatures.kt index aaf41ac19fe3..83344ac5319e 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/HarpFeatures.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/HarpFeatures.kt @@ -1,6 +1,7 @@ package at.hannibal2.skyhanni.features.inventory import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.api.event.HandleEvent import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.events.GuiContainerEvent import at.hannibal2.skyhanni.events.GuiKeyPressEvent @@ -57,7 +58,7 @@ object HarpFeatures { private fun isHarpGui(chestName: String) = inventoryTitlePattern.matches(chestName) private fun isMenuGui(chestName: String) = menuTitlePattern.matches(chestName) - @SubscribeEvent + @HandleEvent fun onGui(event: GuiKeyPressEvent) { if (!LorenzUtils.inSkyBlock) return if (!config.keybinds) return @@ -97,7 +98,7 @@ object HarpFeatures { private var openTime: SimpleTimeMark = SimpleTimeMark.farPast() - @SubscribeEvent + @HandleEvent fun onInventoryOpen(event: InventoryFullyOpenedEvent) { if (!LorenzUtils.inSkyBlock) return if (config.quickRestart && isMenuGui(event.inventoryName)) { @@ -123,7 +124,7 @@ object HarpFeatures { minecraft.currentScreen.setWorldAndResolution(minecraft, i, j) } - @SubscribeEvent + @HandleEvent fun onInventoryClose(event: InventoryCloseEvent) { if (!LorenzUtils.inSkyBlock) return if (!config.guiScale) return @@ -153,7 +154,7 @@ object HarpFeatures { isGUIScaled = false } - @SubscribeEvent + @HandleEvent fun onSlotClick(event: GuiContainerEvent.SlotClickEvent) { if (!LorenzUtils.inSkyBlock) return @@ -185,7 +186,7 @@ object HarpFeatures { } } - @SubscribeEvent + @HandleEvent fun onRenderItemTip(event: RenderItemTipEvent) { if (!LorenzUtils.inSkyBlock) return if (!config.showNumbers) return @@ -200,13 +201,13 @@ object HarpFeatures { event.stackTip = KeyboardManager.getKeyName(keyCode).take(3) } - @SubscribeEvent + @HandleEvent fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) { event.move(2, "misc.harpKeybinds", "inventory.helper.harp.keybinds") event.move(2, "misc.harpNumbers", "inventory.helper.harp.showNumbers") } - @SubscribeEvent + @HandleEvent fun onTooltip(event: LorenzToolTipEvent) { if (!LorenzUtils.inSkyBlock) return if (!config.hideMelodyTooltip) return From 73c20a0ca5f6785f1faaf40e7e1693b778a81757 Mon Sep 17 00:00:00 2001 From: Cal Date: Sat, 8 Jun 2024 15:36:18 +1000 Subject: [PATCH 4/6] a few small changes --- .../skyhannimodule/ModuleProcessor.kt | 56 ++++++++----------- 1 file changed, 22 insertions(+), 34 deletions(-) diff --git a/annotation-processors/src/main/kotlin/at/hannibal2/skyhanni/skyhannimodule/ModuleProcessor.kt b/annotation-processors/src/main/kotlin/at/hannibal2/skyhanni/skyhannimodule/ModuleProcessor.kt index 8a31af33724b..ecc564b1baa3 100644 --- a/annotation-processors/src/main/kotlin/at/hannibal2/skyhanni/skyhannimodule/ModuleProcessor.kt +++ b/annotation-processors/src/main/kotlin/at/hannibal2/skyhanni/skyhannimodule/ModuleProcessor.kt @@ -1,5 +1,6 @@ package at.hannibal2.skyhanni.skyhannimodule +import com.google.devtools.ksp.getClassDeclarationByName import com.google.devtools.ksp.getDeclaredFunctions import com.google.devtools.ksp.processing.CodeGenerator import com.google.devtools.ksp.processing.Dependencies @@ -23,11 +24,9 @@ class ModuleProcessor(private val codeGenerator: CodeGenerator, private val logg override fun process(resolver: Resolver): List { skyHanniEvent = - resolver.getClassDeclarationByName(resolver.getKSNameFromString("at.hannibal2.skyhanni.api.event.SkyHanniEvent")) - ?.asStarProjectedType() - minecraftForgeEvent = - resolver.getClassDeclarationByName(resolver.getKSNameFromString("net.minecraftforge.fml.common.eventhandler.Event")) - ?.asStarProjectedType() + resolver.getClassDeclarationByName("at.hannibal2.skyhanni.api.event.SkyHanniEvent")?.asStarProjectedType() + minecraftForgeEvent = resolver.getClassDeclarationByName("net.minecraftforge.fml.common.eventhandler.Event") + ?.asStarProjectedType() val symbols = resolver.getSymbolsWithAnnotation(SkyHanniModule::class.qualifiedName!!).toList() val validSymbols = symbols.mapNotNull { validateSymbol(it) } @@ -55,7 +54,24 @@ class ModuleProcessor(private val codeGenerator: CodeGenerator, private val logg return null } - checkCorrectEventAnnotations(symbol) + // TODO remove once all events are migrated to SkyHanniEvent + val className = symbol.qualifiedName?.asString() ?: "unknown" + + for (function in symbol.getDeclaredFunctions()) { + if (function.annotations.any { it.shortName.asString() == "SubscribeEvent" }) { + val firstParameter = function.parameters.firstOrNull()?.type?.resolve()!! + if (!minecraftForgeEvent!!.isAssignableFrom(firstParameter)) { + warnings.add("Function in $className must have an event assignable from $minecraftForgeEvent because it is annotated with @SubscribeEvent") + } + } + + if (function.annotations.any { it.shortName.asString() == "HandleEvent" }) { + val firstParameter = function.parameters.firstOrNull()?.type?.resolve()!! + if (!skyHanniEvent!!.isAssignableFrom(firstParameter)) { + warnings.add("Function in $className must have an event assignable from $skyHanniEvent because it is annotated with @HandleEvent") + } + } + } return symbol } @@ -88,32 +104,4 @@ class ModuleProcessor(private val codeGenerator: CodeGenerator, private val logg logger.warn("Generated LoadedModules file with ${symbols.size} modules") } - - // TODO remove once all events are migrated to SkyHanniEvent - private fun checkCorrectEventAnnotations(symbol: KSClassDeclaration) { - - for (function in symbol.getDeclaredFunctions()) { - if (function.annotations.any { it.shortName.asString() == "SubscribeEvent" }) { - val firstParameter = function.parameters.firstOrNull()?.type?.resolve() - isDeclarable(symbol, firstParameter!!, minecraftForgeEvent!!, "SubscribeEvent") - } - - if (function.annotations.any { it.shortName.asString() == "HandleEvent" }) { - val firstParameter = function.parameters.firstOrNull()?.type?.resolve() - isDeclarable(symbol, firstParameter!!, skyHanniEvent!!, "HandleEvent") - } - } - } - - private fun isDeclarable( - clazz: KSClassDeclaration, - parameterType: KSType, - targetType: KSType, - annotationType: String - ) { - if (!targetType.isAssignableFrom(parameterType)) { - val className = clazz.qualifiedName?.asString() ?: "unknown" - warnings.add("Function in $className must have the first parameter assignable from $targetType because it is annotated with @$annotationType") - } - } } From ad681e65d23758439c83b1c3150d73066aaebb60 Mon Sep 17 00:00:00 2001 From: Cal Date: Sat, 8 Jun 2024 15:43:32 +1000 Subject: [PATCH 5/6] now it shouldn't have errors --- .../skyhanni/features/inventory/HarpFeatures.kt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/HarpFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/HarpFeatures.kt index 83344ac5319e..75b1d6ad3cd3 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/HarpFeatures.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/HarpFeatures.kt @@ -58,7 +58,7 @@ object HarpFeatures { private fun isHarpGui(chestName: String) = inventoryTitlePattern.matches(chestName) private fun isMenuGui(chestName: String) = menuTitlePattern.matches(chestName) - @HandleEvent + @SubscribeEvent fun onGui(event: GuiKeyPressEvent) { if (!LorenzUtils.inSkyBlock) return if (!config.keybinds) return @@ -98,7 +98,7 @@ object HarpFeatures { private var openTime: SimpleTimeMark = SimpleTimeMark.farPast() - @HandleEvent + @SubscribeEvent fun onInventoryOpen(event: InventoryFullyOpenedEvent) { if (!LorenzUtils.inSkyBlock) return if (config.quickRestart && isMenuGui(event.inventoryName)) { @@ -124,14 +124,14 @@ object HarpFeatures { minecraft.currentScreen.setWorldAndResolution(minecraft, i, j) } - @HandleEvent + @SubscribeEvent fun onInventoryClose(event: InventoryCloseEvent) { if (!LorenzUtils.inSkyBlock) return if (!config.guiScale) return unSetGUIScale() } - @SubscribeEvent + @HandleEvent fun onDisconnect(event: ClientDisconnectEvent) { if (!config.guiScale) return unSetGUIScale() @@ -154,7 +154,7 @@ object HarpFeatures { isGUIScaled = false } - @HandleEvent + @SubscribeEvent fun onSlotClick(event: GuiContainerEvent.SlotClickEvent) { if (!LorenzUtils.inSkyBlock) return @@ -186,7 +186,7 @@ object HarpFeatures { } } - @HandleEvent + @SubscribeEvent fun onRenderItemTip(event: RenderItemTipEvent) { if (!LorenzUtils.inSkyBlock) return if (!config.showNumbers) return @@ -201,13 +201,13 @@ object HarpFeatures { event.stackTip = KeyboardManager.getKeyName(keyCode).take(3) } - @HandleEvent + @SubscribeEvent fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) { event.move(2, "misc.harpKeybinds", "inventory.helper.harp.keybinds") event.move(2, "misc.harpNumbers", "inventory.helper.harp.showNumbers") } - @HandleEvent + @SubscribeEvent fun onTooltip(event: LorenzToolTipEvent) { if (!LorenzUtils.inSkyBlock) return if (!config.hideMelodyTooltip) return From faeeb1059120f1c16752af011c89ed2d85b58102 Mon Sep 17 00:00:00 2001 From: Cal Date: Sat, 8 Jun 2024 15:53:52 +1000 Subject: [PATCH 6/6] even better error message --- .../at/hannibal2/skyhanni/skyhannimodule/ModuleProcessor.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/annotation-processors/src/main/kotlin/at/hannibal2/skyhanni/skyhannimodule/ModuleProcessor.kt b/annotation-processors/src/main/kotlin/at/hannibal2/skyhanni/skyhannimodule/ModuleProcessor.kt index ecc564b1baa3..5681641331cd 100644 --- a/annotation-processors/src/main/kotlin/at/hannibal2/skyhanni/skyhannimodule/ModuleProcessor.kt +++ b/annotation-processors/src/main/kotlin/at/hannibal2/skyhanni/skyhannimodule/ModuleProcessor.kt @@ -81,7 +81,7 @@ class ModuleProcessor(private val codeGenerator: CodeGenerator, private val logg if (warnings.isNotEmpty()) { warnings.forEach { logger.warn(it) } - error("${warnings.size} errors related to event annotations found, please fix them before continuing") + error("${warnings.size} errors related to event annotations found, please fix them before continuing. Click on the kspKotlin build log for more information.") } val dependencies = symbols.mapNotNull { it.containingFile }.toTypedArray()