@@ -23,15 +23,15 @@ class Frontend {
2323 /// An open file handle to the source code of the file.
2424 private let fileHandle : FileHandle
2525
26- /// The path to the source file being processed.
26+ /// A file URL representing the path to the source file being processed.
2727 ///
2828 /// It is the responsibility of the specific frontend to make guarantees about the validity of
2929 /// this path. For example, the formatting frontend ensures that it is a path to an existing
3030 /// file only when doing in-place formatting (so that the file can be replaced). In other
3131 /// situations, it may correspond to a different file than the underlying file handle (if
3232 /// standard input is used with the `--assume-filename` flag), or it may not be a valid path at
3333 /// all (the string `"<stdin>"`).
34- let path : String
34+ let url : URL
3535
3636 /// The configuration that should applied for this file.
3737 let configuration : Configuration
@@ -46,9 +46,9 @@ class Frontend {
4646 return String ( data: sourceData, encoding: . utf8)
4747 } ( )
4848
49- init ( fileHandle: FileHandle , path : String , configuration: Configuration ) {
49+ init ( fileHandle: FileHandle , url : URL , configuration: Configuration ) {
5050 self . fileHandle = fileHandle
51- self . path = path
51+ self . url = url
5252 self . configuration = configuration
5353 }
5454 }
@@ -81,12 +81,12 @@ class Frontend {
8181
8282 /// Runs the linter or formatter over the inputs.
8383 final func run( ) {
84- let paths = lintFormatOptions. paths
85-
86- if paths. isEmpty {
84+ if lintFormatOptions. paths. isEmpty {
8785 processStandardInput ( )
8886 } else {
89- processPaths ( paths, parallel: lintFormatOptions. parallel)
87+ processURLs (
88+ lintFormatOptions. paths. map ( URL . init ( fileURLWithPath: ) ) ,
89+ parallel: lintFormatOptions. parallel)
9090 }
9191 }
9292
@@ -103,52 +103,55 @@ class Frontend {
103103 /// Processes source content from standard input.
104104 private func processStandardInput( ) {
105105 guard let configuration = configuration (
106- atPath : lintFormatOptions. configurationPath,
107- orInferredFromSwiftFileAtPath : nil )
106+ at : lintFormatOptions. configurationPath. map ( URL . init ( fileURLWithPath : ) ) ,
107+ orInferredFromSwiftFileAt : nil )
108108 else {
109109 // Already diagnosed in the called method.
110110 return
111111 }
112112
113113 let fileToProcess = FileToProcess (
114114 fileHandle: FileHandle . standardInput,
115- path : lintFormatOptions. assumeFilename ?? " <stdin> " ,
115+ url : URL ( fileURLWithPath : lintFormatOptions. assumeFilename ?? " <stdin> " ) ,
116116 configuration: configuration)
117117 processFile ( fileToProcess)
118118 }
119119
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 ) {
122122 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." )
125125
126126 if parallel {
127- let filesToProcess = FileIterator ( paths : paths ) . compactMap ( openAndPrepareFile)
127+ let filesToProcess = FileIterator ( urls : urls ) . compactMap ( openAndPrepareFile)
128128 DispatchQueue . concurrentPerform ( iterations: filesToProcess. count) { index in
129129 processFile ( filesToProcess [ index] )
130130 }
131131 } else {
132- FileIterator ( paths : paths ) . lazy. compactMap ( openAndPrepareFile) . forEach ( processFile)
132+ FileIterator ( urls : urls ) . lazy. compactMap ( openAndPrepareFile) . forEach ( processFile)
133133 }
134134 }
135135
136136 /// Read and prepare the file at the given path for processing, optionally synchronizing
137137 /// 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 " )
141142 return nil
142143 }
143144
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)
146149 else {
147150 // Already diagnosed in the called method.
148151 return nil
149152 }
150153
151- return FileToProcess ( fileHandle: sourceFile, path : path , configuration: configuration)
154+ return FileToProcess ( fileHandle: sourceFile, url : url , configuration: configuration)
152155 }
153156
154157 /// Returns the configuration that applies to the given `.swift` source file, when an explicit
@@ -164,14 +167,14 @@ class Frontend {
164167 /// `swiftFilePath` if one exists, or the default configuration otherwise. If an error occurred
165168 /// when reading the configuration, a diagnostic is emitted and `nil` is returned.
166169 private func configuration(
167- atPath configurationFilePath : String ? ,
168- orInferredFromSwiftFileAtPath swiftFilePath : String ?
170+ at configurationFileURL : URL ? ,
171+ orInferredFromSwiftFileAt swiftFileURL : URL ?
169172 ) -> Configuration ? {
170173 // If an explicit configuration file path was given, try to load it and fail if it cannot be
171174 // 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 {
173176 do {
174- return try configurationLoader. configuration ( atPath : configurationFilePath )
177+ return try configurationLoader. configuration ( at : configurationFileURL )
175178 } catch {
176179 diagnosticsEngine. emitError ( " Unable to read configuration: \( error. localizedDescription) " )
177180 return nil
@@ -180,17 +183,15 @@ class Frontend {
180183
181184 // If no explicit configuration file path was given but a `.swift` source file path was given,
182185 // 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 {
184187 do {
185- if let configuration =
186- try configurationLoader. configuration ( forSwiftFileAtPath: swiftFilePath)
187- {
188+ if let configuration = try configurationLoader. configuration ( forSwiftFileAt: swiftFileURL) {
188189 return configuration
189190 }
190191 // Fall through to the default return at the end of the function.
191192 } catch {
192193 diagnosticsEngine. emitError (
193- " Unable to read configuration for \( swiftFilePath ) : \( error. localizedDescription) " )
194+ " Unable to read configuration for \( swiftFileURL . path ) : \( error. localizedDescription) " )
194195 return nil
195196 }
196197 }
0 commit comments