Skip to content
This repository was archived by the owner on Sep 9, 2020. It is now read-only.

Commit 5e748b4

Browse files
committed
Perform better matching for inner classes
1 parent 448c560 commit 5e748b4

File tree

3 files changed

+166
-13
lines changed

3 files changed

+166
-13
lines changed

src/main/java/org/spongepowered/obfuscation/ObfuscationMapper.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.spongepowered.obfuscation.merge.operation.MatchDiscreteFields;
4242
import org.spongepowered.obfuscation.merge.operation.MatchDiscreteMethods;
4343
import org.spongepowered.obfuscation.merge.operation.MatchEnums;
44+
import org.spongepowered.obfuscation.merge.operation.MatchInnerClasses;
4445
import org.spongepowered.obfuscation.merge.operation.MatchMethodGroups;
4546
import org.spongepowered.obfuscation.merge.operation.MatchReferences;
4647
import org.spongepowered.obfuscation.merge.operation.MatchStringConstants;
@@ -64,7 +65,6 @@
6465
import java.util.List;
6566
import java.util.Map;
6667
import java.util.function.Consumer;
67-
import java.util.regex.Pattern;
6868

6969
public class ObfuscationMapper {
7070

@@ -213,6 +213,7 @@ public static void main(String[] args) throws IOException {
213213
engine.addOperation(new MatchDiscreteFields());
214214
engine.addOperation(new MatchMethodGroups());
215215
engine.addOperation(new MatchDiscreteMethods());
216+
engine.addOperation(new MatchInnerClasses());
216217
engine.addOperation(new MergeMatchedTypes());
217218
engine.addOperation(new CustomMethodMergers());
218219
engine.addOperation(new MergeMatchedMethods());
@@ -295,9 +296,6 @@ public static void main(String[] args) throws IOException {
295296
continue;
296297
}
297298
String mapped = old_mappings.mapType(obf);
298-
if (Pattern.matches("\\$[0-9]+", mapped)) {
299-
continue;
300-
}
301299
String new_obf = new_mappings.inverseType(mapped);
302300
if (new_obf == null) {
303301
unmatched_types.add(mapped);

src/main/java/org/spongepowered/obfuscation/merge/operation/MatchEnums.java

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,13 @@ public class MatchEnums implements MergeOperation {
3333
@Override
3434
public void operate(MergeEngine set) {
3535
for (EnumEntry n : set.getNewSourceSet().getAllEnums()) {
36-
if (n.isAnonType() || n.getEnumConstants().isEmpty()) {
36+
if (n.isAnonType() || n.getEnumConstants().isEmpty() || n.getName().contains("$")) {
3737
continue;
3838
}
39-
boolean is_inner = n.getName().contains("$");
4039

4140
search: for (EnumEntry m : set.getOldSourceSet().getAllEnums()) {
42-
if (m.isAnonType() || m.getEnumConstants().isEmpty()) {
43-
continue;
44-
}
45-
if (n.getEnumConstants().size() < m.getEnumConstants().size()) {
46-
continue;
47-
}
48-
if (m.getName().contains("$") ^ is_inner) {
41+
if (m.isAnonType() || m.getEnumConstants().isEmpty() || n.getEnumConstants().size() < m.getEnumConstants().size()
42+
|| m.getName().contains("$")) {
4943
continue;
5044
}
5145
for (String cst : m.getEnumConstants()) {
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
/*
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) SpongePowered <https://www.spongepowered.org>
5+
* Copyright (c) contributors
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*/
25+
package org.spongepowered.obfuscation.merge.operation;
26+
27+
import com.google.common.collect.HashMultimap;
28+
import com.google.common.collect.Multimap;
29+
import org.spongepowered.despector.ast.type.EnumEntry;
30+
import org.spongepowered.despector.ast.type.TypeEntry;
31+
import org.spongepowered.obfuscation.merge.MergeEngine;
32+
import org.spongepowered.obfuscation.merge.MergeOperation;
33+
import org.spongepowered.obfuscation.merge.data.MatchEntry;
34+
35+
import java.util.ArrayList;
36+
import java.util.Collection;
37+
import java.util.List;
38+
39+
public class MatchInnerClasses implements MergeOperation {
40+
41+
private boolean prepared = false;
42+
43+
private final Multimap<TypeEntry, TypeEntry> old_inners = HashMultimap.create();
44+
private final Multimap<TypeEntry, TypeEntry> new_inners = HashMultimap.create();
45+
46+
private void prep(MergeEngine set) {
47+
for (TypeEntry type : set.getOldSourceSet().getAllClasses()) {
48+
if (!type.getName().contains("$")) {
49+
continue;
50+
}
51+
String parent_name = type.getName().substring(0, type.getName().lastIndexOf('$'));
52+
TypeEntry parent = set.getOldSourceSet().get(parent_name);
53+
if (parent == null) {
54+
throw new IllegalStateException(parent_name + " not found as parent type");
55+
}
56+
this.old_inners.put(parent, type);
57+
}
58+
for (TypeEntry type : set.getNewSourceSet().getAllClasses()) {
59+
if (!type.getName().contains("$")) {
60+
continue;
61+
}
62+
String parent_name = type.getName().substring(0, type.getName().lastIndexOf('$'));
63+
TypeEntry parent = set.getNewSourceSet().get(parent_name);
64+
if (parent == null) {
65+
throw new IllegalStateException(parent_name + " not found as parent type");
66+
}
67+
this.new_inners.put(parent, type);
68+
}
69+
}
70+
71+
@Override
72+
public void operate(MergeEngine set) {
73+
if (!this.prepared) {
74+
this.prepared = true;
75+
prep(set);
76+
}
77+
78+
for (TypeEntry type : set.getOldSourceSet().getAllClasses()) {
79+
MatchEntry match = set.getMatch(type);
80+
if (match == null) {
81+
continue;
82+
}
83+
TypeEntry new_parent = match.getNewType();
84+
Collection<TypeEntry> old_all_inners = this.old_inners.get(type);
85+
if (old_all_inners == null) {
86+
continue;
87+
}
88+
Collection<TypeEntry> new_all_inners = this.new_inners.get(new_parent);
89+
if (new_all_inners == null) {
90+
continue;
91+
}
92+
mergeDistinct(set, old_all_inners, new_all_inners);
93+
}
94+
95+
}
96+
97+
private void mergeDistinct(MergeEngine set, Collection<TypeEntry> old_inners, Collection<TypeEntry> new_inners) {
98+
List<TypeEntry> old_anon = new ArrayList<>();
99+
List<TypeEntry> new_anon = new ArrayList<>();
100+
List<TypeEntry> old_named = new ArrayList<>();
101+
List<TypeEntry> new_named = new ArrayList<>();
102+
103+
for (TypeEntry type : old_inners) {
104+
if (type.isAnonType()) {
105+
old_anon.add(type);
106+
} else {
107+
old_named.add(type);
108+
}
109+
}
110+
111+
for (TypeEntry type : new_inners) {
112+
if (type.isAnonType()) {
113+
new_anon.add(type);
114+
} else {
115+
new_named.add(type);
116+
}
117+
}
118+
119+
if (old_anon.size() == 1 && new_anon.size() == 1) {
120+
set.vote(old_anon.get(0), new_anon.get(0));
121+
} else {
122+
}
123+
124+
if (old_named.size() == 1 && new_named.size() == 1) {
125+
set.vote(old_named.get(0), new_named.get(0));
126+
} else {
127+
for (TypeEntry type : old_named) {
128+
if (set.isTypeMatched(type)) {
129+
continue;
130+
}
131+
if (type instanceof EnumEntry) {
132+
TypeEntry possible = null;
133+
int matches = 0;
134+
135+
for (TypeEntry pos : new_named) {
136+
if (!(pos instanceof EnumEntry)) {
137+
continue;
138+
}
139+
EnumEntry pos_enum = (EnumEntry) pos;
140+
int m = 0;
141+
for (String cst : ((EnumEntry) type).getEnumConstants()) {
142+
if (pos_enum.getEnumConstants().contains(cst)) {
143+
m++;
144+
}
145+
}
146+
if (m > matches) {
147+
possible = pos;
148+
} else if (m == matches) {
149+
possible = null;
150+
}
151+
}
152+
if (possible != null) {
153+
set.vote(type, possible);
154+
}
155+
continue;
156+
}
157+
}
158+
}
159+
}
160+
161+
}

0 commit comments

Comments
 (0)