Skip to content

Commit 8de575f

Browse files
authored
Merge pull request #11442 from ethereum/path-resolution-docs-current-state-v2
Path resolution docs (current state only) v2
2 parents e77e9e4 + 5e37888 commit 8de575f

File tree

4 files changed

+540
-111
lines changed

4 files changed

+540
-111
lines changed

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ Contents
165165
security-considerations.rst
166166
smtchecker.rst
167167
resources.rst
168+
path-resolution.rst
168169
yul.rst
169170
style-guide.rst
170171
common-patterns.rst

docs/layout-of-source-files.rst

Lines changed: 30 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ The component does not yet support all features of the Solidity language and
163163
likely outputs many warnings. In case it reports unsupported features, the
164164
analysis may not be fully sound.
165165

166-
.. index:: source file, ! import, module
166+
.. index:: source file, ! import, module, source unit
167167

168168
.. _import:
169169

@@ -184,6 +184,7 @@ At a global level, you can use import statements of the following form:
184184

185185
import "filename";
186186

187+
The ``filename`` part is called an *import path*.
187188
This statement imports all global symbols from "filename" (and symbols imported there) into the
188189
current global scope (different than in ES6 but backwards-compatible for Solidity).
189190
This form is not recommended for use, because it unpredictably pollutes the namespace.
@@ -216,101 +217,34 @@ the code below creates new global symbols ``alias`` and ``symbol2`` which refere
216217

217218
import {symbol1 as alias, symbol2} from "filename";
218219

219-
Paths
220-
-----
221-
222-
In the above, ``filename`` is always treated as a path with ``/`` as directory separator,
223-
and ``.`` as the current and ``..`` as the parent directory. When ``.`` or ``..`` is followed by a character except ``/``,
224-
it is not considered as the current or the parent directory.
225-
All path names are treated as absolute paths unless they start with the current ``.`` or the parent directory ``..``.
226-
227-
To import a file ``filename`` from the same directory as the current file, use ``import "./filename" as symbolName;``.
228-
If you use ``import "filename" as symbolName;`` instead, a different file could be referenced
229-
(in a global "include directory").
230-
231-
It depends on the compiler (see :ref:`import-compiler`) how to actually resolve the paths.
232-
In general, the directory hierarchy does not need to strictly map onto your local
233-
filesystem, and the path can also map to resources such as ipfs, http or git.
234-
235-
.. note::
236-
Always use relative imports like ``import "./filename.sol";`` and avoid
237-
using ``..`` in path specifiers. In the latter case, it is probably better to use
238-
global paths and set up remappings as explained below.
239-
240-
.. _import-compiler:
241-
242-
Use in Actual Compilers
243-
-----------------------
244-
245-
When invoking the compiler, you can specify how to discover the first element
246-
of a path, and also path prefix remappings. For
247-
example you can setup a remapping so that everything imported from the virtual
248-
directory ``github.com/ethereum/dapp-bin/library`` would actually be read from
249-
your local directory ``/usr/local/dapp-bin/library``.
250-
If multiple remappings apply, the one with the longest key is tried first.
251-
An empty prefix is not allowed. The remappings can depend on a context,
252-
which allows you to configure packages to import e.g., different versions of a
253-
library of the same name.
254-
255-
**solc**:
256-
257-
For solc (the commandline compiler), you provide these path remappings as
258-
``context:prefix=target`` arguments, where both the ``context:`` and the
259-
``=target`` parts are optional (``target`` defaults to ``prefix`` in this
260-
case). All remapping values that are regular files are compiled (including
261-
their dependencies).
262-
263-
This mechanism is backwards-compatible (as long
264-
as no filename contains ``=`` or ``:``) and thus not a breaking change. All
265-
files in or below the ``context`` directory that import a file that starts with
266-
``prefix`` are redirected by replacing ``prefix`` by ``target``.
267-
268-
For example, if you clone ``github.com/ethereum/dapp-bin/`` locally to
269-
``/usr/local/dapp-bin``, you can use the following in your source file:
270-
271-
::
272-
273-
import "github.com/ethereum/dapp-bin/library/iterable_mapping.sol" as it_mapping;
274-
275-
Then run the compiler:
276-
277-
.. code-block:: bash
278-
279-
solc github.com/ethereum/dapp-bin/=/usr/local/dapp-bin/ source.sol
280-
281-
As a more complex example, suppose you rely on a module that uses an old
282-
version of dapp-bin that you checked out to ``/usr/local/dapp-bin_old``, then you can run:
283-
284-
.. code-block:: bash
285-
286-
solc module1:github.com/ethereum/dapp-bin/=/usr/local/dapp-bin/ \
287-
module2:github.com/ethereum/dapp-bin/=/usr/local/dapp-bin_old/ \
288-
source.sol
289-
290-
This means that all imports in ``module2`` point to the old version but imports
291-
in ``module1`` point to the new version.
292-
293-
.. note::
294-
295-
``solc`` only allows you to include files from certain directories. They have
296-
to be in the directory (or subdirectory) of one of the explicitly specified
297-
source files or in the directory (or subdirectory) of a remapping target. If
298-
you want to allow direct absolute includes, add the remapping ``/=/``.
299-
300-
If there are multiple remappings that lead to a valid file, the remapping
301-
with the longest common prefix is chosen.
302-
303-
**Remix**:
304-
305-
`Remix <https://remix.ethereum.org/>`_ provides an automatic remapping for
306-
GitHub and automatically retrieves the file over the network. You can import
307-
the iterable mapping as above, e.g.
308-
309-
::
310-
311-
import "github.com/ethereum/dapp-bin/library/iterable_mapping.sol" as it_mapping;
312-
313-
Remix may add other source code providers in the future.
220+
.. index:: virtual filesystem, source unit name, import; path, filesystem path, import callback, Remix IDE
221+
222+
Import Paths
223+
------------
224+
225+
In order to be able to support reproducible builds on all platforms, the Solidity compiler has to
226+
abstract away the details of the filesystem where source files are stored.
227+
For this reason import paths do not refer directly to files in the host filesystem.
228+
Instead the compiler maintains an internal database (*virtual filesystem* or *VFS* for short) where
229+
each source unit is assigned a unique *source unit name* which is an opaque and unstructured identifier.
230+
The import path specified in an import statement is translated into a source unit name and used to
231+
find the corresponding source unit in this database.
232+
233+
Using the :ref:`Standard JSON <compiler-api>` API it is possible to directly provide the names and
234+
content of all the source files as a part of the compiler input.
235+
In this case source unit names are truly arbitrary.
236+
If, however, you want the compiler to automatically find and load source code into the VFS, your
237+
source unit names need to be structured in a way that makes it possible for an :ref:`import callback
238+
<import-callback>` to locate them.
239+
When using the command-line compiler the default import callback supports only loading source code
240+
from the host filesystem, which means that your source unit names must be paths.
241+
Some environments provide custom callbacks that are more versatile.
242+
For example the `Remix IDE <https://remix.ethereum.org/>`_ provides one that
243+
lets you `import files from HTTP, IPFS and Swarm URLs or refer directly to packages in NPM registry
244+
<https://remix-ide.readthedocs.io/en/latest/import.html>`_.
245+
246+
For a complete description of the virtual filesystem and the path resolution logic used by the
247+
compiler see :ref:`Path Resolution <path-resolution>`.
314248

315249
.. index:: ! comment, natspec
316250

0 commit comments

Comments
 (0)