15d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis/* 24a360e3a3af230badc847867c117f605367170aaFilip Pavlis * Copyright 2017 The Android Open Source Project 35d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis * 45d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis * Licensed under the Apache License, Version 2.0 (the "License"); 55d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis * you may not use this file except in compliance with the License. 65d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis * You may obtain a copy of the License at 75d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis * 84a360e3a3af230badc847867c117f605367170aaFilip Pavlis * http://www.apache.org/licenses/LICENSE-2.0 95d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis * 105d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis * Unless required by applicable law or agreed to in writing, software 115d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis * distributed under the License is distributed on an "AS IS" BASIS, 125d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis * See the License for the specific language governing permissions and 144a360e3a3af230badc847867c117f605367170aaFilip Pavlis * limitations under the License. 155d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis */ 165d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis 17ba381a314edcd57963ed1ac5910595e04faf29ccFilip Pavlispackage com.android.tools.build.jetifier.processor.transform.proguard 185d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis 19ba381a314edcd57963ed1ac5910595e04faf29ccFilip Pavlisimport com.android.tools.build.jetifier.processor.transform.proguard.patterns.GroupsReplacer 20ba381a314edcd57963ed1ac5910595e04faf29ccFilip Pavlisimport com.android.tools.build.jetifier.processor.transform.proguard.patterns.PatternHelper 215d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlisimport java.util.regex.Pattern 225d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis 235d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis/** 245d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis * Parses and rewrites ProGuard rules that contain class filters. See ProGuard documentation 255d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis * https://www.guardsquare.com/en/proguard/manual/usage#filters 265d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis */ 274a360e3a3af230badc847867c117f605367170aaFilip Pavlisclass ProGuardClassFilterParser(private val mapper: ProGuardTypesMapper) { 285d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis 295d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis companion object { 305d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis private const val RULES = "(adaptclassstrings|dontnote|dontwarn)" 315d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis } 325d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis 335d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis val replacer = GroupsReplacer( 345d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis pattern = PatternHelper.build("^ *-$RULES ⦅[^-]+⦆ *$", Pattern.MULTILINE), 355d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis groupsMap = listOf( 36982679c45ee20f39c5da072ff6a80519ee262ef4Filip Pavlis { filter: String -> listOf(rewriteClassFilter(filter)) } 375d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis ) 385d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis ) 395d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis 404a360e3a3af230badc847867c117f605367170aaFilip Pavlis private fun rewriteClassFilter(classFilter: String): String { 415d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis return classFilter 425d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis .splitToSequence(",") 435d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis .filterNotNull() 445d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis .map { it.trim() } 455d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis .filter { it.isNotEmpty() } 465d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis .map { replaceTypeInClassFilter(it) } 47982679c45ee20f39c5da072ff6a80519ee262ef4Filip Pavlis .flatten() 48982679c45ee20f39c5da072ff6a80519ee262ef4Filip Pavlis .distinct() 495d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis .joinToString(separator = ", ") 505d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis } 515d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis 52982679c45ee20f39c5da072ff6a80519ee262ef4Filip Pavlis /** 53982679c45ee20f39c5da072ff6a80519ee262ef4Filip Pavlis * Given a package name matcher that matches several pre-renamed class names, returns several 54982679c45ee20f39c5da072ff6a80519ee262ef4Filip Pavlis * package name matches that collectively match all of the possible pos-renamed names of those 55982679c45ee20f39c5da072ff6a80519ee262ef4Filip Pavlis * classes. 56982679c45ee20f39c5da072ff6a80519ee262ef4Filip Pavlis */ 57982679c45ee20f39c5da072ff6a80519ee262ef4Filip Pavlis private fun replaceTypeInClassFilter(type: String): List<String> { 585d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis if (!type.startsWith('!')) { 595d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis return mapper.replaceType(type) 605d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis } 615d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis 625d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis val withoutNegation = type.substring(1, type.length) 63982679c45ee20f39c5da072ff6a80519ee262ef4Filip Pavlis return mapper.replaceType(withoutNegation) 64982679c45ee20f39c5da072ff6a80519ee262ef4Filip Pavlis .map { '!' + it } 65982679c45ee20f39c5da072ff6a80519ee262ef4Filip Pavlis .toList() 665d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis } 675d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis}