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