All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.dipien.byebyejetifier.scanner.bytecode.CoreRemapper.kt Maven / Gradle / Ivy

There is a newer version: 1.2.2
Show newest version
package com.dipien.byebyejetifier.scanner.bytecode

import com.dipien.byebyejetifier.common.LoggerHelper
import com.dipien.byebyejetifier.core.type.JavaType
import com.dipien.byebyejetifier.scanner.ScannerContext

class CoreRemapper(
    private val context: ScannerContext,
    private val archiveFilePath: String
) {

    companion object {

        const val TAG = "CoreRemapper"

        val AMBIGUOUS_STRINGS = setOf(
            JavaType.fromDotVersion("android.support.v4"),
            JavaType.fromDotVersion("android.support.v4.content"),
            JavaType.fromDotVersion("android.support.v4.widget"),
            JavaType.fromDotVersion("android.support.v4.view"),
            JavaType.fromDotVersion("android.support.v4.media"),
            JavaType.fromDotVersion("android.support.v13"),
            JavaType.fromDotVersion("android.support.v13.view"),
            JavaType.fromDotVersion("android.support.v13.app"),
            JavaType.fromDotVersion("android.support.design.widget")
        )
    }

    fun rewriteType(type: JavaType): JavaType {
        val result = context.typeRewriter.rewriteType(type)
        if (result != null) {
            return result
        }

        context.reportNoMappingFoundFailure(TAG, type)
        return type
    }

    fun rewriteString(value: String): String {
        val hasDotSeparators = value.contains(".")
        val hasSlashSeparators = value.contains("/")

        if (hasDotSeparators && hasSlashSeparators) {
            // We do not support mix of both separators
            return value
        }

        val type = if (hasDotSeparators) {
            JavaType.fromDotVersion(value)
        } else {
            JavaType(value)
        }

        if (!context.config.isEligibleForRewrite(type)) {
            return value
        }

        // Verify that we did not make an ambiguous mapping, see b/116745353
        if (AMBIGUOUS_STRINGS.contains(type)) {
            LoggerHelper.warn(
                "The file '$archiveFilePath' contains a string literal " +
                    "with a package reference '$value'. " +
                    "Libraries using reflection such as annotation processors need to be " +
                    "updated manually to add support for androidx. " +
                    "But if you are sure there is no need to transform this package reference " +
                    "you can ignore this message or exclude this file from scanning using " +
                    "the 'excludedFilesFromScanning' property."
            )
            return value
        }

        // Strings map has a priority over types map
        val mappedString = context.config.stringsMap.mapType(type)
        if (mappedString != null) {
            LoggerHelper.debug("Map string: '$type' -> '$mappedString'")
            return if (hasDotSeparators) mappedString.toDotNotation() else mappedString.fullName
        }

        val mappedType = context.config.typesMap.mapType(type)
        if (mappedType != null) {
            LoggerHelper.debug("Map string: '$type' -> '$mappedType'")
            return if (hasDotSeparators) mappedType.toDotNotation() else mappedType.fullName
        }

        // We might be working with an internal type or field reference, e.g.
        // AccessibilityNodeInfoCompat.PANE_TITLE_KEY. So we try to remove last segment to help it.
        if (value.contains(".")) {
            val subTypeResult = context.config.typesMap.mapType(type.getParentType())
            if (subTypeResult != null) {
                val result = subTypeResult.toDotNotation() + '.' + value.substringAfterLast('.')
                LoggerHelper.debug("Map string: '$value' -> '$result' via type fallback")
                return result
            }
        }

        // Try rewrite rules
        val rewrittenType = context.config.rulesMap.rewriteType(type)
        if (rewrittenType != null) {
            LoggerHelper.debug("Map string: '$value' -> '$rewrittenType' via fallback")
            return if (hasDotSeparators) {
                rewrittenType.toDotNotation()
            } else {
                rewrittenType.fullName
            }
        }

        // We do not treat string content mismatches as errors
        LoggerHelper.debug("Found string '$value' but failed to rewrite")
        return value
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy