Hi All,
Before I start, Im new to open source and to process, so please forgive me if I post a wrong question at wrong place. If Im wrong I would appreciate if you guys point me to the right direction.
Im trying to see if I can fix this issue, [SR-7715] FileManager.DirectoryEnumerator from enumerator(at:includingPropertiesForKeys:options:errorHandler:) enumerates Any instead of URL · Issue #3704 · apple/swift-corelibs-foundation · GitHub. After going through the code, these are my observations,
FileManager.DirectoryEnumerator
is a subclass of NSEnumerator
. The super class implementation returns Any
when the iteration calls nextObject()
method. Which is why in for
or while
loops we are getting the superclass's return type Any
.
The challenge, as far as I see, is making the DirectoryEnumerator
a generic type. The reason we would want generic type is because we are using the same class in two place,
enumerator(at:includingPropertiesForKeys:options:errorHandler:)
enumerator(atPath:)
So if we were to find a solution for this issue, then the solution should be of generic approach.
This is what Im thinking,
One way to improve the API is by not inheriting DirectoryEnumerator
from NSEnumerator
. This way DirectoryEnumerator
class is not limited by it superclass. This gives advantage to convert the DirectoryEnumerator
into a generic class.
extension FileManager {
open class DirectoryEnumerator<T>: Sequence {
public typealias EnumeratorElement = T
public struct Iterator : IteratorProtocol {
let enumerator : DirectoryEnumerator<T>
public func next() -> Any? {
return enumerator.nextObject()
}
}
public func makeIterator() -> Iterator {
return Iterator(enumerator: self)
}
open func nextObject() -> EnumeratorElement? {
NSRequiresConcreteImplementation()
}
}
internal class NSPathDirectoryEnumerator: DirectoryEnumerator<String> {
let innerEnumerator : DirectoryEnumerator<URL>
override func nextObject() -> EnumeratorElement? {
// return path which is String type
}
}
internal class NSURLDirectoryEnumerator : DirectoryEnumerator<URL> {
override func nextObject() -> EnumeratorElement? {
// return URL type
}
}
}
The methods return the will be updated in FileManager
.
class FileManager: NSObject {
open func enumerator(atPath path: String) -> DirectoryEnumerator<String>? {
return NSPathDirectoryEnumerator(path: path)
}
open func enumerator(at url: URL, includingPropertiesForKeys keys: [URLResourceKey]?, options mask: DirectoryEnumerationOptions = [], errorHandler handler: (/* @escaping */ (URL, Error) -> Bool)? = nil) -> DirectoryEnumerator<URL>? {
return NSURLDirectoryEnumerator(url: url, options: mask, errorHandler: handler)
}
}
Please let me know if this is correct approach to solve this bug.