Skip to content

Commit 1da3d87

Browse files
committed
fix Issue 13855 - multi-module selective import statements
- allow to add further `mod : sym1, sym2` blocks to import statement - only allow non-ambiguous variations (requiring look-ahead of 2 tokens)
1 parent 97e51d1 commit 1da3d87

5 files changed

Lines changed: 47 additions & 1 deletion

File tree

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Allow multiple selective imports from different modules in a single import statement
2+
3+
It is now possible to add imports from a different module after a selective
4+
import list, when those import are also selective or when the imported module
5+
has a qualified name.
6+
7+
-------
8+
import pkg.mod1 : sym1, mod2 : sym2;
9+
import pkg.mod1 : sym1, sym2, pkg.mod2;
10+
-------
11+
12+
Unqualified modules or renamed imports following a selective import will be
13+
parsed as part of the selective import list, not as separate modules.
14+
15+
-------
16+
import pkg.mod1 : sym1, mod2; // selectively imports mod2 from pkg.mod1
17+
import pkg.mod1 : sym1, name=mod2; // selectively imports mod2 as name from pkg.mod1
18+
import pkg.mod1 : sym1, name=pkg1.mod1; // parsing renamed selective imports fails due to qualfier
19+
-------

src/dmd/parse.d

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3282,9 +3282,15 @@ final class Parser(AST) : Lexer
32823282
_alias = null;
32833283
}
32843284
s.addAlias(name, _alias);
3285+
if (token.value != TOKcomma)
3286+
break;
3287+
// recognize import pkg.mod1 : a, b, pkg.mod2;
3288+
immutable afterIdent = peekNext2;
3289+
if (peekNext2 == TOKdot || // pkg . mod2
3290+
peekNext2 == TOKcolon) // mod2 : c
3291+
break; // parse another import
32853292
}
32863293
while (token.value == TOKcomma);
3287-
break; // no comma-separated imports of this form
32883294
}
32893295
aliasid = null;
32903296
}

test/compilable/enh13855.d

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import imports.pkg313.c313 : bug, imports.c314 : bug; // previously 2 import statements
2+
import imports.pkg313.c313 : bug, imports.c314; // also allows qualified module w/o selective import
3+
import imports.c314, imports.pkg313.c313 : bug; // unchanged

test/fail_compilation/enh13855a.d

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/*
2+
TEST_OUTPUT:
3+
----
4+
fail_compilation/enh13855a.d(7): Error: module imports.c314 import 'enh13855a' not found
5+
----
6+
*/
7+
import imports.c314 : bug, enh13855a; // unqualified module would be ambiguous, parsed as symbol
8+
import enh13855a, imports.c314 : bug; // works unchanged

test/fail_compilation/enh13855b.d

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/*
2+
REQUIRED_ARGS: -vcolumns
3+
TEST_OUTPUT:
4+
----
5+
fail_compilation/enh13855b.d(9,47): Error: ';' expected
6+
fail_compilation/enh13855b.d(9,52): Error: no identifier for declarator c314
7+
----
8+
*/
9+
import imports.pkg313.c313 : bug, name=imports.c314; // aliased module would require arbitrary lookahead
10+
import name=imports.c314, imports.pkg313.c313 : bug; // works, unchanged

0 commit comments

Comments
 (0)