Import path normalization (path spec v3) #11411
Labels
breaking change ⚠️
closed due inactivity
The issue/PR was automatically closed due to inactivity.
low effort
There is not much implementation work to be done. The task is very easy or tiny.
medium impact
Default level of impact
stale
The issue/PR was marked as stale because it has been open for too long.
Projects
Closes #5146.
Related to #2738.
Part of a set of issues that replaces #11138.
Abstract
Compiler's virtual filesystem currently makes very little assumptions about source unit names. Nearly anything is allowed and different names that would refer to the same file in the actual filesystem are considered different. This is not intuitive to users who mostly expect import paths to work like paths in their filesystem.
This proposal introduces some preprocessing for import paths to better match user expectations while still preserving the rule that different keys in the VFS always represent different source units. It also forbids non-normalized source unit names in the VFS because it will no longer be possible to have imports that match them.
The new rules do not apply to import paths that look like URLs since these may have wildly different semantics depending on the protocol.
Motivation
Same file being compiled multiple times
One of the problems caused by allowing non-normalized paths is the compiler loading and compiling the same file multiple times. At best it just wastes resources. At worst it can lead to hard to understand errors caused by the compiler seeing duplicate definitions.
Unintuitive results of normalization in corner cases
Another reason is getting rid of the weird corner cases related to relative imports. Relative imports (i.e. imports starting with
./
or../
) are treated in a special way by the compiler. Unlike direct imports, relative imports undergo some minimal processing. The compiler takes the source unit name of the importing file, strips the number of path segments corresponding to the number of leading../
segments in the import path, normalizes the import path and then combines the two. The source unit name of the importing file is not normalized. This ensures that relative imports work properly when the importing file is identified with a URL.For example, assuming that you have a file with source unit name of
https://example.com/contract.sol
, containing:If the parent source unit name were to be normalized, the name would become
https:/example.com/token.sol
instead, which is not a valid URL.On the other hand, this leads to surprising results in corner cases. For example
../
segments are treated as normal path segments and get canceled by../
segments in the import path./project/./lib/contract.sol
:URLs
The reason behind exempting URLs from this is that in some schemes
./
and../
sequences might not represent path segments. We do not want to forbid such URLs but we also do not want to hard-code rules for each particular protocol into the compiler.For this reason even after this change it will still be possible to run into the unintuitive normalization mentioned above with e.g.
file://
orhttps://
URLs.file://
urls are not really recommended though and withhttps://
it's up to the server to interpret../
- if it happens to be a part of the URL, it might not really represent going up in the directory hierarachy so the proposed normalization would not necessarily be desirable for such URLs anyway.Specification
When converting an import path that does not have a
protocol://
prefix (whereprotocol
is an arbitrary URL protocol) into a source unit name:./
and../
segments../
and../
segments with the source unit name of the importing file.../
segments can be collapsed. E.g. forx/y/../../../contract.sol
or../x/../../contract.sol
.In the virtual filesystem disallow source unit names that do not have a
protocol://
prefix and contain:./
or../
segments.Backwards Compatibility
The change is not fully backwards-compatible:
import "a/../../b.sol"
will be disallowed. Currently it's a valid import../
and../
segments or consecutive slashes outside of URLs in Standard JSON will need adjustment.The text was updated successfully, but these errors were encountered: