<commit_before>package ch.usi.inf.l3.sana.primj.namers

import ch.usi.inf.l3.sana
import sana.primj
import sana.tiny
import sana.calcj

import sana.core.TransformationComponent
import sana.dsl._
import tiny.ast._
import tiny.errors.ErrorReporting.{error,warning}
import tiny.symbols._
import calcj.ast._
import calcj.ast.operators.{Inc, Dec}
import primj.ast._
import primj.ast.TreeUtils
import primj.symbols._
import primj.modifiers.Ops._
import primj.errors.ErrorCodes._


// package symbolassigners {
//   import scala.language.implicitConversions
//   object Implicits {
//     // We need this to glue compilation phases together easier
//     implicit def tree2TreeOptionSymbolTuple(tree: Tree):
//       (Tree, Option[Symbol]) = (tree, None)
//   }
// }


/*
Program: DONE
Assign: DONE
If: DONE
While: DONE
Block: DONE
For: DONE
Ternary: DONE
Apply: DONE
Return: DONE
MethodDef: DONE
ValDef: DONE
Ident: DONE
NoTree: DONE
TypeUse: DONE
Cast: DONE
Binary: DONE
Literal: DONE
Unary: DONE
*/

trait SymbolAssignerComponent extends
  TransformationComponent[(Tree, Option[Symbol]), Tree] {
  def assign: ((Tree, Option[Symbol])) => Tree
}

trait ProgramSymbolAssignerComponent extends SymbolAssignerComponent {

  def apply(p: (Tree, Option[Symbol])): Tree = {
    val (tree, owner) = p
    tree match {
      case program: Program          =>
        val symbol = Some(ProgramSymbol)
        val newMembers =
          program.members.map(x => assign((x, symbol)).asInstanceOf[DefTree])
        program.copy(members = newMembers, symbol = symbol)
    }
  }

  def isDefinedAt(p: (Tree, Option[Symbol])): Boolean = p match {
    case (_: Program, _) => true
    case _               => false
  }
}


trait MethodDefSymbolAssignerComponent extends SymbolAssignerComponent {
  def apply(p: (Tree, Option[Symbol])): Tree = {
    val (tree, owner) = p
    tree match {
      case mthd: MethodDef          =>
        val symbol  = MethodSymbol(noflags, mthd.name,
          Nil, None, owner)
        val opsym   = Some(symbol)
        val tpt     = assign((mthd.ret, opsym)).asInstanceOf[UseTree]
        val params  = mthd.params.map((x) =>
            assign((x, opsym)).asInstanceOf[ValDef])
        val body    = assign((mthd.body, opsym)).asInstanceOf[Expr]
        symbol.params = params.map(_.symbol).flatten

        owner.foreach(sym => sym.declare(symbol))

        mthd.copy(ret = tpt, params = params, body = body, symbol = opsym)
    }
  }

  def isDefinedAt(p: (Tree, Option[Symbol])): Boolean = p match {
    case (_: MethodDef, _) => true
    case _                 => false
  }
}


trait ValDefSymbolAssignerComponent extends SymbolAssignerComponent {
  def apply(p: (Tree, Option[Symbol])): Tree = {
    val (tree, owner) = p
    tree match {
      case valdef: ValDef          =>
        val symbol  = VariableSymbol(valdef.mods, valdef.name,
          None, owner)
        val opsym   = Some(symbol)
        val tpt     = assign((valdef.tpt, opsym)).asInstanceOf[UseTree]
        val rhs     = assign((valdef.rhs, opsym)).asInstanceOf[Expr]

        owner.foreach(sym => sym.declare(symbol))
        valdef.copy(tpt = tpt, rhs = rhs, symbol = opsym)
    }
  }

  def isDefinedAt(p: (Tree, Option[Symbol])): Boolean = p match {
    case (_: ValDef, _) => true
    case _              => false
  }
}


trait TypeUseSymbolAssignerComponent extends SymbolAssignerComponent {
  def apply(p: (Tree, Option[Symbol])): Tree = {
    val (tree, owner) = p
    tree match {
      case tuse: TypeUse          =>
        val symbol = owner.flatMap(_.getSymbol(tuse.name,
          _.isInstanceOf[TypeSymbol]))
        symbol match {
          case Some(sym)      => TypeUse(sym, tuse.pos)
          case _              => tuse
        }
    }
  }

  def isDefinedAt(p: (Tree, Option[Symbol])): Boolean = p match {
    case (_: TypeUse, _) => true
    case _               => false
  }
}

trait ForSymbolAssignerComponent extends SymbolAssignerComponent {
  def apply(p: (Tree, Option[Symbol])): Tree = {
    val (tree, owner) = p
    tree match {
      case forloop: For          =>
        val symbol  = Some(ScopeSymbol(owner))
        val inits = forloop.inits.map { init =>
          assign((init, symbol))
        }
        val cond = assign((forloop.cond, symbol)).asInstanceOf[Expr]
        val steps = forloop.steps.map { step =>
          assign((step, symbol)).asInstanceOf[Expr]
        }
        val body = assign((forloop.body, symbol)).asInstanceOf[Expr]
        forloop.copy(inits = inits, cond = cond, steps = steps,
          body = body, owner = owner, symbol = symbol)
    }
  }

  def isDefinedAt(p: (Tree, Option[Symbol])): Boolean = p match {
    case (_: For, _)     => true
    case _               => false
  }
}

trait BlockSymbolAssignerComponent extends SymbolAssignerComponent {
  def apply(p: (Tree, Option[Symbol])): Tree = {
    val (tree, owner) = p
    tree match {
      case block: Block          =>
        val symbol  = Some(ScopeSymbol(owner))
        val stmts = block.stmts.map { stmt =>
          assign((stmt, symbol))
        }
        block.copy(stmts = stmts, owner = owner, symbol = symbol)
    }
  }

  def isDefinedAt(p: (Tree, Option[Symbol])): Boolean = p match {
    case (_: Block, _)   => true
    case _               => false
  }
}
// Boring cases, just pass the owner around and assign it to
// all the trees that can have an owner
trait IdentSymbolAssignerComponent extends SymbolAssignerComponent {
  def apply(p: (Tree, Option[Symbol])): Tree = {
    val (tree, owner) = p
    tree match {
      case id: Ident          =>
        Ident(id.symbol, id.pos, owner)
    }
  }

  def isDefinedAt(p: (Tree, Option[Symbol])): Boolean = p match {
    case (_: Ident, _)   => true
    case _               => false
  }
}

trait BinarySymbolAssignerComponent extends SymbolAssignerComponent {
  def apply(p: (Tree, Option[Symbol])): Tree = {
    val (tree, owner) = p
    tree match {
      case bin: Binary          =>
        val lhs = assign((bin.lhs, owner)).asInstanceOf[Expr]
        val rhs = assign((bin.rhs, owner)).asInstanceOf[Expr]
        bin.copy(lhs = lhs, rhs = rhs, owner = owner)
    }
  }

  def isDefinedAt(p: (Tree, Option[Symbol])): Boolean = p match {
    case (_: Binary, _)  => true
    case _               => false
  }
}<commit_msg>Use name for new Idents not symbol at this stage<commit_after>package ch.usi.inf.l3.sana.primj.namers

import ch.usi.inf.l3.sana
import sana.primj
import sana.tiny
import sana.calcj

import sana.core.TransformationComponent
import sana.dsl._
import tiny.ast._
import tiny.errors.ErrorReporting.{error,warning}
import tiny.symbols._
import calcj.ast._
import calcj.ast.operators.{Inc, Dec}
import primj.ast._
import primj.ast.TreeUtils
import primj.symbols._
import primj.modifiers.Ops._
import primj.errors.ErrorCodes._


// package symbolassigners {
//   import scala.language.implicitConversions
//   object Implicits {
//     // We need this to glue compilation phases together easier
//     implicit def tree2TreeOptionSymbolTuple(tree: Tree):
//       (Tree, Option[Symbol]) = (tree, None)
//   }
// }


/*
Program: DONE
Assign: DONE
If: DONE
While: DONE
Block: DONE
For: DONE
Ternary: DONE
Apply: DONE
Return: DONE
MethodDef: DONE
ValDef: DONE
Ident: DONE
NoTree: DONE
TypeUse: DONE
Cast: DONE
Binary: DONE
Literal: DONE
Unary: DONE
*/

trait SymbolAssignerComponent extends
  TransformationComponent[(Tree, Option[Symbol]), Tree] {
  def assign: ((Tree, Option[Symbol])) => Tree
}

trait ProgramSymbolAssignerComponent extends SymbolAssignerComponent {

  def apply(p: (Tree, Option[Symbol])): Tree = {
    val (tree, owner) = p
    tree match {
      case program: Program          =>
        val symbol = Some(ProgramSymbol)
        val newMembers =
          program.members.map(x => assign((x, symbol)).asInstanceOf[DefTree])
        program.copy(members = newMembers, symbol = symbol)
    }
  }

  def isDefinedAt(p: (Tree, Option[Symbol])): Boolean = p match {
    case (_: Program, _) => true
    case _               => false
  }
}


trait MethodDefSymbolAssignerComponent extends SymbolAssignerComponent {
  def apply(p: (Tree, Option[Symbol])): Tree = {
    val (tree, owner) = p
    tree match {
      case mthd: MethodDef          =>
        val symbol  = MethodSymbol(noflags, mthd.name,
          Nil, None, owner)
        owner.foreach(sym => sym.declare(symbol))
        val opsym   = Some(symbol)
        val tpt     = assign((mthd.ret, opsym)).asInstanceOf[UseTree]
        val params  = mthd.params.map((x) =>
            assign((x, opsym)).asInstanceOf[ValDef])
        val body    = assign((mthd.body, opsym)).asInstanceOf[Expr]
        symbol.params = params.map(_.symbol).flatten

        mthd.copy(ret = tpt, params = params, body = body, symbol = opsym)
    }
  }

  def isDefinedAt(p: (Tree, Option[Symbol])): Boolean = p match {
    case (_: MethodDef, _) => true
    case _                 => false
  }
}


trait ValDefSymbolAssignerComponent extends SymbolAssignerComponent {
  def apply(p: (Tree, Option[Symbol])): Tree = {
    val (tree, owner) = p
    tree match {
      case valdef: ValDef          =>
        val symbol  = VariableSymbol(valdef.mods, valdef.name,
          None, owner)
        owner.foreach(sym => sym.declare(symbol))
        val opsym   = Some(symbol)
        val tpt     = assign((valdef.tpt, opsym)).asInstanceOf[UseTree]
        val rhs     = assign((valdef.rhs, opsym)).asInstanceOf[Expr]

        valdef.copy(tpt = tpt, rhs = rhs, symbol = opsym)
    }
  }

  def isDefinedAt(p: (Tree, Option[Symbol])): Boolean = p match {
    case (_: ValDef, _) => true
    case _              => false
  }
}


trait TypeUseSymbolAssignerComponent extends SymbolAssignerComponent {
  def apply(p: (Tree, Option[Symbol])): Tree = {
    val (tree, owner) = p
    tree match {
      case tuse: TypeUse          =>
        val symbol = owner.flatMap(_.getSymbol(tuse.name,
          _.isInstanceOf[TypeSymbol]))
        symbol match {
          case Some(sym)      => TypeUse(sym, tuse.pos)
          case _              => tuse
        }
    }
  }

  def isDefinedAt(p: (Tree, Option[Symbol])): Boolean = p match {
    case (_: TypeUse, _) => true
    case _               => false
  }
}

trait ForSymbolAssignerComponent extends SymbolAssignerComponent {
  def apply(p: (Tree, Option[Symbol])): Tree = {
    val (tree, owner) = p
    tree match {
      case forloop: For          =>
        val symbol  = Some(ScopeSymbol(owner))
        val inits = forloop.inits.map { init =>
          assign((init, symbol))
        }
        val cond = assign((forloop.cond, symbol)).asInstanceOf[Expr]
        val steps = forloop.steps.map { step =>
          assign((step, symbol)).asInstanceOf[Expr]
        }
        val body = assign((forloop.body, symbol)).asInstanceOf[Expr]
        forloop.copy(inits = inits, cond = cond, steps = steps,
          body = body, owner = owner, symbol = symbol)
    }
  }

  def isDefinedAt(p: (Tree, Option[Symbol])): Boolean = p match {
    case (_: For, _)     => true
    case _               => false
  }
}

trait BlockSymbolAssignerComponent extends SymbolAssignerComponent {
  def apply(p: (Tree, Option[Symbol])): Tree = {
    val (tree, owner) = p
    tree match {
      case block: Block          =>
        val symbol  = Some(ScopeSymbol(owner))
        val stmts = block.stmts.map { stmt =>
          assign((stmt, symbol))
        }
        block.copy(stmts = stmts, owner = owner, symbol = symbol)
    }
  }

  def isDefinedAt(p: (Tree, Option[Symbol])): Boolean = p match {
    case (_: Block, _)   => true
    case _               => false
  }
}
// Boring cases, just pass the owner around and assign it to
// all the trees that can have an owner
trait IdentSymbolAssignerComponent extends SymbolAssignerComponent {
  def apply(p: (Tree, Option[Symbol])): Tree = {
    val (tree, owner) = p
    tree match {
      case id: Ident          =>
        Ident(id.name, id.pos, owner)
    }
  }

  def isDefinedAt(p: (Tree, Option[Symbol])): Boolean = p match {
    case (_: Ident, _)   => true
    case _               => false
  }
}

trait BinarySymbolAssignerComponent extends SymbolAssignerComponent {
  def apply(p: (Tree, Option[Symbol])): Tree = {
    val (tree, owner) = p
    tree match {
      case bin: Binary          =>
        val lhs = assign((bin.lhs, owner)).asInstanceOf[Expr]
        val rhs = assign((bin.rhs, owner)).asInstanceOf[Expr]
        bin.copy(lhs = lhs, rhs = rhs, owner = owner)
    }
  }

  def isDefinedAt(p: (Tree, Option[Symbol])): Boolean = p match {
    case (_: Binary, _)  => true
    case _               => false
  }
}
{'fraction_non_alphanumeric': 0.12180094786729857, 'fraction_numerical': 0.00047393364928909954, 'mean_word_length': 2.4830811554332874, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 71, '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': '1555184', 'n_tokens_mistral': 4046, 'n_tokens_neox': 4013, 'n_words': 1039}