blob: 25505fe1eb7fcdd22d2ca75fe325a974b6290035 [file] [log] [blame]
// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.retrace;
import com.android.tools.r8.Keep;
import com.android.tools.r8.naming.ClassNamingForNameMapper;
import com.android.tools.r8.naming.ClassNamingForNameMapper.MappedRangesOfName;
import com.android.tools.r8.naming.MemberNaming;
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.retrace.RetraceClassResult.Element;
import com.android.tools.r8.utils.Box;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.stream.Stream;
@Keep
public class RetraceClassResult extends Result<Element, RetraceClassResult> {
private final ClassReference obfuscatedReference;
private final ClassNamingForNameMapper mapper;
private RetraceClassResult(ClassReference obfuscatedReference, ClassNamingForNameMapper mapper) {
this.obfuscatedReference = obfuscatedReference;
this.mapper = mapper;
}
static RetraceClassResult create(
ClassReference obfuscatedReference, ClassNamingForNameMapper mapper) {
return new RetraceClassResult(obfuscatedReference, mapper);
}
public RetraceFieldResult lookupField(String fieldName) {
return lookup(
fieldName,
(mapper, name) -> {
List<MemberNaming> memberNamings = mapper.mappedNamingsByName.get(name);
if (memberNamings == null || memberNamings.isEmpty()) {
return null;
}
return memberNamings;
},
RetraceFieldResult::new);
}
public RetraceMethodResult lookupMethod(String methodName) {
return lookup(
methodName,
(mapper, name) -> {
MappedRangesOfName mappedRanges = mapper.mappedRangesByRenamedName.get(name);
if (mappedRanges == null || mappedRanges.getMappedRanges().isEmpty()) {
return null;
}
return mappedRanges;
},
RetraceMethodResult::new);
}
private <T, R> R lookup(
String name,
BiFunction<ClassNamingForNameMapper, String, T> lookupFunction,
ResultConstructor<T, R> constructor) {
Box<R> elementBox = new Box<>();
forEach(
element -> {
assert !elementBox.isSet();
T mappedRangesForT = null;
if (element.mapper != null) {
mappedRangesForT = lookupFunction.apply(element.mapper, name);
}
elementBox.set(constructor.create(element, mappedRangesForT, name));
});
return elementBox.get();
}
private boolean hasRetraceResult() {
return mapper != null;
}
@Override
public Stream<Element> stream() {
return Stream.of(
new Element(
this,
mapper == null ? obfuscatedReference : Reference.classFromTypeName(mapper.originalName),
mapper));
}
@Override
public RetraceClassResult forEach(Consumer<Element> resultConsumer) {
stream().forEach(resultConsumer);
return this;
}
private interface ResultConstructor<T, R> {
R create(Element element, T mappings, String obfuscatedName);
}
public static class Element {
private final RetraceClassResult classResult;
private final ClassReference classReference;
private final ClassNamingForNameMapper mapper;
public Element(
RetraceClassResult classResult,
ClassReference classReference,
ClassNamingForNameMapper mapper) {
this.classResult = classResult;
this.classReference = classReference;
this.mapper = mapper;
}
public ClassReference getClassReference() {
return classReference;
}
public RetraceClassResult getRetraceClassResult() {
return classResult;
}
public String retraceSourceFile(String fileName, RetraceBase retraceBase) {
return retraceBase.retraceSourceFile(
classResult.obfuscatedReference, fileName, classReference, mapper != null);
}
public RetraceFieldResult lookupField(String fieldName) {
return lookup(
fieldName,
(mapper, name) -> {
List<MemberNaming> memberNamings = mapper.mappedNamingsByName.get(name);
if (memberNamings == null || memberNamings.isEmpty()) {
return null;
}
return memberNamings;
},
RetraceFieldResult::new);
}
public RetraceMethodResult lookupMethod(String methodName) {
return lookup(
methodName,
(mapper, name) -> {
MappedRangesOfName mappedRanges = mapper.mappedRangesByRenamedName.get(name);
if (mappedRanges == null || mappedRanges.getMappedRanges().isEmpty()) {
return null;
}
return mappedRanges;
},
RetraceMethodResult::new);
}
private <T, R> R lookup(
String name,
BiFunction<ClassNamingForNameMapper, String, T> lookupFunction,
ResultConstructor<T, R> constructor) {
return constructor.create(
this, mapper != null ? lookupFunction.apply(mapper, name) : null, name);
}
}
}