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 */ printOpsnull39fun 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