ImportDeclaration ::= Attribute* "import" (ImportSelection | ImportModuleList) ";"
ImportModuleList ::= (TypeIdentifier ",")* TypeIdentifier?
ImportSelection ::= TypeIdentifier ("," TypeIdentifier)* "in" TypeIdentifier
An import gives access to declarations located in foreign units.
Each foreign unit is specified using a TypeIdentifier that matches to the UnitDeclaration and the physical path of the foreign unit.
Matching units are resolved this way
An import creates a regular scoped symbol that can be optionally used to fully qualify the foreign symbols.
In the same way, imports declared in an import can be fully qualified
but only if they are public.
Because imports create regular symbols, other declarations can conflict with them
These symbols take for name the first identifier of the chain.
The symbols matching to the root of an import dont conflict between themselves
unit b;
import a.b, a.c; // "a" can be redeclared, it is always the same root unit
var s32 a; // error, "a" already declared
They dont create conflict even if located directly in the matching root
The relationship between root and child units only exists in the symbols created for the imports, not directly in the units.
This is for example why this
unit unrelated;
import a; // does not leak "a.b" declarations.
alias C = B; // error, cannot solve type "B"
or that
does not compile.
An import can be used to restrict the set of symbols that can be accessed without qualifier.
In this case the TypeIdentifiers located in the list located before in
must be composed of single Identifiers.
They represent the selection for which unqualified searches in the import work.
unit c;
import g in a;
import f in b;
alias fb = f; // select `f` from `b` as `f` from `a` is not allowed in an unqualified search.
The selection has to represent valid symbols.
The selection does not prevent to pick fully qualified symbols
unit c;
import left in a;
function test()
{
left(); // ok, unqualified and specified in "a" selections
right(); // not ok, it is not specified in "a" selections
a.right(); // ok, not in "a" selection but fully qualified,
// hence, no conflict possible
}
Cycles between two units are allowed if at least one of the involved import declaration is @private
, or specifies a selection, or is nested in a sub scope (function body, aggregate body, etc.).
Otherwise the cycle is considered as an error