<commit_before>package org.jetbrains.plugins.scala
package lang.refactoring.changeSignature

import java.util

import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Ref
import com.intellij.psi._
import com.intellij.psi.search.SearchScope
import com.intellij.psi.search.searches.{OverridingMethodsSearch, ReferencesSearch}
import com.intellij.refactoring.changeSignature.{MethodCallUsageInfo => JavaCallUsageInfo, _}
import com.intellij.refactoring.rename.ResolveSnapshotProvider
import com.intellij.refactoring.rename.ResolveSnapshotProvider.ResolveSnapshot
import com.intellij.usageView.UsageInfo
import com.intellij.util.containers.MultiMap
import org.jetbrains.plugins.scala.extensions._
import org.jetbrains.plugins.scala.lang.psi.ScalaPsiUtil
import org.jetbrains.plugins.scala.lang.psi.api.base.patterns.{ScConstructorPattern, ScInfixPattern}
import org.jetbrains.plugins.scala.lang.psi.api.base.{AuxiliaryConstructor, ScConstructorInvocation, ScPrimaryConstructor, ScReference}
import org.jetbrains.plugins.scala.lang.psi.api.expr._
import org.jetbrains.plugins.scala.lang.psi.api.statements._
import org.jetbrains.plugins.scala.lang.psi.api.toplevel.imports.{ScImportExpr, ScImportSelector}
import org.jetbrains.plugins.scala.lang.psi.api.toplevel.typedef.ScClass
import org.jetbrains.plugins.scala.lang.psi.impl.ScalaPsiElementFactory
import org.jetbrains.plugins.scala.lang.psi.impl.search.ScalaOverridingMemberSearcher
import org.jetbrains.plugins.scala.lang.psi.light._
import org.jetbrains.plugins.scala.lang.refactoring.changeSignature.changeInfo.ScalaChangeInfo

import _root_.scala.annotation.tailrec
import _root_.scala.collection.JavaConverters._
import _root_.scala.collection.mutable.ArrayBuffer

/**
 * Nikolay.Tropin
 * 2014-08-10
 */
class ScalaChangeSignatureUsageProcessor extends ChangeSignatureUsageProcessor with ScalaChangeSignatureUsageHandler {

  override def findUsages(info: ChangeInfo): Array[UsageInfo] = {
    val results = ArrayBuffer[UsageInfo]()
    info match {
      case jInfo: JavaChangeInfo =>
        val method = jInfo.getMethod
        findMethodRefUsages(method, results, searchInJava = false)

        val synthetics = method match {
          case ScPrimaryConstructor.ofClass(clazz) if clazz.isCase =>
            val inExistingClasses = (Seq(clazz) ++ clazz.baseCompanionModule).flatMap {
              _.syntheticMethods
            }
            val inFakeCompanion = clazz.fakeCompanionModule.toSeq.flatMap { obj =>
              obj.membersWithSynthetic
            }
            inExistingClasses ++ inFakeCompanion
          case _ => Seq.empty
        }

        val overriders = OverridingMethodsSearch.search(method).findAll.asScala.toSeq ++
                ScalaOverridingMemberSearcher.search(method).toSeq
        val methods = (method +: overriders ++: synthetics).map {
          case isWrapper(m) => m
          case other => other
        }.distinct

        if (info.isParameterSetOrOrderChanged || info.isParameterNamesChanged) {
          methods.foreach {
            case m: PsiMethod =>
              findParameterUsages(jInfo, m, results)
            case _ =>
          }
        }

        (overriders ++ synthetics).foreach {
          case named: PsiNamedElement =>
            val usageInfo = ScalaNamedElementUsageInfo(named)
            if (usageInfo != null) results += usageInfo

            findMethodRefUsages(named, results, searchInJava = synthetics.contains(named))
          case _ =>
        }
      case _ =>
    }
    results.toArray
  }

  override def shouldPreviewUsages(changeInfo: ChangeInfo, usages: Array[UsageInfo]): Boolean = false

  override def processPrimaryMethod(changeInfo: ChangeInfo): Boolean = changeInfo match {
    case scalaChange: ScalaChangeInfo =>
      scalaChange.function match {
        case f: ScFunction => processNamedElementUsage(changeInfo, FunUsageInfo(f))
        case pc: ScPrimaryConstructor => processNamedElementUsage(changeInfo, PrimaryConstructorUsageInfo(pc))
        case _ =>
      }
      true
    case _ => false
  }

  override def processUsage(changeInfo: ChangeInfo,
                            usageInfo: UsageInfo,
                            beforeMethodChange: Boolean,
                            usages: Array[UsageInfo]): Boolean = {

    def isLastUsage = !beforeMethodChange && usageInfo == usages.last

    def updateNamedElements(): Unit = {
      usages.foreach {
        case namedInfo: ScalaNamedElementUsageInfo =>
          val element = ScalaPsiUtil.nameContext(namedInfo.namedElement)
          val text = element.getText
          element match {
            case _: ScVariableDefinition | _: ScPatternDefinition =>
              val newElement = ScalaPsiElementFactory.createDefinitionWithContext(text, element.getContext, element)
              element.getParent.addAfter(newElement, element)
              element.delete()
            case _: ScVariableDeclaration | _: ScValueDeclaration =>
              val newElement = ScalaPsiElementFactory.createDeclarationFromText(text, element.getContext, element)
              element.getParent.addAfter(newElement, element)
              element.delete()
            case _ =>
          }<commit_msg>use scala processor if change signature was invoked on scala method not via ScalaChangeSignatureDialog<commit_after>package org.jetbrains.plugins.scala
package lang.refactoring.changeSignature

import java.util

import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Ref
import com.intellij.psi._
import com.intellij.psi.search.SearchScope
import com.intellij.psi.search.searches.{OverridingMethodsSearch, ReferencesSearch}
import com.intellij.refactoring.changeSignature.{MethodCallUsageInfo => JavaCallUsageInfo, _}
import com.intellij.refactoring.rename.ResolveSnapshotProvider
import com.intellij.refactoring.rename.ResolveSnapshotProvider.ResolveSnapshot
import com.intellij.usageView.UsageInfo
import com.intellij.util.containers.MultiMap
import org.jetbrains.plugins.scala.extensions._
import org.jetbrains.plugins.scala.lang.psi.ScalaPsiUtil
import org.jetbrains.plugins.scala.lang.psi.api.base.patterns.{ScConstructorPattern, ScInfixPattern}
import org.jetbrains.plugins.scala.lang.psi.api.base.{AuxiliaryConstructor, ScConstructorInvocation, ScPrimaryConstructor, ScReference}
import org.jetbrains.plugins.scala.lang.psi.api.expr._
import org.jetbrains.plugins.scala.lang.psi.api.statements._
import org.jetbrains.plugins.scala.lang.psi.api.toplevel.imports.{ScImportExpr, ScImportSelector}
import org.jetbrains.plugins.scala.lang.psi.api.toplevel.typedef.ScClass
import org.jetbrains.plugins.scala.lang.psi.impl.ScalaPsiElementFactory
import org.jetbrains.plugins.scala.lang.psi.impl.search.ScalaOverridingMemberSearcher
import org.jetbrains.plugins.scala.lang.psi.light._
import org.jetbrains.plugins.scala.lang.refactoring.changeSignature.changeInfo.ScalaChangeInfo

import _root_.scala.annotation.tailrec
import _root_.scala.collection.JavaConverters._
import _root_.scala.collection.mutable.ArrayBuffer

/**
 * Nikolay.Tropin
 * 2014-08-10
 */
class ScalaChangeSignatureUsageProcessor extends ChangeSignatureUsageProcessor with ScalaChangeSignatureUsageHandler {

  override def findUsages(info: ChangeInfo): Array[UsageInfo] = {
    val results = ArrayBuffer[UsageInfo]()
    info match {
      case jInfo: JavaChangeInfo =>
        val method = jInfo.getMethod
        findMethodRefUsages(method, results, searchInJava = false)

        val synthetics = method match {
          case ScPrimaryConstructor.ofClass(clazz) if clazz.isCase =>
            val inExistingClasses = (Seq(clazz) ++ clazz.baseCompanionModule).flatMap {
              _.syntheticMethods
            }
            val inFakeCompanion = clazz.fakeCompanionModule.toSeq.flatMap { obj =>
              obj.membersWithSynthetic
            }
            inExistingClasses ++ inFakeCompanion
          case _ => Seq.empty
        }

        val overriders = OverridingMethodsSearch.search(method).findAll.asScala.toSeq ++
                ScalaOverridingMemberSearcher.search(method).toSeq
        val methods = (method +: overriders ++: synthetics).map {
          case isWrapper(m) => m
          case other => other
        }.distinct

        if (info.isParameterSetOrOrderChanged || info.isParameterNamesChanged) {
          methods.foreach {
            case m: PsiMethod =>
              findParameterUsages(jInfo, m, results)
            case _ =>
          }
        }

        (overriders ++ synthetics).foreach {
          case named: PsiNamedElement =>
            val usageInfo = ScalaNamedElementUsageInfo(named)
            if (usageInfo != null) results += usageInfo

            findMethodRefUsages(named, results, searchInJava = synthetics.contains(named))
          case _ =>
        }
      case _ =>
    }
    results.toArray
  }

  override def shouldPreviewUsages(changeInfo: ChangeInfo, usages: Array[UsageInfo]): Boolean = false

  override def processPrimaryMethod(changeInfo: ChangeInfo): Boolean = {
    val methodUsageInfo = Option(changeInfo.getMethod).collect {
      case f: ScFunction => FunUsageInfo(f)
      case c: ScPrimaryConstructor => PrimaryConstructorUsageInfo(c)
    }
    methodUsageInfo match {
      case Some(usageInfo) =>
        processNamedElementUsage(changeInfo, usageInfo)
        true
      case None =>
        false
    }
  }

  override def processUsage(changeInfo: ChangeInfo,
                            usageInfo: UsageInfo,
                            beforeMethodChange: Boolean,
                            usages: Array[UsageInfo]): Boolean = {

    def isLastUsage = !beforeMethodChange && usageInfo == usages.last

    def updateNamedElements(): Unit = {
      usages.foreach {
        case namedInfo: ScalaNamedElementUsageInfo =>
          val element = ScalaPsiUtil.nameContext(namedInfo.namedElement)
          val text = element.getText
          element match {
            case _: ScVariableDefinition | _: ScPatternDefinition =>
              val newElement = ScalaPsiElementFactory.createDefinitionWithContext(text, element.getContext, element)
              element.getParent.addAfter(newElement, element)
              element.delete()
            case _: ScVariableDeclaration | _: ScValueDeclaration =>
              val newElement = ScalaPsiElementFactory.createDeclarationFromText(text, element.getContext, element)
              element.getParent.addAfter(newElement, element)
              element.delete()
            case _ =>
          }
{'fraction_non_alphanumeric': 0.08540049233099792, 'fraction_numerical': 0.0015148646089755728, 'mean_word_length': 3.147232037691402, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 44, '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': '6278612', 'n_tokens_mistral': 2966, 'n_tokens_neox': 2849, 'n_words': 509}