Support prefix ++ and -- operators
Change-Id: I2437469ad67721736a6b4800f0134e0f358a7dbf
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/106970
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/nnbd_migration/lib/src/graph_builder.dart b/pkg/nnbd_migration/lib/src/graph_builder.dart
index 412a3ba..2360633 100644
--- a/pkg/nnbd_migration/lib/src/graph_builder.dart
+++ b/pkg/nnbd_migration/lib/src/graph_builder.dart
@@ -572,8 +572,25 @@
DecoratedType visitPrefixExpression(PrefixExpression node) {
/* DecoratedType operandType = */
_handleAssignment(_notNullType, node.operand);
- if (node.operator.type == TokenType.BANG) {
+ var operatorType = node.operator.type;
+ if (operatorType == TokenType.BANG) {
return _nonNullableBoolType;
+ } else if (operatorType == TokenType.PLUS_PLUS ||
+ operatorType == TokenType.MINUS_MINUS) {
+ var callee = node.staticElement;
+ if (callee is ClassMemberElement &&
+ callee.enclosingElement.typeParameters.isNotEmpty) {
+ // TODO(paulberry)
+ _unimplemented(node,
+ 'Operator ${operatorType.lexeme} defined on a class with type parameters');
+ }
+ if (callee == null) {
+ // TODO(paulberry)
+ _unimplemented(node, 'Unresolved operator ${operatorType.lexeme}');
+ }
+ var calleeType = getOrComputeElementType(callee);
+ // TODO(paulberry): substitute if necessary
+ return calleeType.returnType;
}
// TODO(brianwilkerson) The remaining cases are invocations.
_unimplemented(
diff --git a/pkg/nnbd_migration/test/graph_builder_test.dart b/pkg/nnbd_migration/test/graph_builder_test.dart
index 7835703..5b408e3 100644
--- a/pkg/nnbd_migration/test/graph_builder_test.dart
+++ b/pkg/nnbd_migration/test/graph_builder_test.dart
@@ -1335,7 +1335,7 @@
assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true);
}
- test_prefixExpression_bang2() async {
+ test_prefixExpression_bang() async {
await analyze('''
bool f(bool b) {
return !b;
@@ -1350,6 +1350,36 @@
assertEdge(never, return_f, hard: false);
}
+ test_prefixExpression_minusMinus() async {
+ await analyze('''
+int f(int i) {
+ return --i;
+}
+''');
+
+ var declaration = decoratedTypeAnnotation('int i').node;
+ var use = checkExpression('i;');
+ assertNullCheck(use, assertEdge(declaration, never, hard: true));
+
+ var returnType = decoratedTypeAnnotation('int f').node;
+ assertEdge(never, returnType, hard: false);
+ }
+
+ test_prefixExpression_plusPlus() async {
+ await analyze('''
+int f(int i) {
+ return ++i;
+}
+''');
+
+ var declaration = decoratedTypeAnnotation('int i').node;
+ var use = checkExpression('i;');
+ assertNullCheck(use, assertEdge(declaration, never, hard: true));
+
+ var returnType = decoratedTypeAnnotation('int f').node;
+ assertEdge(never, returnType, hard: false);
+ }
+
test_propertyAccess_return_type() async {
await analyze('''
class C {