<commit_before>package dotty.tools.dotc.transform

import dotty.tools.dotc.ast.tpd
import dotty.tools.dotc.core.Contexts.Context
import dotty.tools.dotc.core.Flags
import dotty.tools.dotc.core.Types.{NoType, Type, AndType}
import dotty.tools.dotc.transform.TreeTransforms._
import tpd._

import scala.collection.mutable.ListBuffer


/**
 * This transform makes sure that all private member selections from
 * AndTypes are performed from the first component of AndType.
 * This is needed for correctness of erasure. See `tests/run/PrivateAnd.scala`
 */
class CrossCastAnd extends MiniPhaseTransform { thisTransform =>

  override def phaseName: String = "crossCast"

  override def transformSelect(tree: tpd.Select)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
    if (tree.symbol.is(Flags.Private)) {
      // all private member selections have a symbol
      tree.qualifier.tpe.widen match {
        case t @ AndType(l, _) =>

        // find a component of and type that owns the symbol
        def findType(tp: Type): Type = {
            tp match {
              case AndType(l, r) =>
                findType(l).orElse(findType(r))
              case t =>
                if (t.decl(tree.symbol.name).suchThat(_ == tree.symbol).exists)
                  t
                else NoType
            }
          }

          val tp = findType(t)
          if (l eq tp) tree
          else tree.qualifier.asInstance(AndType(tp, tree.qualifier.tpe)).select(tree.symbol)
        case _ => tree
      }
    }
      else tree
  }
}<commit_msg>CrossCastAnd: reimplement it in more compact way.<commit_after>package dotty.tools.dotc.transform

import dotty.tools.dotc.ast.tpd
import dotty.tools.dotc.core.Contexts.Context
import dotty.tools.dotc.core.Flags
import dotty.tools.dotc.core.Types.{NoType, Type, AndType}
import dotty.tools.dotc.transform.TreeTransforms._
import tpd._

import scala.collection.mutable.ListBuffer


/**
 * This transform makes sure that all private member selections from
 * AndTypes are performed from the first component of AndType.
 * This is needed for correctness of erasure. See `tests/run/PrivateAnd.scala`
 */
class CrossCastAnd extends MiniPhaseTransform { thisTransform =>

  override def phaseName: String = "crossCast"

  override def transformSelect(tree: tpd.Select)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {

    lazy val qtype = tree.qualifier.tpe.widen
    val sym = tree.symbol
    if (sym.is(Flags.Private) && qtype.typeSymbol != sym.owner)
      cpy.Select(tree)(tree.qualifier.asInstance(AndType(qtype.baseTypeWithArgs(sym.owner), tree.qualifier.tpe)), tree.name)
    else tree
  }
}
{'fraction_non_alphanumeric': 0.10120391271632806, 'fraction_numerical': 0.0, 'mean_word_length': 3.0719754977029097, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, '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': '1454596', 'n_tokens_mistral': 813, 'n_tokens_neox': 795, 'n_words': 209}