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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/compile_time_constants.dart

Issue 16549004: Add type arguments to constants. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Adjust test status. Created 7 years, 6 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
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 part of dart2js; 5 part of dart2js;
6 6
7 /** 7 /**
8 * The [ConstantHandler] keeps track of compile-time constants, 8 * The [ConstantHandler] keeps track of compile-time constants,
9 * initializations of global and static fields, and default values of 9 * initializations of global and static fields, and default values of
10 * optional parameters. 10 * optional parameters.
(...skipping 14 matching lines...) Expand all
25 25
26 /** The set of variable elements that are in the process of being computed. */ 26 /** The set of variable elements that are in the process of being computed. */
27 final Set<VariableElement> pendingVariables; 27 final Set<VariableElement> pendingVariables;
28 28
29 /** Caches the statics where the initial value cannot be eagerly compiled. */ 29 /** Caches the statics where the initial value cannot be eagerly compiled. */
30 final Set<VariableElement> lazyStatics; 30 final Set<VariableElement> lazyStatics;
31 31
32 /** Caches the createRuntimeType function if registered. */ 32 /** Caches the createRuntimeType function if registered. */
33 Element createRuntimeTypeFunction = null; 33 Element createRuntimeTypeFunction = null;
34 34
35 /** Caches the setRuntimeTypeInfo function if registered. */
36 Element setRuntimeTypeInfoFunction = null;
37
35 ConstantHandler(Compiler compiler, this.constantSystem, 38 ConstantHandler(Compiler compiler, this.constantSystem,
36 { bool this.isMetadata: false }) 39 { bool this.isMetadata: false })
37 : initialVariableValues = new Map<VariableElement, dynamic>(), 40 : initialVariableValues = new Map<VariableElement, dynamic>(),
38 compiledConstants = new Set<Constant>(), 41 compiledConstants = new Set<Constant>(),
39 pendingVariables = new Set<VariableElement>(), 42 pendingVariables = new Set<VariableElement>(),
40 lazyStatics = new Set<VariableElement>(), 43 lazyStatics = new Set<VariableElement>(),
41 super(compiler); 44 super(compiler);
42 45
43 String get name => 'ConstantHandler'; 46 String get name => 'ConstantHandler';
44 47
45 void registerCompileTimeConstant(Constant constant, TreeElements elements) { 48 void registerCompileTimeConstant(Constant constant, TreeElements elements) {
46 registerInstantiatedClass(constant.computeType(compiler).element, elements); 49 registerInstantiatedType(constant.computeType(compiler), elements);
47 if (constant.isFunction()) { 50 if (constant.isFunction()) {
48 FunctionConstant function = constant; 51 FunctionConstant function = constant;
49 registerGetOfStaticFunction(function.element); 52 registerGetOfStaticFunction(function.element);
50 } else if (constant.isInterceptor()) { 53 } else if (constant.isInterceptor()) {
51 // An interceptor constant references the class's prototype chain. 54 // An interceptor constant references the class's prototype chain.
52 InterceptorConstant interceptor = constant; 55 InterceptorConstant interceptor = constant;
53 registerInstantiatedClass(interceptor.dispatchedType.element, elements); 56 registerInstantiatedType(interceptor.dispatchedType, elements);
54 } 57 }
55 compiledConstants.add(constant); 58 compiledConstants.add(constant);
56 } 59 }
57 60
58 void registerInstantiatedClass(ClassElement element, TreeElements elements) { 61 void registerInstantiatedType(DartType type, TreeElements elements) {
59 if (isMetadata) return; 62 if (isMetadata) return;
60 compiler.enqueuer.codegen.registerInstantiatedClass(element, elements); 63 compiler.enqueuer.codegen.registerInstantiatedType(type, elements);
61 } 64 }
62 65
63 void registerStaticUse(Element element) { 66 void registerStaticUse(Element element) {
64 if (isMetadata) return; 67 if (isMetadata) return;
65 compiler.analyzeElement(element.declaration); 68 compiler.analyzeElement(element.declaration);
66 compiler.enqueuer.codegen.registerStaticUse(element); 69 compiler.enqueuer.codegen.registerStaticUse(element);
67 } 70 }
68 71
69 void registerGetOfStaticFunction(FunctionElement element) { 72 void registerGetOfStaticFunction(FunctionElement element) {
70 if (isMetadata) return; 73 if (isMetadata) return;
71 compiler.analyzeElement(element.declaration); 74 compiler.analyzeElement(element.declaration);
72 compiler.enqueuer.codegen.registerGetOfStaticFunction(element); 75 compiler.enqueuer.codegen.registerGetOfStaticFunction(element);
73 } 76 }
74 77
75 void registerStringInstance(TreeElements elements) { 78 void registerStringInstance(TreeElements elements) {
76 registerInstantiatedClass(compiler.stringClass, elements); 79 registerInstantiatedType(compiler.stringClass.rawType, elements);
80 }
81
82 void registerSetRuntimeTypeInfoFunction() {
83 if (setRuntimeTypeInfoFunction != null) return;
ngeoffray 2013/06/17 09:15:03 In non-checked mode, how do you make sure this hel
karlklose 2013/06/19 15:29:05 Added a check.
84 SourceString helperName = const SourceString('setRuntimeTypeInfo');
85 setRuntimeTypeInfoFunction = compiler.findHelper(helperName);
86 registerStaticUse(setRuntimeTypeInfoFunction);
77 } 87 }
78 88
79 void registerCreateRuntimeTypeFunction() { 89 void registerCreateRuntimeTypeFunction() {
80 if (createRuntimeTypeFunction != null) return; 90 if (createRuntimeTypeFunction != null) return;
81 SourceString helperName = const SourceString('createRuntimeType'); 91 SourceString helperName = const SourceString('createRuntimeType');
82 createRuntimeTypeFunction = compiler.findHelper(helperName); 92 createRuntimeTypeFunction = compiler.findHelper(helperName);
83 registerStaticUse(createRuntimeTypeFunction); 93 registerStaticUse(createRuntimeTypeFunction);
84 } 94 }
85 95
86 /** 96 /**
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 isEvaluatingConstant = oldIsEvaluatingConstant; 321 isEvaluatingConstant = oldIsEvaluatingConstant;
312 assert(result != null); 322 assert(result != null);
313 return result; 323 return result;
314 } 324 }
315 325
316 Constant visitNode(Node node) { 326 Constant visitNode(Node node) {
317 return signalNotCompileTimeConstant(node); 327 return signalNotCompileTimeConstant(node);
318 } 328 }
319 329
320 Constant visitLiteralBool(LiteralBool node) { 330 Constant visitLiteralBool(LiteralBool node) {
321 handler.registerInstantiatedClass(compiler.boolClass, elements); 331 handler.registerInstantiatedType(compiler.boolClass.rawType, elements);
322 return constantSystem.createBool(node.value); 332 return constantSystem.createBool(node.value);
323 } 333 }
324 334
325 Constant visitLiteralDouble(LiteralDouble node) { 335 Constant visitLiteralDouble(LiteralDouble node) {
326 handler.registerInstantiatedClass(compiler.doubleClass, elements); 336 handler.registerInstantiatedType(compiler.doubleClass.rawType, elements);
327 return constantSystem.createDouble(node.value); 337 return constantSystem.createDouble(node.value);
328 } 338 }
329 339
330 Constant visitLiteralInt(LiteralInt node) { 340 Constant visitLiteralInt(LiteralInt node) {
331 handler.registerInstantiatedClass(compiler.intClass, elements); 341 handler.registerInstantiatedType(compiler.intClass.rawType, elements);
332 return constantSystem.createInt(node.value); 342 return constantSystem.createInt(node.value);
333 } 343 }
334 344
335 Constant visitLiteralList(LiteralList node) { 345 Constant visitLiteralList(LiteralList node) {
336 if (!node.isConst()) { 346 if (!node.isConst()) {
337 return signalNotCompileTimeConstant(node); 347 return signalNotCompileTimeConstant(node);
338 } 348 }
339 List<Constant> arguments = <Constant>[]; 349 List<Constant> arguments = <Constant>[];
340 for (Link<Node> link = node.elements.nodes; 350 for (Link<Node> link = node.elements.nodes;
341 !link.isEmpty; 351 !link.isEmpty;
342 link = link.tail) { 352 link = link.tail) {
343 arguments.add(evaluateConstant(link.head)); 353 arguments.add(evaluateConstant(link.head));
344 } 354 }
345 // TODO(9476): get type parameters. 355 DartType type = elements.getType(node);
346 compiler.listClass.computeType(compiler); 356 handler.registerInstantiatedType(type, elements);
347 DartType type = compiler.listClass.rawType; 357 if (!type.isRaw) {
358 handler.registerSetRuntimeTypeInfoFunction();
ngeoffray 2013/06/17 09:15:03 Move this check to [registerInstantiatedType]?
karlklose 2013/06/19 15:29:05 Done.
359 }
348 Constant constant = new ListConstant(type, arguments); 360 Constant constant = new ListConstant(type, arguments);
349 handler.registerCompileTimeConstant(constant, elements); 361 handler.registerCompileTimeConstant(constant, elements);
350 return constant; 362 return constant;
351 } 363 }
352 364
353 Constant visitLiteralMap(LiteralMap node) { 365 Constant visitLiteralMap(LiteralMap node) {
354 if (!node.isConst()) { 366 if (!node.isConst()) {
355 return signalNotCompileTimeConstant(node); 367 return signalNotCompileTimeConstant(node);
356 } 368 }
357 List<StringConstant> keys = <StringConstant>[]; 369 List<StringConstant> keys = <StringConstant>[];
(...skipping 14 matching lines...) Expand all
372 List<Constant> values = <Constant>[]; 384 List<Constant> values = <Constant>[];
373 Constant protoValue = null; 385 Constant protoValue = null;
374 for (StringConstant key in keys) { 386 for (StringConstant key in keys) {
375 if (key.value == MapConstant.PROTO_PROPERTY) { 387 if (key.value == MapConstant.PROTO_PROPERTY) {
376 protoValue = map[key]; 388 protoValue = map[key];
377 } else { 389 } else {
378 values.add(map[key]); 390 values.add(map[key]);
379 } 391 }
380 } 392 }
381 bool hasProtoKey = (protoValue != null); 393 bool hasProtoKey = (protoValue != null);
382 // TODO(9476): this should be a List<String> type. 394 InterfaceType sourceType = elements.getType(node);
383 compiler.listClass.computeType(compiler); 395 Link<DartType> arguments =
384 DartType keysType = compiler.listClass.rawType; 396 new Link<DartType>.fromList([compiler.stringClass.rawType]);
397 DartType keysType = new InterfaceType(compiler.listClass, arguments);
385 ListConstant keysList = new ListConstant(keysType, keys); 398 ListConstant keysList = new ListConstant(keysType, keys);
386 handler.registerCompileTimeConstant(keysList, elements); 399 handler.registerCompileTimeConstant(keysList, elements);
387 SourceString className = hasProtoKey 400 SourceString className = hasProtoKey
388 ? MapConstant.DART_PROTO_CLASS 401 ? MapConstant.DART_PROTO_CLASS
389 : MapConstant.DART_CLASS; 402 : MapConstant.DART_CLASS;
390 ClassElement classElement = compiler.jsHelperLibrary.find(className); 403 ClassElement classElement = compiler.jsHelperLibrary.find(className);
391 classElement.ensureResolved(compiler); 404 classElement.ensureResolved(compiler);
392 // TODO(9476): copy over the generic type. 405 Link<DartType> typeArgument = sourceType.typeArguments.tail;
393 DartType type = classElement.rawType; 406 InterfaceType type = new InterfaceType(classElement, typeArgument);
394 handler.registerInstantiatedClass(classElement, elements); 407 handler.registerInstantiatedType(type, elements);
408 if (!type.isRaw) {
ngeoffray 2013/06/17 09:15:03 Ditto.
karlklose 2013/06/19 15:29:05 Done.
409 handler.registerSetRuntimeTypeInfoFunction();
410 }
395 Constant constant = new MapConstant(type, keysList, values, protoValue); 411 Constant constant = new MapConstant(type, keysList, values, protoValue);
396 handler.registerCompileTimeConstant(constant, elements); 412 handler.registerCompileTimeConstant(constant, elements);
397 return constant; 413 return constant;
398 } 414 }
399 415
400 Constant visitLiteralNull(LiteralNull node) { 416 Constant visitLiteralNull(LiteralNull node) {
401 return constantSystem.createNull(); 417 return constantSystem.createNull();
402 } 418 }
403 419
404 Constant visitLiteralString(LiteralString node) { 420 Constant visitLiteralString(LiteralString node) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 if (partString == null) return null; 454 if (partString == null) return null;
439 accumulator = new DartString.concat(accumulator, partString.value); 455 accumulator = new DartString.concat(accumulator, partString.value);
440 }; 456 };
441 handler.registerStringInstance(elements); 457 handler.registerStringInstance(elements);
442 return constantSystem.createString(accumulator, node); 458 return constantSystem.createString(accumulator, node);
443 } 459 }
444 460
445 Constant makeTypeConstant(Element element) { 461 Constant makeTypeConstant(Element element) {
446 DartType elementType = element.computeType(compiler).asRaw(); 462 DartType elementType = element.computeType(compiler).asRaw();
447 if (compiler.mirrorsEnabled) { 463 if (compiler.mirrorsEnabled) {
448 handler.registerInstantiatedClass(element, elements); 464 handler.registerInstantiatedType(elementType, elements);
449 } 465 }
450 DartType constantType = 466 DartType constantType =
451 compiler.backend.typeImplementation.computeType(compiler); 467 compiler.backend.typeImplementation.computeType(compiler);
452 Constant constant = new TypeConstant(elementType, constantType); 468 Constant constant = new TypeConstant(elementType, constantType);
453 // If we use a type literal in a constant, the compile time 469 // If we use a type literal in a constant, the compile time
454 // constant emitter will generate a call to the createRuntimeType 470 // constant emitter will generate a call to the createRuntimeType
455 // helper so we register a use of that. 471 // helper so we register a use of that.
456 handler.registerCreateRuntimeTypeFunction(); 472 handler.registerCreateRuntimeTypeFunction();
457 handler.registerCompileTimeConstant(constant, elements); 473 handler.registerCompileTimeConstant(constant, elements);
458 return constant; 474 return constant;
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 } 658 }
643 return compiledArguments; 659 return compiledArguments;
644 } 660 }
645 661
646 Constant visitNewExpression(NewExpression node) { 662 Constant visitNewExpression(NewExpression node) {
647 if (!node.isConst()) { 663 if (!node.isConst()) {
648 return signalNotCompileTimeConstant(node); 664 return signalNotCompileTimeConstant(node);
649 } 665 }
650 666
651 Send send = node.send; 667 Send send = node.send;
652 FunctionElement constructor = elements[send]; 668 FunctionElement functionElement = elements[send];
669 FunctionElement constructor = functionElement;
ngeoffray 2013/06/17 09:15:03 What is this double assignment for? If line 678 ch
karlklose 2013/06/19 15:29:05 Yes, this is left-over code. Removed.
653 // TODO(ahe): This is nasty: we must eagerly analyze the 670 // TODO(ahe): This is nasty: we must eagerly analyze the
654 // constructor to ensure the redirectionTarget has been computed 671 // constructor to ensure the redirectionTarget has been computed
655 // correctly. Find a way to avoid this. 672 // correctly. Find a way to avoid this.
656 compiler.analyzeElement(constructor.declaration); 673 compiler.analyzeElement(constructor.declaration);
657 constructor = constructor.redirectionTarget; 674 constructor = constructor.redirectionTarget;
658 ClassElement classElement = constructor.getEnclosingClass(); 675 ClassElement classElement = constructor.getEnclosingClass();
659 // The constructor must be an implementation to ensure that field 676 // The constructor must be an implementation to ensure that field
660 // initializers are handled correctly. 677 // initializers are handled correctly.
661 constructor = constructor.implementation; 678 constructor = constructor.implementation;
662 assert(invariant(node, constructor.isImplementation)); 679 assert(invariant(node, constructor.isImplementation));
663 680
664 Selector selector = elements.getSelector(send); 681 Selector selector = elements.getSelector(send);
665 List<Constant> arguments = evaluateArgumentsToConstructor( 682 List<Constant> arguments = evaluateArgumentsToConstructor(
666 node, selector, send.arguments, constructor); 683 node, selector, send.arguments, constructor);
667 ConstructorEvaluator evaluator = 684 ConstructorEvaluator evaluator =
668 new ConstructorEvaluator(node, constructor, handler, compiler); 685 new ConstructorEvaluator(node, constructor, handler, compiler);
669 evaluator.evaluateConstructorFieldValues(arguments); 686 evaluator.evaluateConstructorFieldValues(arguments);
670 List<Constant> jsNewArguments = evaluator.buildJsNewArguments(classElement); 687 List<Constant> jsNewArguments = evaluator.buildJsNewArguments(classElement);
671 688
672 handler.registerInstantiatedClass(classElement, elements); 689 InterfaceType type = elements.getType(node);
673 // TODO(9476): take generic types into account. 690 bool isRedirected = functionElement.isRedirectingFactory;
674 classElement.computeType(compiler); 691 if (isRedirected) {
675 DartType type = classElement.rawType; 692 type = functionElement.computeTargetType(compiler, type);
693 }
694
695 handler.registerInstantiatedType(type, elements);
696 if (type is InterfaceType && !type.isRaw) {
697 handler.registerSetRuntimeTypeInfoFunction();
698 }
676 Constant constant = new ConstructedConstant(type, jsNewArguments); 699 Constant constant = new ConstructedConstant(type, jsNewArguments);
677 handler.registerCompileTimeConstant(constant, elements); 700 handler.registerCompileTimeConstant(constant, elements);
678 return constant; 701 return constant;
679 } 702 }
680 703
681 Constant visitParenthesizedExpression(ParenthesizedExpression node) { 704 Constant visitParenthesizedExpression(ParenthesizedExpression node) {
682 return node.expression.accept(this); 705 return node.expression.accept(this);
683 } 706 }
684 707
685 error(Node node) { 708 error(Node node) {
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
890 if (fieldValue == null) { 913 if (fieldValue == null) {
891 // Use the default value. 914 // Use the default value.
892 fieldValue = handler.compileConstant(field); 915 fieldValue = handler.compileConstant(field);
893 } 916 }
894 jsNewArguments.add(fieldValue); 917 jsNewArguments.add(fieldValue);
895 }, 918 },
896 includeSuperAndInjectedMembers: true); 919 includeSuperAndInjectedMembers: true);
897 return jsNewArguments; 920 return jsNewArguments;
898 } 921 }
899 } 922 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698