Home | History | Annotate | Download | only in patterns
      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 }