content: // Copyright 2023 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 '../callable.dart';
  import '../exception.dart';
  import '../visitor/interface/value.dart';
  import '../value.dart';
  
  /// A SassScript mixin reference.
  ///
  /// A mixin reference captures a mixin from the local environment so that
  /// it may be passed between modules.
  ///
  /// {@category Value}
  final class SassMixin extends Value {
    /// The callable that this mixin invokes.
    ///
    /// Note that this is typed as an [AsyncCallable] so that it will work with
    /// both synchronous and asynchronous evaluate visitors, but in practice the
    /// synchronous evaluate visitor will crash if this isn't a [Callable].
    ///
    /// @nodoc
    @internal
    final AsyncCallable callable;
  
    /// The unique compile context for tracking if this [SassMixin] belongs to the
    /// current compilation or not.
    final Object? _compileContext;
  
    SassMixin(this.callable) : _compileContext = null;
  
    @internal
    SassMixin.withCompileContext(this.callable, this._compileContext);
  
    /// @nodoc
    @internal
    T accept<T>(ValueVisitor<T> visitor) => visitor.visitMixin(this);
  
    SassMixin assertMixin([String? name]) => this;
  
    /// Asserts that this SassMixin belongs to [compileContext] and returns it.
    ///
    /// It's checked before evaluating a SassMixin to prevent execution of
    /// SassMixin across different compilations.
    @internal
    SassMixin assertCompileContext(Object compileContext) {
      if (_compileContext != null && _compileContext != compileContext) {
        throw SassScriptException(
            "$this does not belong to current compilation.");
      }
  
      return this;
    }
  
    bool operator ==(Object other) =>
        other is SassMixin && callable == other.callable;
  
    int get hashCode => callable.hashCode;
  }
  