mirror of https://github.com/FabricMC/yarn.git
Migrate name proposal code to filament
This commit is contained in:
parent
70d538edef
commit
24a83e4ae9
12
build.gradle
12
build.gradle
|
@ -9,7 +9,6 @@ buildscript {
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath "cuchaz:enigma-cli:${project.enigma_version}"
|
classpath "cuchaz:enigma-cli:${project.enigma_version}"
|
||||||
classpath "net.fabricmc:name-proposal:${project.name_proposal_version}"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +70,6 @@ def unpickMetaFile = file("unpick-definitions/unpick.json")
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
enigmaRuntime "cuchaz:enigma-swing:${project.enigma_version}"
|
enigmaRuntime "cuchaz:enigma-swing:${project.enigma_version}"
|
||||||
enigmaRuntime "net.fabricmc:name-proposal:${project.name_proposal_version}"
|
|
||||||
enigmaRuntime "net.fabricmc:cfr:${project.cfr_version}"
|
enigmaRuntime "net.fabricmc:cfr:${project.cfr_version}"
|
||||||
javadocClasspath "net.fabricmc:fabric-loader:${project.fabric_loader_version}"
|
javadocClasspath "net.fabricmc:fabric-loader:${project.fabric_loader_version}"
|
||||||
javadocClasspath "org.jetbrains:annotations:${project.jetbrains_annotations_version}"
|
javadocClasspath "org.jetbrains:annotations:${project.jetbrains_annotations_version}"
|
||||||
|
@ -106,8 +104,8 @@ import net.fabricmc.filament.task.mappingio.CompleteMappingsTask
|
||||||
import net.fabricmc.filament.task.mappingio.ConvertMappingsTask
|
import net.fabricmc.filament.task.mappingio.ConvertMappingsTask
|
||||||
import net.fabricmc.filament.task.mappingio.FormatMappingsTask
|
import net.fabricmc.filament.task.mappingio.FormatMappingsTask
|
||||||
import net.fabricmc.filament.task.mappingio.MergeMappingsTask
|
import net.fabricmc.filament.task.mappingio.MergeMappingsTask
|
||||||
|
import net.fabricmc.filament.nameproposal.MappingNameCompleter
|
||||||
import net.fabricmc.mappingio.format.MappingFormat
|
import net.fabricmc.mappingio.format.MappingFormat
|
||||||
import net.fabricmc.nameproposal.MappingNameCompleter
|
|
||||||
import org.gradle.work.DisableCachingByDefault
|
import org.gradle.work.DisableCachingByDefault
|
||||||
import com.diffplug.spotless.LineEnding
|
import com.diffplug.spotless.LineEnding
|
||||||
import groovy.xml.XmlSlurper
|
import groovy.xml.XmlSlurper
|
||||||
|
@ -624,7 +622,13 @@ abstract class EnigmaTask extends JavaExec {
|
||||||
abstract Property<File> getMappings()
|
abstract Property<File> getMappings()
|
||||||
|
|
||||||
EnigmaTask() {
|
EnigmaTask() {
|
||||||
classpath = project.configurations.enigmaRuntime
|
def filamentCodeSource = MappingPoetTask.class.getProtectionDomain().getCodeSource()
|
||||||
|
def filamentJarFile = new File(filamentCodeSource.getLocation().getFile())
|
||||||
|
def runtimeClasspath = project.files()
|
||||||
|
runtimeClasspath.from(project.configurations.enigmaRuntime)
|
||||||
|
runtimeClasspath.from(filamentJarFile)
|
||||||
|
|
||||||
|
classpath = runtimeClasspath
|
||||||
mainClass.set('cuchaz.enigma.gui.Main')
|
mainClass.set('cuchaz.enigma.gui.Main')
|
||||||
jvmArgs "-Xmx2048m"
|
jvmArgs "-Xmx2048m"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
filament_version=0.8.0
|
filament_version=0.9.0
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 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.nameproposal;
|
||||||
|
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
|
public class Constants {
|
||||||
|
public static int ASM_VERSION = Opcodes.ASM9;
|
||||||
|
}
|
|
@ -0,0 +1,164 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2021 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.nameproposal;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.objectweb.asm.ClassReader;
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
|
import org.objectweb.asm.tree.AbstractInsnNode;
|
||||||
|
import org.objectweb.asm.tree.FieldInsnNode;
|
||||||
|
import org.objectweb.asm.tree.InsnList;
|
||||||
|
import org.objectweb.asm.tree.LdcInsnNode;
|
||||||
|
import org.objectweb.asm.tree.MethodInsnNode;
|
||||||
|
import org.objectweb.asm.tree.MethodNode;
|
||||||
|
import org.objectweb.asm.tree.analysis.Analyzer;
|
||||||
|
import org.objectweb.asm.tree.analysis.AnalyzerException;
|
||||||
|
import org.objectweb.asm.tree.analysis.Frame;
|
||||||
|
import org.objectweb.asm.tree.analysis.SourceInterpreter;
|
||||||
|
import org.objectweb.asm.tree.analysis.SourceValue;
|
||||||
|
|
||||||
|
public class FieldNameFinder {
|
||||||
|
public Map<MappingEntry, String> findNames(Iterable<byte[]> classes) throws Exception {
|
||||||
|
Map<String, List<MethodNode>> methods = new HashMap<>();
|
||||||
|
Map<String, Set<String>> enumFields = new HashMap<>();
|
||||||
|
|
||||||
|
for (byte[] data : classes) {
|
||||||
|
ClassReader reader = new ClassReader(data);
|
||||||
|
NameFinderVisitor vClass = new NameFinderVisitor(Constants.ASM_VERSION, enumFields, methods);
|
||||||
|
reader.accept(vClass, ClassReader.SKIP_FRAMES);
|
||||||
|
}
|
||||||
|
|
||||||
|
return findNames(enumFields, methods);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<MappingEntry, String> findNames(Map<String, Set<String>> allEnumFields, Map<String, List<MethodNode>> classes) {
|
||||||
|
Analyzer<SourceValue> analyzer = new Analyzer<>(new SourceInterpreter());
|
||||||
|
Map<MappingEntry, String> fieldNames = new HashMap<>();
|
||||||
|
Map<String, Set<String>> fieldNamesUsed = new HashMap<>();
|
||||||
|
Map<String, Set<String>> fieldNamesDuplicate = new HashMap<>();
|
||||||
|
|
||||||
|
for (Map.Entry<String, List<MethodNode>> entry : classes.entrySet()) {
|
||||||
|
String owner = entry.getKey();
|
||||||
|
Set<String> enumFields = allEnumFields.getOrDefault(owner, Collections.emptySet());
|
||||||
|
|
||||||
|
for (MethodNode mn : entry.getValue()) {
|
||||||
|
Frame<SourceValue>[] frames;
|
||||||
|
|
||||||
|
try {
|
||||||
|
frames = analyzer.analyze(owner, mn);
|
||||||
|
} catch (AnalyzerException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
InsnList instrs = mn.instructions;
|
||||||
|
|
||||||
|
for (int i = 1; i < instrs.size(); i++) {
|
||||||
|
AbstractInsnNode instr1 = instrs.get(i - 1);
|
||||||
|
AbstractInsnNode instr2 = instrs.get(i);
|
||||||
|
String s = null;
|
||||||
|
|
||||||
|
if (instr2.getOpcode() == Opcodes.PUTSTATIC && ((FieldInsnNode) instr2).owner.equals(owner)
|
||||||
|
&& (instr1 instanceof MethodInsnNode && ((MethodInsnNode) instr1).owner.equals(owner) || enumFields.contains(((FieldInsnNode) instr2).desc + ((FieldInsnNode) instr2).name))
|
||||||
|
&& (instr1.getOpcode() == Opcodes.INVOKESTATIC || (instr1.getOpcode() == Opcodes.INVOKESPECIAL && "<init>".equals(((MethodInsnNode) instr1).name)))) {
|
||||||
|
for (int j = 0; j < frames[i - 1].getStackSize(); j++) {
|
||||||
|
SourceValue sv = frames[i - 1].getStack(j);
|
||||||
|
|
||||||
|
for (AbstractInsnNode ci : sv.insns) {
|
||||||
|
if (ci instanceof LdcInsnNode && ((LdcInsnNode) ci).cst instanceof String) {
|
||||||
|
//if (s == null || !s.equals(((LdcInsnNode) ci).cst)) {
|
||||||
|
if (s == null) {
|
||||||
|
s = (String) (((LdcInsnNode) ci).cst);
|
||||||
|
// stringsFound++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s != null) {
|
||||||
|
if (s.contains(":")) {
|
||||||
|
s = s.substring(s.indexOf(':') + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s.contains("/")) {
|
||||||
|
int separator = s.indexOf('/');
|
||||||
|
String sFirst = s.substring(0, separator);
|
||||||
|
String sLast;
|
||||||
|
|
||||||
|
if (s.contains(".") && s.indexOf('.') > separator) {
|
||||||
|
sLast = s.substring(separator + 1, s.indexOf('.'));
|
||||||
|
} else {
|
||||||
|
sLast = s.substring(separator + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sFirst.endsWith("s")) {
|
||||||
|
sFirst = sFirst.substring(0, sFirst.length() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
s = sLast + "_" + sFirst;
|
||||||
|
}
|
||||||
|
|
||||||
|
String oldS = s;
|
||||||
|
boolean hasAlpha = false;
|
||||||
|
|
||||||
|
for (int j = 0; j < s.length(); j++) {
|
||||||
|
char c = s.charAt(j);
|
||||||
|
|
||||||
|
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
|
||||||
|
hasAlpha = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(c >= 'A' && c <= 'Z') && !(c >= 'a' && c <= 'z') && !(c >= '0' && c <= '9') && !(c == '_')) {
|
||||||
|
s = s.substring(0, j) + "_" + s.substring(j + 1);
|
||||||
|
} else if (j > 0 && Character.isUpperCase(s.charAt(j)) && Character.isLowerCase(s.charAt(j - 1))) {
|
||||||
|
s = s.substring(0, j) + "_" + s.substring(j, j + 1).toLowerCase(Locale.ROOT) + s.substring(j + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasAlpha) {
|
||||||
|
s = s.toUpperCase(Locale.ROOT);
|
||||||
|
|
||||||
|
Set<String> usedNames = fieldNamesUsed.computeIfAbsent(((FieldInsnNode) instr2).owner, (a) -> new HashSet<>());
|
||||||
|
Set<String> usedNamesDuplicate = fieldNamesDuplicate.computeIfAbsent(((FieldInsnNode) instr2).owner, (a) -> new HashSet<>());
|
||||||
|
|
||||||
|
if (!usedNamesDuplicate.contains(s)) {
|
||||||
|
if (!usedNames.add(s)) {
|
||||||
|
System.out.println("Warning: Duplicate key: " + s + " (" + oldS + ")!");
|
||||||
|
usedNamesDuplicate.add(s);
|
||||||
|
usedNames.remove(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usedNames.contains(s)) {
|
||||||
|
fieldNames.put(new MappingEntry(((FieldInsnNode) instr2).owner, ((FieldInsnNode) instr2).name, ((FieldInsnNode) instr2).desc), s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fieldNames;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 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.nameproposal;
|
||||||
|
|
||||||
|
public record MappingEntry(String owner, String name, String desc) {
|
||||||
|
}
|
|
@ -0,0 +1,166 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 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.nameproposal;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.jar.JarEntry;
|
||||||
|
import java.util.jar.JarInputStream;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.objectweb.asm.ClassReader;
|
||||||
|
import org.objectweb.asm.tree.ClassNode;
|
||||||
|
|
||||||
|
import net.fabricmc.mappingio.MappedElementKind;
|
||||||
|
import net.fabricmc.mappingio.MappingReader;
|
||||||
|
import net.fabricmc.mappingio.MappingWriter;
|
||||||
|
import net.fabricmc.mappingio.format.MappingFormat;
|
||||||
|
import net.fabricmc.mappingio.tree.MappingTree;
|
||||||
|
import net.fabricmc.mappingio.tree.MemoryMappingTree;
|
||||||
|
|
||||||
|
public class MappingNameCompleter {
|
||||||
|
// <intermediaryJar> <inputYarnMappings> <inputIntermediaryMappings> <outputYarnMappings>
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
completeNames(Paths.get(args[0]), Paths.get(args[1]), Paths.get(args[2]), Paths.get(args[3]));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void completeNames(Path intermediaryJar, Path inputYarnMappings, Path inputIntermediaryMappings, Path outputYarnMappings) throws IOException {
|
||||||
|
NameFinder nameFinder = new NameFinder();
|
||||||
|
|
||||||
|
acceptJar(nameFinder, intermediaryJar);
|
||||||
|
|
||||||
|
// We need the full intermediary mappings on their own to lookup the record component's root fields/methods.
|
||||||
|
nameFinder.acceptIntermediaryMappings(readMappings(inputIntermediaryMappings));
|
||||||
|
|
||||||
|
Map<MappingEntry, String> fieldNames = nameFinder.getFieldNames();
|
||||||
|
Map<MappingEntry, String> methodNames = nameFinder.getMethodNames();
|
||||||
|
Map<String, String> recordNames = nameFinder.getRecordNames();
|
||||||
|
|
||||||
|
System.out.printf("Found %d field names%n", fieldNames.size());
|
||||||
|
System.out.printf("Found %d method names%n", methodNames.size());
|
||||||
|
System.out.printf("Found %d record names%n", recordNames.size());
|
||||||
|
|
||||||
|
final MemoryMappingTree yarn = readMappings(inputYarnMappings);
|
||||||
|
final int yarnIntermediaryNs = yarn.getNamespaceId("intermediary");
|
||||||
|
final int yarnNamedNs = yarn.getNamespaceId("named");
|
||||||
|
|
||||||
|
for (Map.Entry<MappingEntry, String> entry : fieldNames.entrySet()) {
|
||||||
|
MappingEntry mappingEntry = entry.getKey();
|
||||||
|
|
||||||
|
// Ensure there is a class mapping for this
|
||||||
|
yarn.visitClass(mappingEntry.owner());
|
||||||
|
|
||||||
|
MemoryMappingTree.ClassMapping classMapping = yarn.getClass(mappingEntry.owner(), yarnIntermediaryNs);
|
||||||
|
|
||||||
|
yarn.visitField(mappingEntry.name(), mappingEntry.desc());
|
||||||
|
MappingTree.FieldMapping fieldMapping = Objects.requireNonNull(classMapping.getField(mappingEntry.name(), mappingEntry.desc(), yarnIntermediaryNs), "Could not find field");
|
||||||
|
String yarnFieldName = fieldMapping.getName(yarnNamedNs);
|
||||||
|
|
||||||
|
if (yarnFieldName == null || yarnFieldName.startsWith("field_") || yarnFieldName.startsWith("comp_")) {
|
||||||
|
// Set a new dst name if it doesn't have one, or matches intermediary
|
||||||
|
yarn.visitDstName(MappedElementKind.FIELD, yarnNamedNs, entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Map.Entry<MappingEntry, String> entry : methodNames.entrySet()) {
|
||||||
|
MappingEntry mappingEntry = entry.getKey();
|
||||||
|
|
||||||
|
// Ensure there is a class mapping for this
|
||||||
|
yarn.visitClass(mappingEntry.owner());
|
||||||
|
|
||||||
|
MemoryMappingTree.ClassMapping classMapping = yarn.getClass(mappingEntry.owner(), yarnIntermediaryNs);
|
||||||
|
|
||||||
|
yarn.visitMethod(mappingEntry.name(), mappingEntry.desc());
|
||||||
|
MappingTree.MethodMapping methodMapping = Objects.requireNonNull(classMapping.getMethod(mappingEntry.name(), mappingEntry.desc(), yarnIntermediaryNs), "Could not find method");
|
||||||
|
String yarnFieldName = methodMapping.getName(yarnNamedNs);
|
||||||
|
|
||||||
|
if (yarnFieldName == null || yarnFieldName.startsWith("method_") || yarnFieldName.startsWith("comp_")) {
|
||||||
|
// Set a new dst name if it doesn't have one, or matches intermediary
|
||||||
|
yarn.visitDstName(MappedElementKind.METHOD, yarnNamedNs, entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inheritMappedNamesOfEnclosingClasses(yarn);
|
||||||
|
|
||||||
|
try (MappingWriter mappingWriter = MappingWriter.create(outputYarnMappings, MappingFormat.TINY_2_FILE)) {
|
||||||
|
yarn.accept(mappingWriter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void acceptJar(NameFinder nameFinder, Path jar) throws IOException {
|
||||||
|
try (JarInputStream jarInputStream = new JarInputStream(Files.newInputStream(jar))) {
|
||||||
|
JarEntry entry;
|
||||||
|
|
||||||
|
while ((entry = jarInputStream.getNextJarEntry()) != null) {
|
||||||
|
if (!entry.getName().endsWith(".class")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClassReader reader = new ClassReader(jarInputStream);
|
||||||
|
ClassNode classNode = new ClassNode();
|
||||||
|
reader.accept(classNode, 0);
|
||||||
|
|
||||||
|
nameFinder.accept(classNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MemoryMappingTree readMappings(Path path) throws IOException {
|
||||||
|
MemoryMappingTree mappingTree = new MemoryMappingTree();
|
||||||
|
MappingReader.read(path, mappingTree);
|
||||||
|
return mappingTree;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Based off loom: https://github.com/FabricMC/fabric-loom/commit/98d8f3767253a1a3308542c2e896cbf5f4382033.
|
||||||
|
*/
|
||||||
|
private static void inheritMappedNamesOfEnclosingClasses(MemoryMappingTree tree) {
|
||||||
|
int namedIdx = tree.getNamespaceId("named");
|
||||||
|
|
||||||
|
// The tree does not have an index by intermediary names by default
|
||||||
|
tree.setIndexByDstNames(true);
|
||||||
|
|
||||||
|
for (MappingTree.ClassMapping classEntry : tree.getClasses()) {
|
||||||
|
String intermediaryName = Objects.requireNonNull(classEntry.getSrcName());
|
||||||
|
String namedName = classEntry.getDstName(namedIdx);
|
||||||
|
|
||||||
|
// No named name, or intermediary name equals the named - and inner class.
|
||||||
|
if ((namedName == null || intermediaryName.equals(namedName)) && intermediaryName.contains("$")) {
|
||||||
|
String[] path = intermediaryName.split(Pattern.quote("$"));
|
||||||
|
int parts = path.length;
|
||||||
|
|
||||||
|
for (int i = parts - 2; i >= 0; i--) {
|
||||||
|
String currentPath = String.join("$", Arrays.copyOfRange(path, 0, i + 1));
|
||||||
|
|
||||||
|
String namedParentClass = tree.mapClassName(currentPath, namedIdx);
|
||||||
|
|
||||||
|
if (!namedParentClass.equals(currentPath)) {
|
||||||
|
classEntry.setDstName(namedParentClass
|
||||||
|
+ "$" + String.join("$", Arrays.copyOfRange(path, i + 1, path.length)),
|
||||||
|
namedIdx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2021 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.nameproposal;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.objectweb.asm.tree.ClassNode;
|
||||||
|
import org.objectweb.asm.tree.MethodNode;
|
||||||
|
|
||||||
|
import net.fabricmc.mappingio.tree.MappingTree;
|
||||||
|
import net.fabricmc.mappingio.tree.MemoryMappingTree;
|
||||||
|
|
||||||
|
public class NameFinder {
|
||||||
|
// comp_x -> name
|
||||||
|
private final Map<String, String> recordNames = new HashMap<>();
|
||||||
|
private final Map<MappingEntry, String> recordFieldNames = new HashMap<>();
|
||||||
|
private final Map<MappingEntry, String> recordMethodNames = new HashMap<>();
|
||||||
|
|
||||||
|
private final Map<String, Set<String>> enumFields = new HashMap<>();
|
||||||
|
private final Map<String, List<MethodNode>> methods = new HashMap<>();
|
||||||
|
|
||||||
|
public void accept(ClassNode classNode) {
|
||||||
|
classNode.accept(new NameFinderVisitor(Constants.ASM_VERSION, enumFields, methods));
|
||||||
|
|
||||||
|
if ("java/lang/Record".equals(classNode.superName)) {
|
||||||
|
classNode.accept(new RecordComponentNameFinder(Constants.ASM_VERSION, recordNames));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void acceptIntermediaryMappings(MemoryMappingTree mappingTree) {
|
||||||
|
if (recordNames.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int intermediaryId = mappingTree.getNamespaceId("intermediary");
|
||||||
|
|
||||||
|
for (Map.Entry<String, String> entry : recordNames.entrySet()) {
|
||||||
|
boolean foundMethod = false;
|
||||||
|
boolean foundField = false;
|
||||||
|
|
||||||
|
for (MappingTree.ClassMapping classMapping : mappingTree.getClasses()) {
|
||||||
|
for (MappingTree.FieldMapping fieldMapping : classMapping.getFields()) {
|
||||||
|
if (fieldMapping.getName(intermediaryId).equals(entry.getKey())) {
|
||||||
|
MappingEntry fieldEntry = new MappingEntry(classMapping.getName(intermediaryId), fieldMapping.getName(intermediaryId), fieldMapping.getDesc(intermediaryId));
|
||||||
|
recordFieldNames.put(fieldEntry, entry.getValue());
|
||||||
|
foundField = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (MappingTree.MethodMapping methodMapping : classMapping.getMethods()) {
|
||||||
|
if (methodMapping.getName(intermediaryId).equals(entry.getKey())) {
|
||||||
|
MappingEntry fieldEntry = new MappingEntry(classMapping.getName(intermediaryId), methodMapping.getName(intermediaryId), methodMapping.getDesc(intermediaryId));
|
||||||
|
recordMethodNames.put(fieldEntry, entry.getValue());
|
||||||
|
foundMethod = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!foundField) {
|
||||||
|
System.err.println("Failed to find field for " + entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!foundMethod) {
|
||||||
|
System.err.println("Failed to find method for " + entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getRecordNames() {
|
||||||
|
return recordNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<MappingEntry, String> getFieldNames() {
|
||||||
|
Map<MappingEntry, String> fieldNames = new HashMap<>(new FieldNameFinder().findNames(enumFields, methods));
|
||||||
|
fieldNames.putAll(recordFieldNames);
|
||||||
|
return fieldNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<MappingEntry, String> getMethodNames() {
|
||||||
|
return recordMethodNames;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2021 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.nameproposal;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.objectweb.asm.ClassVisitor;
|
||||||
|
import org.objectweb.asm.FieldVisitor;
|
||||||
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
|
import org.objectweb.asm.tree.MethodNode;
|
||||||
|
|
||||||
|
public class NameFinderVisitor extends ClassVisitor {
|
||||||
|
private String owner;
|
||||||
|
private final Map<String, Set<String>> allEnumFields;
|
||||||
|
private final Map<String, List<MethodNode>> allMethods;
|
||||||
|
|
||||||
|
public NameFinderVisitor(int api, Map<String, Set<String>> allEnumFields, Map<String, List<MethodNode>> allMethods) {
|
||||||
|
super(api);
|
||||||
|
this.allMethods = allMethods;
|
||||||
|
this.allEnumFields = allEnumFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
|
||||||
|
this.owner = name;
|
||||||
|
super.visit(version, access, name, signature, superName, interfaces);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) {
|
||||||
|
if ((access & Opcodes.ACC_ENUM) != 0) {
|
||||||
|
if (!allEnumFields.computeIfAbsent(owner, s -> new HashSet<>()).add(descriptor + name)) {
|
||||||
|
throw new IllegalArgumentException("Found two enum fields with the same name \"" + name + "\"!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.visitField(access, name, descriptor, signature, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MethodVisitor visitMethod(
|
||||||
|
final int access,
|
||||||
|
final String name,
|
||||||
|
final String descriptor,
|
||||||
|
final String signature,
|
||||||
|
final String[] exceptions) {
|
||||||
|
if ("<clinit>".equals(name)) {
|
||||||
|
MethodNode node = new MethodNode(api, access, name, descriptor, signature, exceptions);
|
||||||
|
allMethods.computeIfAbsent(owner, s -> new ArrayList<>()).add(node);
|
||||||
|
return node;
|
||||||
|
} else {
|
||||||
|
return super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,134 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2021 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.nameproposal;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.objectweb.asm.ClassVisitor;
|
||||||
|
import org.objectweb.asm.Handle;
|
||||||
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
|
public final class RecordComponentNameFinder extends ClassVisitor {
|
||||||
|
static final Handle OBJ_MTH_BOOTSTRAP = new Handle(
|
||||||
|
Opcodes.H_INVOKESTATIC,
|
||||||
|
"java/lang/runtime/ObjectMethods",
|
||||||
|
"bootstrap",
|
||||||
|
"""
|
||||||
|
(Ljava/lang/invoke/MethodHandles$Lookup;\
|
||||||
|
Ljava/lang/String;Ljava/lang/invoke/TypeDescriptor;\
|
||||||
|
Ljava/lang/Class;Ljava/lang/String;\
|
||||||
|
[Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object;""",
|
||||||
|
false
|
||||||
|
);
|
||||||
|
static final Set<Component> OBJECT_METHODS = Set.of(
|
||||||
|
new Component("equals", "(Ljava/lang/Object;)Z"),
|
||||||
|
new Component("toString", "()Ljava/lang/String;"),
|
||||||
|
new Component("hashCode", "()I")
|
||||||
|
);
|
||||||
|
// comp_x -> name
|
||||||
|
private final Map<String, String> recordNames;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public RecordComponentNameFinder(int api, Map<String, String> recordNames) {
|
||||||
|
super(api);
|
||||||
|
this.recordNames = recordNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
|
||||||
|
super.visit(version, access, name, signature, superName, interfaces);
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
|
||||||
|
var nameAndType = new Component(name, descriptor);
|
||||||
|
|
||||||
|
if (OBJECT_METHODS.contains(nameAndType)) {
|
||||||
|
return new ObjectMethodVisitor(api, nameAndType);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ObjectMethodVisitor extends MethodVisitor {
|
||||||
|
private final String owner;
|
||||||
|
private final Component id;
|
||||||
|
|
||||||
|
ObjectMethodVisitor(int api, Component id) {
|
||||||
|
super(api);
|
||||||
|
this.owner = Objects.requireNonNull(RecordComponentNameFinder.this.name);
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitInvokeDynamicInsn(String name, String descriptor, Handle bootstrapMethodHandle, Object... bootstrapMethodArguments) {
|
||||||
|
super.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments);
|
||||||
|
|
||||||
|
if (!bootstrapMethodHandle.equals(OBJ_MTH_BOOTSTRAP) || !id.checkIndy(this.owner, name, descriptor)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert bootstrapMethodArguments[0] instanceof Type;
|
||||||
|
String recordClassName = ((Type) bootstrapMethodArguments[0]).getInternalName();
|
||||||
|
|
||||||
|
if (!recordClassName.equals(owner)) {
|
||||||
|
System.out.println("found mismatching object method bootstrap record class in caller class " + owner + "::" + id);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert bootstrapMethodArguments[1] instanceof String;
|
||||||
|
String[] names = ((String) bootstrapMethodArguments[1]).split(";");
|
||||||
|
assert names.length == bootstrapMethodArguments.length - 2;
|
||||||
|
|
||||||
|
for (int i = 2; i < bootstrapMethodArguments.length; i++) {
|
||||||
|
if (bootstrapMethodArguments[i] instanceof Handle handle) {
|
||||||
|
if (handle.getTag() == Opcodes.H_GETFIELD && handle.getOwner().equals(recordClassName)) {
|
||||||
|
var argName = names[i - 2];
|
||||||
|
put(recordNames, handle.getName(), argName);
|
||||||
|
} else {
|
||||||
|
// valid bytecode but we cannot guess
|
||||||
|
System.out.println("found special constant pool method handle, cannot process: " + owner + "::" + id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// valid bytecode, may be condy bsm arg, can't process
|
||||||
|
System.out.println("found special bootstrap method arg (maybe condy), cannot process: " + owner + "::" + id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void put(Map<String, String> out, String key, String value) {
|
||||||
|
var old = out.put(key, value);
|
||||||
|
|
||||||
|
if (old == null || old.equals(value)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Found conflicting name for component " + key + " in " + owner + "::"
|
||||||
|
+ id + ", replaced " + old + " with " + value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private record Component(String name, String desc) {
|
||||||
|
boolean checkIndy(String owner, String name, String desc) {
|
||||||
|
return this.name.equals(name) && ("(L" + owner + ";" + this.desc.substring(1)).equals(desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 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.nameproposal.enigma;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import cuchaz.enigma.analysis.index.JarIndex;
|
||||||
|
import cuchaz.enigma.api.service.JarIndexerService;
|
||||||
|
import cuchaz.enigma.api.service.NameProposalService;
|
||||||
|
import cuchaz.enigma.classprovider.ClassProvider;
|
||||||
|
import cuchaz.enigma.translation.mapping.EntryRemapper;
|
||||||
|
import cuchaz.enigma.translation.representation.entry.Entry;
|
||||||
|
import cuchaz.enigma.translation.representation.entry.FieldEntry;
|
||||||
|
import cuchaz.enigma.translation.representation.entry.MethodEntry;
|
||||||
|
import org.objectweb.asm.tree.ClassNode;
|
||||||
|
|
||||||
|
import net.fabricmc.filament.nameproposal.MappingEntry;
|
||||||
|
import net.fabricmc.filament.nameproposal.NameFinder;
|
||||||
|
|
||||||
|
public class EnigmaNameProposalService implements JarIndexerService, NameProposalService {
|
||||||
|
private Map<String, String> recordNames;
|
||||||
|
Map<MappingEntry, String> fieldNames;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void acceptJar(Set<String> classNames, ClassProvider classProvider, JarIndex jarIndex) {
|
||||||
|
NameFinder nameFinder = new NameFinder();
|
||||||
|
|
||||||
|
for (String className : classNames) {
|
||||||
|
ClassNode classNode = classProvider.get(className);
|
||||||
|
nameFinder.accept(Objects.requireNonNull(classNode, "Failed to get ClassNode for " + className));
|
||||||
|
}
|
||||||
|
|
||||||
|
recordNames = nameFinder.getRecordNames();
|
||||||
|
fieldNames = nameFinder.getFieldNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<String> proposeName(Entry<?> obfEntry, EntryRemapper remapper) {
|
||||||
|
Objects.requireNonNull(recordNames, "Cannot proposeName before indexing");
|
||||||
|
|
||||||
|
if (obfEntry instanceof FieldEntry fieldEntry) {
|
||||||
|
if (fieldEntry.getName().startsWith("comp_")) {
|
||||||
|
return Optional.ofNullable(recordNames.get(fieldEntry.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.ofNullable(fieldNames.get(new MappingEntry(fieldEntry.getContainingClass().getFullName(), fieldEntry.getName(), fieldEntry.getDesc().toString())));
|
||||||
|
} else if (obfEntry instanceof MethodEntry methodEntry) {
|
||||||
|
if (methodEntry.getName().startsWith("comp_")) {
|
||||||
|
return Optional.ofNullable(recordNames.get(methodEntry.getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2021 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.nameproposal.enigma;
|
||||||
|
|
||||||
|
import cuchaz.enigma.api.service.EnigmaServiceContext;
|
||||||
|
import cuchaz.enigma.api.service.ObfuscationTestService;
|
||||||
|
import cuchaz.enigma.translation.representation.entry.ClassEntry;
|
||||||
|
import cuchaz.enigma.translation.representation.entry.Entry;
|
||||||
|
import cuchaz.enigma.translation.representation.entry.FieldEntry;
|
||||||
|
import cuchaz.enigma.translation.representation.entry.MethodEntry;
|
||||||
|
|
||||||
|
public class IntermediaryObfuscationTestService implements ObfuscationTestService {
|
||||||
|
private final String prefix, classPrefix, classPackagePrefix, fieldPrefix, methodPrefix, componentPrefix;
|
||||||
|
|
||||||
|
public IntermediaryObfuscationTestService(EnigmaServiceContext<ObfuscationTestService> context) {
|
||||||
|
this.prefix = context.getArgument("package").orElse("net/minecraft") + "/";
|
||||||
|
this.classPrefix = context.getArgument("classPrefix").orElse("class_");
|
||||||
|
this.fieldPrefix = context.getArgument("fieldPrefix").orElse("field_");
|
||||||
|
this.methodPrefix = context.getArgument("methodPrefix").orElse("method_");
|
||||||
|
this.componentPrefix = context.getArgument("componentPrefix").orElse("comp_");
|
||||||
|
|
||||||
|
this.classPackagePrefix = this.prefix + this.classPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean testDeobfuscated(Entry<?> entry) {
|
||||||
|
if (entry instanceof ClassEntry) {
|
||||||
|
ClassEntry ce = (ClassEntry) entry;
|
||||||
|
String[] components = ce.getFullName().split("\\$");
|
||||||
|
|
||||||
|
// all obfuscated components are, at their outermost, class_
|
||||||
|
String lastComponent = components[components.length - 1];
|
||||||
|
|
||||||
|
if (lastComponent.startsWith(this.classPrefix) || lastComponent.startsWith(this.classPackagePrefix)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (entry instanceof FieldEntry) {
|
||||||
|
if (entry.getName().startsWith(this.fieldPrefix)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry.getName().startsWith(this.componentPrefix)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (entry instanceof MethodEntry) {
|
||||||
|
if (entry.getName().startsWith(this.methodPrefix)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry.getName().startsWith(this.componentPrefix)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// unknown type
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// known type, not obfuscated
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 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.nameproposal.enigma;
|
||||||
|
|
||||||
|
import cuchaz.enigma.api.EnigmaPlugin;
|
||||||
|
import cuchaz.enigma.api.EnigmaPluginContext;
|
||||||
|
import cuchaz.enigma.api.service.JarIndexerService;
|
||||||
|
import cuchaz.enigma.api.service.NameProposalService;
|
||||||
|
import cuchaz.enigma.api.service.ObfuscationTestService;
|
||||||
|
|
||||||
|
public class NameProposalServiceEnigmaPlugin implements EnigmaPlugin {
|
||||||
|
private static final String ID_PREFIX = "nameproposal:";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(EnigmaPluginContext ctx) {
|
||||||
|
ctx.registerService(ID_PREFIX + "intermediary_obfuscation_test", ObfuscationTestService.TYPE, IntermediaryObfuscationTestService::new);
|
||||||
|
|
||||||
|
EnigmaNameProposalService service = new EnigmaNameProposalService();
|
||||||
|
ctx.registerService(ID_PREFIX + "jar_indexer", JarIndexerService.TYPE, ctx1 -> service);
|
||||||
|
ctx.registerService(ID_PREFIX + "name_proposal", NameProposalService.TYPE, ctx1 -> service);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
net.fabricmc.filament.nameproposal.enigma.NameProposalServiceEnigmaPlugin
|
|
@ -7,7 +7,6 @@ enigma_version=2.5.0
|
||||||
unpick_version=2.3.0
|
unpick_version=2.3.0
|
||||||
cfr_version=0.2.2
|
cfr_version=0.2.2
|
||||||
vineflower_version=1.9.3
|
vineflower_version=1.9.3
|
||||||
name_proposal_version=0.2.0
|
|
||||||
asm_version=9.6
|
asm_version=9.6
|
||||||
|
|
||||||
# Javadoc generation/linking
|
# Javadoc generation/linking
|
||||||
|
|
Loading…
Reference in New Issue