Kotlin metadata annotation remapping (#573)
Co-authored-by: Juuxel <6596629+Juuxel@users.noreply.github.com>dev/0.11
parent
421b41ebc7
commit
d71af0cfd7
|
@ -1,4 +1,4 @@
|
||||||
[*.{gradle,java}]
|
[*.{gradle,java,kotlin}]
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
ij_continuation_indent_size = 8
|
ij_continuation_indent_size = 8
|
||||||
ij_java_imports_layout = $*,|,java.**,|,javax.**,|,*,|,net.fabricmc.**
|
ij_java_imports_layout = $*,|,java.**,|,javax.**,|,*,|,net.fabricmc.**
|
||||||
|
|
43
build.gradle
43
build.gradle
|
@ -8,6 +8,7 @@ plugins {
|
||||||
id 'checkstyle'
|
id 'checkstyle'
|
||||||
id 'jacoco'
|
id 'jacoco'
|
||||||
id 'codenarc'
|
id 'codenarc'
|
||||||
|
id "org.jetbrains.kotlin.jvm" version "1.5.31" // Must match the version included with gradle.
|
||||||
id "com.diffplug.spotless" version "5.14.1"
|
id "com.diffplug.spotless" version "5.14.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +20,11 @@ tasks.withType(JavaCompile).configureEach {
|
||||||
it.options.release = 17
|
it.options.release = 17
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "16" // Change to 17 when updating gradle/kotlin to 1.6.10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
group = 'net.fabricmc'
|
group = 'net.fabricmc'
|
||||||
archivesBaseName = project.name
|
archivesBaseName = project.name
|
||||||
|
@ -92,6 +98,11 @@ dependencies {
|
||||||
// source code remapping
|
// source code remapping
|
||||||
implementation ('net.fabricmc:mercury:0.2.4')
|
implementation ('net.fabricmc:mercury:0.2.4')
|
||||||
|
|
||||||
|
// Kotlin
|
||||||
|
implementation("org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.4.1") {
|
||||||
|
transitive = false
|
||||||
|
}
|
||||||
|
|
||||||
// Kapt integration
|
// Kapt integration
|
||||||
compileOnly('org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0')
|
compileOnly('org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0')
|
||||||
|
|
||||||
|
@ -100,7 +111,10 @@ dependencies {
|
||||||
testImplementation('org.spockframework:spock-core:2.0-groovy-3.0') {
|
testImplementation('org.spockframework:spock-core:2.0-groovy-3.0') {
|
||||||
exclude module: 'groovy-all'
|
exclude module: 'groovy-all'
|
||||||
}
|
}
|
||||||
testImplementation 'io.javalin:javalin:3.13.11'
|
testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
|
||||||
|
testImplementation ('io.javalin:javalin:3.13.11') {
|
||||||
|
exclude group: 'org.jetbrains.kotlin'
|
||||||
|
}
|
||||||
testImplementation 'net.fabricmc:fabric-installer:0.9.0'
|
testImplementation 'net.fabricmc:fabric-installer:0.9.0'
|
||||||
|
|
||||||
compileOnly 'org.jetbrains:annotations:23.0.0'
|
compileOnly 'org.jetbrains:annotations:23.0.0'
|
||||||
|
@ -127,6 +141,13 @@ spotless {
|
||||||
groovy {
|
groovy {
|
||||||
licenseHeaderFile(rootProject.file("HEADER")).yearSeparator("-")
|
licenseHeaderFile(rootProject.file("HEADER")).yearSeparator("-")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
licenseHeaderFile(rootProject.file("HEADER")).yearSeparator("-")
|
||||||
|
targetExclude("**/build.gradle.kts")
|
||||||
|
targetExclude("src/test/resources/projects/*/**")
|
||||||
|
ktlint()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkstyle {
|
checkstyle {
|
||||||
|
@ -172,18 +193,6 @@ import org.w3c.dom.Document
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
import org.w3c.dom.Node
|
import org.w3c.dom.Node
|
||||||
|
|
||||||
def patchPom(groovy.util.Node node) {
|
|
||||||
node.dependencies.first().each {
|
|
||||||
def groupId = it.get("groupId").first().value().first()
|
|
||||||
|
|
||||||
// Patch all eclipse deps to use a strict version
|
|
||||||
if (groupId.startsWith("org.eclipse.")) {
|
|
||||||
def version = it.get("version").first().value().first()
|
|
||||||
it.get("version").first().value = new groovy.util.NodeList(["[$version]"])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
publishing {
|
publishing {
|
||||||
publications {
|
publications {
|
||||||
plugin(MavenPublication) { publication ->
|
plugin(MavenPublication) { publication ->
|
||||||
|
@ -192,10 +201,6 @@ publishing {
|
||||||
version project.version
|
version project.version
|
||||||
|
|
||||||
from components.java
|
from components.java
|
||||||
|
|
||||||
pom.withXml {
|
|
||||||
patchPom(asNode())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also publish a snapshot so people can use the latest version if they wish
|
// Also publish a snapshot so people can use the latest version if they wish
|
||||||
|
@ -205,10 +210,6 @@ publishing {
|
||||||
version baseVersion + '-SNAPSHOT'
|
version baseVersion + '-SNAPSHOT'
|
||||||
|
|
||||||
from components.java
|
from components.java
|
||||||
|
|
||||||
pom.withXml {
|
|
||||||
patchPom(asNode())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Manually crate the plugin marker for snapshot versions
|
// Manually crate the plugin marker for snapshot versions
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
name = fabric-loom
|
name = fabric-loom
|
||||||
description = The Gradle plugin for Fabric
|
description = The Gradle plugin for Fabric
|
||||||
url = https://github.com/FabricMC/fabric-loom
|
url = https://github.com/FabricMC/fabric-loom
|
||||||
|
|
||||||
|
kotlin.stdlib.default.dependency = false
|
|
@ -46,6 +46,7 @@ import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
|
||||||
import net.fabricmc.loom.configuration.RemappedConfigurationEntry;
|
import net.fabricmc.loom.configuration.RemappedConfigurationEntry;
|
||||||
import net.fabricmc.loom.configuration.processors.dependency.ModDependencyInfo;
|
import net.fabricmc.loom.configuration.processors.dependency.ModDependencyInfo;
|
||||||
import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl;
|
import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl;
|
||||||
|
import net.fabricmc.loom.kotlin.remapping.KotlinMetadataTinyRemapperExtension;
|
||||||
import net.fabricmc.loom.util.Constants;
|
import net.fabricmc.loom.util.Constants;
|
||||||
import net.fabricmc.loom.util.TinyRemapperHelper;
|
import net.fabricmc.loom.util.TinyRemapperHelper;
|
||||||
import net.fabricmc.loom.util.ZipUtils;
|
import net.fabricmc.loom.util.ZipUtils;
|
||||||
|
@ -134,16 +135,22 @@ public class ModProcessor {
|
||||||
private void remapJars(List<ModDependencyInfo> remapList) throws IOException {
|
private void remapJars(List<ModDependencyInfo> remapList) throws IOException {
|
||||||
final LoomGradleExtension extension = LoomGradleExtension.get(project);
|
final LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||||
final MappingsProviderImpl mappingsProvider = extension.getMappingsProvider();
|
final MappingsProviderImpl mappingsProvider = extension.getMappingsProvider();
|
||||||
|
final boolean useKotlinExtension = project.getPluginManager().hasPlugin("org.jetbrains.kotlin.jvm");
|
||||||
|
|
||||||
Path[] mcDeps = project.getConfigurations().getByName(Constants.Configurations.LOADER_DEPENDENCIES).getFiles()
|
Path[] mcDeps = project.getConfigurations().getByName(Constants.Configurations.LOADER_DEPENDENCIES).getFiles()
|
||||||
.stream().map(File::toPath).toArray(Path[]::new);
|
.stream().map(File::toPath).toArray(Path[]::new);
|
||||||
|
|
||||||
project.getLogger().lifecycle(":remapping " + remapList.size() + " mods (TinyRemapper, " + fromM + " -> " + toM + ")");
|
project.getLogger().lifecycle(":remapping " + remapList.size() + " mods (TinyRemapper, " + fromM + " -> " + toM + ")");
|
||||||
|
|
||||||
final TinyRemapper remapper = TinyRemapper.newRemapper()
|
TinyRemapper.Builder builder = TinyRemapper.newRemapper()
|
||||||
.withMappings(TinyRemapperHelper.create(mappingsProvider.getMappings(), fromM, toM, false))
|
.withMappings(TinyRemapperHelper.create(mappingsProvider.getMappings(), fromM, toM, false))
|
||||||
.renameInvalidLocals(false)
|
.renameInvalidLocals(false);
|
||||||
.build();
|
|
||||||
|
if (useKotlinExtension) {
|
||||||
|
builder.extension(KotlinMetadataTinyRemapperExtension.INSTANCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
final TinyRemapper remapper = builder.build();
|
||||||
|
|
||||||
for (Path minecraftJar : extension.getMinecraftJars(MappingsNamespace.INTERMEDIARY)) {
|
for (Path minecraftJar : extension.getMinecraftJars(MappingsNamespace.INTERMEDIARY)) {
|
||||||
remapper.readClassPathAsync(minecraftJar);
|
remapper.readClassPathAsync(minecraftJar);
|
||||||
|
|
|
@ -37,6 +37,7 @@ import java.util.Objects;
|
||||||
import org.gradle.api.Project;
|
import org.gradle.api.Project;
|
||||||
|
|
||||||
import net.fabricmc.loom.LoomGradleExtension;
|
import net.fabricmc.loom.LoomGradleExtension;
|
||||||
|
import net.fabricmc.loom.kotlin.remapping.KotlinMetadataTinyRemapperExtension;
|
||||||
import net.fabricmc.loom.task.AbstractRemapJarTask;
|
import net.fabricmc.loom.task.AbstractRemapJarTask;
|
||||||
import net.fabricmc.loom.util.service.SharedService;
|
import net.fabricmc.loom.util.service.SharedService;
|
||||||
import net.fabricmc.loom.util.service.SharedServiceManager;
|
import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||||
|
@ -52,9 +53,10 @@ public class TinyRemapperService implements SharedService {
|
||||||
final LoomGradleExtension extension = LoomGradleExtension.get(project);
|
final LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||||
final SharedServiceManager sharedServiceManager = SharedServiceManager.get(project);
|
final SharedServiceManager sharedServiceManager = SharedServiceManager.get(project);
|
||||||
final boolean legacyMixin = extension.getMixin().getUseLegacyMixinAp().get();
|
final boolean legacyMixin = extension.getMixin().getUseLegacyMixinAp().get();
|
||||||
|
final boolean useKotlinExtension = project.getPluginManager().hasPlugin("org.jetbrains.kotlin.jvm");
|
||||||
|
|
||||||
// Generates an id that is used to share the remapper across projects. This tasks in the remap jar task name to handle custom remap jar tasks separately.
|
// Generates an id that is used to share the remapper across projects. This tasks in the remap jar task name to handle custom remap jar tasks separately.
|
||||||
final String id = extension.getMappingsProvider().getBuildServiceName("remapJarService", from, to) + ":" + remapJarTask.getName();
|
final String id = extension.getMappingsProvider().getBuildServiceName("remapJarService", from, to) + ":" + remapJarTask.getName() + (useKotlinExtension ? ":kotlin" : "");
|
||||||
|
|
||||||
TinyRemapperService service = sharedServiceManager.getOrCreateService(id, () -> {
|
TinyRemapperService service = sharedServiceManager.getOrCreateService(id, () -> {
|
||||||
List<IMappingProvider> mappings = new ArrayList<>();
|
List<IMappingProvider> mappings = new ArrayList<>();
|
||||||
|
@ -64,7 +66,7 @@ public class TinyRemapperService implements SharedService {
|
||||||
mappings.add(MixinMappingsService.getService(SharedServiceManager.get(project)).getMappingProvider(from, to));
|
mappings.add(MixinMappingsService.getService(SharedServiceManager.get(project)).getMappingProvider(from, to));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new TinyRemapperService(mappings, !legacyMixin);
|
return new TinyRemapperService(mappings, !legacyMixin, useKotlinExtension);
|
||||||
});
|
});
|
||||||
|
|
||||||
service.readClasspath(remapJarTask.getClasspath().getFiles().stream().map(File::toPath).toList());
|
service.readClasspath(remapJarTask.getClasspath().getFiles().stream().map(File::toPath).toList());
|
||||||
|
@ -78,7 +80,7 @@ public class TinyRemapperService implements SharedService {
|
||||||
// Set to true once remapping has started, once set no inputs can be read.
|
// Set to true once remapping has started, once set no inputs can be read.
|
||||||
private boolean isRemapping = false;
|
private boolean isRemapping = false;
|
||||||
|
|
||||||
public TinyRemapperService(List<IMappingProvider> mappings, boolean useMixinExtension) {
|
public TinyRemapperService(List<IMappingProvider> mappings, boolean useMixinExtension, boolean useKotlinExtension) {
|
||||||
TinyRemapper.Builder builder = TinyRemapper.newRemapper();
|
TinyRemapper.Builder builder = TinyRemapper.newRemapper();
|
||||||
|
|
||||||
for (IMappingProvider provider : mappings) {
|
for (IMappingProvider provider : mappings) {
|
||||||
|
@ -89,6 +91,10 @@ public class TinyRemapperService implements SharedService {
|
||||||
builder.extension(new net.fabricmc.tinyremapper.extension.mixin.MixinExtension());
|
builder.extension(new net.fabricmc.tinyremapper.extension.mixin.MixinExtension());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (useKotlinExtension) {
|
||||||
|
builder.extension(KotlinMetadataTinyRemapperExtension.INSTANCE);
|
||||||
|
}
|
||||||
|
|
||||||
tinyRemapper = builder.build();
|
tinyRemapper = builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 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.kotlin.remapping
|
||||||
|
|
||||||
|
import kotlinx.metadata.jvm.KotlinClassHeader
|
||||||
|
import kotlinx.metadata.jvm.KotlinClassMetadata
|
||||||
|
import org.objectweb.asm.AnnotationVisitor
|
||||||
|
import org.objectweb.asm.Opcodes
|
||||||
|
import org.objectweb.asm.commons.Remapper
|
||||||
|
import org.objectweb.asm.tree.AnnotationNode
|
||||||
|
|
||||||
|
class KotlinClassMetadataRemappingAnnotationVisitor(private val remapper: Remapper, val next: AnnotationVisitor) :
|
||||||
|
AnnotationNode(Opcodes.ASM9, KotlinMetadataRemappingClassVisitor.ANNOTATION_DESCRIPTOR) {
|
||||||
|
|
||||||
|
private var _name: String? = null
|
||||||
|
|
||||||
|
override fun visit(name: String?, value: Any?) {
|
||||||
|
super.visit(name, value)
|
||||||
|
this._name = name
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitEnd() {
|
||||||
|
super.visitEnd()
|
||||||
|
when (val metadata = readMetadata()) {
|
||||||
|
is KotlinClassMetadata.Class -> {
|
||||||
|
val klass = metadata.toKmClass()
|
||||||
|
val writer = KotlinClassMetadata.Class.Writer()
|
||||||
|
klass.accept(RemappingKmVisitors(remapper).RemappingKmClassVisitor(writer))
|
||||||
|
writeClassHeader(writer.write().header)
|
||||||
|
}
|
||||||
|
is KotlinClassMetadata.SyntheticClass -> {
|
||||||
|
val klambda = metadata.toKmLambda()
|
||||||
|
|
||||||
|
if (klambda != null) {
|
||||||
|
val writer = KotlinClassMetadata.SyntheticClass.Writer()
|
||||||
|
klambda.accept(RemappingKmVisitors(remapper).RemappingKmLambdaVisitor(writer))
|
||||||
|
writeClassHeader(writer.write().header)
|
||||||
|
} else {
|
||||||
|
accept(next)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Can only be turned into KmPackage which is useless data
|
||||||
|
is KotlinClassMetadata.FileFacade, is KotlinClassMetadata.MultiFileClassPart,
|
||||||
|
// Can't be turned into data
|
||||||
|
is KotlinClassMetadata.MultiFileClassFacade, is KotlinClassMetadata.Unknown, null -> {
|
||||||
|
// do nothing
|
||||||
|
accept(next)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
private fun readMetadata(): KotlinClassMetadata? {
|
||||||
|
var kind: Int? = null
|
||||||
|
var metadataVersion: IntArray? = null
|
||||||
|
var data1: Array<String>? = null
|
||||||
|
var data2: Array<String>? = null
|
||||||
|
var extraString: String? = null
|
||||||
|
var packageName: String? = null
|
||||||
|
var extraInt: Int? = null
|
||||||
|
|
||||||
|
if (values == null) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
values.chunked(2).forEach { (name, value) ->
|
||||||
|
when (name) {
|
||||||
|
"k" -> kind = value as Int
|
||||||
|
"mv" -> metadataVersion = (value as List<Int>).toIntArray()
|
||||||
|
"d1" -> data1 = (value as List<String>).toTypedArray()
|
||||||
|
"d2" -> data2 = (value as List<String>).toTypedArray()
|
||||||
|
"xs" -> extraString = value as String
|
||||||
|
"pn" -> packageName = value as String
|
||||||
|
"xi" -> extraInt = value as Int
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val header = KotlinClassHeader(kind, metadataVersion, data1, data2, extraString, packageName, extraInt)
|
||||||
|
return KotlinClassMetadata.read(header)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun writeClassHeader(header: KotlinClassHeader) {
|
||||||
|
val newNode = AnnotationNode(api, desc)
|
||||||
|
newNode.values = this.values.toMutableList()
|
||||||
|
|
||||||
|
newNode.run {
|
||||||
|
for (i in values.indices step 2) {
|
||||||
|
when (values[i]) {
|
||||||
|
"k" -> values[i + 1] = header.kind
|
||||||
|
"mv" -> values[i + 1] = header.metadataVersion.toList()
|
||||||
|
"d1" -> values[i + 1] = header.data1.toList()
|
||||||
|
"d2" -> values[i + 1] = header.data2.toList()
|
||||||
|
"xs" -> values[i + 1] = header.extraString
|
||||||
|
"pn" -> values[i + 1] = header.packageName
|
||||||
|
"xi" -> values[i + 1] = header.extraInt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newNode.accept(next)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 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.kotlin.remapping
|
||||||
|
|
||||||
|
import org.objectweb.asm.AnnotationVisitor
|
||||||
|
import org.objectweb.asm.ClassVisitor
|
||||||
|
import org.objectweb.asm.Opcodes
|
||||||
|
import org.objectweb.asm.Type
|
||||||
|
import org.objectweb.asm.commons.Remapper
|
||||||
|
|
||||||
|
class KotlinMetadataRemappingClassVisitor(private val remapper: Remapper, next: ClassVisitor?) : ClassVisitor(Opcodes.ASM9, next) {
|
||||||
|
companion object {
|
||||||
|
val ANNOTATION_DESCRIPTOR: String = Type.getDescriptor(Metadata::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitAnnotation(descriptor: String, visible: Boolean): AnnotationVisitor? {
|
||||||
|
var result: AnnotationVisitor? = super.visitAnnotation(descriptor, visible)
|
||||||
|
|
||||||
|
if (descriptor == ANNOTATION_DESCRIPTOR && result != null) {
|
||||||
|
result = KotlinClassMetadataRemappingAnnotationVisitor(remapper, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 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.kotlin.remapping
|
||||||
|
|
||||||
|
import net.fabricmc.tinyremapper.TinyRemapper
|
||||||
|
import net.fabricmc.tinyremapper.api.TrClass
|
||||||
|
import org.objectweb.asm.ClassVisitor
|
||||||
|
|
||||||
|
object KotlinMetadataTinyRemapperExtension : TinyRemapper.ApplyVisitorProvider, TinyRemapper.Extension {
|
||||||
|
override fun insertApplyVisitor(cls: TrClass, next: ClassVisitor): ClassVisitor {
|
||||||
|
return KotlinMetadataRemappingClassVisitor(cls.environment.remapper, next)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun attach(builder: TinyRemapper.Builder) {
|
||||||
|
builder.extraPreApplyVisitor(this)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,359 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 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.kotlin.remapping
|
||||||
|
|
||||||
|
import kotlinx.metadata.ClassName
|
||||||
|
import kotlinx.metadata.Flags
|
||||||
|
import kotlinx.metadata.KmAnnotation
|
||||||
|
import kotlinx.metadata.KmClassExtensionVisitor
|
||||||
|
import kotlinx.metadata.KmClassVisitor
|
||||||
|
import kotlinx.metadata.KmConstructorExtensionVisitor
|
||||||
|
import kotlinx.metadata.KmConstructorVisitor
|
||||||
|
import kotlinx.metadata.KmContractVisitor
|
||||||
|
import kotlinx.metadata.KmEffectExpressionVisitor
|
||||||
|
import kotlinx.metadata.KmEffectInvocationKind
|
||||||
|
import kotlinx.metadata.KmEffectType
|
||||||
|
import kotlinx.metadata.KmEffectVisitor
|
||||||
|
import kotlinx.metadata.KmExtensionType
|
||||||
|
import kotlinx.metadata.KmFunctionExtensionVisitor
|
||||||
|
import kotlinx.metadata.KmFunctionVisitor
|
||||||
|
import kotlinx.metadata.KmLambdaVisitor
|
||||||
|
import kotlinx.metadata.KmPropertyExtensionVisitor
|
||||||
|
import kotlinx.metadata.KmPropertyVisitor
|
||||||
|
import kotlinx.metadata.KmTypeAliasVisitor
|
||||||
|
import kotlinx.metadata.KmTypeExtensionVisitor
|
||||||
|
import kotlinx.metadata.KmTypeParameterExtensionVisitor
|
||||||
|
import kotlinx.metadata.KmTypeParameterVisitor
|
||||||
|
import kotlinx.metadata.KmTypeVisitor
|
||||||
|
import kotlinx.metadata.KmValueParameterVisitor
|
||||||
|
import kotlinx.metadata.KmVariance
|
||||||
|
import kotlinx.metadata.jvm.JvmClassExtensionVisitor
|
||||||
|
import kotlinx.metadata.jvm.JvmConstructorExtensionVisitor
|
||||||
|
import kotlinx.metadata.jvm.JvmFieldSignature
|
||||||
|
import kotlinx.metadata.jvm.JvmFunctionExtensionVisitor
|
||||||
|
import kotlinx.metadata.jvm.JvmMethodSignature
|
||||||
|
import kotlinx.metadata.jvm.JvmPropertyExtensionVisitor
|
||||||
|
import kotlinx.metadata.jvm.JvmTypeExtensionVisitor
|
||||||
|
import kotlinx.metadata.jvm.JvmTypeParameterExtensionVisitor
|
||||||
|
import org.objectweb.asm.commons.Remapper
|
||||||
|
|
||||||
|
class RemappingKmVisitors(private val remapper: Remapper) {
|
||||||
|
private fun remapJvmMethodSignature(signature: JvmMethodSignature?): JvmMethodSignature? {
|
||||||
|
if (signature != null) {
|
||||||
|
return JvmMethodSignature(signature.name, remapper.mapMethodDesc(signature.desc))
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun remapJvmFieldSignature(signature: JvmFieldSignature?): JvmFieldSignature? {
|
||||||
|
if (signature != null) {
|
||||||
|
return JvmFieldSignature(signature.name, remapper.mapDesc(signature.desc))
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class RemappingKmClassVisitor(delegate: KmClassVisitor?) : KmClassVisitor(delegate) {
|
||||||
|
override fun visit(flags: Flags, name: ClassName) {
|
||||||
|
super.visit(flags, remapper.map(name))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitNestedClass(name: String) {
|
||||||
|
super.visitNestedClass(remapper.map(name))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitSealedSubclass(name: ClassName) {
|
||||||
|
super.visitSealedSubclass(remapper.map(name))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitSupertype(flags: Flags): KmTypeVisitor {
|
||||||
|
return RemappingKmTypeVisitor(super.visitSupertype(flags))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitFunction(flags: Flags, name: String): KmFunctionVisitor {
|
||||||
|
return RemappingKmFunctionVisitor(super.visitFunction(flags, name))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitInlineClassUnderlyingType(flags: Flags): KmTypeVisitor {
|
||||||
|
return RemappingKmTypeVisitor(super.visitInlineClassUnderlyingType(flags))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitProperty(flags: Flags, name: String, getterFlags: Flags, setterFlags: Flags): KmPropertyVisitor {
|
||||||
|
return RemappingKmPropertyVisitor(super.visitProperty(flags, name, getterFlags, setterFlags))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitTypeAlias(flags: Flags, name: String): KmTypeAliasVisitor {
|
||||||
|
return RemappingKmTypeAliasVisitor(super.visitTypeAlias(flags, name))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitConstructor(flags: Flags): KmConstructorVisitor {
|
||||||
|
return RemappingKmConstructorVisitor(super.visitConstructor(flags))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitExtensions(type: KmExtensionType): KmClassExtensionVisitor {
|
||||||
|
return RemappingJvmClassExtensionVisitor(super.visitExtensions(type) as JvmClassExtensionVisitor?)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitTypeParameter(
|
||||||
|
flags: Flags,
|
||||||
|
name: String,
|
||||||
|
id: Int,
|
||||||
|
variance: KmVariance
|
||||||
|
): KmTypeParameterVisitor {
|
||||||
|
return RemappingKmTypeParameterVisitor(super.visitTypeParameter(flags, name, id, variance))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class RemappingKmLambdaVisitor(delegate: KmLambdaVisitor?) : KmLambdaVisitor(delegate) {
|
||||||
|
override fun visitFunction(flags: Flags, name: String): KmFunctionVisitor {
|
||||||
|
return RemappingKmFunctionVisitor(super.visitFunction(flags, name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class RemappingKmTypeVisitor(delegate: KmTypeVisitor?) : KmTypeVisitor(delegate) {
|
||||||
|
override fun visitClass(name: ClassName) {
|
||||||
|
super.visitClass(remapper.map(name))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitTypeAlias(name: ClassName) {
|
||||||
|
super.visitTypeAlias(remapper.map(name))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitAbbreviatedType(flags: Flags): KmTypeVisitor {
|
||||||
|
return RemappingKmTypeVisitor(super.visitAbbreviatedType(flags))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitArgument(flags: Flags, variance: KmVariance): KmTypeVisitor {
|
||||||
|
return RemappingKmTypeVisitor(super.visitArgument(flags, variance))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitOuterType(flags: Flags): KmTypeVisitor {
|
||||||
|
return RemappingKmTypeVisitor(super.visitOuterType(flags))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitFlexibleTypeUpperBound(flags: Flags, typeFlexibilityId: String?): KmTypeVisitor {
|
||||||
|
return RemappingKmTypeVisitor(super.visitFlexibleTypeUpperBound(flags, typeFlexibilityId))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitExtensions(type: KmExtensionType): KmTypeExtensionVisitor {
|
||||||
|
return RemappingJvmTypeExtensionVisitor(super.visitExtensions(type) as JvmTypeExtensionVisitor?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class RemappingJvmTypeExtensionVisitor(delegate: JvmTypeExtensionVisitor?) : JvmTypeExtensionVisitor(delegate) {
|
||||||
|
override fun visitAnnotation(annotation: KmAnnotation) {
|
||||||
|
super.visitAnnotation(KmAnnotation(remapper.map(annotation.className), annotation.arguments))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class RemappingKmFunctionVisitor(delegate: KmFunctionVisitor?) : KmFunctionVisitor(delegate) {
|
||||||
|
override fun visitReceiverParameterType(flags: Flags): KmTypeVisitor {
|
||||||
|
return RemappingKmTypeVisitor(super.visitReceiverParameterType(flags))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitReturnType(flags: Flags): KmTypeVisitor {
|
||||||
|
return RemappingKmTypeVisitor(super.visitReturnType(flags))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitValueParameter(flags: Flags, name: String): KmValueParameterVisitor {
|
||||||
|
return RemappingKmValueParameterVisitor(super.visitValueParameter(flags, name))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitExtensions(type: KmExtensionType): KmFunctionExtensionVisitor {
|
||||||
|
return RemappingJvmFunctionExtensionVisitor(super.visitExtensions(type) as JvmFunctionExtensionVisitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitContract(): KmContractVisitor {
|
||||||
|
return RemappingKmContractVisitor(super.visitContract())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class RemappingKmContractVisitor(delegate: KmContractVisitor?) : KmContractVisitor(delegate) {
|
||||||
|
override fun visitEffect(type: KmEffectType, invocationKind: KmEffectInvocationKind?): KmEffectVisitor {
|
||||||
|
return RemappingKmEffectVisitor(super.visitEffect(type, invocationKind))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class RemappingKmEffectVisitor(delegate: KmEffectVisitor?) : KmEffectVisitor(delegate) {
|
||||||
|
override fun visitConclusionOfConditionalEffect(): KmEffectExpressionVisitor {
|
||||||
|
return RemappingKmEffectExpressionVisitor(super.visitConclusionOfConditionalEffect())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitConstructorArgument(): KmEffectExpressionVisitor {
|
||||||
|
return RemappingKmEffectExpressionVisitor(super.visitConclusionOfConditionalEffect())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class RemappingKmEffectExpressionVisitor(delegate: KmEffectExpressionVisitor?) : KmEffectExpressionVisitor(delegate) {
|
||||||
|
override fun visitAndArgument(): KmEffectExpressionVisitor {
|
||||||
|
return RemappingKmEffectExpressionVisitor(super.visitAndArgument())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitIsInstanceType(flags: Flags): KmTypeVisitor {
|
||||||
|
return RemappingKmTypeVisitor(super.visitIsInstanceType(flags))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitOrArgument(): KmEffectExpressionVisitor {
|
||||||
|
return RemappingKmEffectExpressionVisitor(super.visitOrArgument())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class RemappingKmPropertyVisitor(delegate: KmPropertyVisitor?) : KmPropertyVisitor(delegate) {
|
||||||
|
override fun visitReceiverParameterType(flags: Flags): KmTypeVisitor {
|
||||||
|
return RemappingKmTypeVisitor(super.visitReceiverParameterType(flags))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitReturnType(flags: Flags): KmTypeVisitor {
|
||||||
|
return RemappingKmTypeVisitor(super.visitReturnType(flags))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitSetterParameter(flags: Flags, name: String): KmValueParameterVisitor {
|
||||||
|
return RemappingKmValueParameterVisitor(super.visitSetterParameter(flags, name))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitExtensions(type: KmExtensionType): KmPropertyExtensionVisitor {
|
||||||
|
return RemappingJvmPropertyExtensionVisitor(super.visitExtensions(type) as JvmPropertyExtensionVisitor?)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitTypeParameter(
|
||||||
|
flags: Flags,
|
||||||
|
name: String,
|
||||||
|
id: Int,
|
||||||
|
variance: KmVariance
|
||||||
|
): KmTypeParameterVisitor {
|
||||||
|
return RemappingKmTypeParameterVisitor(super.visitTypeParameter(flags, name, id, variance))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class RemappingJvmPropertyExtensionVisitor(delegate: JvmPropertyExtensionVisitor?) : JvmPropertyExtensionVisitor(delegate) {
|
||||||
|
override fun visit(
|
||||||
|
jvmFlags: Flags,
|
||||||
|
fieldSignature: JvmFieldSignature?,
|
||||||
|
getterSignature: JvmMethodSignature?,
|
||||||
|
setterSignature: JvmMethodSignature?
|
||||||
|
) {
|
||||||
|
super.visit(jvmFlags, remapJvmFieldSignature(fieldSignature), remapJvmMethodSignature(getterSignature), remapJvmMethodSignature(setterSignature))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitSyntheticMethodForAnnotations(signature: JvmMethodSignature?) {
|
||||||
|
super.visitSyntheticMethodForAnnotations(remapJvmMethodSignature(signature))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitSyntheticMethodForDelegate(signature: JvmMethodSignature?) {
|
||||||
|
super.visitSyntheticMethodForDelegate(remapJvmMethodSignature(signature))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class RemappingKmTypeParameterVisitor(delegate: KmTypeParameterVisitor?) : KmTypeParameterVisitor(delegate) {
|
||||||
|
override fun visitExtensions(type: KmExtensionType): KmTypeParameterExtensionVisitor {
|
||||||
|
return RemappingJvmTypeParameterExtensionVisitor(super.visitExtensions(type) as JvmTypeParameterExtensionVisitor?)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitUpperBound(flags: Flags): KmTypeVisitor {
|
||||||
|
return RemappingKmTypeVisitor(super.visitUpperBound(flags))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class RemappingJvmTypeParameterExtensionVisitor(delegate: JvmTypeParameterExtensionVisitor?) : JvmTypeParameterExtensionVisitor(delegate) {
|
||||||
|
override fun visitAnnotation(annotation: KmAnnotation) {
|
||||||
|
super.visitAnnotation(KmAnnotation(remapper.map(annotation.className), annotation.arguments))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class RemappingKmValueParameterVisitor(delegate: KmValueParameterVisitor?) : KmValueParameterVisitor(delegate) {
|
||||||
|
override fun visitType(flags: Flags): KmTypeVisitor {
|
||||||
|
return RemappingKmTypeVisitor(super.visitType(flags))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitVarargElementType(flags: Flags): KmTypeVisitor {
|
||||||
|
return RemappingKmTypeVisitor(super.visitVarargElementType(flags))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class RemappingKmTypeAliasVisitor(delegate: KmTypeAliasVisitor?) : KmTypeAliasVisitor(delegate) {
|
||||||
|
override fun visitExpandedType(flags: Flags): KmTypeVisitor {
|
||||||
|
return RemappingKmTypeVisitor(super.visitExpandedType(flags))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitTypeParameter(
|
||||||
|
flags: Flags,
|
||||||
|
name: String,
|
||||||
|
id: Int,
|
||||||
|
variance: KmVariance
|
||||||
|
): KmTypeParameterVisitor {
|
||||||
|
return RemappingKmTypeParameterVisitor(super.visitTypeParameter(flags, name, id, variance))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitUnderlyingType(flags: Flags): KmTypeVisitor {
|
||||||
|
return RemappingKmTypeVisitor(super.visitUnderlyingType(flags))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitAnnotation(annotation: KmAnnotation) {
|
||||||
|
super.visitAnnotation(KmAnnotation(remapper.map(annotation.className), annotation.arguments))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class RemappingJvmFunctionExtensionVisitor(delegate: JvmFunctionExtensionVisitor?) : JvmFunctionExtensionVisitor(delegate) {
|
||||||
|
override fun visit(signature: JvmMethodSignature?) {
|
||||||
|
super.visit(remapJvmMethodSignature(signature))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitLambdaClassOriginName(internalName: String) {
|
||||||
|
super.visitLambdaClassOriginName(remapper.map(internalName))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class RemappingJvmClassExtensionVisitor(delegate: JvmClassExtensionVisitor?) : JvmClassExtensionVisitor(delegate) {
|
||||||
|
override fun visitAnonymousObjectOriginName(internalName: String) {
|
||||||
|
super.visitAnonymousObjectOriginName(remapper.map(internalName))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitLocalDelegatedProperty(
|
||||||
|
flags: Flags,
|
||||||
|
name: String,
|
||||||
|
getterFlags: Flags,
|
||||||
|
setterFlags: Flags
|
||||||
|
): KmPropertyVisitor {
|
||||||
|
return RemappingKmPropertyVisitor(super.visitLocalDelegatedProperty(flags, name, getterFlags, setterFlags))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class RemappingKmConstructorVisitor(delegate: KmConstructorVisitor?) : KmConstructorVisitor(delegate) {
|
||||||
|
override fun visitExtensions(type: KmExtensionType): KmConstructorExtensionVisitor {
|
||||||
|
return RemappingJvmConstructorExtensionVisitor(super.visitExtensions(type) as JvmConstructorExtensionVisitor?)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitValueParameter(flags: Flags, name: String): KmValueParameterVisitor {
|
||||||
|
return RemappingKmValueParameterVisitor(super.visitValueParameter(flags, name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class RemappingJvmConstructorExtensionVisitor(delegate: JvmConstructorExtensionVisitor?) : JvmConstructorExtensionVisitor(delegate) {
|
||||||
|
override fun visit(signature: JvmMethodSignature?) {
|
||||||
|
super.visit(remapJvmMethodSignature(signature))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,7 +28,7 @@ import org.gradle.util.GradleVersion
|
||||||
|
|
||||||
class LoomTestConstants {
|
class LoomTestConstants {
|
||||||
public final static String DEFAULT_GRADLE = GradleVersion.current().getVersion()
|
public final static String DEFAULT_GRADLE = GradleVersion.current().getVersion()
|
||||||
public final static String PRE_RELEASE_GRADLE = "7.5-20220110230252+0000"
|
public final static String PRE_RELEASE_GRADLE = "7.5-20220116010338+0000"
|
||||||
|
|
||||||
public final static String[] STANDARD_TEST_VERSIONS = [DEFAULT_GRADLE, PRE_RELEASE_GRADLE]
|
public final static String[] STANDARD_TEST_VERSIONS = [DEFAULT_GRADLE, PRE_RELEASE_GRADLE]
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
package net.fabricmc.loom.test.integration
|
package net.fabricmc.loom.test.integration
|
||||||
|
|
||||||
import net.fabricmc.loom.test.util.GradleProjectTestTrait
|
import net.fabricmc.loom.test.util.GradleProjectTestTrait
|
||||||
|
import net.fabricmc.loom.test.util.ServerRunner
|
||||||
import spock.lang.Specification
|
import spock.lang.Specification
|
||||||
import spock.lang.Unroll
|
import spock.lang.Unroll
|
||||||
|
|
||||||
|
@ -36,12 +37,17 @@ class KotlinTest extends Specification implements GradleProjectTestTrait {
|
||||||
def "kotlin build (gradle #version)"() {
|
def "kotlin build (gradle #version)"() {
|
||||||
setup:
|
setup:
|
||||||
def gradle = gradleProject(project: "kotlin", version: version)
|
def gradle = gradleProject(project: "kotlin", version: version)
|
||||||
|
def server = ServerRunner.create(gradle.projectDir, "1.16.5")
|
||||||
|
.withMod(gradle.getOutputFile("fabric-example-mod-0.0.1.jar"))
|
||||||
|
.downloadMod(ServerRunner.FABRIC_LANG_KOTLIN, "fabric-language-kotlin-1.7.1+kotlin.1.6.10.jar")
|
||||||
|
|
||||||
when:
|
when:
|
||||||
def result = gradle.run(task: "build")
|
def result = gradle.run(task: "build")
|
||||||
|
def serverResult = server.run()
|
||||||
|
|
||||||
then:
|
then:
|
||||||
result.task(":build").outcome == SUCCESS
|
result.task(":build").outcome == SUCCESS
|
||||||
|
serverResult.successful()
|
||||||
|
|
||||||
where:
|
where:
|
||||||
version << STANDARD_TEST_VERSIONS
|
version << STANDARD_TEST_VERSIONS
|
||||||
|
|
|
@ -34,6 +34,7 @@ class ServerRunner {
|
||||||
"1.16.5": "https://github.com/FabricMC/fabric/releases/download/0.37.1%2B1.16/fabric-api-0.37.1+1.16.jar",
|
"1.16.5": "https://github.com/FabricMC/fabric/releases/download/0.37.1%2B1.16/fabric-api-0.37.1+1.16.jar",
|
||||||
"1.17.1": "https://github.com/FabricMC/fabric/releases/download/0.37.1%2B1.17/fabric-api-0.37.1+1.17.jar"
|
"1.17.1": "https://github.com/FabricMC/fabric/releases/download/0.37.1%2B1.17/fabric-api-0.37.1+1.17.jar"
|
||||||
]
|
]
|
||||||
|
static final String FABRIC_LANG_KOTLIN = "https://maven.fabricmc.net/net/fabricmc/fabric-language-kotlin/1.7.1%2Bkotlin.1.6.10/fabric-language-kotlin-1.7.1%2Bkotlin.1.6.10.jar"
|
||||||
|
|
||||||
final File serverDir
|
final File serverDir
|
||||||
final String minecraftVersion
|
final String minecraftVersion
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 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.kotlin
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
import java.io.PrintWriter
|
||||||
|
import java.io.StringWriter
|
||||||
|
import java.nio.file.Paths
|
||||||
|
import net.fabricmc.loom.kotlin.remapping.KotlinMetadataRemappingClassVisitor
|
||||||
|
import net.fabricmc.loom.util.TinyRemapperHelper
|
||||||
|
import net.fabricmc.mappingio.MappingReader
|
||||||
|
import net.fabricmc.mappingio.tree.MemoryMappingTree
|
||||||
|
import net.fabricmc.tinyremapper.IMappingProvider
|
||||||
|
import net.fabricmc.tinyremapper.TinyRemapper
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.objectweb.asm.ClassReader
|
||||||
|
import org.objectweb.asm.Opcodes
|
||||||
|
import org.objectweb.asm.util.Textifier
|
||||||
|
import org.objectweb.asm.util.TraceClassVisitor
|
||||||
|
|
||||||
|
// See: https://github.com/JetBrains/kotlin/blob/master/libraries/kotlinx-metadata/jvm/test/kotlinx/metadata/test/MetadataSmokeTest.kt#L67
|
||||||
|
class KotlinClassMetadataRemappingAnnotationVisitorTest {
|
||||||
|
/*
|
||||||
|
val test = KmClass()
|
||||||
|
klass.accept(RemappingKmClassVisitor(remapper, test))
|
||||||
|
println(GsonBuilder().setPrettyPrinting().create().toJson(test))
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun simpleTest() {
|
||||||
|
val inputPosInChunk = getClassBytes("PosInChunk")
|
||||||
|
|
||||||
|
val classReader = ClassReader(inputPosInChunk)
|
||||||
|
|
||||||
|
val tinyRemapper = TinyRemapper.newRemapper()
|
||||||
|
.withMappings(readMappings("PosInChunk"))
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val stringWriter = StringWriter()
|
||||||
|
val traceClassVisitor = TraceClassVisitor(null, TextifierImpl(), PrintWriter(stringWriter))
|
||||||
|
|
||||||
|
classReader.accept(KotlinMetadataRemappingClassVisitor(tinyRemapper.environment.remapper, traceClassVisitor), 0)
|
||||||
|
|
||||||
|
val d2Regex = Regex("(d2=)(.*)")
|
||||||
|
val asm = stringWriter.toString()
|
||||||
|
println(d2Regex.find(asm)?.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getClassBytes(name: String): ByteArray {
|
||||||
|
return File("src/test/resources/classes/$name.class").readBytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun readMappings(name: String): IMappingProvider {
|
||||||
|
val mappingTree = MemoryMappingTree()
|
||||||
|
MappingReader.read(Paths.get("src/test/resources/mappings/$name.mappings"), mappingTree)
|
||||||
|
return TinyRemapperHelper.create(mappingTree, "named", "intermediary", false)
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TextifierImpl : Textifier(Opcodes.ASM9)
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,220 @@
|
||||||
|
tiny 2 0 intermediary named
|
||||||
|
c net/minecraft/class_2338 net/minecraft/util/math/BlockPos
|
||||||
|
c Represents the position of a block in a three-dimensional volume.\n\n<p>The position is integer-valued.\n\n<p>A block position may be mutable; hence, when using block positions\nobtained from other places as map keys, etc., you should call {@link\n#toImmutable()} to obtain an immutable block position.
|
||||||
|
f J field_10976 BITS_X
|
||||||
|
f Lcom/mojang/serialization/Codec; field_25064 CODEC
|
||||||
|
f Lorg/apache/logging/log4j/Logger; field_18789 LOGGER
|
||||||
|
f Lnet/minecraft/class_2338; field_10980 ORIGIN
|
||||||
|
c The block position which x, y, and z values are all zero.
|
||||||
|
f I field_10983 BIT_SHIFT_Z
|
||||||
|
f I field_10975 SIZE_BITS_Y
|
||||||
|
f J field_10974 BITS_Y
|
||||||
|
f I field_10978 SIZE_BITS_X
|
||||||
|
f I field_10981 BIT_SHIFT_X
|
||||||
|
f J field_10973 BITS_Z
|
||||||
|
f I field_10977 SIZE_BITS_Z
|
||||||
|
m ([I)Lnet/minecraft/class_2338; method_29095 method_29095
|
||||||
|
p 0 values
|
||||||
|
m (Ljava/util/Random;IIIIIII)Ljava/lang/Iterable; method_27156 iterateRandomly
|
||||||
|
c Iterates through {@code count} random block positions in the given area.\n\n<p>The iterator yields positions in no specific order. The same position\nmay be returned multiple times by the iterator.
|
||||||
|
p 6 maxY
|
||||||
|
c the maximum y value for returned positions
|
||||||
|
p 7 maxZ
|
||||||
|
c the maximum z value for returned positions
|
||||||
|
p 4 minZ
|
||||||
|
c the minimum z value for returned positions
|
||||||
|
p 5 maxX
|
||||||
|
c the maximum x value for returned positions
|
||||||
|
p 2 minX
|
||||||
|
c the minimum x value for returned positions
|
||||||
|
p 3 minY
|
||||||
|
c the minimum y value for returned positions
|
||||||
|
p 0 random
|
||||||
|
c the {@link Random} object used to compute new positions
|
||||||
|
p 1 count
|
||||||
|
c the number of positions to iterate
|
||||||
|
m (JIII)J method_10096 add
|
||||||
|
p 0 value
|
||||||
|
p 3 y
|
||||||
|
p 2 x
|
||||||
|
p 4 z
|
||||||
|
m ()Lnet/minecraft/class_2338$class_2339; method_25503 mutableCopy
|
||||||
|
c Returns a mutable copy of this block position.\n\n<p>If this block position is a mutable one, mutation to this block\nposition won't affect the returned position.
|
||||||
|
m (I)Lnet/minecraft/class_2338; method_10088 west
|
||||||
|
p 1 distance
|
||||||
|
m (I)Lnet/minecraft/class_2338; method_10076 north
|
||||||
|
p 1 distance
|
||||||
|
m ()J method_10063 asLong
|
||||||
|
m ()Lnet/minecraft/class_2338; method_10084 up
|
||||||
|
m (Lnet/minecraft/class_2382;)V <init> <init>
|
||||||
|
p 1 pos
|
||||||
|
m (Lnet/minecraft/class_2338;III)Ljava/util/stream/Stream; method_25998 streamOutwards
|
||||||
|
p 0 center
|
||||||
|
p 3 maxZ
|
||||||
|
p 1 maxX
|
||||||
|
p 2 maxY
|
||||||
|
m (Lnet/minecraft/class_2374;)V <init> <init>
|
||||||
|
p 1 pos
|
||||||
|
m (Lnet/minecraft/class_2382;)Lnet/minecraft/class_2338; method_10081 add
|
||||||
|
m (Lnet/minecraft/class_238;)Ljava/util/stream/Stream; method_29715 stream
|
||||||
|
p 0 box
|
||||||
|
m ()Lnet/minecraft/class_2338; method_10072 south
|
||||||
|
m (III)Lnet/minecraft/class_2338; method_10069 add
|
||||||
|
m (I)Lnet/minecraft/class_2338; method_35830 multiply
|
||||||
|
m (Ljava/util/Random;ILnet/minecraft/class_2338;I)Ljava/lang/Iterable; method_34848 iterateRandomly
|
||||||
|
c Iterates through {@code count} random block positions in a given range around the given position.\n\n<p>The iterator yields positions in no specific order. The same position\nmay be returned multiple times by the iterator.
|
||||||
|
p 0 random
|
||||||
|
c the {@link Random} object used to compute new positions
|
||||||
|
p 1 count
|
||||||
|
c the number of positions to iterate
|
||||||
|
p 2 around
|
||||||
|
c the {@link BlockPos} to iterate around
|
||||||
|
p 3 range
|
||||||
|
c the maximum distance from the given pos in any axis
|
||||||
|
m (I)Lnet/minecraft/class_2338; method_10077 south
|
||||||
|
p 1 distance
|
||||||
|
m (I)Lnet/minecraft/class_2338; method_10089 east
|
||||||
|
p 1 distance
|
||||||
|
m (J)J method_10091 removeChunkSectionLocalY
|
||||||
|
p 0 y
|
||||||
|
m (J)I method_10071 unpackLongY
|
||||||
|
p 0 packedPos
|
||||||
|
m (Lnet/minecraft/class_2338;ILnet/minecraft/class_2350;Lnet/minecraft/class_2350;)Ljava/lang/Iterable; method_30512 iterateInSquare
|
||||||
|
c Iterates block positions around the {@code center} in a square of\n({@code 2 * radius + 1}) by ({@code 2 * radius + 1}). The blocks\nare iterated in a (square) spiral around the center.\n\n<p>The first block returned is the center, then the iterator moves\na block towards the first direction, followed by moving along\nthe second direction.\n\n@throws IllegalStateException when the 2 directions lie on the same axis
|
||||||
|
p 2 firstDirection
|
||||||
|
c the direction the iterator moves first
|
||||||
|
p 3 secondDirection
|
||||||
|
c the direction the iterator moves after the first
|
||||||
|
p 0 center
|
||||||
|
c the center of iteration
|
||||||
|
p 1 radius
|
||||||
|
c the maximum chebychev distance
|
||||||
|
m (J)I method_10083 unpackLongZ
|
||||||
|
p 0 packedPos
|
||||||
|
m (J)Lnet/minecraft/class_2338; method_10092 fromLong
|
||||||
|
p 0 packedPos
|
||||||
|
m (I)Lnet/minecraft/class_2338; method_33096 withY
|
||||||
|
p 1 y
|
||||||
|
m (Ljava/util/stream/IntStream;)Lcom/mojang/serialization/DataResult; method_29094 method_29094
|
||||||
|
p 0 stream
|
||||||
|
m (Lnet/minecraft/class_2338;Lnet/minecraft/class_2338;)Ljava/util/stream/Stream; method_20437 stream
|
||||||
|
p 1 end
|
||||||
|
p 0 start
|
||||||
|
m (Lnet/minecraft/class_2350;)Lnet/minecraft/class_2338; method_10093 offset
|
||||||
|
m (I)Lnet/minecraft/class_2338; method_10086 up
|
||||||
|
p 1 distance
|
||||||
|
m (III)J method_10064 asLong
|
||||||
|
p 0 x
|
||||||
|
p 1 y
|
||||||
|
p 2 z
|
||||||
|
m ()Lnet/minecraft/class_2338; method_10074 down
|
||||||
|
m (IIIIII)Ljava/lang/Iterable; method_10094 iterate
|
||||||
|
p 1 startY
|
||||||
|
p 0 startX
|
||||||
|
p 3 endX
|
||||||
|
p 2 startZ
|
||||||
|
p 5 endZ
|
||||||
|
p 4 endY
|
||||||
|
m ()Lnet/minecraft/class_2338; method_10062 toImmutable
|
||||||
|
c Returns an immutable block position with the same x, y, and z as this\nposition.\n\n<p>This method should be called when a block position is used as map\nkeys as to prevent side effects of mutations of mutable block positions.
|
||||||
|
m ()Lnet/minecraft/class_2338; method_10078 east
|
||||||
|
m (Lnet/minecraft/class_3341;)Ljava/util/stream/Stream; method_23627 stream
|
||||||
|
p 0 box
|
||||||
|
m (Lnet/minecraft/class_2350;I)Lnet/minecraft/class_2338; method_10079 offset
|
||||||
|
m (Lnet/minecraft/class_2338;III)Ljava/lang/Iterable; method_25996 iterateOutwards
|
||||||
|
c Iterates block positions around the {@code center}. The iteration order\nis mainly based on the manhattan distance of the position from the\ncenter.\n\n<p>For the same manhattan distance, the positions are iterated by y\noffset, from negative to positive. For the same y offset, the positions\nare iterated by x offset, from negative to positive. For the two\npositions with the same x and y offsets and the same manhattan distance,\nthe one with a positive z offset is visited first before the one with a\nnegative z offset.
|
||||||
|
p 2 rangeY
|
||||||
|
c the maximum y difference from the center
|
||||||
|
p 3 rangeZ
|
||||||
|
c the maximum z difference from the center
|
||||||
|
p 0 center
|
||||||
|
c the center of iteration
|
||||||
|
p 1 rangeX
|
||||||
|
c the maximum x difference from the center
|
||||||
|
m (Lnet/minecraft/class_2338;)Ljava/util/stream/IntStream; method_29093 method_29093
|
||||||
|
p 0 pos
|
||||||
|
m (Lnet/minecraft/class_2382;)Lnet/minecraft/class_2338; method_10059 subtract
|
||||||
|
m (Lnet/minecraft/class_2382;)Lnet/minecraft/class_2338; method_10075 crossProduct
|
||||||
|
p 1 pos
|
||||||
|
m (IIIIII)Ljava/util/stream/Stream; method_17962 stream
|
||||||
|
p 1 startY
|
||||||
|
p 0 startX
|
||||||
|
p 3 endX
|
||||||
|
p 2 startZ
|
||||||
|
p 5 endZ
|
||||||
|
p 4 endY
|
||||||
|
m (Lnet/minecraft/class_2350$class_2351;I)Lnet/minecraft/class_2338; method_30513 offset
|
||||||
|
m (Lnet/minecraft/class_2338;IILjava/util/function/Predicate;)Ljava/util/Optional; method_25997 findClosest
|
||||||
|
p 3 condition
|
||||||
|
p 1 horizontalRange
|
||||||
|
p 2 verticalRange
|
||||||
|
p 0 pos
|
||||||
|
m (I)Lnet/minecraft/class_2338; method_10087 down
|
||||||
|
m (DDD)Lnet/minecraft/class_2338; method_10080 add
|
||||||
|
m (Lnet/minecraft/class_2338;Lnet/minecraft/class_2338;)Ljava/lang/Iterable; method_10097 iterate
|
||||||
|
p 1 end
|
||||||
|
p 0 start
|
||||||
|
m ()Lnet/minecraft/class_2338; method_10095 north
|
||||||
|
m ()Lnet/minecraft/class_2338; method_10067 west
|
||||||
|
m (J)I method_10061 unpackLongX
|
||||||
|
p 0 packedPos
|
||||||
|
m (Lnet/minecraft/class_243;)V <init> <init>
|
||||||
|
p 1 pos
|
||||||
|
m (JLnet/minecraft/class_2350;)J method_10060 offset
|
||||||
|
p 2 direction
|
||||||
|
p 0 value
|
||||||
|
m (Lnet/minecraft/class_2470;)Lnet/minecraft/class_2338; method_10070 rotate
|
||||||
|
p 1 rotationrotate
|
||||||
|
c net/minecraft/class_1923 net/minecraft/util/math/ChunkPos
|
||||||
|
f I field_9180 z
|
||||||
|
f I field_9181 x
|
||||||
|
f Lnet/minecraft/class_1923; field_35107 ORIGIN
|
||||||
|
f J field_17348 MARKER
|
||||||
|
m ()Lnet/minecraft/class_2338; method_8323 getStartPos
|
||||||
|
m (Lnet/minecraft/class_1923;)I method_24022 getChebyshevDistance
|
||||||
|
p 1 pos
|
||||||
|
m ()J method_8324 toLong
|
||||||
|
m (II)J method_8331 toLong
|
||||||
|
p 1 chunkZ
|
||||||
|
p 0 chunkX
|
||||||
|
m ()I method_17887 getRegionRelativeX
|
||||||
|
m ()I method_17885 getRegionX
|
||||||
|
m (J)V <init> <init>
|
||||||
|
p 1 pos
|
||||||
|
m ()I method_33940 getCenterX
|
||||||
|
m (J)I method_8325 getPackedX
|
||||||
|
p 0 pos
|
||||||
|
m (Lnet/minecraft/class_2338;)V <init> <init>
|
||||||
|
p 1 pos
|
||||||
|
m ()I method_33942 getCenterZ
|
||||||
|
m ()I method_8326 getStartX
|
||||||
|
m ()I method_8328 getStartZ
|
||||||
|
m (III)Lnet/minecraft/class_2338; method_35231 getBlockPos
|
||||||
|
p 2 y
|
||||||
|
p 1 offsetX
|
||||||
|
p 3 offsetZ
|
||||||
|
m (I)I method_33939 getOffsetX
|
||||||
|
p 1 offset
|
||||||
|
m (Lnet/minecraft/class_1923;Lnet/minecraft/class_1923;)Ljava/util/stream/Stream; method_19281 stream
|
||||||
|
p 0 pos1
|
||||||
|
p 1 pos2
|
||||||
|
m (Lnet/minecraft/class_2338;)J method_37232 toLong
|
||||||
|
p 0 pos
|
||||||
|
m (I)I method_33941 getOffsetZ
|
||||||
|
p 1 offset
|
||||||
|
m ()I method_17888 getRegionRelativeZ
|
||||||
|
m (I)Lnet/minecraft/class_2338; method_33943 getCenterAtY
|
||||||
|
p 1 y
|
||||||
|
m ()I method_17886 getRegionZ
|
||||||
|
m ()I method_8327 getEndX
|
||||||
|
m (II)V <init> <init>
|
||||||
|
p 2 z
|
||||||
|
p 1 x
|
||||||
|
m ()I method_8329 getEndZ
|
||||||
|
m (J)I method_8332 getPackedZ
|
||||||
|
p 0 pos
|
||||||
|
m (Lnet/minecraft/class_1923;I)Ljava/util/stream/Stream; method_19280 stream
|
||||||
|
p 0 center
|
||||||
|
p 1 radius
|
||||||
|
m (Ljava/lang/Object;)Z equals equals
|
||||||
|
p 1 o
|
|
@ -1,7 +1,8 @@
|
||||||
import java.util.Properties
|
import java.util.Properties
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm") version "1.5.21"
|
kotlin("jvm") version "1.6.10"
|
||||||
|
kotlin("plugin.serialization") version "1.6.10"
|
||||||
id("fabric-loom")
|
id("fabric-loom")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +16,6 @@ version = "0.0.1"
|
||||||
dependencies {
|
dependencies {
|
||||||
minecraft(group = "com.mojang", name = "minecraft", version = "1.16.5")
|
minecraft(group = "com.mojang", name = "minecraft", version = "1.16.5")
|
||||||
mappings(group = "net.fabricmc", name = "yarn", version = "1.16.5+build.5", classifier = "v2")
|
mappings(group = "net.fabricmc", name = "yarn", version = "1.16.5+build.5", classifier = "v2")
|
||||||
modImplementation("net.fabricmc:fabric-loader:0.11.2")
|
modImplementation("net.fabricmc:fabric-loader:0.12.12")
|
||||||
modImplementation(group = "net.fabricmc", name = "fabric-language-kotlin", version = "1.6.3+kotlin.1.5.21")
|
modImplementation(group = "net.fabricmc", name = "fabric-language-kotlin", version = "1.7.1+kotlin.1.6.10")
|
||||||
}
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package net.fabricmc.language.kotlin
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
import net.minecraft.util.Identifier
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class ExampleSerializable(@Serializable(with = IdentifierSerializer::class) val identifier: Identifier, val test: Double) {
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package net.fabricmc.language.kotlin
|
||||||
|
|
||||||
|
import kotlinx.serialization.KSerializer
|
||||||
|
import kotlinx.serialization.encoding.Decoder
|
||||||
|
import kotlinx.serialization.encoding.Encoder
|
||||||
|
import kotlinx.serialization.descriptors.PrimitiveKind
|
||||||
|
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
|
||||||
|
|
||||||
|
import net.minecraft.util.Identifier
|
||||||
|
|
||||||
|
// Based on https://kotlin.github.io/kotlinx.serialization/kotlinx-serialization-core/kotlinx-serialization-core/kotlinx.serialization.descriptors/-primitive-serial-descriptor.html
|
||||||
|
class IdentifierSerializer : KSerializer<Identifier> {
|
||||||
|
override val descriptor =
|
||||||
|
PrimitiveSerialDescriptor("net.fabricmc.language.kotlin.IdentifierSerializer", PrimitiveKind.STRING)
|
||||||
|
|
||||||
|
override fun deserialize(decoder: Decoder): Identifier {
|
||||||
|
val split = decoder.decodeString().split(':')
|
||||||
|
return Identifier(split[0], split[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun serialize(encoder: Encoder, value: Identifier) {
|
||||||
|
encoder.encodeString("${value.namespace}:${value.path}")
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package net.fabricmc.language.kotlin
|
||||||
|
|
||||||
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.util.math.ChunkPos
|
||||||
|
|
||||||
|
data class PosInChunk(val x: Int, val y: Int, val z: Int) {
|
||||||
|
constructor(blockPos: BlockPos) : this(blockPos.x and 15, blockPos.y, blockPos.z and 15)
|
||||||
|
|
||||||
|
fun getBlockPos(chunkPos: ChunkPos) = BlockPos(chunkPos.startX + x, y, chunkPos.startZ + z)
|
||||||
|
}
|
|
@ -2,14 +2,22 @@ package net.fabricmc.language.kotlin
|
||||||
|
|
||||||
import net.fabricmc.api.ModInitializer
|
import net.fabricmc.api.ModInitializer
|
||||||
import org.apache.logging.log4j.LogManager
|
import org.apache.logging.log4j.LogManager
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
import kotlinx.serialization.json.*
|
||||||
|
|
||||||
|
import net.minecraft.util.Identifier
|
||||||
|
|
||||||
class TestModClass : ModInitializer {
|
class TestModClass : ModInitializer {
|
||||||
|
|
||||||
val logger = LogManager.getFormatterLogger("KotlinLanguageTest")
|
val logger = LogManager.getFormatterLogger("KotlinLanguageTest")
|
||||||
|
|
||||||
override fun onInitialize() {
|
override fun onInitialize() {
|
||||||
|
val json = Json.encodeToString(ExampleSerializable(Identifier("kotlin:hello"), 12.0))
|
||||||
|
val obj = Json.decodeFromString<ExampleSerializable>(json)
|
||||||
|
|
||||||
logger.info("**************************")
|
logger.info("**************************")
|
||||||
logger.info("Hello from Kotlin TestModClass")
|
logger.info("Hello from Kotlin TestModClass")
|
||||||
|
logger.info(json)
|
||||||
|
logger.info(obj)
|
||||||
logger.info("**************************")
|
logger.info("**************************")
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,32 +2,24 @@
|
||||||
"schemaVersion": 1,
|
"schemaVersion": 1,
|
||||||
"id": "modid",
|
"id": "modid",
|
||||||
"version": "${version}",
|
"version": "${version}",
|
||||||
|
|
||||||
"name": "Example Mod",
|
"name": "Example Mod",
|
||||||
"description": "This is an example description! Tell everyone what your mod is about!",
|
"description": "This is an example description! Tell everyone what your mod is about!",
|
||||||
"authors": [
|
|
||||||
"Me!"
|
|
||||||
],
|
|
||||||
"contact": {
|
"contact": {
|
||||||
"homepage": "https://fabricmc.net/",
|
"homepage": "https://fabricmc.net/",
|
||||||
"sources": "https://github.com/FabricMC/fabric-example-mod"
|
"sources": "https://github.com/FabricMC/fabric-example-mod"
|
||||||
},
|
},
|
||||||
|
|
||||||
"license": "CC0-1.0",
|
"license": "CC0-1.0",
|
||||||
|
|
||||||
"environment": "*",
|
"environment": "*",
|
||||||
"entrypoints": {
|
"entrypoints": {
|
||||||
"main": [
|
"main": [
|
||||||
"net.fabricmc.language.kotlin.TestModClass"
|
{
|
||||||
|
"adapter": "kotlin",
|
||||||
|
"value": "net.fabricmc.language.kotlin.TestModClass"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
"depends": {
|
"depends": {
|
||||||
"fabricloader": ">=0.7.4",
|
"fabricloader": ">=0.7.4",
|
||||||
"fabric": "*",
|
|
||||||
"minecraft": "1.16.x"
|
"minecraft": "1.16.x"
|
||||||
},
|
|
||||||
"suggests": {
|
|
||||||
"another-mod": "*"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue