content: // Copyright 2021 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:js/js.dart';
  
  import '../../value.dart';
  import '../../util/nullable.dart';
  import '../immutable.dart';
  import '../reflection.dart';
  
  /// The JavaScript `SassNumber` class.
  final JSClass numberClass = () {
    var jsClass = createJSClass('sass.SassNumber', (
      Object self,
      num value, [
      Object? unitOrOptions,
    ]) {
      if (unitOrOptions is String) return SassNumber(value, unitOrOptions);
  
      var options = unitOrOptions as _ConstructorOptions?;
      return SassNumber.withUnits(
        value,
        numeratorUnits:
            options?.numeratorUnits.andThen(jsToDartList)?.cast<String>(),
        denominatorUnits:
            options?.denominatorUnits.andThen(jsToDartList)?.cast<String>(),
      );
    });
  
    jsClass.defineGetters({
      'value': (SassNumber self) => self.value,
      'isInt': (SassNumber self) => self.isInt,
      'asInt': (SassNumber self) => self.asInt,
      'numeratorUnits': (SassNumber self) => ImmutableList(self.numeratorUnits),
      'denominatorUnits': (SassNumber self) =>
          ImmutableList(self.denominatorUnits),
      'hasUnits': (SassNumber self) => self.hasUnits,
    });
  
    jsClass.defineMethods({
      'assertInt': (SassNumber self, [String? name]) => self.assertInt(name),
      'assertInRange': (SassNumber self, num min, num max, [String? name]) =>
          self.valueInRange(min, max, name),
      'assertNoUnits': (SassNumber self, [String? name]) =>
          self..assertNoUnits(name),
      'assertUnit': (SassNumber self, String unit, [String? name]) =>
          self..assertUnit(unit, name),
      'hasUnit': (SassNumber self, String unit) => self.hasUnit(unit),
      'compatibleWithUnit': (SassNumber self, String unit) =>
          self.hasUnits && self.compatibleWithUnit(unit),
      'convert': (
        SassNumber self,
        Object numeratorUnits,
        Object denominatorUnits, [
        String? name,
      ]) =>
          self.convert(
            jsToDartList(numeratorUnits).cast<String>(),
            jsToDartList(denominatorUnits).cast<String>(),
            name,
          ),
      'convertToMatch': (
        SassNumber self,
        SassNumber other, [
        String? name,
        String? otherName,
      ]) =>
          self.convertToMatch(other, name, otherName),
      'convertValue': (
        SassNumber self,
        Object numeratorUnits,
        Object denominatorUnits, [
        String? name,
      ]) =>
          self.convertValue(
            jsToDartList(numeratorUnits).cast<String>(),
            jsToDartList(denominatorUnits).cast<String>(),
            name,
          ),
      'convertValueToMatch': (
        SassNumber self,
        SassNumber other, [
        String? name,
        String? otherName,
      ]) =>
          self.convertValueToMatch(other, name, otherName),
      'coerce': (
        SassNumber self,
        Object numeratorUnits,
        Object denominatorUnits, [
        String? name,
      ]) =>
          self.coerce(
            jsToDartList(numeratorUnits).cast<String>(),
            jsToDartList(denominatorUnits).cast<String>(),
            name,
          ),
      'coerceToMatch': (
        SassNumber self,
        SassNumber other, [
        String? name,
        String? otherName,
      ]) =>
          self.coerceToMatch(other, name, otherName),
      'coerceValue': (
        SassNumber self,
        Object numeratorUnits,
        Object denominatorUnits, [
        String? name,
      ]) =>
          self.coerceValue(
            jsToDartList(numeratorUnits).cast<String>(),
            jsToDartList(denominatorUnits).cast<String>(),
            name,
          ),
      'coerceValueToMatch': (
        SassNumber self,
        SassNumber other, [
        String? name,
        String? otherName,
      ]) =>
          self.coerceValueToMatch(other, name, otherName),
    });
  
    // Our concrete number types are actually subclasses of [SassNumber], so we
    // have to go up one in the superclass chain to inject [jsClass].
    getJSClass(SassNumber(0)).superclass.injectSuperclass(jsClass);
  
    return jsClass;
  }();
  
  @JS()
  @anonymous
  class _ConstructorOptions {
    external Object? get numeratorUnits;
    external Object? get denominatorUnits;
  }
  