comparison dmd/import.c @ 1:c53b6e3fe49a trunk

[svn r5] Initial commit. Most things are very rough.
author lindquist
date Sat, 01 Sep 2007 21:43:27 +0200
parents
children aaade6ded589
comparison
equal deleted inserted replaced
0:a9e71648e74d 1:c53b6e3fe49a
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