Skip to content

Commit c644444

Browse files
committed
Convert AW to AT for ForgeGradle
1 parent 061dfd0 commit c644444

File tree

9 files changed

+140
-27
lines changed

9 files changed

+140
-27
lines changed

build-logic/build.gradle

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ indra {
1313
dependencies {
1414
api(apiLibs.gson)
1515
implementation("gradle.plugin.org.jetbrains.gradle.plugin.idea-ext:gradle-idea-ext:${apiLibs.versions.ideaExt.get()}")
16+
implementation(libs.at)
17+
implementation(libs.accessWidener)
18+
19+
// arch-loom is used by SpongeNeo but must be declared here to avoid a classloader conflict with its transitive dependencies
20+
api("dev.architectury:architectury-loom:1.6.411")
1621
}
1722

1823
indraSpotlessLicenser {

build-logic/settings.gradle

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,14 @@ pluginManagement {
99

1010
dependencyResolutionManagement {
1111
repositoriesMode = RepositoriesMode.FAIL_ON_PROJECT_REPOS
12-
repositories { pluginManagement.repositories.each { add(it) } }
12+
repositories {
13+
pluginManagement.repositories.each { add(it) }
14+
maven {
15+
url = "https://maven.architectury.dev/"
16+
name = "architectury"
17+
}
18+
}
19+
1320
versionCatalogs {
1421
libs {
1522
from files("../gradle/libs.versions.toml")
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
* This file is part of Sponge, licensed under the MIT License (MIT).
3+
*
4+
* Copyright (c) SpongePowered <https://www.spongepowered.org>
5+
* Copyright (c) contributors
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*/
25+
package org.spongepowered.gradle.impl;
26+
27+
import dev.architectury.at.AccessChange;
28+
import dev.architectury.at.AccessTransform;
29+
import dev.architectury.at.AccessTransformSet;
30+
import dev.architectury.at.ModifierChange;
31+
import dev.architectury.at.io.AccessTransformFormats;
32+
import net.fabricmc.accesswidener.AccessWidenerReader;
33+
import net.fabricmc.accesswidener.AccessWidenerVisitor;
34+
import org.cadixdev.bombe.type.signature.MethodSignature;
35+
import org.gradle.api.DefaultTask;
36+
import org.gradle.api.GradleException;
37+
import org.gradle.api.file.ConfigurableFileCollection;
38+
import org.gradle.api.file.RegularFileProperty;
39+
import org.gradle.api.tasks.InputFiles;
40+
import org.gradle.api.tasks.OutputFile;
41+
import org.gradle.api.tasks.TaskAction;
42+
43+
import java.io.BufferedReader;
44+
import java.io.BufferedWriter;
45+
import java.io.File;
46+
import java.io.IOException;
47+
import java.nio.file.Files;
48+
import java.util.Set;
49+
50+
public abstract class ConvertAWToAT extends DefaultTask {
51+
52+
@InputFiles
53+
public abstract ConfigurableFileCollection getAccessWideners();
54+
55+
public void accessWideners(Object... paths) {
56+
this.getAccessWideners().from(paths);
57+
}
58+
59+
@OutputFile
60+
public abstract RegularFileProperty getAccessTransformer();
61+
62+
@TaskAction
63+
public void convert() {
64+
final Set<File> awFiles = this.getAccessWideners().getFiles();
65+
final File atFile = this.getAccessTransformer().get().getAsFile();
66+
67+
final AccessTransformSet at = AccessTransformSet.create();
68+
69+
for (final File awFile : awFiles) {
70+
try (final BufferedReader reader = Files.newBufferedReader(awFile.toPath())) {
71+
ConvertAWToAT.convert(reader, at);
72+
} catch (final IOException e) {
73+
throw new GradleException("Failed to read access widener: " + awFile, e);
74+
}
75+
}
76+
77+
try (final BufferedWriter writer = Files.newBufferedWriter(atFile.toPath())) {
78+
AccessTransformFormats.FML.write(writer, at);
79+
} catch (IOException e) {
80+
throw new GradleException("Failed to write access transformer: " + atFile, e);
81+
}
82+
}
83+
84+
public static void convert(final BufferedReader reader, final AccessTransformSet at) throws IOException {
85+
new AccessWidenerReader(new AccessWidenerVisitor() {
86+
@Override
87+
public void visitClass(final String name, final AccessWidenerReader.AccessType access, final boolean transitive) {
88+
at.getOrCreateClass(name).merge(ConvertAWToAT.convertEntry(access));
89+
}
90+
91+
@Override
92+
public void visitMethod(final String owner, final String name, final String descriptor, final AccessWidenerReader.AccessType access, final boolean transitive) {
93+
at.getOrCreateClass(owner).mergeMethod(MethodSignature.of(name, descriptor), ConvertAWToAT.convertEntry(access));
94+
}
95+
96+
@Override
97+
public void visitField(final String owner, final String name, final String descriptor, final AccessWidenerReader.AccessType access, final boolean transitive) {
98+
at.getOrCreateClass(owner).mergeField(name, ConvertAWToAT.convertEntry(access));
99+
}
100+
}).read(reader);
101+
}
102+
103+
public static AccessTransform convertEntry(final AccessWidenerReader.AccessType access) {
104+
return switch (access) {
105+
case ACCESSIBLE -> AccessTransform.of(AccessChange.PUBLIC);
106+
case EXTENDABLE, MUTABLE -> AccessTransform.of(AccessChange.PUBLIC, ModifierChange.REMOVE);
107+
};
108+
}
109+
}

build.gradle.kts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@ dependencies {
176176
}
177177
}
178178

179+
minecraft {
180+
accessWideners(main.resources.filter { it.name.endsWith(".accesswidener") })
181+
}
182+
179183
allprojects {
180184
configurations.configureEach {
181185
resolutionStrategy.dependencySubstitution {
@@ -199,13 +203,6 @@ allprojects {
199203
minecraft {
200204
version(minecraftVersion)
201205
injectRepositories(false)
202-
project.sourceSets["main"].resources
203-
.filter { it.name.endsWith(".accesswidener") }
204-
.files
205-
.forEach {
206-
accessWideners(it)
207-
parent?.minecraft?.accessWideners(it)
208-
}
209206
}
210207

211208
dependencies {

forge/build.gradle.kts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
22
import net.minecraftforge.gradle.userdev.UserDevExtension
3+
import org.spongepowered.gradle.impl.ConvertAWToAT
34

45
buildscript {
56
repositories {
@@ -201,20 +202,25 @@ dependencies {
201202
runtimeOnly(project(bootstrapDevProject.path))
202203
}
203204

205+
val convertAWToAT = tasks.register("convertAWToAT", ConvertAWToAT::class) {
206+
accessWideners(main.get().resources.filter { it.name.endsWith(".accesswidener") })
207+
accessWideners(forgeMain.resources.filter { it.name.endsWith(".accesswidener") })
208+
accessTransformer.set(project.layout.buildDirectory.file("generated/resources/at.cfg"))
209+
}
210+
204211
val mixinConfigs: MutableSet<String> = spongeImpl.mixinConfigurations
205212

206213
extensions.configure(UserDevExtension::class) {
207214
mappings("official", "1.21.3")
208-
// accessWidenerPath.set(file("../src/main/resources/common.accesswidener")) TODO
215+
accessTransformers.from(convertAWToAT.flatMap { it.accessTransformer })
209216

210217
reobf = false
211218

212219
runs {
213220
configureEach {
214221
ideaModule("Sponge.SpongeForge.main")
215222

216-
property("forge.logging.markers", "REGISTRIES")
217-
property("forge.logging.console.level", "debug")
223+
// property("forge.logging.console.level", "debug")
218224

219225
// jvmArgs("-Dbsl.debug=true") // Uncomment to debug bootstrap classpath
220226

generator/build.gradle.kts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,7 @@ plugins {
55
description = "Code generator for automatically producing API catalog classes based off of Vanilla MC data"
66

77
minecraft {
8-
rootProject.sourceSets["main"].resources
9-
.filter { it.name.endsWith(".accesswidener") }
10-
.files
11-
.forEach {
12-
accessWideners(it)
13-
}
8+
accessWideners(rootProject.sourceSets["main"].resources.filter { it.name.endsWith(".accesswidener") })
149
}
1510

1611
configurations.configureEach {

gradle/libs.versions.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ terminalConsoleAppender = { module = "net.minecrell:terminalconsoleappender", ve
6868

6969
# buildtime-only
7070
vineflower = { module = "org.vineflower:vineflower", version.ref = "vineflower" }
71+
at = { module = "dev.architectury:at", version = "1.0.1" }
7172

7273
[plugins]
7374
blossom = { id = "net.kyori.blossom", version = "2.1.0" }

neoforge/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ plugins {
1414
alias(libs.plugins.shadow)
1515
id("implementation-structure")
1616
alias(libs.plugins.blossom)
17-
id("dev.architectury.loom") version "1.6.411"
17+
id("dev.architectury.loom")
1818
}
1919

2020
val commonProject = parent!!

vanilla/build.gradle.kts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -126,15 +126,8 @@ val superclassConfigs = spongeImpl.getNamedConfigurations("superClassChanges")
126126
val mixinConfigs = spongeImpl.mixinConfigurations
127127

128128
minecraft {
129-
main.get().resources
130-
.filter { it.name.endsWith(".accesswidener") }
131-
.files
132-
.forEach { accessWideners(it) }
133-
134-
vanillaMain.resources
135-
.filter { it.name.endsWith(".accesswidener") }
136-
.files
137-
.forEach { accessWideners(it) }
129+
accessWideners(main.get().resources.filter { it.name.endsWith(".accesswidener") })
130+
accessWideners(vanillaMain.resources.filter { it.name.endsWith(".accesswidener") })
138131
}
139132

140133
configurations.configureEach {

0 commit comments

Comments
 (0)