@@ -29,24 +29,55 @@ struct ScriptWriter {
29
29
/// Whether to include line numbers in the output.
30
30
private let includeLineNumbers : Bool
31
31
32
+ // Split lines after this length. Do not use this in combination with JavaScript as it might
33
+ // split line comments, string literals, ... across multiple lines which changes semantics.
34
+ private let maxLineLength : Int
35
+
32
36
/// Current line, used when including line numbers in the output.
33
37
public private( set) var currentLineNumber = 0
34
38
35
- public init ( stripComments: Bool = false , includeLineNumbers: Bool = false , indent: Int = 4 , initialIndentionLevel: Int = 0 ) {
39
+ public init ( stripComments: Bool = false , includeLineNumbers: Bool = false , indent: Int = 4 , initialIndentionLevel: Int = 0 , maxLineLength : Int = Int . max ) {
36
40
self . indent = String ( repeating: " " , count: indent)
37
41
self . currentIndention = String ( repeating: " " , count: indent * initialIndentionLevel)
38
42
self . stripComments = stripComments
39
43
self . includeLineNumbers = includeLineNumbers
44
+ self . maxLineLength = maxLineLength
40
45
}
41
46
42
- /// Emit one line of code.
43
- mutating func emit< S: StringProtocol > ( _ line: S ) {
44
- assert ( !line. contains ( " \n " ) )
47
+ private mutating func emitImpl< S: StringProtocol > ( _ line: S ) {
45
48
currentLineNumber += 1
46
49
if includeLineNumbers { code += " \( String ( format: " %3i " , currentLineNumber) ) . " }
47
50
code += currentIndention + line + " \n "
48
51
}
49
52
53
+ /// Emit one line of code.
54
+ mutating func emit< S: StringProtocol > ( _ line: S ) {
55
+ assert ( maxLineLength > currentIndention. count)
56
+ let splitAt = maxLineLength - currentIndention. count
57
+ assert ( !line. contains ( " \n " ) )
58
+ var line = line. prefix ( line. count)
59
+ while line. count > splitAt {
60
+ var lineToPrint = line. prefix ( splitAt + 1 )
61
+ if let spaceIndex = lineToPrint. lastIndex ( of: " " ) ,
62
+ spaceIndex != lineToPrint. startIndex {
63
+ // Only print the line if it contains non-space characters trimming all trailing
64
+ // spaces.
65
+ lineToPrint = lineToPrint. prefix ( upTo: spaceIndex)
66
+ if let lastChar = ( lineToPrint. lastIndex { $0 != " " } ) {
67
+ emitImpl ( line. prefix ( through: lastChar) )
68
+ }
69
+ line = line. suffix ( from: line. index ( after: spaceIndex) )
70
+ } else {
71
+ emitImpl ( line. prefix ( splitAt) )
72
+ line = line. suffix ( line. count - splitAt)
73
+ }
74
+ line = line. suffix ( from: line. firstIndex { $0 != " " } ?? line. endIndex)
75
+ }
76
+ if !line. isEmpty {
77
+ emitImpl ( line)
78
+ }
79
+ }
80
+
50
81
/// Emit a comment.
51
82
mutating func emitComment( _ comment: String ) {
52
83
guard !stripComments else { return }
0 commit comments