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

Side by Side Diff: pkg/compiler/lib/src/compile_time_constants.dart

Issue 1109393012: Allow use of deferred type-literals in non-constant contexts. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 7 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 library dart2js.compile_time_constant_evaluator; 5 library dart2js.compile_time_constant_evaluator;
6 6
7 import 'constant_system_dart.dart'; 7 import 'constant_system_dart.dart';
8 import 'constants/constant_system.dart'; 8 import 'constants/constant_system.dart';
9 import 'constants/expressions.dart'; 9 import 'constants/expressions.dart';
10 import 'constants/values.dart'; 10 import 'constants/values.dart';
(...skipping 30 matching lines...) Expand all
41 /// if possible. 41 /// if possible.
42 void compileVariable(VariableElement element); 42 void compileVariable(VariableElement element);
43 43
44 /// Compiles the compile-time constant for [node], or reports an error if 44 /// Compiles the compile-time constant for [node], or reports an error if
45 /// [node] is not a compile-time constant. 45 /// [node] is not a compile-time constant.
46 /// 46 ///
47 /// Depending on implementation, the constant compiler might also compute 47 /// Depending on implementation, the constant compiler might also compute
48 /// the compile-time constant for the backend interpretation of constants. 48 /// the compile-time constant for the backend interpretation of constants.
49 /// 49 ///
50 /// The returned constant is always of the frontend interpretation. 50 /// The returned constant is always of the frontend interpretation.
51 ConstantExpression compileNode(Node node, TreeElements elements); 51 ConstantExpression compileNode(Node node, TreeElements elements,
52 {bool enforceConst: true});
Johnni Winther 2015/04/30 09:15:03 Document [enforceConst].
sigurdm 2015/04/30 11:21:44 Done.
52 53
53 /// Compiles the compile-time constant for the value [metadata], or reports an 54 /// Compiles the compile-time constant for the value [metadata], or reports an
54 /// error if the value is not a compile-time constant. 55 /// error if the value is not a compile-time constant.
55 /// 56 ///
56 /// Depending on implementation, the constant compiler might also compute 57 /// Depending on implementation, the constant compiler might also compute
57 /// the compile-time constant for the backend interpretation of constants. 58 /// the compile-time constant for the backend interpretation of constants.
58 /// 59 ///
59 /// The returned constant is always of the frontend interpretation. 60 /// The returned constant is always of the frontend interpretation.
60 ConstantExpression compileMetadata(MetadataAnnotation metadata, 61 ConstantExpression compileMetadata(MetadataAnnotation metadata,
61 Node node, 62 Node node,
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 ConstantExpression compileNodeWithDefinitions(Node node, 207 ConstantExpression compileNodeWithDefinitions(Node node,
207 TreeElements definitions, 208 TreeElements definitions,
208 {bool isConst: true}) { 209 {bool isConst: true}) {
209 assert(node != null); 210 assert(node != null);
210 CompileTimeConstantEvaluator evaluator = new CompileTimeConstantEvaluator( 211 CompileTimeConstantEvaluator evaluator = new CompileTimeConstantEvaluator(
211 this, definitions, compiler, isConst: isConst); 212 this, definitions, compiler, isConst: isConst);
212 AstConstant constant = evaluator.evaluate(node); 213 AstConstant constant = evaluator.evaluate(node);
213 return constant != null ? constant.expression : null; 214 return constant != null ? constant.expression : null;
214 } 215 }
215 216
216 ConstantExpression compileNode(Node node, TreeElements elements) { 217 ConstantExpression compileNode(Node node, TreeElements elements,
217 return compileNodeWithDefinitions(node, elements); 218 {bool enforceConst: true}) {
219 return compileNodeWithDefinitions(node, elements, isConst: enforceConst);
218 } 220 }
219 221
220 ConstantExpression compileMetadata(MetadataAnnotation metadata, 222 ConstantExpression compileMetadata(MetadataAnnotation metadata,
221 Node node, 223 Node node,
222 TreeElements elements) { 224 TreeElements elements) {
223 return compileNodeWithDefinitions(node, elements); 225 return compileNodeWithDefinitions(node, elements);
224 } 226 }
225 227
226 void forgetElement(Element element) { 228 void forgetElement(Element element) {
227 initialVariableValues.remove(element); 229 initialVariableValues.remove(element);
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 text, 464 text,
463 constantSystem.createString(new LiteralDartString(text))))]; 465 constantSystem.createString(new LiteralDartString(text))))];
464 AstConstant constant = makeConstructedConstant( 466 AstConstant constant = makeConstructedConstant(
465 compiler, handler, context, node, type, compiler.symbolConstructor, 467 compiler, handler, context, node, type, compiler.symbolConstructor,
466 CallStructure.ONE_ARG, 468 CallStructure.ONE_ARG,
467 arguments, arguments); 469 arguments, arguments);
468 return new AstConstant( 470 return new AstConstant(
469 context, node, new SymbolConstantExpression(constant.value, text)); 471 context, node, new SymbolConstantExpression(constant.value, text));
470 } 472 }
471 473
472 AstConstant makeTypeConstant(Node node, DartType elementType) { 474 ConstantExpression makeTypeConstant(DartType elementType) {
473 DartType constantType = 475 DartType constantType =
474 compiler.backend.typeImplementation.computeType(compiler); 476 compiler.backend.typeImplementation.computeType(compiler);
475 return new AstConstant( 477 return new TypeConstantExpression(
476 context, node, new TypeConstantExpression( 478 new TypeConstantValue(elementType, constantType), elementType);
477 new TypeConstantValue(elementType, constantType),
478 elementType));
479 } 479 }
480 480
481 /// Returns true if the prefix of the send resolves to a deferred import 481 /// Returns true if the prefix of the send resolves to a deferred import
482 /// prefix. 482 /// prefix.
483 bool isDeferredUse(Send send) { 483 bool isDeferredUse(Send send) {
484 if (send == null) return false; 484 if (send == null) return false;
485 return compiler.deferredLoadTask 485 return compiler.deferredLoadTask
486 .deferredPrefixElement(send, elements) != null; 486 .deferredPrefixElement(send, elements) != null;
487 } 487 }
488 488
489 AstConstant visitIdentifier(Identifier node) { 489 AstConstant visitIdentifier(Identifier node) {
490 Element element = elements[node]; 490 Element element = elements[node];
491 if (Elements.isClass(element) || Elements.isTypedef(element)) { 491 if (Elements.isClass(element) || Elements.isTypedef(element)) {
492 TypeDeclarationElement typeDeclarationElement = element; 492 TypeDeclarationElement typeDeclarationElement = element;
493 DartType type = typeDeclarationElement.rawType; 493 DartType type = typeDeclarationElement.rawType;
494 return makeTypeConstant(node, type); 494 return new AstConstant(element, node, makeTypeConstant(type));
495 } 495 }
496 return signalNotCompileTimeConstant(node); 496 return signalNotCompileTimeConstant(node);
497 } 497 }
498 498
499 // TODO(floitsch): provide better error-messages. 499 // TODO(floitsch): provide better error-messages.
500 AstConstant visitSend(Send send) { 500 AstConstant visitSend(Send send) {
501 Element element = elements[send]; 501 Element element = elements[send];
502 if (send.isPropertyAccess) { 502 if (send.isPropertyAccess) {
503 if (isDeferredUse(send)) { 503 ConstantExpression result;
504 return signalNotCompileTimeConstant(send, 504
505 message: MessageKind.DEFERRED_COMPILE_TIME_CONSTANT);
506 }
507 if (Elements.isStaticOrTopLevelFunction(element)) { 505 if (Elements.isStaticOrTopLevelFunction(element)) {
508 FunctionElementX function = element; 506 FunctionElementX function = element;
509 function.computeType(compiler); 507 function.computeType(compiler);
510 return new AstConstant( 508 result = new FunctionConstantExpression(
511 context, send, new FunctionConstantExpression( 509 new FunctionConstantValue(function), function);
512 new FunctionConstantValue(function),
513 function));
514 } else if (Elements.isStaticOrTopLevelField(element)) { 510 } else if (Elements.isStaticOrTopLevelField(element)) {
515 ConstantExpression result; 511 ConstantExpression elementExpression;
516 if (element.isConst) { 512 if (element.isConst) {
517 result = handler.compileConstant(element); 513 elementExpression = handler.compileConstant(element);
518 } else if (element.isFinal && !isEvaluatingConstant) { 514 } else if (element.isFinal && !isEvaluatingConstant) {
519 result = handler.compileVariable(element); 515 elementExpression = handler.compileVariable(element);
520 } 516 }
521 if (result != null) { 517 if (elementExpression != null) {
522 return new AstConstant( 518 result =
523 context, send, 519 new VariableConstantExpression(elementExpression.value, element);
524 new VariableConstantExpression(result.value, element));
525 } 520 }
526 } else if (Elements.isClass(element) || Elements.isTypedef(element)) { 521 } else if (Elements.isClass(element) || Elements.isTypedef(element)) {
527 assert(elements.isTypeLiteral(send)); 522 assert(elements.isTypeLiteral(send));
528 return makeTypeConstant(send, elements.getTypeLiteralType(send)); 523 result = makeTypeConstant(elements.getTypeLiteralType(send));
529 } else if (send.receiver != null) { 524 } else if (send.receiver != null) {
530 if (send.selector.asIdentifier().source == "length") { 525 if (send.selector.asIdentifier().source == "length") {
531 AstConstant left = evaluate(send.receiver); 526 AstConstant left = evaluate(send.receiver);
532 if (left != null && left.value.isString) { 527 if (left != null && left.value.isString) {
533 StringConstantValue stringConstantValue = left.value; 528 StringConstantValue stringConstantValue = left.value;
534 DartString string = stringConstantValue.primitiveValue; 529 DartString string = stringConstantValue.primitiveValue;
535 IntConstantValue length = constantSystem.createInt(string.length); 530 IntConstantValue length = constantSystem.createInt(string.length);
536 return new AstConstant( 531 result = new VariableConstantExpression(length, element);
537 context, send, new VariableConstantExpression(length, element));
538 } 532 }
539 } 533 }
540 // Fall through to error handling. 534 // Fall through to error handling.
541 } else if (!Elements.isUnresolved(element) 535 } else if (!Elements.isUnresolved(element)
542 && element.isVariable 536 && element.isVariable
543 && element.isConst) { 537 && element.isConst) {
544 ConstantExpression result = handler.compileConstant(element); 538 ConstantExpression variableExpression =
545 if (result != null) { 539 handler.compileConstant(element);
546 return new AstConstant( 540 if (variableExpression != null) {
547 context, send, 541 result = new VariableConstantExpression(variableExpression.value,
548 new VariableConstantExpression(result.value, element)); 542 element);
549 } 543 }
550 } 544 }
551 return signalNotCompileTimeConstant(send); 545 if (result == null) {
546 return signalNotCompileTimeConstant(send);
547 }
548 if (isDeferredUse(send)) {
549 if (isEvaluatingConstant) {
550 error(send, MessageKind.DEFERRED_COMPILE_TIME_CONSTANT);
551 }
552 PrefixElement prefix = compiler.deferredLoadTask
553 .deferredPrefixElement(send, elements);
554 result = new DeferredConstantExpression(
555 new DeferredConstantValue(result.value, prefix),
556 result,
557 prefix);
558 compiler.deferredLoadTask
559 .registerConstantDeferredUse(result.value, prefix);
560 }
561 return new AstConstant(context, send, result);
552 } else if (send.isCall) { 562 } else if (send.isCall) {
553 if (element == compiler.identicalFunction 563 if (element == compiler.identicalFunction
554 && send.argumentCount() == 2) { 564 && send.argumentCount() == 2) {
555 AstConstant left = evaluate(send.argumentsNode.nodes.head); 565 AstConstant left = evaluate(send.argumentsNode.nodes.head);
556 AstConstant right = evaluate(send.argumentsNode.nodes.tail.head); 566 AstConstant right = evaluate(send.argumentsNode.nodes.tail.head);
557 if (left == null || right == null) { 567 if (left == null || right == null) {
558 return null; 568 return null;
559 } 569 }
560 ConstantValue result = 570 ConstantValue result =
561 constantSystem.identity.fold(left.value, right.value); 571 constantSystem.identity.fold(left.value, right.value);
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 Map<Node, AstConstant> concreteArgumentMap = 746 Map<Node, AstConstant> concreteArgumentMap =
737 <Node, AstConstant>{}; 747 <Node, AstConstant>{};
738 for (Link<Node> link = send.arguments; !link.isEmpty; link = link.tail) { 748 for (Link<Node> link = send.arguments; !link.isEmpty; link = link.tail) {
739 Node argument = link.head; 749 Node argument = link.head;
740 NamedArgument namedArgument = argument.asNamedArgument(); 750 NamedArgument namedArgument = argument.asNamedArgument();
741 if (namedArgument != null) { 751 if (namedArgument != null) {
742 argument = namedArgument.expression; 752 argument = namedArgument.expression;
743 } 753 }
744 concreteArgumentMap[argument] = evaluateConstant(argument); 754 concreteArgumentMap[argument] = evaluateConstant(argument);
745 } 755 }
746
747 List<AstConstant> normalizedArguments = 756 List<AstConstant> normalizedArguments =
748 evaluateArgumentsToConstructor( 757 evaluateArgumentsToConstructor(
749 node, callStructure, send.arguments, constructor.implementation, 758 node, callStructure, send.arguments, constructor.implementation,
750 compileArgument: (node) => concreteArgumentMap[node]); 759 compileArgument: (node) => concreteArgumentMap[node]);
751 List<AstConstant> concreteArguments = 760 List<AstConstant> concreteArguments =
752 concreteArgumentMap.values.toList(); 761 concreteArgumentMap.values.toList();
753 762
754 if (constructor == compiler.intEnvironment || 763 if (constructor == compiler.intEnvironment ||
755 constructor == compiler.boolEnvironment || 764 constructor == compiler.boolEnvironment ||
756 constructor == compiler.stringEnvironment) { 765 constructor == compiler.stringEnvironment) {
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
1147 ConstantValue get value => expression.value; 1156 ConstantValue get value => expression.value;
1148 1157
1149 String toString() => expression.toString(); 1158 String toString() => expression.toString();
1150 } 1159 }
1151 1160
1152 /// A synthetic constant used to recover from errors. 1161 /// A synthetic constant used to recover from errors.
1153 class ErroneousAstConstant extends AstConstant { 1162 class ErroneousAstConstant extends AstConstant {
1154 ErroneousAstConstant(Element element, Node node) 1163 ErroneousAstConstant(Element element, Node node)
1155 : super(element, node, new ErroneousConstantExpression()); 1164 : super(element, node, new ErroneousConstantExpression());
1156 } 1165 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/constants/expressions.dart » ('j') | pkg/compiler/lib/src/deferred_load.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698