blob: 90ffd66b4f2251989602bf05eeae6bbec8daf7c7 [file] [log] [blame]
// Copyright (c) 2025, 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;
import com.android.tools.r8.ProgramResource.Kind;
import com.android.tools.r8.keepanno.annotations.KeepForApi;
import com.android.tools.r8.keepanno.asm.KeepEdgeReader;
import com.android.tools.r8.keepanno.ast.KeepDeclaration;
import com.android.tools.r8.keepanno.keeprules.KeepRuleExtractor;
import com.android.tools.r8.keepanno.keeprules.KeepRuleExtractorOptions;
import com.android.tools.r8.shaking.ProguardConfigurationSourceStrings;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.ExceptionDiagnostic;
import com.android.tools.r8.utils.ExceptionUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Reporter;
import java.util.Collections;
import java.util.List;
/** Experimental API to extract keep rules from keep annotations. */
@KeepForApi
public class ExtractKeepAnnoRules {
private static void run(
AndroidApp app,
StringConsumer consumer,
KeepRuleExtractorOptions extractorOptions,
Reporter reporter) {
try {
extractKeepAnnotationRules(app, consumer, extractorOptions, reporter);
} catch (ResourceException e) {
throw reporter.fatalError(new ExceptionDiagnostic(e));
}
consumer.finished(reporter);
}
private static void extractKeepAnnotationRules(
AndroidApp app,
StringConsumer consumer,
KeepRuleExtractorOptions extractorOptions,
Reporter reporter)
throws ResourceException {
// TODO(b/425252849): Parallelize.
for (ProgramResourceProvider provider : app.getProgramResourceProviders()) {
for (ProgramResource resource : provider.getProgramResources()) {
if (resource.getKind() == Kind.CF) {
List<KeepDeclaration> declarations = KeepEdgeReader.readKeepEdges(resource.getBytes());
if (!declarations.isEmpty()) {
KeepRuleExtractor extractor =
new KeepRuleExtractor(
rule -> {
ProguardConfigurationSourceStrings source =
new ProguardConfigurationSourceStrings(
Collections.singletonList(rule), null, resource.getOrigin());
consumer.accept(source.get(), reporter);
},
extractorOptions);
declarations.forEach(extractor::extract);
}
}
}
}
}
/** Experimental API to extract keep rules from keep annotations. */
public static void run(ExtractKeepAnnoRulesCommand command) throws CompilationFailedException {
AndroidApp app = command.getInputApp();
StringConsumer rulesConsumer = command.getRulesConsumer();
KeepRuleExtractorOptions extractorOptions = command.getExtractorOptions();
InternalOptions options = command.getInternalOptions();
ExceptionUtils.withCompilationHandler(
options.reporter,
() -> {
run(app, rulesConsumer, extractorOptions, options.reporter);
});
}
public static void main(String[] args) throws CompilationFailedException {
System.out.println("The keep annotations keep rules extraction tool is experimental.");
ExtractKeepAnnoRulesCommand.Builder builder = ExtractKeepAnnoRulesCommand.parse(args);
ExtractKeepAnnoRulesCommand command = builder.build();
if (command.isPrintHelp()) {
System.out.println(ExtractR8RulesCommand.USAGE_MESSAGE);
return;
}
if (command.isPrintVersion()) {
System.out.println("ExtractR8Rules " + Version.LABEL);
return;
}
run(command);
}
}