summaryrefslogtreecommitdiff
path: root/src/main/java/cuchaz/enigma/analysis/EntryRenamer.java
blob: b0bcc91e4ba62dcdddf83195155ee6dfaf596659 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*******************************************************************************
 * Copyright (c) 2015 Jeff Martin.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public
 * License v3.0 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl.html
 * <p>
 * Contributors:
 * Jeff Martin - initial API and implementation
 ******************************************************************************/

package cuchaz.enigma.analysis;

import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import cuchaz.enigma.mapping.*;

import java.util.AbstractMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class EntryRenamer {

	public static <T> void renameClassesInSet(Map<String, String> renames, Set<T> set) {
		List<T> entries = Lists.newArrayList();
		for (T val : set) {
			entries.add(renameClassesInThing(renames, val));
		}
		set.clear();
		set.addAll(entries);
	}

	public static <Key, Val> void renameClassesInMap(Map<String, String> renames, Map<Key, Val> map) {
		// for each key/value pair...
		Set<Map.Entry<Key, Val>> entriesToAdd = Sets.newHashSet();
		for (Map.Entry<Key, Val> entry : map.entrySet()) {
			entriesToAdd.add(new AbstractMap.SimpleEntry<>(renameClassesInThing(renames, entry.getKey()), renameClassesInThing(renames, entry.getValue())));
		}
		map.clear();
		for (Map.Entry<Key, Val> entry : entriesToAdd) {
			map.put(entry.getKey(), entry.getValue());
		}
	}

	public static <Key, Val> void renameClassesInMultimap(Map<String, String> renames, Multimap<Key, Val> map) {
		// for each key/value pair...
		Set<Map.Entry<Key, Val>> entriesToAdd = Sets.newHashSet();
		for (Map.Entry<Key, Val> entry : map.entries()) {
			entriesToAdd.add(new AbstractMap.SimpleEntry<>(renameClassesInThing(renames, entry.getKey()), renameClassesInThing(renames, entry.getValue())));
		}
		map.clear();
		for (Map.Entry<Key, Val> entry : entriesToAdd) {
			map.put(entry.getKey(), entry.getValue());
		}
	}

	public static <Key, Val> void renameMethodsInMultimap(Map<MethodEntry, MethodEntry> renames, Multimap<Key, Val> map) {
		// for each key/value pair...
		Set<Map.Entry<Key, Val>> entriesToAdd = Sets.newHashSet();
		for (Map.Entry<Key, Val> entry : map.entries()) {
			entriesToAdd.add(new AbstractMap.SimpleEntry<>(renameMethodsInThing(renames, entry.getKey()), renameMethodsInThing(renames, entry.getValue())));
		}
		map.clear();
		for (Map.Entry<Key, Val> entry : entriesToAdd) {
			map.put(entry.getKey(), entry.getValue());
		}
	}

	public static <Key, Val> void renameMethodsInMap(Map<MethodEntry, MethodEntry> renames, Map<Key, Val> map) {
		// for each key/value pair...
		Set<Map.Entry<Key, Val>> entriesToAdd = Sets.newHashSet();
		for (Map.Entry<Key, Val> entry : map.entrySet()) {
			entriesToAdd.add(new AbstractMap.SimpleEntry<>(renameMethodsInThing(renames, entry.getKey()), renameMethodsInThing(renames, entry.getValue())));
		}
		map.clear();
		for (Map.Entry<Key, Val> entry : entriesToAdd) {
			map.put(entry.getKey(), entry.getValue());
		}
	}

	@SuppressWarnings("unchecked")
	public static <T> T renameMethodsInThing(Map<MethodEntry, MethodEntry> renames, T thing) {
		if (thing instanceof MethodEntry) {
			MethodEntry methodEntry = (MethodEntry) thing;
			MethodEntry newMethodEntry = renames.get(methodEntry);
			if (newMethodEntry != null) {
				return (T) new MethodEntry(
						methodEntry.getOwnerClassEntry(),
						newMethodEntry.getName(),
						methodEntry.getDesc()
				);
			}
			return thing;
		} else if (thing instanceof LocalVariableEntry) {
			LocalVariableEntry variableEntry = (LocalVariableEntry) thing;
			return (T) new LocalVariableEntry(
					renameMethodsInThing(renames, variableEntry.getOwnerEntry()),
					variableEntry.getIndex(),
					variableEntry.getName()
			);
		} else if (thing instanceof EntryReference) {
			EntryReference<Entry, Entry> reference = (EntryReference<Entry, Entry>) thing;
			reference.entry = renameMethodsInThing(renames, reference.entry);
			reference.context = renameMethodsInThing(renames, reference.context);
			return thing;
		}
		return thing;
	}

	@SuppressWarnings("unchecked")
	public static <T> T renameClassesInThing(final Map<String, String> renames, T thing) {
		if (thing instanceof String) {
			String stringEntry = (String) thing;
			if (renames.containsKey(stringEntry)) {
				return (T) renames.get(stringEntry);
			}
		} else if (thing instanceof ClassEntry) {
			ClassEntry classEntry = (ClassEntry) thing;
			return (T) new ClassEntry(renameClassesInThing(renames, classEntry.getClassName()));
		} else if (thing instanceof FieldDefEntry) {
			FieldDefEntry fieldEntry = (FieldDefEntry) thing;
			return (T) new FieldDefEntry(renameClassesInThing(renames, fieldEntry.getOwnerClassEntry()), fieldEntry.getName(), renameClassesInThing(renames, fieldEntry.getDesc()), fieldEntry.getAccess());
		} else if (thing instanceof MethodDefEntry) {
			MethodDefEntry methodEntry = (MethodDefEntry) thing;
			return (T) new MethodDefEntry(renameClassesInThing(renames, methodEntry.getOwnerClassEntry()), methodEntry.getName(), renameClassesInThing(renames, methodEntry.getDesc()), methodEntry.getAccess());
		} else if (thing instanceof LocalVariableEntry) {
			LocalVariableEntry argumentEntry = (LocalVariableEntry) thing;
			return (T) new LocalVariableEntry(renameClassesInThing(renames, argumentEntry.getOwnerEntry()), argumentEntry.getIndex(), argumentEntry.getName());
		} else if (thing instanceof EntryReference) {
			EntryReference<Entry, Entry> reference = (EntryReference<Entry, Entry>) thing;
			reference.entry = renameClassesInThing(renames, reference.entry);
			reference.context = renameClassesInThing(renames, reference.context);
			return thing;
		} else if (thing instanceof MethodDescriptor) {
			return (T) ((MethodDescriptor) thing).remap(className -> renameClassesInThing(renames, className));
		} else if (thing instanceof TypeDescriptor) {
			return (T) ((TypeDescriptor) thing).remap(className -> renameClassesInThing(renames, className));
		}

		return thing;
	}
}