Home | History | Annotate | Download | only in proguard
      1 /*
      2  * Copyright 2018 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.tools.build.jetifier.core.proguard
     18 
     19 import com.android.tools.build.jetifier.core.utils.Log
     20 
     21 /**
     22  * Contains custom mappings to map support library types referenced in ProGuard to new ones.
     23  */
     24 data class ProGuardTypesMap(private val rules: Map<ProGuardType, Set<ProGuardType>>) {
     25 
     26     companion object {
     27         const val TAG = "ProGuardTypesMap"
     28 
     29         val EMPTY = ProGuardTypesMap(emptyMap())
     30     }
     31 
     32     private val expandedRules: Map<ProGuardType, Set<ProGuardType>> by lazy {
     33         val expandedMap = mutableMapOf<ProGuardType, Set<ProGuardType>>()
     34         rules.forEach { (from, to) ->
     35             if (from.needsExpansion() || to.any { it.needsExpansion() }) {
     36                 ProGuardType.EXPANSION_TOKENS.forEach {
     37                     t -> expandedMap.put(from.expandWith(t), to.map { it.expandWith(t) }.toSet())
     38                 }
     39             } else {
     40                 expandedMap.put(from, to)
     41             }
     42         }
     43         expandedMap
     44     }
     45 
     46     constructor(vararg rules: Pair<ProGuardType, ProGuardType>)
     47         : this(rules.map { it.first to setOf(it.second) }.toMap())
     48 
     49     /** Returns JSON data model of this class */
     50     fun toJson(): JsonData {
     51         return JsonData(rules.map { it.key.value to it.value.map { it.value }.toList() }.toMap())
     52     }
     53 
     54     fun mapType(type: ProGuardType): Set<ProGuardType>? {
     55         return expandedRules[type]
     56     }
     57 
     58     /**
     59      * JSON data model for [ProGuardTypesMap].
     60      */
     61     data class JsonData(val rules: Map<String, List<String>>) {
     62 
     63         /** Creates instance of [ProGuardTypesMap] */
     64         fun toMappings(): ProGuardTypesMap {
     65             return ProGuardTypesMap(rules
     66                 .map { ProGuardType(it.key) to it.value.map { ProGuardType(it) }.toSet() }
     67                 .toMap())
     68         }
     69     }
     70 
     71     /**
     72      * Creates reversed version of this map (values become keys). If there are multiple keys mapped
     73      * to the same value only the first value is used and warning message is printed.
     74      */
     75     fun reverseMap(): ProGuardTypesMap {
     76         val reversed = mutableMapOf<ProGuardType, ProGuardType>()
     77         for ((from, to) in rules) {
     78             if (to.size > 1) {
     79                 // Skip reversal of a set
     80                 continue
     81             }
     82 
     83             val conflictFrom = reversed[to.single()]
     84             if (conflictFrom != null) {
     85                 // Conflict - skip
     86                 Log.w(TAG, "Conflict: %s -> (%s, %s)", to, from, conflictFrom)
     87                 continue
     88             }
     89             reversed[to.single()] = from
     90         }
     91 
     92         return ProGuardTypesMap(reversed
     93             .map { it.key to setOf(it.value) }
     94             .toMap())
     95     }
     96 }