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

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
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/constants.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 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 &&
65 !type.isRaw &&
66 compiler.backend.needsRti(type.element)) {
67 registerSetRuntimeTypeInfoFunction();
68 }
61 } 69 }
62 70
63 void registerStaticUse(Element element) { 71 void registerStaticUse(Element element) {
64 if (isMetadata) return; 72 if (isMetadata) return;
65 compiler.analyzeElement(element.declaration); 73 compiler.analyzeElement(element.declaration);
66 compiler.enqueuer.codegen.registerStaticUse(element); 74 compiler.enqueuer.codegen.registerStaticUse(element);
67 } 75 }
68 76
69 void registerGetOfStaticFunction(FunctionElement element) { 77 void registerGetOfStaticFunction(FunctionElement element) {
70 if (isMetadata) return; 78 if (isMetadata) return;
71 compiler.analyzeElement(element.declaration); 79 compiler.analyzeElement(element.declaration);
72 compiler.enqueuer.codegen.registerGetOfStaticFunction(element); 80 compiler.enqueuer.codegen.registerGetOfStaticFunction(element);
73 } 81 }
74 82
75 void registerStringInstance(TreeElements elements) { 83 void registerStringInstance(TreeElements elements) {
76 registerInstantiatedClass(compiler.stringClass, elements); 84 registerInstantiatedType(compiler.stringClass.rawType, elements);
85 }
86
87 void registerSetRuntimeTypeInfoFunction() {
88 if (setRuntimeTypeInfoFunction != null) return;
89 SourceString helperName = const SourceString('setRuntimeTypeInfo');
90 setRuntimeTypeInfoFunction = compiler.findHelper(helperName);
91 registerStaticUse(setRuntimeTypeInfoFunction);
77 } 92 }
78 93
79 void registerCreateRuntimeTypeFunction() { 94 void registerCreateRuntimeTypeFunction() {
80 if (createRuntimeTypeFunction != null) return; 95 if (createRuntimeTypeFunction != null) return;
81 SourceString helperName = const SourceString('createRuntimeType'); 96 SourceString helperName = const SourceString('createRuntimeType');
82 createRuntimeTypeFunction = compiler.findHelper(helperName); 97 createRuntimeTypeFunction = compiler.findHelper(helperName);
83 registerStaticUse(createRuntimeTypeFunction); 98 registerStaticUse(createRuntimeTypeFunction);
84 } 99 }
85 100
86 /** 101 /**
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 isEvaluatingConstant = oldIsEvaluatingConstant; 326 isEvaluatingConstant = oldIsEvaluatingConstant;
312 assert(result != null); 327 assert(result != null);
313 return result; 328 return result;
314 } 329 }
315 330
316 Constant visitNode(Node node) { 331 Constant visitNode(Node node) {
317 return signalNotCompileTimeConstant(node); 332 return signalNotCompileTimeConstant(node);
318 } 333 }
319 334
320 Constant visitLiteralBool(LiteralBool node) { 335 Constant visitLiteralBool(LiteralBool node) {
321 handler.registerInstantiatedClass(compiler.boolClass, elements); 336 handler.registerInstantiatedType(compiler.boolClass.rawType, elements);
322 return constantSystem.createBool(node.value); 337 return constantSystem.createBool(node.value);
323 } 338 }
324 339
325 Constant visitLiteralDouble(LiteralDouble node) { 340 Constant visitLiteralDouble(LiteralDouble node) {
326 handler.registerInstantiatedClass(compiler.doubleClass, elements); 341 handler.registerInstantiatedType(compiler.doubleClass.rawType, elements);
327 return constantSystem.createDouble(node.value); 342 return constantSystem.createDouble(node.value);
328 } 343 }
329 344
330 Constant visitLiteralInt(LiteralInt node) { 345 Constant visitLiteralInt(LiteralInt node) {
331 handler.registerInstantiatedClass(compiler.intClass, elements); 346 handler.registerInstantiatedType(compiler.intClass.rawType, elements);
332 return constantSystem.createInt(node.value); 347 return constantSystem.createInt(node.value);
333 } 348 }
334 349
335 Constant visitLiteralList(LiteralList node) { 350 Constant visitLiteralList(LiteralList node) {
336 if (!node.isConst()) { 351 if (!node.isConst()) {
337 return signalNotCompileTimeConstant(node); 352 return signalNotCompileTimeConstant(node);
338 } 353 }
339 List<Constant> arguments = <Constant>[]; 354 List<Constant> arguments = <Constant>[];
340 for (Link<Node> link = node.elements.nodes; 355 for (Link<Node> link = node.elements.nodes;
341 !link.isEmpty; 356 !link.isEmpty;
342 link = link.tail) { 357 link = link.tail) {
343 arguments.add(evaluateConstant(link.head)); 358 arguments.add(evaluateConstant(link.head));
344 } 359 }
345 // TODO(9476): get type parameters. 360 DartType type = elements.getType(node);
346 compiler.listClass.computeType(compiler); 361 handler.registerInstantiatedType(type, elements);
347 DartType type = compiler.listClass.rawType;
348 Constant constant = new ListConstant(type, arguments); 362 Constant constant = new ListConstant(type, arguments);
349 handler.registerCompileTimeConstant(constant, elements); 363 handler.registerCompileTimeConstant(constant, elements);
350 return constant; 364 return constant;
351 } 365 }
352 366
353 Constant visitLiteralMap(LiteralMap node) { 367 Constant visitLiteralMap(LiteralMap node) {
354 if (!node.isConst()) { 368 if (!node.isConst()) {
355 return signalNotCompileTimeConstant(node); 369 return signalNotCompileTimeConstant(node);
356 } 370 }
357 List<StringConstant> keys = <StringConstant>[]; 371 List<StringConstant> keys = <StringConstant>[];
(...skipping 14 matching lines...) Expand all
372 List<Constant> values = <Constant>[]; 386 List<Constant> values = <Constant>[];
373 Constant protoValue = null; 387 Constant protoValue = null;
374 for (StringConstant key in keys) { 388 for (StringConstant key in keys) {
375 if (key.value == MapConstant.PROTO_PROPERTY) { 389 if (key.value == MapConstant.PROTO_PROPERTY) {
376 protoValue = map[key]; 390 protoValue = map[key];
377 } else { 391 } else {
378 values.add(map[key]); 392 values.add(map[key]);
379 } 393 }
380 } 394 }
381 bool hasProtoKey = (protoValue != null); 395 bool hasProtoKey = (protoValue != null);
382 // TODO(9476): this should be a List<String> type. 396 InterfaceType sourceType = elements.getType(node);
383 compiler.listClass.computeType(compiler); 397 Link<DartType> arguments =
384 DartType keysType = compiler.listClass.rawType; 398 new Link<DartType>.fromList([compiler.stringClass.rawType]);
399 DartType keysType = new InterfaceType(compiler.listClass, arguments);
385 ListConstant keysList = new ListConstant(keysType, keys); 400 ListConstant keysList = new ListConstant(keysType, keys);
386 handler.registerCompileTimeConstant(keysList, elements); 401 handler.registerCompileTimeConstant(keysList, elements);
387 SourceString className = hasProtoKey 402 SourceString className = hasProtoKey
388 ? MapConstant.DART_PROTO_CLASS 403 ? MapConstant.DART_PROTO_CLASS
389 : MapConstant.DART_CLASS; 404 : MapConstant.DART_CLASS;
390 ClassElement classElement = compiler.jsHelperLibrary.find(className); 405 ClassElement classElement = compiler.jsHelperLibrary.find(className);
391 classElement.ensureResolved(compiler); 406 classElement.ensureResolved(compiler);
392 // TODO(9476): copy over the generic type. 407 Link<DartType> typeArgument = sourceType.typeArguments.tail;
393 DartType type = classElement.rawType; 408 InterfaceType type = new InterfaceType(classElement, typeArgument);
394 handler.registerInstantiatedClass(classElement, elements); 409 handler.registerInstantiatedType(type, elements);
395 Constant constant = new MapConstant(type, keysList, values, protoValue); 410 Constant constant = new MapConstant(type, keysList, values, protoValue);
396 handler.registerCompileTimeConstant(constant, elements); 411 handler.registerCompileTimeConstant(constant, elements);
397 return constant; 412 return constant;
398 } 413 }
399 414
400 Constant visitLiteralNull(LiteralNull node) { 415 Constant visitLiteralNull(LiteralNull node) {
401 return constantSystem.createNull(); 416 return constantSystem.createNull();
402 } 417 }
403 418
404 Constant visitLiteralString(LiteralString node) { 419 Constant visitLiteralString(LiteralString node) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 if (partString == null) return null; 453 if (partString == null) return null;
439 accumulator = new DartString.concat(accumulator, partString.value); 454 accumulator = new DartString.concat(accumulator, partString.value);
440 }; 455 };
441 handler.registerStringInstance(elements); 456 handler.registerStringInstance(elements);
442 return constantSystem.createString(accumulator, node); 457 return constantSystem.createString(accumulator, node);
443 } 458 }
444 459
445 Constant makeTypeConstant(Element element) { 460 Constant makeTypeConstant(Element element) {
446 DartType elementType = element.computeType(compiler).asRaw(); 461 DartType elementType = element.computeType(compiler).asRaw();
447 if (compiler.mirrorsEnabled) { 462 if (compiler.mirrorsEnabled) {
448 handler.registerInstantiatedClass(element, elements); 463 handler.registerInstantiatedType(elementType, elements);
449 } 464 }
450 DartType constantType = 465 DartType constantType =
451 compiler.backend.typeImplementation.computeType(compiler); 466 compiler.backend.typeImplementation.computeType(compiler);
452 Constant constant = new TypeConstant(elementType, constantType); 467 Constant constant = new TypeConstant(elementType, constantType);
453 // If we use a type literal in a constant, the compile time 468 // If we use a type literal in a constant, the compile time
454 // constant emitter will generate a call to the createRuntimeType 469 // constant emitter will generate a call to the createRuntimeType
455 // helper so we register a use of that. 470 // helper so we register a use of that.
456 handler.registerCreateRuntimeTypeFunction(); 471 handler.registerCreateRuntimeTypeFunction();
457 handler.registerCompileTimeConstant(constant, elements); 472 handler.registerCompileTimeConstant(constant, elements);
458 return constant; 473 return constant;
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 if (!node.isConst()) { 662 if (!node.isConst()) {
648 return signalNotCompileTimeConstant(node); 663 return signalNotCompileTimeConstant(node);
649 } 664 }
650 665
651 Send send = node.send; 666 Send send = node.send;
652 FunctionElement constructor = elements[send]; 667 FunctionElement constructor = elements[send];
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);
672
673 InterfaceType type = elements.getType(node);
674 if ( constructor.isRedirectingFactory) {
675 type = constructor.computeTargetType(compiler, type);
676 }
677
657 constructor = constructor.redirectionTarget; 678 constructor = constructor.redirectionTarget;
658 ClassElement classElement = constructor.getEnclosingClass(); 679 ClassElement classElement = constructor.getEnclosingClass();
659 // The constructor must be an implementation to ensure that field 680 // The constructor must be an implementation to ensure that field
660 // initializers are handled correctly. 681 // initializers are handled correctly.
661 constructor = constructor.implementation; 682 constructor = constructor.implementation;
662 assert(invariant(node, constructor.isImplementation)); 683 assert(invariant(node, constructor.isImplementation));
663 684
664 Selector selector = elements.getSelector(send); 685 Selector selector = elements.getSelector(send);
665 List<Constant> arguments = evaluateArgumentsToConstructor( 686 List<Constant> arguments = evaluateArgumentsToConstructor(
666 node, selector, send.arguments, constructor); 687 node, selector, send.arguments, constructor);
667 ConstructorEvaluator evaluator = 688 ConstructorEvaluator evaluator =
668 new ConstructorEvaluator(node, constructor, handler, compiler); 689 new ConstructorEvaluator(node, constructor, handler, compiler);
669 evaluator.evaluateConstructorFieldValues(arguments); 690 evaluator.evaluateConstructorFieldValues(arguments);
670 List<Constant> jsNewArguments = evaluator.buildJsNewArguments(classElement); 691 List<Constant> jsNewArguments = evaluator.buildJsNewArguments(classElement);
671 692
672 handler.registerInstantiatedClass(classElement, elements); 693 handler.registerInstantiatedType(type, elements);
673 // TODO(9476): take generic types into account.
674 classElement.computeType(compiler);
675 DartType type = classElement.rawType;
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
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/constants.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698