You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Each Dart file (library file or part file) defines a combined import scope
which combines the combined import scope of its parent file with its own
imports and import prefixes. The combined import scope of a dart files is
defined as:
Let C be the combined import scope of the parent file, or an empty scope
if the current file is a library file.
Let I be a scope containing all the imported declarations of all
non-prefixed import directives of the current file. The parent scope of I is C.
The import scope are computed the same way as for a pre-feature
library. The implicit import of dart:core only applies to the
library file. As usual, it’s a compile-time error if any import‘s
target URI does not resolve to a valid Dart library file.
Let’s introduce importsOf(S), where S is a set of import
directives from a single Dart file, to refer to that computation, which
introduces a scope containing the declarations introduced by all the import s (the declarations of the export scope of each imported
library, minus those hidden by a show or hide operator, combined
such that a name conflicts of different declarations is not an error,
but the name is marked as conflicted in the scope, and then referencing
it is an error.)
Let P be a prefix scope containing all the import prefixes declared by
the current file. The parent scope of P is I.
The P scope contains an entry for each name where the current file
has an import directive with that name as prefix, as name. (If an
import is deferred, it’s a compile-time error if more than one import directive in the same file has that prefix name, as usual. It’s not an error if two import deferred prefixes have the same name
if they occur in different files, other file’s imports are only
suggestions.)
The P scope binds each such name to a prefix import scope, Pname, computed as importsOf(Sname)
where Sname is the set of import directives with that
prefix name.
If an import is deferred, its Pname is a deferred
scope which has an extra loadLibrary member added, as usual, and the
import has an implicit hide loadLibrary modifier.
If Pname is not deferred, and the parent scope in C
has a non-deferred prefix import scope with the same name, Cname, then the parent scope of Pname is Cname. A part file can use the same prefix as a prefix
that it inherits, because inherited imports are only suggestions. If it
adds to that import scope, by importing into it, that can shadow
existing declarations, just like in the top-level declaration scope. A
deferred prefix import scope cannot be extended, and cannot extend
another prefix scope, deferred prefix scopes are always linked to a
single import directive.
It’s possible to look further up in the import chain C for a prefix
scope to extend. Here it’s chosen that that importing parent file gets
to decide which names the part file has access to. If it wants to make
a transitive parent import prefix available, it should just not shadow
it.
The commentary "It’s not an error if two import deferred prefixes have the same name if they occur in different files, other file’s imports are only suggestions" seems to imply that we can have the following:
Given that this is not an error, we would presumably have a situation where p in part2 shadows p in part1, which in turn shadows p in main. No errors, those deferred imports in parents are simply shadowed away.
However, if the import isn't deferred then we have a different situation:
With this setup, the bindings available for the prefix p in part2 are all the names from other_lib2 plus all the names that aren't already taken from other_lib1 plus all the names that aren't already taken from other_lib.
These approaches are surprisingly different. Is this what we want?
Another possibility would be to simply say that it is an error for the file tree that constitutes a library if, globally, any deferred library prefix has the same name as any other library prefix (deferred or not).
@dart-lang/language-team, WDYT?
The text was updated successfully, but these errors were encountered:
What is specified is what I want, unsurprisingly 😁.
Deferred imports are really singletons, living by themselves.
That's what the current rule of "no two imports with the same name if any of them are deferred" means. The unit of deferred loading is a single import statement. A single library to be loaded deferredly.
They do not combine with other import prefixes.
We don't know, and haven't needed to say, whether the error would be that you can't deferred-load two libraries, or that two deferred imports with the same name would count as a name clash, beause each introduce a name independently.
This is generalized here to having imports in multiple scopes, using the latter interpretation. Each deferred import is a stand-alone declaration, not combining with anything else, but there is only a name clash if two are declared in the same file. Otherwise it's just shadowing as normal, they shadow any inherited import with the same name, including any inherited import prefix with the same name.
Where a non-deferred prefixed import would use an inherited (non-deferred) prefix with the same name as parent scope, the deferred import just doesn't do that. That's the only difference. One-prefix, one library.
Another possibility would be to simply say that it is an error for the file tree that constitutes a library if, globally, any deferred library prefix has the same name as any other library prefix (deferred or not).
Since you can always rename prefixes, that wouldn't restrict what you can do, only what you can name it.
It's not impossible. I don't see a strong need for it.
I think it would feel fairly annoying if a deferred import prefix in one part file conflicts with a prefix import in an unrelated sibling/cousin-third-removed part file, when neither file can see the names of the other.
If we make a restriction (again, don't think it's needed), I'd only make it an error to have an import prefix and a deferred prefix with the same name if one actually shadows the other, that is if one of them is in the combined import scope of the parent file of the declaration of the other.
If you can't see the other name, it's not a confict.
Or, at a minimum, the two should be on the same part of path to the library file, so one could potentially see the other, if it hasn't been shadowed on the way.
The feature specification on parts with imports contains the following scope description:
The commentary "It’s not an error if two import deferred prefixes have the same name if they occur in different files, other file’s imports are only suggestions" seems to imply that we can have the following:
Given that this is not an error, we would presumably have a situation where
p
inpart2
shadowsp
inpart1
, which in turn shadowsp
inmain
. No errors, those deferred imports in parents are simply shadowed away.However, if the import isn't deferred then we have a different situation:
With this setup, the bindings available for the prefix
p
inpart2
are all the names fromother_lib2
plus all the names that aren't already taken fromother_lib1
plus all the names that aren't already taken fromother_lib
.These approaches are surprisingly different. Is this what we want?
Another possibility would be to simply say that it is an error for the file tree that constitutes a library if, globally, any deferred library prefix has the same name as any other library prefix (deferred or not).
@dart-lang/language-team, WDYT?
The text was updated successfully, but these errors were encountered: