diff --git a/src/test/groovy/net/fabricmc/loom/test/integration/AnnotationsApplyTest.groovy b/src/test/groovy/net/fabricmc/loom/test/integration/AnnotationsApplyTest.groovy new file mode 100644 index 00000000..e208b378 --- /dev/null +++ b/src/test/groovy/net/fabricmc/loom/test/integration/AnnotationsApplyTest.groovy @@ -0,0 +1,75 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2025 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.test.integration + +import java.util.function.Predicate + +import org.objectweb.asm.ClassReader +import org.objectweb.asm.tree.ClassNode +import org.objectweb.asm.tree.MethodNode +import spock.lang.Specification +import spock.lang.Unroll + +import net.fabricmc.loom.test.util.GradleProjectTestTrait +import net.fabricmc.loom.util.ZipUtils + +import static net.fabricmc.loom.test.LoomTestConstants.STANDARD_TEST_VERSIONS +import static org.gradle.testkit.runner.TaskOutcome.SUCCESS + +class AnnotationsApplyTest extends Specification implements GradleProjectTestTrait { + @Unroll + def "annotations apply (gradle #version)"() { + setup: + def gradle = gradleProject(project: "annotationsApply", version: version) + + when: + def result = gradle.run(task: "build") + + then: + result.task(":build").outcome == SUCCESS + checkClass(gradle, "net/minecraft/util/math/BlockPos") { + MethodNode method = it.methods.find { + it.name == "add" && it.desc == "(Lnet/minecraft/util/math/Vec3i;)Lnet/minecraft/util/math/BlockPos;" + } + + if (method == null || method.invisibleAnnotations == null) { + return false + } + + method.invisibleAnnotations.any { it.desc == "Lorg/jetbrains/annotations/Contract;" } + } + + where: + version << STANDARD_TEST_VERSIONS + } + + boolean checkClass(GradleProject gradle, String clazz, Predicate test) { + byte[] bytecode = ZipUtils.unpack(gradle.getGeneratedMinecraft("25w42a-net.fabricmc.yarn.25w42a.25w42a+build.9-v2").toPath(), "${clazz}.class") + ClassReader reader = new ClassReader(bytecode) + ClassNode node = new ClassNode() + reader.accept(node, 0) + return test.test(node) + } +} diff --git a/src/test/groovy/net/fabricmc/loom/test/util/GradleProjectTestTrait.groovy b/src/test/groovy/net/fabricmc/loom/test/util/GradleProjectTestTrait.groovy index d14673be..86df3a47 100644 --- a/src/test/groovy/net/fabricmc/loom/test/util/GradleProjectTestTrait.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/util/GradleProjectTestTrait.groovy @@ -24,7 +24,6 @@ package net.fabricmc.loom.test.util -import groovy.io.FileType import groovy.transform.Immutable import org.apache.commons.io.FileUtils import org.gradle.testkit.runner.BuildResult @@ -261,25 +260,33 @@ trait GradleProjectTestTrait { return ZipUtils.unpackNullable(file.toPath(), entryName) != null } - File getGeneratedSources(String mappings, String jarType = "merged") { - return new File(getGradleHomeDir(), "caches/fabric-loom/minecraftMaven/net/minecraft/minecraft-${jarType}/${mappings}/minecraft-${jarType}-${mappings}-sources.jar") + File getGeneratedMinecraft(String mappings, String jarType = "merged", String classifier = "") { + String classifierSuffix = classifier.isEmpty() ? "" : "-$classifier" + return new File(getGradleHomeDir(), "caches/fabric-loom/minecraftMaven/net/minecraft/minecraft-${jarType}/${mappings}/minecraft-${jarType}-${mappings}${classifierSuffix}.jar") } - File getGeneratedLocalSources(String mappings) { - File file - getProjectDir().traverse(type: FileType.FILES) { - if (it.name.startsWith("minecraft-merged-") - && it.name.contains(mappings) - && it.name.endsWith("-sources.jar")) { - file = it - } + File getGeneratedSources(String mappings, String jarType = "merged") { + return getGeneratedMinecraft(mappings, jarType, "sources") + } + + File getGeneratedLocalMinecraft(String mappings, String jarType = "merged", String classifier = "") { + String classifierSuffix = classifier.isEmpty() ? "" : "-$classifier" + + File file = new File(getProjectDir(), ".gradle/loom-cache/minecraftMaven/net/minecraft") + file = file.listFiles().find { + it.name.startsWith("minecraft-${jarType}-") } if (file == null) { throw new FileNotFoundException() } - return file + String jarFileName = "${file.name}-${mappings}${classifierSuffix}.jar" + return new File(file, "${mappings}/${jarFileName}") + } + + File getGeneratedLocalSources(String mappings, String jarType = "merged") { + return getGeneratedLocalMinecraft(mappings, jarType, "sources") } void buildSrc(String name, boolean apply = true) { diff --git a/src/test/resources/projects/annotationsApply/build.gradle b/src/test/resources/projects/annotationsApply/build.gradle new file mode 100644 index 00000000..7aec635b --- /dev/null +++ b/src/test/resources/projects/annotationsApply/build.gradle @@ -0,0 +1,9 @@ +plugins { + id 'fabric-loom' +} + +dependencies { + minecraft "com.mojang:minecraft:25w42a" + mappings "net.fabricmc:yarn:25w42a+build.9:v2" + modImplementation "net.fabricmc:fabric-loader:0.17.3" +} diff --git a/src/test/resources/projects/annotationsApply/src/main/java/ExampleMod.java b/src/test/resources/projects/annotationsApply/src/main/java/ExampleMod.java new file mode 100644 index 00000000..f6675524 --- /dev/null +++ b/src/test/resources/projects/annotationsApply/src/main/java/ExampleMod.java @@ -0,0 +1,8 @@ + +import net.fabricmc.api.ModInitializer; + +public class ExampleMod implements ModInitializer { + @Override + public void onInitialize() { + } +}