diff options
| author | 2020-06-03 13:39:42 -0400 | |
|---|---|---|
| committer | 2020-06-03 18:39:42 +0100 | |
| commit | 0f47403d0220757fed189b76e2071e25b1025cb8 (patch) | |
| tree | 879bf72c4476f0a5e0d82da99d7ff2b2276bcaca /src/main/java/cuchaz/enigma/translation/representation | |
| parent | Fix search dialog hanging for a short time sometimes (#250) (diff) | |
| download | enigma-fork-0f47403d0220757fed189b76e2071e25b1025cb8.tar.gz enigma-fork-0f47403d0220757fed189b76e2071e25b1025cb8.tar.xz enigma-fork-0f47403d0220757fed189b76e2071e25b1025cb8.zip | |
Split GUI code to separate module (#242)
* Split into modules
* Post merge compile fixes
Co-authored-by: modmuss50 <modmuss50@gmail.com>
Diffstat (limited to 'src/main/java/cuchaz/enigma/translation/representation')
16 files changed, 0 insertions, 1709 deletions
diff --git a/src/main/java/cuchaz/enigma/translation/representation/AccessFlags.java b/src/main/java/cuchaz/enigma/translation/representation/AccessFlags.java deleted file mode 100644 index b280eef..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/AccessFlags.java +++ /dev/null | |||
| @@ -1,116 +0,0 @@ | |||
| 1 | package cuchaz.enigma.translation.representation; | ||
| 2 | |||
| 3 | import cuchaz.enigma.analysis.Access; | ||
| 4 | import org.objectweb.asm.Opcodes; | ||
| 5 | |||
| 6 | import java.lang.reflect.Modifier; | ||
| 7 | |||
| 8 | public class AccessFlags { | ||
| 9 | public static final AccessFlags PRIVATE = new AccessFlags(Opcodes.ACC_PRIVATE); | ||
| 10 | public static final AccessFlags PUBLIC = new AccessFlags(Opcodes.ACC_PUBLIC); | ||
| 11 | |||
| 12 | private int flags; | ||
| 13 | |||
| 14 | public AccessFlags(int flags) { | ||
| 15 | this.flags = flags; | ||
| 16 | } | ||
| 17 | |||
| 18 | public boolean isPrivate() { | ||
| 19 | return Modifier.isPrivate(this.flags); | ||
| 20 | } | ||
| 21 | |||
| 22 | public boolean isProtected() { | ||
| 23 | return Modifier.isProtected(this.flags); | ||
| 24 | } | ||
| 25 | |||
| 26 | public boolean isPublic() { | ||
| 27 | return Modifier.isPublic(this.flags); | ||
| 28 | } | ||
| 29 | |||
| 30 | public boolean isSynthetic() { | ||
| 31 | return (this.flags & Opcodes.ACC_SYNTHETIC) != 0; | ||
| 32 | } | ||
| 33 | |||
| 34 | public boolean isStatic() { | ||
| 35 | return Modifier.isStatic(this.flags); | ||
| 36 | } | ||
| 37 | |||
| 38 | public boolean isEnum() { | ||
| 39 | return (flags & Opcodes.ACC_ENUM) != 0; | ||
| 40 | } | ||
| 41 | |||
| 42 | public boolean isBridge() { | ||
| 43 | return (flags & Opcodes.ACC_BRIDGE) != 0; | ||
| 44 | } | ||
| 45 | |||
| 46 | public boolean isFinal() { | ||
| 47 | return (flags & Opcodes.ACC_FINAL) != 0; | ||
| 48 | } | ||
| 49 | |||
| 50 | public boolean isInterface() { | ||
| 51 | return (flags & Opcodes.ACC_INTERFACE) != 0; | ||
| 52 | } | ||
| 53 | |||
| 54 | public AccessFlags setPrivate() { | ||
| 55 | this.setVisibility(Opcodes.ACC_PRIVATE); | ||
| 56 | return this; | ||
| 57 | } | ||
| 58 | |||
| 59 | public AccessFlags setProtected() { | ||
| 60 | this.setVisibility(Opcodes.ACC_PROTECTED); | ||
| 61 | return this; | ||
| 62 | } | ||
| 63 | |||
| 64 | public AccessFlags setPublic() { | ||
| 65 | this.setVisibility(Opcodes.ACC_PUBLIC); | ||
| 66 | return this; | ||
| 67 | } | ||
| 68 | |||
| 69 | public AccessFlags setBridge() { | ||
| 70 | flags |= Opcodes.ACC_BRIDGE; | ||
| 71 | return this; | ||
| 72 | } | ||
| 73 | |||
| 74 | @Deprecated | ||
| 75 | public AccessFlags setBridged() { | ||
| 76 | return setBridge(); | ||
| 77 | } | ||
| 78 | |||
| 79 | public void setVisibility(int visibility) { | ||
| 80 | this.resetVisibility(); | ||
| 81 | this.flags |= visibility; | ||
| 82 | } | ||
| 83 | |||
| 84 | private void resetVisibility() { | ||
| 85 | this.flags &= ~(Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED | Opcodes.ACC_PUBLIC); | ||
| 86 | } | ||
| 87 | |||
| 88 | public int getFlags() { | ||
| 89 | return this.flags; | ||
| 90 | } | ||
| 91 | |||
| 92 | @Override | ||
| 93 | public boolean equals(Object obj) { | ||
| 94 | return obj instanceof AccessFlags && ((AccessFlags) obj).flags == flags; | ||
| 95 | } | ||
| 96 | |||
| 97 | @Override | ||
| 98 | public int hashCode() { | ||
| 99 | return flags; | ||
| 100 | } | ||
| 101 | |||
| 102 | @Override | ||
| 103 | public String toString() { | ||
| 104 | StringBuilder builder = new StringBuilder(Access.get(this).toString().toLowerCase()); | ||
| 105 | if (isStatic()) { | ||
| 106 | builder.append(" static"); | ||
| 107 | } | ||
| 108 | if (isSynthetic()) { | ||
| 109 | builder.append(" synthetic"); | ||
| 110 | } | ||
| 111 | if (isBridge()) { | ||
| 112 | builder.append(" bridge"); | ||
| 113 | } | ||
| 114 | return builder.toString(); | ||
| 115 | } | ||
| 116 | } | ||
diff --git a/src/main/java/cuchaz/enigma/translation/representation/Lambda.java b/src/main/java/cuchaz/enigma/translation/representation/Lambda.java deleted file mode 100644 index 63eb563..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/Lambda.java +++ /dev/null | |||
| @@ -1,105 +0,0 @@ | |||
| 1 | package cuchaz.enigma.translation.representation; | ||
| 2 | |||
| 3 | import cuchaz.enigma.translation.Translatable; | ||
| 4 | import cuchaz.enigma.translation.Translator; | ||
| 5 | import cuchaz.enigma.translation.mapping.EntryMap; | ||
| 6 | import cuchaz.enigma.translation.mapping.EntryMapping; | ||
| 7 | import cuchaz.enigma.translation.mapping.EntryResolver; | ||
| 8 | import cuchaz.enigma.translation.mapping.ResolutionStrategy; | ||
| 9 | import cuchaz.enigma.translation.representation.entry.ClassEntry; | ||
| 10 | import cuchaz.enigma.translation.representation.entry.MethodEntry; | ||
| 11 | import cuchaz.enigma.translation.representation.entry.ParentedEntry; | ||
| 12 | |||
| 13 | import java.util.Objects; | ||
| 14 | |||
| 15 | public class Lambda implements Translatable { | ||
| 16 | private final String invokedName; | ||
| 17 | private final MethodDescriptor invokedType; | ||
| 18 | private final MethodDescriptor samMethodType; | ||
| 19 | private final ParentedEntry<?> implMethod; | ||
| 20 | private final MethodDescriptor instantiatedMethodType; | ||
| 21 | |||
| 22 | public Lambda(String invokedName, MethodDescriptor invokedType, MethodDescriptor samMethodType, ParentedEntry<?> implMethod, MethodDescriptor instantiatedMethodType) { | ||
| 23 | this.invokedName = invokedName; | ||
| 24 | this.invokedType = invokedType; | ||
| 25 | this.samMethodType = samMethodType; | ||
| 26 | this.implMethod = implMethod; | ||
| 27 | this.instantiatedMethodType = instantiatedMethodType; | ||
| 28 | } | ||
| 29 | |||
| 30 | @Override | ||
| 31 | public Lambda translate(Translator translator, EntryResolver resolver, EntryMap<EntryMapping> mappings) { | ||
| 32 | MethodEntry samMethod = new MethodEntry(getInterface(), invokedName, samMethodType); | ||
| 33 | EntryMapping samMethodMapping = resolveMapping(resolver, mappings, samMethod); | ||
| 34 | |||
| 35 | return new Lambda( | ||
| 36 | samMethodMapping != null ? samMethodMapping.getTargetName() : invokedName, | ||
| 37 | invokedType.translate(translator, resolver, mappings), | ||
| 38 | samMethodType.translate(translator, resolver, mappings), | ||
| 39 | implMethod.translate(translator, resolver, mappings), | ||
| 40 | instantiatedMethodType.translate(translator, resolver, mappings) | ||
| 41 | ); | ||
| 42 | } | ||
| 43 | |||
| 44 | private EntryMapping resolveMapping(EntryResolver resolver, EntryMap<EntryMapping> mappings, MethodEntry methodEntry) { | ||
| 45 | for (MethodEntry entry : resolver.resolveEntry(methodEntry, ResolutionStrategy.RESOLVE_ROOT)) { | ||
| 46 | EntryMapping mapping = mappings.get(entry); | ||
| 47 | if (mapping != null) { | ||
| 48 | return mapping; | ||
| 49 | } | ||
| 50 | } | ||
| 51 | return null; | ||
| 52 | } | ||
| 53 | |||
| 54 | public ClassEntry getInterface() { | ||
| 55 | return invokedType.getReturnDesc().getTypeEntry(); | ||
| 56 | } | ||
| 57 | |||
| 58 | public String getInvokedName() { | ||
| 59 | return invokedName; | ||
| 60 | } | ||
| 61 | |||
| 62 | public MethodDescriptor getInvokedType() { | ||
| 63 | return invokedType; | ||
| 64 | } | ||
| 65 | |||
| 66 | public MethodDescriptor getSamMethodType() { | ||
| 67 | return samMethodType; | ||
| 68 | } | ||
| 69 | |||
| 70 | public ParentedEntry<?> getImplMethod() { | ||
| 71 | return implMethod; | ||
| 72 | } | ||
| 73 | |||
| 74 | public MethodDescriptor getInstantiatedMethodType() { | ||
| 75 | return instantiatedMethodType; | ||
| 76 | } | ||
| 77 | |||
| 78 | @Override | ||
| 79 | public boolean equals(Object o) { | ||
| 80 | if (this == o) return true; | ||
| 81 | if (o == null || getClass() != o.getClass()) return false; | ||
| 82 | Lambda lambda = (Lambda) o; | ||
| 83 | return Objects.equals(invokedName, lambda.invokedName) && | ||
| 84 | Objects.equals(invokedType, lambda.invokedType) && | ||
| 85 | Objects.equals(samMethodType, lambda.samMethodType) && | ||
| 86 | Objects.equals(implMethod, lambda.implMethod) && | ||
| 87 | Objects.equals(instantiatedMethodType, lambda.instantiatedMethodType); | ||
| 88 | } | ||
| 89 | |||
| 90 | @Override | ||
| 91 | public int hashCode() { | ||
| 92 | return Objects.hash(invokedName, invokedType, samMethodType, implMethod, instantiatedMethodType); | ||
| 93 | } | ||
| 94 | |||
| 95 | @Override | ||
| 96 | public String toString() { | ||
| 97 | return "Lambda{" + | ||
| 98 | "invokedName='" + invokedName + '\'' + | ||
| 99 | ", invokedType=" + invokedType + | ||
| 100 | ", samMethodType=" + samMethodType + | ||
| 101 | ", implMethod=" + implMethod + | ||
| 102 | ", instantiatedMethodType=" + instantiatedMethodType + | ||
| 103 | '}'; | ||
| 104 | } | ||
| 105 | } | ||
diff --git a/src/main/java/cuchaz/enigma/translation/representation/MethodDescriptor.java b/src/main/java/cuchaz/enigma/translation/representation/MethodDescriptor.java deleted file mode 100644 index 37a7014..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/MethodDescriptor.java +++ /dev/null | |||
| @@ -1,132 +0,0 @@ | |||
| 1 | /******************************************************************************* | ||
| 2 | * Copyright (c) 2015 Jeff Martin. | ||
| 3 | * All rights reserved. This program and the accompanying materials | ||
| 4 | * are made available under the terms of the GNU Lesser General Public | ||
| 5 | * License v3.0 which accompanies this distribution, and is available at | ||
| 6 | * http://www.gnu.org/licenses/lgpl.html | ||
| 7 | * <p> | ||
| 8 | * Contributors: | ||
| 9 | * Jeff Martin - initial API and implementation | ||
| 10 | ******************************************************************************/ | ||
| 11 | |||
| 12 | package cuchaz.enigma.translation.representation; | ||
| 13 | |||
| 14 | import com.google.common.collect.Lists; | ||
| 15 | import cuchaz.enigma.translation.Translatable; | ||
| 16 | import cuchaz.enigma.translation.Translator; | ||
| 17 | import cuchaz.enigma.translation.mapping.EntryMapping; | ||
| 18 | import cuchaz.enigma.translation.mapping.EntryResolver; | ||
| 19 | import cuchaz.enigma.translation.mapping.EntryMap; | ||
| 20 | import cuchaz.enigma.translation.representation.entry.ClassEntry; | ||
| 21 | import cuchaz.enigma.utils.Utils; | ||
| 22 | |||
| 23 | import java.util.ArrayList; | ||
| 24 | import java.util.List; | ||
| 25 | import java.util.function.Function; | ||
| 26 | |||
| 27 | public class MethodDescriptor implements Translatable { | ||
| 28 | |||
| 29 | private List<TypeDescriptor> argumentDescs; | ||
| 30 | private TypeDescriptor returnDesc; | ||
| 31 | |||
| 32 | public MethodDescriptor(String desc) { | ||
| 33 | try { | ||
| 34 | this.argumentDescs = Lists.newArrayList(); | ||
| 35 | int i = 0; | ||
| 36 | while (i < desc.length()) { | ||
| 37 | char c = desc.charAt(i); | ||
| 38 | if (c == '(') { | ||
| 39 | assert (this.argumentDescs.isEmpty()); | ||
| 40 | assert (this.returnDesc == null); | ||
| 41 | i++; | ||
| 42 | } else if (c == ')') { | ||
| 43 | i++; | ||
| 44 | break; | ||
| 45 | } else { | ||
| 46 | String type = TypeDescriptor.parseFirst(desc.substring(i)); | ||
| 47 | this.argumentDescs.add(new TypeDescriptor(type)); | ||
| 48 | i += type.length(); | ||
| 49 | } | ||
| 50 | } | ||
| 51 | this.returnDesc = new TypeDescriptor(TypeDescriptor.parseFirst(desc.substring(i))); | ||
| 52 | } catch (Exception ex) { | ||
| 53 | throw new IllegalArgumentException("Unable to parse method descriptor: " + desc, ex); | ||
| 54 | } | ||
| 55 | } | ||
| 56 | |||
| 57 | public MethodDescriptor(List<TypeDescriptor> argumentDescs, TypeDescriptor returnDesc) { | ||
| 58 | this.argumentDescs = argumentDescs; | ||
| 59 | this.returnDesc = returnDesc; | ||
| 60 | } | ||
| 61 | |||
| 62 | public List<TypeDescriptor> getArgumentDescs() { | ||
| 63 | return this.argumentDescs; | ||
| 64 | } | ||
| 65 | |||
| 66 | public TypeDescriptor getReturnDesc() { | ||
| 67 | return this.returnDesc; | ||
| 68 | } | ||
| 69 | |||
| 70 | @Override | ||
| 71 | public String toString() { | ||
| 72 | StringBuilder buf = new StringBuilder(); | ||
| 73 | buf.append("("); | ||
| 74 | for (TypeDescriptor desc : this.argumentDescs) { | ||
| 75 | buf.append(desc); | ||
| 76 | } | ||
| 77 | buf.append(")"); | ||
| 78 | buf.append(this.returnDesc); | ||
| 79 | return buf.toString(); | ||
| 80 | } | ||
| 81 | |||
| 82 | public Iterable<TypeDescriptor> types() { | ||
| 83 | List<TypeDescriptor> descs = Lists.newArrayList(); | ||
| 84 | descs.addAll(this.argumentDescs); | ||
| 85 | descs.add(this.returnDesc); | ||
| 86 | return descs; | ||
| 87 | } | ||
| 88 | |||
| 89 | @Override | ||
| 90 | public boolean equals(Object other) { | ||
| 91 | return other instanceof MethodDescriptor && equals((MethodDescriptor) other); | ||
| 92 | } | ||
| 93 | |||
| 94 | public boolean equals(MethodDescriptor other) { | ||
| 95 | return this.argumentDescs.equals(other.argumentDescs) && this.returnDesc.equals(other.returnDesc); | ||
| 96 | } | ||
| 97 | |||
| 98 | @Override | ||
| 99 | public int hashCode() { | ||
| 100 | return Utils.combineHashesOrdered(this.argumentDescs.hashCode(), this.returnDesc.hashCode()); | ||
| 101 | } | ||
| 102 | |||
| 103 | public boolean hasClass(ClassEntry classEntry) { | ||
| 104 | for (TypeDescriptor desc : types()) { | ||
| 105 | if (desc.containsType() && desc.getTypeEntry().equals(classEntry)) { | ||
| 106 | return true; | ||
| 107 | } | ||
| 108 | } | ||
| 109 | return false; | ||
| 110 | } | ||
| 111 | |||
| 112 | public MethodDescriptor remap(Function<String, String> remapper) { | ||
| 113 | List<TypeDescriptor> argumentDescs = new ArrayList<>(this.argumentDescs.size()); | ||
| 114 | for (TypeDescriptor desc : this.argumentDescs) { | ||
| 115 | argumentDescs.add(desc.remap(remapper)); | ||
| 116 | } | ||
| 117 | return new MethodDescriptor(argumentDescs, returnDesc.remap(remapper)); | ||
| 118 | } | ||
| 119 | |||
| 120 | @Override | ||
| 121 | public MethodDescriptor translate(Translator translator, EntryResolver resolver, EntryMap<EntryMapping> mappings) { | ||
| 122 | List<TypeDescriptor> translatedArguments = new ArrayList<>(argumentDescs.size()); | ||
| 123 | for (TypeDescriptor argument : argumentDescs) { | ||
| 124 | translatedArguments.add(translator.translate(argument)); | ||
| 125 | } | ||
| 126 | return new MethodDescriptor(translatedArguments, translator.translate(returnDesc)); | ||
| 127 | } | ||
| 128 | |||
| 129 | public boolean canConflictWith(MethodDescriptor descriptor) { | ||
| 130 | return descriptor.argumentDescs.equals(argumentDescs); | ||
| 131 | } | ||
| 132 | } | ||
diff --git a/src/main/java/cuchaz/enigma/translation/representation/Signature.java b/src/main/java/cuchaz/enigma/translation/representation/Signature.java deleted file mode 100644 index 424088a..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/Signature.java +++ /dev/null | |||
| @@ -1,98 +0,0 @@ | |||
| 1 | package cuchaz.enigma.translation.representation; | ||
| 2 | |||
| 3 | import cuchaz.enigma.bytecode.translators.TranslationSignatureVisitor; | ||
| 4 | import cuchaz.enigma.translation.Translatable; | ||
| 5 | import cuchaz.enigma.translation.Translator; | ||
| 6 | import cuchaz.enigma.translation.mapping.EntryMap; | ||
| 7 | import cuchaz.enigma.translation.mapping.EntryMapping; | ||
| 8 | import cuchaz.enigma.translation.mapping.EntryResolver; | ||
| 9 | import cuchaz.enigma.translation.representation.entry.ClassEntry; | ||
| 10 | import org.objectweb.asm.signature.SignatureReader; | ||
| 11 | import org.objectweb.asm.signature.SignatureVisitor; | ||
| 12 | import org.objectweb.asm.signature.SignatureWriter; | ||
| 13 | |||
| 14 | import java.util.function.Function; | ||
| 15 | import java.util.regex.Pattern; | ||
| 16 | |||
| 17 | public class Signature implements Translatable { | ||
| 18 | private static final Pattern OBJECT_PATTERN = Pattern.compile(".*:Ljava/lang/Object;:.*"); | ||
| 19 | |||
| 20 | private final String signature; | ||
| 21 | private final boolean isType; | ||
| 22 | |||
| 23 | private Signature(String signature, boolean isType) { | ||
| 24 | if (signature != null && OBJECT_PATTERN.matcher(signature).matches()) { | ||
| 25 | signature = signature.replaceAll(":Ljava/lang/Object;:", "::"); | ||
| 26 | } | ||
| 27 | |||
| 28 | this.signature = signature; | ||
| 29 | this.isType = isType; | ||
| 30 | } | ||
| 31 | |||
| 32 | public static Signature createTypedSignature(String signature) { | ||
| 33 | if (signature != null && !signature.isEmpty()) { | ||
| 34 | return new Signature(signature, true); | ||
| 35 | } | ||
| 36 | return new Signature(null, true); | ||
| 37 | } | ||
| 38 | |||
| 39 | public static Signature createSignature(String signature) { | ||
| 40 | if (signature != null && !signature.isEmpty()) { | ||
| 41 | return new Signature(signature, false); | ||
| 42 | } | ||
| 43 | return new Signature(null, false); | ||
| 44 | } | ||
| 45 | |||
| 46 | public String getSignature() { | ||
| 47 | return signature; | ||
| 48 | } | ||
| 49 | |||
| 50 | public boolean isType() { | ||
| 51 | return isType; | ||
| 52 | } | ||
| 53 | |||
| 54 | public Signature remap(Function<String, String> remapper) { | ||
| 55 | if (signature == null) { | ||
| 56 | return this; | ||
| 57 | } | ||
| 58 | SignatureWriter writer = new SignatureWriter(); | ||
| 59 | SignatureVisitor visitor = new TranslationSignatureVisitor(remapper, writer); | ||
| 60 | if (isType) { | ||
| 61 | new SignatureReader(signature).acceptType(visitor); | ||
| 62 | } else { | ||
| 63 | new SignatureReader(signature).accept(visitor); | ||
| 64 | } | ||
| 65 | return new Signature(writer.toString(), isType); | ||
| 66 | } | ||
| 67 | |||
| 68 | @Override | ||
| 69 | public boolean equals(Object obj) { | ||
| 70 | if (obj instanceof Signature) { | ||
| 71 | Signature other = (Signature) obj; | ||
| 72 | return (other.signature == null && signature == null || other.signature != null | ||
| 73 | && signature != null && other.signature.equals(signature)) | ||
| 74 | && other.isType == this.isType; | ||
| 75 | } | ||
| 76 | return false; | ||
| 77 | } | ||
| 78 | |||
| 79 | @Override | ||
| 80 | public int hashCode() { | ||
| 81 | int hash = (isType ? 1 : 0) << 16; | ||
| 82 | if (signature != null) { | ||
| 83 | hash |= signature.hashCode(); | ||
| 84 | } | ||
| 85 | |||
| 86 | return hash; | ||
| 87 | } | ||
| 88 | |||
| 89 | @Override | ||
| 90 | public String toString() { | ||
| 91 | return signature; | ||
| 92 | } | ||
| 93 | |||
| 94 | @Override | ||
| 95 | public Translatable translate(Translator translator, EntryResolver resolver, EntryMap<EntryMapping> mappings) { | ||
| 96 | return remap(name -> translator.translate(new ClassEntry(name)).getFullName()); | ||
| 97 | } | ||
| 98 | } | ||
diff --git a/src/main/java/cuchaz/enigma/translation/representation/TypeDescriptor.java b/src/main/java/cuchaz/enigma/translation/representation/TypeDescriptor.java deleted file mode 100644 index f7ba849..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/TypeDescriptor.java +++ /dev/null | |||
| @@ -1,268 +0,0 @@ | |||
| 1 | /******************************************************************************* | ||
| 2 | * Copyright (c) 2015 Jeff Martin. | ||
| 3 | * All rights reserved. This program and the accompanying materials | ||
| 4 | * are made available under the terms of the GNU Lesser General Public | ||
| 5 | * License v3.0 which accompanies this distribution, and is available at | ||
| 6 | * http://www.gnu.org/licenses/lgpl.html | ||
| 7 | * <p> | ||
| 8 | * Contributors: | ||
| 9 | * Jeff Martin - initial API and implementation | ||
| 10 | ******************************************************************************/ | ||
| 11 | |||
| 12 | package cuchaz.enigma.translation.representation; | ||
| 13 | |||
| 14 | import com.google.common.base.Preconditions; | ||
| 15 | import com.google.common.collect.Maps; | ||
| 16 | import cuchaz.enigma.translation.Translatable; | ||
| 17 | import cuchaz.enigma.translation.Translator; | ||
| 18 | import cuchaz.enigma.translation.mapping.EntryMapping; | ||
| 19 | import cuchaz.enigma.translation.mapping.EntryResolver; | ||
| 20 | import cuchaz.enigma.translation.mapping.EntryMap; | ||
| 21 | import cuchaz.enigma.translation.representation.entry.ClassEntry; | ||
| 22 | |||
| 23 | import java.util.Map; | ||
| 24 | import java.util.function.Function; | ||
| 25 | |||
| 26 | public class TypeDescriptor implements Translatable { | ||
| 27 | |||
| 28 | protected final String desc; | ||
| 29 | |||
| 30 | public TypeDescriptor(String desc) { | ||
| 31 | Preconditions.checkNotNull(desc, "Desc cannot be null"); | ||
| 32 | |||
| 33 | // don't deal with generics | ||
| 34 | // this is just for raw jvm types | ||
| 35 | if (desc.charAt(0) == 'T' || desc.indexOf('<') >= 0 || desc.indexOf('>') >= 0) { | ||
| 36 | throw new IllegalArgumentException("don't use with generic types or templates: " + desc); | ||
| 37 | } | ||
| 38 | |||
| 39 | this.desc = desc; | ||
| 40 | } | ||
| 41 | |||
| 42 | public static String parseFirst(String in) { | ||
| 43 | |||
| 44 | if (in == null || in.length() <= 0) { | ||
| 45 | throw new IllegalArgumentException("No desc to parse, input is empty!"); | ||
| 46 | } | ||
| 47 | |||
| 48 | // read one desc from the input | ||
| 49 | |||
| 50 | char c = in.charAt(0); | ||
| 51 | |||
| 52 | // first check for void | ||
| 53 | if (c == 'V') { | ||
| 54 | return "V"; | ||
| 55 | } | ||
| 56 | |||
| 57 | // then check for primitives | ||
| 58 | Primitive primitive = Primitive.get(c); | ||
| 59 | if (primitive != null) { | ||
| 60 | return in.substring(0, 1); | ||
| 61 | } | ||
| 62 | |||
| 63 | // then check for classes | ||
| 64 | if (c == 'L') { | ||
| 65 | return readClass(in); | ||
| 66 | } | ||
| 67 | |||
| 68 | // then check for templates | ||
| 69 | if (c == 'T') { | ||
| 70 | return readClass(in); | ||
| 71 | } | ||
| 72 | |||
| 73 | // then check for arrays | ||
| 74 | int dim = countArrayDimension(in); | ||
| 75 | if (dim > 0) { | ||
| 76 | String arrayType = TypeDescriptor.parseFirst(in.substring(dim)); | ||
| 77 | return in.substring(0, dim + arrayType.length()); | ||
| 78 | } | ||
| 79 | |||
| 80 | throw new IllegalArgumentException("don't know how to parse: " + in); | ||
| 81 | } | ||
| 82 | |||
| 83 | private static int countArrayDimension(String in) { | ||
| 84 | int i = 0; | ||
| 85 | while (i < in.length() && in.charAt(i) == '[') | ||
| 86 | i++; | ||
| 87 | return i; | ||
| 88 | } | ||
| 89 | |||
| 90 | private static String readClass(String in) { | ||
| 91 | // read all the characters in the buffer until we hit a ';' | ||
| 92 | // include the parameters too | ||
| 93 | StringBuilder buf = new StringBuilder(); | ||
| 94 | int depth = 0; | ||
| 95 | for (int i = 0; i < in.length(); i++) { | ||
| 96 | char c = in.charAt(i); | ||
| 97 | buf.append(c); | ||
| 98 | |||
| 99 | if (c == '<') { | ||
| 100 | depth++; | ||
| 101 | } else if (c == '>') { | ||
| 102 | depth--; | ||
| 103 | } else if (depth == 0 && c == ';') { | ||
| 104 | return buf.toString(); | ||
| 105 | } | ||
| 106 | } | ||
| 107 | return null; | ||
| 108 | } | ||
| 109 | |||
| 110 | public static TypeDescriptor of(String name) { | ||
| 111 | return new TypeDescriptor("L" + name + ";"); | ||
| 112 | } | ||
| 113 | |||
| 114 | @Override | ||
| 115 | public String toString() { | ||
| 116 | return this.desc; | ||
| 117 | } | ||
| 118 | |||
| 119 | public boolean isVoid() { | ||
| 120 | return this.desc.length() == 1 && this.desc.charAt(0) == 'V'; | ||
| 121 | } | ||
| 122 | |||
| 123 | public boolean isPrimitive() { | ||
| 124 | return this.desc.length() == 1 && Primitive.get(this.desc.charAt(0)) != null; | ||
| 125 | } | ||
| 126 | |||
| 127 | public Primitive getPrimitive() { | ||
| 128 | if (!isPrimitive()) { | ||
| 129 | throw new IllegalStateException("not a primitive"); | ||
| 130 | } | ||
| 131 | return Primitive.get(this.desc.charAt(0)); | ||
| 132 | } | ||
| 133 | |||
| 134 | public boolean isType() { | ||
| 135 | return this.desc.charAt(0) == 'L' && this.desc.charAt(this.desc.length() - 1) == ';'; | ||
| 136 | } | ||
| 137 | |||
| 138 | public ClassEntry getTypeEntry() { | ||
| 139 | if (isType()) { | ||
| 140 | String name = this.desc.substring(1, this.desc.length() - 1); | ||
| 141 | |||
| 142 | int pos = name.indexOf('<'); | ||
| 143 | if (pos >= 0) { | ||
| 144 | // remove the parameters from the class name | ||
| 145 | name = name.substring(0, pos); | ||
| 146 | } | ||
| 147 | |||
| 148 | return new ClassEntry(name); | ||
| 149 | |||
| 150 | } else if (isArray() && getArrayType().isType()) { | ||
| 151 | return getArrayType().getTypeEntry(); | ||
| 152 | } else { | ||
| 153 | throw new IllegalStateException("desc doesn't have a class"); | ||
| 154 | } | ||
| 155 | } | ||
| 156 | |||
| 157 | public boolean isArray() { | ||
| 158 | return this.desc.charAt(0) == '['; | ||
| 159 | } | ||
| 160 | |||
| 161 | public int getArrayDimension() { | ||
| 162 | if (!isArray()) { | ||
| 163 | throw new IllegalStateException("not an array"); | ||
| 164 | } | ||
| 165 | return countArrayDimension(this.desc); | ||
| 166 | } | ||
| 167 | |||
| 168 | public TypeDescriptor getArrayType() { | ||
| 169 | if (!isArray()) { | ||
| 170 | throw new IllegalStateException("not an array"); | ||
| 171 | } | ||
| 172 | return new TypeDescriptor(this.desc.substring(getArrayDimension())); | ||
| 173 | } | ||
| 174 | |||
| 175 | public boolean containsType() { | ||
| 176 | return isType() || (isArray() && getArrayType().containsType()); | ||
| 177 | } | ||
| 178 | |||
| 179 | @Override | ||
| 180 | public boolean equals(Object other) { | ||
| 181 | return other instanceof TypeDescriptor && equals((TypeDescriptor) other); | ||
| 182 | } | ||
| 183 | |||
| 184 | public boolean equals(TypeDescriptor other) { | ||
| 185 | return this.desc.equals(other.desc); | ||
| 186 | } | ||
| 187 | |||
| 188 | @Override | ||
| 189 | public int hashCode() { | ||
| 190 | return this.desc.hashCode(); | ||
| 191 | } | ||
| 192 | |||
| 193 | public TypeDescriptor remap(Function<String, String> remapper) { | ||
| 194 | String desc = this.desc; | ||
| 195 | if (isType() || (isArray() && containsType())) { | ||
| 196 | String replacedName = remapper.apply(this.getTypeEntry().getFullName()); | ||
| 197 | if (replacedName != null) { | ||
| 198 | if (this.isType()) { | ||
| 199 | desc = "L" + replacedName + ";"; | ||
| 200 | } else { | ||
| 201 | desc = getArrayPrefix(this.getArrayDimension()) + "L" + replacedName + ";"; | ||
| 202 | } | ||
| 203 | } | ||
| 204 | } | ||
| 205 | return new TypeDescriptor(desc); | ||
| 206 | } | ||
| 207 | |||
| 208 | private static String getArrayPrefix(int dimension) { | ||
| 209 | StringBuilder buf = new StringBuilder(); | ||
| 210 | for (int i = 0; i < dimension; i++) { | ||
| 211 | buf.append("["); | ||
| 212 | } | ||
| 213 | return buf.toString(); | ||
| 214 | } | ||
| 215 | |||
| 216 | public int getSize() { | ||
| 217 | switch (desc.charAt(0)) { | ||
| 218 | case 'J': | ||
| 219 | case 'D': | ||
| 220 | if (desc.length() == 1) { | ||
| 221 | return 2; | ||
| 222 | } else { | ||
| 223 | return 1; | ||
| 224 | } | ||
| 225 | default: | ||
| 226 | return 1; | ||
| 227 | } | ||
| 228 | } | ||
| 229 | |||
| 230 | @Override | ||
| 231 | public Translatable translate(Translator translator, EntryResolver resolver, EntryMap<EntryMapping> mappings) { | ||
| 232 | return remap(name -> translator.translate(new ClassEntry(name)).getFullName()); | ||
| 233 | } | ||
| 234 | |||
| 235 | public enum Primitive { | ||
| 236 | BYTE('B'), | ||
| 237 | CHARACTER('C'), | ||
| 238 | SHORT('S'), | ||
| 239 | INTEGER('I'), | ||
| 240 | LONG('J'), | ||
| 241 | FLOAT('F'), | ||
| 242 | DOUBLE('D'), | ||
| 243 | BOOLEAN('Z'); | ||
| 244 | |||
| 245 | private static final Map<Character, Primitive> lookup; | ||
| 246 | |||
| 247 | static { | ||
| 248 | lookup = Maps.newTreeMap(); | ||
| 249 | for (Primitive val : values()) { | ||
| 250 | lookup.put(val.getCode(), val); | ||
| 251 | } | ||
| 252 | } | ||
| 253 | |||
| 254 | private char code; | ||
| 255 | |||
| 256 | Primitive(char code) { | ||
| 257 | this.code = code; | ||
| 258 | } | ||
| 259 | |||
| 260 | public static Primitive get(char code) { | ||
| 261 | return lookup.get(code); | ||
| 262 | } | ||
| 263 | |||
| 264 | public char getCode() { | ||
| 265 | return this.code; | ||
| 266 | } | ||
| 267 | } | ||
| 268 | } | ||
diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/ClassDefEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/ClassDefEntry.java deleted file mode 100644 index 6930765..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/ClassDefEntry.java +++ /dev/null | |||
| @@ -1,93 +0,0 @@ | |||
| 1 | /******************************************************************************* | ||
| 2 | * Copyright (c) 2015 Jeff Martin. | ||
| 3 | * All rights reserved. This program and the accompanying materials | ||
| 4 | * are made available under the terms of the GNU Lesser General Public | ||
| 5 | * License v3.0 which accompanies this distribution, and is available at | ||
| 6 | * http://www.gnu.org/licenses/lgpl.html | ||
| 7 | * <p> | ||
| 8 | * Contributors: | ||
| 9 | * Jeff Martin - initial API and implementation | ||
| 10 | ******************************************************************************/ | ||
| 11 | |||
| 12 | package cuchaz.enigma.translation.representation.entry; | ||
| 13 | |||
| 14 | import com.google.common.base.Preconditions; | ||
| 15 | import cuchaz.enigma.translation.Translator; | ||
| 16 | import cuchaz.enigma.translation.mapping.EntryMapping; | ||
| 17 | import cuchaz.enigma.translation.representation.AccessFlags; | ||
| 18 | import cuchaz.enigma.translation.representation.Signature; | ||
| 19 | |||
| 20 | import javax.annotation.Nullable; | ||
| 21 | import java.util.Arrays; | ||
| 22 | |||
| 23 | public class ClassDefEntry extends ClassEntry implements DefEntry<ClassEntry> { | ||
| 24 | private final AccessFlags access; | ||
| 25 | private final Signature signature; | ||
| 26 | private final ClassEntry superClass; | ||
| 27 | private final ClassEntry[] interfaces; | ||
| 28 | |||
| 29 | public ClassDefEntry(String className, Signature signature, AccessFlags access, @Nullable ClassEntry superClass, ClassEntry[] interfaces) { | ||
| 30 | this(getOuterClass(className), getInnerName(className), signature, access, superClass, interfaces, null); | ||
| 31 | } | ||
| 32 | |||
| 33 | public ClassDefEntry(ClassEntry parent, String className, Signature signature, AccessFlags access, @Nullable ClassEntry superClass, ClassEntry[] interfaces) { | ||
| 34 | this(parent, className, signature, access, superClass, interfaces, null); | ||
| 35 | } | ||
| 36 | |||
| 37 | public ClassDefEntry(ClassEntry parent, String className, Signature signature, AccessFlags access, @Nullable ClassEntry superClass, | ||
| 38 | ClassEntry[] interfaces, String javadocs) { | ||
| 39 | super(parent, className, javadocs); | ||
| 40 | Preconditions.checkNotNull(signature, "Class signature cannot be null"); | ||
| 41 | Preconditions.checkNotNull(access, "Class access cannot be null"); | ||
| 42 | |||
| 43 | this.signature = signature; | ||
| 44 | this.access = access; | ||
| 45 | this.superClass = superClass; | ||
| 46 | this.interfaces = interfaces != null ? interfaces : new ClassEntry[0]; | ||
| 47 | } | ||
| 48 | |||
| 49 | public static ClassDefEntry parse(int access, String name, String signature, String superName, String[] interfaces) { | ||
| 50 | ClassEntry superClass = superName != null ? new ClassEntry(superName) : null; | ||
| 51 | ClassEntry[] interfaceClasses = Arrays.stream(interfaces).map(ClassEntry::new).toArray(ClassEntry[]::new); | ||
| 52 | return new ClassDefEntry(name, Signature.createSignature(signature), new AccessFlags(access), superClass, interfaceClasses); | ||
| 53 | } | ||
| 54 | |||
| 55 | public Signature getSignature() { | ||
| 56 | return signature; | ||
| 57 | } | ||
| 58 | |||
| 59 | @Override | ||
| 60 | public AccessFlags getAccess() { | ||
| 61 | return access; | ||
| 62 | } | ||
| 63 | |||
| 64 | @Nullable | ||
| 65 | public ClassEntry getSuperClass() { | ||
| 66 | return superClass; | ||
| 67 | } | ||
| 68 | |||
| 69 | public ClassEntry[] getInterfaces() { | ||
| 70 | return interfaces; | ||
| 71 | } | ||
| 72 | |||
| 73 | @Override | ||
| 74 | public ClassDefEntry translate(Translator translator, @Nullable EntryMapping mapping) { | ||
| 75 | Signature translatedSignature = translator.translate(signature); | ||
| 76 | String translatedName = mapping != null ? mapping.getTargetName() : name; | ||
| 77 | AccessFlags translatedAccess = mapping != null ? mapping.getAccessModifier().transform(access) : access; | ||
| 78 | ClassEntry translatedSuper = translator.translate(superClass); | ||
| 79 | ClassEntry[] translatedInterfaces = Arrays.stream(interfaces).map(translator::translate).toArray(ClassEntry[]::new); | ||
| 80 | String docs = mapping != null ? mapping.getJavadoc() : null; | ||
| 81 | return new ClassDefEntry(parent, translatedName, translatedSignature, translatedAccess, translatedSuper, translatedInterfaces, docs); | ||
| 82 | } | ||
| 83 | |||
| 84 | @Override | ||
| 85 | public ClassDefEntry withName(String name) { | ||
| 86 | return new ClassDefEntry(parent, name, signature, access, superClass, interfaces, javadocs); | ||
| 87 | } | ||
| 88 | |||
| 89 | @Override | ||
| 90 | public ClassDefEntry withParent(ClassEntry parent) { | ||
| 91 | return new ClassDefEntry(parent, name, signature, access, superClass, interfaces, javadocs); | ||
| 92 | } | ||
| 93 | } | ||
diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/ClassEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/ClassEntry.java deleted file mode 100644 index d6171f1..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/ClassEntry.java +++ /dev/null | |||
| @@ -1,214 +0,0 @@ | |||
| 1 | /******************************************************************************* | ||
| 2 | * Copyright (c) 2015 Jeff Martin. | ||
| 3 | * All rights reserved. This program and the accompanying materials | ||
| 4 | * are made available under the terms of the GNU Lesser General Public | ||
| 5 | * License v3.0 which accompanies this distribution, and is available at | ||
| 6 | * http://www.gnu.org/licenses/lgpl.html | ||
| 7 | * <p> | ||
| 8 | * Contributors: | ||
| 9 | * Jeff Martin - initial API and implementation | ||
| 10 | ******************************************************************************/ | ||
| 11 | |||
| 12 | package cuchaz.enigma.translation.representation.entry; | ||
| 13 | |||
| 14 | import cuchaz.enigma.throwables.IllegalNameException; | ||
| 15 | import cuchaz.enigma.translation.Translator; | ||
| 16 | import cuchaz.enigma.translation.mapping.EntryMapping; | ||
| 17 | import cuchaz.enigma.translation.mapping.NameValidator; | ||
| 18 | import cuchaz.enigma.translation.representation.TypeDescriptor; | ||
| 19 | |||
| 20 | import javax.annotation.Nonnull; | ||
| 21 | import javax.annotation.Nullable; | ||
| 22 | import java.util.List; | ||
| 23 | import java.util.Objects; | ||
| 24 | |||
| 25 | public class ClassEntry extends ParentedEntry<ClassEntry> implements Comparable<ClassEntry> { | ||
| 26 | private final String fullName; | ||
| 27 | |||
| 28 | public ClassEntry(String className) { | ||
| 29 | this(getOuterClass(className), getInnerName(className), null); | ||
| 30 | } | ||
| 31 | |||
| 32 | public ClassEntry(@Nullable ClassEntry parent, String className) { | ||
| 33 | this(parent, className, null); | ||
| 34 | } | ||
| 35 | |||
| 36 | public ClassEntry(@Nullable ClassEntry parent, String className, @Nullable String javadocs) { | ||
| 37 | super(parent, className, javadocs); | ||
| 38 | if (parent != null) { | ||
| 39 | fullName = parent.getFullName() + "$" + name; | ||
| 40 | } else { | ||
| 41 | fullName = name; | ||
| 42 | } | ||
| 43 | |||
| 44 | if (parent == null && className.indexOf('.') >= 0) { | ||
| 45 | throw new IllegalArgumentException("Class name must be in JVM format. ie, path/to/package/class$inner : " + className); | ||
| 46 | } | ||
| 47 | } | ||
| 48 | |||
| 49 | @Override | ||
| 50 | public Class<ClassEntry> getParentType() { | ||
| 51 | return ClassEntry.class; | ||
| 52 | } | ||
| 53 | |||
| 54 | @Override | ||
| 55 | public String getName() { | ||
| 56 | return this.name; | ||
| 57 | } | ||
| 58 | |||
| 59 | public String getFullName() { | ||
| 60 | return fullName; | ||
| 61 | } | ||
| 62 | |||
| 63 | @Override | ||
| 64 | public ClassEntry translate(Translator translator, @Nullable EntryMapping mapping) { | ||
| 65 | if (name.charAt(0) == '[') { | ||
| 66 | String translatedName = translator.translate(new TypeDescriptor(name)).toString(); | ||
| 67 | return new ClassEntry(parent, translatedName); | ||
| 68 | } | ||
| 69 | |||
| 70 | String translatedName = mapping != null ? mapping.getTargetName() : name; | ||
| 71 | String docs = mapping != null ? mapping.getJavadoc() : null; | ||
| 72 | return new ClassEntry(parent, translatedName, docs); | ||
| 73 | } | ||
| 74 | |||
| 75 | @Override | ||
| 76 | public ClassEntry getContainingClass() { | ||
| 77 | return this; | ||
| 78 | } | ||
| 79 | |||
| 80 | @Override | ||
| 81 | public int hashCode() { | ||
| 82 | return fullName.hashCode(); | ||
| 83 | } | ||
| 84 | |||
| 85 | @Override | ||
| 86 | public boolean equals(Object other) { | ||
| 87 | return other instanceof ClassEntry && equals((ClassEntry) other); | ||
| 88 | } | ||
| 89 | |||
| 90 | public boolean equals(ClassEntry other) { | ||
| 91 | return other != null && Objects.equals(parent, other.parent) && this.name.equals(other.name); | ||
| 92 | } | ||
| 93 | |||
| 94 | @Override | ||
| 95 | public boolean canConflictWith(Entry<?> entry) { | ||
| 96 | return true; | ||
| 97 | } | ||
| 98 | |||
| 99 | @Override | ||
| 100 | public void validateName(String name) throws IllegalNameException { | ||
| 101 | NameValidator.validateClassName(name); | ||
| 102 | } | ||
| 103 | |||
| 104 | @Override | ||
| 105 | public ClassEntry withName(String name) { | ||
| 106 | return new ClassEntry(parent, name, javadocs); | ||
| 107 | } | ||
| 108 | |||
| 109 | @Override | ||
| 110 | public ClassEntry withParent(ClassEntry parent) { | ||
| 111 | return new ClassEntry(parent, name, javadocs); | ||
| 112 | } | ||
| 113 | |||
| 114 | @Override | ||
| 115 | public String toString() { | ||
| 116 | return getFullName(); | ||
| 117 | } | ||
| 118 | |||
| 119 | public String getPackageName() { | ||
| 120 | return getPackageName(fullName); | ||
| 121 | } | ||
| 122 | |||
| 123 | public String getSimpleName() { | ||
| 124 | int packagePos = name.lastIndexOf('/'); | ||
| 125 | if (packagePos > 0) { | ||
| 126 | return name.substring(packagePos + 1); | ||
| 127 | } | ||
| 128 | return name; | ||
| 129 | } | ||
| 130 | |||
| 131 | public boolean isInnerClass() { | ||
| 132 | return parent != null; | ||
| 133 | } | ||
| 134 | |||
| 135 | @Nullable | ||
| 136 | public ClassEntry getOuterClass() { | ||
| 137 | return parent; | ||
| 138 | } | ||
| 139 | |||
| 140 | @Nonnull | ||
| 141 | public ClassEntry getOutermostClass() { | ||
| 142 | if (parent == null) { | ||
| 143 | return this; | ||
| 144 | } | ||
| 145 | return parent.getOutermostClass(); | ||
| 146 | } | ||
| 147 | |||
| 148 | public ClassEntry buildClassEntry(List<ClassEntry> classChain) { | ||
| 149 | assert (classChain.contains(this)); | ||
| 150 | StringBuilder buf = new StringBuilder(); | ||
| 151 | for (ClassEntry chainEntry : classChain) { | ||
| 152 | if (buf.length() == 0) { | ||
| 153 | buf.append(chainEntry.getFullName()); | ||
| 154 | } else { | ||
| 155 | buf.append("$"); | ||
| 156 | buf.append(chainEntry.getSimpleName()); | ||
| 157 | } | ||
| 158 | |||
| 159 | if (chainEntry == this) { | ||
| 160 | break; | ||
| 161 | } | ||
| 162 | } | ||
| 163 | return new ClassEntry(buf.toString()); | ||
| 164 | } | ||
| 165 | |||
| 166 | public boolean isJre() { | ||
| 167 | String packageName = getPackageName(); | ||
| 168 | return packageName != null && (packageName.startsWith("java") || packageName.startsWith("javax")); | ||
| 169 | } | ||
| 170 | |||
| 171 | public static String getPackageName(String name) { | ||
| 172 | int pos = name.lastIndexOf('/'); | ||
| 173 | if (pos > 0) { | ||
| 174 | return name.substring(0, pos); | ||
| 175 | } | ||
| 176 | return null; | ||
| 177 | } | ||
| 178 | |||
| 179 | @Nullable | ||
| 180 | public static ClassEntry getOuterClass(String name) { | ||
| 181 | int index = name.lastIndexOf('$'); | ||
| 182 | if (index >= 0) { | ||
| 183 | return new ClassEntry(name.substring(0, index)); | ||
| 184 | } | ||
| 185 | return null; | ||
| 186 | } | ||
| 187 | |||
| 188 | public static String getInnerName(String name) { | ||
| 189 | int innerClassPos = name.lastIndexOf('$'); | ||
| 190 | if (innerClassPos > 0) { | ||
| 191 | return name.substring(innerClassPos + 1); | ||
| 192 | } | ||
| 193 | return name; | ||
| 194 | } | ||
| 195 | |||
| 196 | @Override | ||
| 197 | public String getSourceRemapName() { | ||
| 198 | ClassEntry outerClass = getOuterClass(); | ||
| 199 | if (outerClass != null) { | ||
| 200 | return outerClass.getSourceRemapName() + "." + name; | ||
| 201 | } | ||
| 202 | return getSimpleName(); | ||
| 203 | } | ||
| 204 | |||
| 205 | @Override | ||
| 206 | public int compareTo(ClassEntry entry) { | ||
| 207 | String fullName = getFullName(); | ||
| 208 | String otherFullName = entry.getFullName(); | ||
| 209 | if (fullName.length() != otherFullName.length()) { | ||
| 210 | return fullName.length() - otherFullName.length(); | ||
| 211 | } | ||
| 212 | return fullName.compareTo(otherFullName); | ||
| 213 | } | ||
| 214 | } | ||
diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/DefEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/DefEntry.java deleted file mode 100644 index 82536c7..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/DefEntry.java +++ /dev/null | |||
| @@ -1,7 +0,0 @@ | |||
| 1 | package cuchaz.enigma.translation.representation.entry; | ||
| 2 | |||
| 3 | import cuchaz.enigma.translation.representation.AccessFlags; | ||
| 4 | |||
| 5 | public interface DefEntry<P extends Entry<?>> extends Entry<P> { | ||
| 6 | AccessFlags getAccess(); | ||
| 7 | } | ||
diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/Entry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/Entry.java deleted file mode 100644 index 72b0391..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/Entry.java +++ /dev/null | |||
| @@ -1,107 +0,0 @@ | |||
| 1 | /******************************************************************************* | ||
| 2 | * Copyright (c) 2015 Jeff Martin. | ||
| 3 | * All rights reserved. This program and the accompanying materials | ||
| 4 | * are made available under the terms of the GNU Lesser General Public | ||
| 5 | * License v3.0 which accompanies this distribution, and is available at | ||
| 6 | * http://www.gnu.org/licenses/lgpl.html | ||
| 7 | * <p> | ||
| 8 | * Contributors: | ||
| 9 | * Jeff Martin - initial API and implementation | ||
| 10 | ******************************************************************************/ | ||
| 11 | |||
| 12 | package cuchaz.enigma.translation.representation.entry; | ||
| 13 | |||
| 14 | import cuchaz.enigma.throwables.IllegalNameException; | ||
| 15 | import cuchaz.enigma.translation.Translatable; | ||
| 16 | import cuchaz.enigma.translation.mapping.NameValidator; | ||
| 17 | |||
| 18 | import javax.annotation.Nullable; | ||
| 19 | import java.util.ArrayList; | ||
| 20 | import java.util.List; | ||
| 21 | |||
| 22 | public interface Entry<P extends Entry<?>> extends Translatable { | ||
| 23 | String getName(); | ||
| 24 | |||
| 25 | String getJavadocs(); | ||
| 26 | |||
| 27 | default String getSourceRemapName() { | ||
| 28 | return getName(); | ||
| 29 | } | ||
| 30 | |||
| 31 | @Nullable | ||
| 32 | P getParent(); | ||
| 33 | |||
| 34 | Class<P> getParentType(); | ||
| 35 | |||
| 36 | Entry<P> withName(String name); | ||
| 37 | |||
| 38 | Entry<P> withParent(P parent); | ||
| 39 | |||
| 40 | boolean canConflictWith(Entry<?> entry); | ||
| 41 | |||
| 42 | @Nullable | ||
| 43 | default ClassEntry getContainingClass() { | ||
| 44 | P parent = getParent(); | ||
| 45 | if (parent == null) { | ||
| 46 | return null; | ||
| 47 | } | ||
| 48 | if (parent instanceof ClassEntry) { | ||
| 49 | return (ClassEntry) parent; | ||
| 50 | } | ||
| 51 | return parent.getContainingClass(); | ||
| 52 | } | ||
| 53 | |||
| 54 | default List<Entry<?>> getAncestry() { | ||
| 55 | P parent = getParent(); | ||
| 56 | List<Entry<?>> entries = new ArrayList<>(); | ||
| 57 | if (parent != null) { | ||
| 58 | entries.addAll(parent.getAncestry()); | ||
| 59 | } | ||
| 60 | entries.add(this); | ||
| 61 | return entries; | ||
| 62 | } | ||
| 63 | |||
| 64 | @Nullable | ||
| 65 | @SuppressWarnings("unchecked") | ||
| 66 | default <E extends Entry<?>> E findAncestor(Class<E> type) { | ||
| 67 | List<Entry<?>> ancestry = getAncestry(); | ||
| 68 | for (int i = ancestry.size() - 1; i >= 0; i--) { | ||
| 69 | Entry<?> ancestor = ancestry.get(i); | ||
| 70 | if (type.isAssignableFrom(ancestor.getClass())) { | ||
| 71 | return (E) ancestor; | ||
| 72 | } | ||
| 73 | } | ||
| 74 | return null; | ||
| 75 | } | ||
| 76 | |||
| 77 | @SuppressWarnings("unchecked") | ||
| 78 | default <E extends Entry<?>> Entry<P> replaceAncestor(E target, E replacement) { | ||
| 79 | if (replacement.equals(target)) { | ||
| 80 | return this; | ||
| 81 | } | ||
| 82 | |||
| 83 | if (equals(target)) { | ||
| 84 | return (Entry<P>) replacement; | ||
| 85 | } | ||
| 86 | |||
| 87 | P parent = getParent(); | ||
| 88 | if (parent == null) { | ||
| 89 | return this; | ||
| 90 | } | ||
| 91 | |||
| 92 | return withParent((P) parent.replaceAncestor(target, replacement)); | ||
| 93 | } | ||
| 94 | |||
| 95 | default void validateName(String name) throws IllegalNameException { | ||
| 96 | NameValidator.validateIdentifier(name); | ||
| 97 | } | ||
| 98 | |||
| 99 | @SuppressWarnings("unchecked") | ||
| 100 | @Nullable | ||
| 101 | default <C extends Entry<?>> Entry<C> castParent(Class<C> parentType) { | ||
| 102 | if (parentType.equals(getParentType())) { | ||
| 103 | return (Entry<C>) this; | ||
| 104 | } | ||
| 105 | return null; | ||
| 106 | } | ||
| 107 | } | ||
diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/FieldDefEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/FieldDefEntry.java deleted file mode 100644 index f9282b2..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/FieldDefEntry.java +++ /dev/null | |||
| @@ -1,71 +0,0 @@ | |||
| 1 | /******************************************************************************* | ||
| 2 | * Copyright (c) 2015 Jeff Martin. | ||
| 3 | * All rights reserved. This program and the accompanying materials | ||
| 4 | * are made available under the terms of the GNU Lesser General Public | ||
| 5 | * License v3.0 which accompanies this distribution, and is available at | ||
| 6 | * http://www.gnu.org/licenses/lgpl.html | ||
| 7 | * <p> | ||
| 8 | * Contributors: | ||
| 9 | * Jeff Martin - initial API and implementation | ||
| 10 | ******************************************************************************/ | ||
| 11 | |||
| 12 | package cuchaz.enigma.translation.representation.entry; | ||
| 13 | |||
| 14 | import com.google.common.base.Preconditions; | ||
| 15 | import cuchaz.enigma.translation.Translator; | ||
| 16 | import cuchaz.enigma.translation.mapping.EntryMapping; | ||
| 17 | import cuchaz.enigma.translation.representation.AccessFlags; | ||
| 18 | import cuchaz.enigma.translation.representation.Signature; | ||
| 19 | import cuchaz.enigma.translation.representation.TypeDescriptor; | ||
| 20 | |||
| 21 | import javax.annotation.Nullable; | ||
| 22 | |||
| 23 | public class FieldDefEntry extends FieldEntry implements DefEntry<ClassEntry> { | ||
| 24 | private final AccessFlags access; | ||
| 25 | private final Signature signature; | ||
| 26 | |||
| 27 | public FieldDefEntry(ClassEntry owner, String name, TypeDescriptor desc, Signature signature, AccessFlags access) { | ||
| 28 | this(owner, name, desc, signature, access, null); | ||
| 29 | } | ||
| 30 | |||
| 31 | public FieldDefEntry(ClassEntry owner, String name, TypeDescriptor desc, Signature signature, AccessFlags access, String javadocs) { | ||
| 32 | super(owner, name, desc, javadocs); | ||
| 33 | Preconditions.checkNotNull(access, "Field access cannot be null"); | ||
| 34 | Preconditions.checkNotNull(signature, "Field signature cannot be null"); | ||
| 35 | this.access = access; | ||
| 36 | this.signature = signature; | ||
| 37 | } | ||
| 38 | |||
| 39 | public static FieldDefEntry parse(ClassEntry owner, int access, String name, String desc, String signature) { | ||
| 40 | return new FieldDefEntry(owner, name, new TypeDescriptor(desc), Signature.createTypedSignature(signature), new AccessFlags(access), null); | ||
| 41 | } | ||
| 42 | |||
| 43 | @Override | ||
| 44 | public AccessFlags getAccess() { | ||
| 45 | return access; | ||
| 46 | } | ||
| 47 | |||
| 48 | public Signature getSignature() { | ||
| 49 | return signature; | ||
| 50 | } | ||
| 51 | |||
| 52 | @Override | ||
| 53 | public FieldDefEntry translate(Translator translator, @Nullable EntryMapping mapping) { | ||
| 54 | TypeDescriptor translatedDesc = translator.translate(desc); | ||
| 55 | Signature translatedSignature = translator.translate(signature); | ||
| 56 | String translatedName = mapping != null ? mapping.getTargetName() : name; | ||
| 57 | AccessFlags translatedAccess = mapping != null ? mapping.getAccessModifier().transform(access) : access; | ||
| 58 | String docs = mapping != null ? mapping.getJavadoc() : null; | ||
| 59 | return new FieldDefEntry(parent, translatedName, translatedDesc, translatedSignature, translatedAccess, docs); | ||
| 60 | } | ||
| 61 | |||
| 62 | @Override | ||
| 63 | public FieldDefEntry withName(String name) { | ||
| 64 | return new FieldDefEntry(parent, name, desc, signature, access, javadocs); | ||
| 65 | } | ||
| 66 | |||
| 67 | @Override | ||
| 68 | public FieldDefEntry withParent(ClassEntry owner) { | ||
| 69 | return new FieldDefEntry(owner, this.name, this.desc, signature, access, javadocs); | ||
| 70 | } | ||
| 71 | } | ||
diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/FieldEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/FieldEntry.java deleted file mode 100644 index bef0edf..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/FieldEntry.java +++ /dev/null | |||
| @@ -1,96 +0,0 @@ | |||
| 1 | /******************************************************************************* | ||
| 2 | * Copyright (c) 2015 Jeff Martin. | ||
| 3 | * All rights reserved. This program and the accompanying materials | ||
| 4 | * are made available under the terms of the GNU Lesser General Public | ||
| 5 | * License v3.0 which accompanies this distribution, and is available at | ||
| 6 | * http://www.gnu.org/licenses/lgpl.html | ||
| 7 | * <p> | ||
| 8 | * Contributors: | ||
| 9 | * Jeff Martin - initial API and implementation | ||
| 10 | ******************************************************************************/ | ||
| 11 | |||
| 12 | package cuchaz.enigma.translation.representation.entry; | ||
| 13 | |||
| 14 | import com.google.common.base.Preconditions; | ||
| 15 | import cuchaz.enigma.translation.Translator; | ||
| 16 | import cuchaz.enigma.translation.mapping.EntryMapping; | ||
| 17 | import cuchaz.enigma.translation.representation.TypeDescriptor; | ||
| 18 | import cuchaz.enigma.utils.Utils; | ||
| 19 | |||
| 20 | import javax.annotation.Nullable; | ||
| 21 | |||
| 22 | public class FieldEntry extends ParentedEntry<ClassEntry> implements Comparable<FieldEntry> { | ||
| 23 | protected final TypeDescriptor desc; | ||
| 24 | |||
| 25 | public FieldEntry(ClassEntry parent, String name, TypeDescriptor desc) { | ||
| 26 | this(parent, name, desc, null); | ||
| 27 | } | ||
| 28 | |||
| 29 | public FieldEntry(ClassEntry parent, String name, TypeDescriptor desc, String javadocs) { | ||
| 30 | super(parent, name, javadocs); | ||
| 31 | |||
| 32 | Preconditions.checkNotNull(parent, "Owner cannot be null"); | ||
| 33 | Preconditions.checkNotNull(desc, "Field descriptor cannot be null"); | ||
| 34 | |||
| 35 | this.desc = desc; | ||
| 36 | } | ||
| 37 | |||
| 38 | public static FieldEntry parse(String owner, String name, String desc) { | ||
| 39 | return new FieldEntry(new ClassEntry(owner), name, new TypeDescriptor(desc), null); | ||
| 40 | } | ||
| 41 | |||
| 42 | @Override | ||
| 43 | public Class<ClassEntry> getParentType() { | ||
| 44 | return ClassEntry.class; | ||
| 45 | } | ||
| 46 | |||
| 47 | public TypeDescriptor getDesc() { | ||
| 48 | return this.desc; | ||
| 49 | } | ||
| 50 | |||
| 51 | @Override | ||
| 52 | public FieldEntry withName(String name) { | ||
| 53 | return new FieldEntry(parent, name, desc, null); | ||
| 54 | } | ||
| 55 | |||
| 56 | @Override | ||
| 57 | public FieldEntry withParent(ClassEntry parent) { | ||
| 58 | return new FieldEntry(parent, this.name, this.desc, null); | ||
| 59 | } | ||
| 60 | |||
| 61 | @Override | ||
| 62 | protected FieldEntry translate(Translator translator, @Nullable EntryMapping mapping) { | ||
| 63 | String translatedName = mapping != null ? mapping.getTargetName() : name; | ||
| 64 | String docs = mapping != null ? mapping.getJavadoc() : null; | ||
| 65 | return new FieldEntry(parent, translatedName, translator.translate(desc), docs); | ||
| 66 | } | ||
| 67 | |||
| 68 | @Override | ||
| 69 | public int hashCode() { | ||
| 70 | return Utils.combineHashesOrdered(this.parent, this.name, this.desc); | ||
| 71 | } | ||
| 72 | |||
| 73 | @Override | ||
| 74 | public boolean equals(Object other) { | ||
| 75 | return other instanceof FieldEntry && equals((FieldEntry) other); | ||
| 76 | } | ||
| 77 | |||
| 78 | public boolean equals(FieldEntry other) { | ||
| 79 | return this.parent.equals(other.parent) && name.equals(other.name) && desc.equals(other.desc); | ||
| 80 | } | ||
| 81 | |||
| 82 | @Override | ||
| 83 | public boolean canConflictWith(Entry<?> entry) { | ||
| 84 | return entry instanceof FieldEntry && ((FieldEntry) entry).parent.equals(parent); | ||
| 85 | } | ||
| 86 | |||
| 87 | @Override | ||
| 88 | public String toString() { | ||
| 89 | return this.parent.getFullName() + "." + this.name + ":" + this.desc; | ||
| 90 | } | ||
| 91 | |||
| 92 | @Override | ||
| 93 | public int compareTo(FieldEntry entry) { | ||
| 94 | return (name + desc.toString()).compareTo(entry.name + entry.desc.toString()); | ||
| 95 | } | ||
| 96 | } | ||
diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableDefEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableDefEntry.java deleted file mode 100644 index aad4236..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableDefEntry.java +++ /dev/null | |||
| @@ -1,51 +0,0 @@ | |||
| 1 | package cuchaz.enigma.translation.representation.entry; | ||
| 2 | |||
| 3 | import com.google.common.base.Preconditions; | ||
| 4 | import cuchaz.enigma.translation.Translator; | ||
| 5 | import cuchaz.enigma.translation.mapping.EntryMapping; | ||
| 6 | import cuchaz.enigma.translation.representation.TypeDescriptor; | ||
| 7 | |||
| 8 | import javax.annotation.Nullable; | ||
| 9 | |||
| 10 | /** | ||
| 11 | * TypeDescriptor... | ||
| 12 | * Created by Thog | ||
| 13 | * 19/10/2016 | ||
| 14 | */ | ||
| 15 | public class LocalVariableDefEntry extends LocalVariableEntry { | ||
| 16 | protected final TypeDescriptor desc; | ||
| 17 | |||
| 18 | public LocalVariableDefEntry(MethodEntry ownerEntry, int index, String name, boolean parameter, TypeDescriptor desc, String javadoc) { | ||
| 19 | super(ownerEntry, index, name, parameter, javadoc); | ||
| 20 | Preconditions.checkNotNull(desc, "Variable desc cannot be null"); | ||
| 21 | |||
| 22 | this.desc = desc; | ||
| 23 | } | ||
| 24 | |||
| 25 | public TypeDescriptor getDesc() { | ||
| 26 | return desc; | ||
| 27 | } | ||
| 28 | |||
| 29 | @Override | ||
| 30 | public LocalVariableDefEntry translate(Translator translator, @Nullable EntryMapping mapping) { | ||
| 31 | TypeDescriptor translatedDesc = translator.translate(desc); | ||
| 32 | String translatedName = mapping != null ? mapping.getTargetName() : name; | ||
| 33 | String javadoc = mapping != null ? mapping.getJavadoc() : javadocs; | ||
| 34 | return new LocalVariableDefEntry(parent, index, translatedName, parameter, translatedDesc, javadoc); | ||
| 35 | } | ||
| 36 | |||
| 37 | @Override | ||
| 38 | public LocalVariableDefEntry withName(String name) { | ||
| 39 | return new LocalVariableDefEntry(parent, index, name, parameter, desc, javadocs); | ||
| 40 | } | ||
| 41 | |||
| 42 | @Override | ||
| 43 | public LocalVariableDefEntry withParent(MethodEntry entry) { | ||
| 44 | return new LocalVariableDefEntry(entry, index, name, parameter, desc, javadocs); | ||
| 45 | } | ||
| 46 | |||
| 47 | @Override | ||
| 48 | public String toString() { | ||
| 49 | return this.parent + "(" + this.index + ":" + this.name + ":" + this.desc + ")"; | ||
| 50 | } | ||
| 51 | } | ||
diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableEntry.java deleted file mode 100644 index 3ccb1fa..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableEntry.java +++ /dev/null | |||
| @@ -1,93 +0,0 @@ | |||
| 1 | package cuchaz.enigma.translation.representation.entry; | ||
| 2 | |||
| 3 | import com.google.common.base.Preconditions; | ||
| 4 | import cuchaz.enigma.translation.Translator; | ||
| 5 | import cuchaz.enigma.translation.mapping.EntryMapping; | ||
| 6 | import cuchaz.enigma.utils.Utils; | ||
| 7 | |||
| 8 | import javax.annotation.Nullable; | ||
| 9 | |||
| 10 | /** | ||
| 11 | * TypeDescriptor... | ||
| 12 | * Created by Thog | ||
| 13 | * 19/10/2016 | ||
| 14 | */ | ||
| 15 | public class LocalVariableEntry extends ParentedEntry<MethodEntry> implements Comparable<LocalVariableEntry> { | ||
| 16 | |||
| 17 | protected final int index; | ||
| 18 | protected final boolean parameter; | ||
| 19 | |||
| 20 | public LocalVariableEntry(MethodEntry parent, int index, String name, boolean parameter, String javadoc) { | ||
| 21 | super(parent, name, javadoc); | ||
| 22 | |||
| 23 | Preconditions.checkNotNull(parent, "Variable owner cannot be null"); | ||
| 24 | Preconditions.checkArgument(index >= 0, "Index must be positive"); | ||
| 25 | |||
| 26 | this.index = index; | ||
| 27 | this.parameter = parameter; | ||
| 28 | } | ||
| 29 | |||
| 30 | @Override | ||
| 31 | public Class<MethodEntry> getParentType() { | ||
| 32 | return MethodEntry.class; | ||
| 33 | } | ||
| 34 | |||
| 35 | public boolean isArgument() { | ||
| 36 | return this.parameter; | ||
| 37 | } | ||
| 38 | |||
| 39 | public int getIndex() { | ||
| 40 | return index; | ||
| 41 | } | ||
| 42 | |||
| 43 | @Override | ||
| 44 | public String getName() { | ||
| 45 | return this.name; | ||
| 46 | } | ||
| 47 | |||
| 48 | @Override | ||
| 49 | public LocalVariableEntry translate(Translator translator, @Nullable EntryMapping mapping) { | ||
| 50 | String translatedName = mapping != null ? mapping.getTargetName() : name; | ||
| 51 | String javadoc = mapping != null ? mapping.getJavadoc() : null; | ||
| 52 | return new LocalVariableEntry(parent, index, translatedName, parameter, javadoc); | ||
| 53 | } | ||
| 54 | |||
| 55 | @Override | ||
| 56 | public LocalVariableEntry withName(String name) { | ||
| 57 | return new LocalVariableEntry(parent, index, name, parameter, javadocs); | ||
| 58 | } | ||
| 59 | |||
| 60 | @Override | ||
| 61 | public LocalVariableEntry withParent(MethodEntry parent) { | ||
| 62 | return new LocalVariableEntry(parent, index, name, parameter, javadocs); | ||
| 63 | } | ||
| 64 | |||
| 65 | @Override | ||
| 66 | public int hashCode() { | ||
| 67 | return Utils.combineHashesOrdered(this.parent, this.index); | ||
| 68 | } | ||
| 69 | |||
| 70 | @Override | ||
| 71 | public boolean equals(Object other) { | ||
| 72 | return other instanceof LocalVariableEntry && equals((LocalVariableEntry) other); | ||
| 73 | } | ||
| 74 | |||
| 75 | public boolean equals(LocalVariableEntry other) { | ||
| 76 | return this.parent.equals(other.parent) && this.index == other.index; | ||
| 77 | } | ||
| 78 | |||
| 79 | @Override | ||
| 80 | public boolean canConflictWith(Entry<?> entry) { | ||
| 81 | return entry instanceof LocalVariableEntry && ((LocalVariableEntry) entry).parent.equals(parent); | ||
| 82 | } | ||
| 83 | |||
| 84 | @Override | ||
| 85 | public String toString() { | ||
| 86 | return this.parent + "(" + this.index + ":" + this.name + ")"; | ||
| 87 | } | ||
| 88 | |||
| 89 | @Override | ||
| 90 | public int compareTo(LocalVariableEntry entry) { | ||
| 91 | return Integer.compare(index, entry.index); | ||
| 92 | } | ||
| 93 | } | ||
diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/MethodDefEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/MethodDefEntry.java deleted file mode 100644 index 4e75a5c..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/MethodDefEntry.java +++ /dev/null | |||
| @@ -1,71 +0,0 @@ | |||
| 1 | /******************************************************************************* | ||
| 2 | * Copyright (c) 2015 Jeff Martin. | ||
| 3 | * All rights reserved. This program and the accompanying materials | ||
| 4 | * are made available under the terms of the GNU Lesser General Public | ||
| 5 | * License v3.0 which accompanies this distribution, and is available at | ||
| 6 | * http://www.gnu.org/licenses/lgpl.html | ||
| 7 | * <p> | ||
| 8 | * Contributors: | ||
| 9 | * Jeff Martin - initial API and implementation | ||
| 10 | ******************************************************************************/ | ||
| 11 | |||
| 12 | package cuchaz.enigma.translation.representation.entry; | ||
| 13 | |||
| 14 | import com.google.common.base.Preconditions; | ||
| 15 | import cuchaz.enigma.translation.Translator; | ||
| 16 | import cuchaz.enigma.translation.mapping.EntryMapping; | ||
| 17 | import cuchaz.enigma.translation.representation.AccessFlags; | ||
| 18 | import cuchaz.enigma.translation.representation.MethodDescriptor; | ||
| 19 | import cuchaz.enigma.translation.representation.Signature; | ||
| 20 | |||
| 21 | import javax.annotation.Nullable; | ||
| 22 | |||
| 23 | public class MethodDefEntry extends MethodEntry implements DefEntry<ClassEntry> { | ||
| 24 | private final AccessFlags access; | ||
| 25 | private final Signature signature; | ||
| 26 | |||
| 27 | public MethodDefEntry(ClassEntry owner, String name, MethodDescriptor descriptor, Signature signature, AccessFlags access) { | ||
| 28 | this(owner, name, descriptor, signature, access, null); | ||
| 29 | } | ||
| 30 | |||
| 31 | public MethodDefEntry(ClassEntry owner, String name, MethodDescriptor descriptor, Signature signature, AccessFlags access, String docs) { | ||
| 32 | super(owner, name, descriptor, docs); | ||
| 33 | Preconditions.checkNotNull(access, "Method access cannot be null"); | ||
| 34 | Preconditions.checkNotNull(signature, "Method signature cannot be null"); | ||
| 35 | this.access = access; | ||
| 36 | this.signature = signature; | ||
| 37 | } | ||
| 38 | |||
| 39 | public static MethodDefEntry parse(ClassEntry owner, int access, String name, String desc, String signature) { | ||
| 40 | return new MethodDefEntry(owner, name, new MethodDescriptor(desc), Signature.createSignature(signature), new AccessFlags(access), null); | ||
| 41 | } | ||
| 42 | |||
| 43 | @Override | ||
| 44 | public AccessFlags getAccess() { | ||
| 45 | return access; | ||
| 46 | } | ||
| 47 | |||
| 48 | public Signature getSignature() { | ||
| 49 | return signature; | ||
| 50 | } | ||
| 51 | |||
| 52 | @Override | ||
| 53 | public MethodDefEntry translate(Translator translator, @Nullable EntryMapping mapping) { | ||
| 54 | MethodDescriptor translatedDesc = translator.translate(descriptor); | ||
| 55 | Signature translatedSignature = translator.translate(signature); | ||
| 56 | String translatedName = mapping != null ? mapping.getTargetName() : name; | ||
| 57 | AccessFlags translatedAccess = mapping != null ? mapping.getAccessModifier().transform(access) : access; | ||
| 58 | String docs = mapping != null ? mapping.getJavadoc() : null; | ||
| 59 | return new MethodDefEntry(parent, translatedName, translatedDesc, translatedSignature, translatedAccess, docs); | ||
| 60 | } | ||
| 61 | |||
| 62 | @Override | ||
| 63 | public MethodDefEntry withName(String name) { | ||
| 64 | return new MethodDefEntry(parent, name, descriptor, signature, access, javadocs); | ||
| 65 | } | ||
| 66 | |||
| 67 | @Override | ||
| 68 | public MethodDefEntry withParent(ClassEntry parent) { | ||
| 69 | return new MethodDefEntry(new ClassEntry(parent.getFullName()), name, descriptor, signature, access, javadocs); | ||
| 70 | } | ||
| 71 | } | ||
diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/MethodEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/MethodEntry.java deleted file mode 100644 index e1ffad3..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/MethodEntry.java +++ /dev/null | |||
| @@ -1,105 +0,0 @@ | |||
| 1 | /******************************************************************************* | ||
| 2 | * Copyright (c) 2015 Jeff Martin. | ||
| 3 | * All rights reserved. This program and the accompanying materials | ||
| 4 | * are made available under the terms of the GNU Lesser General Public | ||
| 5 | * License v3.0 which accompanies this distribution, and is available at | ||
| 6 | * http://www.gnu.org/licenses/lgpl.html | ||
| 7 | * <p> | ||
| 8 | * Contributors: | ||
| 9 | * Jeff Martin - initial API and implementation | ||
| 10 | ******************************************************************************/ | ||
| 11 | |||
| 12 | package cuchaz.enigma.translation.representation.entry; | ||
| 13 | |||
| 14 | import com.google.common.base.Preconditions; | ||
| 15 | import cuchaz.enigma.translation.Translator; | ||
| 16 | import cuchaz.enigma.translation.mapping.EntryMapping; | ||
| 17 | import cuchaz.enigma.translation.representation.MethodDescriptor; | ||
| 18 | import cuchaz.enigma.utils.Utils; | ||
| 19 | |||
| 20 | import javax.annotation.Nullable; | ||
| 21 | |||
| 22 | public class MethodEntry extends ParentedEntry<ClassEntry> implements Comparable<MethodEntry> { | ||
| 23 | |||
| 24 | protected final MethodDescriptor descriptor; | ||
| 25 | |||
| 26 | public MethodEntry(ClassEntry parent, String name, MethodDescriptor descriptor) { | ||
| 27 | this(parent, name, descriptor, null); | ||
| 28 | } | ||
| 29 | |||
| 30 | public MethodEntry(ClassEntry parent, String name, MethodDescriptor descriptor, String javadocs) { | ||
| 31 | super(parent, name, javadocs); | ||
| 32 | |||
| 33 | Preconditions.checkNotNull(parent, "Parent cannot be null"); | ||
| 34 | Preconditions.checkNotNull(descriptor, "Method descriptor cannot be null"); | ||
| 35 | |||
| 36 | this.descriptor = descriptor; | ||
| 37 | } | ||
| 38 | |||
| 39 | public static MethodEntry parse(String owner, String name, String desc) { | ||
| 40 | return new MethodEntry(new ClassEntry(owner), name, new MethodDescriptor(desc), null); | ||
| 41 | } | ||
| 42 | |||
| 43 | @Override | ||
| 44 | public Class<ClassEntry> getParentType() { | ||
| 45 | return ClassEntry.class; | ||
| 46 | } | ||
| 47 | |||
| 48 | public MethodDescriptor getDesc() { | ||
| 49 | return this.descriptor; | ||
| 50 | } | ||
| 51 | |||
| 52 | public boolean isConstructor() { | ||
| 53 | return name.equals("<init>") || name.equals("<clinit>"); | ||
| 54 | } | ||
| 55 | |||
| 56 | @Override | ||
| 57 | public MethodEntry translate(Translator translator, @Nullable EntryMapping mapping) { | ||
| 58 | String translatedName = mapping != null ? mapping.getTargetName() : name; | ||
| 59 | String docs = mapping != null ? mapping.getJavadoc() : null; | ||
| 60 | return new MethodEntry(parent, translatedName, translator.translate(descriptor), docs); | ||
| 61 | } | ||
| 62 | |||
| 63 | @Override | ||
| 64 | public MethodEntry withName(String name) { | ||
| 65 | return new MethodEntry(parent, name, descriptor, javadocs); | ||
| 66 | } | ||
| 67 | |||
| 68 | @Override | ||
| 69 | public MethodEntry withParent(ClassEntry parent) { | ||
| 70 | return new MethodEntry(new ClassEntry(parent.getFullName()), name, descriptor, javadocs); | ||
| 71 | } | ||
| 72 | |||
| 73 | @Override | ||
| 74 | public int hashCode() { | ||
| 75 | return Utils.combineHashesOrdered(this.parent, this.name, this.descriptor); | ||
| 76 | } | ||
| 77 | |||
| 78 | @Override | ||
| 79 | public boolean equals(Object other) { | ||
| 80 | return other instanceof MethodEntry && equals((MethodEntry) other); | ||
| 81 | } | ||
| 82 | |||
| 83 | public boolean equals(MethodEntry other) { | ||
| 84 | return this.parent.equals(other.getParent()) && this.name.equals(other.getName()) && this.descriptor.equals(other.getDesc()); | ||
| 85 | } | ||
| 86 | |||
| 87 | @Override | ||
| 88 | public boolean canConflictWith(Entry<?> entry) { | ||
| 89 | if (entry instanceof MethodEntry) { | ||
| 90 | MethodEntry methodEntry = (MethodEntry) entry; | ||
| 91 | return methodEntry.parent.equals(parent) && methodEntry.descriptor.canConflictWith(descriptor); | ||
| 92 | } | ||
| 93 | return false; | ||
| 94 | } | ||
| 95 | |||
| 96 | @Override | ||
| 97 | public String toString() { | ||
| 98 | return this.parent.getFullName() + "." + this.name + this.descriptor; | ||
| 99 | } | ||
| 100 | |||
| 101 | @Override | ||
| 102 | public int compareTo(MethodEntry entry) { | ||
| 103 | return (name + descriptor.toString()).compareTo(entry.name + entry.descriptor.toString()); | ||
| 104 | } | ||
| 105 | } | ||
diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/ParentedEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/ParentedEntry.java deleted file mode 100644 index cbc5faf..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/ParentedEntry.java +++ /dev/null | |||
| @@ -1,82 +0,0 @@ | |||
| 1 | /******************************************************************************* | ||
| 2 | * Copyright (c) 2015 Jeff Martin. | ||
| 3 | * All rights reserved. This program and the accompanying materials | ||
| 4 | * are made available under the terms of the GNU Lesser General Public | ||
| 5 | * License v3.0 which accompanies this distribution, and is available at | ||
| 6 | * http://www.gnu.org/licenses/lgpl.html | ||
| 7 | * <p> | ||
| 8 | * Contributors: | ||
| 9 | * Jeff Martin - initial API and implementation | ||
| 10 | ******************************************************************************/ | ||
| 11 | |||
| 12 | package cuchaz.enigma.translation.representation.entry; | ||
| 13 | |||
| 14 | import com.google.common.base.Preconditions; | ||
| 15 | import cuchaz.enigma.translation.Translatable; | ||
| 16 | import cuchaz.enigma.translation.Translator; | ||
| 17 | import cuchaz.enigma.translation.mapping.EntryMap; | ||
| 18 | import cuchaz.enigma.translation.mapping.EntryMapping; | ||
| 19 | import cuchaz.enigma.translation.mapping.EntryResolver; | ||
| 20 | import cuchaz.enigma.translation.mapping.ResolutionStrategy; | ||
| 21 | |||
| 22 | import javax.annotation.Nullable; | ||
| 23 | |||
| 24 | public abstract class ParentedEntry<P extends Entry<?>> implements Entry<P> { | ||
| 25 | protected final P parent; | ||
| 26 | protected final String name; | ||
| 27 | protected final @Nullable String javadocs; | ||
| 28 | |||
| 29 | protected ParentedEntry(P parent, String name, String javadocs) { | ||
| 30 | this.parent = parent; | ||
| 31 | this.name = name; | ||
| 32 | this.javadocs = javadocs; | ||
| 33 | |||
| 34 | Preconditions.checkNotNull(name, "Name cannot be null"); | ||
| 35 | } | ||
| 36 | |||
| 37 | @Override | ||
| 38 | public abstract ParentedEntry<P> withParent(P parent); | ||
| 39 | |||
| 40 | @Override | ||
| 41 | public abstract ParentedEntry<P> withName(String name); | ||
| 42 | |||
| 43 | protected abstract ParentedEntry<P> translate(Translator translator, @Nullable EntryMapping mapping); | ||
| 44 | |||
| 45 | @Override | ||
| 46 | public String getName() { | ||
| 47 | return name; | ||
| 48 | } | ||
| 49 | |||
| 50 | @Override | ||
| 51 | @Nullable | ||
| 52 | public P getParent() { | ||
| 53 | return parent; | ||
| 54 | } | ||
| 55 | |||
| 56 | @Nullable | ||
| 57 | @Override | ||
| 58 | public String getJavadocs() { | ||
| 59 | return javadocs; | ||
| 60 | } | ||
| 61 | |||
| 62 | @Override | ||
| 63 | public ParentedEntry<P> translate(Translator translator, EntryResolver resolver, EntryMap<EntryMapping> mappings) { | ||
| 64 | P parent = getParent(); | ||
| 65 | EntryMapping mapping = resolveMapping(resolver, mappings); | ||
| 66 | if (parent == null) { | ||
| 67 | return translate(translator, mapping); | ||
| 68 | } | ||
| 69 | P translatedParent = translator.translate(parent); | ||
| 70 | return withParent(translatedParent).translate(translator, mapping); | ||
| 71 | } | ||
| 72 | |||
| 73 | private EntryMapping resolveMapping(EntryResolver resolver, EntryMap<EntryMapping> mappings) { | ||
| 74 | for (ParentedEntry<P> entry : resolver.resolveEntry(this, ResolutionStrategy.RESOLVE_ROOT)) { | ||
| 75 | EntryMapping mapping = mappings.get(entry); | ||
| 76 | if (mapping != null) { | ||
| 77 | return mapping; | ||
| 78 | } | ||
| 79 | } | ||
| 80 | return null; | ||
| 81 | } | ||
| 82 | } | ||