@@ -72,25 +72,6 @@ public actor BuildSystemManager {
72
72
}
73
73
}
74
74
75
- /// Splits `message` on newline characters such that each chunk is at most `maxChunkSize` bytes long.
76
- ///
77
- /// The intended use case for this is to split compiler arguments into multiple chunks so that each chunk doesn't exceed
78
- /// the maximum message length of `os_log` and thus won't get truncated.
79
- ///
80
- /// - Note: This will only split along newline boundary. If a single line is longer than `maxChunkSize`, it won't be
81
- /// split. This is fine for compiler argument splitting since a single argument is rarely longer than 800 characters.
82
- private func splitLongMultilineMessage( message: String , maxChunkSize: Int ) -> [ String ] {
83
- var chunks : [ String ] = [ ]
84
- for line in message. split ( separator: " \n " , omittingEmptySubsequences: false ) {
85
- if let lastChunk = chunks. last, lastChunk. utf8. count + line. utf8. count < maxChunkSize {
86
- chunks [ chunks. count - 1 ] += " \n " + line
87
- } else {
88
- chunks. append ( String ( line) )
89
- }
90
- }
91
- return chunks
92
- }
93
-
94
75
extension BuildSystemManager {
95
76
public var delegate : BuildSystemDelegate ? {
96
77
get { _delegate }
@@ -160,23 +141,7 @@ extension BuildSystemManager {
160
141
// to reference `document` instead of `mainFile`.
161
142
settings = settings. patching ( newFile: document. pseudoPath, originalFile: mainFile. pseudoPath)
162
143
}
163
- let log = """
164
- Compiler Arguments:
165
- \( settings. compilerArguments. joined ( separator: " \n " ) )
166
-
167
- Working directory:
168
- \( settings. workingDirectory ?? " <nil> " )
169
- """
170
-
171
- let chunks = splitLongMultilineMessage ( message: log, maxChunkSize: 800 )
172
- for (index, chunk) in chunks. enumerated ( ) {
173
- logger. log (
174
- """
175
- Build settings for \( document. forLogging) ( \( index + 1 ) / \( chunks. count) )
176
- \( chunk)
177
- """
178
- )
179
- }
144
+ await BuildSettingsLogger . shared. log ( settings: settings, for: document)
180
145
return settings
181
146
}
182
147
@@ -334,3 +299,55 @@ extension BuildSystemManager {
334
299
return self . watchedFiles [ uri] ? . mainFile
335
300
}
336
301
}
302
+
303
+ // MARK: - Build settings logger
304
+
305
+ /// Shared logger that only logs build settings for a file once unless they change
306
+ fileprivate actor BuildSettingsLogger {
307
+ static let shared = BuildSettingsLogger ( )
308
+
309
+ private var loggedSettings : [ DocumentURI : FileBuildSettings ] = [ : ]
310
+
311
+ func log( settings: FileBuildSettings , for uri: DocumentURI ) {
312
+ guard loggedSettings [ uri] != settings else {
313
+ return
314
+ }
315
+ loggedSettings [ uri] = settings
316
+ let log = """
317
+ Compiler Arguments:
318
+ \( settings. compilerArguments. joined ( separator: " \n " ) )
319
+
320
+ Working directory:
321
+ \( settings. workingDirectory ?? " <nil> " )
322
+ """
323
+
324
+ let chunks = splitLongMultilineMessage ( message: log, maxChunkSize: 800 )
325
+ for (index, chunk) in chunks. enumerated ( ) {
326
+ logger. log (
327
+ """
328
+ Build settings for \( uri. forLogging) ( \( index + 1 ) / \( chunks. count) )
329
+ \( chunk)
330
+ """
331
+ )
332
+ }
333
+ }
334
+
335
+ /// Splits `message` on newline characters such that each chunk is at most `maxChunkSize` bytes long.
336
+ ///
337
+ /// The intended use case for this is to split compiler arguments into multiple chunks so that each chunk doesn't exceed
338
+ /// the maximum message length of `os_log` and thus won't get truncated.
339
+ ///
340
+ /// - Note: This will only split along newline boundary. If a single line is longer than `maxChunkSize`, it won't be
341
+ /// split. This is fine for compiler argument splitting since a single argument is rarely longer than 800 characters.
342
+ private func splitLongMultilineMessage( message: String , maxChunkSize: Int ) -> [ String ] {
343
+ var chunks : [ String ] = [ ]
344
+ for line in message. split ( separator: " \n " , omittingEmptySubsequences: false ) {
345
+ if let lastChunk = chunks. last, lastChunk. utf8. count + line. utf8. count < maxChunkSize {
346
+ chunks [ chunks. count - 1 ] += " \n " + line
347
+ } else {
348
+ chunks. append ( String ( line) )
349
+ }
350
+ }
351
+ return chunks
352
+ }
353
+ }
0 commit comments