Here's my suggestion, with one notable gap in it:
The file string will be in the following format:
file-string → module-name '/' directories(opt) file-name
module-name → identifier
directories → path-component '/' directories(opt)
file-name → path-suffix
identifier → [same as Swift identifier]
path-component → [all characters except slash and null]
'/' in this grammar, even on systems with a different path separator.
In current compilers, directories is always omitted. Future compilers may include some combination of directory names that appear in
#filePath to distinguish it from other files with the same file-name; the algorithm they will use to select these directory names is not specified by this proposal.
The hole is, of course, the last sentence. I haven't yet come up with a good way to decide which directories to include. ("Remove the common prefix" is not a good choice because, if your compile includes generated source files outside of the tree, you end up with very large prefixes containing much of the information we'd like to remove.)
Suggestions are welcome, or we can just punt on this question, or we can even decide that we'll never support this.
#filePath returns the exact string passed to
#file splits the
#filePath string on path separators, takes the last component, and combines it with the module name.
(This means that
#sourceLocation actually is a way you could introduce two "files" with the same file-name. That suggests that maybe we ought to specify and implement the algorithm for generating directories—or we could just emit a warning on
#sourceLocations that introduce conflicts. After all,
#sourceLocation already lets you do silly things like roll line numbers backwards.)