<commit_before>package org.jetbrains.plugins.scala.lang.psi

import _root_.scala.collection.mutable.ArrayBuffer
import impl.ScalaPsiElementFactory
import api.toplevel.imports.{ScImportExpr, ScImportStmt}
import api.toplevel.packaging.{ScPackageStatement, ScPackaging}
import api.toplevel.typedef.ScTypeDefinition
import com.intellij.psi._
import scope._

trait ScImportsHolder extends ScalaPsiElement {
  override def processDeclarations(processor: PsiScopeProcessor,
      state : ResolveState,
      lastParent: PsiElement,
      place: PsiElement): Boolean = {
    import org.jetbrains.plugins.scala.lang.resolve._

    if (lastParent != null) {
      var run = lastParent.getPrevSibling
      while (run != null) {
        if (run.isInstanceOf[ScImportStmt] &&
            !run.processDeclarations(processor, state, lastParent, place)) return false
        run = run.getPrevSibling
      }
    }
    true
  }

  //todo[Sasha] rewrite using ScalaElementTypes
  def deleteImportStmt(stmt: ScImportStmt): Unit = {
    val remove = getNode.removeChild _
    val node = stmt.getNode
    val next = node.getTreeNext
    if (next == null) {
      remove(node)
    }
    else if (next.getText.indexOf("\n") != -1) {
      remove(next)
      remove(node)
    } else if (next.getText.charAt(0) == ';') {
      val nextnext = next.getTreeNext
      if (nextnext == null) {
        remove(next)
        remove(node)
      }
      else if (next.getText.indexOf("\n") != -1) {
        remove(nextnext)
        remove(next)
        remove(node)
      } else {
        remove(node)
        remove(next)
      }
    }
    else {
      remove(node)
    }
  }

  private def importStatementsInHeader: Seq[ScImportStmt] = {
    var end = false
    val buf = new ArrayBuffer[ScImportStmt]
    for (child <- getChildren if !end) {
      child match {
        case x: ScImportStmt => buf += x
        case _: ScTypeDefinition | _: ScPackaging => end = true
        case _ =>
      }
    }
    return buf.toSeq
  }

  def addImportForClass(clazz: PsiClass) {
    val newImport = ScalaPsiElementFactory.createImportStatementFromClass(this, clazz, this.getManager)
    val resolve = ScalaPsiElementFactory.getResolveForClassQualifier(this, clazz, getManager)
    val sameExpressions: Array[ScImportExpr] = (for (importStmt <- importStatementsInHeader; importExpr <- importStmt.importExprs
      if resolve != null && importExpr.qualifier.resolve == resolve)
      yield importExpr).toArray
    val importSt = if (sameExpressions.length == 0) newImport
                   else {
                     val stmt = ScalaPsiElementFactory.createBigImportStmt(newImport.importExprs(0), sameExpressions, this.getManager)
                     for (expr <- sameExpressions) expr.deleteExpr
                     stmt
                   }
    def tryImport(imp: PsiElement): Boolean = {
      var prev: PsiElement = imp.getPrevSibling
      prev match {
        case null => return true
        case _: ScTypeDefinition => return false
        case _: ScPackaging => return false
        case _ => return tryImport(prev)
      }
    }
    def lessTo(left: ScImportStmt, right: ScImportStmt): Boolean = left.getText.toLowerCase < right.getText.toLowerCase
    def isLT(s: String): Boolean = s.toCharArray.filter((c: Char) => c match {case ' ' | '\n' => false case _ => true}).length == 0
    findChild(classOf[ScImportStmt]) match {
      case Some(x) if tryImport(x) => {
        var stmt: PsiElement = x
        var added = false
        while (!added && stmt != null && (stmt.isInstanceOf[ScImportStmt]) || isLT(stmt.getText) || stmt.getText == ";") {
          stmt match {
            case im: ScImportStmt => {
              if (lessTo(importSt, im)) {
                added = true
                addBefore(importSt, im)
              }
            }
            case _ =>
          }
          stmt = stmt.getNextSibling
        }<commit_msg>starting to refactor adding import logic<commit_after>package org.jetbrains.plugins.scala.lang.psi

import _root_.scala.collection.mutable.ArrayBuffer
import impl.ScalaPsiElementFactory
import api.toplevel.imports.{ScImportExpr, ScImportStmt}
import api.toplevel.packaging.{ScPackageStatement, ScPackaging}
import api.toplevel.typedef.ScTypeDefinition
import com.intellij.psi._
import scope._

trait ScImportsHolder extends ScalaPsiElement {
  override def processDeclarations(processor: PsiScopeProcessor,
      state : ResolveState,
      lastParent: PsiElement,
      place: PsiElement): Boolean = {
    import org.jetbrains.plugins.scala.lang.resolve._

    if (lastParent != null) {
      var run = lastParent.getPrevSibling
      while (run != null) {
        if (run.isInstanceOf[ScImportStmt] &&
            !run.processDeclarations(processor, state, lastParent, place)) return false
        run = run.getPrevSibling
      }
    }
    true
  }

  //todo[Sasha] rewrite using ScalaElementTypes
  def deleteImportStmt(stmt: ScImportStmt): Unit = {
    val remove = getNode.removeChild _
    val node = stmt.getNode
    val next = node.getTreeNext
    if (next == null) {
      remove(node)
    }
    else if (next.getText.indexOf("\n") != -1) {
      remove(next)
      remove(node)
    } else if (next.getText.charAt(0) == ';') {
      val nextnext = next.getTreeNext
      if (nextnext == null) {
        remove(next)
        remove(node)
      }
      else if (next.getText.indexOf("\n") != -1) {
        remove(nextnext)
        remove(next)
        remove(node)
      } else {
        remove(node)
        remove(next)
      }
    }
    else {
      remove(node)
    }
  }

  private def importStatementsInHeader: Seq[ScImportStmt] = {
    var end = false
    val buf = new ArrayBuffer[ScImportStmt]
    for (child <- getChildren if !end) {
      child match {
        case x: ScImportStmt => buf += x
        case _: ScTypeDefinition | _: ScPackaging => end = true
        case _ =>
      }
    }
    return buf.toSeq
  }

  def addImportForClass(clazz: PsiClass) {
    //Create simple variant what to import
    val importSt = ScalaPsiElementFactory.createImportStatementFromClass(this, clazz, this.getManager)
    //Getting qualifier resolve, to compare with other import expressions
    val resolve = ScalaPsiElementFactory.getResolveForClassQualifier(this, clazz, getManager)
    this match {
      //If we have not Block we tring to collect same qualifiers to one import expression
      case _: ScalaFile | _: ScPackaging => {
        //looking for expresssions which collecting
        val sameExpressions: Array[ScImportExpr] = (for (importStmt <- importStatementsInHeader; importExpr <- importStmt.importExprs
          if resolve != null && importExpr.qualifier.resolve == resolve)
          yield importExpr).toArray
        if (sameExpressions.length != 0) {
          //getting collected import statement
          val stmt = ScalaPsiElementFactory.createBigImportStmt(importSt.importExprs(0), sameExpressions, this.getManager)
          //deleting collected expressions
          for (expr <- sameExpressions) expr.deleteExpr
          importSt = stmt
        }
      }
      case _ =>
    }
    def tryImport(imp: PsiElement): Boolean = {
      var prev: PsiElement = imp.getPrevSibling
      prev match {
        case null => return true
        case _: ScTypeDefinition => return false
        case _: ScPackaging => return false
        case _ => return tryImport(prev)
      }
    }
    def lessTo(left: ScImportStmt, right: ScImportStmt): Boolean = left.getText.toLowerCase < right.getText.toLowerCase
    def isLT(s: String): Boolean = s.toCharArray.filter((c: Char) => c match {case ' ' | '\n' => false case _ => true}).length == 0
    findChild(classOf[ScImportStmt]) match {
      case Some(x) if tryImport(x) => {
        var stmt: PsiElement = x
        var added = false
        while (!added && stmt != null && (stmt.isInstanceOf[ScImportStmt]) || isLT(stmt.getText) || stmt.getText == ";") {
          stmt match {
            case im: ScImportStmt => {
              if (lessTo(importSt, im)) {
                added = true
                addBefore(importSt, im)
              }
            }
            case _ =>
          }
          stmt = stmt.getNextSibling
        }
{'fraction_non_alphanumeric': 0.10181022961973028, 'fraction_numerical': 0.0014579030494472117, 'mean_word_length': 2.458823529411765, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 31, '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': '6126191', 'n_tokens_mistral': 2437, 'n_tokens_neox': 2436, 'n_words': 576}