diff options
56 files changed, 458 insertions, 120 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 diff --git a/build.gradle.kts b/build.gradle.kts index e9e769a8..e51d082c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -30,8 +30,8 @@ plugins { id("com.github.johnrengelman.shadow") version "7.1.2" id("io.github.juuxel.loom-quiltflower") version "1.7.3" `maven-publish` - id("io.freefair.lombok") version "6.5.1" - kotlin("jvm") version "1.7.20" + kotlin("jvm") version "1.8.0" + id("com.google.devtools.ksp") version "1.8.0-1.0.8" } @@ -62,6 +62,7 @@ loom { pack200Provider.set(dev.architectury.pack200.java.Pack200Adapter()) mixinConfig("mixins.notenoughupdates.json") } + @Suppress("UnstableApiUsage") mixin { defaultRefmapName.set("mixins.notenoughupdates.refmap.json") } @@ -78,44 +79,43 @@ repositories { maven("https://repo.polyfrost.cc/releases") } -lombok { - version.set("1.18.24") -} - -< |
