diff options
| author | 2018-12-15 22:29:41 +0200 | |
|---|---|---|
| committer | 2018-12-15 21:29:41 +0100 | |
| commit | 4ff89cb1d48cb6916220ee308bf40810cfd868e2 (patch) | |
| tree | 1145080fde3ea6d727848d15994a3b71478ee22f /src/main/java/cuchaz/enigma/bytecode | |
| parent | Fix #78 (#85) (diff) | |
| download | enigma-fork-4ff89cb1d48cb6916220ee308bf40810cfd868e2.tar.gz enigma-fork-4ff89cb1d48cb6916220ee308bf40810cfd868e2.tar.xz enigma-fork-4ff89cb1d48cb6916220ee308bf40810cfd868e2.zip | |
Tweak variable name generation (#86)
* Don't apply offset to all methods in abstract class
* Tweak local variable naming
Diffstat (limited to 'src/main/java/cuchaz/enigma/bytecode')
| -rw-r--r-- | src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java | 70 |
1 files changed, 43 insertions, 27 deletions
diff --git a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java index 52b40b0..6d0d550 100644 --- a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java +++ b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java | |||
| @@ -1,14 +1,13 @@ | |||
| 1 | package cuchaz.enigma.bytecode.translators; | 1 | package cuchaz.enigma.bytecode.translators; |
| 2 | 2 | ||
| 3 | import cuchaz.enigma.mapping.MethodDescriptor; | 3 | import cuchaz.enigma.mapping.*; |
| 4 | import cuchaz.enigma.mapping.Signature; | ||
| 5 | import cuchaz.enigma.mapping.Translator; | ||
| 6 | import cuchaz.enigma.mapping.TypeDescriptor; | ||
| 7 | import cuchaz.enigma.mapping.entry.*; | 4 | import cuchaz.enigma.mapping.entry.*; |
| 8 | import org.objectweb.asm.*; | 5 | import org.objectweb.asm.*; |
| 9 | 6 | ||
| 7 | import java.util.Collection; | ||
| 10 | import java.util.List; | 8 | import java.util.List; |
| 11 | import java.util.Locale; | 9 | import java.util.Locale; |
| 10 | import java.util.stream.Collectors; | ||
| 12 | 11 | ||
| 13 | public class TranslationMethodVisitor extends MethodVisitor { | 12 | public class TranslationMethodVisitor extends MethodVisitor { |
| 14 | private final ClassDefEntry ownerEntry; | 13 | private final ClassDefEntry ownerEntry; |
| @@ -85,17 +84,26 @@ public class TranslationMethodVisitor extends MethodVisitor { | |||
| 85 | hasParameterMeta = true; | 84 | hasParameterMeta = true; |
| 86 | 85 | ||
| 87 | String translatedSignature = translator.getTranslatedSignature(Signature.createTypedSignature(signature)).toString(); | 86 | String translatedSignature = translator.getTranslatedSignature(Signature.createTypedSignature(signature)).toString(); |
| 88 | int offsetIndex = index; | 87 | int argumentIndex = methodEntry.getArgumentIndex(ownerEntry, index); |
| 89 | 88 | ||
| 90 | if (offsetIndex >= 0) { | 89 | if (argumentIndex >= 0) { |
| 91 | LocalVariableDefEntry entry = new LocalVariableDefEntry(methodEntry, offsetIndex, name, new TypeDescriptor(desc)); | 90 | LocalVariableDefEntry entry = new LocalVariableDefEntry(methodEntry, index, name, new TypeDescriptor(desc)); |
| 92 | LocalVariableDefEntry translatedEntry = translator.getTranslatedVariableDef(entry); | 91 | LocalVariableDefEntry translatedEntry = translator.getTranslatedVariableDef(entry); |
| 93 | String translatedName = translatedEntry.getName(); | 92 | String translatedName = translatedEntry.getName(); |
| 94 | 93 | ||
| 95 | // TODO: Better name inference | 94 | // TODO: Better name inference |
| 96 | if (translatedName.equals(entry.getName())) { | 95 | if (translatedName.equals(entry.getName())) { |
| 97 | boolean argument = offsetIndex < methodEntry.getDesc().getArgumentDescs().size(); | 96 | List<TypeDescriptor> arguments = methodEntry.getDesc().getArgumentDescs(); |
| 98 | translatedName = inferName(argument, offsetIndex, translatedEntry.getDesc()); | 97 | List<TypeDescriptor> translatedArguments = arguments.stream() |
| 98 | .map(translator::getTranslatedTypeDesc) | ||
| 99 | .collect(Collectors.toList()); | ||
| 100 | |||
| 101 | boolean argument = argumentIndex < arguments.size(); | ||
| 102 | if (argument) { | ||
| 103 | translatedName = inferArgumentName(argumentIndex, translatedEntry.getDesc(), translatedArguments); | ||
| 104 | } else { | ||
| 105 | translatedName = inferLocalVariableName(argumentIndex, translatedEntry.getDesc()); | ||
| 106 | } | ||
| 99 | } | 107 | } |
| 100 | 108 | ||
| 101 | super.visitLocalVariable(translatedName, translatedEntry.getDesc().toString(), translatedSignature, start, end, index); | 109 | super.visitLocalVariable(translatedName, translatedEntry.getDesc().toString(), translatedSignature, start, end, index); |
| @@ -147,48 +155,56 @@ public class TranslationMethodVisitor extends MethodVisitor { | |||
| 147 | // If we didn't receive any parameter metadata, generate it | 155 | // If we didn't receive any parameter metadata, generate it |
| 148 | if (!hasParameterMeta) { | 156 | if (!hasParameterMeta) { |
| 149 | List<TypeDescriptor> arguments = methodEntry.getDesc().getArgumentDescs(); | 157 | List<TypeDescriptor> arguments = methodEntry.getDesc().getArgumentDescs(); |
| 150 | int flags = ownerEntry.getAccess().getFlags(); | 158 | int offset = ((methodEntry.getAccess().getFlags() & Opcodes.ACC_ABSTRACT) != 0) ? 1 : 0; |
| 151 | int offset = ((flags & Opcodes.ACC_INTERFACE) != 0 || (flags & Opcodes.ACC_ABSTRACT) != 0) ? 1 : 0; | ||
| 152 | 159 | ||
| 153 | for (int index = 0; index < arguments.size(); index++) { | 160 | for (int argumentIndex = 0; argumentIndex < arguments.size(); argumentIndex++) { |
| 154 | LocalVariableEntry entry = new LocalVariableEntry(methodEntry, offset, "", true); | 161 | LocalVariableEntry entry = new LocalVariableEntry(methodEntry, offset, "", true); |
| 155 | LocalVariableEntry translatedEntry = translator.getTranslatedVariable(entry); | 162 | LocalVariableEntry translatedEntry = translator.getTranslatedVariable(entry); |
| 156 | String translatedName = translatedEntry.getName(); | 163 | String translatedName = translatedEntry.getName(); |
| 157 | if (translatedName.equals(entry.getName())) { | 164 | if (translatedName.equals(entry.getName())) { |
| 158 | super.visitParameter(inferName(true, index, arguments.get(index)), 0); | 165 | super.visitParameter(inferArgumentName(argumentIndex, arguments.get(argumentIndex), arguments), 0); |
| 159 | } else { | 166 | } else { |
| 160 | super.visitParameter(translatedName, 0); | 167 | super.visitParameter(translatedName, 0); |
| 161 | } | 168 | } |
| 162 | 169 | ||
| 163 | offset += arguments.get(index).getSize(); | 170 | offset += arguments.get(argumentIndex).getSize(); |
| 164 | } | 171 | } |
| 165 | } | 172 | } |
| 166 | super.visitEnd(); | 173 | super.visitEnd(); |
| 167 | } | 174 | } |
| 168 | 175 | ||
| 169 | private String inferName(boolean argument, int argumentIndex, TypeDescriptor desc) { | 176 | private String inferArgumentName(int index, TypeDescriptor desc, Collection<TypeDescriptor> arguments) { |
| 177 | boolean uniqueType = arguments.stream().filter(desc::equals).count() <= 1; | ||
| 170 | String translatedName; | 178 | String translatedName; |
| 171 | int nameIndex = argumentIndex + 1; | 179 | int nameIndex = index + 1; |
| 172 | StringBuilder nameBuilder = new StringBuilder(argument ? "a" : "v"); | 180 | StringBuilder nameBuilder = new StringBuilder(getTypeName(desc)); |
| 181 | if (!uniqueType || NameValidator.isReserved(nameBuilder.toString())) { | ||
| 182 | nameBuilder.append(nameIndex); | ||
| 183 | } | ||
| 184 | translatedName = nameBuilder.toString(); | ||
| 185 | return translatedName; | ||
| 186 | } | ||
| 187 | |||
| 188 | private String inferLocalVariableName(int index, TypeDescriptor desc) { | ||
| 189 | int nameIndex = index + 1; | ||
| 190 | return getTypeName(desc) + nameIndex; | ||
| 191 | } | ||
| 192 | |||
| 193 | private String getTypeName(TypeDescriptor desc) { | ||
| 173 | // Unfortunately each of these have different name getters, so they have different code paths | 194 | // Unfortunately each of these have different name getters, so they have different code paths |
| 174 | if (desc.isPrimitive()) { | 195 | if (desc.isPrimitive()) { |
| 175 | TypeDescriptor.Primitive argCls = desc.getPrimitive(); | 196 | TypeDescriptor.Primitive argCls = desc.getPrimitive(); |
| 176 | nameBuilder.append(argCls.name()); | 197 | return argCls.name().toLowerCase(Locale.ROOT); |
| 177 | } else if (desc.isArray()) { | 198 | } else if (desc.isArray()) { |
| 178 | // List types would require this whole block again, so just go with aListx | 199 | // List types would require this whole block again, so just go with aListx |
| 179 | nameBuilder.append("Arr"); | 200 | return "arr"; |
| 180 | } else if (desc.isType()) { | 201 | } else if (desc.isType()) { |
| 181 | String typeName = desc.getTypeEntry().getSimpleName().replace("$", ""); | 202 | String typeName = desc.getTypeEntry().getSimpleName().replace("$", ""); |
| 182 | typeName = typeName.substring(0, 1).toUpperCase(Locale.ROOT) + typeName.substring(1); | 203 | typeName = typeName.substring(0, 1).toLowerCase(Locale.ROOT) + typeName.substring(1); |
| 183 | nameBuilder.append(typeName); | 204 | return typeName; |
| 184 | } else { | 205 | } else { |
| 185 | System.err.println("Encountered invalid argument type descriptor " + desc.toString()); | 206 | System.err.println("Encountered invalid argument type descriptor " + desc.toString()); |
| 186 | nameBuilder.append("Unk"); | 207 | return "var"; |
| 187 | } | 208 | } |
| 188 | if (!argument || methodEntry.getDesc().getArgumentDescs().size() > 1) { | ||
| 189 | nameBuilder.append(nameIndex); | ||
| 190 | } | ||
| 191 | translatedName = nameBuilder.toString(); | ||
| 192 | return translatedName; | ||
| 193 | } | 209 | } |
| 194 | } | 210 | } |