|
21 | 21 | import Foundation |
22 | 22 |
|
23 | 23 | public final class SourceManager { |
24 | | - private var sources: [String] |
25 | | - private var sourceIds: [String: UInt16] |
| 24 | + internal var sourceUrls: [URL] |
| 25 | + private var sourceIds: [URL: UInt16] |
26 | 26 |
|
27 | 27 | init() { |
28 | | - self.sources = ["console"] |
| 28 | + self.sourceUrls = [URL(string: "console")!] |
29 | 29 | self.sourceIds = [:] |
30 | 30 | } |
31 | 31 |
|
32 | 32 | public static let consoleSourceId: UInt16 = 0 |
33 | 33 | public static let unknownSourceId: UInt16 = UInt16.max |
34 | 34 |
|
| 35 | + public func sourceId(for url: URL) -> UInt16? { |
| 36 | + return self.sourceIds[self.absoluteUrl(url)] |
| 37 | + } |
| 38 | + |
35 | 39 | public func sourceId(for path: String) -> UInt16? { |
36 | | - return self.sourceIds[path] |
| 40 | + return self.sourceIds[self.absoluteUrl(path)] |
37 | 41 | } |
38 | 42 |
|
39 | 43 | public func obtainSourceId(for path: String) -> UInt16 { |
40 | | - if let id = self.sourceId(for: path) { |
| 44 | + return self.obtainSourceId(for: URL(fileURLWithPath: path)) |
| 45 | + } |
| 46 | + |
| 47 | + public func obtainSourceId(for url: URL) -> UInt16 { |
| 48 | + let canonicalUrl = self.absoluteUrl(url) |
| 49 | + if let id = self.sourceIds[canonicalUrl] { |
41 | 50 | return id |
42 | | - } else if self.sources.count == UInt16.max { |
| 51 | + } else if self.sourceUrls.count == UInt16.max { |
43 | 52 | return SourceManager.unknownSourceId |
44 | 53 | } else { |
45 | | - self.sources.append(path) |
46 | | - return UInt16(self.sources.count - 1) |
| 54 | + let newSourceId = UInt16(self.sourceUrls.count) |
| 55 | + self.sourceUrls.append(canonicalUrl) |
| 56 | + self.sourceIds[canonicalUrl] = newSourceId |
| 57 | + return newSourceId |
47 | 58 | } |
48 | 59 | } |
49 | 60 |
|
50 | | - public func sourcePath(for sourceId: UInt16) -> String? { |
| 61 | + public func sourceUrl(for sourceId: UInt16) -> URL? { |
51 | 62 | guard sourceId != SourceManager.unknownSourceId else { |
52 | 63 | return nil |
53 | 64 | } |
54 | | - return self.sources[Int(sourceId)] |
| 65 | + return self.sourceUrls[Int(sourceId)] |
55 | 66 | } |
56 | 67 |
|
57 | 68 | public func readSource(for sourceId: UInt16) throws -> String { |
58 | | - guard let sourcePath = self.sourcePath(for: sourceId) else { |
| 69 | + guard let sourceUrl = self.sourceUrl(for: sourceId) else { |
59 | 70 | throw EvalError.unknownFile("<path for source id = \(sourceId)>") |
60 | 71 | } |
61 | | - return try String(contentsOfFile: sourcePath, encoding: String.Encoding.utf8) |
| 72 | + return try String(contentsOf: sourceUrl) |
| 73 | + } |
| 74 | + |
| 75 | + public func readSource(for url: URL) throws -> String { |
| 76 | + return try self.readSource(for: self.obtainSourceId(for: url)) |
| 77 | + } |
| 78 | + |
| 79 | + public func readSource(for path: String) throws -> String { |
| 80 | + return try self.readSource(for: self.obtainSourceId(for: path)) |
| 81 | + } |
| 82 | + |
| 83 | + private func absoluteUrl(_ url: URL) -> URL { |
| 84 | + return url.standardizedFileURL.absoluteURL |
62 | 85 | } |
63 | 86 |
|
64 | | - public func readSource(for filepath: String) throws -> String { |
65 | | - return try self.readSource(for: self.obtainSourceId(for: filepath)) |
| 87 | + private func absoluteUrl(_ path: String) -> URL { |
| 88 | + return self.absoluteUrl(URL(fileURLWithPath: path)) |
66 | 89 | } |
67 | 90 | } |
0 commit comments