Skip to content

Commit c9d502a

Browse files
committed
reuse codeprinter
1 parent ab27cfa commit c9d502a

5 files changed

Lines changed: 277 additions & 279 deletions

File tree

Package.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,10 @@ let package = Package(
263263
name: "SwiftJavaShared"
264264
),
265265

266+
.target(
267+
name: "CodePrinting"
268+
),
269+
266270
.target(
267271
name: "SwiftJavaToolLib",
268272
dependencies: [
@@ -277,6 +281,7 @@ let package = Package(
277281
"JavaNet",
278282
"SwiftJavaShared",
279283
"SwiftJavaConfigurationShared",
284+
"CodePrinting",
280285
.product(name: "Subprocess", package: "swift-subprocess"),
281286
],
282287
swiftSettings: [
@@ -324,6 +329,7 @@ let package = Package(
324329
.product(name: "SwiftJavaJNICore", package: "swift-java-jni-core"),
325330
"SwiftJavaShared",
326331
"SwiftJavaConfigurationShared",
332+
"CodePrinting",
327333
],
328334
swiftSettings: [
329335
.swiftLanguageMode(.v5)
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2024-2025 Apple Inc. and the Swift.org project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of Swift.org project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
// ==== -----------------------------------------------------------------------
16+
// MARK: CodePrinter
17+
18+
public struct CodePrinter {
19+
var contents: String = ""
20+
21+
var verbose: Bool = false
22+
23+
var indentationDepth: Int = 0 {
24+
didSet {
25+
indentationText = String(repeating: indentationPart, count: indentationDepth)
26+
}
27+
}
28+
29+
/// String to use for one level of indentationDepth.
30+
public var indentationPart: String = " " {
31+
didSet {
32+
indentationText = String(repeating: indentationPart, count: indentationDepth)
33+
}
34+
}
35+
public var indentationText: String = ""
36+
/// If true, next print() should starts with indentation.
37+
var atNewline = true
38+
39+
public static func toString(_ block: (inout CodePrinter) throws -> Void) rethrows -> String {
40+
var printer = CodePrinter()
41+
try block(&printer)
42+
return printer.finalize()
43+
}
44+
45+
var mode: PrintMode
46+
public enum PrintMode {
47+
case accumulateAll
48+
case flushToFileOnWrite
49+
}
50+
public init(mode: PrintMode = .flushToFileOnWrite) {
51+
self.mode = mode
52+
}
53+
54+
mutating func append(_ text: String) {
55+
contents.append(text)
56+
if self.verbose {
57+
Swift.print(text, terminator: "")
58+
}
59+
}
60+
61+
mutating func append<S>(contentsOf text: S)
62+
where S: Sequence, S.Element == Character {
63+
contents.append(contentsOf: text)
64+
if self.verbose {
65+
for t in text {
66+
Swift.print(t, terminator: "")
67+
}
68+
}
69+
}
70+
71+
public mutating func printHashIfBlock(
72+
_ header: Any,
73+
function: String = #function,
74+
file: String = #fileID,
75+
line: UInt = #line,
76+
body: (inout CodePrinter) throws -> Void
77+
) rethrows {
78+
print("#if \(header)")
79+
indent()
80+
try body(&self)
81+
outdent()
82+
print("#endif // end of \(header)", .sloc, function: function, file: file, line: line)
83+
}
84+
85+
public mutating func printBraceBlock(
86+
_ header: Any,
87+
parameters: [String]? = nil,
88+
function: String = #function,
89+
file: String = #fileID,
90+
line: UInt = #line,
91+
body: (inout CodePrinter) throws -> Void
92+
) rethrows {
93+
print("\(header) {", .continue)
94+
if let parameters {
95+
print(" (\(parameters.joined(separator: ", "))) in", .continue)
96+
}
97+
println()
98+
indent()
99+
try body(&self)
100+
outdent()
101+
print("}", .sloc, function: function, file: file, line: line)
102+
}
103+
104+
public mutating func printParts(
105+
_ parts: String...,
106+
terminator: PrinterTerminator = .newLine,
107+
function: String = #function,
108+
file: String = #fileID,
109+
line: UInt = #line
110+
) {
111+
for part in parts {
112+
guard part.trimmingCharacters(in: .whitespacesAndNewlines).count != 0 else {
113+
continue
114+
}
115+
116+
self.print(part, terminator, function: function, file: file, line: line)
117+
}
118+
}
119+
120+
/// Print a plain newline, e.g. to separate declarations.
121+
public mutating func println(
122+
_ terminator: PrinterTerminator = .newLine,
123+
function: String = #function,
124+
file: String = #fileID,
125+
line: UInt = #line
126+
) {
127+
print("")
128+
}
129+
130+
public mutating func print(
131+
_ text: Any,
132+
_ terminator: PrinterTerminator = .newLine,
133+
function: String = #function,
134+
file: String = #fileID,
135+
line: UInt = #line
136+
) {
137+
let lines = "\(text)".split(separator: "\n", omittingEmptySubsequences: false)
138+
var first = true
139+
for line in lines {
140+
if !first {
141+
append("\n")
142+
append(indentationText)
143+
} else {
144+
if atNewline {
145+
append(indentationText)
146+
}
147+
first = false
148+
}
149+
append(contentsOf: line)
150+
}
151+
152+
if terminator == .sloc {
153+
append(" // \(function) @ \(file):\(line)\n")
154+
atNewline = true
155+
} else {
156+
append(terminator.rawValue)
157+
atNewline = terminator == .newLine || terminator == .commaNewLine
158+
}
159+
}
160+
161+
public mutating func start(_ text: String) {
162+
print(text, .continue)
163+
}
164+
165+
public mutating func printSeparator(_ text: String) {
166+
assert(!text.contains(where: \.isNewline))
167+
print(
168+
"""
169+
170+
// ==== --------------------------------------------------
171+
// \(text)
172+
173+
"""
174+
)
175+
}
176+
177+
public mutating func finalize() -> String {
178+
defer { contents = "" }
179+
return contents
180+
}
181+
182+
public mutating func indent(file: String = #fileID, line: UInt = #line, function: String = #function) {
183+
indentationDepth += 1
184+
}
185+
186+
public mutating func outdent(file: String = #fileID, line: UInt = #line, function: String = #function) {
187+
indentationDepth -= 1
188+
assert(indentationDepth >= 0, "Outdent beyond zero at [\(file):\(line)](\(function))")
189+
}
190+
191+
public var isEmpty: Bool {
192+
self.contents.isEmpty
193+
}
194+
195+
public mutating func dump(file: String = #fileID, line: UInt = #line) {
196+
Swift.print("// CodePrinter.dump @ \(file):\(line)")
197+
Swift.print(contents)
198+
}
199+
}
200+
201+
// ==== -----------------------------------------------------------------------
202+
// MARK: PrinterTerminator
203+
204+
public enum PrinterTerminator: String {
205+
case newLine = "\n"
206+
case space = " "
207+
case commaSpace = ", "
208+
case commaNewLine = ",\n"
209+
case `continue` = ""
210+
case sloc = "// <source location>"
211+
212+
public static func parameterSeparator(_ isLast: Bool) -> Self {
213+
if isLast {
214+
.continue
215+
} else {
216+
.commaSpace
217+
}
218+
}
219+
220+
public static func parameterNewlineSeparator(_ isLast: Bool) -> Self {
221+
if isLast {
222+
.newLine
223+
} else {
224+
.commaNewLine
225+
}
226+
}
227+
}

0 commit comments

Comments
 (0)