| // Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| import 'package:analyzer/dart/ast/ast.dart'; |
| import 'package:nnbd_migration/src/conditional_discard.dart'; |
| |
| /// Records information about how a conditional expression or statement might |
| /// need to be modified. |
| class ConditionalModification { |
| final int offset; |
| |
| final int end; |
| |
| final bool isStatement; |
| |
| final ConditionalDiscard discard; |
| |
| final _KeepNode condition; |
| |
| final _KeepNode thenStatement; |
| |
| final _KeepNode? elseStatement; |
| |
| factory ConditionalModification(AstNode node, ConditionalDiscard discard) { |
| if (node is IfStatement) { |
| return ConditionalModification._( |
| node.offset, |
| node.end, |
| true, |
| discard, |
| _KeepNode(node.condition), |
| _KeepNode(node.thenStatement), |
| node.elseStatement == null ? null : _KeepNode(node.elseStatement!)); |
| } else if (node is IfElement) { |
| return ConditionalModification._( |
| node.offset, |
| node.end, |
| node is Statement, |
| discard, |
| _KeepNode(node.condition), |
| _KeepNode(node.thenElement), |
| node.elseElement == null ? null : _KeepNode(node.elseElement!)); |
| } else { |
| throw UnimplementedError('TODO(paulberry)'); |
| } |
| } |
| |
| ConditionalModification._(this.offset, this.end, this.isStatement, |
| this.discard, this.condition, this.thenStatement, this.elseStatement); |
| } |
| |
| /// Helper object used by [ConditionalModification] to keep track of AST nodes |
| /// within the conditional expression. |
| class _KeepNode { |
| final int offset; |
| |
| final int end; |
| |
| final bool isExpression; |
| |
| factory _KeepNode(AstNode node) { |
| int offset = node.offset; |
| int end = node.end; |
| if (node is Block && node.statements.isNotEmpty) { |
| offset = node.statements.beginToken!.offset; |
| end = node.statements.endToken!.end; |
| } |
| return _KeepNode._(offset, end, node is Expression); |
| } |
| |
| _KeepNode._(this.offset, this.end, this.isExpression); |
| } |