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
|
||||
ij_continuation_indent_size = 8
|
||||
ij_java_imports_layout = $*,|,java.**,|,javax.**,|,*,|,net.fabricmc.**
|
||||
|
|
43
build.gradle
43
build.gradle
|
@ -8,6 +8,7 @@ plugins {
|
|||
id 'checkstyle'
|
||||
id 'jacoco'
|
||||
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"
|
||||
}
|
||||
|
||||
|
@ -19,6 +20,11 @@ tasks.withType(JavaCompile).configureEach {
|
|||
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'
|
||||
archivesBaseName = project.name
|
||||
|
@ -92,6 +98,11 @@ dependencies {
|
|||
// source code remapping
|
||||
implementation ('net.fabricmc:mercury:0.2.4')
|
||||
|
||||
// Kotlin
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.4.1") {
|
||||
transitive = false
|
||||
}
|
||||
|
||||
// Kapt integration
|
||||
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') {
|
||||
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'
|
||||
|
||||
compileOnly 'org.jetbrains:annotations:23.0.0'
|
||||
|
@ -127,6 +141,13 @@ spotless {
|
|||
groovy {
|
||||
licenseHeaderFile(rootProject.file("HEADER")).yearSeparator("-")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
licenseHeaderFile(rootProject.file("HEADER")).yearSeparator("-")
|
||||
targetExclude("**/build.gradle.kts")
|
||||
targetExclude("src/test/resources/projects/*/**")
|
||||
ktlint()
|
||||
}
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
|
@ -172,18 +193,6 @@ import org.w3c.dom.Document
|
|||
import org.w3c.dom.Element
|
||||
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 {
|
||||
publications {
|
||||
plugin(MavenPublication) { publication ->
|
||||
|
@ -192,10 +201,6 @@ publishing {
|
|||
version project.version
|
||||
|
||||
from components.java
|
||||
|
||||
pom.withXml {
|
||||
patchPom(asNode())
|
||||
}
|
||||
}
|
||||
|
||||
// Also publish a snapshot so people can use the latest version if they wish
|
||||
|
@ -205,10 +210,6 @@ publishing {
|
|||
version baseVersion + '-SNAPSHOT'
|
||||
|
||||
from components.java
|
||||
|
||||
pom.withXml {
|
||||
patchPom(asNode())
|
||||
}
|
||||
}
|
||||
|
||||
// Manually crate the plugin marker for snapshot versions
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
name = fabric-loom
|
||||
description = The Gradle plugin for Fabric
|
||||
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.processors.dependency.ModDependencyInfo;
|
||||
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.TinyRemapperHelper;
|
||||
import net.fabricmc.loom.util.ZipUtils;
|
||||
|
@ -134,16 +135,22 @@ public class ModProcessor {
|
|||
private void remapJars(List<ModDependencyInfo> remapList) throws IOException {
|
||||
final LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
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()
|
||||
.stream().map(File::toPath).toArray(Path[]::new);
|
||||
|
||||
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))
|
||||
.renameInvalidLocals(false)
|
||||
.build();
|
||||
.renameInvalidLocals(false);
|
||||
|
||||
if (useKotlinExtension) {
|
||||
builder.extension(KotlinMetadataTinyRemapperExtension.INSTANCE);
|
||||
}
|
||||
|
||||
final TinyRemapper remapper = builder.build();
|
||||
|
||||
for (Path minecraftJar : extension.getMinecraftJars(MappingsNamespace.INTERMEDIARY)) {
|
||||
remapper.readClassPathAsync(minecraftJar);
|
||||
|
|
|
@ -37,6 +37,7 @@ import java.util.Objects;
|
|||
import org.gradle.api.Project;
|
||||
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.kotlin.remapping.KotlinMetadataTinyRemapperExtension;
|
||||
import net.fabricmc.loom.task.AbstractRemapJarTask;
|
||||
import net.fabricmc.loom.util.service.SharedService;
|
||||
import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||
|
@ -52,9 +53,10 @@ public class TinyRemapperService implements SharedService {
|
|||
final LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
final SharedServiceManager sharedServiceManager = SharedServiceManager.get(project);
|
||||
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.
|
||||
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, () -> {
|
||||
List<IMappingProvider> mappings = new ArrayList<>();
|
||||
|
@ -64,7 +66,7 @@ public class TinyRemapperService implements SharedService {
|
|||
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());
|
||||
|
@ -78,7 +80,7 @@ public class TinyRemapperService implements SharedService {
|
|||
// Set to true once remapping has started, once set no inputs can be read.
|
||||
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();
|
||||
|
||||
for (IMappingProvider provider : mappings) {
|
||||
|
@ -89,6 +91,10 @@ public class TinyRemapperService implements SharedService {
|
|||
builder.extension(new net.fabricmc.tinyremapper.extension.mixin.MixinExtension());
|
||||
}
|
||||
|
||||
if (useKotlinExtension) {
|
||||
builder.extension(KotlinMetadataTinyRemapperExtension.INSTANCE);
|
||||
}
|
||||
|
||||
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 {
|
||||
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]
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
package net.fabricmc.loom.test.integration
|
||||
|
||||
import net.fabricmc.loom.test.util.GradleProjectTestTrait
|
||||
import net.fabricmc.loom.test.util.ServerRunner
|
||||
import spock.lang.Specification
|
||||
import spock.lang.Unroll
|
||||
|
||||
|
@ -36,12 +37,17 @@ class KotlinTest extends Specification implements GradleProjectTestTrait {
|
|||
def "kotlin build (gradle #version)"() {
|
||||
setup:
|
||||
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:
|
||||
def result = gradle.run(task: "build")
|
||||
def serverResult = server.run()
|
||||
|
||||
then:
|
||||
result.task(":build").outcome == SUCCESS
|
||||
serverResult.successful()
|
||||
|
||||
where:
|
||||
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.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 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
|
||||
|
||||
plugins {
|
||||
kotlin("jvm") version "1.5.21"
|
||||
kotlin("jvm") version "1.6.10"
|
||||
kotlin("plugin.serialization") version "1.6.10"
|
||||
id("fabric-loom")
|
||||
}
|
||||
|
||||
|
@ -15,6 +16,6 @@ version = "0.0.1"
|
|||
dependencies {
|
||||
minecraft(group = "com.mojang", name = "minecraft", version = "1.16.5")
|
||||
mappings(group = "net.fabricmc", name = "yarn", version = "1.16.5+build.5", classifier = "v2")
|
||||
modImplementation("net.fabricmc:fabric-loader:0.11.2")
|
||||
modImplementation(group = "net.fabricmc", name = "fabric-language-kotlin", version = "1.6.3+kotlin.1.5.21")
|
||||
modImplementation("net.fabricmc:fabric-loader:0.12.12")
|
||||
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 org.apache.logging.log4j.LogManager
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.json.*
|
||||
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
class TestModClass : ModInitializer {
|
||||
|
||||
val logger = LogManager.getFormatterLogger("KotlinLanguageTest")
|
||||
|
||||
override fun onInitialize() {
|
||||
val json = Json.encodeToString(ExampleSerializable(Identifier("kotlin:hello"), 12.0))
|
||||
val obj = Json.decodeFromString<ExampleSerializable>(json)
|
||||
|
||||
logger.info("**************************")
|
||||
logger.info("Hello from Kotlin TestModClass")
|
||||
logger.info(json)
|
||||
logger.info(obj)
|
||||
logger.info("**************************")
|
||||
}
|
||||
}
|
|
@ -2,32 +2,24 @@
|
|||
"schemaVersion": 1,
|
||||
"id": "modid",
|
||||
"version": "${version}",
|
||||
|
||||
"name": "Example Mod",
|
||||
"description": "This is an example description! Tell everyone what your mod is about!",
|
||||
"authors": [
|
||||
"Me!"
|
||||
],
|
||||
"contact": {
|
||||
"homepage": "https://fabricmc.net/",
|
||||
"sources": "https://github.com/FabricMC/fabric-example-mod"
|
||||
},
|
||||
|
||||
"license": "CC0-1.0",
|
||||
|
||||
"environment": "*",
|
||||
"entrypoints": {
|
||||
"main": [
|
||||
"net.fabricmc.language.kotlin.TestModClass"
|
||||
{
|
||||
"adapter": "kotlin",
|
||||
"value": "net.fabricmc.language.kotlin.TestModClass"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"depends": {
|
||||
"fabricloader": ">=0.7.4",
|
||||
"fabric": "*",
|
||||
"minecraft": "1.16.x"
|
||||
},
|
||||
"suggests": {
|
||||
"another-mod": "*"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue