@@ -23,15 +23,15 @@ class Frontend {
23
23
/// An open file handle to the source code of the file.
24
24
private let fileHandle : FileHandle
25
25
26
- /// The path to the source file being processed.
26
+ /// A file URL representing the path to the source file being processed.
27
27
///
28
28
/// It is the responsibility of the specific frontend to make guarantees about the validity of
29
29
/// this path. For example, the formatting frontend ensures that it is a path to an existing
30
30
/// file only when doing in-place formatting (so that the file can be replaced). In other
31
31
/// situations, it may correspond to a different file than the underlying file handle (if
32
32
/// standard input is used with the `--assume-filename` flag), or it may not be a valid path at
33
33
/// all (the string `"<stdin>"`).
34
- let path : String
34
+ let url : URL
35
35
36
36
/// The configuration that should applied for this file.
37
37
let configuration : Configuration
@@ -46,9 +46,9 @@ class Frontend {
46
46
return String ( data: sourceData, encoding: . utf8)
47
47
} ( )
48
48
49
- init ( fileHandle: FileHandle , path : String , configuration: Configuration ) {
49
+ init ( fileHandle: FileHandle , url : URL , configuration: Configuration ) {
50
50
self . fileHandle = fileHandle
51
- self . path = path
51
+ self . url = url
52
52
self . configuration = configuration
53
53
}
54
54
}
@@ -81,12 +81,12 @@ class Frontend {
81
81
82
82
/// Runs the linter or formatter over the inputs.
83
83
final func run( ) {
84
- let paths = lintFormatOptions. paths
85
-
86
- if paths. isEmpty {
84
+ if lintFormatOptions. paths. isEmpty {
87
85
processStandardInput ( )
88
86
} else {
89
- processPaths ( paths, parallel: lintFormatOptions. parallel)
87
+ processURLs (
88
+ lintFormatOptions. paths. map ( URL . init ( fileURLWithPath: ) ) ,
89
+ parallel: lintFormatOptions. parallel)
90
90
}
91
91
}
92
92
@@ -103,52 +103,55 @@ class Frontend {
103
103
/// Processes source content from standard input.
104
104
private func processStandardInput( ) {
105
105
guard let configuration = configuration (
106
- atPath : lintFormatOptions. configurationPath,
107
- orInferredFromSwiftFileAtPath : nil )
106
+ at : lintFormatOptions. configurationPath. map ( URL . init ( fileURLWithPath : ) ) ,
107
+ orInferredFromSwiftFileAt : nil )
108
108
else {
109
109
// Already diagnosed in the called method.
110
110
return
111
111
}
112
112
113
113
let fileToProcess = FileToProcess (
114
114
fileHandle: FileHandle . standardInput,
115
- path : lintFormatOptions. assumeFilename ?? " <stdin> " ,
115
+ url : URL ( fileURLWithPath : lintFormatOptions. assumeFilename ?? " <stdin> " ) ,
116
116
configuration: configuration)
117
117
processFile ( fileToProcess)
118
118
}
119
119
120
- /// Processes source content from a list of files and/or directories provided as paths .
121
- private func processPaths ( _ paths : [ String ] , parallel: Bool ) {
120
+ /// Processes source content from a list of files and/or directories provided as file URLs .
121
+ private func processURLs ( _ urls : [ URL ] , parallel: Bool ) {
122
122
precondition (
123
- !paths . isEmpty,
124
- " processPaths (_:) should only be called when paths is non-empty." )
123
+ !urls . isEmpty,
124
+ " processURLs (_:) should only be called when 'urls' is non-empty." )
125
125
126
126
if parallel {
127
- let filesToProcess = FileIterator ( paths : paths ) . compactMap ( openAndPrepareFile)
127
+ let filesToProcess = FileIterator ( urls : urls ) . compactMap ( openAndPrepareFile)
128
128
DispatchQueue . concurrentPerform ( iterations: filesToProcess. count) { index in
129
129
processFile ( filesToProcess [ index] )
130
130
}
131
131
} else {
132
- FileIterator ( paths : paths ) . lazy. compactMap ( openAndPrepareFile) . forEach ( processFile)
132
+ FileIterator ( urls : urls ) . lazy. compactMap ( openAndPrepareFile) . forEach ( processFile)
133
133
}
134
134
}
135
135
136
136
/// Read and prepare the file at the given path for processing, optionally synchronizing
137
137
/// diagnostic output.
138
- private func openAndPrepareFile( atPath path: String ) -> FileToProcess ? {
139
- guard let sourceFile = FileHandle ( forReadingAtPath: path) else {
140
- diagnosticsEngine. emitError ( " Unable to open \( path) " )
138
+ private func openAndPrepareFile( at url: URL ) -> FileToProcess ? {
139
+ guard let sourceFile = try ? FileHandle ( forReadingFrom: url) else {
140
+ diagnosticsEngine. emitError (
141
+ " Unable to open \( url. relativePath) : file is not readable or does not exist " )
141
142
return nil
142
143
}
143
144
144
- guard let configuration = configuration (
145
- atPath: lintFormatOptions. configurationPath, orInferredFromSwiftFileAtPath: path)
145
+ guard
146
+ let configuration = configuration (
147
+ at: lintFormatOptions. configurationPath. map ( URL . init ( fileURLWithPath: ) ) ,
148
+ orInferredFromSwiftFileAt: url)
146
149
else {
147
150
// Already diagnosed in the called method.
148
151
return nil
149
152
}
150
153
151
- return FileToProcess ( fileHandle: sourceFile, path : path , configuration: configuration)
154
+ return FileToProcess ( fileHandle: sourceFile, url : url , configuration: configuration)
152
155
}
153
156
154
157
/// Returns the configuration that applies to the given `.swift` source file, when an explicit
@@ -164,14 +167,14 @@ class Frontend {
164
167
/// `swiftFilePath` if one exists, or the default configuration otherwise. If an error occurred
165
168
/// when reading the configuration, a diagnostic is emitted and `nil` is returned.
166
169
private func configuration(
167
- atPath configurationFilePath : String ? ,
168
- orInferredFromSwiftFileAtPath swiftFilePath : String ?
170
+ at configurationFileURL : URL ? ,
171
+ orInferredFromSwiftFileAt swiftFileURL : URL ?
169
172
) -> Configuration ? {
170
173
// If an explicit configuration file path was given, try to load it and fail if it cannot be
171
174
// loaded. (Do not try to fall back to a path inferred from the source file path.)
172
- if let configurationFilePath = configurationFilePath {
175
+ if let configurationFileURL = configurationFileURL {
173
176
do {
174
- return try configurationLoader. configuration ( atPath : configurationFilePath )
177
+ return try configurationLoader. configuration ( at : configurationFileURL )
175
178
} catch {
176
179
diagnosticsEngine. emitError ( " Unable to read configuration: \( error. localizedDescription) " )
177
180
return nil
@@ -180,17 +183,15 @@ class Frontend {
180
183
181
184
// If no explicit configuration file path was given but a `.swift` source file path was given,
182
185
// then try to load the configuration by inferring it based on the source file path.
183
- if let swiftFilePath = swiftFilePath {
186
+ if let swiftFileURL = swiftFileURL {
184
187
do {
185
- if let configuration =
186
- try configurationLoader. configuration ( forSwiftFileAtPath: swiftFilePath)
187
- {
188
+ if let configuration = try configurationLoader. configuration ( forSwiftFileAt: swiftFileURL) {
188
189
return configuration
189
190
}
190
191
// Fall through to the default return at the end of the function.
191
192
} catch {
192
193
diagnosticsEngine. emitError (
193
- " Unable to read configuration for \( swiftFilePath ) : \( error. localizedDescription) " )
194
+ " Unable to read configuration for \( swiftFileURL . path ) : \( error. localizedDescription) " )
194
195
return nil
195
196
}
196
197
}
0 commit comments