1 /* 2 * Copyright 2017 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.processor.transform.proguard.patterns 18 19 /** 20 * Runs multiple [GroupsReplacer]s on given strings. 21 */ 22 class ReplacersRunner(val replacers: List<GroupsReplacer>) { 23 24 /** 25 * Runs all the [GroupsReplacer]s on the given [input]. 26 * 27 * The replacers have to be distinct as this method can't guarantee that output of one replacer 28 * won't be matched by another replacer. 29 */ 30 fun applyReplacers(input: String): String { 31 val sb = StringBuilder() 32 var lastSeenChar = 0 33 var processedInput = input 34 35 for (replacer in replacers) { 36 val matcher = replacer.pattern.matcher(processedInput) 37 38 while (matcher.find()) { 39 if (lastSeenChar < matcher.start()) { 40 sb.append(processedInput, lastSeenChar, matcher.start()) 41 } 42 43 val result = replacer.runReplacements(matcher) 44 sb.append(result.joinToString(System.lineSeparator())) 45 lastSeenChar = matcher.end() 46 } 47 48 if (lastSeenChar == 0) { 49 continue 50 } 51 52 if (lastSeenChar <= processedInput.length - 1) { 53 sb.append(processedInput, lastSeenChar, processedInput.length) 54 } 55 56 lastSeenChar = 0 57 processedInput = sb.toString() 58 sb.setLength(0) 59 } 60 return processedInput 61 } 62 }