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

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: Address comments. 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);
64 if (type is InterfaceType && !type.isRaw &&
ngeoffray 2013/06/19 19:55:48 nit: move !type.isRaw to a new line.
karlklose 2013/06/20 12:49:21 Done.
65 compiler.backend.needsRti(type.element)) {
66 registerSetRuntimeTypeInfoFunction();
67 }
61 } 68 }
62 69
63 void registerStaticUse(Element element) { 70 void registerStaticUse(Element element) {
64 if (isMetadata) return; 71 if (isMetadata) return;
65 compiler.analyzeElement(element.declaration); 72 compiler.analyzeElement(element.declaration);
66 compiler.enqueuer.codegen.registerStaticUse(element); 73 compiler.enqueuer.codegen.registerStaticUse(element);
67 } 74 }
68 75
69 void registerGetOfStaticFunction(FunctionElement element) { 76 void registerGetOfStaticFunction(FunctionElement element) {
70 if (isMetadata) return; 77 if (isMetadata) return;
71 compiler.analyzeElement(element.declaration); 78 compiler.analyzeElement(element.declaration);
72 compiler.enqueuer.codegen.registerGetOfStaticFunction(element); 79 compiler.enqueuer.codegen.registerGetOfStaticFunction(element);
73 } 80 }
74 81
75 void registerStringInstance(TreeElements elements) { 82 void registerStringInstance(TreeElements elements) {
76 registerInstantiatedClass(compiler.stringClass, elements); 83 registerInstantiatedType(compiler.stringClass.rawType, elements);
84 }
85
86 void registerSetRuntimeTypeInfoFunction() {
87 if (setRuntimeTypeInfoFunction != null) return;
88 SourceString helperName = const SourceString('setRuntimeTypeInfo');
89 setRuntimeTypeInfoFunction = compiler.findHelper(helperName);
90 registerStaticUse(setRuntimeTypeInfoFunction);
77 } 91 }
78 92
79 void registerCreateRuntimeTypeFunction() { 93 void registerCreateRuntimeTypeFunction() {
80 if (createRuntimeTypeFunction != null) return; 94 if (createRuntimeTypeFunction != null) return;
81 SourceString helperName = const SourceString('createRuntimeType'); 95 SourceString helperName = const SourceString('createRuntimeType');
82 createRuntimeTypeFunction = compiler.findHelper(helperName); 96 createRuntimeTypeFunction = compiler.findHelper(helperName);
83 registerStaticUse(createRuntimeTypeFunction); 97 registerStaticUse(createRuntimeTypeFunction);
84 } 98 }
85 99
86 /** 100 /**
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 isEvaluatingConstant = oldIsEvaluatingConstant; 325 isEvaluatingConstant = oldIsEvaluatingConstant;
312 assert(result != null); 326 assert(result != null);
313 return result; 327 return result;
314 } 328 }
315 329
316 Constant visitNode(Node node) { 330 Constant visitNode(Node node) {
317 return signalNotCompileTimeConstant(node); 331 return signalNotCompileTimeConstant(node);
318 } 332 }
319 333
320 Constant visitLiteralBool(LiteralBool node) { 334 Constant visitLiteralBool(LiteralBool node) {
321 handler.registerInstantiatedClass(compiler.boolClass, elements); 335 handler.registerInstantiatedType(compiler.boolClass.rawType, elements);
322 return constantSystem.createBool(node.value); 336 return constantSystem.createBool(node.value);
323 } 337 }
324 338
325 Constant visitLiteralDouble(LiteralDouble node) { 339 Constant visitLiteralDouble(LiteralDouble node) {
326 handler.registerInstantiatedClass(compiler.doubleClass, elements); 340 handler.registerInstantiatedType(compiler.doubleClass.rawType, elements);
327 return constantSystem.createDouble(node.value); 341 return constantSystem.createDouble(node.value);
328 } 342 }
329 343
330 Constant visitLiteralInt(LiteralInt node) { 344 Constant visitLiteralInt(LiteralInt node) {
331 handler.registerInstantiatedClass(compiler.intClass, elements); 345 handler.registerInstantiatedType(compiler.intClass.rawType, elements);
332 return constantSystem.createInt(node.value); 346 return constantSystem.createInt(node.value);
333 } 347 }
334 348
335 Constant visitLiteralList(LiteralList node) { 349 Constant visitLiteralList(LiteralList node) {
336 if (!node.isConst()) { 350 if (!node.isConst()) {
337 return signalNotCompileTimeConstant(node); 351 return signalNotCompileTimeConstant(node);
338 } 352 }
339 List<Constant> arguments = <Constant>[]; 353 List<Constant> arguments = <Constant>[];
340 for (Link<Node> link = node.elements.nodes; 354 for (Link<Node> link = node.elements.nodes;
341 !link.isEmpty; 355 !link.isEmpty;
342 link = link.tail) { 356 link = link.tail) {
343 arguments.add(evaluateConstant(link.head)); 357 arguments.add(evaluateConstant(link.head));
344 } 358 }
345 // TODO(9476): get type parameters. 359 DartType type = elements.getType(node);
346 compiler.listClass.computeType(compiler); 360 handler.registerInstantiatedType(type, elements);
347 DartType type = compiler.listClass.rawType;
348 Constant constant = new ListConstant(type, arguments); 361 Constant constant = new ListConstant(type, arguments);
349 handler.registerCompileTimeConstant(constant, elements); 362 handler.registerCompileTimeConstant(constant, elements);
350 return constant; 363 return constant;
351 } 364 }
352 365
353 Constant visitLiteralMap(LiteralMap node) { 366 Constant visitLiteralMap(LiteralMap node) {
354 if (!node.isConst()) { 367 if (!node.isConst()) {
355 return signalNotCompileTimeConstant(node); 368 return signalNotCompileTimeConstant(node);
356 } 369 }
357 List<StringConstant> keys = <StringConstant>[]; 370 List<StringConstant> keys = <StringConstant>[];
(...skipping 14 matching lines...) Expand all
372 List<Constant> values = <Constant>[]; 385 List<Constant> values = <Constant>[];
373 Constant protoValue = null; 386 Constant protoValue = null;
374 for (StringConstant key in keys) { 387 for (StringConstant key in keys) {
375 if (key.value == MapConstant.PROTO_PROPERTY) { 388 if (key.value == MapConstant.PROTO_PROPERTY) {
376 protoValue = map[key]; 389 protoValue = map[key];
377 } else { 390 } else {
378 values.add(map[key]); 391 values.add(map[key]);
379 } 392 }
380 } 393 }
381 bool hasProtoKey = (protoValue != null); 394 bool hasProtoKey = (protoValue != null);
382 // TODO(9476): this should be a List<String> type. 395 InterfaceType sourceType = elements.getType(node);
383 compiler.listClass.computeType(compiler); 396 Link<DartType> arguments =
384 DartType keysType = compiler.listClass.rawType; 397 new Link<DartType>.fromList([compiler.stringClass.rawType]);
398 DartType keysType = new InterfaceType(compiler.listClass, arguments);
385 ListConstant keysList = new ListConstant(keysType, keys); 399 ListConstant keysList = new ListConstant(keysType, keys);
386 handler.registerCompileTimeConstant(keysList, elements); 400 handler.registerCompileTimeConstant(keysList, elements);
387 SourceString className = hasProtoKey 401 SourceString className = hasProtoKey
388 ? MapConstant.DART_PROTO_CLASS 402 ? MapConstant.DART_PROTO_CLASS
389 : MapConstant.DART_CLASS; 403 : MapConstant.DART_CLASS;
390 ClassElement classElement = compiler.jsHelperLibrary.find(className); 404 ClassElement classElement = compiler.jsHelperLibrary.find(className);
391 classElement.ensureResolved(compiler); 405 classElement.ensureResolved(compiler);
392 // TODO(9476): copy over the generic type. 406 Link<DartType> typeArgument = sourceType.typeArguments.tail;
393 DartType type = classElement.rawType; 407 InterfaceType type = new InterfaceType(classElement, typeArgument);
394 handler.registerInstantiatedClass(classElement, elements); 408 handler.registerInstantiatedType(type, elements);
395 Constant constant = new MapConstant(type, keysList, values, protoValue); 409 Constant constant = new MapConstant(type, keysList, values, protoValue);
396 handler.registerCompileTimeConstant(constant, elements); 410 handler.registerCompileTimeConstant(constant, elements);
397 return constant; 411 return constant;
398 } 412 }
399 413
400 Constant visitLiteralNull(LiteralNull node) { 414 Constant visitLiteralNull(LiteralNull node) {
401 return constantSystem.createNull(); 415 return constantSystem.createNull();
402 } 416 }
403 417
404 Constant visitLiteralString(LiteralString node) { 418 Constant visitLiteralString(LiteralString node) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 if (partString == null) return null; 452 if (partString == null) return null;
439 accumulator = new DartString.concat(accumulator, partString.value); 453 accumulator = new DartString.concat(accumulator, partString.value);
440 }; 454 };
441 handler.registerStringInstance(elements); 455 handler.registerStringInstance(elements);
442 return constantSystem.createString(accumulator, node); 456 return constantSystem.createString(accumulator, node);
443 } 457 }
444 458
445 Constant makeTypeConstant(Element element) { 459 Constant makeTypeConstant(Element element) {
446 DartType elementType = element.computeType(compiler).asRaw(); 460 DartType elementType = element.computeType(compiler).asRaw();
447 if (compiler.mirrorsEnabled) { 461 if (compiler.mirrorsEnabled) {
448 handler.registerInstantiatedClass(element, elements); 462 handler.registerInstantiatedType(elementType, elements);
449 } 463 }
450 DartType constantType = 464 DartType constantType =
451 compiler.backend.typeImplementation.computeType(compiler); 465 compiler.backend.typeImplementation.computeType(compiler);
452 Constant constant = new TypeConstant(elementType, constantType); 466 Constant constant = new TypeConstant(elementType, constantType);
453 // If we use a type literal in a constant, the compile time 467 // If we use a type literal in a constant, the compile time
454 // constant emitter will generate a call to the createRuntimeType 468 // constant emitter will generate a call to the createRuntimeType
455 // helper so we register a use of that. 469 // helper so we register a use of that.
456 handler.registerCreateRuntimeTypeFunction(); 470 handler.registerCreateRuntimeTypeFunction();
457 handler.registerCompileTimeConstant(constant, elements); 471 handler.registerCompileTimeConstant(constant, elements);
458 return constant; 472 return constant;
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 } 656 }
643 return compiledArguments; 657 return compiledArguments;
644 } 658 }
645 659
646 Constant visitNewExpression(NewExpression node) { 660 Constant visitNewExpression(NewExpression node) {
647 if (!node.isConst()) { 661 if (!node.isConst()) {
648 return signalNotCompileTimeConstant(node); 662 return signalNotCompileTimeConstant(node);
649 } 663 }
650 664
651 Send send = node.send; 665 Send send = node.send;
652 FunctionElement constructor = elements[send]; 666 FunctionElement functionElement = elements[send];
667 FunctionElement constructor = functionElement;
ngeoffray 2013/06/19 19:55:48 Didn't you say you removed this?
karlklose 2013/06/20 12:49:21 It was needed to preserve the original constructor
653 // TODO(ahe): This is nasty: we must eagerly analyze the 668 // TODO(ahe): This is nasty: we must eagerly analyze the
654 // constructor to ensure the redirectionTarget has been computed 669 // constructor to ensure the redirectionTarget has been computed
655 // correctly. Find a way to avoid this. 670 // correctly. Find a way to avoid this.
656 compiler.analyzeElement(constructor.declaration); 671 compiler.analyzeElement(constructor.declaration);
657 constructor = constructor.redirectionTarget; 672 constructor = constructor.redirectionTarget;
658 ClassElement classElement = constructor.getEnclosingClass(); 673 ClassElement classElement = constructor.getEnclosingClass();
659 // The constructor must be an implementation to ensure that field 674 // The constructor must be an implementation to ensure that field
660 // initializers are handled correctly. 675 // initializers are handled correctly.
661 constructor = constructor.implementation; 676 constructor = constructor.implementation;
662 assert(invariant(node, constructor.isImplementation)); 677 assert(invariant(node, constructor.isImplementation));
663 678
664 Selector selector = elements.getSelector(send); 679 Selector selector = elements.getSelector(send);
665 List<Constant> arguments = evaluateArgumentsToConstructor( 680 List<Constant> arguments = evaluateArgumentsToConstructor(
666 node, selector, send.arguments, constructor); 681 node, selector, send.arguments, constructor);
667 ConstructorEvaluator evaluator = 682 ConstructorEvaluator evaluator =
668 new ConstructorEvaluator(node, constructor, handler, compiler); 683 new ConstructorEvaluator(node, constructor, handler, compiler);
669 evaluator.evaluateConstructorFieldValues(arguments); 684 evaluator.evaluateConstructorFieldValues(arguments);
670 List<Constant> jsNewArguments = evaluator.buildJsNewArguments(classElement); 685 List<Constant> jsNewArguments = evaluator.buildJsNewArguments(classElement);
671 686
672 handler.registerInstantiatedClass(classElement, elements); 687 InterfaceType type = elements.getType(node);
673 // TODO(9476): take generic types into account. 688 bool isRedirected = functionElement.isRedirectingFactory;
674 classElement.computeType(compiler); 689 if (isRedirected) {
675 DartType type = classElement.rawType; 690 type = functionElement.computeTargetType(compiler, type);
691 }
692
693 handler.registerInstantiatedType(type, elements);
676 Constant constant = new ConstructedConstant(type, jsNewArguments); 694 Constant constant = new ConstructedConstant(type, jsNewArguments);
677 handler.registerCompileTimeConstant(constant, elements); 695 handler.registerCompileTimeConstant(constant, elements);
678 return constant; 696 return constant;
679 } 697 }
680 698
681 Constant visitParenthesizedExpression(ParenthesizedExpression node) { 699 Constant visitParenthesizedExpression(ParenthesizedExpression node) {
682 return node.expression.accept(this); 700 return node.expression.accept(this);
683 } 701 }
684 702
685 error(Node node) { 703 error(Node node) {
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
890 if (fieldValue == null) { 908 if (fieldValue == null) {
891 // Use the default value. 909 // Use the default value.
892 fieldValue = handler.compileConstant(field); 910 fieldValue = handler.compileConstant(field);
893 } 911 }
894 jsNewArguments.add(fieldValue); 912 jsNewArguments.add(fieldValue);
895 }, 913 },
896 includeSuperAndInjectedMembers: true); 914 includeSuperAndInjectedMembers: true);
897 return jsNewArguments; 915 return jsNewArguments;
898 } 916 }
899 } 917 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698