blob: 2f19681cf7de01a570ff1e543dd15c1a1bb9ed3f [file] [log] [blame]
// Copyright (c) 2020, 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.tracereferences;
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.references.MethodReference;
import com.android.tools.r8.references.PackageReference;
import com.android.tools.r8.references.TypeReference;
import com.android.tools.r8.tracereferences.TraceReferencesConsumer.TracedClass;
import com.android.tools.r8.tracereferences.TraceReferencesConsumer.TracedField;
import com.android.tools.r8.tracereferences.TraceReferencesConsumer.TracedMethod;
import com.android.tools.r8.tracereferences.internal.TraceReferencesResult;
import com.android.tools.r8.utils.ListUtils;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.StringUtils.BraceType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
abstract class Formatter {
private final StringBuilder output;
Formatter() {
output = new StringBuilder();
}
String get() {
return output.toString();
}
protected void append(String string) {
output.append(string);
}
protected void appendLine(String string) {
output.append(StringUtils.lines(string));
}
protected void printArguments(MethodReference method) {
StringUtils.append(
output,
ListUtils.map(method.getFormalTypes(), TypeReference::getTypeName),
",",
BraceType.PARENS);
}
protected abstract void printConstructorName(MethodReference method);
protected abstract void printField(TracedField field);
protected abstract void printMethod(TracedMethod method);
protected abstract void printPackageNames(List<String> packageNames);
protected void printReturn(MethodReference method) {
append(method.getReturnType() != null ? method.getReturnType().getTypeName() : "void");
}
protected void printNameAndReturn(MethodReference method) {
if (method.getMethodName().equals("<init>")) {
printConstructorName(method);
} else {
printReturn(method);
append(" ");
append(method.getMethodName());
}
}
protected abstract void printTypeHeader(TracedClass clazz);
protected abstract void printTypeFooter();
void format(TraceReferencesResult result) {
print(
result.getTracedClasses(),
result.getTracedPackageNames(),
result.getTracedFields(),
result.getTracedMethods());
}
private void print(
Set<TracedClass> types,
Set<PackageReference> keepPackageNames,
Map<ClassReference, Set<TracedField>> fields,
Map<ClassReference, Set<TracedMethod>> methods) {
List<TracedClass> sortedTypes = new ArrayList<>(types);
sortedTypes.sort(Comparator.comparing(tracedClass -> tracedClass.getReference().getTypeName()));
for (TracedClass type : sortedTypes) {
Set<TracedMethod> methodsForClass =
methods.getOrDefault(type.getReference(), Collections.emptySet());
Set<TracedField> fieldsForClass =
fields.getOrDefault(type.getReference(), Collections.emptySet());
if (type.isMissingDefinition()) {
continue;
}
printTypeHeader(type);
List<TracedMethod> sortedMethods = new ArrayList<>(methodsForClass.size());
for (TracedMethod method : methodsForClass) {
if (method.isMissingDefinition()) {
continue;
}
assert method.getAccessFlags() != null;
sortedMethods.add(method);
}
sortedMethods.sort(
Comparator.comparing(tracedMethod -> tracedMethod.getReference().toString()));
for (TracedMethod method : sortedMethods) {
printMethod(method);
}
List<TracedField> sortedFields = new ArrayList<>(fieldsForClass);
sortedFields.sort(Comparator.comparing(tracedField -> tracedField.getReference().toString()));
for (TracedField field : sortedFields) {
if (field.isMissingDefinition()) {
continue;
}
printField(field);
}
printTypeFooter();
}
List<String> packageNamesToKeep =
keepPackageNames.stream()
.map(PackageReference::getPackageName)
.sorted()
.collect(Collectors.toList());
printPackageNames(packageNamesToKeep);
}
}