]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/d/dmd/dimport.d
Merge dmd, druntime ceff48bf7d, phobos dcbfbd43a
[thirdparty/gcc.git] / gcc / d / dmd / dimport.d
1 /**
2 * A `Dsymbol` representing a renamed import.
3 *
4 * Copyright: Copyright (C) 1999-2024 by The D Language Foundation, All Rights Reserved
5 * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright)
6 * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
7 * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dimport.d, _dimport.d)
8 * Documentation: https://dlang.org/phobos/dmd_dimport.html
9 * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/dimport.d
10 */
11
12 module dmd.dimport;
13
14 import dmd.arraytypes;
15 import dmd.dmodule;
16 import dmd.dsymbol;
17 import dmd.errors;
18 import dmd.identifier;
19 import dmd.location;
20 import dmd.visitor;
21
22 /***********************************************************
23 */
24 extern (C++) final class Import : Dsymbol
25 {
26 /* static import aliasId = pkg1.pkg2.id : alias1 = name1, alias2 = name2;
27 */
28 Identifier[] packages; // array of Identifier's representing packages
29 Identifier id; // module Identifier
30 Identifier aliasId;
31 int isstatic; // !=0 if static import
32 Visibility visibility;
33
34 // Pairs of alias=name to bind into current namespace
35 Identifiers names;
36 Identifiers aliases;
37
38 Module mod;
39 Package pkg; // leftmost package/module
40
41 // corresponding AliasDeclarations for alias=name pairs
42 AliasDeclarations aliasdecls;
43
44 extern (D) this(const ref Loc loc, Identifier[] packages, Identifier id, Identifier aliasId, int isstatic)
45 {
46 Identifier selectIdent()
47 {
48 // select Dsymbol identifier (bracketed)
49 if (aliasId)
50 {
51 // import [aliasId] = std.stdio;
52 return aliasId;
53 }
54 else if (packages.length > 0)
55 {
56 // import [std].stdio;
57 return packages[0];
58 }
59 else
60 {
61 // import [id];
62 return id;
63 }
64 }
65
66 super(loc, selectIdent());
67
68 assert(id);
69 version (none)
70 {
71 import core.stdc.stdio;
72
73 printf("Import::Import(");
74 foreach (id; packages)
75 {
76 printf("%s.", id.toChars());
77 }
78 printf("%s)\n", id.toChars());
79 }
80 this.packages = packages;
81 this.id = id;
82 this.aliasId = aliasId;
83 this.isstatic = isstatic;
84 this.visibility = Visibility.Kind.private_; // default to private
85 }
86
87 extern (D) void addAlias(Identifier name, Identifier _alias)
88 {
89 if (isstatic)
90 .error(loc, "%s `%s` cannot have an import bind list", kind, toPrettyChars);
91 if (!aliasId)
92 this.ident = null; // make it an anonymous import
93 names.push(name);
94 aliases.push(_alias);
95 }
96
97 override const(char)* kind() const
98 {
99 return isstatic ? "static import" : "import";
100 }
101
102 override Visibility visible() pure nothrow @nogc @safe
103 {
104 return visibility;
105 }
106
107 // copy only syntax trees
108 override Import syntaxCopy(Dsymbol s)
109 {
110 assert(!s);
111 auto si = new Import(loc, packages, id, aliasId, isstatic);
112 si.comment = comment;
113 for (size_t i = 0; i < names.length; i++)
114 {
115 si.addAlias(names[i], aliases[i]);
116 }
117 return si;
118 }
119
120 /*******************************
121 * Mark the imported packages as accessible from the current
122 * scope. This access check is necessary when using FQN b/c
123 * we're using a single global package tree.
124 * https://issues.dlang.org/show_bug.cgi?id=313
125 */
126 extern (D) void addPackageAccess(ScopeDsymbol scopesym)
127 {
128 //printf("Import::addPackageAccess('%s') %p\n", toPrettyChars(), this);
129 if (packages.length > 0)
130 {
131 // import a.b.c.d;
132 auto p = pkg; // a
133 scopesym.addAccessiblePackage(p, visibility);
134 foreach (id; packages[1 .. $]) // [b, c]
135 {
136 auto sym = p.symtab.lookup(id);
137 // https://issues.dlang.org/show_bug.cgi?id=17991
138 // An import of truly empty file/package can happen
139 // https://issues.dlang.org/show_bug.cgi?id=20151
140 // Package in the path conflicts with a module name
141 if (sym is null)
142 break;
143 // https://issues.dlang.org/show_bug.cgi?id=23327
144 // Package conflicts with symbol of the same name
145 p = sym.isPackage();
146 if (p is null)
147 break;
148 scopesym.addAccessiblePackage(p, visibility);
149 }
150 }
151 scopesym.addAccessiblePackage(mod, visibility); // d
152 }
153
154 override Dsymbol toAlias()
155 {
156 if (aliasId)
157 return mod;
158 return this;
159 }
160
161 override bool overloadInsert(Dsymbol s)
162 {
163 /* Allow multiple imports with the same package base, but disallow
164 * alias collisions
165 * https://issues.dlang.org/show_bug.cgi?id=5412
166 */
167 assert(ident && ident == s.ident);
168 Import imp;
169 if (!aliasId && (imp = s.isImport()) !is null && !imp.aliasId)
170 return true;
171 else
172 return false;
173 }
174
175 override inout(Import) isImport() inout
176 {
177 return this;
178 }
179
180 override void accept(Visitor v)
181 {
182 v.visit(this);
183 }
184 }