22//
33// This source file is part of the Swift.org open source project
44//
5- // Copyright (c) 2024 Apple Inc. and the Swift.org project authors
5+ // Copyright (c) 2024-2025 Apple Inc. and the Swift.org project authors
66// Licensed under Apache License v2.0
77//
88// See LICENSE.txt for license information
1212//
1313//===----------------------------------------------------------------------===//
1414
15- import Foundation
16-
17- #if os(Windows)
18- let PATH_SEPARATOR = " \\ "
15+ #if canImport(FoundationEssentials)
16+ import FoundationEssentials
1917#else
20- let PATH_SEPARATOR = " / "
18+ import Foundation
2119#endif
2220
21+ // ==== -----------------------------------------------------------------------
22+ // MARK: CodePrinter
23+
2324public struct CodePrinter {
24- var contents : String = " "
25+ public var contents : String = " "
2526
26- var verbose : Bool = false
27- let log = Logger ( label: " printer " , logLevel: . info)
27+ public var verbose : Bool = false
2828
29- var indentationDepth : Int = 0 {
29+ public var indentationDepth : Int = 0 {
3030 didSet {
3131 indentationText = String ( repeating: indentationPart, count: indentationDepth)
3232 }
@@ -40,15 +40,15 @@ public struct CodePrinter {
4040 }
4141 public var indentationText : String = " "
4242 /// If true, next print() should starts with indentation.
43- var atNewline = true
43+ public var atNewline = true
4444
4545 public static func toString( _ block: ( inout CodePrinter ) throws -> Void ) rethrows -> String {
4646 var printer = CodePrinter ( )
4747 try block ( & printer)
4848 return printer. finalize ( )
4949 }
5050
51- var mode : PrintMode
51+ public var mode : PrintMode
5252 public enum PrintMode {
5353 case accumulateAll
5454 case flushToFileOnWrite
@@ -57,14 +57,14 @@ public struct CodePrinter {
5757 self . mode = mode
5858 }
5959
60- mutating func append( _ text: String ) {
60+ public mutating func append( _ text: String ) {
6161 contents. append ( text)
6262 if self . verbose {
6363 Swift . print ( text, terminator: " " )
6464 }
6565 }
6666
67- mutating func append< S> ( contentsOf text: S )
67+ public mutating func append< S> ( contentsOf text: S )
6868 where S: Sequence , S. Element == Character {
6969 contents. append ( contentsOf: text)
7070 if self . verbose {
@@ -168,7 +168,6 @@ public struct CodePrinter {
168168 print ( text, . continue)
169169 }
170170
171- // TODO: remove this in real mode, this just helps visually while working on it
172171 public mutating func printSeparator( _ text: String ) {
173172 assert ( !text. contains ( where: \. isNewline) )
174173 print (
@@ -182,20 +181,16 @@ public struct CodePrinter {
182181 }
183182
184183 public mutating func finalize( ) -> String {
185- // assert(indentationDepth == 0, "Finalize CodePrinter with non-zero indentationDepth. Text was: \(contents)") // FIXME: do this
186184 defer { contents = " " }
187-
188185 return contents
189186 }
190187
191188 public mutating func indent( file: String = #fileID, line: UInt = #line, function: String = #function) {
192189 indentationDepth += 1
193- log. trace ( " Indent => \( indentationDepth) " , file: file, line: line, function: function)
194190 }
195191
196192 public mutating func outdent( file: String = #fileID, line: UInt = #line, function: String = #function) {
197193 indentationDepth -= 1
198- log. trace ( " Outdent => \( indentationDepth) " , file: file, line: line, function: function)
199194 assert ( indentationDepth >= 0 , " Outdent beyond zero at [ \( file) : \( line) ]( \( function) ) " )
200195 }
201196
@@ -207,9 +202,11 @@ public struct CodePrinter {
207202 Swift . print ( " // CodePrinter.dump @ \( file) : \( line) " )
208203 Swift . print ( contents)
209204 }
210-
211205}
212206
207+ // ==== -----------------------------------------------------------------------
208+ // MARK: PrinterTerminator
209+
213210public enum PrinterTerminator : String {
214211 case newLine = " \n "
215212 case space = " "
@@ -235,17 +232,32 @@ public enum PrinterTerminator: String {
235232 }
236233}
237234
235+ // ==== -----------------------------------------------------------------------
236+ // MARK: PATH_SEPARATOR
237+
238+ #if os(Windows)
239+ public let PATH_SEPARATOR = " \\ "
240+ #else
241+ public let PATH_SEPARATOR = " / "
242+ #endif
243+
244+ // ==== -----------------------------------------------------------------------
245+ // MARK: CodePrinter + writeContents
246+
238247extension CodePrinter {
239248
240- /// - Returns: the output path of the generated file, if any (i.e. not in accumulate in memory mode)
241- package mutating func writeContents(
249+ /// Write the accumulated contents to a file in the given output directory.
250+ ///
251+ /// - Returns: the output path of the generated file, if any (i.e. not in accumulate-in-memory mode)
252+ public mutating func writeContents(
242253 outputDirectory _outputDirectory: String ,
243254 javaPackagePath: String ? ,
244255 filename _filename: String
245256 ) throws -> URL ? {
246-
247- // We handle 'filename' that has a path, since that simplifies passing paths from root output directory enourmously.
248- // This just moves the directory parts into the output directory part in order for us to create the sub-directories.
257+ // We handle 'filename' that has a path, since that simplifies passing
258+ // paths from root output directory enormously. This just moves the
259+ // directory parts into the output directory part in order for us to
260+ // create the sub-directories.
249261 let outputDirectory : String
250262 let filename : String
251263 if _filename. contains ( PATH_SEPARATOR) {
@@ -260,8 +272,9 @@ extension CodePrinter {
260272 }
261273
262274 guard self . mode != . accumulateAll else {
263- // if we're accumulating everything, we don't want to finalize/flush any contents
264- // let's mark that this is where a write would have happened though:
275+ // if we're accumulating everything, we don't want to finalize/flush
276+ // any contents; let's mark that this is where a write would have
277+ // happened though:
265278 print ( " // ^^^^ Contents of: \( outputDirectory) \( PATH_SEPARATOR) \( filename) " )
266279 return nil
267280 }
@@ -281,15 +294,12 @@ extension CodePrinter {
281294 }
282295
283296 let targetDirectory = [ outputDirectory, javaPackagePath] . compactMap { $0 } . joined ( separator: PATH_SEPARATOR)
284- log. debug ( " Prepare target directory: ' \( targetDirectory) ' for file \( filename. bold) " )
285297 do {
286298 try FileManager . default. createDirectory (
287299 atPath: targetDirectory,
288300 withIntermediateDirectories: true
289301 )
290302 } catch {
291- // log and throw since it can be confusing what the reason for failing the write was otherwise
292- log. warning ( " Failed to create directory: \( targetDirectory) " )
293303 throw error
294304 }
295305
0 commit comments