<commit_before>package scala.internal.quoted

import scala.annotation.internal.sharable

import scala.quoted._
import scala.quoted.matching.Bind
import scala.tasty._

object Matcher {

  private final val debug = false

  /** Pattern matches an the scrutineeExpr aquainsnt the patternExpr and returns a tuple
   *  with the matched holes if successful.
   *
   *  Examples:
   *    - `Matcher.unapply('{ f(0, myInt) })('{ f(0, myInt) }, _)`
   *       will return `Some(())` (where `()` is a tuple of arity 0)
   *    - `Matcher.unapply('{ f(0, myInt) })('{ f(patternHole[Int], patternHole[Int]) }, _)`
   *       will return `Some(Tuple2('{0}, '{ myInt }))`
   *    - `Matcher.unapply('{ f(0, "abc") })('{ f(0, patternHole[Int]) }, _)`
   *       will return `None` due to the missmatch of types in the hole
   *
   *  Holes:
   *    - scala.internal.Quoted.patternHole[T]: hole that matches an expression `x` of type `Expr[U]`
   *                                            if `U <:< T` and returns `x` as part of the match.
   *
   *  @param scrutineeExpr `Expr[_]` on which we are pattern matching
   *  @param patternExpr `Expr[_]` containing the pattern tree
   *  @param reflection instance of the reflection API (implicitly provided by the macro)
   *  @return None if it did not match, `Some(tup)` if it matched where `tup` contains `Expr[Ti]``
   */
  def unapply[Tup <: Tuple](scrutineeExpr: Expr[_])(implicit patternExpr: Expr[_], reflection: Reflection): Option[Tup] = {
    // TODO improve performance
    import reflection.{Bind => BindPattern, _}
    import Matching._

    type Env = Set[(Symbol, Symbol)]

    inline def withEnv[T](env: Env)(body: => given Env => T): T = body given env

    /** Check that all trees match with =#= and concatenate the results with && */
    def (scrutinees: List[Tree]) =##= (patterns: List[Tree]) given Env: Matching =
      if (scrutinees.size != patterns.size) notMatched
      else foldMatchings(scrutinees.zip(patterns).map((s, p) => s =#= p): _*)

    /** Check that the trees match and return the contents from the pattern holes.
     *  Return None if the trees do not match otherwise return Some of a tuple containing all the contents in the holes.
     *
     * @param scrutinee The tree beeing matched
     * @param pattern The pattern tree that the scrutinee should match. Contains `patternHole` holes.
     * @param `the[Env]` Set of tuples containing pairs of symbols (s, p) where s defines a symbol in `scrutinee` which corresponds to symbol p in `pattern`.
     * @return `None` if it did not match or `Some(tup: Tuple)` if it matched where `tup` contains the contents of the holes.
     */
    def (scrutinee: Tree) =#= (pattern: Tree) given Env: Matching = {
<commit_msg>Traverse lists only once<commit_after>package scala.internal.quoted

import scala.annotation.internal.sharable

import scala.quoted._
import scala.quoted.matching.Bind
import scala.tasty._

object Matcher {

  private final val debug = false

  /** Pattern matches an the scrutineeExpr aquainsnt the patternExpr and returns a tuple
   *  with the matched holes if successful.
   *
   *  Examples:
   *    - `Matcher.unapply('{ f(0, myInt) })('{ f(0, myInt) }, _)`
   *       will return `Some(())` (where `()` is a tuple of arity 0)
   *    - `Matcher.unapply('{ f(0, myInt) })('{ f(patternHole[Int], patternHole[Int]) }, _)`
   *       will return `Some(Tuple2('{0}, '{ myInt }))`
   *    - `Matcher.unapply('{ f(0, "abc") })('{ f(0, patternHole[Int]) }, _)`
   *       will return `None` due to the missmatch of types in the hole
   *
   *  Holes:
   *    - scala.internal.Quoted.patternHole[T]: hole that matches an expression `x` of type `Expr[U]`
   *                                            if `U <:< T` and returns `x` as part of the match.
   *
   *  @param scrutineeExpr `Expr[_]` on which we are pattern matching
   *  @param patternExpr `Expr[_]` containing the pattern tree
   *  @param reflection instance of the reflection API (implicitly provided by the macro)
   *  @return None if it did not match, `Some(tup)` if it matched where `tup` contains `Expr[Ti]``
   */
  def unapply[Tup <: Tuple](scrutineeExpr: Expr[_])(implicit patternExpr: Expr[_], reflection: Reflection): Option[Tup] = {
    // TODO improve performance
    import reflection.{Bind => BindPattern, _}
    import Matching._

    type Env = Set[(Symbol, Symbol)]

    inline def withEnv[T](env: Env)(body: => given Env => T): T = body given env

    /** Check that all trees match with =#= and concatenate the results with && */
    def (scrutinees: List[Tree]) =##= (patterns: List[Tree]) given Env: Matching = {
      def rec(l1: List[Tree], l2: List[Tree]): Matching = (l1, l2) match {
        case (x :: xs, y :: ys) => x =#= y && rec(xs, ys)
        case (Nil, Nil) => matched
        case _ => notMatched
      }
      rec(scrutinees, patterns)
    }

    /** Check that the trees match and return the contents from the pattern holes.
     *  Return None if the trees do not match otherwise return Some of a tuple containing all the contents in the holes.
     *
     * @param scrutinee The tree beeing matched
     * @param pattern The pattern tree that the scrutinee should match. Contains `patternHole` holes.
     * @param `the[Env]` Set of tuples containing pairs of symbols (s, p) where s defines a symbol in `scrutinee` which corresponds to symbol p in `pattern`.
     * @return `None` if it did not match or `Some(tup: Tuple)` if it matched where `tup` contains the contents of the holes.
     */
    def (scrutinee: Tree) =#= (pattern: Tree) given Env: Matching = {

{'fraction_non_alphanumeric': 0.12609238451935081, 'fraction_numerical': 0.0035669698591046907, 'mean_word_length': 3.06966618287373, 'pattern_counts': {'":': 0, '<': 9, '<?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': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3828260', 'n_tokens_mistral': 1790, 'n_tokens_neox': 1745, 'n_words': 638}