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) { |