OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 serialization.summarize_const_expr; | 5 library serialization.summarize_const_expr; |
6 | 6 |
7 import 'package:analyzer/dart/ast/ast.dart'; | 7 import 'package:analyzer/dart/ast/ast.dart'; |
8 import 'package:analyzer/dart/ast/token.dart'; | 8 import 'package:analyzer/dart/ast/token.dart'; |
9 import 'package:analyzer/dart/element/type.dart' show DartType; | 9 import 'package:analyzer/dart/element/type.dart' show DartType; |
10 import 'package:analyzer/src/summary/format.dart'; | 10 import 'package:analyzer/src/summary/format.dart'; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 } | 62 } |
63 throw new StateError('Unexpected initializer type ${node.runtimeType}'); | 63 throw new StateError('Unexpected initializer type ${node.runtimeType}'); |
64 } | 64 } |
65 | 65 |
66 /** | 66 /** |
67 * Instances of this class keep track of intermediate state during | 67 * Instances of this class keep track of intermediate state during |
68 * serialization of a single constant [Expression]. | 68 * serialization of a single constant [Expression]. |
69 */ | 69 */ |
70 abstract class AbstractConstExprSerializer { | 70 abstract class AbstractConstExprSerializer { |
71 /** | 71 /** |
| 72 * Whether an expression that should be a constant is being serialized. |
| 73 * |
| 74 * For constants we need to store more than we need just for type inference, |
| 75 * because we need to be able to restore these AST to evaluate actual values |
| 76 * of constants. So, we need to store constructor arguments, elements for |
| 77 * list and map literals even if these literals are typed. |
| 78 */ |
| 79 final bool forConst; |
| 80 |
| 81 /** |
72 * See [UnlinkedExprBuilder.isValidConst]. | 82 * See [UnlinkedExprBuilder.isValidConst]. |
73 */ | 83 */ |
74 bool isValidConst = true; | 84 bool isValidConst = true; |
75 | 85 |
76 /** | 86 /** |
77 * See [UnlinkedExprBuilder.name]. | 87 * See [UnlinkedExprBuilder.name]. |
78 */ | 88 */ |
79 String name = null; | 89 String name = null; |
80 | 90 |
81 /** | 91 /** |
(...skipping 20 matching lines...) Expand all Loading... |
102 /** | 112 /** |
103 * See [UnlinkedExprBuilder.strings]. | 113 * See [UnlinkedExprBuilder.strings]. |
104 */ | 114 */ |
105 final List<String> strings = <String>[]; | 115 final List<String> strings = <String>[]; |
106 | 116 |
107 /** | 117 /** |
108 * See [UnlinkedExprBuilder.references]. | 118 * See [UnlinkedExprBuilder.references]. |
109 */ | 119 */ |
110 final List<EntityRefBuilder> references = <EntityRefBuilder>[]; | 120 final List<EntityRefBuilder> references = <EntityRefBuilder>[]; |
111 | 121 |
| 122 AbstractConstExprSerializer(this.forConst); |
| 123 |
112 /** | 124 /** |
113 * Return `true` if the given [name] is a parameter reference. | 125 * Return `true` if the given [name] is a parameter reference. |
114 */ | 126 */ |
115 bool isParameterName(String name); | 127 bool isParameterName(String name); |
116 | 128 |
117 /** | 129 /** |
118 * Serialize the given [expr] expression into this serializer state. | 130 * Serialize the given [expr] expression into this serializer state. |
119 */ | 131 */ |
120 void serialize(Expression expr) { | 132 void serialize(Expression expr) { |
121 try { | 133 try { |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 } else if (expr is AwaitExpression) { | 418 } else if (expr is AwaitExpression) { |
407 isValidConst = false; | 419 isValidConst = false; |
408 _serialize(expr.expression); | 420 _serialize(expr.expression); |
409 operations.add(UnlinkedExprOperation.await); | 421 operations.add(UnlinkedExprOperation.await); |
410 } else { | 422 } else { |
411 throw new StateError('Unknown expression type: $expr'); | 423 throw new StateError('Unknown expression type: $expr'); |
412 } | 424 } |
413 } | 425 } |
414 | 426 |
415 void _serializeArguments(ArgumentList argumentList) { | 427 void _serializeArguments(ArgumentList argumentList) { |
416 List<Expression> arguments = argumentList.arguments; | 428 if (forConst) { |
417 // Serialize the arguments. | 429 List<Expression> arguments = argumentList.arguments; |
418 List<String> argumentNames = <String>[]; | 430 // Serialize the arguments. |
419 arguments.forEach((arg) { | 431 List<String> argumentNames = <String>[]; |
420 if (arg is NamedExpression) { | 432 arguments.forEach((arg) { |
421 argumentNames.add(arg.name.label.name); | 433 if (arg is NamedExpression) { |
422 _serialize(arg.expression); | 434 argumentNames.add(arg.name.label.name); |
423 } else { | 435 _serialize(arg.expression); |
424 _serialize(arg); | 436 } else { |
425 } | 437 _serialize(arg); |
426 }); | 438 } |
427 // Add numbers of named and positional arguments, and the op-code. | 439 }); |
428 ints.add(argumentNames.length); | 440 // Add numbers of named and positional arguments, and the op-code. |
429 strings.addAll(argumentNames); | 441 ints.add(argumentNames.length); |
430 ints.add(arguments.length - argumentNames.length); | 442 strings.addAll(argumentNames); |
| 443 ints.add(arguments.length - argumentNames.length); |
| 444 } else { |
| 445 ints.add(0); |
| 446 ints.add(0); |
| 447 } |
431 } | 448 } |
432 | 449 |
433 void _serializeAssignment(AssignmentExpression expr) { | 450 void _serializeAssignment(AssignmentExpression expr) { |
434 isValidConst = false; | 451 isValidConst = false; |
435 // Push the value. | 452 // Push the value. |
436 _serialize(expr.rightHandSide); | 453 _serialize(expr.rightHandSide); |
437 // Push the assignment operator. | 454 // Push the assignment operator. |
438 TokenType operator = expr.operator.type; | 455 TokenType operator = expr.operator.type; |
439 UnlinkedExprAssignOperator assignmentOperator; | 456 UnlinkedExprAssignOperator assignmentOperator; |
440 if (operator == TokenType.EQ) { | 457 if (operator == TokenType.EQ) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
514 } else if (operator == TokenType.PERCENT) { | 531 } else if (operator == TokenType.PERCENT) { |
515 operations.add(UnlinkedExprOperation.modulo); | 532 operations.add(UnlinkedExprOperation.modulo); |
516 } else if (operator == TokenType.QUESTION_QUESTION) { | 533 } else if (operator == TokenType.QUESTION_QUESTION) { |
517 operations.add(UnlinkedExprOperation.ifNull); | 534 operations.add(UnlinkedExprOperation.ifNull); |
518 } else { | 535 } else { |
519 throw new StateError('Unknown operator: $operator'); | 536 throw new StateError('Unknown operator: $operator'); |
520 } | 537 } |
521 } | 538 } |
522 | 539 |
523 void _serializeListLiteral(ListLiteral expr) { | 540 void _serializeListLiteral(ListLiteral expr) { |
524 List<Expression> elements = expr.elements; | 541 if (forConst || expr.typeArguments == null) { |
525 elements.forEach(_serialize); | 542 List<Expression> elements = expr.elements; |
526 ints.add(elements.length); | 543 elements.forEach(_serialize); |
| 544 ints.add(elements.length); |
| 545 } else { |
| 546 ints.add(0); |
| 547 } |
527 if (expr.typeArguments != null && | 548 if (expr.typeArguments != null && |
528 expr.typeArguments.arguments.length == 1) { | 549 expr.typeArguments.arguments.length == 1) { |
529 references.add(serializeTypeName(expr.typeArguments.arguments[0])); | 550 references.add(serializeTypeName(expr.typeArguments.arguments[0])); |
530 operations.add(UnlinkedExprOperation.makeTypedList); | 551 operations.add(UnlinkedExprOperation.makeTypedList); |
531 } else { | 552 } else { |
532 operations.add(UnlinkedExprOperation.makeUntypedList); | 553 operations.add(UnlinkedExprOperation.makeUntypedList); |
533 } | 554 } |
534 } | 555 } |
535 | 556 |
536 void _serializeMapLiteral(MapLiteral expr) { | 557 void _serializeMapLiteral(MapLiteral expr) { |
537 for (MapLiteralEntry entry in expr.entries) { | 558 if (forConst || expr.typeArguments == null) { |
538 _serialize(entry.key); | 559 for (MapLiteralEntry entry in expr.entries) { |
539 _serialize(entry.value); | 560 _serialize(entry.key); |
| 561 _serialize(entry.value); |
| 562 } |
| 563 ints.add(expr.entries.length); |
| 564 } else { |
| 565 ints.add(0); |
540 } | 566 } |
541 ints.add(expr.entries.length); | |
542 if (expr.typeArguments != null && | 567 if (expr.typeArguments != null && |
543 expr.typeArguments.arguments.length == 2) { | 568 expr.typeArguments.arguments.length == 2) { |
544 references.add(serializeTypeName(expr.typeArguments.arguments[0])); | 569 references.add(serializeTypeName(expr.typeArguments.arguments[0])); |
545 references.add(serializeTypeName(expr.typeArguments.arguments[1])); | 570 references.add(serializeTypeName(expr.typeArguments.arguments[1])); |
546 operations.add(UnlinkedExprOperation.makeTypedMap); | 571 operations.add(UnlinkedExprOperation.makeTypedMap); |
547 } else { | 572 } else { |
548 operations.add(UnlinkedExprOperation.makeUntypedMap); | 573 operations.add(UnlinkedExprOperation.makeUntypedMap); |
549 } | 574 } |
550 } | 575 } |
551 | 576 |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
664 if (typeArguments == null) { | 689 if (typeArguments == null) { |
665 ints.add(0); | 690 ints.add(0); |
666 } else { | 691 } else { |
667 ints.add(typeArguments.arguments.length); | 692 ints.add(typeArguments.arguments.length); |
668 for (TypeAnnotation type in typeArguments.arguments) { | 693 for (TypeAnnotation type in typeArguments.arguments) { |
669 references.add(serializeTypeName(type)); | 694 references.add(serializeTypeName(type)); |
670 } | 695 } |
671 } | 696 } |
672 } | 697 } |
673 } | 698 } |
OLD | NEW |