Imports
The import
directive is used to import items from other Solidity files. This can be useful to
keep a single definition in one file, which can be used in multiple other files. For example,
you could have an interface in one source file, which several contracts implement or use
which are in other files. Solidity imports are somewhat similar to JavaScript ES6, however
there is no export statement, or default export.
The following items are always exported, which means they can be imported into another file.
global constants
struct definitions
enums definitions
event definitions
global functions
free standing functions
contracts, including abstract contract, libraries, and interfaces
There are a few different flavours of import. You can specify if you want everything imported, or just a select few items. You can also rename the imports. The following directive imports only foo and bar:
import {foo, bar} from "defines.sol";
Solang will look for the file defines.sol in the same directory as the current file. You can specify
more directories to search with the --importpath
commandline option.
Just like with ES6, import
is hoisted to the top and both foo and bar are usuable
even before the import
statement. It is also possible to import everything from
defines.sol by leaving the list out. Note that this is different than ES6, which would import nothing
with this syntax.
import "defines.sol";
Another method for locating files is using import maps. This maps the first directory
of an import path to a different location on the file system. Say you add
the command line option --importmap @openzeppelin=/opt/openzeppelin-contracts/contracts
, then
import "@openzeppelin/interfaces/IERC20.sol";
will automatically map to /opt/openzeppelin-contracts/contracts/interfaces/IERC20.sol.
Everything defined in defines.sol is now usable in your Solidity file. However, if an item with the same name is defined in defines.sol and also in the current file, you will get a warning. It is permitted to import the same file more than once.
It is also possible to rename an import. In this case, only item foo will be imported, and bar will be imported as baz. This is useful if you have already have a bar and you want to avoid a naming conflict.
import {bar as baz,foo} from "defines.sol";
Rather than renaming individual imports, it is also possible to make all the items in a file available under a special import object. In this case, the bar defined in defines.sol can is now visible as defs.bar, and foo as defs.foo. As long as there is no previous item defs, there can be no naming conflict.
import "defines.sol" as defs;
There is another syntax, which does exactly the same.
import * as defs from "defines.sol";