1
|
1
|
|
2 // Compiler implementation of the D programming language
|
|
3 // Copyright (c) 1999-2006 by Digital Mars
|
|
4 // All Rights Reserved
|
|
5 // written by Walter Bright
|
|
6 // http://www.digitalmars.com
|
|
7 // License for redistribution is by either the Artistic License
|
|
8 // in artistic.txt, or the GNU General Public License in gnu.txt.
|
|
9 // See the included readme.txt for details.
|
|
10
|
|
11 #include <stdio.h>
|
|
12 #include <assert.h>
|
|
13
|
|
14 #include "root.h"
|
|
15 #include "dsymbol.h"
|
|
16 #include "import.h"
|
|
17 #include "identifier.h"
|
|
18 #include "module.h"
|
|
19 #include "scope.h"
|
|
20 #include "hdrgen.h"
|
|
21 #include "mtype.h"
|
|
22 #include "declaration.h"
|
|
23 #include "id.h"
|
|
24
|
|
25 /********************************* Import ****************************/
|
|
26
|
|
27 Import::Import(Loc loc, Array *packages, Identifier *id, Identifier *aliasId,
|
|
28 int isstatic)
|
|
29 : Dsymbol(id)
|
|
30 {
|
|
31 this->loc = loc;
|
|
32 this->packages = packages;
|
|
33 this->id = id;
|
|
34 this->aliasId = aliasId;
|
|
35 this->isstatic = isstatic;
|
|
36 pkg = NULL;
|
|
37 mod = NULL;
|
|
38
|
|
39 if (aliasId)
|
|
40 this->ident = aliasId;
|
|
41 // Kludge to change Import identifier to first package
|
|
42 else if (packages && packages->dim)
|
|
43 this->ident = (Identifier *)packages->data[0];
|
|
44 }
|
|
45
|
|
46 void Import::addAlias(Identifier *name, Identifier *alias)
|
|
47 {
|
|
48 if (isstatic)
|
|
49 error("cannot have an import bind list");
|
|
50
|
|
51 if (!aliasId)
|
|
52 this->ident = NULL; // make it an anonymous import
|
|
53
|
|
54 names.push(name);
|
|
55 aliases.push(alias);
|
|
56 }
|
|
57
|
|
58 char *Import::kind()
|
|
59 {
|
|
60 return isstatic ? (char *)"static import" : (char *)"import";
|
|
61 }
|
|
62
|
|
63
|
|
64 Dsymbol *Import::syntaxCopy(Dsymbol *s)
|
|
65 {
|
|
66 assert(!s);
|
|
67
|
|
68 Import *si;
|
|
69
|
|
70 si = new Import(loc, packages, id, aliasId, isstatic);
|
|
71
|
|
72 for (size_t i = 0; i < names.dim; i++)
|
|
73 {
|
|
74 si->addAlias((Identifier *)names.data[i], (Identifier *)aliases.data[i]);
|
|
75 }
|
|
76
|
|
77 return si;
|
|
78 }
|
|
79
|
|
80 void Import::load(Scope *sc)
|
|
81 {
|
|
82 DsymbolTable *dst;
|
|
83 Dsymbol *s;
|
|
84
|
|
85 //printf("Import::load('%s')\n", toChars());
|
|
86
|
|
87 // See if existing module
|
|
88 dst = Package::resolve(packages, NULL, &pkg);
|
|
89
|
|
90 s = dst->lookup(id);
|
|
91 if (s)
|
|
92 {
|
|
93 if (s->isModule())
|
|
94 mod = (Module *)s;
|
|
95 else
|
|
96 error("package and module have the same name");
|
|
97 }
|
|
98
|
|
99 if (!mod)
|
|
100 {
|
|
101 // Load module
|
|
102 mod = Module::load(loc, packages, id);
|
|
103 dst->insert(id, mod); // id may be different from mod->ident,
|
|
104 // if so then insert alias
|
|
105 if (!mod->importedFrom)
|
|
106 mod->importedFrom = sc ? sc->module->importedFrom : Module::rootModule;
|
|
107 }
|
|
108 if (!pkg)
|
|
109 pkg = mod;
|
|
110 mod->semantic();
|
|
111
|
|
112 //printf("-Import::load('%s'), pkg = %p\n", toChars(), pkg);
|
|
113 }
|
|
114
|
|
115
|
|
116 void Import::semantic(Scope *sc)
|
|
117 {
|
|
118 //printf("Import::semantic('%s')\n", toChars());
|
|
119
|
|
120 load(sc);
|
|
121
|
|
122 if (mod)
|
|
123 {
|
|
124 #if 0
|
|
125 if (mod->loc.linnum != 0)
|
|
126 { /* If the line number is not 0, then this is not
|
|
127 * a 'root' module, i.e. it was not specified on the command line.
|
|
128 */
|
|
129 mod->importedFrom = sc->module->importedFrom;
|
|
130 assert(mod->importedFrom);
|
|
131 }
|
|
132 #endif
|
|
133
|
|
134 if (!isstatic && !aliasId && !names.dim)
|
|
135 {
|
|
136 /* Default to private importing
|
|
137 */
|
|
138 enum PROT prot = sc->protection;
|
|
139 if (!sc->explicitProtection)
|
|
140 prot = PROTprivate;
|
|
141 sc->scopesym->importScope(mod, prot);
|
|
142 }
|
|
143
|
|
144 // Modules need a list of each imported module
|
|
145 sc->module->aimports.push(mod);
|
|
146
|
|
147 if (mod->needmoduleinfo)
|
|
148 sc->module->needmoduleinfo = 1;
|
|
149
|
|
150 sc = sc->push(mod);
|
|
151 for (size_t i = 0; i < aliasdecls.dim; i++)
|
|
152 { Dsymbol *s = (Dsymbol *)aliasdecls.data[i];
|
|
153
|
|
154 //printf("\tImport alias semantic('%s')\n", s->toChars());
|
|
155 if (!mod->search(loc, (Identifier *)names.data[i], 0))
|
|
156 error("%s not found", ((Identifier *)names.data[i])->toChars());
|
|
157
|
|
158 s->semantic(sc);
|
|
159 }
|
|
160 sc = sc->pop();
|
|
161 }
|
|
162 //printf("-Import::semantic('%s'), pkg = %p\n", toChars(), pkg);
|
|
163 }
|
|
164
|
|
165 void Import::semantic2(Scope *sc)
|
|
166 {
|
|
167 //printf("Import::semantic2('%s')\n", toChars());
|
|
168 mod->semantic2();
|
|
169 if (mod->needmoduleinfo)
|
|
170 sc->module->needmoduleinfo = 1;
|
|
171 }
|
|
172
|
|
173 Dsymbol *Import::toAlias()
|
|
174 {
|
|
175 if (aliasId)
|
|
176 return mod;
|
|
177 return this;
|
|
178 }
|
|
179
|
|
180 int Import::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
|
|
181 {
|
|
182 int result = 0;
|
|
183
|
|
184 if (names.dim == 0)
|
|
185 return Dsymbol::addMember(sc, sd, memnum);
|
|
186
|
|
187 if (aliasId)
|
|
188 result = Dsymbol::addMember(sc, sd, memnum);
|
|
189
|
|
190 for (size_t i = 0; i < names.dim; i++)
|
|
191 {
|
|
192 Identifier *name = (Identifier *)names.data[i];
|
|
193 Identifier *alias = (Identifier *)aliases.data[i];
|
|
194
|
|
195 if (!alias)
|
|
196 alias = name;
|
|
197
|
|
198 #if 1
|
|
199 TypeIdentifier *tname = new TypeIdentifier(loc, name);
|
|
200 #else
|
|
201 TypeIdentifier *tname = new TypeIdentifier(loc, NULL);
|
|
202 if (packages)
|
|
203 {
|
|
204 for (size_t j = 0; j < packages->dim; j++)
|
|
205 { Identifier *pid = (Identifier *)packages->data[j];
|
|
206
|
|
207 if (!tname->ident)
|
|
208 tname->ident = pid;
|
|
209 else
|
|
210 tname->addIdent(pid);
|
|
211 }
|
|
212 }
|
|
213 if (!tname->ident)
|
|
214 tname->ident = id;
|
|
215 else
|
|
216 tname->addIdent(id);
|
|
217 tname->addIdent(name);
|
|
218 #endif
|
|
219 AliasDeclaration *ad = new AliasDeclaration(loc, alias, tname);
|
|
220 result |= ad->addMember(sc, sd, memnum);
|
|
221
|
|
222 aliasdecls.push(ad);
|
|
223 }
|
|
224
|
|
225 return result;
|
|
226 }
|
|
227
|
|
228 Dsymbol *Import::search(Loc loc, Identifier *ident, int flags)
|
|
229 {
|
|
230 //printf("%s.Import::search(ident = '%s', flags = x%x)\n", toChars(), ident->toChars(), flags);
|
|
231
|
|
232 if (!pkg)
|
|
233 load(NULL);
|
|
234
|
|
235 // Forward it to the package/module
|
|
236 return pkg->search(loc, ident, flags);
|
|
237 }
|
|
238
|
|
239 int Import::overloadInsert(Dsymbol *s)
|
|
240 {
|
|
241 // Allow multiple imports of the same name
|
|
242 return s->isImport() != NULL;
|
|
243 }
|
|
244
|
|
245 void Import::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
|
246 {
|
|
247 if (hgs->hdrgen && id == Id::object)
|
|
248 return; // object is imported by default
|
|
249
|
|
250 if (isstatic)
|
|
251 buf->writestring("static ");
|
|
252 buf->writestring("import ");
|
|
253 if (aliasId)
|
|
254 {
|
|
255 buf->printf("%s = ", aliasId->toChars());
|
|
256 }
|
|
257 if (packages && packages->dim)
|
|
258 {
|
|
259 for (size_t i = 0; i < packages->dim; i++)
|
|
260 { Identifier *pid = (Identifier *)packages->data[i];
|
|
261
|
|
262 buf->printf("%s.", pid->toChars());
|
|
263 }
|
|
264 }
|
|
265 buf->printf("%s;", id->toChars());
|
|
266 buf->writenl();
|
|
267 }
|
|
268
|