ProGuardClassFilterParser.kt revision 5d7619f3c22d5d40ff099ae5599bdbb47453d2cc
15d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis/*
25d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis * Copyright (C) 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 *
85d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip 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
145d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis * limitations under the License
155d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis */
165d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis
175d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlispackage android.support.tools.jetifier.core.transform.proguard
185d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis
195d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlisimport android.support.tools.jetifier.core.transform.proguard.patterns.GroupsReplacer
205d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlisimport android.support.tools.jetifier.core.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 */
275d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip 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(
365d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis            { filter : String -> rewriteClassFilter(filter) }
375d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis        )
385d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis    )
395d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis
405d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip 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) }
475d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis            .joinToString(separator = ", ")
485d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis    }
495d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis
505d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis    private fun replaceTypeInClassFilter(type: String) : String {
515d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis        if (!type.startsWith('!')) {
525d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis            return mapper.replaceType(type)
535d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis        }
545d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis
555d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis        val withoutNegation = type.substring(1, type.length)
565d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis        return '!' + mapper.replaceType(withoutNegation)
575d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis    }
585d7619f3c22d5d40ff099ae5599bdbb47453d2ccFilip Pavlis}