blob: 4c04b52f202cb5c6c3605136d4799df847727d09 [file] [log] [blame]
// Copyright (c) 2017, 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.shaking;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.utils.StringUtils;
import java.util.function.Consumer;
class UsagePrinter {
private static final String INDENT = " ";
static final UsagePrinter DONT_PRINT = new NoOpUsagePrinter();
private final Consumer<String> consumer;
private DexProgramClass enclosingClazz = null;
private boolean clazzPrefixPrinted = false;
UsagePrinter(Consumer<String> consumer) {
this.consumer = consumer;
}
void append(String string) {
consumer.accept(string);
}
void printUnusedClass(DexProgramClass clazz) {
append(clazz.toSourceString());
append(StringUtils.LINE_SEPARATOR);
}
// Visiting methods and fields of the given clazz.
void visiting(DexProgramClass clazz) {
assert enclosingClazz == null;
enclosingClazz = clazz;
}
// Visited methods and fields of the top at the clazz stack.
void visited() {
enclosingClazz = null;
clazzPrefixPrinted = false;
}
private void printClazzPrefixIfNecessary() {
assert enclosingClazz != null;
if (!clazzPrefixPrinted) {
append(enclosingClazz.toSourceString());
append(":");
append(StringUtils.LINE_SEPARATOR);
clazzPrefixPrinted = true;
}
}
void printUnusedMethod(DexEncodedMethod method) {
printClazzPrefixIfNecessary();
append(INDENT);
String accessFlags = method.accessFlags.toString();
if (!accessFlags.isEmpty()) {
append(accessFlags);
append(" ");
}
append(method.method.proto.returnType.toSourceString());
append(" ");
append(method.method.name.toSourceString());
append("(");
for (int i = 0; i < method.method.proto.parameters.values.length; i++) {
if (i != 0) {
append(",");
}
append(method.method.proto.parameters.values[i].toSourceString());
}
append(")");
append(StringUtils.LINE_SEPARATOR);
}
void printUnusedField(DexEncodedField field) {
printClazzPrefixIfNecessary();
append(INDENT);
String accessFlags = field.accessFlags.toString();
if (!accessFlags.isEmpty()) {
append(accessFlags);
append(" ");
}
append(field.field.type.toSourceString());
append(" ");
append(field.field.name.toSourceString());
append(StringUtils.LINE_SEPARATOR);
}
// Empty implementation to silently ignore printing dead code.
private static class NoOpUsagePrinter extends UsagePrinter {
public NoOpUsagePrinter() {
super(null);
}
@Override
void printUnusedClass(DexProgramClass clazz) {
// Intentionally left empty.
}
@Override
void visiting(DexProgramClass clazz) {
// Intentionally left empty.
}
@Override
void visited() {
// Intentionally left empty.
}
@Override
void printUnusedMethod(DexEncodedMethod method) {
// Intentionally left empty.
}
@Override
void printUnusedField(DexEncodedField field) {
// Intentionally left empty.
}
}
}