blob: 6bfd90ffaf84d4b47c39a33443590407bc5dc4ea [file] [log] [blame]
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@file:JvmName("R8ResourceShrinker")
package com.android.build.shrinker.usages
import com.android.tools.r8.ProgramResource
import com.android.tools.r8.ProgramResourceProvider
import com.android.tools.r8.ResourceShrinker
import com.android.tools.r8.origin.PathOrigin
import com.android.tools.r8.references.MethodReference
import java.nio.file.Path
fun runResourceShrinkerAnalysis(bytes: ByteArray, file: Path, callback: AnalysisCallback) {
val resource =
ProgramResource.fromBytes(PathOrigin(file), ProgramResource.Kind.DEX, bytes, null)
val provider = ProgramResourceProvider { listOf(resource) }
val command = ResourceShrinker.Builder().addProgramResourceProvider(provider).build()
ResourceShrinker.run(command, AnalysisAdapter(callback))
}
/** An adapter so R8 API classes do not leak into other modules. */
class AnalysisAdapter(val impl: AnalysisCallback) : ResourceShrinker.ReferenceChecker {
override fun shouldProcess(internalName: String): Boolean = impl.shouldProcess(internalName)
override fun referencedStaticField(internalName: String, fieldName: String) =
impl.referencedStaticField(internalName, fieldName)
override fun referencedInt(value: Int) = impl.referencedInt(value)
override fun referencedString(value: String) = impl.referencedString(value)
override fun referencedMethod(
internalName: String, methodName: String, methodDescriptor: String
) = impl.referencedMethod(internalName, methodName, methodDescriptor)
override fun startMethodVisit(methodReference: MethodReference
) = impl.startMethodVisit(methodReference)
override fun endMethodVisit(methodReference: MethodReference
) = impl.endMethodVisit(methodReference)
}
interface AnalysisCallback {
fun shouldProcess(internalName: String): Boolean
fun referencedInt(value: Int)
fun referencedString(value: String)
fun referencedStaticField(internalName: String, fieldName: String)
fun referencedMethod(internalName: String, methodName: String, methodDescriptor: String)
fun startMethodVisit(methodReference: MethodReference)
fun endMethodVisit(methodReference: MethodReference)
}
class MethodVisitingStatus(var isVisiting: Boolean = false, var methodName: String? = null)