summaryrefslogtreecommitdiff
path: root/src/main/java/cuchaz/enigma/translation/representation/Lambda.java
blob: 63eb5630a61744090cc97c772630e8cbfef5aeb2 (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
package cuchaz.enigma.translation.representation;

import cuchaz.enigma.translation.Translatable;
import cuchaz.enigma.translation.Translator;
import cuchaz.enigma.translation.mapping.EntryMap;
import cuchaz.enigma.translation.mapping.EntryMapping;
import cuchaz.enigma.translation.mapping.EntryResolver;
import cuchaz.enigma.translation.mapping.ResolutionStrategy;
import cuchaz.enigma.translation.representation.entry.ClassEntry;
import cuchaz.enigma.translation.representation.entry.MethodEntry;
import cuchaz.enigma.translation.representation.entry.ParentedEntry;

import java.util.Objects;

public class Lambda implements Translatable {
	private final String invokedName;
	private final MethodDescriptor invokedType;
	private final MethodDescriptor samMethodType;
	private final ParentedEntry<?> implMethod;
	private final MethodDescriptor instantiatedMethodType;

	public Lambda(String invokedName, MethodDescriptor invokedType, MethodDescriptor samMethodType, ParentedEntry<?> implMethod, MethodDescriptor instantiatedMethodType) {
		this.invokedName = invokedName;
		this.invokedType = invokedType;
		this.samMethodType = samMethodType;
		this.implMethod = implMethod;
		this.instantiatedMethodType = instantiatedMethodType;
	}

	@Override
	public Lambda translate(Translator translator, EntryResolver resolver, EntryMap<EntryMapping> mappings) {
		MethodEntry samMethod = new MethodEntry(getInterface(), invokedName, samMethodType);
		EntryMapping samMethodMapping = resolveMapping(resolver, mappings, samMethod);

		return new Lambda(
			samMethodMapping != null ? samMethodMapping.getTargetName() : invokedName,
			invokedType.translate(translator, resolver, mappings),
			samMethodType.translate(translator, resolver, mappings),
			implMethod.translate(translator, resolver, mappings),
			instantiatedMethodType.translate(translator, resolver, mappings)
		);
	}

	private EntryMapping resolveMapping(EntryResolver resolver, EntryMap<EntryMapping> mappings, MethodEntry methodEntry) {
		for (MethodEntry entry : resolver.resolveEntry(methodEntry, ResolutionStrategy.RESOLVE_ROOT)) {
			EntryMapping mapping = mappings.get(entry);
			if (mapping != null) {
				return mapping;
			}
		}
		return null;
	}

	public ClassEntry getInterface() {
		return invokedType.getReturnDesc().getTypeEntry();
	}

	public String getInvokedName() {
		return invokedName;
	}

	public MethodDescriptor getInvokedType() {
		return invokedType;
	}

	public MethodDescriptor getSamMethodType() {
		return samMethodType;
	}

	public ParentedEntry<?> getImplMethod() {
		return implMethod;
	}

	public MethodDescriptor getInstantiatedMethodType() {
		return instantiatedMethodType;
	}

	@Override
	public boolean equals(Object o) {
		if (this == o) return true;
		if (o == null || getClass() != o.getClass()) return false;
		Lambda lambda = (Lambda) o;
		return Objects.equals(invokedName, lambda.invokedName) &&
			Objects.equals(invokedType, lambda.invokedType) &&
			Objects.equals(samMethodType, lambda.samMethodType) &&
			Objects.equals(implMethod, lambda.implMethod) &&
			Objects.equals(instantiatedMethodType, lambda.instantiatedMethodType);
	}

	@Override
	public int hashCode() {
		return Objects.hash(invokedName, invokedType, samMethodType, implMethod, instantiatedMethodType);
	}

	@Override
	public String toString() {
		return "Lambda{" +
			"invokedName='" + invokedName + '\'' +
			", invokedType=" + invokedType +
			", samMethodType=" + samMethodType +
			", implMethod=" + implMethod +
			", instantiatedMethodType=" + instantiatedMethodType +
			'}';
	}
}