aboutsummaryrefslogtreecommitdiff
path: root/annotations
diff options
context:
space:
mode:
authornea <nea@nea.moe>2023-01-14 17:03:22 +0100
committernea <nea@nea.moe>2023-01-14 17:03:22 +0100
commitee19ed5c066b0f867563dd61bd4dc9a6ebe9c641 (patch)
tree5ae860bbfee9f589de6123ae97649aba4bdcdee0 /annotations
parent4b3aad7142c04071961e8b4a87cb1b4759da38b7 (diff)
downloadNotEnoughUpdates-ee19ed5c066b0f867563dd61bd4dc9a6ebe9c641.tar.gz
NotEnoughUpdates-ee19ed5c066b0f867563dd61bd4dc9a6ebe9c641.tar.bz2
NotEnoughUpdates-ee19ed5c066b0f867563dd61bd4dc9a6ebe9c641.zip
Annotation registering (and also some comptime performance)
Diffstat (limited to 'annotations')
-rw-r--r--annotations/build.gradle.kts44
-rw-r--r--annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSubscribe.kt24
-rw-r--r--annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSymbolProcessor.kt140
-rw-r--r--annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSymbolProcessorProvider.kt30
-rw-r--r--annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUEventSubscriber.kt34
-rw-r--r--annotations/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider20
6 files changed, 292 insertions, 0 deletions
diff --git a/annotations/build.gradle.kts b/annotations/build.gradle.kts
new file mode 100644
index 00000000..c9e13173
--- /dev/null
+++ b/annotations/build.gradle.kts
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+plugins {
+ kotlin("jvm")
+ java
+}
+
+repositories {
+ mavenCentral()
+}
+
+tasks.withType<JavaCompile> {
+ if (JavaVersion.current().isJava9Compatible) {
+ options.release.set(8)
+ }
+}
+
+dependencies {
+ implementation(kotlin("stdlib-jdk8"))
+ implementation("com.google.devtools.ksp:symbol-processing-api:1.8.0-1.0.8")
+ implementation("com.squareup:kotlinpoet:1.12.0")
+ implementation("com.squareup:kotlinpoet-ksp:1.12.0")
+}
+
+
+
+
diff --git a/annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSubscribe.kt b/annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSubscribe.kt
new file mode 100644
index 00000000..1ba6be99
--- /dev/null
+++ b/annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSubscribe.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2023 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.autosubscribe
+
+@Retention(AnnotationRetention.SOURCE)
+@Target(AnnotationTarget.CLASS)
+annotation class NEUAutoSubscribe
diff --git a/annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSymbolProcessor.kt b/annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSymbolProcessor.kt
new file mode 100644
index 00000000..3ab71912
--- /dev/null
+++ b/annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSymbolProcessor.kt
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2023 Linnea Gräf
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.autosubscribe
+
+import com.google.devtools.ksp.getDeclaredFunctions
+import com.google.devtools.ksp.getDeclaredProperties
+import com.google.devtools.ksp.processing.CodeGenerator
+import com.google.devtools.ksp.processing.KSPLogger
+import com.google.devtools.ksp.processing.Resolver
+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.squareup.kotlinpoet.FileSpec
+import com.squareup.kotlinpoet.FunSpec
+import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
+import com.squareup.kotlinpoet.TypeSpec
+import com.squareup.kotlinpoet.ksp.addOriginatingKSFile
+import com.squareup.kotlinpoet.ksp.toClassName
+import com.squareup.kotlinpoet.ksp.writeTo
+import java.util.function.Consumer
+
+internal class NEUAutoSymbolProcessor(val codeGenerator: CodeGenerator, val logger: KSPLogger) : SymbolProcessor {
+ fun collectSubscribers(elements: Sequence<KSAnnotated>): List<NEUEventSubscriber> = buildList {
+ for (element in elements) {
+ if (element !is KSClassDeclaration) {
+ logger.error("@NEUAutoSubscribe is only valid on class or object declarations", element)
+ continue
+ }
+ val name = element.qualifiedName
+ if (name == null) {
+ logger.error("@NEUAutoSubscribe could not find name", element)
+ continue
+ }
+ when (element.classKind) {
+ ClassKind.CLASS -> {
+ val instanceGetter = element.getDeclaredFunctions().find {
+ it.simpleName.asString() == "getInstance"
+ }
+ val instanceVariable = element.getDeclaredProperties().find {
+ it.simpleName.asString() == "INSTANCE"
+ }
+ if (instanceGetter != null) {
+ val returnType = instanceGetter.returnType
+ // TODO: typechecking
+ add(NEUEventSubscriber(InvocationKind.GET_INSTANCE, element))
+ } else if (instanceVariable != null) {
+ // TODO: typechecking
+ add(NEUEventSubscriber(InvocationKind.ACCESS_INSTANCE, element))
+ } else {
+ // TODO: typechecking
+ add(NEUEventSubscriber(InvocationKind.DEFAULT_CONSTRUCTOR, element))
+ }
+ }
+
+ ClassKind.OBJECT -> {
+ add(NEUEventSubscriber(InvocationKind.OBJECT_INSTANCE, element))
+ }
+
+ else -> {
+ logger.error(
+ "@NEUAutoSubscribe is only valid on classes and objects, not on ${element.classKind}",
+ element
+ )
+ continue
+ }
+ }
+ }
+
+ }
+
+ val subscribers = mutableListOf<NEUEventSubscriber>()
+ override fun process(resolver: Resolver): List<KSAnnotated> {
+ val candidates = resolver.getSymbolsWithAnnotation(NEUAutoSubscribe::class.qualifiedName!!)
+ subscribers.addAll(collectSubscribers(candidates))
+ return emptyList()
+ }
+
+ override fun finish() {
+ if (subscribers.isEmpty()) return
+ FileSpec.builder("io.github.moulberry.notenoughupdates.autosubscribe", "AutoLoad")
+ .addFileComment("@generated by ${NEUAutoSymbolProcessor::class.simpleName}")
+ .addType(
+ TypeSpec.objectBuilder("AutoLoad")
+ .addFunction(
+ FunSpec.builder("provide")
+ .addParameter("consumer", Consumer::class.parameterizedBy(Any::class))
+ .apply {
+ subscribers.sortedBy { it.declaration.simpleName.asString() }.forEach { (invocationKind, declaration) ->
+ when (invocationKind) {
+ InvocationKind.GET_INSTANCE -> addStatement(
+ "consumer.accept(%T.getInstance())",
+ declaration.toClassName()
+ )
+
+ InvocationKind.OBJECT_INSTANCE -> addStatement(
+ "consumer.accept(%T)",
+ declaration.toClassName()
+ )
+
+ InvocationKind.DEFAULT_CONSTRUCTOR -> addStatement(
+ "consumer.accept(%T())",
+ declaration.toClassName()
+ )
+
+ InvocationKind.ACCESS_INSTANCE -> addStatement(
+ "consumer.accept(%T.INSTANCE)",
+ declaration.toClassName()
+ )
+ }
+ declaration.containingFile?.let {
+ addOriginatingKSFile(it)
+ }
+ }
+ }
+ .build()
+ )
+ .build()
+ )
+ .build()
+ .writeTo(codeGenerator, aggregating = true)
+ }
+}
diff --git a/annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSymbolProcessorProvider.kt b/annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSymbolProcessorProvider.kt
new file mode 100644
index 00000000..ef0edd88
--- /dev/null
+++ b/annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSymbolProcessorProvider.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2023 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.autosubscribe
+
+import com.google.devtools.ksp.processing.SymbolProcessor
+import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
+import com.google.devtools.ksp.processing.SymbolProcessorProvider
+
+class NEUAutoSymbolProcessorProvider : SymbolProcessorProvider {
+ override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor {
+ return NEUAutoSymbolProcessor(environment.codeGenerator, environment.logger)
+ }
+}
diff --git a/annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUEventSubscriber.kt b/annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUEventSubscriber.kt
new file mode 100644
index 00000000..d17b6004
--- /dev/null
+++ b/annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUEventSubscriber.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023 Linnea Gräf
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.autosubscribe
+
+import com.google.devtools.ksp.symbol.KSClassDeclaration
+
+internal data class NEUEventSubscriber(
+ val invocationKind: InvocationKind,
+ val declaration: KSClassDeclaration,
+)
+
+internal enum class InvocationKind {
+ GET_INSTANCE,
+ OBJECT_INSTANCE,
+ DEFAULT_CONSTRUCTOR,
+ ACCESS_INSTANCE,
+}
diff --git a/annotations/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider b/annotations/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider
new file mode 100644
index 00000000..eaad70ce
--- /dev/null
+++ b/annotations/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider
@@ -0,0 +1,20 @@
+#
+# Copyright (C) 2023 NotEnoughUpdates contributors
+#
+# This file is part of NotEnoughUpdates.
+#
+# NotEnoughUpdates is free software: you can redistribute it
+# and/or modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation, either
+# version 3 of the License, or (at your option) any later version.
+#
+# NotEnoughUpdates is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+#
+
+io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSymbolProcessorProvider