summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Julian Burner2023-04-28 13:14:32 +0200
committerGravatar GitHub2023-04-28 12:14:32 +0100
commitb73d303f3aca9610d3bad866518f21cc813a2c87 (patch)
tree45f97f9bc6934d647b339f836f71cd865e8a1d8e
parentBump version (diff)
downloadenigma-b73d303f3aca9610d3bad866518f21cc813a2c87.tar.gz
enigma-b73d303f3aca9610d3bad866518f21cc813a2c87.tar.xz
enigma-b73d303f3aca9610d3bad866518f21cc813a2c87.zip
Allow shadowing fields (#475)
* Fix Enigma not allowing to shadow static fields * Fix mapping uniqueness verification * Allow shadowing any field * Fix a message Co-authored-by: ByMartrixx <bymartrixx@gmail.com>
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/mapping/MappingValidator.java47
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/representation/entry/ClassEntry.java5
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/representation/entry/Entry.java2
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/representation/entry/FieldEntry.java7
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableEntry.java5
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/representation/entry/MethodEntry.java5
-rw-r--r--enigma/src/main/java/cuchaz/enigma/utils/validation/Message.java2
-rw-r--r--enigma/src/main/resources/lang/en_us.json2
8 files changed, 72 insertions, 3 deletions
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/MappingValidator.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/MappingValidator.java
index 5f42373c..f6c0a6b8 100644
--- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/MappingValidator.java
+++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/MappingValidator.java
@@ -4,10 +4,13 @@ import java.util.Collection;
4import java.util.HashSet; 4import java.util.HashSet;
5import java.util.List; 5import java.util.List;
6 6
7import javax.annotation.Nullable;
8
7import cuchaz.enigma.analysis.index.InheritanceIndex; 9import cuchaz.enigma.analysis.index.InheritanceIndex;
8import cuchaz.enigma.analysis.index.JarIndex; 10import cuchaz.enigma.analysis.index.JarIndex;
9import cuchaz.enigma.translation.Translator; 11import cuchaz.enigma.translation.Translator;
10import cuchaz.enigma.translation.mapping.tree.EntryTree; 12import cuchaz.enigma.translation.mapping.tree.EntryTree;
13import cuchaz.enigma.translation.representation.AccessFlags;
11import cuchaz.enigma.translation.representation.entry.ClassEntry; 14import cuchaz.enigma.translation.representation.entry.ClassEntry;
12import cuchaz.enigma.translation.representation.entry.Entry; 15import cuchaz.enigma.translation.representation.entry.Entry;
13import cuchaz.enigma.utils.validation.Message; 16import cuchaz.enigma.utils.validation.Message;
@@ -41,12 +44,20 @@ public class MappingValidator {
41 Collection<ClassEntry> relatedClasses = getRelatedClasses(containingClass); 44 Collection<ClassEntry> relatedClasses = getRelatedClasses(containingClass);
42 45
43 boolean error = false; 46 boolean error = false;
47 Entry<?> shadowedEntry;
44 48
45 for (ClassEntry relatedClass : relatedClasses) { 49 for (ClassEntry relatedClass : relatedClasses) {
50 if (isStatic(entry) && relatedClass != containingClass) {
51 // static entries can only conflict with entries in the same class
52 continue;
53 }
54
46 Entry<?> relatedEntry = entry.replaceAncestor(containingClass, relatedClass); 55 Entry<?> relatedEntry = entry.replaceAncestor(containingClass, relatedClass);
47 Entry<?> translatedEntry = deobfuscator.translate(relatedEntry); 56 Entry<?> translatedEntry = deobfuscator.translate(relatedEntry);
48 57
49 List<? extends Entry<?>> translatedSiblings = obfToDeobf.getSiblings(relatedEntry).stream().map(deobfuscator::translate).toList(); 58 List<? extends Entry<?>> translatedSiblings = obfToDeobf.getSiblings(relatedEntry).stream()
59 .map(deobfuscator::translate)
60 .toList();
50 61
51 if (!isUnique(translatedEntry, translatedSiblings, name)) { 62 if (!isUnique(translatedEntry, translatedSiblings, name)) {
52 Entry<?> parent = translatedEntry.getParent(); 63 Entry<?> parent = translatedEntry.getParent();
@@ -58,6 +69,14 @@ public class MappingValidator {
58 } 69 }
59 70
60 error = true; 71 error = true;
72 } else if ((shadowedEntry = getShadowedEntry(translatedEntry, translatedSiblings, name)) != null) {
73 Entry<?> parent = shadowedEntry.getParent();
74
75 if (parent != null) {
76 vc.raise(Message.SHADOWED_NAME_CLASS, name, parent);
77 } else {
78 vc.raise(Message.SHADOWED_NAME, name);
79 }
61 } 80 }
62 } 81 }
63 82
@@ -77,11 +96,35 @@ public class MappingValidator {
77 96
78 private boolean isUnique(Entry<?> entry, List<? extends Entry<?>> siblings, String name) { 97 private boolean isUnique(Entry<?> entry, List<? extends Entry<?>> siblings, String name) {
79 for (Entry<?> sibling : siblings) { 98 for (Entry<?> sibling : siblings) {
80 if (entry.canConflictWith(sibling) && sibling.getName().equals(name)) { 99 if (canConflict(entry, sibling) && sibling.getName().equals(name)) {
81 return false; 100 return false;
82 } 101 }
83 } 102 }
84 103
85 return true; 104 return true;
86 } 105 }
106
107 private boolean canConflict(Entry<?> entry, Entry<?> sibling) {
108 return entry.canConflictWith(sibling);
109 }
110
111 @Nullable
112 private Entry<?> getShadowedEntry(Entry<?> entry, List<? extends Entry<?>> siblings, String name) {
113 for (Entry<?> sibling : siblings) {
114 if (canShadow(entry, sibling) && sibling.getName().equals(name)) {
115 return sibling;
116 }
117 }
118
119 return null;
120 }
121
122 private boolean canShadow(Entry<?> entry, Entry<?> sibling) {
123 return entry.canShadow(sibling);
124 }
125
126 private boolean isStatic(Entry<?> entry) {
127 AccessFlags accessFlags = index.getEntryIndex().getEntryAccess(entry);
128 return accessFlags != null && accessFlags.isStatic();
129 }
87} 130}
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/ClassEntry.java b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/ClassEntry.java
index be5f0b38..8659b402 100644
--- a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/ClassEntry.java
+++ b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/ClassEntry.java
@@ -122,6 +122,11 @@ public class ClassEntry extends ParentedEntry<ClassEntry> implements Comparable<
122 } 122 }
123 123
124 @Override 124 @Override
125 public boolean canShadow(Entry<?> entry) {
126 return false;
127 }
128
129 @Override
125 public void validateName(ValidationContext vc, String name) { 130 public void validateName(ValidationContext vc, String name) {
126 IdentifierValidation.validateClassName(vc, name, this.isInnerClass()); 131 IdentifierValidation.validateClassName(vc, name, this.isInnerClass());
127 } 132 }
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/Entry.java b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/Entry.java
index 9615ca8e..71425e0f 100644
--- a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/Entry.java
+++ b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/Entry.java
@@ -108,6 +108,8 @@ public interface Entry<P extends Entry<?>> extends Translatable {
108 108
109 boolean canConflictWith(Entry<?> entry); 109 boolean canConflictWith(Entry<?> entry);
110 110
111 boolean canShadow(Entry<?> entry);
112
111 default ClassEntry getContainingClass() { 113 default ClassEntry getContainingClass() {
112 ClassEntry last = null; 114 ClassEntry last = null;
113 Entry<?> current = this; 115 Entry<?> current = this;
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/FieldEntry.java b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/FieldEntry.java
index c1592a43..b4ad1bac 100644
--- a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/FieldEntry.java
+++ b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/FieldEntry.java
@@ -85,7 +85,12 @@ public class FieldEntry extends ParentedEntry<ClassEntry> implements Comparable<
85 85
86 @Override 86 @Override
87 public boolean canConflictWith(Entry<?> entry) { 87 public boolean canConflictWith(Entry<?> entry) {
88 return entry instanceof FieldEntry && ((FieldEntry) entry).parent.equals(parent); 88 return false;
89 }
90
91 @Override
92 public boolean canShadow(Entry<?> entry) {
93 return entry instanceof FieldEntry;
89 } 94 }
90 95
91 @Override 96 @Override
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableEntry.java b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableEntry.java
index d22188b2..9d0bbedd 100644
--- a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableEntry.java
+++ b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableEntry.java
@@ -85,6 +85,11 @@ public class LocalVariableEntry extends ParentedEntry<MethodEntry> implements Co
85 } 85 }
86 86
87 @Override 87 @Override
88 public boolean canShadow(Entry<?> entry) {
89 return false;
90 }
91
92 @Override
88 public String toString() { 93 public String toString() {
89 return this.parent + "(" + this.index + ":" + this.name + ")"; 94 return this.parent + "(" + this.index + ":" + this.name + ")";
90 } 95 }
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/MethodEntry.java b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/MethodEntry.java
index 6fc3f0a0..5ccb9081 100644
--- a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/MethodEntry.java
+++ b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/MethodEntry.java
@@ -98,6 +98,11 @@ public class MethodEntry extends ParentedEntry<ClassEntry> implements Comparable
98 } 98 }
99 99
100 @Override 100 @Override
101 public boolean canShadow(Entry<?> entry) {
102 return entry instanceof MethodEntry;
103 }
104
105 @Override
101 public String toString() { 106 public String toString() {
102 return this.getFullName() + this.descriptor; 107 return this.getFullName() + this.descriptor;
103 } 108 }
diff --git a/enigma/src/main/java/cuchaz/enigma/utils/validation/Message.java b/enigma/src/main/java/cuchaz/enigma/utils/validation/Message.java
index b7e67f2b..9dbbb187 100644
--- a/enigma/src/main/java/cuchaz/enigma/utils/validation/Message.java
+++ b/enigma/src/main/java/cuchaz/enigma/utils/validation/Message.java
@@ -17,6 +17,8 @@ public class Message {
17 public static final Message UNKNOWN_RECORD_GETTER = create(Type.ERROR, "unknown_record_getter"); 17 public static final Message UNKNOWN_RECORD_GETTER = create(Type.ERROR, "unknown_record_getter");
18 18
19 public static final Message STYLE_VIOLATION = create(Type.WARNING, "style_violation"); 19 public static final Message STYLE_VIOLATION = create(Type.WARNING, "style_violation");
20 public static final Message SHADOWED_NAME_CLASS = create(Type.WARNING, "shadowed_name_class");
21 public static final Message SHADOWED_NAME = create(Type.WARNING, "shadowed_name");
20 22
21 public final Type type; 23 public final Type type;
22 public final String textKey; 24 public final String textKey;
diff --git a/enigma/src/main/resources/lang/en_us.json b/enigma/src/main/resources/lang/en_us.json
index 82f2d371..3919b9e2 100644
--- a/enigma/src/main/resources/lang/en_us.json
+++ b/enigma/src/main/resources/lang/en_us.json
@@ -217,6 +217,8 @@
217 "validation.message.illegal_doc_comment_end": "Javadoc comment cannot contain the character sequence '*/'.", 217 "validation.message.illegal_doc_comment_end": "Javadoc comment cannot contain the character sequence '*/'.",
218 "validation.message.reserved_identifier": "'%s' is a reserved identifier.", 218 "validation.message.reserved_identifier": "'%s' is a reserved identifier.",
219 "validation.message.unknown_record_getter": "Could not find a matching record component getter for %s", 219 "validation.message.unknown_record_getter": "Could not find a matching record component getter for %s",
220 "validation.message.shadowed_name_class": "Name '%s' shadows another in '%s'.",
221 "validation.message.shadowed_name": "Name '%s' shadows another entry.",
220 222
221 "crash.title": "%s - Crash Report", 223 "crash.title": "%s - Crash Report",
222 "crash.summary": "%s has crashed! =(", 224 "crash.summary": "%s has crashed! =(",