xref: /aosp_15_r20/external/ktfmt/core/src/main/java/com/facebook/ktfmt/debughelpers/OpsDebug.kt (revision 5be3f65c8cf0e6db0a7e312df5006e8e93cdf9ec)
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
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.facebook.ktfmt.debughelpers
18 
19 import com.google.common.collect.ImmutableList
20 import com.google.common.collect.Range
21 import com.google.googlejavaformat.CloseOp
22 import com.google.googlejavaformat.CommentsHelper
23 import com.google.googlejavaformat.Doc
24 import com.google.googlejavaformat.Input
25 import com.google.googlejavaformat.Op
26 import com.google.googlejavaformat.OpenOp
27 import com.google.googlejavaformat.OpsBuilder
28 import com.google.googlejavaformat.Output
29 import java.util.regex.Pattern
30 
31 /** A regex to extract the indent size from OpenOp.toString(). */
32 private val OPENOP_STRING_FORM_REGEX = Pattern.compile("""OpenOp\{plusIndent=Const\{n=(\d+)}}""")
33 
34 /**
35  * printOps prints a list of Ops in a hierarchical way.
36  *
37  * It's useful when debugging incorrect newlines.
38  */
printOpsnull39 fun printOps(ops: ImmutableList<Op>) {
40   println("Ops: ")
41   var indent = 0
42   for (op in ops) {
43     val line =
44         when (op) {
45           is OpenOp -> {
46             val matcher = OPENOP_STRING_FORM_REGEX.matcher(op.toString())
47             if (matcher.matches()) {
48               val opIndent = matcher.group(1)
49               "[ " + if (opIndent != "0") opIndent else ""
50             } else {
51               "[ $op"
52             }
53           }
54           is CloseOp -> "]"
55           is Doc.Token -> {
56             var result: String? = ""
57             val output =
58                 object : Output() {
59                   override fun indent(indent: Int) = Unit
60 
61                   override fun blankLine(k: Int, wanted: OpsBuilder.BlankLineWanted?) = Unit
62 
63                   override fun markForPartialFormat(start: Input.Token?, end: Input.Token?) = Unit
64 
65                   override fun getCommentsHelper(): CommentsHelper {
66                     throw Throwable()
67                   }
68 
69                   override fun append(text: String?, range: Range<Int>?) {
70                     result = text
71                   }
72                 }
73             op.write(output)
74             """"$result""""
75           }
76           else -> {
77             val result = op.toString()
78             if (result == "Space{}") "\" \"" else result
79           }
80         }
81     if (op is CloseOp) {
82       indent--
83     }
84     repeat(2 * indent) { print(" ") }
85     if (op is OpenOp) {
86       indent++
87     }
88     println(line)
89   }
90   println()
91 }
92