<commit_before>package org.jetbrains.plugins.scala
package overrideImplement

import com.intellij.codeInsight.generation.{GenerateMembersUtil, ClassMember => JClassMember}
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi._
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.plugins.scala.ScalaBundle
import org.jetbrains.plugins.scala.extensions._
import org.jetbrains.plugins.scala.lang.psi.api.base.Constructor
import org.jetbrains.plugins.scala.lang.psi.api.statements._
import org.jetbrains.plugins.scala.lang.psi.api.statements.params.ScClassParameter
import org.jetbrains.plugins.scala.lang.psi.api.toplevel.ScTypedDefinition
import org.jetbrains.plugins.scala.lang.psi.api.toplevel.templates.ScTemplateBody
import org.jetbrains.plugins.scala.lang.psi.api.toplevel.typedef.{ScMember, ScTemplateDefinition, ScTrait, ScTypeDefinition}
import org.jetbrains.plugins.scala.lang.psi.impl.ScalaPsiElementFactory.createOverrideImplementVariableWithClass
import org.jetbrains.plugins.scala.lang.psi.impl.toplevel.typedef.TypeDefinitionMembers._
import org.jetbrains.plugins.scala.lang.psi.types._
import org.jetbrains.plugins.scala.lang.resolve.ResolveUtils
import org.jetbrains.plugins.scala.project.ProjectContext
import org.jetbrains.plugins.scala.statistics.{FeatureKey, Stats}

import scala.collection.mutable
import scala.jdk.CollectionConverters._

/**
 * User: <NAME>
 * Date: 08.07.2008
 */

object ScalaOIUtil {

  private[this] def toClassMember(signature: Signature, isOverride: Boolean): Option[ClassMember] = {
    val Signature(named, substitutor) = signature
    val maybeContext = Option(named.nameContext)

    def createMember(parameter: ScClassParameter): ScValue = {
      implicit val projectContext: ProjectContext = parameter.projectContext

      createOverrideImplementVariableWithClass(
        variable = parameter,
        substitutor = substitutor,
        needsOverrideModifier = true,
        isVal = true,
        clazz = parameter.containingClass
      ).asInstanceOf[ScValue]
    }

    named match {
      case typedDefinition: ScTypedDefinition =>
        maybeContext.collect {
          case x: ScValue => new ScValueMember(x, typedDefinition, substitutor, isOverride)
          case x: ScVariable => new ScVariableMember(x, typedDefinition, substitutor, isOverride)
          case x: ScClassParameter if x.isVal => new ScValueMember(createMember(x), typedDefinition, substitutor, isOverride)
        }
      case _ =>
        maybeContext.collect {
          case x: ScTypeAlias if x.containingClass != null => ScAliasMember(x, substitutor, isOverride)
          case x: PsiField => JavaFieldMember(x, substitutor)
        }
    }
  }

  def invokeOverrideImplement(file: PsiFile, isImplement: Boolean,
                              methodName: String = null)
                             (implicit project: Project, editor: Editor): Unit = {

    Stats.trigger(FeatureKey.overrideImplement)

    val clazz = file.findElementAt(editor.getCaretModel.getOffset - 1)
      .parentOfType(classOf[ScTemplateDefinition], strict = false)
      .getOrElse(return)

    val classMembers =
      if (isImplement) getMembersToImplement(clazz, withSelfType = true)
      else getMembersToOverride(clazz)
    if (classMembers.isEmpty) return

    val selectedMembers = mutable.ListBuffer[ClassMember]()
    if (!ApplicationManager.getApplication.isUnitTestMode) {

      val chooser = new ScalaMemberChooser[ClassMember](classMembers.toArray, false, true, isImplement, true, true, clazz)
      chooser.setTitle(if (isImplement) ScalaBundle.message("select.method.implement") else ScalaBundle.message("select.method.override"))
      if (isImplement) chooser.selectElements(classMembers.toArray[JClassMember])
      chooser.show()

      val elements = chooser.getSelectedElements
      if (elements != null) selectedMembers ++= elements.asScala
      if (selectedMembers.isEmpty) return
    } else {
      selectedMembers ++= classMembers.find {
        case named: ScalaNamedMember if named.name == methodName => true
        case _ => false
      }.toSeq
    }

    runAction(selectedMembers, isImplement, clazz)
  }


  def runAction(selectedMembers: collection.Seq[ClassMember],
                isImplement: Boolean,
                clazz: ScTemplateDefinition)
               (implicit project: Project, editor: Editor): Unit =
    executeWriteActionCommand(if (isImplement) ScalaBundle.message("action.implement.method") else ScalaBundle.message("action.override.method")) {
      val sortedMembers = ScalaMemberChooser.sorted(selectedMembers, clazz)
      val genInfos = sortedMembers.map(new ScalaGenerationInfo(_))
      val anchor = getAnchor(editor.getCaretModel.getOffset, clazz)

      val inserted = GenerateMembersUtil.insertMembersBeforeAnchor(clazz, anchor.orNull, genInfos.reverse.asJava).asScala
      inserted.lastOption.foreach(_.positionCaret(editor, toEditMethodBody = true))
    }

  def getMembersToImplement(clazz: ScTemplateDefinition, withOwn: Boolean = false, withSelfType: Boolean = false): collection.Seq[ClassMember] =
    classMembersWithFilter(clazz, withSelfType, isOverride = false)(needImplement(_, clazz, withOwn), needImplement(_, clazz, withOwn))

  def getAllMembersToOverride(clazz: ScTemplateDefinition): collection.Seq[ClassMember] =
    classMembersWithFilter(clazz, withSelfType = true)(Function.const(true), Function.const(true))

  def getMembersToOverride(clazz: ScTemplateDefinition): collection.Seq[ClassMember] =
    classMembersWithFilter(clazz, withSelfType = true)(needOverride(_, clazz), needOverride(_, clazz))

  private[this] def classMembersWithFilter(definition: ScTemplateDefinition,
                                           withSelfType: Boolean,
                                           isOverride: Boolean = true)
                                          (f1: PhysicalMethodSignature => Boolean,
                                           f2: PsiNamedElement => Boolean): collection.Seq[ClassMember] = {
    val maybeThisType = if (withSelfType)
      for {
        selfType <- definition.selfType
        clazzType = definition.getTypeWithProjections().getOrAny

        glb = selfType.glb(clazzType)
        if glb.isInstanceOf[ScCompoundType]
      } yield (glb.asInstanceOf[ScCompoundType], Some(clazzType))
    else
      None

    val types = maybeThisType.fold(getTypes(definition)) {
      case (compoundType, compoundTypeThisType) => getTypes(compoundType, compoundTypeThisType)
    }.allSignatures

    val signatures = maybeThisType.fold(getSignatures(definition)) {
      case (compoundType, compoundTypeThisType) => getSignatures(compoundType, compoundTypeThisType)
    }

    val methods = signatures.allSignatures.filter {
      case signature: PhysicalMethodSignature if signature.namedElement.isValid => f1(signature)
      case _ => false
    }.map {
      case signature: PhysicalMethodSignature =>
        val method = signature.method
        assert(method.containingClass != null, s"Containing Class is null: ${method.getText}")
        ScMethodMember(signature, isOverride)
    }<commit_msg>Fix for scala 3 migration<commit_after>package org.jetbrains.plugins.scala
package overrideImplement

import com.intellij.codeInsight.generation.{GenerateMembersUtil, ClassMember => JClassMember}
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi._
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.plugins.scala.ScalaBundle
import org.jetbrains.plugins.scala.extensions._
import org.jetbrains.plugins.scala.lang.psi.api.base.Constructor
import org.jetbrains.plugins.scala.lang.psi.api.statements._
import org.jetbrains.plugins.scala.lang.psi.api.statements.params.ScClassParameter
import org.jetbrains.plugins.scala.lang.psi.api.toplevel.ScTypedDefinition
import org.jetbrains.plugins.scala.lang.psi.api.toplevel.templates.ScTemplateBody
import org.jetbrains.plugins.scala.lang.psi.api.toplevel.typedef.{ScMember, ScTemplateDefinition, ScTrait, ScTypeDefinition}
import org.jetbrains.plugins.scala.lang.psi.impl.ScalaPsiElementFactory.createOverrideImplementVariableWithClass
import org.jetbrains.plugins.scala.lang.psi.impl.toplevel.typedef.TypeDefinitionMembers._
import org.jetbrains.plugins.scala.lang.psi.types._
import org.jetbrains.plugins.scala.lang.resolve.ResolveUtils
import org.jetbrains.plugins.scala.project.ProjectContext
import org.jetbrains.plugins.scala.statistics.{FeatureKey, Stats}

import scala.collection.mutable
import scala.jdk.CollectionConverters._

/**
 * User: <NAME>
 * Date: 08.07.2008
 */

object ScalaOIUtil {

  private[this] def toClassMember(signature: Signature, isOverride: Boolean): Option[ClassMember] = {
    val Signature(named, substitutor) = signature
    val maybeContext = Option(named.nameContext)

    def createMember(parameter: ScClassParameter): ScValue = {
      implicit val projectContext: ProjectContext = parameter.projectContext

      createOverrideImplementVariableWithClass(
        variable = parameter,
        substitutor = substitutor,
        needsOverrideModifier = true,
        isVal = true,
        clazz = parameter.containingClass
      ).asInstanceOf[ScValue]
    }

    named match {
      case typedDefinition: ScTypedDefinition =>
        maybeContext.collect {
          case x: ScValue => new ScValueMember(x, typedDefinition, substitutor, isOverride)
          case x: ScVariable => new ScVariableMember(x, typedDefinition, substitutor, isOverride)
          case x: ScClassParameter if x.isVal => new ScValueMember(createMember(x), typedDefinition, substitutor, isOverride)
        }
      case _ =>
        maybeContext.collect {
          case x: ScTypeAlias if x.containingClass != null => ScAliasMember(x, substitutor, isOverride)
          case x: PsiField => JavaFieldMember(x, substitutor)
        }
    }
  }

  def invokeOverrideImplement(file: PsiFile, isImplement: Boolean,
                              methodName: String = null)
                             (implicit project: Project, editor: Editor): Unit = {

    Stats.trigger(FeatureKey.overrideImplement)

    val clazz = file.findElementAt(editor.getCaretModel.getOffset - 1)
      .parentOfType(classOf[ScTemplateDefinition], strict = false)
      .getOrElse(return)

    val classMembers =
      if (isImplement) getMembersToImplement(clazz, withSelfType = true)
      else getMembersToOverride(clazz)
    if (classMembers.isEmpty) return

    val selectedMembers = mutable.ListBuffer[ClassMember]()
    if (!ApplicationManager.getApplication.isUnitTestMode) {

      val chooser = new ScalaMemberChooser[ClassMember](classMembers.toArray, false, true, isImplement, true, true, clazz)
      chooser.setTitle(if (isImplement) ScalaBundle.message("select.method.implement") else ScalaBundle.message("select.method.override"))
      if (isImplement) chooser.selectElements(classMembers.toArray[JClassMember])
      chooser.show()

      val elements = chooser.getSelectedElements
      if (elements != null) selectedMembers ++= elements.asScala
      if (selectedMembers.isEmpty) return
    } else {
      selectedMembers ++= classMembers.find {
        case named: ScalaNamedMember if named.name == methodName => true
        case _ => false
      }.toSeq
    }

    runAction(selectedMembers, isImplement, clazz)
  }


  def runAction(selectedMembers: collection.Seq[ClassMember],
                isImplement: Boolean,
                clazz: ScTemplateDefinition)
               (implicit project: Project, editor: Editor): Unit =
    executeWriteActionCommand(if (isImplement) ScalaBundle.message("action.implement.method") else ScalaBundle.message("action.override.method")) {
      val sortedMembers = ScalaMemberChooser.sorted(selectedMembers, clazz)
      val genInfos = sortedMembers.map(new ScalaGenerationInfo(_))
      val anchor = getAnchor(editor.getCaretModel.getOffset, clazz)

      val inserted = GenerateMembersUtil.insertMembersBeforeAnchor(clazz, anchor.orNull, genInfos.reverse.asJava).asScala
      inserted.lastOption.foreach(_.positionCaret(editor, toEditMethodBody = true))
    }

  def getMembersToImplement(clazz: ScTemplateDefinition, withOwn: Boolean = false, withSelfType: Boolean = false): Seq[ClassMember] =
    classMembersWithFilter(clazz, withSelfType, isOverride = false)(needImplement(_, clazz, withOwn), needImplement(_, clazz, withOwn))

  def getAllMembersToOverride(clazz: ScTemplateDefinition): Seq[ClassMember] =
    classMembersWithFilter(clazz, withSelfType = true)(Function.const(true), Function.const(true))

  def getMembersToOverride(clazz: ScTemplateDefinition): Seq[ClassMember] =
    classMembersWithFilter(clazz, withSelfType = true)(needOverride(_, clazz), needOverride(_, clazz))

  private[this] def classMembersWithFilter(definition: ScTemplateDefinition,
                                           withSelfType: Boolean,
                                           isOverride: Boolean = true)
                                          (f1: PhysicalMethodSignature => Boolean,
                                           f2: PsiNamedElement => Boolean): Seq[ClassMember] = {
    val maybeThisType = if (withSelfType)
      for {
        selfType <- definition.selfType
        clazzType = definition.getTypeWithProjections().getOrAny

        glb = selfType.glb(clazzType)
        if glb.isInstanceOf[ScCompoundType]
      } yield (glb.asInstanceOf[ScCompoundType], Some(clazzType))
    else
      None

    val types = maybeThisType.fold(getTypes(definition)) {
      case (compoundType, compoundTypeThisType) => getTypes(compoundType, compoundTypeThisType)
    }.allSignatures

    val signatures = maybeThisType.fold(getSignatures(definition)) {
      case (compoundType, compoundTypeThisType) => getSignatures(compoundType, compoundTypeThisType)
    }

    val methods = signatures.allSignatures.filter {
      case signature: PhysicalMethodSignature if signature.namedElement.isValid => f1(signature)
      case _ => false
    }.map {
      case signature: PhysicalMethodSignature =>
        val method = signature.method
        assert(method.containingClass != null, s"Containing Class is null: ${method.getText}")
        ScMethodMember(signature, isOverride)
    }
{'fraction_non_alphanumeric': 0.09275924131247404, 'fraction_numerical': 0.0017305828603073514, 'mean_word_length': 3.747617482747289, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2281010', 'n_tokens_mistral': 4049, 'n_tokens_neox': 3924, 'n_words': 768}