<commit_before>package japgolly.scalajs.react.extra.internal

import scala.reflect.macros.blackbox.Context
import japgolly.scalajs.react.extra.Reusability
import japgolly.scalajs.react.internal.ReactMacroUtils

class ReusabilityMacros(val c: Context) extends ReactMacroUtils {
  import c.universe._

  def quietCaseClass[T: c.WeakTypeTag]: c.Expr[Reusability[T]] =
    implCaseClass[T](Nil, false)

  def debugCaseClass[T: c.WeakTypeTag]: c.Expr[Reusability[T]] =
    implCaseClass[T](Nil, true)

  def quietCaseClassExcept[T: c.WeakTypeTag](field1: c.Expr[scala.Symbol], fieldN: c.Expr[scala.Symbol]*): c.Expr[Reusability[T]] =
    implCaseClass[T](field1 :: fieldN.toList, false)

  def debugCaseClassExcept[T: c.WeakTypeTag](field1: c.Expr[scala.Symbol], fieldN: c.Expr[scala.Symbol]*): c.Expr[Reusability[T]] =
    implCaseClass[T](field1 :: fieldN.toList, true)

  private def implCaseClass[T: c.WeakTypeTag](exclusions: Seq[c.Expr[scala.Symbol]], debug: Boolean): c.Expr[Reusability[T]] = {
    val T              = caseClassType[T]
    val fieldsAndTypes = primaryConstructorParamsExcluding(T, exclusions)
    val Reusability    = q"_root_.japgolly.scalajs.react.extra.Reusability"

    val impl =
      fieldsAndTypes match {
        case Nil =>
          q"$Reusability.const[$T](true)"

        case (n, t) :: Nil =>
          q"$Reusability.by[$T,$t](_.$n)"

        case _ =>
          var insts = Vector.empty[ValDef]
          var tests = Vector.empty[Tree]

          val reusability = c.typeOf[japgolly.scalajs.react.extra.Reusability[_]]
          val memo = collection.mutable.HashMap.empty[Type, TermName]
          for ((n, t) <- fieldsAndTypes) {
            val fp = memo.getOrElseUpdate(t, {
              val tmp = TermName(c.freshName())
              insts :+= q"val $tmp = ${needInferImplicit(appliedType(reusability, t))}"
              tmp
            })
            tests :+= q"$fp.test(a.$n, b.$n)"
          }

          val testExpr = tests.reduce((a,b) => q"$a && $b")

          q""" {
            ..$insts
            $Reusability.fn[$T]((a,b) => $testExpr)
          } """
      }

    if (debug) println("\n" + showCode(impl) + "\n")
    c.Expr[Reusability[T]](impl)
  }
}<commit_msg>Fix deprecation warning in ReusabilityMacros<commit_after>package japgolly.scalajs.react.extra.internal

import scala.reflect.macros.blackbox.Context
import japgolly.scalajs.react.extra.Reusability
import japgolly.scalajs.react.internal.ReactMacroUtils

class ReusabilityMacros(val c: Context) extends ReactMacroUtils {
  import c.universe._

  def quietCaseClass[T: c.WeakTypeTag]: c.Expr[Reusability[T]] =
    implCaseClass[T](Nil, false)

  def debugCaseClass[T: c.WeakTypeTag]: c.Expr[Reusability[T]] =
    implCaseClass[T](Nil, true)

  def quietCaseClassExcept[T: c.WeakTypeTag](field1: c.Expr[scala.Symbol], fieldN: c.Expr[scala.Symbol]*): c.Expr[Reusability[T]] =
    implCaseClass[T](field1 :: fieldN.toList, false)

  def debugCaseClassExcept[T: c.WeakTypeTag](field1: c.Expr[scala.Symbol], fieldN: c.Expr[scala.Symbol]*): c.Expr[Reusability[T]] =
    implCaseClass[T](field1 :: fieldN.toList, true)

  private def implCaseClass[T: c.WeakTypeTag](exclusions: Seq[c.Expr[scala.Symbol]], debug: Boolean): c.Expr[Reusability[T]] = {
    val T              = caseClassType[T]
    val fieldsAndTypes = primaryConstructorParamsExcluding(T, exclusions)
    val Reusability    = q"_root_.japgolly.scalajs.react.extra.Reusability"

    val impl =
      fieldsAndTypes match {
        case Nil =>
          q"$Reusability.const[$T](true)"

        case (n, t) :: Nil =>
          q"$Reusability.by[$T,$t](_.$n)"

        case _ =>
          var insts = Vector.empty[ValDef]
          var tests = Vector.empty[Tree]

          val reusability = c.typeOf[japgolly.scalajs.react.extra.Reusability[_]]
          val memo = collection.mutable.HashMap.empty[Type, TermName]
          for ((n, t) <- fieldsAndTypes) {
            val fp = memo.getOrElseUpdate(t, {
              val tmp = TermName(c.freshName())
              insts :+= q"val $tmp = ${needInferImplicit(appliedType(reusability, t))}"
              tmp
            })
            tests :+= q"$fp.test(a.$n, b.$n)"
          }

          val testExpr = tests.reduce((a,b) => q"$a && $b")

          q""" {
            ..$insts
            $Reusability[$T]((a,b) => $testExpr)
          } """
      }

    if (debug) println("\n" + showCode(impl) + "\n")
    c.Expr[Reusability[T]](impl)
  }
}
{'fraction_non_alphanumeric': 0.14959749552772808, 'fraction_numerical': 0.0017889087656529517, 'mean_word_length': 2.8895652173913042, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '20791', 'n_tokens_mistral': 1597, 'n_tokens_neox': 1540, 'n_words': 256}