<commit_before>package ch.usi.inf.l3.sana.arrooj.typechecker


import ch.usi.inf.l3.sana
import sana.ooj
import sana.arrooj
import sana.arrayj
import sana.brokenj
import sana.primj
import sana.tiny
import sana.calcj

import tiny.dsl._
import tiny.ast.{UseTree, Expr, Tree, NoTree}
import tiny.types.Type
import tiny.symbols.Symbol
import tiny.errors.ErrorReporting.{error, warning}
import calcj.typechecker.TyperComponent
import arrayj.ast.{TreeUtils => _,
                   TreeCopiers => _, _}
import arrooj.ast._
import ooj.modifiers.Ops._
import primj.ast.ValDefApi
import primj.symbols.VariableSymbol
import ooj.ast.SelectApi
import arrooj.ast.Implicits._
import arrooj.ast.TreeExtractors._
import arrooj.symbols.{ArraySymbol, SymbolUtils}
import arrooj.types.{ArrayType, TypeUtils}
import arrooj.errors.ErrorCodes._

@component
trait ArrayAccessTyperComponent
  extends arrayj.typechecker.ArrayAccessTyperComponent {

  override protected def typeArrayAccess(access: ArrayAccessApi): Unit = {
    access.array.tpe.map {
      case atpe: ArrayType             =>
        access.tpe = atpe.componentType
      case _                           =>
        error(NON_ARRAY_ELEMENT_ACCESS, "", "", access.pos)
    }
    access.array.symbol.foreach {
      case sym: ArraySymbol  =>
        access.symbol = sym.componentSymbol
      case v: VariableSymbol =>
        v.typeSymbol.foreach {
          case sym: ArraySymbol  =>
            access.symbol = sym.componentSymbol
          case s                 =>
            ()
        }
      case s                 =>
        ()
    }
  }
}


@component
trait ArrayTypeUseTyperComponent
  extends TyperComponent {
  (tuse: ArrayTypeUseApi) => {
    val tpt = typed(tuse.tpt).asInstanceOf[UseTree]
    val res =
      TreeCopiers.copyArrayTypeUse(tuse)(tpt = tpt)
    tpt.tpe.foreach { tpe =>
      res.tpe = TypeUtils.mkArrayType(tpe)
    }
    tpt.symbol.foreach { sym =>
      res.symbol = SymbolUtils.mkArraySymbol(sym)
    }
    res
  }
}

@component
trait ArrayInitializerTyperComponent
  extends arrayj.typechecker.ArrayInitializerTyperComponent {

  override protected def setComponentTypesIfNeeded(
    init: ArrayInitializerApi): List[Expr]= init.elements.map { elem =>
      (init.componentType, elem) match {
        case (Some(bt), elem: ArrayInitializerApi)    =>
          bt() match {
            case ArrayType(ArrayType(t)) =>
              elem.componentType = () => t
            case _                       =>
          }
        case _                                                             =>
          ()
      }
      typed(elem).asInstanceOf[Expr]
    }


  override protected def toArrayType(tpe: Type): Type =
    TypeUtils.mkArrayType(tpe)
}

@component
trait ValDefTyperComponent extends ooj.typechecker.ValDefTyperComponent {

  protected override def typeRhs(valdef: ValDefApi): Expr = {
    if(valdef.mods.isField &&
                    (valdef.mods.isStatic || !valdef.mods.isFinal) &&
                    valdef.rhs == NoTree) {
      if(valdef.mods.isFinal)
        valdef.hasDefaultInit = true
      val dflt = getDefaultFieldValue(valdef.tpt.tpe)
      valdef.owner.foreach(dflt.owner = _)
      typed(dflt).asInstanceOf[Expr]
    } else {
      val rhs = valdef.rhs match {
        case rhs: ArrayInitializerApi =>
          getComponentType(valdef.symbol).foreach { bt =>
            rhs.componentType = bt
          }
        case _                       =>
          ()
      }
      typed(valdef.rhs).asInstanceOf[Expr]
    }
  }
  protected def getComponentType(
      symbol: Option[Symbol]): Option[() => Type] =
    symbol.flatMap(_.tpe.flatMap {
      case tpe: ArrayType        => Some(() => tpe.componentType)
      case _                     => None
    })

}

@component<commit_msg>Small tweak<commit_after>package ch.usi.inf.l3.sana.arrooj.typechecker


import ch.usi.inf.l3.sana
import sana.ooj
import sana.arrooj
import sana.arrayj
import sana.brokenj
import sana.primj
import sana.tiny
import sana.calcj

import tiny.dsl._
import tiny.ast.{UseTree, Expr, Tree, NoTree}
import tiny.types.Type
import tiny.symbols.Symbol
import tiny.errors.ErrorReporting.{error, warning}
import calcj.typechecker.TyperComponent
import arrayj.ast.{TreeUtils => _,
                   TreeCopiers => _, _}
import arrooj.ast._
import ooj.modifiers.Ops._
import primj.ast.ValDefApi
import primj.symbols.VariableSymbol
import ooj.ast.SelectApi
import arrooj.ast.Implicits._
import arrooj.ast.TreeExtractors._
import arrooj.symbols.{ArraySymbol, SymbolUtils}
import arrooj.types.{ArrayType, TypeUtils}
import arrooj.errors.ErrorCodes._

@component
trait ArrayAccessTyperComponent
  extends arrayj.typechecker.ArrayAccessTyperComponent {

  override protected def typeArrayAccess(access: ArrayAccessApi): Unit = {
    access.array.tpe.map {
      case atpe: ArrayType             =>
        access.tpe = atpe.componentType
      case _                           =>
        error(NON_ARRAY_ELEMENT_ACCESS, "", "", access.pos)
    }
    access.array.symbol.foreach {
      case sym: ArraySymbol  =>
        access.symbol = sym.componentSymbol
      case v: VariableSymbol =>
        v.typeSymbol.foreach {
          case sym: ArraySymbol  =>
            access.symbol = sym.componentSymbol
          case s                 =>
            ()
        }
      case s                 =>
        ()
    }
  }
}


@component
trait ArrayTypeUseTyperComponent
  extends TyperComponent {
  (tuse: ArrayTypeUseApi) => {
    val tpt = typed(tuse.tpt).asInstanceOf[UseTree]
    val res =
      TreeCopiers.copyArrayTypeUse(tuse)(tpt = tpt)
    tpt.tpe.foreach { tpe =>
      res.tpe = TypeUtils.mkArrayType(tpe)
    }
    tpt.symbol.foreach { sym =>
      res.symbol = SymbolUtils.mkArraySymbol(sym)
    }
    res
  }
}

@component
trait ArrayInitializerTyperComponent
  extends arrayj.typechecker.ArrayInitializerTyperComponent {

  override protected def setComponentTypesIfNeeded(
    init: ArrayInitializerApi): List[Expr]= init.elements.map { elem =>
      (init.componentType, elem) match {
        case (Some(bt), elem: ArrayInitializerApi)    =>
          bt() match {
            case ArrayType(ArrayType(t)) =>
              elem.componentType = () => t
            case _                       =>
          }
        case _                                                             =>
          ()
      }
      typed(elem).asInstanceOf[Expr]
    }


  override protected def toArrayType(tpe: Type): Type =
    TypeUtils.mkArrayType(tpe)
}

@component
trait ValDefTyperComponent extends ooj.typechecker.ValDefTyperComponent {

  protected override def typeRhs(valdef: ValDefApi): Expr = {
    if(valdef.mods.isField &&
                    (valdef.mods.isStatic || !valdef.mods.isFinal) &&
                    valdef.rhs == NoTree) {
      if(valdef.mods.isFinal)
        valdef.hasDefaultInit = true
      val dflt = getDefaultFieldValue(valdef.tpt.tpe)
      valdef.owner.foreach(dflt.owner = _)
      typed(dflt).asInstanceOf[Expr]
    } else {
      valdef.rhs match {
        case rhs: ArrayInitializerApi =>
          getComponentType(valdef.symbol).foreach { bt =>
            rhs.componentType = bt
          }
        case _                       =>
          ()
      }
      typed(valdef.rhs).asInstanceOf[Expr]
    }
  }
  protected def getComponentType(
      symbol: Option[Symbol]): Option[() => Type] =
    symbol.flatMap(_.tpe.flatMap {
      case tpe: ArrayType        => Some(() => tpe.componentType)
      case _                     => None
    })

}

@component
{'fraction_non_alphanumeric': 0.10007932310946589, 'fraction_numerical': 0.0005288207297726071, 'mean_word_length': 2.2014388489208634, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 53, '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': '520135', 'n_tokens_mistral': 2338, 'n_tokens_neox': 2328, 'n_words': 422}