| Index: sdk/lib/_internal/compiler/implementation/typechecker.dart
|
| diff --git a/sdk/lib/_internal/compiler/implementation/typechecker.dart b/sdk/lib/_internal/compiler/implementation/typechecker.dart
|
| index d060765e05196e70d83e73026d7ba1507e529773..79ea3ef0c084b248b936a8c1cf09dc376f7c24ef 100644
|
| --- a/sdk/lib/_internal/compiler/implementation/typechecker.dart
|
| +++ b/sdk/lib/_internal/compiler/implementation/typechecker.dart
|
| @@ -185,7 +185,7 @@ class TypePromotion {
|
| }
|
|
|
| String toString() {
|
| - return 'Promote ${variable} to ${type}';
|
| + return 'Promote ${variable} to ${type}${isValid ? '' : ' (invalid)'}';
|
| }
|
| }
|
|
|
| @@ -410,16 +410,18 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| }
|
| }
|
|
|
| - void reshowTypePromotions(Node node, Node receiver, Node argument) {
|
| - for (TypePromotion typePromotion in getShownTypePromotionsFor(receiver)) {
|
| + /// Show type promotions from [left] and [right] in [node] given that the
|
| + /// promoted variables are not potentially mutated in [right].
|
| + void reshowTypePromotions(Node node, Node left, Node right) {
|
| + for (TypePromotion typePromotion in getShownTypePromotionsFor(left)) {
|
| typePromotion = typePromotion.copy();
|
| - checkTypePromotion(argument, typePromotion);
|
| + checkTypePromotion(right, typePromotion);
|
| showTypePromotion(node, typePromotion);
|
| }
|
|
|
| - for (TypePromotion typePromotion in getShownTypePromotionsFor(argument)) {
|
| + for (TypePromotion typePromotion in getShownTypePromotionsFor(right)) {
|
| typePromotion = typePromotion.copy();
|
| - checkTypePromotion(argument, typePromotion);
|
| + checkTypePromotion(right, typePromotion);
|
| showTypePromotion(node, typePromotion);
|
| }
|
| }
|
| @@ -931,6 +933,17 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| analyze(node.receiver);
|
| if (!node.isIsNotCheck) {
|
| Element variable = elements[node.receiver];
|
| + if (variable == null) {
|
| + // Look for the variable element within parenthesized expressions.
|
| + ParenthesizedExpression parentheses =
|
| + node.receiver.asParenthesizedExpression();
|
| + while (parentheses != null) {
|
| + variable = elements[parentheses.expression];
|
| + if (variable != null) break;
|
| + parentheses = parentheses.expression.asParenthesizedExpression();
|
| + }
|
| + }
|
| +
|
| if (variable != null &&
|
| (variable.isVariable() || variable.isParameter())) {
|
| DartType knownType = getKnownType(variable);
|
| @@ -1410,7 +1423,12 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| }
|
|
|
| DartType visitParenthesizedExpression(ParenthesizedExpression node) {
|
| - return analyze(node.expression);
|
| + Expression expression = node.expression;
|
| + DartType type = analyze(expression);
|
| + for (TypePromotion typePromotion in getShownTypePromotionsFor(expression)) {
|
| + showTypePromotion(node, typePromotion);
|
| + }
|
| + return type;
|
| }
|
|
|
| DartType visitConditional(Conditional node) {
|
|
|