blob: 311db8a622e98e74d5d6c15e79d0c15f6782fe95 [file] [log] [blame]
// 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:analysis_server/src/nullability/nullability_node.dart';
/// Data structure to keep track of the relationship between [NullabilityNode]
/// objects.
class NullabilityGraph {
/// Map from a nullability node to those nodes that are "downstream" from it
/// (meaning that if a key node is nullable, then all the nodes in the
/// corresponding value will either have to be nullable, or null checks will
/// have to be added).
final _downstream = Map<NullabilityNode, List<NullabilityNode>>.identity();
/// Map from a nullability node to those nodes that are "upstream" from it
/// (meaning that if a node in the value is nullable, then the corresponding
/// key node will have to be nullable, or null checks will have to be added).
final _upstream = Map<NullabilityNode, List<NullabilityNode>>.identity();
/// Records that [sourceNode] is immediately upstream from [destinationNode].
void connect(NullabilityNode sourceNode, NullabilityNode destinationNode) {
(_downstream[sourceNode] ??= []).add(destinationNode);
(_upstream[destinationNode] ??= []).add(sourceNode);
}
void debugDump() {
for (var entry in _downstream.entries) {
print('${entry.key} -> ${entry.value.join(', ')}');
}
}
/// Iterates through all nodes that are "downstream" of [node] (i.e. if
/// [node] is nullable, then all the iterated nodes will either have to be
/// nullable, or null checks will have to be added).
///
/// There is no guarantee of uniqueness of the iterated nodes.
Iterable<NullabilityNode> getDownstreamNodes(NullabilityNode node) =>
_downstream[node] ?? const [];
/// Iterates through all nodes that are "upstream" of [node] (i.e. if
/// any of the iterated nodes are nullable, then [node] will either have to be
/// nullable, or null checks will have to be added).
// ///
// /// There is no guarantee of uniqueness of the iterated nodes.
Iterable<NullabilityNode> getUpstreamNodes(NullabilityNode node) =>
_upstream[node] ?? const [];
}