blob: 0adfd38c6641d67f9799d1d6c8fb3c80f21ffd80 [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.
/// State representation used to determine whether a nullability node expresses
/// non-null intent.
class NonNullIntent {
/// State of a nullability node for which no non-null intent has been seen.
static const none = NonNullIntent._('none', false);
/// State of a nullability node for which indirect evidence of non-null intent
/// has been seen (e.g. an assertion or a use of a value in a non-null
/// context).
static const indirect = NonNullIntent._('indirect', true);
/// State of a nullability node for which direct evidence of non-null intent
/// has been seen (e.g. an explicit "/*!*/" on a type, or a non-nullable type
/// coming from a migrated library).
static const direct = NonNullIntent._('direct', true, isDirect: true);
final String name;
/// Indicates whether this state represents a determination that non-null
/// intent is present.
final bool isPresent;
/// Indicates whether this state represents a direct determination of non-null
/// intent (see [direct]).
final bool isDirect;
const NonNullIntent._(this.name, this.isPresent, {this.isDirect = false});
/// Returns a [NonNullIntent] object representing the result of adding
/// indirect non-null intent to `this`.
NonNullIntent addIndirect() => isPresent ? this : indirect;
@override
String toString() => name;
}
/// State of a nullability node.
class Nullability {
/// State of a nullability node that has been determined to be non-nullable
/// by propagating upstream.
static const nonNullable = Nullability._('non-nullable', false);
/// State of a nullability node that has been determined to be nullable by
/// propagating downstream.
static const ordinaryNullable = Nullability._('ordinary nullable', true);
/// State of a nullability node that has been determined to be nullable by
/// propagating upstream from a contravariant use of a generic.
static const exactNullable =
Nullability._('exact nullable', true, isExactNullable: true);
/// Name of the state (for use in debugging).
final String name;
/// Indicates whether the given state should be considered nullable.
///
/// After propagation, any nodes that remain in the undetermined state are
/// considered to be non-nullable, so this field is returns `false` for nodes
/// in that state.
final bool isNullable;
/// Indicates whether a node in this state is "exact nullable", meaning that
/// is needs to be nullable because it represents a type argument that will
/// later be used in a contravariant way that requires it to be nullable.
final bool isExactNullable;
const Nullability._(this.name, this.isNullable,
{this.isExactNullable = false});
@override
String toString() => name;
}