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