Mercurial > projects > ddmd
comparison dmd/TraitsExp.d @ 179:cd48cb899aee
Updated to dmd2.040
author | korDen |
---|---|
date | Sun, 17 Oct 2010 20:56:07 +0400 |
parents | e3afd1303184 |
children | b0d41ff5e0df |
comparison
equal
deleted
inserted
replaced
178:e3afd1303184 | 179:cd48cb899aee |
---|---|
37 | 37 |
38 import core.stdc.string : strcmp; | 38 import core.stdc.string : strcmp; |
39 | 39 |
40 /************************************************ | 40 /************************************************ |
41 * Delegate to be passed to overloadApply() that looks | 41 * Delegate to be passed to overloadApply() that looks |
42 * for virtual functions. | 42 * for functions matching a trait. |
43 */ | 43 */ |
44 | 44 |
45 struct Pvirtuals | 45 struct Ptrait |
46 { | 46 { |
47 Expression e1; | 47 Expression e1; |
48 Expressions exps; | 48 Expressions exps; // collected results |
49 Identifier ident; // which trait we're looking for | |
49 | 50 |
50 bool visit(FuncDeclaration f) | 51 bool visit(FuncDeclaration f) |
51 { | 52 { |
52 Pvirtuals* p = &this; | 53 if (ident == Id.getVirtualFunctions && !f.isVirtual()) |
53 | 54 return false; |
54 if (f.isVirtual()) | 55 |
55 { | 56 Expression e; |
56 Expression e; | 57 |
57 | 58 if (e1.op == TOKdotvar) |
58 if (p.e1.op == TOKdotvar) | 59 { |
59 { | 60 DotVarExp dve = cast(DotVarExp)e1; |
60 DotVarExp dve = cast(DotVarExp)p.e1; | 61 e = new DotVarExp(Loc(0), dve.e1, f); |
61 e = new DotVarExp(Loc(0), dve.e1, f); | 62 } |
62 } | 63 else |
63 else | 64 e = new DsymbolExp(Loc(0), f); |
64 e = new DsymbolExp(Loc(0), f); | 65 exps.push(e); |
65 p.exps.push(e); | 66 |
66 } | |
67 return false; | 67 return false; |
68 } | 68 } |
69 } | 69 } |
70 | |
71 | |
72 | 70 |
73 class TraitsExp : Expression | 71 class TraitsExp : Expression |
74 { | 72 { |
75 Identifier ident; | 73 Identifier ident; |
76 | 74 |
95 printf("TraitsExp.semantic() %s\n", toChars()); | 93 printf("TraitsExp.semantic() %s\n", toChars()); |
96 } | 94 } |
97 if (ident != Id.compiles && ident != Id.isSame) | 95 if (ident != Id.compiles && ident != Id.isSame) |
98 TemplateInstance.semanticTiargs(loc, sc, args, 1); | 96 TemplateInstance.semanticTiargs(loc, sc, args, 1); |
99 size_t dim = args ? args.dim : 0; | 97 size_t dim = args ? args.dim : 0; |
100 Object o; | |
101 Declaration d; | 98 Declaration d; |
102 FuncDeclaration f; | 99 FuncDeclaration f; |
103 | 100 |
104 string ISTYPE(string cond) | 101 string ISTYPE(string cond) |
105 { | 102 { |
178 else if (ident == Id.isFinalFunction) | 175 else if (ident == Id.isFinalFunction) |
179 { | 176 { |
180 mixin(ISDSYMBOL(q{(f = s.isFuncDeclaration()) !is null && f.isFinal()})); | 177 mixin(ISDSYMBOL(q{(f = s.isFuncDeclaration()) !is null && f.isFinal()})); |
181 } | 178 } |
182 //version(DMDV2) { | 179 //version(DMDV2) { |
180 else if (ident == Id.isStaticFunction) | |
181 { | |
182 mixin(ISDSYMBOL(q{(f = s.isFuncDeclaration()) !is null && !f.needThis()})); | |
183 } | |
183 else if (ident == Id.isRef) | 184 else if (ident == Id.isRef) |
184 { | 185 { |
185 mixin(ISDSYMBOL(q{(d = s.isDeclaration()) !is null && d.isRef()})); | 186 mixin(ISDSYMBOL(q{(d = s.isDeclaration()) !is null && d.isRef()})); |
186 } | 187 } |
187 else if (ident == Id.isOut) | 188 else if (ident == Id.isOut) |
190 } | 191 } |
191 else if (ident == Id.isLazy) | 192 else if (ident == Id.isLazy) |
192 { | 193 { |
193 mixin(ISDSYMBOL(q{(d = s.isDeclaration()) !is null && d.storage_class & STClazy})); | 194 mixin(ISDSYMBOL(q{(d = s.isDeclaration()) !is null && d.storage_class & STClazy})); |
194 } | 195 } |
196 else if (ident == Id.identifier) | |
197 { | |
198 // Get identifier for symbol as a string literal | |
199 if (dim != 1) | |
200 goto Ldimerror; | |
201 auto o = args[0]; | |
202 Dsymbol s = getDsymbol(o); | |
203 if (!s || !s.ident) | |
204 { | |
205 error("argument %s has no identifier", ident.toChars()); ///< CHANGED o to ident!!! | |
206 goto Lfalse; | |
207 } | |
208 StringExp se = new StringExp(loc, s.ident.toChars()); | |
209 return se.semantic(sc); | |
210 } | |
195 //} | 211 //} |
196 else if (ident == Id.hasMember || | 212 else if (ident == Id.hasMember || |
197 ident == Id.getMember || | 213 ident == Id.getMember || |
214 ident == Id.getOverloads || | |
198 ident == Id.getVirtualFunctions) | 215 ident == Id.getVirtualFunctions) |
199 { | 216 { |
200 if (dim != 2) | 217 if (dim != 2) |
201 goto Ldimerror; | 218 goto Ldimerror; |
202 auto o_ = args[0]; | 219 auto o = args[0]; |
203 Expression e = isExpression(args[1]); | 220 Expression e = isExpression(args[1]); |
204 if (!e) | 221 if (!e) |
205 { error("expression expected as second argument of __traits %s", ident.toChars()); | 222 { error("expression expected as second argument of __traits %s", ident.toChars()); |
206 goto Lfalse; | 223 goto Lfalse; |
207 } | 224 } |
216 { error("string must be chars"); | 233 { error("string must be chars"); |
217 goto Lfalse; | 234 goto Lfalse; |
218 } | 235 } |
219 Identifier id = Lexer.idPool(fromStringz(cast(char*)se.string_)); | 236 Identifier id = Lexer.idPool(fromStringz(cast(char*)se.string_)); |
220 | 237 |
221 Type t = isType(o_); | 238 Type t = isType(o); |
222 e = isExpression(o_); | 239 e = isExpression(o); |
223 Dsymbol s = isDsymbol(o_); | 240 Dsymbol s = isDsymbol(o); |
224 if (t) | 241 if (t) |
225 e = typeDotIdExp(loc, t, id); | 242 e = typeDotIdExp(loc, t, id); |
226 else if (e) | 243 else if (e) |
227 e = new DotIdExp(loc, e, id); | 244 e = new DotIdExp(loc, e, id); |
228 else if (s) | 245 else if (s) |
249 else if (ident == Id.getMember) | 266 else if (ident == Id.getMember) |
250 { | 267 { |
251 e = e.semantic(sc); | 268 e = e.semantic(sc); |
252 return e; | 269 return e; |
253 } | 270 } |
254 else if (ident == Id.getVirtualFunctions) | 271 else if (ident == Id.getVirtualFunctions || ident == Id.getOverloads) |
255 { | 272 { |
256 uint errors = global.errors; | 273 uint errors = global.errors; |
257 Expression ex = e; | 274 Expression ex = e; |
258 e = e.semantic(sc); | 275 e = e.semantic(sc); |
259 if (errors < global.errors) | 276 if (errors < global.errors) |
260 error("%s cannot be resolved", ex.toChars()); | 277 error("%s cannot be resolved", ex.toChars()); |
261 | 278 |
262 /* Create tuple of virtual function overloads of e | 279 /* Create tuple of virtual function overloads of e |
263 */ | 280 */ |
264 //e.dump(0); | 281 //e.dump(0); |
265 Expressions exps = new Expressions(); | 282 Expressions exps = new Expressions(); |
266 FuncDeclaration f_; | 283 FuncDeclaration f_; |
267 if (e.op == TOKvar) | 284 if (e.op == TOKvar) |
275 f_ = dve.var.isFuncDeclaration(); | 292 f_ = dve.var.isFuncDeclaration(); |
276 } | 293 } |
277 else | 294 else |
278 f_ = null; | 295 f_ = null; |
279 | 296 |
280 Pvirtuals p; | 297 Ptrait p; |
281 p.exps = exps; | 298 p.exps = exps; |
282 p.e1 = e; | 299 p.e1 = e; |
300 p.ident = ident; | |
283 overloadApply(f_, p); | 301 overloadApply(f_, p); |
284 | 302 |
285 TupleExp tup = new TupleExp(loc, exps); | 303 TupleExp tup = new TupleExp(loc, exps); |
286 return tup.semantic(sc); | 304 return tup.semantic(sc); |
287 } | 305 } |
290 } | 308 } |
291 else if (ident == Id.classInstanceSize) | 309 else if (ident == Id.classInstanceSize) |
292 { | 310 { |
293 if (dim != 1) | 311 if (dim != 1) |
294 goto Ldimerror; | 312 goto Ldimerror; |
295 Object o_ = args[0]; | 313 Object o = args[0]; |
296 Dsymbol s = getDsymbol(o_); | 314 Dsymbol s = getDsymbol(o); |
297 ClassDeclaration cd; | 315 ClassDeclaration cd; |
298 if (!s || (cd = s.isClassDeclaration()) is null) | 316 if (!s || (cd = s.isClassDeclaration()) is null) |
299 { | 317 { |
300 error("first argument is not a class"); | 318 error("first argument is not a class"); |
301 goto Lfalse; | 319 goto Lfalse; |
304 } | 322 } |
305 else if (ident == Id.allMembers || ident == Id.derivedMembers) | 323 else if (ident == Id.allMembers || ident == Id.derivedMembers) |
306 { | 324 { |
307 if (dim != 1) | 325 if (dim != 1) |
308 goto Ldimerror; | 326 goto Ldimerror; |
309 Object o_ = args[0]; | 327 Object o = args[0]; |
310 Dsymbol s = getDsymbol(o_); | 328 Dsymbol s = getDsymbol(o); |
311 ScopeDsymbol sd; | 329 ScopeDsymbol sd; |
312 if (!s) | 330 if (!s) |
313 { | 331 { |
314 error("argument has no members"); | 332 error("argument has no members"); |
315 goto Lfalse; | 333 goto Lfalse; |
362 */ | 380 */ |
363 if (!dim) | 381 if (!dim) |
364 goto Lfalse; | 382 goto Lfalse; |
365 | 383 |
366 for (size_t i = 0; i < dim; i++) | 384 for (size_t i = 0; i < dim; i++) |
367 { Object o_ = args[i]; | 385 { Object o = args[i]; |
368 Expression e; | 386 Expression e; |
369 | 387 |
370 uint errors = global.errors; | 388 uint errors = global.errors; |
371 global.gag++; | 389 global.gag++; |
372 | 390 |
373 Type t = isType(o_); | 391 Type t = isType(o); |
374 if (t) | 392 if (t) |
375 { Dsymbol s; | 393 { Dsymbol s; |
376 t.resolve(loc, sc, &e, &t, &s); | 394 t.resolve(loc, sc, &e, &t, &s); |
377 if (t) | 395 if (t) |
378 t.semantic(loc, sc); | 396 t.semantic(loc, sc); |
439 goto Ltrue; | 457 goto Ltrue; |
440 else | 458 else |
441 goto Lfalse; | 459 goto Lfalse; |
442 } | 460 } |
443 else | 461 else |
444 { error("unrecognized trait %s", ident.toChars()); | 462 { |
463 error("unrecognized trait %s", ident.toChars()); | |
445 goto Lfalse; | 464 goto Lfalse; |
446 } | 465 } |
447 | 466 |
448 return null; | 467 return null; |
449 | 468 |
450 Lnottype: | 469 // Not used |
451 error("%s is not a type", o/*.toChars()*/); // BUG: o is Object, no member toChars() | 470 //Lnottype: |
452 goto Lfalse; | 471 // error("%s is not a type", o.toChars()); |
472 // goto Lfalse; | |
453 | 473 |
454 Ldimerror: | 474 Ldimerror: |
455 error("wrong number of arguments %d", dim); | 475 error("wrong number of arguments %d", dim); |
456 goto Lfalse; | 476 goto Lfalse; |
457 | 477 |