content: // Copyright 2016 Google Inc. Use of this source code is governed by an
  // MIT-style license that can be found in the LICENSE file or at
  // https://opensource.org/licenses/MIT.
  
  import 'package:meta/meta.dart';
  
  import '../../extend/functions.dart';
  import '../../visitor/interface/selector.dart';
  import '../selector.dart';
  
  /// Matches any element in the given namespace.
  ///
  /// {@category AST}
  final class UniversalSelector extends SimpleSelector {
    /// The selector namespace.
    ///
    /// If this is `null`, this matches all elements in the default namespace. If
    /// it's the empty string, this matches all elements that aren't in any
    /// namespace. If it's `*`, this matches all elements in any namespace.
    /// Otherwise, it matches all elements in the given namespace.
    final String? namespace;
  
    int get specificity => 0;
  
    UniversalSelector(super.span, {this.namespace});
  
    T accept<T>(SelectorVisitor<T> visitor) =>
        visitor.visitUniversalSelector(this);
  
    /// @nodoc
    @internal
    List<SimpleSelector>? unify(List<SimpleSelector> compound) {
      switch (compound) {
        case [UniversalSelector() || TypeSelector(), ...var rest]:
          var unified = unifyUniversalAndElement(this, compound.first);
          if (unified == null) return null;
          return [unified, ...rest];
  
        case [PseudoSelector first] when first.isHost || first.isHostContext:
          return null;
  
        case []:
          return [this];
  
        case _:
          return namespace == null || namespace == "*"
              ? compound
              : [this, ...compound];
      }
    }
  
    bool isSuperselector(SimpleSelector other) {
      if (namespace == '*') return true;
      if (other is TypeSelector) return namespace == other.name.namespace;
      if (other is UniversalSelector) return namespace == other.namespace;
      return namespace == null || super.isSuperselector(other);
    }
  
    bool operator ==(Object other) =>
        other is UniversalSelector && other.namespace == namespace;
  
    int get hashCode => namespace.hashCode;
  }
  