Add tests and task

This commit is contained in:
modmuss50 2024-05-17 19:39:20 +01:00
parent 48cf4b54d0
commit 2a7aa1e312
13 changed files with 575 additions and 126 deletions

View File

@ -60,14 +60,6 @@ configurations {
}
javadocClasspath
decompileClasspath
mappingPoetJar {
transitive = false
}
mappingPoet {
extendsFrom mappingPoetJar
extendsFrom asm
transitive = true
}
}
def unpickMetaFile = file("unpick-definitions/unpick.json")
@ -81,7 +73,6 @@ dependencies {
javadocClasspath "com.google.code.findbugs:jsr305:3.0.2" // for some other jsr annotations
decompileClasspath "net.fabricmc:cfr:${project.cfr_version}"
decompileClasspath "org.vineflower:vineflower:${project.vineflower_version}"
mappingPoetJar "net.fabricmc:mappingpoet:${project.mappingpoet_version}"
asm "org.ow2.asm:asm:${project.asm_version}"
asm "org.ow2.asm:asm-tree:${project.asm_version}"
asm "org.ow2.asm:asm-commons:${project.asm_version}"
@ -102,6 +93,7 @@ import cuchaz.enigma.command.CheckMappingsCommand
import net.fabricmc.filament.task.MapJarTask
import net.fabricmc.filament.task.DownloadTask
import net.fabricmc.filament.task.UnpickJarTask
import net.fabricmc.filament.task.MappingPoetTask;
import net.fabricmc.filament.task.base.WithFileInput
import net.fabricmc.filament.task.base.WithFileOutput
import net.fabricmc.filament.task.enigma.MapSpecializedMethodsTask
@ -430,20 +422,12 @@ tasks.register('syncDependencies', Sync) {
}
def fakeSourceDir = file(".gradle/temp/fakeSource")
tasks.register('genFakeSource', JavaExec) {
dependsOn mergeV2, mapNamedJar, syncDependencies
tasks.register('genFakeSource', MappingPoetTask) {
group = "javadoc generation"
inputs.file mergeV2.output
inputs.file mapNamedJar.output
inputs.dir mcLibsDir
outputs.dir fakeSourceDir
mainClass = "net.fabricmc.mappingpoet.Main"
classpath configurations.mappingPoet
// use merged v2 so we have all namespaces in jd
args mergeV2.outputFile.getAbsolutePath(), mapNamedJar.outputFile.getAbsolutePath(), fakeSourceDir.getAbsolutePath(), mcLibsDir.getAbsolutePath()
mappings = mergeV2.output
minecraftJar = mapNamedJar.output
libraries.from(minecraftLibraries)
output = fakeSourceDir
}
def decompileOutput = layout.buildDirectory.file("namedSrc")
@ -480,8 +464,6 @@ javadoc {
dependsOn genFakeSource
group = "javadoc generation"
def mappingPoetJar = project.provider { zipTree configurations.mappingPoetJar.singleFile }
failOnError = false
maxMemory = '2G'
@ -498,7 +480,7 @@ javadoc {
'implSpec:a:Implementation Requirements:',
'implNote:a:Implementation Note:'
)
taglets "net.fabricmc.mappingpoet.jd.MappingTaglet"
taglets "net.fabricmc.filament.mappingpoet.jd.MappingTaglet"
// taglet path, header, extra stylesheet settings deferred
it.use()
@ -537,26 +519,13 @@ javadoc {
source fileTree(fakeSourceDir) + sourceSets.constants.allJava + sourceSets.packageDocs.allJava
classpath = configurations.javadocClasspath.plus minecraftLibraries
def fs = project.services.get(FileSystemOperations.class)
def outputDir = javadoc.destinationDir
// TODO how to do this?
// def tagletClasspath = configurations.mappingPoet.files.toList()
doLast {
fs.copy {
from mappingPoetJar
include "copy_on_click.js"
into outputDir
}
}
def tagletClasspath = configurations.mappingPoet.files.toList()
doFirst {
// lazy setting
options {
tagletPath tagletClasspath
header mappingPoetJar.get().filter { it.name == 'javadoc_header.txt' }.singleFile.text.trim() // cannot include line breaks
addFileOption "-add-stylesheet", mappingPoetJar.get().filter { it.name == 'forms.css' }.singleFile
}
options {
// tagletPath tagletClasspath
header file("gradle/javadoc/header.txt").text.trim() // cannot include line breaks
addFileOption "-add-stylesheet", file("gradle/javadoc/forms.css")
}
}
@ -565,6 +534,7 @@ tasks.register('javadocJar', Jar) {
group = "javadoc generation"
from javadoc.destinationDir
from file("gradle/javadoc/copy_on_click.js")
archiveVersion.set yarnVersion
archiveClassifier = 'javadoc'

View File

@ -36,7 +36,6 @@ dependencies {
implementation "net.fabricmc.unpick:unpick-format-utils:$properties.unpick_version"
implementation "net.fabricmc.unpick:unpick-cli:$properties.unpick_version"
implementation "net.fabricmc:tiny-remapper:$properties.tiny_remapper_version"
implementation "net.fabricmc:mappingpoet:$properties.mappingpoet_version"
implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.4.2'
implementation 'net.fabricmc:mapping-io:0.5.1'
implementation 'net.fabricmc:javapoet:0.1.1'

View File

@ -16,17 +16,11 @@
package net.fabricmc.filament.mappingpoet;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.lang.reflect.Modifier;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
@ -50,49 +44,11 @@ import org.objectweb.asm.tree.InnerClassNode;
import net.fabricmc.filament.mappingpoet.Environment.ClassNamePointer;
import net.fabricmc.filament.mappingpoet.Environment.NestedClassInfo;
public class Main {
public static void main(String[] args) {
if (args.length != 3 && args.length != 4) {
System.out.println("<mappings> <inputJar> <outputDir> [<librariesDir>]");
return;
}
Path mappings = Paths.get(args[0]);
Path inputJar = Paths.get(args[1]);
Path outputDirectory = Paths.get(args[2]);
Path librariesDir = args.length < 4 ? null : Paths.get(args[3]);
try {
if (Files.exists(outputDirectory)) {
try (var stream = Files.walk(outputDirectory)) {
stream.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.forEach(File::delete);
}
}
Files.createDirectories(outputDirectory);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
if (!Files.exists(mappings)) {
System.out.println("could not find mappings");
return;
}
if (!Files.exists(inputJar)) {
System.out.println("could not find input jar");
return;
}
generate(mappings, inputJar, outputDirectory, librariesDir);
}
public static void generate(Path mappings, Path inputJar, Path outputDirectory, Path librariesDir) {
public class MappingPoet {
public static void generate(Path mappings, Path inputJar, Path outputDirectory, List<Path> libraries) {
final MappingsStore mapping = new MappingsStore(mappings);
Map<String, ClassBuilder> classes = new HashMap<>();
forEachClass(inputJar, (classNode, environment) -> writeClass(mapping, classNode, classes, environment), librariesDir);
forEachClass(inputJar, (classNode, environment) -> writeClass(mapping, classNode, classes, environment), libraries);
for (ClassBuilder classBuilder : classes.values()) {
String name = classBuilder.getClassName();
@ -110,7 +66,7 @@ public class Main {
}
}
private static void forEachClass(Path jar, ClassNodeConsumer classNodeConsumer, Path librariesDir) {
private static void forEachClass(Path jar, ClassNodeConsumer classNodeConsumer, List<Path> libraries) {
List<ClassNode> classes = new ArrayList<>();
Map<String, Collection<String>> supers = new HashMap<>();
Set<String> sealedClasses = new HashSet<>(); // their subclsses/impls need non-sealed modifier
@ -118,8 +74,8 @@ public class Main {
Map<String, Environment.NestedClassInfo> nestedClasses = new ConcurrentHashMap<>();
Map<String, ClassNamePointer> classNames = new ConcurrentHashMap<>();
if (librariesDir != null) {
scanNestedClasses(classNames, nestedClasses, librariesDir);
if (libraries.isEmpty()) {
scanNestedClasses(classNames, nestedClasses, libraries);
}
try (JarFile jarFile = new JarFile(jar.toFile())) {
@ -178,44 +134,35 @@ public class Main {
}
}
private static void scanNestedClasses(Map<String, ClassNamePointer> classNames, Map<String, Environment.NestedClassInfo> instanceInnerClasses, Path librariesDir) {
private static void scanNestedClasses(Map<String, ClassNamePointer> classNames, Map<String, Environment.NestedClassInfo> instanceInnerClasses, List<Path> libraries) {
try {
Files.walkFileTree(librariesDir, new SimpleFileVisitor<>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if (!file.getFileName().toString().endsWith(".jar")) {
return FileVisitResult.CONTINUE;
}
for (Path library : libraries) {
try (JarFile jarFile = new JarFile(library.toFile())) {
Enumeration<JarEntry> entryEnumerator = jarFile.entries();
try (JarFile jarFile = new JarFile(file.toFile())) {
Enumeration<JarEntry> entryEnumerator = jarFile.entries();
while (entryEnumerator.hasMoreElements()) {
JarEntry entry = entryEnumerator.nextElement();
while (entryEnumerator.hasMoreElements()) {
JarEntry entry = entryEnumerator.nextElement();
if (entry.isDirectory() || !entry.getName().endsWith(".class")) {
continue;
}
if (entry.isDirectory() || !entry.getName().endsWith(".class")) {
continue;
}
try (InputStream is = jarFile.getInputStream(entry)) {
ClassReader reader = new ClassReader(is);
reader.accept(new ClassVisitor(Opcodes.ASM9) {
@Override
public void visitInnerClass(String name, String outerName, String simpleName, int access) {
instanceInnerClasses.put(name, new NestedClassInfo(outerName, !Modifier.isStatic(access), simpleName));
try (InputStream is = jarFile.getInputStream(entry)) {
ClassReader reader = new ClassReader(is);
reader.accept(new ClassVisitor(Opcodes.ASM9) {
@Override
public void visitInnerClass(String name, String outerName, String simpleName, int access) {
instanceInnerClasses.put(name, new NestedClassInfo(outerName, !Modifier.isStatic(access), simpleName));
if (outerName != null) {
classNames.put(name, new ClassNamePointer(simpleName, outerName));
}
if (outerName != null) {
classNames.put(name, new ClassNamePointer(simpleName, outerName));
}
}, ClassReader.SKIP_CODE);
}
}
}, ClassReader.SKIP_CODE);
}
}
return FileVisitResult.CONTINUE;
}
});
}
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
@ -225,7 +172,7 @@ public class Main {
String javaBinary = internalName.replace('/', '.');
try {
Class<?> c = Class.forName(javaBinary, false, Main.class.getClassLoader());
Class<?> c = Class.forName(javaBinary, false, MappingPoet.class.getClassLoader());
return !Modifier.isStatic(c.getModifiers()) && c.getDeclaringClass() != null;
} catch (Throwable ex) {
return false;

View File

@ -0,0 +1,35 @@
package net.fabricmc.filament.task;
import java.io.File;
import org.gradle.api.DefaultTask;
import org.gradle.api.file.ConfigurableFileCollection;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.OutputDirectory;
import org.gradle.api.tasks.TaskAction;
import net.fabricmc.filament.mappingpoet.MappingPoet;
public abstract class MappingPoetTask extends DefaultTask {
@InputFile
public abstract RegularFileProperty getMappings();
@InputFile
public abstract RegularFileProperty getMinecraftJar();
@InputFiles
public abstract ConfigurableFileCollection getLibraries();
@OutputDirectory
public abstract DirectoryProperty getOutput();
@TaskAction
public void run() {
MappingPoet.generate(
getMappings().get().getAsFile().toPath(),
getMinecraftJar().get().getAsFile().toPath(),
getOutput().get().getAsFile().toPath(),
getLibraries().getFiles().stream().map(File::toPath).toList()
);
}
}

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2020 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.filament.test.mappingpoet;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface BorkAnno {
}

View File

@ -0,0 +1,262 @@
/*
* Copyright (c) 2020 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.filament.test.mappingpoet;
import java.net.URLClassLoader;
import java.util.Collections;
import java.util.Comparator;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.IntFunction;
import java.util.function.UnaryOperator;
import com.squareup.javapoet.ArrayTypeName;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeVariableName;
import com.squareup.javapoet.WildcardTypeName;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.objectweb.asm.signature.SignatureReader;
import net.fabricmc.filament.mappingpoet.signature.ClassSignature;
import net.fabricmc.filament.mappingpoet.signature.MethodSignature;
import net.fabricmc.filament.mappingpoet.signature.PoetClassMethodSignatureVisitor;
import net.fabricmc.filament.mappingpoet.signature.PoetTypeSignatureWriter;
import net.fabricmc.filament.mappingpoet.signature.TypeAnnotationBank;
import net.fabricmc.filament.mappingpoet.signature.TypeAnnotationMapping;
import net.fabricmc.filament.mappingpoet.Signatures;
public class SignaturesTest {
@Test
public void testRandomMapType() {
//signature Ljava/util/Map<Ljava/util/Map$Entry<[[Ljava/lang/String;[Ljava/util/List<[I>;>;[[[D>;
//Map<Map.Entry<String[][], List<int[]>[]>, double[][][]> map = new HashMap<>();
String signature = "Ljava/util/Map<Ljava/util/Map$Entry<[[Ljava/lang/String;[Ljava/util/List<[I>;>;[[[D>;";
Map.Entry<Integer, TypeName> result = Signatures.parseParameterizedType(signature, 0);
Assertions.assertEquals(85, result.getKey().intValue());
Assertions.assertEquals("java.util.Map<java.util.Map.Entry<java.lang.String[][], java.util.List<int[]>[]>, double[][][]>", result.getValue().toString());
PoetTypeSignatureWriter writer = new PoetTypeSignatureWriter(TypeAnnotationBank.EMPTY, s -> false);
new SignatureReader(signature).acceptType(writer);
Assertions.assertEquals("java.util.Map<java.util.Map.Entry<java.lang.String[][], java.util.List<int[]>[]>, double[][][]>", writer.compute().toString());
}
@Test
public void testCrazyOne() {
String classSignature = "<B::Ljava/util/Comparator<-TA;>;C:Ljava/lang/ClassLoader;:Ljava/lang/Iterable<*>;>Ljava/lang/Object;";
Map.Entry<Integer, TypeName> result = Signatures.parseParameterizedType(classSignature, 4);
Assertions.assertEquals(32, result.getKey().intValue());
Assertions.assertEquals("java.util.Comparator<? super A>", result.getValue().toString());
result = Signatures.parseParameterizedType(classSignature, 34);
Assertions.assertEquals(57, result.getKey().intValue());
Assertions.assertEquals("java.lang.ClassLoader", result.getValue().toString());
result = Signatures.parseParameterizedType(classSignature, 58);
Assertions.assertEquals(81, result.getKey().intValue());
Assertions.assertEquals("java.lang.Iterable<?>", result.getValue().toString());
}
@Test
public void soo() {
TestOuter<Integer>.Inner<Comparator<Integer>, URLClassLoader>.ExtraInner<UnaryOperator<Map<int[][], BiFunction<Comparator<Integer>, Integer, URLClassLoader>>>> local = new TestOuter<Integer>().new Inner<Comparator<Integer>, URLClassLoader>().new ExtraInner<UnaryOperator<Map<int[][], BiFunction<Comparator<Integer>, Integer, URLClassLoader>>>>();
local.hashCode();
// signature Lnet/fabricmc/mappingpoet/TestOuter<Ljava/lang/Integer;>.Inner<Ljava/util/Comparator<Ljava/lang/Integer;>;Ljava/net/URLClassLoader;>.ExtraInner<Ljava/util/function/UnaryOperator<Ljava/util/Map<[[ILjava/util/function/BiFunction<Ljava/util/Comparator<Ljava/lang/Integer;>;Ljava/lang/Integer;Ljava/net/URLClassLoader;>;>;>;>;
String signature = "Lnet/fabricmc/mappingpoet/TestOuter<Ljava/lang/Integer;>.Inner<Ljava/util/Comparator<Ljava/lang/Integer;>;Ljava/net/URLClassLoader;>.ExtraInner<Ljava/util/function/UnaryOperator<Ljava/util/Map<[[ILjava/util/function/BiFunction<Ljava/util/Comparator<Ljava/lang/Integer;>;Ljava/lang/Integer;Ljava/net/URLClassLoader;>;>;>;>;";
Map.Entry<Integer, TypeName> result = Signatures.parseParameterizedType(signature, 0);
Assertions.assertEquals(322, result.getKey().intValue());
Assertions.assertEquals("net.fabricmc.mappingpoet.TestOuter<java.lang.Integer>.Inner<java.util.Comparator<java.lang.Integer>, java.net.URLClassLoader>.ExtraInner<java.util.function.UnaryOperator<java.util.Map<int[][], java.util.function.BiFunction<java.util.Comparator<java.lang.Integer>, java.lang.Integer, java.net.URLClassLoader>>>>", result.getValue().toString());
PoetTypeSignatureWriter writer = new PoetTypeSignatureWriter(TypeAnnotationBank.EMPTY, s -> false);
new SignatureReader(signature).acceptType(writer);
Assertions.assertEquals("net.fabricmc.mappingpoet.TestOuter<java.lang.Integer>.Inner<java.util.Comparator<java.lang.Integer>, java.net.URLClassLoader>.ExtraInner<java.util.function.UnaryOperator<java.util.Map<int[][], java.util.function.BiFunction<java.util.Comparator<java.lang.Integer>, java.lang.Integer, java.net.URLClassLoader>>>>", writer.compute().toString());
}
@Test
public void arrSoo() {
@SuppressWarnings("unchecked")
TestOuter<Integer>.Inner<Comparator<Integer>, URLClassLoader>.ExtraInner<UnaryOperator<Map<int[][], BiFunction<Comparator<Integer>, Integer, URLClassLoader>>>>[][] arr = (TestOuter<Integer>.Inner<Comparator<Integer>, URLClassLoader>.ExtraInner<UnaryOperator<Map<int[][], BiFunction<Comparator<Integer>, Integer, URLClassLoader>>>>[][]) new TestOuter<?>.Inner<?, ?>.ExtraInner<?>[0][];
arr.toString();
// signature [[Lnet/fabricmc/mappingpoet/TestOuter<Ljava/lang/Integer;>.Inner<Ljava/util/Comparator<Ljava/lang/Integer;>;Ljava/net/URLClassLoader;>.ExtraInner<Ljava/util/function/UnaryOperator<Ljava/util/Map<[[ILjava/util/function/BiFunction<Ljava/util/Comparator<Ljava/lang/Integer;>;Ljava/lang/Integer;Ljava/net/URLClassLoader;>;>;>;>;
String arraySignature = "[[Lnet/fabricmc/mappingpoet/TestOuter<Ljava/lang/Integer;>.Inner<Ljava/util/Comparator<Ljava/lang/Integer;>;Ljava/net/URLClassLoader;>.ExtraInner<Ljava/util/function/UnaryOperator<Ljava/util/Map<[[ILjava/util/function/BiFunction<Ljava/util/Comparator<Ljava/lang/Integer;>;Ljava/lang/Integer;Ljava/net/URLClassLoader;>;>;>;>;";
Map.Entry<Integer, TypeName> result = Signatures.parseParameterizedType(arraySignature, 0);
Assertions.assertEquals(324, result.getKey().intValue());
Assertions.assertEquals("net.fabricmc.mappingpoet.TestOuter<java.lang.Integer>.Inner<java.util.Comparator<java.lang.Integer>, java.net.URLClassLoader>.ExtraInner<java.util.function.UnaryOperator<java.util.Map<int[][], java.util.function.BiFunction<java.util.Comparator<java.lang.Integer>, java.lang.Integer, java.net.URLClassLoader>>>>[][]", result.getValue().toString());
PoetTypeSignatureWriter writer = new PoetTypeSignatureWriter(TypeAnnotationBank.EMPTY, s -> false);
new SignatureReader(arraySignature).acceptType(writer);
Assertions.assertEquals("net.fabricmc.mappingpoet.TestOuter<java.lang.Integer>.Inner<java.util.Comparator<java.lang.Integer>, java.net.URLClassLoader>.ExtraInner<java.util.function.UnaryOperator<java.util.Map<int[][], java.util.function.BiFunction<java.util.Comparator<java.lang.Integer>, java.lang.Integer, java.net.URLClassLoader>>>>[][]", writer.compute().toString());
}
@Test
public void testClassDeeSignature() {
// signature <D::Ljava/util/function/UnaryOperator<Ljava/util/Map<[[ILjava/util/function/BiFunction<TB;TA;TC;>;>;>;>Ljava/lang/Object;
String classSig = "<D::Ljava/util/function/UnaryOperator<Ljava/util/Map<[[ILjava/util/function/BiFunction<TB;TA;TC;>;>;>;>Ljava/lang/Object;";
Map.Entry<Integer, TypeName> dBound = Signatures.parseParameterizedType(classSig, 4);
Assertions.assertEquals(102, dBound.getKey().intValue());
Assertions.assertEquals("java.util.function.UnaryOperator<java.util.Map<int[][], java.util.function.BiFunction<B, A, C>>>", dBound.getValue().toString());
ClassSignature parsed = Signatures.parseClassSignature(classSig);
Assertions.assertIterableEquals(Collections.singleton(TypeVariableName.get("D")), parsed.generics());
Assertions.assertEquals(ClassName.OBJECT, parsed.superclass());
Assertions.assertIterableEquals(Collections.emptyList(), parsed.superinterfaces());
}
@Test
public void testClassDeeSignatureVisitor() {
// signature <D::Ljava/util/function/UnaryOperator<Ljava/util/Map<[[ILjava/util/function/BiFunction<TB;TA;TC;>;>;>;>Ljava/lang/Object;
String classSig = "<D::Ljava/util/function/UnaryOperator<Ljava/util/Map<[[ILjava/util/function/BiFunction<TB;TA;TC;>;>;>;>Ljava/lang/Object;";
PoetClassMethodSignatureVisitor visitor = new PoetClassMethodSignatureVisitor(TypeAnnotationMapping.EMPTY, s -> false, true);
new SignatureReader(classSig).accept(visitor);
ClassSignature parsed = visitor.collectClass();
Assertions.assertIterableEquals(Collections.singleton(TypeVariableName.get("D")), parsed.generics());
Assertions.assertEquals(ClassName.OBJECT, parsed.superclass());
Assertions.assertIterableEquals(Collections.emptyList(), parsed.superinterfaces());
}
@Test
public void testCollectionIntFunctionToArraySignature() {
// signature <T:Ljava/lang/Object;>(Ljava/util/function/IntFunction<[TT;>;)[TT;
String methodSignature = "<T:Ljava/lang/Object;>(Ljava/util/function/IntFunction<[TT;>;)[TT;";
MethodSignature parsed = Signatures.parseMethodSignature(methodSignature);
Assertions.assertIterableEquals(Collections.singleton(TypeVariableName.get("T")), parsed.generics());
Assertions.assertEquals(ArrayTypeName.of(TypeVariableName.get("T")), parsed.result());
Assertions.assertIterableEquals(Collections.emptyList(), parsed.thrown());
Assertions.assertIterableEquals(Collections.singleton(ParameterizedTypeName.get(ClassName.get(IntFunction.class), ArrayTypeName.of(TypeVariableName.get("T")))), parsed.parameters());
}
@Test
public void testCollectionArrayToArraySignature() {
// signature <T:Ljava/lang/Object;>([TT;)[TT;
String methodSignature = "<T:Ljava/lang/Object;>([TT;)[TT;";
MethodSignature parsed = Signatures.parseMethodSignature(methodSignature);
Assertions.assertIterableEquals(Collections.singleton(TypeVariableName.get("T")), parsed.generics());
Assertions.assertEquals(ArrayTypeName.of(TypeVariableName.get("T")), parsed.result());
Assertions.assertIterableEquals(Collections.emptyList(), parsed.thrown());
Assertions.assertIterableEquals(Collections.singleton(ArrayTypeName.of(TypeVariableName.get("T"))), parsed.parameters());
}
@Test
public void testCollectionArrayToArraySignatureVisitor() {
// signature <T:Ljava/lang/Object;>([TT;)[TT;
String methodSignature = "<T:Ljava/lang/Object;>([TT;)[TT;";
PoetClassMethodSignatureVisitor visitor = new PoetClassMethodSignatureVisitor(TypeAnnotationMapping.EMPTY, s -> false, false);
new SignatureReader(methodSignature).accept(visitor);
MethodSignature parsed = visitor.collectMethod();
Assertions.assertIterableEquals(Collections.singleton(TypeVariableName.get("T")), parsed.generics());
Assertions.assertEquals(ArrayTypeName.of(TypeVariableName.get("T")), parsed.result());
Assertions.assertIterableEquals(Collections.emptyList(), parsed.thrown());
Assertions.assertIterableEquals(Collections.singleton(ArrayTypeName.of(TypeVariableName.get("T"))), parsed.parameters());
}
@Test
public void testTweakLastSignature() {
// signature (Ljava/util/function/UnaryOperator<Lcom/squareup/javapoet/TypeName;>;)V
String methodSignature = "(Ljava/util/function/UnaryOperator<Lcom/squareup/javapoet/TypeName;>;)V";
MethodSignature parsed = Signatures.parseMethodSignature(methodSignature);
Assertions.assertTrue(parsed.generics().isEmpty());
Assertions.assertEquals(TypeName.VOID, parsed.result());
Assertions.assertIterableEquals(Collections.emptyList(), parsed.thrown());
ClassName unaryOperatorClass = ClassName.get(UnaryOperator.class);
ClassName typeNameClass = ClassName.get(TypeName.class);
Assertions.assertIterableEquals(Collections.singleton(ParameterizedTypeName.get(unaryOperatorClass, typeNameClass)), parsed.parameters());
}
@Test
public void testTweakLastSignatureVisitor() {
// signature (Ljava/util/function/UnaryOperator<Lcom/squareup/javapoet/TypeName;>;)V
String methodSignature = "(Ljava/util/function/UnaryOperator<Lcom/squareup/javapoet/TypeName;>;)V";
PoetClassMethodSignatureVisitor visitor = new PoetClassMethodSignatureVisitor(TypeAnnotationMapping.EMPTY, s -> false, false);
new SignatureReader(methodSignature).accept(visitor);
MethodSignature parsed = visitor.collectMethod();
Assertions.assertTrue(parsed.generics().isEmpty());
Assertions.assertEquals(TypeName.VOID, parsed.result());
Assertions.assertIterableEquals(Collections.emptyList(), parsed.thrown());
ClassName unaryOperatorClass = ClassName.get(UnaryOperator.class);
ClassName typeNameClass = ClassName.get(TypeName.class);
Assertions.assertIterableEquals(Collections.singleton(ParameterizedTypeName.get(unaryOperatorClass, typeNameClass)), parsed.parameters());
}
@Test
public void testCheckHeadSignature() {
// signature <E:Ljava/lang/Throwable;>(Lnet/fabricmc/filament/mappingpoet/Signatures$HeadChecker<TE;>;)V^TE;
String raw = "<E:Ljava/lang/Throwable;>(Lnet/fabricmc/filament/mappingpoet/Signatures$HeadChecker<TE;>;)V^TE;";
MethodSignature parsed = Signatures.parseMethodSignature(raw);
Assertions.assertIterableEquals(Collections.singleton(TypeVariableName.get("E", ClassName.get(Throwable.class))), parsed.generics());
ClassName headCheckerClass = ClassName.get(Signatures.class).nestedClass("HeadChecker");
Assertions.assertIterableEquals(Collections.singleton(ParameterizedTypeName.get(headCheckerClass, TypeVariableName.get("E"))), parsed.parameters());
Assertions.assertEquals(TypeName.VOID, parsed.result());
Assertions.assertIterableEquals(Collections.singleton(TypeVariableName.get("E")), parsed.thrown());
}
@Test
public void testCheckHeadSignatureVisitor() {
// signature <E:Ljava/lang/Throwable;>(Lnet/fabricmc/filament/mappingpoet/Signatures$HeadChecker<TE;>;)V^TE;
String raw = "<E:Ljava/lang/Throwable;>(Lnet/fabricmc/filament/mappingpoet/Signatures$HeadChecker<TE;>;)V^TE;";
PoetClassMethodSignatureVisitor visitor = new PoetClassMethodSignatureVisitor(TypeAnnotationMapping.EMPTY, s -> false, false);
new SignatureReader(raw).accept(visitor);
MethodSignature parsed = visitor.collectMethod();
Assertions.assertIterableEquals(Collections.singleton(TypeVariableName.get("E", ClassName.get(Throwable.class))), parsed.generics());
ClassName headCheckerClass = ClassName.get(Signatures.class).nestedClass("HeadChecker");
Assertions.assertIterableEquals(Collections.singleton(ParameterizedTypeName.get(headCheckerClass, TypeVariableName.get("E"))), parsed.parameters());
Assertions.assertEquals(TypeName.VOID, parsed.result());
Assertions.assertIterableEquals(Collections.singleton(TypeVariableName.get("E")), parsed.thrown());
}
@Test
public void testBrokenVariantSettingSignature() {
// Ljava/util/Map<Lnet/minecraft/data/client/model/VariantSetting<*>;Lnet/minecraft/data/client/model/VariantSetting<*>.Value;>;
String signature = "Ljava/util/Map<Lnet/minecraft/data/client/model/VariantSetting<*>;Lnet/minecraft/data/client/model/VariantSetting<*>.Value;>;";
Map.Entry<Integer, TypeName> parsed = Signatures.parseParameterizedType(signature, 0);
Assertions.assertEquals(125, parsed.getKey().intValue());
ClassName variantSettingClass = ClassName.get("net.minecraft.data.client.model", "VariantSetting");
ParameterizedTypeName wildcardVariantSetting = ParameterizedTypeName.get(variantSettingClass, WildcardTypeName.subtypeOf(TypeName.OBJECT));
ParameterizedTypeName valueClass = wildcardVariantSetting.nestedClass("Value");
ClassName mapClass = ClassName.get(Map.class);
ParameterizedTypeName genericMap = ParameterizedTypeName.get(mapClass, wildcardVariantSetting, valueClass);
Assertions.assertEquals(genericMap, parsed.getValue());
PoetTypeSignatureWriter writer = new PoetTypeSignatureWriter(TypeAnnotationBank.EMPTY, s -> false);
new SignatureReader(signature).acceptType(writer);
Assertions.assertEquals(genericMap, writer.compute());
}
@Test
public void testStaticOuters() {
Outer.MiddleStatic.@TestAnno InnerStatic instance = null;
// https://docs.oracle.com/javase/specs/jvms/se15/html/jvms-4.html#jvms-4.7.20.2-220-B-A.1
Outer.@TestAnno("a") MiddleStatic<@TestAnno("b") Object>.@TestAnno("c") Inner<@TestAnno("d") Integer> instance2 = new Outer.MiddleStatic<>().new Inner<Integer>();
String input = "Lnet/fabricmc/mappingpoet/Outer$MiddleStatic<Ljava/lang/Object;>.Inner<Ljava/lang/Integer;>;";
TypeName name = Signatures.parseFieldSignature(input);
Assertions.assertEquals("net.fabricmc.mappingpoet.Outer.MiddleStatic<java.lang.Object>.Inner<java.lang.Integer>", name.toString());
PoetTypeSignatureWriter writer = new PoetTypeSignatureWriter(TypeAnnotationBank.EMPTY, s -> false);
new SignatureReader(input).acceptType(writer);
Assertions.assertEquals(name, writer.compute());
}
}

View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2020 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.filament.test.mappingpoet;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.FIELD})
public @interface TestAnno {
String value() default "";
}

View File

@ -0,0 +1,101 @@
/*
* Copyright (c) 2020 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.filament.test.mappingpoet;
import java.util.Comparator;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.UnaryOperator;
enum StupidEnum {
FIRST,
@TestAnno
SECOND;
}
// signature <A::Ljava/lang/Comparable<-TA;>;>Ljava/lang/Object;
public class TestOuter<A extends Comparable<? super A>> {
// signature <B::Ljava/util/Comparator<-TA;>;C:Ljava/lang/ClassLoader;:Ljava/lang/Iterable<*>;>Ljava/lang/Object;
class Inner<B extends Comparator<? super A>, C extends ClassLoader & AutoCloseable> {
// signature <D::Ljava/util/function/UnaryOperator<Ljava/util/Map<[[ILjava/util/function/BiFunction<TB;TA;TC;>;>;>;>Ljava/lang/Object;
class ExtraInner<D extends UnaryOperator<Map<int[][], BiFunction<B, A, C>>>> {
ExtraInner(Inner<B, C> Inner.this) {
// constructor receiver example. Notice 'this' cannot receive parameter annos
}
void work(@TestAnno("on extra inner")ExtraInner<D> this, Inner<@TestAnno("pig") B, C> @TestAnno("lion") [][] @TestAnno("rat") [] arr) {
}
void work2(ExtraInner<D> this) {
}
}
}
}
class Outer {
void eat(@BorkAnno @TestAnno MiddleTwo.InnerThree<Integer> apple) {
}
void eat(@BorkAnno MiddleStatic.@TestAnno InnerStatic apple) {
}
static class MiddleStatic<T> {
static class InnerStatic {
}
class Inner<U> {
}
}
class MiddleTwo {
class InnerThree<E> {
}
}
}
class OuterTwo<T> {
static class InnerOne<G> {
class InnerTwo {
InnerTwo(InnerOne<G> InnerOne.this) {
}
void called(InnerTwo this, InnerTwo other) {
}
class NestedThree<W> {
void work(NestedThree<W> this, NestedThree<W> other) {
}
}
}
}
class InnerTwo {
class NestedThree<W> {
void workSelf(@TestAnno("on myself!")NestedThree<@TestAnno("on my W") W> this) {
}
void workSelf1(NestedThree<@TestAnno("on my W only") W> this) {
}
void workSelf2(@TestAnno("on myself only")NestedThree<W> this) {
}
void work(@TestAnno("on myself!")NestedThree<@TestAnno("on my W") W> this, NestedThree<@TestAnno("on their W") W> other) {
}
}
}
}

View File

@ -0,0 +1,5 @@
tiny 2 0 intermediary official named
notice This is an example to test functionalities!
c net/fabricmc/mappingpoet/Outer a net/fabricmc/mappingpoet/Outer
m (Lnet/fabricmc/mappingpoet/Outer$MiddleTwo$InnerThree;)V eaten ate eat
c net/hackingmc/fightingpoet/ZombieTest b net/fabricmc/mappingpoet/SignaturesTest

View File

@ -13,7 +13,6 @@ asm_version=9.6
# Javadoc generation/linking
fabric_loader_version=0.15.10
jetbrains_annotations_version=24.1.0
mappingpoet_version=0.4.2
# Build logic
tiny_remapper_version=0.10.3

View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2020 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
document.onreadystatechange = function() {
if(document.readyState == "complete") {
const items = document.querySelectorAll(".copyable");
items.forEach(item => {
item.title = "Click to copy";
item.style["cursor"] = "pointer";
item.onclick = function() {
var range = document.createRange();
range.selectNode(item);
window.getSelection().addRange(range);
document.execCommand("copy");
window.getSelection().removeRange(range);
console.log("Copied to clipboard");
};
});
}
};

39
gradle/javadoc/forms.css Normal file
View File

@ -0,0 +1,39 @@
.fabric {
font: 400 14px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
color: #111;
background-color: #fdfdfd;
-webkit-text-size-adjust: 100%;
-webkit-font-feature-settings: "kern" 1;
-moz-font-feature-settings: "kern" 1;
-o-font-feature-settings: "kern" 1;
font-feature-settings: "kern" 1;
font-kerning: normal;
display: flex;
flex-direction: column;
}
.fabric table {
width: 100%;
text-align: left;
color: #3f3f3f;
border-collapse: collapse;
border: 1px solid #e8e8e8;
}
.fabric table tr:nth-child(even) {
background-color: #f7f7f7;
}
.fabric table th, table td {
padding: 1px 10px;
}
.fabric table th {
background-color: #f0f0f0;
border: 1px solid #dedede;
border-bottom-color: #c9c9c9;
}
.fabric table td {
border: 1px solid #e8e8e8;
}

View File

@ -0,0 +1 @@
<script src="{@docRoot}/copy_on_click.js"></script>