comparison dmd2/import.c @ 758:f04dde6e882c

Added initial D2 support, D2 frontend and changes to codegen to make things compile.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Tue, 11 Nov 2008 01:38:48 +0100
parents
children 356e65836fb5
comparison
equal deleted inserted replaced
757:2c730d530c98 758:f04dde6e882c
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 protection = PROTundefined;
37 pkg = NULL;
38 mod = NULL;
39
40 if (aliasId)
41 this->ident = aliasId;
42 // Kludge to change Import identifier to first package
43 else if (packages && packages->dim)
44 this->ident = (Identifier *)packages->data[0];
45 }
46
47 void Import::addAlias(Identifier *name, Identifier *alias)
48 {
49 if (isstatic)
50 error("cannot have an import bind list");
51
52 if (!aliasId)
53 this->ident = NULL; // make it an anonymous import
54
55 names.push(name);
56 aliases.push(alias);
57 }
58
59 const char *Import::kind()
60 {
61 return isstatic ? (char *)"static import" : (char *)"import";
62 }
63
64 enum PROT Import::prot()
65 {
66 return protection;
67 }
68
69 Dsymbol *Import::syntaxCopy(Dsymbol *s)
70 {
71 assert(!s);
72
73 Import *si;
74
75 si = new Import(loc, packages, id, aliasId, isstatic);
76
77 for (size_t i = 0; i < names.dim; i++)
78 {
79 si->addAlias((Identifier *)names.data[i], (Identifier *)aliases.data[i]);
80 }
81
82 return si;
83 }
84
85 void Import::load(Scope *sc)
86 {
87 DsymbolTable *dst;
88 Dsymbol *s;
89
90 //printf("Import::load('%s')\n", toChars());
91
92 // See if existing module
93 dst = Package::resolve(packages, NULL, &pkg);
94
95 s = dst->lookup(id);
96 if (s)
97 {
98 if (s->isModule())
99 mod = (Module *)s;
100 else
101 error("package and module have the same name");
102 }
103
104 if (!mod)
105 {
106 // Load module
107 mod = Module::load(loc, packages, id);
108 dst->insert(id, mod); // id may be different from mod->ident,
109 // if so then insert alias
110 if (!mod->importedFrom)
111 mod->importedFrom = sc ? sc->module->importedFrom : Module::rootModule;
112 }
113 if (!pkg)
114 pkg = mod;
115 mod->semantic();
116
117 //printf("-Import::load('%s'), pkg = %p\n", toChars(), pkg);
118 }
119
120
121 void Import::semantic(Scope *sc)
122 {
123 //printf("Import::semantic('%s')\n", toChars());
124
125 load(sc);
126
127 if (mod)
128 {
129 #if 0
130 if (mod->loc.linnum != 0)
131 { /* If the line number is not 0, then this is not
132 * a 'root' module, i.e. it was not specified on the command line.
133 */
134 mod->importedFrom = sc->module->importedFrom;
135 assert(mod->importedFrom);
136 }
137 #endif
138
139 /* Default to private importing
140 */
141 protection = sc->protection;
142 if (!sc->explicitProtection)
143 protection = PROTprivate;
144
145 if (!isstatic && !aliasId && !names.dim)
146 {
147 sc->scopesym->importScope(mod, protection);
148 }
149
150 // Modules need a list of each imported module
151 sc->module->aimports.push(mod);
152
153 if (mod->needmoduleinfo)
154 sc->module->needmoduleinfo = 1;
155
156 sc = sc->push(mod);
157 for (size_t i = 0; i < aliasdecls.dim; i++)
158 { AliasDeclaration *ad = (AliasDeclaration *)aliasdecls.data[i];
159
160 //printf("\tImport alias semantic('%s')\n", s->toChars());
161 if (!mod->search(loc, (Identifier *)names.data[i], 0))
162 error("%s not found", ((Identifier *)names.data[i])->toChars());
163
164 ad->semantic(sc);
165 ad->protection = protection;
166 }
167 sc = sc->pop();
168 }
169 //printf("-Import::semantic('%s'), pkg = %p\n", toChars(), pkg);
170 }
171
172 void Import::semantic2(Scope *sc)
173 {
174 //printf("Import::semantic2('%s')\n", toChars());
175 mod->semantic2();
176 if (mod->needmoduleinfo)
177 sc->module->needmoduleinfo = 1;
178 }
179
180 Dsymbol *Import::toAlias()
181 {
182 if (aliasId)
183 return mod;
184 return this;
185 }
186
187 int Import::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
188 {
189 int result = 0;
190
191 if (names.dim == 0)
192 return Dsymbol::addMember(sc, sd, memnum);
193
194 if (aliasId)
195 result = Dsymbol::addMember(sc, sd, memnum);
196
197 for (size_t i = 0; i < names.dim; i++)
198 {
199 Identifier *name = (Identifier *)names.data[i];
200 Identifier *alias = (Identifier *)aliases.data[i];
201
202 if (!alias)
203 alias = name;
204
205 #if 1
206 TypeIdentifier *tname = new TypeIdentifier(loc, name);
207 #else
208 TypeIdentifier *tname = new TypeIdentifier(loc, NULL);
209 if (packages)
210 {
211 for (size_t j = 0; j < packages->dim; j++)
212 { Identifier *pid = (Identifier *)packages->data[j];
213
214 if (!tname->ident)
215 tname->ident = pid;
216 else
217 tname->addIdent(pid);
218 }
219 }
220 if (!tname->ident)
221 tname->ident = id;
222 else
223 tname->addIdent(id);
224 tname->addIdent(name);
225 #endif
226 AliasDeclaration *ad = new AliasDeclaration(loc, alias, tname);
227 result |= ad->addMember(sc, sd, memnum);
228
229 aliasdecls.push(ad);
230 }
231
232 return result;
233 }
234
235 Dsymbol *Import::search(Loc loc, Identifier *ident, int flags)
236 {
237 //printf("%s.Import::search(ident = '%s', flags = x%x)\n", toChars(), ident->toChars(), flags);
238
239 if (!pkg)
240 load(NULL);
241
242 // Forward it to the package/module
243 return pkg->search(loc, ident, flags);
244 }
245
246 int Import::overloadInsert(Dsymbol *s)
247 {
248 // Allow multiple imports of the same name
249 return s->isImport() != NULL;
250 }
251
252 void Import::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
253 {
254 if (hgs->hdrgen && id == Id::object)
255 return; // object is imported by default
256
257 if (isstatic)
258 buf->writestring("static ");
259 buf->writestring("import ");
260 if (aliasId)
261 {
262 buf->printf("%s = ", aliasId->toChars());
263 }
264 if (packages && packages->dim)
265 {
266 for (size_t i = 0; i < packages->dim; i++)
267 { Identifier *pid = (Identifier *)packages->data[i];
268
269 buf->printf("%s.", pid->toChars());
270 }
271 }
272 buf->printf("%s;", id->toChars());
273 buf->writenl();
274 }
275