0
|
1 module dmd.Import;
|
|
2
|
|
3 import dmd.Dsymbol;
|
|
4 import dmd.Array;
|
|
5 import dmd.DsymbolTable;
|
|
6 import dmd.PROT;
|
|
7 import dmd.Identifier;
|
|
8 import dmd.Module;
|
|
9 import dmd.Package;
|
|
10 import dmd.Loc;
|
|
11 import dmd.OutBuffer;
|
|
12 import dmd.HdrGenState;
|
|
13 import dmd.Scope;
|
|
14 import dmd.TypeIdentifier;
|
|
15 import dmd.AliasDeclaration;
|
|
16 import dmd.ScopeDsymbol;
|
|
17 import dmd.StorageClassDeclaration;
|
|
18 import dmd.STC;
|
|
19 import dmd.ProtDeclaration;
|
|
20 import dmd.Global;
|
|
21
|
|
22 import std.stdio;
|
|
23
|
|
24 void escapePath(OutBuffer buf, string fname)
|
|
25 {
|
|
26 foreach (char c; fname)
|
|
27 {
|
|
28 switch (c)
|
|
29 {
|
|
30 case '(':
|
|
31 case ')':
|
|
32 case '\\':
|
|
33 buf.writebyte('\\');
|
|
34 default:
|
|
35 buf.writebyte(*fname);
|
|
36 break;
|
|
37 }
|
|
38 }
|
|
39 }
|
|
40
|
|
41 class Import : Dsymbol
|
|
42 {
|
|
43 Array packages; // array of Identifier's representing packages
|
|
44 Identifier id; // module Identifier
|
|
45 Identifier aliasId;
|
|
46 int isstatic; // !=0 if static import
|
|
47
|
|
48 // Pairs of alias=name to bind into current namespace
|
|
49 Array names;
|
|
50 Array aliases;
|
|
51
|
|
52 Array aliasdecls; // AliasDeclarations for names/aliases
|
|
53
|
|
54 Module mod;
|
|
55 Package pkg; // leftmost package/module
|
|
56
|
|
57 this(Loc loc, Array packages, Identifier id, Identifier aliasId, int isstatic)
|
|
58 {
|
|
59 super(id);
|
|
60
|
|
61 names = new Array();
|
|
62 aliases = new Array();
|
|
63 aliasdecls = new Array();
|
|
64
|
|
65 assert(id);
|
|
66 this.loc = loc;
|
|
67 this.packages = packages;
|
|
68 this.id = id;
|
|
69 this.aliasId = aliasId;
|
|
70 this.isstatic = isstatic;
|
|
71
|
|
72 if (aliasId)
|
|
73 this.ident = aliasId;
|
|
74 // Kludge to change Import identifier to first package
|
|
75 else if (packages && packages.dim)
|
|
76 this.ident = cast(Identifier)packages.data[0];
|
|
77 }
|
|
78
|
|
79 void addAlias(Identifier name, Identifier alias_)
|
|
80 {
|
|
81 if (isstatic)
|
|
82 error("cannot have an import bind list");
|
|
83
|
|
84 if (!aliasId)
|
|
85 this.ident = null; // make it an anonymous import
|
|
86
|
|
87 names.push(cast(void*)name);
|
|
88 aliases.push(cast(void*)alias_);
|
|
89 }
|
|
90
|
|
91 string kind()
|
|
92 {
|
|
93 return isstatic ? "static import" : "import";
|
|
94 }
|
|
95
|
|
96 Dsymbol syntaxCopy(Dsymbol s) // copy only syntax trees
|
|
97 {
|
|
98 assert(false);
|
|
99 }
|
|
100
|
|
101 void load(Scope sc)
|
|
102 {
|
|
103 DsymbolTable dst;
|
|
104 Dsymbol s;
|
|
105
|
|
106 //writef("Import::load('%s')\n", toChars());
|
|
107
|
|
108 // See if existing module
|
|
109 dst = Package.resolve(packages, null, &pkg);
|
|
110
|
|
111 s = dst.lookup(id);
|
|
112 if (s)
|
|
113 {
|
|
114 version (TARGET_NET) {
|
|
115 mod = cast(Module)s;
|
|
116 } else {
|
|
117 if (s.isModule())
|
|
118 mod = cast(Module)s;
|
|
119 else
|
|
120 error("package and module have the same name");
|
|
121 }
|
|
122 }
|
|
123
|
|
124 if (!mod)
|
|
125 {
|
|
126 // Load module
|
|
127 mod = Module.load(loc, packages, id);
|
|
128 dst.insert(id, mod); // id may be different from mod->ident,
|
|
129 // if so then insert alias
|
|
130 if (!mod.importedFrom)
|
|
131 mod.importedFrom = sc ? sc.module_.importedFrom : Module.rootModule;
|
|
132 }
|
|
133
|
|
134 if (!pkg)
|
|
135 pkg = mod;
|
|
136
|
|
137 //writef("-Import::load('%s'), pkg = %p\n", toChars(), pkg);
|
|
138 }
|
|
139
|
|
140 void semantic(Scope sc)
|
|
141 {
|
|
142 //writef("Import.semantic('%s')\n", toChars());
|
|
143
|
|
144 load(sc);
|
|
145
|
|
146 if (mod)
|
|
147 {
|
|
148 static if (false) {
|
|
149 if (mod.loc.linnum != 0)
|
|
150 { /* If the line number is not 0, then this is not
|
|
151 * a 'root' module, i.e. it was not specified on the command line.
|
|
152 */
|
|
153 mod.importedFrom = sc.module_.importedFrom;
|
|
154 assert(mod.importedFrom);
|
|
155 }
|
|
156 }
|
|
157
|
|
158 // Modules need a list of each imported module
|
|
159 //printf("%s imports %s\n", sc.module.toChars(), mod.toChars());
|
|
160 sc.module_.aimports.push(cast(void*)mod);
|
|
161
|
|
162 if (!isstatic && !aliasId && !names.dim)
|
|
163 {
|
|
164 /* Default to private importing
|
|
165 */
|
|
166 PROT prot = sc.protection;
|
|
167 if (!sc.explicitProtection)
|
|
168 prot = PROT.PROTprivate;
|
|
169
|
|
170 sc.scopesym.importScope(mod, prot);
|
|
171 }
|
|
172
|
|
173 mod.semantic();
|
|
174
|
|
175 if (mod.needmoduleinfo)
|
|
176 sc.module_.needmoduleinfo = 1;
|
|
177
|
|
178 sc = sc.push(mod);
|
|
179 for (size_t i = 0; i < aliasdecls.dim; i++)
|
|
180 {
|
|
181 Dsymbol s = cast(Dsymbol)aliasdecls.data[i];
|
|
182
|
|
183 //writef("\tImport alias semantic('%s')\n", s.toChars());
|
|
184 if (!mod.search(loc, cast(Identifier)names.data[i], 0))
|
|
185 error("%s not found", (cast(Identifier)names.data[i]).toChars());
|
|
186
|
|
187 s.semantic(sc);
|
|
188 }
|
|
189 sc = sc.pop();
|
|
190 }
|
|
191
|
|
192 if (global.params.moduleDeps !is null)
|
|
193 {
|
|
194 /* The grammar of the file is:
|
|
195 * ImportDeclaration
|
|
196 * .= BasicImportDeclaration [ " : " ImportBindList ] [ " . "
|
|
197 * ModuleAliasIdentifier ] "\n"
|
|
198 *
|
|
199 * BasicImportDeclaration
|
|
200 * .= ModuleFullyQualifiedName " (" FilePath ") : " Protection
|
|
201 * " [ " static" ] : " ModuleFullyQualifiedName " (" FilePath ")"
|
|
202 *
|
|
203 * FilePath
|
|
204 * - any string with '(', ')' and '\' escaped with the '\' character
|
|
205 */
|
|
206
|
|
207 OutBuffer ob = global.params.moduleDeps;
|
|
208
|
|
209 ob.writestring(sc.module_.toPrettyChars());
|
|
210 ob.writestring(" (");
|
|
211 escapePath(ob, sc.module_.srcfile.toChars());
|
|
212 ob.writestring(") : ");
|
|
213
|
|
214 ProtDeclaration.protectionToCBuffer(ob, sc.protection);
|
|
215 if (isstatic)
|
|
216 StorageClassDeclaration.stcToCBuffer(ob, STC.STCstatic);
|
|
217 ob.writestring(": ");
|
|
218
|
|
219 if (packages)
|
|
220 {
|
|
221 for (size_t i = 0; i < packages.dim; i++)
|
|
222 {
|
|
223 Identifier pid = cast(Identifier)packages.data[i];
|
|
224 ob.printf("%s.", pid.toChars());
|
|
225 }
|
|
226 }
|
|
227
|
|
228 ob.writestring(id.toChars());
|
|
229 ob.writestring(" (");
|
|
230 if (mod)
|
|
231 escapePath(ob, mod.srcfile.toChars());
|
|
232 else
|
|
233 ob.writestring("???");
|
|
234 ob.writebyte(')');
|
|
235
|
|
236 for (size_t i = 0; i < names.dim; i++)
|
|
237 {
|
|
238 if (i == 0)
|
|
239 ob.writebyte(':');
|
|
240 else
|
|
241 ob.writebyte(',');
|
|
242
|
|
243 Identifier name = cast(Identifier)names.data[i];
|
|
244 Identifier alias_ = cast(Identifier)aliases.data[i];
|
|
245
|
|
246 if (!alias_)
|
|
247 {
|
|
248 ob.printf("%s", name.toChars());
|
|
249 alias_ = name;
|
|
250 }
|
|
251 else
|
|
252 ob.printf("%s=%s", alias_.toChars(), name.toChars());
|
|
253 }
|
|
254
|
|
255 if (aliasId)
|
|
256 ob.printf(" . %s", aliasId.toChars());
|
|
257
|
|
258 ob.writenl();
|
|
259 }
|
|
260
|
|
261 //printf("-Import.semantic('%s'), pkg = %p\n", toChars(), pkg);
|
|
262 }
|
|
263
|
|
264 void semantic2(Scope sc)
|
|
265 {
|
|
266 //printf("Import::semantic2('%s')\n", toChars());
|
|
267 mod.semantic2();
|
|
268 if (mod.needmoduleinfo)
|
|
269 sc.module_.needmoduleinfo = 1;
|
|
270 }
|
|
271
|
|
272 Dsymbol toAlias()
|
|
273 {
|
|
274 if (aliasId)
|
|
275 return mod;
|
|
276 return this;
|
|
277 }
|
|
278
|
|
279 /*****************************
|
|
280 * Add import to sd's symbol table.
|
|
281 */
|
13
|
282 bool addMember(Scope sc, ScopeDsymbol sd, bool memnum)
|
0
|
283 {
|
|
284 bool result = false;
|
|
285
|
|
286 if (names.dim == 0)
|
|
287 return Dsymbol.addMember(sc, sd, memnum);
|
|
288
|
|
289 if (aliasId)
|
|
290 result = Dsymbol.addMember(sc, sd, memnum);
|
|
291
|
|
292 /* Instead of adding the import to sd's symbol table,
|
|
293 * add each of the alias=name pairs
|
|
294 */
|
|
295 for (size_t i = 0; i < names.dim; i++)
|
|
296 {
|
|
297 Identifier name = cast(Identifier)names.data[i];
|
|
298 Identifier alias_ = cast(Identifier)aliases.data[i];
|
|
299
|
|
300 if (!alias_)
|
|
301 alias_ = name;
|
|
302
|
|
303 TypeIdentifier tname = new TypeIdentifier(loc, name);
|
|
304 AliasDeclaration ad = new AliasDeclaration(loc, alias_, tname);
|
|
305 result |= ad.addMember(sc, sd, memnum);
|
|
306
|
|
307 aliasdecls.push(cast(void*)ad);
|
|
308 }
|
|
309
|
|
310 return result;
|
|
311 }
|
|
312
|
|
313 Dsymbol search(Loc loc, Identifier ident, int flags)
|
|
314 {
|
|
315 //printf("%s.Import.search(ident = '%s', flags = x%x)\n", toChars(), ident.toChars(), flags);
|
|
316
|
|
317 if (!pkg)
|
|
318 {
|
|
319 load(null);
|
|
320 mod.semantic();
|
|
321 }
|
|
322
|
|
323 // Forward it to the package/module
|
|
324 return pkg.search(loc, ident, flags);
|
|
325 }
|
|
326
|
|
327 bool overloadInsert(Dsymbol s)
|
|
328 {
|
|
329 // Allow multiple imports of the same name
|
|
330 return s.isImport() !is null;
|
|
331 }
|
|
332
|
|
333 void toCBuffer(OutBuffer buf, HdrGenState* hgs)
|
|
334 {
|
|
335 assert(false);
|
|
336 }
|
|
337
|
|
338 Import isImport() { return this; }
|
|
339 } |