Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(546)

Side by Side Diff: frog/leg/compile_time_constants.dart

Issue 9665001: Implement constant maps. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Cosmetic changes. Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | frog/leg/lib/constant_map.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 class Constant implements Hashable { 5 class Constant implements Hashable {
6 const Constant(); 6 const Constant();
7 7
8 bool isNull() => false; 8 bool isNull() => false;
9 bool isBool() => false; 9 bool isBool() => false;
10 bool isTrue() => false; 10 bool isTrue() => false;
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 entry.writeJsCode(buffer, handler); 268 entry.writeJsCode(buffer, handler);
269 } 269 }
270 } 270 }
271 buffer.add("])"); 271 buffer.add("])");
272 } 272 }
273 273
274 bool operator ==(var other) { 274 bool operator ==(var other) {
275 if (other is !ListConstant) return false; 275 if (other is !ListConstant) return false;
276 ListConstant otherList = other; 276 ListConstant otherList = other;
277 if (hashCode() != otherList.hashCode()) return false; 277 if (hashCode() != otherList.hashCode()) return false;
278 // TODO(floitsch): verify that the types are the same. 278 // TODO(floitsch): verify that the generic types are the same.
279 if (entries.length != otherList.entries.length) return false; 279 if (entries.length != otherList.entries.length) return false;
280 for (int i = 0; i < entries.length; i++) { 280 for (int i = 0; i < entries.length; i++) {
281 if (entries[i] != otherList.entries[i]) return false; 281 if (entries[i] != otherList.entries[i]) return false;
282 } 282 }
283 return true; 283 return true;
284 } 284 }
285 285
286 int hashCode() => _hashCode; 286 int hashCode() => _hashCode;
287 } 287 }
288 288
289 class MapConstant extends ObjectConstant {
290 /** The dart class implementing constant map literals. */
291 static final SourceString DART_CLASS = const SourceString("ConstantMap");
292 static final SourceString LENGTH_NAME = const SourceString("length");
293 static final SourceString JS_OBJECT_NAME = const SourceString("_jsObject");
294 static final SourceString KEYS_NAME = const SourceString("_keys");
295
296 final ListConstant keys;
297 final List<Constant> values;
298 int _hashCode;
299
300 MapConstant(Type type, this.keys, this.values) : super(type) {
301 // TODO(floitsch): create a better hash.
302 int hash = 0;
303 for (Constant value in values) hash ^= value.hashCode();
304 _hashCode = hash;
305 }
306 bool isMap() => true;
307
308 void writeJsCode(StringBuffer buffer, ConstantHandler handler) {
309 void writeJsMap() {
310 String isolatePrototype = "${handler.compiler.namer.ISOLATE}.prototype";
311 buffer.add("{");
312 for (int i = 0; i < keys.entries.length; i++) {
313 if (i != 0) buffer.add(", ");
314
315 StringConstant key = keys.entries[i];
316 key.writeJsCode(buffer, handler);
317 buffer.add(": ");
318 Constant value = values[i];
319 // TODO(floitsch): share this code with the ListConstant and
320 // ConstructedConstant.
321 if (value.isObject()) {
322 String name = handler.getNameForConstant(value);
323 buffer.add("$isolatePrototype.$name");
324 } else {
325 value.writeJsCode(buffer, handler);
326 }
327 }
328 buffer.add("}");
329 }
330
331 buffer.add("new ");
332 buffer.add(handler.getJsConstructor(type.element));
333 buffer.add("(");
334 // We have to send the arguments in the same order as they appear in the
335 // class element.
ngeoffray 2012/03/09 18:08:50 Please also say that it's because we emit the orde
floitsch 2012/03/10 17:40:24 Done.
336 int emittedArgumentCount = 0;
337 ClassElement classElement = type.element;
ngeoffray 2012/03/09 18:08:50 Share that with line 332.
floitsch 2012/03/10 17:40:24 Done.
338 for (Element element in classElement.members) {
339 if (element.name == LENGTH_NAME) {
340 buffer.add(keys.entries.length);
341 } else if (element.name == JS_OBJECT_NAME) {
342 writeJsMap();
343 } else if (element.name == KEYS_NAME) {
344 keys.writeJsCode(buffer, handler);
345 } else {
346 continue;
ngeoffray 2012/03/09 18:08:50 Please add a comment that this is for methods.
floitsch 2012/03/10 17:40:24 Done.
347 }
348 emittedArgumentCount++;
349 if (emittedArgumentCount == 3) {
350 break; // All arguments have been emitted.
351 } else {
352 buffer.add(", ");
353 }
354 }
355 if (emittedArgumentCount != 3) {
356 handler.compiler.internalError("Could not generate constant map");
ngeoffray 2012/03/09 18:08:50 Maybe say something more explicit like: "compiler
floitsch 2012/03/10 17:40:24 Done.
357 }
358 buffer.add(")");
359 }
360
361 bool operator ==(var other) {
362 if (other is !MapConstant) return false;
363 MapConstant otherMap = other;
364 if (hashCode() != otherMap.hashCode()) return false;
365 // TODO(floitsch): verify that the generic types are the same.
366 if (keys != otherMap.keys) return false;
367 for (int i = 0; i < values.length; i++) {
368 if (values[i] != otherMap.values[i]) return false;
369 }
370 return true;
371 }
372
373 int hashCode() => _hashCode;
374 }
375
289 class ConstructedConstant extends ObjectConstant { 376 class ConstructedConstant extends ObjectConstant {
290 final List<Constant> fields; 377 final List<Constant> fields;
291 int _hashCode; 378 int _hashCode;
292 379
293 ConstructedConstant(Type type, this.fields) : super(type) { 380 ConstructedConstant(Type type, this.fields) : super(type) {
294 assert(type !== null); 381 assert(type !== null);
295 // TODO(floitsch): create a better hash. 382 // TODO(floitsch): create a better hash.
296 int hash = 0; 383 int hash = 0;
297 for (Constant field in fields) { 384 for (Constant field in fields) {
298 hash ^= field.hashCode(); 385 hash ^= field.hashCode();
299 } 386 }
300 hash ^= type.element.hashCode(); 387 hash ^= type.element.hashCode();
301 _hashCode = hash; 388 _hashCode = hash;
302 } 389 }
303 bool isConstructedObject() => true; 390 bool isConstructedObject() => true;
304 391
305 void writeJsCode(StringBuffer buffer, ConstantHandler handler) { 392 void writeJsCode(StringBuffer buffer, ConstantHandler handler) {
306 buffer.add("new "); 393 buffer.add("new ");
307 buffer.add(handler.getJsConstructor(type.element)); 394 buffer.add(handler.getJsConstructor(type.element));
308 buffer.add("("); 395 buffer.add("(");
309 String isolatePrototype = "${handler.compiler.namer.ISOLATE}.prototype"; 396 String isolatePrototype = "${handler.compiler.namer.ISOLATE}.prototype";
310 for (int i = 0; i < fields.length; i++) { 397 for (int i = 0; i < fields.length; i++) {
311 if (i != 0) buffer.add(", "); 398 if (i != 0) buffer.add(", ");
312 Constant field = fields[i]; 399 Constant field = fields[i];
313 // TODO(floitsch): share this code with the ListConstant. 400 // TODO(floitsch): share this code with the ListConstant.
314 if (field.isObject()) { 401 if (field.isObject()) {
315 String name = handler.getNameForConstant(entry); 402 String name = handler.getNameForConstant(field);
316 buffer.add("$isolatePrototype.$name"); 403 buffer.add("$isolatePrototype.$name");
317 } else { 404 } else {
318 field.writeJsCode(buffer, handler); 405 field.writeJsCode(buffer, handler);
319 } 406 }
320 } 407 }
321 buffer.add(")"); 408 buffer.add(")");
322 } 409 }
323 410
324 bool operator ==(var otherVar) { 411 bool operator ==(var otherVar) {
325 if (otherVar is !ConstructedConstant) return false; 412 if (otherVar is !ConstructedConstant) return false;
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 Constant visitLiteralDouble(LiteralDouble node) { 672 Constant visitLiteralDouble(LiteralDouble node) {
586 return new DoubleConstant(node.value); 673 return new DoubleConstant(node.value);
587 } 674 }
588 675
589 Constant visitLiteralInt(LiteralInt node) { 676 Constant visitLiteralInt(LiteralInt node) {
590 return new IntConstant(node.value); 677 return new IntConstant(node.value);
591 } 678 }
592 679
593 Constant visitLiteralList(LiteralList node) { 680 Constant visitLiteralList(LiteralList node) {
594 if (!node.isConst()) error(node); 681 if (!node.isConst()) error(node);
595 List arguments = []; 682 List<Constant> arguments = <Constant>[];
596 for (Link<Node> link = node.elements.nodes; 683 for (Link<Node> link = node.elements.nodes;
597 !link.isEmpty(); 684 !link.isEmpty();
598 link = link.tail) { 685 link = link.tail) {
599 arguments.add(evaluate(link.head)); 686 arguments.add(evaluate(link.head));
600 } 687 }
601 // TODO(floitsch): get type from somewhere. 688 // TODO(floitsch): get type from somewhere.
602 Type type = null; 689 Type type = null;
603 return constantHandler.compileListLiteral(node, type, arguments); 690 return constantHandler.compileListLiteral(node, type, arguments);
604 } 691 }
605 692
606 Constant visitLiteralMap(LiteralMap node) { 693 Constant visitLiteralMap(LiteralMap node) {
607 compiler.unimplemented("CompileTimeConstantEvaluator map", node: node); 694 // TODO(floitsch): check for isConst, once the parser adds it into the node.
695 // if (!node.isConst()) error(node);
696 List<StringConstant> keys = <StringConstant>[];
697 List<Constant> values = <Constant>[];
698 for (Link<Node> link = node.entries.nodes;
699 !link.isEmpty();
700 link = link.tail) {
701 LiteralMapEntry entry = link.head;
702 Constant key = evaluate(entry.key);
703 if (!key.isString()) {
704 compiler.internalError("Key for literal map not a String",
705 node: entry.key);
706 }
707 keys.add(key);
708 values.add(evaluate(entry.value));
709 }
710 // TODO(floitsch): this should be a List<String> type.
711 Type keysType = null;
712 ListConstant keysList = new ListConstant(keysType, keys);
713 // We don't actually need to register the constant, but there is no reason
714 // not to.
715 constantHandler.registerCompileTimeConstant(keysList);
716 ClassElement classElement =
717 compiler.jsHelperLibrary.find(MapConstant.DART_CLASS);
718 classElement.resolve(compiler);
719 // TODO(floitsch): copy over the generic type.
720 Type type = new SimpleType(classElement.name, classElement);
721 compiler.registerInstantiatedClass(classElement);
722 Constant constant = new MapConstant(type, keysList, values);
723 constantHandler.registerCompileTimeConstant(constant);
724 return constant;
608 } 725 }
609 726
610 Constant visitLiteralNull(LiteralNull node) { 727 Constant visitLiteralNull(LiteralNull node) {
611 return new NullConstant(); 728 return new NullConstant();
612 } 729 }
613 730
614 Constant visitLiteralString(LiteralString node) { 731 Constant visitLiteralString(LiteralString node) {
615 return new StringConstant(node.dartString); 732 return new StringConstant(node.dartString);
616 } 733 }
617 734
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
762 arguments); 879 arguments);
763 } 880 }
764 881
765 error(Node node) { 882 error(Node node) {
766 // TODO(floitsch): get the list of constants that are currently compiled 883 // TODO(floitsch): get the list of constants that are currently compiled
767 // and present some kind of stack-trace. 884 // and present some kind of stack-trace.
768 MessageKind kind = MessageKind.NOT_A_COMPILE_TIME_CONSTANT; 885 MessageKind kind = MessageKind.NOT_A_COMPILE_TIME_CONSTANT;
769 compiler.reportError(node, new CompileTimeConstantError(kind, const [])); 886 compiler.reportError(node, new CompileTimeConstantError(kind, const []));
770 } 887 }
771 } 888 }
OLDNEW
« no previous file with comments | « no previous file | frog/leg/lib/constant_map.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698