anchor.diff:    final String pattern;
   
     // The resulting matching rule. `null` if the pattern was empty or invalid.
  -  final _IgnoreRule rule;
  +  final _IgnoreRule? rule;
   
     // An invalid pattern is also considered empty.
     bool get empty => rule == null;
     bool get valid => exception == null;
   
     // For invalid patterns this contains a description of the problem.
  -  final FormatException exception;
  +  final FormatException? exception;
   
     _IgnoreParseResult(this.pattern, this.rule) : exception = null;
     _IgnoreParseResult.invalid(this.pattern, this.exception) : rule = null;
  
positive.code: /// expects [path] to start with '/'
  ///
  /// If [path] should be matched as a directory, it should end with '/'.
  bool _matchesStack(List<_IgnorePrefixPair> ignores, String path) {
    // This is optimized by trying the rules in reverse order.
    // If a rule matches, the result is true if the rule is not negative.
    for (final ignorePair in ignores.reversed) {
  
negative.code:     // directories leading up to the current entity.
      // The single `null` aligns popping and pushing in this stack with [toVisit]
      // below.
      final ignoreStack = <_IgnorePrefixPair?>[null];
      // Find all ignores between './' and [beneath] (not inclusive).
  
      // [index] points at the next '/' in the path.
  