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

Unified Diff: pkg/analyzer/lib/src/generated/static_type_analyzer.dart

Issue 1045553002: Implement the new '??' operator in analyzer. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix if_null_precedence_test for unchecked operation. Created 5 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/analyzer/lib/src/generated/incremental_scanner.dart ('k') | pkg/analyzer/lib/src/task/dart.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/generated/static_type_analyzer.dart
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index af157bbbc2701b4d804c8f2b9afefb29ebe60d92..79481baa2099c29eb08c7ac1aaf7384c89b50f16 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -6,6 +6,8 @@ library engine.resolver.static_type_analyzer;
import 'dart:collection';
+import 'package:analyzer/src/generated/scanner.dart';
+
import 'ast.dart';
import 'element.dart';
import 'java_engine.dart';
@@ -230,6 +232,14 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
*/
@override
Object visitBinaryExpression(BinaryExpression node) {
+ if (node.operator.type == TokenType.QUESTION_QUESTION) {
+ // Evaluation of an if-null expresion e of the form e1 ?? e2 is
+ // equivalent to the evaluation of the expression
+ // ((x) => x == null ? e2 : x)(e1). The static type of e is the least
+ // upper bound of the static type of e1 and the static type of e2.
+ _analyzeLeastUpperBound(node, node.leftOperand, node.rightOperand);
+ return null;
+ }
ExecutableElement staticMethodElement = node.staticElement;
DartType staticType = _computeStaticReturnType(staticMethodElement);
staticType = _refineBinaryExpressionType(node, staticType);
@@ -276,34 +286,7 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
*/
@override
Object visitConditionalExpression(ConditionalExpression node) {
- DartType staticThenType = _getStaticType(node.thenExpression);
- DartType staticElseType = _getStaticType(node.elseExpression);
- if (staticThenType == null) {
- // TODO(brianwilkerson) Determine whether this can still happen.
- staticThenType = _dynamicType;
- }
- if (staticElseType == null) {
- // TODO(brianwilkerson) Determine whether this can still happen.
- staticElseType = _dynamicType;
- }
- DartType staticType = staticThenType.getLeastUpperBound(staticElseType);
- if (staticType == null) {
- staticType = _dynamicType;
- }
- _recordStaticType(node, staticType);
- DartType propagatedThenType = node.thenExpression.propagatedType;
- DartType propagatedElseType = node.elseExpression.propagatedType;
- if (propagatedThenType != null || propagatedElseType != null) {
- if (propagatedThenType == null) {
- propagatedThenType = staticThenType;
- }
- if (propagatedElseType == null) {
- propagatedElseType = staticElseType;
- }
- DartType propagatedType =
- propagatedThenType.getLeastUpperBound(propagatedElseType);
- _recordPropagatedTypeIfBetter(node, propagatedType);
- }
+ _analyzeLeastUpperBound(node, node.thenExpression, node.elseExpression);
return null;
}
@@ -1198,6 +1181,42 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
}
/**
+ * Set the static (propagated) type of [node] to be the least upper bound
+ * of the static (propagated) types of subexpressions [expr1] and [expr2].
+ */
+ void _analyzeLeastUpperBound(
+ Expression node, Expression expr1, Expression expr2) {
+ DartType staticType1 = _getStaticType(expr1);
+ DartType staticType2 = _getStaticType(expr2);
+ if (staticType1 == null) {
+ // TODO(brianwilkerson) Determine whether this can still happen.
+ staticType1 = _dynamicType;
+ }
+ if (staticType2 == null) {
+ // TODO(brianwilkerson) Determine whether this can still happen.
+ staticType2 = _dynamicType;
+ }
+ DartType staticType = staticType1.getLeastUpperBound(staticType2);
+ if (staticType == null) {
+ staticType = _dynamicType;
+ }
+ _recordStaticType(node, staticType);
+ DartType propagatedType1 = expr1.propagatedType;
+ DartType propagatedType2 = expr2.propagatedType;
+ if (propagatedType1 != null || propagatedType2 != null) {
+ if (propagatedType1 == null) {
+ propagatedType1 = staticType1;
+ }
+ if (propagatedType2 == null) {
+ propagatedType2 = staticType2;
+ }
+ DartType propagatedType =
+ propagatedType1.getLeastUpperBound(propagatedType2);
+ _recordPropagatedTypeIfBetter(node, propagatedType);
+ }
+ }
+
+ /**
* Record that the static type of the given node is the type of the second argument to the method
* represented by the given element.
*
« no previous file with comments | « pkg/analyzer/lib/src/generated/incremental_scanner.dart ('k') | pkg/analyzer/lib/src/task/dart.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698