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

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

Issue 1859343004: dartfmt pkg/compiler (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 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
« no previous file with comments | « pkg/compiler/lib/src/common/work.dart ('k') | pkg/compiler/lib/src/compiler.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 library dart2js.compile_time_constant_evaluator; 5 library dart2js.compile_time_constant_evaluator;
6 6
7 import 'common.dart'; 7 import 'common.dart';
8 import 'common/resolution.dart' show 8 import 'common/resolution.dart' show Resolution;
9 Resolution; 9 import 'common/tasks.dart' show CompilerTask;
10 import 'common/tasks.dart' show 10 import 'compiler.dart' show Compiler;
11 CompilerTask;
12 import 'compiler.dart' show
13 Compiler;
14 import 'constant_system_dart.dart'; 11 import 'constant_system_dart.dart';
15 import 'constants/constant_system.dart'; 12 import 'constants/constant_system.dart';
16 import 'constants/evaluation.dart'; 13 import 'constants/evaluation.dart';
17 import 'constants/expressions.dart'; 14 import 'constants/expressions.dart';
18 import 'constants/values.dart'; 15 import 'constants/values.dart';
19 import 'core_types.dart' show 16 import 'core_types.dart' show CoreTypes;
20 CoreTypes;
21 import 'dart_types.dart'; 17 import 'dart_types.dart';
22 import 'elements/elements.dart'; 18 import 'elements/elements.dart';
23 import 'elements/modelx.dart' show 19 import 'elements/modelx.dart' show FunctionElementX;
24 FunctionElementX; 20 import 'resolution/tree_elements.dart' show TreeElements;
25 import 'resolution/tree_elements.dart' show
26 TreeElements;
27 import 'resolution/operators.dart'; 21 import 'resolution/operators.dart';
28 import 'tree/tree.dart'; 22 import 'tree/tree.dart';
29 import 'util/util.dart' show 23 import 'util/util.dart' show Link;
30 Link; 24 import 'universe/call_structure.dart' show CallStructure;
31 import 'universe/call_structure.dart' show
32 CallStructure;
33 25
34 /// A [ConstantEnvironment] provides access for constants compiled for variable 26 /// A [ConstantEnvironment] provides access for constants compiled for variable
35 /// initializers. 27 /// initializers.
36 abstract class ConstantEnvironment { 28 abstract class ConstantEnvironment {
37 /// The [ConstantSystem] used by this environment. 29 /// The [ConstantSystem] used by this environment.
38 ConstantSystem get constantSystem; 30 ConstantSystem get constantSystem;
39 31
40 /// Returns the constant value computed for [expression]. 32 /// Returns the constant value computed for [expression].
41 // TODO(johnniwinther): Support directly evaluation of [expression]. 33 // TODO(johnniwinther): Support directly evaluation of [expression].
42 ConstantValue getConstantValue(ConstantExpression expression); 34 ConstantValue getConstantValue(ConstantExpression expression);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 ConstantExpression compileNode(Node node, TreeElements elements, 72 ConstantExpression compileNode(Node node, TreeElements elements,
81 {bool enforceConst: true}); 73 {bool enforceConst: true});
82 74
83 /// Compiles the compile-time constant for the value [metadata], or reports an 75 /// Compiles the compile-time constant for the value [metadata], or reports an
84 /// error if the value is not a compile-time constant. 76 /// error if the value is not a compile-time constant.
85 /// 77 ///
86 /// Depending on implementation, the constant compiler might also compute 78 /// Depending on implementation, the constant compiler might also compute
87 /// the compile-time constant for the backend interpretation of constants. 79 /// the compile-time constant for the backend interpretation of constants.
88 /// 80 ///
89 /// The returned constant is always of the frontend interpretation. 81 /// The returned constant is always of the frontend interpretation.
90 ConstantExpression compileMetadata(MetadataAnnotation metadata, 82 ConstantExpression compileMetadata(
91 Node node, 83 MetadataAnnotation metadata, Node node, TreeElements elements);
92 TreeElements elements);
93 84
94 /// Evaluates [constant] and caches the result. 85 /// Evaluates [constant] and caches the result.
95 // TODO(johnniwinther): Remove when all constants are evaluated. 86 // TODO(johnniwinther): Remove when all constants are evaluated.
96 void evaluate(ConstantExpression constant); 87 void evaluate(ConstantExpression constant);
97 } 88 }
98 89
99 /// A [BackendConstantEnvironment] provides access to constants needed for 90 /// A [BackendConstantEnvironment] provides access to constants needed for
100 /// backend implementation. 91 /// backend implementation.
101 abstract class BackendConstantEnvironment extends ConstantEnvironment { 92 abstract class BackendConstantEnvironment extends ConstantEnvironment {
102 /// Returns the compile-time constant value associated with [node]. 93 /// Returns the compile-time constant value associated with [node].
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 } 166 }
176 167
177 ConstantExpression compileConstant(VariableElement element) { 168 ConstantExpression compileConstant(VariableElement element) {
178 return internalCompileVariable(element, true, true); 169 return internalCompileVariable(element, true, true);
179 } 170 }
180 171
181 @override 172 @override
182 void evaluate(ConstantExpression constant) { 173 void evaluate(ConstantExpression constant) {
183 constantValueMap.putIfAbsent(constant, () { 174 constantValueMap.putIfAbsent(constant, () {
184 return constant.evaluate( 175 return constant.evaluate(
185 new _CompilerEnvironment(compiler), 176 new _CompilerEnvironment(compiler), constantSystem);
186 constantSystem);
187 }); 177 });
188 } 178 }
189 179
190 ConstantExpression compileVariable(VariableElement element) { 180 ConstantExpression compileVariable(VariableElement element) {
191 return internalCompileVariable(element, false, true); 181 return internalCompileVariable(element, false, true);
192 } 182 }
193 183
194 /// Compile [element] into a constant expression. If [isConst] is true, 184 /// Compile [element] into a constant expression. If [isConst] is true,
195 /// then [element] is a constant variable. If [checkType] is true, then 185 /// then [element] is a constant variable. If [checkType] is true, then
196 /// report an error if [element] does not typecheck. 186 /// report an error if [element] does not typecheck.
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 node, element.messageKind, element.messageArguments); 246 node, element.messageKind, element.messageArguments);
257 } else { 247 } else {
258 // We need to throw an exception at runtime. 248 // We need to throw an exception at runtime.
259 expression = null; 249 expression = null;
260 } 250 }
261 } else { 251 } else {
262 DartType constantType = value.getType(coreTypes); 252 DartType constantType = value.getType(coreTypes);
263 if (!constantSystem.isSubtype( 253 if (!constantSystem.isSubtype(
264 compiler.types, constantType, elementType)) { 254 compiler.types, constantType, elementType)) {
265 if (isConst) { 255 if (isConst) {
266 reporter.reportErrorMessage( 256 reporter.reportErrorMessage(node, MessageKind.NOT_ASSIGNABLE,
267 node, 257 {'fromType': constantType, 'toType': elementType});
268 MessageKind.NOT_ASSIGNABLE,
269 {'fromType': constantType,
270 'toType': elementType});
271 } else { 258 } else {
272 // If the field cannot be lazily initialized, we will throw 259 // If the field cannot be lazily initialized, we will throw
273 // the exception at runtime. 260 // the exception at runtime.
274 expression = null; 261 expression = null;
275 } 262 }
276 } 263 }
277 } 264 }
278 } 265 }
279 } 266 }
280 if (expression != null) { 267 if (expression != null) {
281 initialVariableValues[element.declaration] = expression; 268 initialVariableValues[element.declaration] = expression;
282 } else { 269 } else {
283 assert(invariant(element, !isConst, 270 assert(invariant(element, !isConst,
284 message: "Variable $element does not compile to a constant.")); 271 message: "Variable $element does not compile to a constant."));
285 } 272 }
286 pendingVariables.remove(element); 273 pendingVariables.remove(element);
287 return expression; 274 return expression;
288 } 275 }
289 276
290 void cacheConstantValue(ConstantExpression expression, ConstantValue value) { 277 void cacheConstantValue(ConstantExpression expression, ConstantValue value) {
291 constantValueMap[expression] = value; 278 constantValueMap[expression] = value;
292 } 279 }
293 280
294 ConstantExpression compileNodeWithDefinitions( 281 ConstantExpression compileNodeWithDefinitions(
295 Node node, TreeElements definitions, {bool isConst: true}) { 282 Node node, TreeElements definitions,
283 {bool isConst: true}) {
296 assert(node != null); 284 assert(node != null);
297 CompileTimeConstantEvaluator evaluator = new CompileTimeConstantEvaluator( 285 CompileTimeConstantEvaluator evaluator = new CompileTimeConstantEvaluator(
298 this, definitions, compiler, isConst: isConst); 286 this, definitions, compiler,
287 isConst: isConst);
299 AstConstant constant = evaluator.evaluate(node); 288 AstConstant constant = evaluator.evaluate(node);
300 if (constant != null) { 289 if (constant != null) {
301 cacheConstantValue(constant.expression, constant.value); 290 cacheConstantValue(constant.expression, constant.value);
302 return constant.expression; 291 return constant.expression;
303 } 292 }
304 return null; 293 return null;
305 } 294 }
306 295
307 ConstantValue getConstantValue(ConstantExpression expression) { 296 ConstantValue getConstantValue(ConstantExpression expression) {
308 return constantValueMap[expression]; 297 return constantValueMap[expression];
(...skipping 24 matching lines...) Expand all
333 /// constant evaluation. 322 /// constant evaluation.
334 class DartConstantCompiler extends ConstantCompilerBase { 323 class DartConstantCompiler extends ConstantCompilerBase {
335 DartConstantCompiler(Compiler compiler) 324 DartConstantCompiler(Compiler compiler)
336 : super(compiler, const DartConstantSystem()); 325 : super(compiler, const DartConstantSystem());
337 326
338 ConstantExpression getConstantForNode(Node node, TreeElements definitions) { 327 ConstantExpression getConstantForNode(Node node, TreeElements definitions) {
339 return definitions.getConstant(node); 328 return definitions.getConstant(node);
340 } 329 }
341 330
342 ConstantExpression compileNodeWithDefinitions( 331 ConstantExpression compileNodeWithDefinitions(
343 Node node, TreeElements definitions, {bool isConst: true}) { 332 Node node, TreeElements definitions,
333 {bool isConst: true}) {
344 ConstantExpression constant = definitions.getConstant(node); 334 ConstantExpression constant = definitions.getConstant(node);
345 if (constant != null && getConstantValue(constant) != null) { 335 if (constant != null && getConstantValue(constant) != null) {
346 return constant; 336 return constant;
347 } 337 }
348 constant = 338 constant =
349 super.compileNodeWithDefinitions(node, definitions, isConst: isConst); 339 super.compileNodeWithDefinitions(node, definitions, isConst: isConst);
350 if (constant != null) { 340 if (constant != null) {
351 definitions.setConstant(node, constant); 341 definitions.setConstant(node, constant);
352 } 342 }
353 return constant; 343 return constant;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 isEvaluatingConstant = oldIsEvaluatingConstant; 376 isEvaluatingConstant = oldIsEvaluatingConstant;
387 assert(result != null); 377 assert(result != null);
388 return result; 378 return result;
389 } 379 }
390 380
391 AstConstant visitNode(Node node) { 381 AstConstant visitNode(Node node) {
392 return signalNotCompileTimeConstant(node); 382 return signalNotCompileTimeConstant(node);
393 } 383 }
394 384
395 AstConstant visitLiteralBool(LiteralBool node) { 385 AstConstant visitLiteralBool(LiteralBool node) {
396 return new AstConstant(context, node, 386 return new AstConstant(
387 context,
388 node,
397 new BoolConstantExpression(node.value), 389 new BoolConstantExpression(node.value),
398 constantSystem.createBool(node.value)); 390 constantSystem.createBool(node.value));
399 } 391 }
400 392
401 AstConstant visitLiteralDouble(LiteralDouble node) { 393 AstConstant visitLiteralDouble(LiteralDouble node) {
402 return new AstConstant(context, node, 394 return new AstConstant(
395 context,
396 node,
403 new DoubleConstantExpression(node.value), 397 new DoubleConstantExpression(node.value),
404 constantSystem.createDouble(node.value)); 398 constantSystem.createDouble(node.value));
405 } 399 }
406 400
407 AstConstant visitLiteralInt(LiteralInt node) { 401 AstConstant visitLiteralInt(LiteralInt node) {
408 return new AstConstant(context, node, new IntConstantExpression(node.value), 402 return new AstConstant(context, node, new IntConstantExpression(node.value),
409 constantSystem.createInt(node.value)); 403 constantSystem.createInt(node.value));
410 } 404 }
411 405
412 AstConstant visitLiteralList(LiteralList node) { 406 AstConstant visitLiteralList(LiteralList node) {
413 if (!node.isConst) { 407 if (!node.isConst) {
414 return signalNotCompileTimeConstant(node); 408 return signalNotCompileTimeConstant(node);
415 } 409 }
416 List<ConstantExpression> argumentExpressions = <ConstantExpression>[]; 410 List<ConstantExpression> argumentExpressions = <ConstantExpression>[];
417 List<ConstantValue> argumentValues = <ConstantValue>[]; 411 List<ConstantValue> argumentValues = <ConstantValue>[];
418 for (Link<Node> link = node.elements.nodes; 412 for (Link<Node> link = node.elements.nodes;
419 !link.isEmpty; 413 !link.isEmpty;
420 link = link.tail) { 414 link = link.tail) {
421 AstConstant argument = evaluateConstant(link.head); 415 AstConstant argument = evaluateConstant(link.head);
422 if (argument == null) { 416 if (argument == null) {
423 return null; 417 return null;
424 } 418 }
425 argumentExpressions.add(argument.expression); 419 argumentExpressions.add(argument.expression);
426 argumentValues.add(argument.value); 420 argumentValues.add(argument.value);
427 } 421 }
428 DartType type = elements.getType(node); 422 DartType type = elements.getType(node);
429 return new AstConstant(context, node, 423 return new AstConstant(
424 context,
425 node,
430 new ListConstantExpression(type, argumentExpressions), 426 new ListConstantExpression(type, argumentExpressions),
431 constantSystem.createList(type, argumentValues)); 427 constantSystem.createList(type, argumentValues));
432 } 428 }
433 429
434 AstConstant visitLiteralMap(LiteralMap node) { 430 AstConstant visitLiteralMap(LiteralMap node) {
435 if (!node.isConst) { 431 if (!node.isConst) {
436 return signalNotCompileTimeConstant(node); 432 return signalNotCompileTimeConstant(node);
437 } 433 }
438 List<ConstantExpression> keyExpressions = <ConstantExpression>[]; 434 List<ConstantExpression> keyExpressions = <ConstantExpression>[];
439 List<ConstantExpression> valueExpressions = <ConstantExpression>[]; 435 List<ConstantExpression> valueExpressions = <ConstantExpression>[];
(...skipping 15 matching lines...) Expand all
455 keyValues.add(key.value); 451 keyValues.add(key.value);
456 } else { 452 } else {
457 reporter.reportWarningMessage( 453 reporter.reportWarningMessage(
458 entry.key, MessageKind.EQUAL_MAP_ENTRY_KEY); 454 entry.key, MessageKind.EQUAL_MAP_ENTRY_KEY);
459 } 455 }
460 keyExpressions.add(key.expression); 456 keyExpressions.add(key.expression);
461 valueExpressions.add(value.expression); 457 valueExpressions.add(value.expression);
462 map[key.value] = value.value; 458 map[key.value] = value.value;
463 } 459 }
464 InterfaceType type = elements.getType(node); 460 InterfaceType type = elements.getType(node);
465 return new AstConstant(context, node, 461 return new AstConstant(
462 context,
463 node,
466 new MapConstantExpression(type, keyExpressions, valueExpressions), 464 new MapConstantExpression(type, keyExpressions, valueExpressions),
467 constantSystem.createMap( 465 constantSystem.createMap(
468 compiler, type, keyValues, map.values.toList())); 466 compiler, type, keyValues, map.values.toList()));
469 } 467 }
470 468
471 AstConstant visitLiteralNull(LiteralNull node) { 469 AstConstant visitLiteralNull(LiteralNull node) {
472 return new AstConstant(context, node, new NullConstantExpression(), 470 return new AstConstant(context, node, new NullConstantExpression(),
473 constantSystem.createNull()); 471 constantSystem.createNull());
474 } 472 }
475 473
476 AstConstant visitLiteralString(LiteralString node) { 474 AstConstant visitLiteralString(LiteralString node) {
477 return new AstConstant(context, node, 475 return new AstConstant(
476 context,
477 node,
478 new StringConstantExpression(node.dartString.slowToString()), 478 new StringConstantExpression(node.dartString.slowToString()),
479 constantSystem.createString(node.dartString)); 479 constantSystem.createString(node.dartString));
480 } 480 }
481 481
482 AstConstant visitStringJuxtaposition(StringJuxtaposition node) { 482 AstConstant visitStringJuxtaposition(StringJuxtaposition node) {
483 AstConstant left = evaluate(node.first); 483 AstConstant left = evaluate(node.first);
484 AstConstant right = evaluate(node.second); 484 AstConstant right = evaluate(node.second);
485 if (left == null || right == null) return null; 485 if (left == null || right == null) return null;
486 StringConstantValue leftValue = left.value; 486 StringConstantValue leftValue = left.value;
487 StringConstantValue rightValue = right.value; 487 StringConstantValue rightValue = right.value;
488 return new AstConstant(context, node, 488 return new AstConstant(
489 context,
490 node,
489 new ConcatenateConstantExpression([left.expression, right.expression]), 491 new ConcatenateConstantExpression([left.expression, right.expression]),
490 constantSystem.createString(new DartString.concat( 492 constantSystem.createString(new DartString.concat(
491 leftValue.primitiveValue, rightValue.primitiveValue))); 493 leftValue.primitiveValue, rightValue.primitiveValue)));
492 } 494 }
493 495
494 AstConstant visitStringInterpolation(StringInterpolation node) { 496 AstConstant visitStringInterpolation(StringInterpolation node) {
495 List<ConstantExpression> subexpressions = <ConstantExpression>[]; 497 List<ConstantExpression> subexpressions = <ConstantExpression>[];
496 AstConstant initialString = evaluate(node.string); 498 AstConstant initialString = evaluate(node.string);
497 if (initialString == null) { 499 if (initialString == null) {
498 return null; 500 return null;
(...skipping 23 matching lines...) Expand all
522 } 524 }
523 accumulator = new DartString.concat(accumulator, expressionString); 525 accumulator = new DartString.concat(accumulator, expressionString);
524 AstConstant partString = evaluate(part.string); 526 AstConstant partString = evaluate(part.string);
525 if (partString == null) return null; 527 if (partString == null) return null;
526 subexpressions.add(partString.expression); 528 subexpressions.add(partString.expression);
527 StringConstantValue partStringValue = partString.value; 529 StringConstantValue partStringValue = partString.value;
528 accumulator = 530 accumulator =
529 new DartString.concat(accumulator, partStringValue.primitiveValue); 531 new DartString.concat(accumulator, partStringValue.primitiveValue);
530 } 532 }
531 ; 533 ;
532 return new AstConstant(context, node, 534 return new AstConstant(
535 context,
536 node,
533 new ConcatenateConstantExpression(subexpressions), 537 new ConcatenateConstantExpression(subexpressions),
534 constantSystem.createString(accumulator)); 538 constantSystem.createString(accumulator));
535 } 539 }
536 540
537 AstConstant visitLiteralSymbol(LiteralSymbol node) { 541 AstConstant visitLiteralSymbol(LiteralSymbol node) {
538 InterfaceType type = coreTypes.symbolType; 542 InterfaceType type = coreTypes.symbolType;
539 String text = node.slowNameString; 543 String text = node.slowNameString;
540 List<AstConstant> arguments = <AstConstant>[ 544 List<AstConstant> arguments = <AstConstant>[
541 new AstConstant(context, node, new StringConstantExpression(text), 545 new AstConstant(context, node, new StringConstantExpression(text),
542 constantSystem.createString(new LiteralDartString(text))) 546 constantSystem.createString(new LiteralDartString(text)))
(...skipping 30 matching lines...) Expand all
573 } 577 }
574 578
575 // TODO(floitsch): provide better error-messages. 579 // TODO(floitsch): provide better error-messages.
576 AstConstant visitSend(Send send) { 580 AstConstant visitSend(Send send) {
577 Element element = elements[send]; 581 Element element = elements[send];
578 if (send.isPropertyAccess) { 582 if (send.isPropertyAccess) {
579 AstConstant result; 583 AstConstant result;
580 if (Elements.isStaticOrTopLevelFunction(element)) { 584 if (Elements.isStaticOrTopLevelFunction(element)) {
581 FunctionElementX function = element; 585 FunctionElementX function = element;
582 function.computeType(resolution); 586 function.computeType(resolution);
583 result = new AstConstant(context, send, 587 result = new AstConstant(
588 context,
589 send,
584 new FunctionConstantExpression(function), 590 new FunctionConstantExpression(function),
585 new FunctionConstantValue(function)); 591 new FunctionConstantValue(function));
586 } else if (Elements.isStaticOrTopLevelField(element)) { 592 } else if (Elements.isStaticOrTopLevelField(element)) {
587 ConstantExpression elementExpression; 593 ConstantExpression elementExpression;
588 if (element.isConst) { 594 if (element.isConst) {
589 elementExpression = handler.compileConstant(element); 595 elementExpression = handler.compileConstant(element);
590 } else if (element.isFinal && !isEvaluatingConstant) { 596 } else if (element.isFinal && !isEvaluatingConstant) {
591 elementExpression = handler.compileVariable(element); 597 elementExpression = handler.compileVariable(element);
592 } 598 }
593 if (elementExpression != null) { 599 if (elementExpression != null) {
594 result = new AstConstant(context, send, 600 result = new AstConstant(
601 context,
602 send,
595 new VariableConstantExpression(element), 603 new VariableConstantExpression(element),
596 handler.getConstantValue(elementExpression)); 604 handler.getConstantValue(elementExpression));
597 } 605 }
598 } else if (Elements.isClass(element) || Elements.isTypedef(element)) { 606 } else if (Elements.isClass(element) || Elements.isTypedef(element)) {
599 assert(elements.isTypeLiteral(send)); 607 assert(elements.isTypeLiteral(send));
600 DartType elementType = elements.getTypeLiteralType(send); 608 DartType elementType = elements.getTypeLiteralType(send);
601 result = new AstConstant(context, send, 609 result = new AstConstant(
610 context,
611 send,
602 new TypeConstantExpression(elementType), 612 new TypeConstantExpression(elementType),
603 makeTypeConstant(elementType)); 613 makeTypeConstant(elementType));
604 } else if (send.receiver != null) { 614 } else if (send.receiver != null) {
605 if (send.selector.asIdentifier().source == "length") { 615 if (send.selector.asIdentifier().source == "length") {
606 AstConstant left = evaluate(send.receiver); 616 AstConstant left = evaluate(send.receiver);
607 if (left != null && left.value.isString) { 617 if (left != null && left.value.isString) {
608 StringConstantValue stringConstantValue = left.value; 618 StringConstantValue stringConstantValue = left.value;
609 DartString string = stringConstantValue.primitiveValue; 619 DartString string = stringConstantValue.primitiveValue;
610 IntConstantValue length = constantSystem.createInt(string.length); 620 IntConstantValue length = constantSystem.createInt(string.length);
611 result = new AstConstant(context, send, 621 result = new AstConstant(context, send,
612 new StringLengthConstantExpression(left.expression), length); 622 new StringLengthConstantExpression(left.expression), length);
613 } 623 }
614 } 624 }
615 // Fall through to error handling. 625 // Fall through to error handling.
616 } else if (!Elements.isUnresolved(element) && 626 } else if (!Elements.isUnresolved(element) &&
617 element.isVariable && 627 element.isVariable &&
618 element.isConst) { 628 element.isConst) {
619 ConstantExpression variableExpression = 629 ConstantExpression variableExpression =
620 handler.compileConstant(element); 630 handler.compileConstant(element);
621 if (variableExpression != null) { 631 if (variableExpression != null) {
622 result = new AstConstant(context, send, 632 result = new AstConstant(
633 context,
634 send,
623 new VariableConstantExpression(element), 635 new VariableConstantExpression(element),
624 handler.getConstantValue(variableExpression)); 636 handler.getConstantValue(variableExpression));
625 } 637 }
626 } 638 }
627 if (result == null) { 639 if (result == null) {
628 return signalNotCompileTimeConstant(send); 640 return signalNotCompileTimeConstant(send);
629 } 641 }
630 if (isDeferredUse(send)) { 642 if (isDeferredUse(send)) {
631 if (isEvaluatingConstant) { 643 if (isEvaluatingConstant) {
632 reporter.reportErrorMessage( 644 reporter.reportErrorMessage(
633 send, MessageKind.DEFERRED_COMPILE_TIME_CONSTANT); 645 send, MessageKind.DEFERRED_COMPILE_TIME_CONSTANT);
634 } 646 }
635 PrefixElement prefix = 647 PrefixElement prefix =
636 compiler.deferredLoadTask.deferredPrefixElement(send, elements); 648 compiler.deferredLoadTask.deferredPrefixElement(send, elements);
637 result = new AstConstant(context, send, 649 result = new AstConstant(
650 context,
651 send,
638 new DeferredConstantExpression(result.expression, prefix), 652 new DeferredConstantExpression(result.expression, prefix),
639 new DeferredConstantValue(result.value, prefix)); 653 new DeferredConstantValue(result.value, prefix));
640 compiler.deferredLoadTask.registerConstantDeferredUse( 654 compiler.deferredLoadTask
641 result.value, prefix); 655 .registerConstantDeferredUse(result.value, prefix);
642 } 656 }
643 return result; 657 return result;
644 } else if (send.isCall) { 658 } else if (send.isCall) {
645 if (element == compiler.identicalFunction && send.argumentCount() == 2) { 659 if (element == compiler.identicalFunction && send.argumentCount() == 2) {
646 AstConstant left = evaluate(send.argumentsNode.nodes.head); 660 AstConstant left = evaluate(send.argumentsNode.nodes.head);
647 AstConstant right = evaluate(send.argumentsNode.nodes.tail.head); 661 AstConstant right = evaluate(send.argumentsNode.nodes.tail.head);
648 if (left == null || right == null) { 662 if (left == null || right == null) {
649 return null; 663 return null;
650 } 664 }
651 ConstantValue result = 665 ConstantValue result =
652 constantSystem.identity.fold(left.value, right.value); 666 constantSystem.identity.fold(left.value, right.value);
653 if (result != null) { 667 if (result != null) {
654 return new AstConstant(context, send, new IdenticalConstantExpression( 668 return new AstConstant(
655 left.expression, right.expression), result); 669 context,
670 send,
671 new IdenticalConstantExpression(
672 left.expression, right.expression),
673 result);
656 } 674 }
657 } 675 }
658 return signalNotCompileTimeConstant(send); 676 return signalNotCompileTimeConstant(send);
659 } else if (send.isPrefix) { 677 } else if (send.isPrefix) {
660 assert(send.isOperator); 678 assert(send.isOperator);
661 AstConstant receiverConstant = evaluate(send.receiver); 679 AstConstant receiverConstant = evaluate(send.receiver);
662 if (receiverConstant == null) { 680 if (receiverConstant == null) {
663 return null; 681 return null;
664 } 682 }
665 Operator node = send.selector; 683 Operator node = send.selector;
666 UnaryOperator operator = UnaryOperator.parse(node.source); 684 UnaryOperator operator = UnaryOperator.parse(node.source);
667 UnaryOperation operation = constantSystem.lookupUnary(operator); 685 UnaryOperation operation = constantSystem.lookupUnary(operator);
668 if (operation == null) { 686 if (operation == null) {
669 reporter.internalError(send.selector, "Unexpected operator."); 687 reporter.internalError(send.selector, "Unexpected operator.");
670 } 688 }
671 ConstantValue folded = operation.fold(receiverConstant.value); 689 ConstantValue folded = operation.fold(receiverConstant.value);
672 if (folded == null) { 690 if (folded == null) {
673 return signalNotCompileTimeConstant(send); 691 return signalNotCompileTimeConstant(send);
674 } 692 }
675 return new AstConstant(context, send, 693 return new AstConstant(
694 context,
695 send,
676 new UnaryConstantExpression(operator, receiverConstant.expression), 696 new UnaryConstantExpression(operator, receiverConstant.expression),
677 folded); 697 folded);
678 } else if (send.isOperator && !send.isPostfix) { 698 } else if (send.isOperator && !send.isPostfix) {
679 assert(send.argumentCount() == 1); 699 assert(send.argumentCount() == 1);
680 AstConstant left = evaluate(send.receiver); 700 AstConstant left = evaluate(send.receiver);
681 AstConstant right = evaluate(send.argumentsNode.nodes.head); 701 AstConstant right = evaluate(send.argumentsNode.nodes.head);
682 if (left == null || right == null) { 702 if (left == null || right == null) {
683 return null; 703 return null;
684 } 704 }
685 ConstantValue leftValue = left.value; 705 ConstantValue leftValue = left.value;
(...skipping 23 matching lines...) Expand all
709 default: 729 default:
710 BinaryOperation operation = constantSystem.lookupBinary(operator); 730 BinaryOperation operation = constantSystem.lookupBinary(operator);
711 if (operation != null) { 731 if (operation != null) {
712 folded = operation.fold(leftValue, rightValue); 732 folded = operation.fold(leftValue, rightValue);
713 } 733 }
714 } 734 }
715 } 735 }
716 if (folded == null) { 736 if (folded == null) {
717 return signalNotCompileTimeConstant(send); 737 return signalNotCompileTimeConstant(send);
718 } 738 }
719 return new AstConstant(context, send, new BinaryConstantExpression( 739 return new AstConstant(
720 left.expression, operator, right.expression), folded); 740 context,
741 send,
742 new BinaryConstantExpression(
743 left.expression, operator, right.expression),
744 folded);
721 } 745 }
722 return signalNotCompileTimeConstant(send); 746 return signalNotCompileTimeConstant(send);
723 } 747 }
724 748
725 AstConstant visitConditional(Conditional node) { 749 AstConstant visitConditional(Conditional node) {
726 AstConstant condition = evaluate(node.condition); 750 AstConstant condition = evaluate(node.condition);
727 if (condition == null) { 751 if (condition == null) {
728 return null; 752 return null;
729 } else if (!condition.value.isBool) { 753 } else if (!condition.value.isBool) {
730 DartType conditionType = condition.value.getType(coreTypes); 754 DartType conditionType = condition.value.getType(coreTypes);
731 if (isEvaluatingConstant) { 755 if (isEvaluatingConstant) {
732 reporter.reportErrorMessage( 756 reporter.reportErrorMessage(node.condition, MessageKind.NOT_ASSIGNABLE,
733 node.condition, 757 {'fromType': conditionType, 'toType': coreTypes.boolType});
734 MessageKind.NOT_ASSIGNABLE,
735 {'fromType': conditionType,
736 'toType': coreTypes.boolType});
737 return new ErroneousAstConstant(context, node); 758 return new ErroneousAstConstant(context, node);
738 } 759 }
739 return null; 760 return null;
740 } 761 }
741 AstConstant thenExpression = evaluate(node.thenExpression); 762 AstConstant thenExpression = evaluate(node.thenExpression);
742 AstConstant elseExpression = evaluate(node.elseExpression); 763 AstConstant elseExpression = evaluate(node.elseExpression);
743 if (thenExpression == null || elseExpression == null) { 764 if (thenExpression == null || elseExpression == null) {
744 return null; 765 return null;
745 } 766 }
746 BoolConstantValue boolCondition = condition.value; 767 BoolConstantValue boolCondition = condition.value;
747 return new AstConstant(context, node, new ConditionalConstantExpression( 768 return new AstConstant(
748 condition.expression, thenExpression.expression, 769 context,
749 elseExpression.expression), boolCondition.primitiveValue 770 node,
750 ? thenExpression.value 771 new ConditionalConstantExpression(condition.expression,
751 : elseExpression.value); 772 thenExpression.expression, elseExpression.expression),
773 boolCondition.primitiveValue
774 ? thenExpression.value
775 : elseExpression.value);
752 } 776 }
753 777
754 AstConstant visitSendSet(SendSet node) { 778 AstConstant visitSendSet(SendSet node) {
755 return signalNotCompileTimeConstant(node); 779 return signalNotCompileTimeConstant(node);
756 } 780 }
757 781
758 /** 782 /**
759 * Returns the normalized list of constant arguments that are passed to the 783 * Returns the normalized list of constant arguments that are passed to the
760 * constructor including both the concrete arguments and default values for 784 * constructor including both the concrete arguments and default values for
761 * omitted optional arguments. 785 * omitted optional arguments.
762 * 786 *
763 * Invariant: [target] must be an implementation element. 787 * Invariant: [target] must be an implementation element.
764 */ 788 */
765 List<AstConstant> evaluateArgumentsToConstructor(Node node, 789 List<AstConstant> evaluateArgumentsToConstructor(
766 CallStructure callStructure, Link<Node> arguments, 790 Node node,
767 ConstructorElement target, {AstConstant compileArgument(Node node)}) { 791 CallStructure callStructure,
792 Link<Node> arguments,
793 ConstructorElement target,
794 {AstConstant compileArgument(Node node)}) {
768 assert(invariant(node, target.isImplementation)); 795 assert(invariant(node, target.isImplementation));
769 796
770 AstConstant compileDefaultValue(VariableElement element) { 797 AstConstant compileDefaultValue(VariableElement element) {
771 ConstantExpression constant = handler.compileConstant(element); 798 ConstantExpression constant = handler.compileConstant(element);
772 return new AstConstant.fromDefaultValue( 799 return new AstConstant.fromDefaultValue(
773 element, constant, handler.getConstantValue(constant)); 800 element, constant, handler.getConstantValue(constant));
774 } 801 }
775 target.computeType(resolution); 802 target.computeType(resolution);
776 803
777 FunctionSignature signature = target.functionSignature; 804 FunctionSignature signature = target.functionSignature;
778 if (!callStructure.signatureApplies(signature)) { 805 if (!callStructure.signatureApplies(signature)) {
779 String name = Elements.constructorNameForDiagnostics( 806 String name = Elements.constructorNameForDiagnostics(
780 target.enclosingClass.name, target.name); 807 target.enclosingClass.name, target.name);
781 reporter.reportErrorMessage( 808 reporter.reportErrorMessage(node,
782 node, MessageKind.INVALID_CONSTRUCTOR_ARGUMENTS, 809 MessageKind.INVALID_CONSTRUCTOR_ARGUMENTS, {'constructorName': name});
783 {'constructorName': name});
784 810
785 return new List<AstConstant>.filled( 811 return new List<AstConstant>.filled(
786 target.functionSignature.parameterCount, 812 target.functionSignature.parameterCount,
787 new ErroneousAstConstant(context, node)); 813 new ErroneousAstConstant(context, node));
788 } 814 }
789 return callStructure.makeArgumentsList( 815 return callStructure.makeArgumentsList(
790 arguments, target, compileArgument, compileDefaultValue); 816 arguments, target, compileArgument, compileDefaultValue);
791 } 817 }
792 818
793 AstConstant visitNewExpression(NewExpression node) { 819 AstConstant visitNewExpression(NewExpression node) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
827 // a post-process action, so we have to make sure it is done here. 853 // a post-process action, so we have to make sure it is done here.
828 compiler.resolver.resolveRedirectionChain(constructor, node); 854 compiler.resolver.resolveRedirectionChain(constructor, node);
829 855
830 bool isInvalid = false; 856 bool isInvalid = false;
831 InterfaceType constructedType = type; 857 InterfaceType constructedType = type;
832 ConstructorElement implementation; 858 ConstructorElement implementation;
833 if (constructor.isRedirectingFactory) { 859 if (constructor.isRedirectingFactory) {
834 if (constructor.isEffectiveTargetMalformed) { 860 if (constructor.isEffectiveTargetMalformed) {
835 isInvalid = true; 861 isInvalid = true;
836 } else { 862 } else {
837 constructedType = 863 constructedType = constructor.computeEffectiveTargetType(type);
838 constructor.computeEffectiveTargetType(type);
839 ConstructorElement target = constructor.effectiveTarget; 864 ConstructorElement target = constructor.effectiveTarget;
840 // The constructor must be an implementation to ensure that field 865 // The constructor must be an implementation to ensure that field
841 // initializers are handled correctly. 866 // initializers are handled correctly.
842 implementation = target.implementation; 867 implementation = target.implementation;
843 } 868 }
844 } else { 869 } else {
845 // The constructor must be an implementation to ensure that field 870 // The constructor must be an implementation to ensure that field
846 // initializers are handled correctly. 871 // initializers are handled correctly.
847 implementation = constructor.implementation; 872 implementation = constructor.implementation;
848 isInvalid = implementation.isMalformed; 873 isInvalid = implementation.isMalformed;
(...skipping 26 matching lines...) Expand all
875 assert(normalizedArguments != null); 900 assert(normalizedArguments != null);
876 concreteArguments = normalizedArguments; 901 concreteArguments = normalizedArguments;
877 } 902 }
878 903
879 if (constructor == compiler.intEnvironment || 904 if (constructor == compiler.intEnvironment ||
880 constructor == compiler.boolEnvironment || 905 constructor == compiler.boolEnvironment ||
881 constructor == compiler.stringEnvironment) { 906 constructor == compiler.stringEnvironment) {
882 return createFromEnvironmentConstant(node, constructedType, constructor, 907 return createFromEnvironmentConstant(node, constructedType, constructor,
883 callStructure, normalizedArguments, concreteArguments); 908 callStructure, normalizedArguments, concreteArguments);
884 } else { 909 } else {
885 return makeConstructedConstant(compiler, handler, context, node, type, 910 return makeConstructedConstant(
886 constructor, constructedType, implementation, callStructure, 911 compiler,
887 concreteArguments, normalizedArguments); 912 handler,
913 context,
914 node,
915 type,
916 constructor,
917 constructedType,
918 implementation,
919 callStructure,
920 concreteArguments,
921 normalizedArguments);
888 } 922 }
889 } 923 }
890 924
891 AstConstant createFromEnvironmentConstant(Node node, InterfaceType type, 925 AstConstant createFromEnvironmentConstant(
892 ConstructorElement constructor, CallStructure callStructure, 926 Node node,
927 InterfaceType type,
928 ConstructorElement constructor,
929 CallStructure callStructure,
893 List<AstConstant> normalizedArguments, 930 List<AstConstant> normalizedArguments,
894 List<AstConstant> concreteArguments) { 931 List<AstConstant> concreteArguments) {
895 var firstArgument = normalizedArguments[0].value; 932 var firstArgument = normalizedArguments[0].value;
896 ConstantValue defaultValue = normalizedArguments[1].value; 933 ConstantValue defaultValue = normalizedArguments[1].value;
897 934
898 if (firstArgument.isNull) { 935 if (firstArgument.isNull) {
899 reporter.reportErrorMessage( 936 reporter.reportErrorMessage(
900 normalizedArguments[0].node, MessageKind.NULL_NOT_ALLOWED); 937 normalizedArguments[0].node, MessageKind.NULL_NOT_ALLOWED);
901 return null; 938 return null;
902 } 939 }
903 940
904 if (!firstArgument.isString) { 941 if (!firstArgument.isString) {
905 DartType type = defaultValue.getType(coreTypes); 942 DartType type = defaultValue.getType(coreTypes);
906 reporter.reportErrorMessage( 943 reporter.reportErrorMessage(
907 normalizedArguments[0].node, 944 normalizedArguments[0].node,
908 MessageKind.NOT_ASSIGNABLE, 945 MessageKind.NOT_ASSIGNABLE,
909 {'fromType': type, 946 {'fromType': type, 'toType': coreTypes.stringType});
910 'toType': coreTypes.stringType});
911 return null; 947 return null;
912 } 948 }
913 949
914 if (constructor == compiler.intEnvironment && 950 if (constructor == compiler.intEnvironment &&
915 !(defaultValue.isNull || defaultValue.isInt)) { 951 !(defaultValue.isNull || defaultValue.isInt)) {
916 DartType type = defaultValue.getType(coreTypes); 952 DartType type = defaultValue.getType(coreTypes);
917 reporter.reportErrorMessage( 953 reporter.reportErrorMessage(
918 normalizedArguments[1].node, 954 normalizedArguments[1].node,
919 MessageKind.NOT_ASSIGNABLE, 955 MessageKind.NOT_ASSIGNABLE,
920 {'fromType': type, 956 {'fromType': type, 'toType': coreTypes.intType});
921 'toType': coreTypes.intType});
922 return null; 957 return null;
923 } 958 }
924 959
925 if (constructor == compiler.boolEnvironment && 960 if (constructor == compiler.boolEnvironment &&
926 !(defaultValue.isNull || defaultValue.isBool)) { 961 !(defaultValue.isNull || defaultValue.isBool)) {
927 DartType type = defaultValue.getType(coreTypes); 962 DartType type = defaultValue.getType(coreTypes);
928 reporter.reportErrorMessage( 963 reporter.reportErrorMessage(
929 normalizedArguments[1].node, 964 normalizedArguments[1].node,
930 MessageKind.NOT_ASSIGNABLE, 965 MessageKind.NOT_ASSIGNABLE,
931 {'fromType': type, 966 {'fromType': type, 'toType': coreTypes.boolType});
932 'toType': coreTypes.boolType});
933 return null; 967 return null;
934 } 968 }
935 969
936 if (constructor == compiler.stringEnvironment && 970 if (constructor == compiler.stringEnvironment &&
937 !(defaultValue.isNull || defaultValue.isString)) { 971 !(defaultValue.isNull || defaultValue.isString)) {
938 DartType type = defaultValue.getType(coreTypes); 972 DartType type = defaultValue.getType(coreTypes);
939 reporter.reportErrorMessage( 973 reporter.reportErrorMessage(
940 normalizedArguments[1].node, 974 normalizedArguments[1].node,
941 MessageKind.NOT_ASSIGNABLE, 975 MessageKind.NOT_ASSIGNABLE,
942 {'fromType': type, 976 {'fromType': type, 'toType': coreTypes.stringType});
943 'toType': coreTypes.stringType});
944 return null; 977 return null;
945 } 978 }
946 979
947 String name = firstArgument.primitiveValue.slowToString(); 980 String name = firstArgument.primitiveValue.slowToString();
948 String value = compiler.fromEnvironment(name); 981 String value = compiler.fromEnvironment(name);
949 982
950 AstConstant createEvaluatedConstant(ConstantValue value) { 983 AstConstant createEvaluatedConstant(ConstantValue value) {
951 ConstantExpression expression; 984 ConstantExpression expression;
952 ConstantExpression name = concreteArguments[0].expression; 985 ConstantExpression name = concreteArguments[0].expression;
953 ConstantExpression defaultValue; 986 ConstantExpression defaultValue;
(...skipping 28 matching lines...) Expand all
982 } else { 1015 } else {
983 return createEvaluatedConstant(defaultValue); 1016 return createEvaluatedConstant(defaultValue);
984 } 1017 }
985 } else { 1018 } else {
986 assert(constructor == compiler.stringEnvironment); 1019 assert(constructor == compiler.stringEnvironment);
987 return createEvaluatedConstant( 1020 return createEvaluatedConstant(
988 constantSystem.createString(new DartString.literal(value))); 1021 constantSystem.createString(new DartString.literal(value)));
989 } 1022 }
990 } 1023 }
991 1024
992 static AstConstant makeConstructedConstant(Compiler compiler, 1025 static AstConstant makeConstructedConstant(
993 ConstantCompilerBase handler, Element context, Node node, 1026 Compiler compiler,
994 InterfaceType type, ConstructorElement constructor, 1027 ConstantCompilerBase handler,
995 InterfaceType constructedType, ConstructorElement target, 1028 Element context,
996 CallStructure callStructure, List<AstConstant> concreteArguments, 1029 Node node,
1030 InterfaceType type,
1031 ConstructorElement constructor,
1032 InterfaceType constructedType,
1033 ConstructorElement target,
1034 CallStructure callStructure,
1035 List<AstConstant> concreteArguments,
997 List<AstConstant> normalizedArguments) { 1036 List<AstConstant> normalizedArguments) {
998 if (target.isRedirectingFactory) { 1037 if (target.isRedirectingFactory) {
999 // This happens is case of cyclic redirection. 1038 // This happens is case of cyclic redirection.
1000 assert(invariant(node, compiler.compilationFailed, 1039 assert(invariant(node, compiler.compilationFailed,
1001 message: "makeConstructedConstant can only be called with the " 1040 message: "makeConstructedConstant can only be called with the "
1002 "effective target: $constructor")); 1041 "effective target: $constructor"));
1003 return new ErroneousAstConstant(context, node); 1042 return new ErroneousAstConstant(context, node);
1004 } 1043 }
1005 assert(invariant(node, 1044 assert(invariant(
1045 node,
1006 callStructure.signatureApplies(constructor.functionSignature) || 1046 callStructure.signatureApplies(constructor.functionSignature) ||
1007 compiler.compilationFailed, 1047 compiler.compilationFailed,
1008 message: "Call structure $callStructure does not apply to constructor " 1048 message: "Call structure $callStructure does not apply to constructor "
1009 "$constructor.")); 1049 "$constructor."));
1010 1050
1011 ConstructorEvaluator evaluator = 1051 ConstructorEvaluator evaluator =
1012 new ConstructorEvaluator(constructedType, target, handler, compiler); 1052 new ConstructorEvaluator(constructedType, target, handler, compiler);
1013 evaluator.evaluateConstructorFieldValues(normalizedArguments); 1053 evaluator.evaluateConstructorFieldValues(normalizedArguments);
1014 Map<FieldElement, AstConstant> fieldConstants = 1054 Map<FieldElement, AstConstant> fieldConstants =
1015 evaluator.buildFieldConstants(target.enclosingClass); 1055 evaluator.buildFieldConstants(target.enclosingClass);
1016 Map<FieldElement, ConstantValue> fieldValues = 1056 Map<FieldElement, ConstantValue> fieldValues =
1017 <FieldElement, ConstantValue>{}; 1057 <FieldElement, ConstantValue>{};
1018 fieldConstants.forEach((FieldElement field, AstConstant astConstant) { 1058 fieldConstants.forEach((FieldElement field, AstConstant astConstant) {
1019 fieldValues[field] = astConstant.value; 1059 fieldValues[field] = astConstant.value;
1020 }); 1060 });
1021 return new AstConstant(context, node, new ConstructedConstantExpression( 1061 return new AstConstant(
1022 type, constructor, callStructure, 1062 context,
1063 node,
1064 new ConstructedConstantExpression(type, constructor, callStructure,
1023 concreteArguments.map((e) => e.expression).toList()), 1065 concreteArguments.map((e) => e.expression).toList()),
1024 new ConstructedConstantValue(constructedType, fieldValues)); 1066 new ConstructedConstantValue(constructedType, fieldValues));
1025 } 1067 }
1026 1068
1027 AstConstant visitParenthesizedExpression(ParenthesizedExpression node) { 1069 AstConstant visitParenthesizedExpression(ParenthesizedExpression node) {
1028 return node.expression.accept(this); 1070 return node.expression.accept(this);
1029 } 1071 }
1030 1072
1031 AstConstant signalNotCompileTimeConstant(Node node, 1073 AstConstant signalNotCompileTimeConstant(Node node,
1032 {MessageKind message: MessageKind.NOT_A_COMPILE_TIME_CONSTANT}) { 1074 {MessageKind message: MessageKind.NOT_A_COMPILE_TIME_CONSTANT}) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1078 return super.visitSend(send); 1120 return super.visitSend(send);
1079 } 1121 }
1080 1122
1081 void potentiallyCheckType(TypedElement element, AstConstant constant) { 1123 void potentiallyCheckType(TypedElement element, AstConstant constant) {
1082 if (compiler.options.enableTypeAssertions) { 1124 if (compiler.options.enableTypeAssertions) {
1083 DartType elementType = element.type.substByContext(constructedType); 1125 DartType elementType = element.type.substByContext(constructedType);
1084 DartType constantType = constant.value.getType(coreTypes); 1126 DartType constantType = constant.value.getType(coreTypes);
1085 if (!constantSystem.isSubtype( 1127 if (!constantSystem.isSubtype(
1086 compiler.types, constantType, elementType)) { 1128 compiler.types, constantType, elementType)) {
1087 reporter.withCurrentElement(constant.element, () { 1129 reporter.withCurrentElement(constant.element, () {
1088 reporter.reportErrorMessage( 1130 reporter.reportErrorMessage(constant.node, MessageKind.NOT_ASSIGNABLE,
1089 constant.node, 1131 {'fromType': constantType, 'toType': elementType});
1090 MessageKind.NOT_ASSIGNABLE,
1091 {'fromType': constantType,
1092 'toType': elementType});
1093 }); 1132 });
1094 } 1133 }
1095 } 1134 }
1096 } 1135 }
1097 1136
1098 void updateFieldValue(Node node, TypedElement element, AstConstant constant) { 1137 void updateFieldValue(Node node, TypedElement element, AstConstant constant) {
1099 potentiallyCheckType(element, constant); 1138 potentiallyCheckType(element, constant);
1100 fieldValues[element] = constant; 1139 fieldValues[element] = constant;
1101 } 1140 }
1102 1141
(...skipping 17 matching lines...) Expand all
1120 potentiallyCheckType(parameter, argument); 1159 potentiallyCheckType(parameter, argument);
1121 definitions[parameter] = argument; 1160 definitions[parameter] = argument;
1122 } 1161 }
1123 }); 1162 });
1124 } 1163 }
1125 1164
1126 void evaluateSuperOrRedirectSend( 1165 void evaluateSuperOrRedirectSend(
1127 List<AstConstant> compiledArguments, FunctionElement targetConstructor) { 1166 List<AstConstant> compiledArguments, FunctionElement targetConstructor) {
1128 ConstructorEvaluator evaluator = new ConstructorEvaluator( 1167 ConstructorEvaluator evaluator = new ConstructorEvaluator(
1129 constructedType.asInstanceOf(targetConstructor.enclosingClass), 1168 constructedType.asInstanceOf(targetConstructor.enclosingClass),
1130 targetConstructor, handler, compiler); 1169 targetConstructor,
1170 handler,
1171 compiler);
1131 evaluator.evaluateConstructorFieldValues(compiledArguments); 1172 evaluator.evaluateConstructorFieldValues(compiledArguments);
1132 // Copy over the fieldValues from the super/redirect-constructor. 1173 // Copy over the fieldValues from the super/redirect-constructor.
1133 // No need to go through [updateFieldValue] because the 1174 // No need to go through [updateFieldValue] because the
1134 // assignments have already been checked in checked mode. 1175 // assignments have already been checked in checked mode.
1135 evaluator.fieldValues.forEach((key, value) => fieldValues[key] = value); 1176 evaluator.fieldValues.forEach((key, value) => fieldValues[key] = value);
1136 } 1177 }
1137 1178
1138 /** 1179 /**
1139 * Runs through the initializers of the given [constructor] and updates 1180 * Runs through the initializers of the given [constructor] and updates
1140 * the [fieldValues] map. 1181 * the [fieldValues] map.
(...skipping 20 matching lines...) Expand all
1161 !link.isEmpty; 1202 !link.isEmpty;
1162 link = link.tail) { 1203 link = link.tail) {
1163 assert(link.head is Send); 1204 assert(link.head is Send);
1164 if (link.head is! SendSet) { 1205 if (link.head is! SendSet) {
1165 // A super initializer or constructor redirection. 1206 // A super initializer or constructor redirection.
1166 Send call = link.head; 1207 Send call = link.head;
1167 FunctionElement target = elements[call]; 1208 FunctionElement target = elements[call];
1168 if (!target.isMalformed) { 1209 if (!target.isMalformed) {
1169 List<AstConstant> compiledArguments = 1210 List<AstConstant> compiledArguments =
1170 evaluateArgumentsToConstructor( 1211 evaluateArgumentsToConstructor(
1171 call, 1212 call,
1172 elements.getSelector(call).callStructure, 1213 elements.getSelector(call).callStructure,
1173 call.arguments, 1214 call.arguments,
1174 target, 1215 target,
1175 compileArgument: evaluateConstant); 1216 compileArgument: evaluateConstant);
1176 evaluateSuperOrRedirectSend(compiledArguments, target); 1217 evaluateSuperOrRedirectSend(compiledArguments, target);
1177 } 1218 }
1178 foundSuperOrRedirect = true; 1219 foundSuperOrRedirect = true;
1179 } else { 1220 } else {
1180 // A field initializer. 1221 // A field initializer.
1181 SendSet init = link.head; 1222 SendSet init = link.head;
1182 Link<Node> initArguments = init.arguments; 1223 Link<Node> initArguments = init.arguments;
1183 assert(!initArguments.isEmpty && initArguments.tail.isEmpty); 1224 assert(!initArguments.isEmpty && initArguments.tail.isEmpty);
1184 AstConstant fieldValue = evaluate(initArguments.head); 1225 AstConstant fieldValue = evaluate(initArguments.head);
1185 updateFieldValue(init, elements[init], fieldValue); 1226 updateFieldValue(init, elements[init], fieldValue);
1186 } 1227 }
1187 } 1228 }
1188 } 1229 }
1189 1230
1190 if (!foundSuperOrRedirect) { 1231 if (!foundSuperOrRedirect) {
1191 // No super initializer found. Try to find the default constructor if 1232 // No super initializer found. Try to find the default constructor if
1192 // the class is not Object. 1233 // the class is not Object.
1193 ClassElement enclosingClass = constructor.enclosingClass; 1234 ClassElement enclosingClass = constructor.enclosingClass;
1194 ClassElement superClass = enclosingClass.superclass; 1235 ClassElement superClass = enclosingClass.superclass;
1195 if (!enclosingClass.isObject) { 1236 if (!enclosingClass.isObject) {
1196 assert(superClass != null); 1237 assert(superClass != null);
1197 assert(superClass.isResolved); 1238 assert(superClass.isResolved);
1198 1239
1199 FunctionElement targetConstructor = 1240 FunctionElement targetConstructor =
1200 superClass.lookupDefaultConstructor(); 1241 superClass.lookupDefaultConstructor();
1201 // If we do not find a default constructor, an error was reported 1242 // If we do not find a default constructor, an error was reported
1202 // already and compilation will fail anyway. So just ignore that case. 1243 // already and compilation will fail anyway. So just ignore that case.
1203 if (targetConstructor != null) { 1244 if (targetConstructor != null) {
1204 List<AstConstant> compiledArguments = evaluateArgumentsToConstructor( 1245 List<AstConstant> compiledArguments = evaluateArgumentsToConstructor(
1205 functionNode, CallStructure.NO_ARGS, const Link<Node>(), 1246 functionNode,
1247 CallStructure.NO_ARGS,
1248 const Link<Node>(),
1206 targetConstructor); 1249 targetConstructor);
1207 evaluateSuperOrRedirectSend(compiledArguments, targetConstructor); 1250 evaluateSuperOrRedirectSend(compiledArguments, targetConstructor);
1208 } 1251 }
1209 } 1252 }
1210 } 1253 }
1211 } 1254 }
1212 1255
1213 /** 1256 /**
1214 * Simulates the execution of the [constructor] with the given 1257 * Simulates the execution of the [constructor] with the given
1215 * [arguments] to obtain the field values that need to be passed to the 1258 * [arguments] to obtain the field values that need to be passed to the
1216 * native JavaScript constructor. 1259 * native JavaScript constructor.
1217 */ 1260 */
1218 void evaluateConstructorFieldValues(List<AstConstant> arguments) { 1261 void evaluateConstructorFieldValues(List<AstConstant> arguments) {
1219 if (constructor.isMalformed) return; 1262 if (constructor.isMalformed) return;
1220 reporter.withCurrentElement(constructor, () { 1263 reporter.withCurrentElement(constructor, () {
1221 assignArgumentsToParameters(arguments); 1264 assignArgumentsToParameters(arguments);
1222 evaluateConstructorInitializers(); 1265 evaluateConstructorInitializers();
1223 }); 1266 });
1224 } 1267 }
1225 1268
1226 /// Builds a normalized list of the constant values for each field in the 1269 /// Builds a normalized list of the constant values for each field in the
1227 /// inheritance chain of [classElement]. 1270 /// inheritance chain of [classElement].
1228 Map<FieldElement, AstConstant> buildFieldConstants( 1271 Map<FieldElement, AstConstant> buildFieldConstants(
1229 ClassElement classElement) { 1272 ClassElement classElement) {
1230 Map<FieldElement, AstConstant> fieldConstants = <FieldElement, AstConstant>{ 1273 Map<FieldElement, AstConstant> fieldConstants =
1231 }; 1274 <FieldElement, AstConstant>{};
1232 classElement.implementation 1275 classElement.implementation.forEachInstanceField(
1233 .forEachInstanceField((ClassElement enclosing, FieldElement field) { 1276 (ClassElement enclosing, FieldElement field) {
1234 AstConstant fieldValue = fieldValues[field]; 1277 AstConstant fieldValue = fieldValues[field];
1235 if (fieldValue == null) { 1278 if (fieldValue == null) {
1236 // Use the default value. 1279 // Use the default value.
1237 ConstantExpression fieldExpression = 1280 ConstantExpression fieldExpression =
1238 handler.internalCompileVariable(field, true, false); 1281 handler.internalCompileVariable(field, true, false);
1239 fieldValue = new AstConstant.fromDefaultValue( 1282 fieldValue = new AstConstant.fromDefaultValue(
1240 field, fieldExpression, handler.getConstantValue(fieldExpression)); 1283 field, fieldExpression, handler.getConstantValue(fieldExpression));
1241 // TODO(het): If the field value doesn't typecheck due to the type 1284 // TODO(het): If the field value doesn't typecheck due to the type
1242 // variable in the constructor invocation, then report the error on the 1285 // variable in the constructor invocation, then report the error on the
1243 // invocation rather than the field. 1286 // invocation rather than the field.
(...skipping 17 matching lines...) Expand all
1261 class AstConstant { 1304 class AstConstant {
1262 final Element element; 1305 final Element element;
1263 final Node node; 1306 final Node node;
1264 final ConstantExpression expression; 1307 final ConstantExpression expression;
1265 final ConstantValue value; 1308 final ConstantValue value;
1266 1309
1267 AstConstant(this.element, this.node, this.expression, this.value); 1310 AstConstant(this.element, this.node, this.expression, this.value);
1268 1311
1269 factory AstConstant.fromDefaultValue(VariableElement element, 1312 factory AstConstant.fromDefaultValue(VariableElement element,
1270 ConstantExpression constant, ConstantValue value) { 1313 ConstantExpression constant, ConstantValue value) {
1271 return new AstConstant(element, element.initializer != null 1314 return new AstConstant(
1272 ? element.initializer 1315 element,
1273 : element.node, constant, value); 1316 element.initializer != null ? element.initializer : element.node,
1317 constant,
1318 value);
1274 } 1319 }
1275 1320
1276 String toString() => expression.toString(); 1321 String toString() => expression.toString();
1277 } 1322 }
1278 1323
1279 /// A synthetic constant used to recover from errors. 1324 /// A synthetic constant used to recover from errors.
1280 class ErroneousAstConstant extends AstConstant { 1325 class ErroneousAstConstant extends AstConstant {
1281 ErroneousAstConstant(Element element, Node node) : super(element, node, 1326 ErroneousAstConstant(Element element, Node node)
1282 // TODO(johnniwinther): Return a [NonConstantValue] instead. 1327 : super(
1283 new ErroneousConstantExpression(), new NullConstantValue()); 1328 element,
1329 node,
1330 // TODO(johnniwinther): Return a [NonConstantValue] instead.
1331 new ErroneousConstantExpression(),
1332 new NullConstantValue());
1284 } 1333 }
1285 1334
1286 // TODO(johnniwinther): Clean this up. 1335 // TODO(johnniwinther): Clean this up.
1287 TreeElements _analyzeElementEagerly(Compiler compiler, AstElement element) { 1336 TreeElements _analyzeElementEagerly(Compiler compiler, AstElement element) {
1288 compiler.resolution.computeWorldImpact(element.declaration); 1337 compiler.resolution.computeWorldImpact(element.declaration);
1289 return element.resolvedAst.elements; 1338 return element.resolvedAst.elements;
1290 } 1339 }
1291 1340
1292 class _CompilerEnvironment implements Environment { 1341 class _CompilerEnvironment implements Environment {
1293 final Compiler compiler; 1342 final Compiler compiler;
1294 1343
1295 _CompilerEnvironment(this.compiler); 1344 _CompilerEnvironment(this.compiler);
1296 1345
1297 @override 1346 @override
1298 String readFromEnvironment(String name) { 1347 String readFromEnvironment(String name) {
1299 return compiler.fromEnvironment(name); 1348 return compiler.fromEnvironment(name);
1300 } 1349 }
1301 } 1350 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/common/work.dart ('k') | pkg/compiler/lib/src/compiler.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698