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

import com.intellij.psi.util.PsiUtilBase
import org.jetbrains.plugins.scala.lang.psi.api.ScalaFile
import com.intellij.openapi.actionSystem._
import org.jetbrains.plugins.scala.lang.refactoring.util.ScalaRefactoringUtil
import com.intellij.openapi.ui.popup.{JBPopup, JBPopupFactory}
import javax.swing._
import org.jetbrains.plugins.scala.lang.psi.presentation.ScImplicitFunctionListCellRenderer
import com.intellij.psi._
import collection.mutable.ArrayBuffer
import org.jetbrains.plugins.scala.lang.psi.api.expr._
import org.jetbrains.plugins.scala.lang.psi.api.statements.ScFunction
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.IconLoader
import com.intellij.openapi.keymap.KeymapUtil
import com.intellij.codeInsight.CodeInsightBundle
import java.awt.event.{MouseAdapter, MouseEvent}
import javax.swing.border.Border
import java.awt.{Font, Point, Rectangle, Color}
import javax.swing.event.{ListSelectionEvent, ListSelectionListener}
import com.intellij.util.Alarm
import scala.Some
import org.jetbrains.plugins.scala.util.IntentionUtils
import com.intellij.openapi.editor.colors.impl.EditorColorsSchemeImpl
import com.intellij.openapi.editor.colors.EditorFontType

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

object GoToImplicitConversionAction {
  var popup: JBPopup = null
  var list: JList = null

  def getPopup = popup

  def setPopup(p: JBPopup) {
    popup = p
  }

  def getList = list

  def setList(l: JList) {
    list = l
  }
}

class GoToImplicitConversionAction extends AnAction("Go to implicit conversion action") {
  private var hint: LightBulbHint = null
  private val hintAlarm: Alarm = new Alarm

  override def update(e: AnActionEvent) {
    ScalaActionUtil.enableAndShowIfInScalaFile(e)
  }

  def actionPerformed(e: AnActionEvent) {
    val context = e.getDataContext
    val project = PlatformDataKeys.PROJECT.getData(context)
    val editor = PlatformDataKeys.EDITOR.getData(context)
    if (project == null || editor == null) return
    val file = PsiUtilBase.getPsiFileInEditor(editor, project)
    if (!file.isInstanceOf[ScalaFile]) return

    def forExpr(expr: ScExpression): Boolean = {
      val implicitConversions = { //todo: too complex logic, should be simplified, and moved into one place
        lazy val additionalExpression = expr.getAdditionalExpression
        if (ScUnderScoreSectionUtil.isUnderscoreFunction(expr)) {
          val conv1 = expr.getImplicitConversions(fromUnder = false)
          val conv2 = expr.getImplicitConversions(fromUnder = true)
          if (conv2._2 != None) conv2
          else if (conv1._2 != None) conv1
          else if (additionalExpression != None) {
            val conv3 = additionalExpression.get._1.getImplicitConversions(fromUnder = false, expectedOption = Some(additionalExpression.get._2))
            if (conv3._2 != None) conv3
            else conv1
          } else conv1
        } else if (additionalExpression != None) {
          val conv3 = additionalExpression.get._1.getImplicitConversions(fromUnder = false, expectedOption = Some(additionalExpression.get._2))
          if (conv3._2 != None) conv3
          else expr.getImplicitConversions(fromUnder = false)
        } else expr.getImplicitConversions(fromUnder = false)
      }
      val functions = implicitConversions._1
      if (functions.length == 0) return true
      val conversionFun = implicitConversions._2.getOrElse(null)
      val model: DefaultListModel = new DefaultListModel
      val firstPart = implicitConversions._3.sortBy(_.getName)
      val secondPart = implicitConversions._4.sortBy(_.getName)
      var actualIndex = -1
      //todo actualIndex should be another if conversionFun is not one
      for (element <- firstPart) {
        val elem = new Parameters(element, expr, editor, firstPart, secondPart)
        model.addElement(elem)
        if (element == conversionFun) actualIndex = model.indexOf(elem)
      }
      for (element <- secondPart) {
        val elem = new Parameters(element, expr, editor, firstPart, secondPart)
        model.addElement(elem)
        if (element == conversionFun) actualIndex = model.indexOf(elem)
      }
      val list: JList = new JList(model)
      val renderer = new ScImplicitFunctionListCellRenderer(conversionFun)
      val font = editor.getColorsScheme.getFont(EditorFontType.PLAIN)
      renderer.setFont(font)
      list.setFont(font)
      list.setCellRenderer(renderer)
      list.getSelectionModel.addListSelectionListener(new ListSelectionListener {
        def valueChanged(e: ListSelectionEvent) {
          hintAlarm.cancelAllRequests
          val item = list.getSelectedValue.asInstanceOf[Parameters]
          if (item == null) return
          updateHint(item, project)
        }
      })
      if (actualIndex >= 0 && actualIndex < list.getModel.getSize) {
        list.getSelectionModel.setSelectionInterval(actualIndex, actualIndex)
      }
      GoToImplicitConversionAction.setList(list)

      val builder = JBPopupFactory.getInstance.createListPopupBuilder(list)
      val popup = builder.setTitle("Choose implicit conversion method:").setAdText("Press Alt+Enter").
      setMovable(false).setResizable(false).setRequestFocus(true).
      setItemChoosenCallback(new Runnable {
        def run() {
          val entity = list.getSelectedValue.asInstanceOf[Parameters]
          entity.getNewExpression match {
            case f: ScFunction =>
              f.getSyntheticNavigationElement match {
                case Some(n: NavigatablePsiElement) => n.navigate(true)
                case _ => f.navigate(true)
              }
            case n: NavigatablePsiElement => n.navigate(true)
            case _ => //do nothing
          }
        }
      }).createPopup
      popup.showInBestPositionFor(editor)

      GoToImplicitConversionAction.setPopup(popup)

      hint = new LightBulbHint(editor, project, expr)
      hint.createHint(firstPart, secondPart)

      false
    }

    if (editor.getSelectionModel.hasSelection) {
      val selectionStart = editor.getSelectionModel.getSelectionStart
      val selectionEnd = editor.getSelectionModel.getSelectionEnd
      val opt = ScalaRefactoringUtil.getExpression(project, editor, file, selectionStart, selectionEnd)
      opt match {
        case Some((expr, _)) =>
          if (forExpr(expr)) return
        case _ => return
      }
    } else {
      val offset = editor.getCaretModel.getOffset
      val element: PsiElement = file.findElementAt(offset) match {
        case w: PsiWhiteSpace if w.getTextRange.getStartOffset == offset &&
          w.getText.contains("\n") => file.findElementAt(offset - 1)
        case p => p<commit_msg>Scroll Implicit conversion dialog to actual conversion.<commit_after>package org.jetbrains.plugins.scala.actions

import com.intellij.psi.util.PsiUtilBase
import org.jetbrains.plugins.scala.lang.psi.api.ScalaFile
import com.intellij.openapi.actionSystem._
import org.jetbrains.plugins.scala.lang.refactoring.util.ScalaRefactoringUtil
import com.intellij.openapi.ui.popup.{JBPopup, JBPopupFactory}
import javax.swing._
import org.jetbrains.plugins.scala.lang.psi.presentation.ScImplicitFunctionListCellRenderer
import com.intellij.psi._
import collection.mutable.ArrayBuffer
import org.jetbrains.plugins.scala.lang.psi.api.expr._
import org.jetbrains.plugins.scala.lang.psi.api.statements.ScFunction
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.IconLoader
import com.intellij.openapi.keymap.KeymapUtil
import com.intellij.codeInsight.CodeInsightBundle
import java.awt.event.{MouseAdapter, MouseEvent}
import javax.swing.border.Border
import java.awt.{Font, Point, Rectangle, Color}
import javax.swing.event.{ListSelectionEvent, ListSelectionListener}
import com.intellij.util.Alarm
import scala.Some
import org.jetbrains.plugins.scala.util.IntentionUtils
import com.intellij.openapi.editor.colors.impl.EditorColorsSchemeImpl
import com.intellij.openapi.editor.colors.EditorFontType

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

object GoToImplicitConversionAction {
  var popup: JBPopup = null
  var list: JList = null

  def getPopup = popup

  def setPopup(p: JBPopup) {
    popup = p
  }

  def getList = list

  def setList(l: JList) {
    list = l
  }
}

class GoToImplicitConversionAction extends AnAction("Go to implicit conversion action") {
  private var hint: LightBulbHint = null
  private val hintAlarm: Alarm = new Alarm

  override def update(e: AnActionEvent) {
    ScalaActionUtil.enableAndShowIfInScalaFile(e)
  }

  def actionPerformed(e: AnActionEvent) {
    val context = e.getDataContext
    val project = PlatformDataKeys.PROJECT.getData(context)
    val editor = PlatformDataKeys.EDITOR.getData(context)
    if (project == null || editor == null) return
    val file = PsiUtilBase.getPsiFileInEditor(editor, project)
    if (!file.isInstanceOf[ScalaFile]) return

    def forExpr(expr: ScExpression): Boolean = {
      val implicitConversions = { //todo: too complex logic, should be simplified, and moved into one place
        lazy val additionalExpression = expr.getAdditionalExpression
        if (ScUnderScoreSectionUtil.isUnderscoreFunction(expr)) {
          val conv1 = expr.getImplicitConversions(fromUnder = false)
          val conv2 = expr.getImplicitConversions(fromUnder = true)
          if (conv2._2 != None) conv2
          else if (conv1._2 != None) conv1
          else if (additionalExpression != None) {
            val conv3 = additionalExpression.get._1.getImplicitConversions(fromUnder = false, expectedOption = Some(additionalExpression.get._2))
            if (conv3._2 != None) conv3
            else conv1
          } else conv1
        } else if (additionalExpression != None) {
          val conv3 = additionalExpression.get._1.getImplicitConversions(fromUnder = false, expectedOption = Some(additionalExpression.get._2))
          if (conv3._2 != None) conv3
          else expr.getImplicitConversions(fromUnder = false)
        } else expr.getImplicitConversions(fromUnder = false)
      }
      val functions = implicitConversions._1
      if (functions.length == 0) return true
      val conversionFun = implicitConversions._2.getOrElse(null)
      val model: DefaultListModel = new DefaultListModel
      val firstPart = implicitConversions._3.sortBy(_.getName)
      val secondPart = implicitConversions._4.sortBy(_.getName)
      var actualIndex = -1
      //todo actualIndex should be another if conversionFun is not one
      for (element <- firstPart) {
        val elem = new Parameters(element, expr, editor, firstPart, secondPart)
        model.addElement(elem)
        if (element == conversionFun) actualIndex = model.indexOf(elem)
      }
      for (element <- secondPart) {
        val elem = new Parameters(element, expr, editor, firstPart, secondPart)
        model.addElement(elem)
        if (element == conversionFun) actualIndex = model.indexOf(elem)
      }
      val list: JList = new JList(model)
      val renderer = new ScImplicitFunctionListCellRenderer(conversionFun)
      val font = editor.getColorsScheme.getFont(EditorFontType.PLAIN)
      renderer.setFont(font)
      list.setFont(font)
      list.setCellRenderer(renderer)
      list.getSelectionModel.addListSelectionListener(new ListSelectionListener {
        def valueChanged(e: ListSelectionEvent) {
          hintAlarm.cancelAllRequests
          val item = list.getSelectedValue.asInstanceOf[Parameters]
          if (item == null) return
          updateHint(item, project)
        }
      })
      GoToImplicitConversionAction.setList(list)

      val builder = JBPopupFactory.getInstance.createListPopupBuilder(list)
      val popup = builder.setTitle("Choose implicit conversion method:").setAdText("Press Alt+Enter").
      setMovable(false).setResizable(false).setRequestFocus(true).
      setItemChoosenCallback(new Runnable {
        def run() {
          val entity = list.getSelectedValue.asInstanceOf[Parameters]
          entity.getNewExpression match {
            case f: ScFunction =>
              f.getSyntheticNavigationElement match {
                case Some(n: NavigatablePsiElement) => n.navigate(true)
                case _ => f.navigate(true)
              }
            case n: NavigatablePsiElement => n.navigate(true)
            case _ => //do nothing
          }
        }
      }).createPopup
      popup.showInBestPositionFor(editor)

      if (actualIndex >= 0 && actualIndex < list.getModel.getSize) {
        list.getSelectionModel.setSelectionInterval(actualIndex, actualIndex)
        list.ensureIndexIsVisible(actualIndex)
      }

      GoToImplicitConversionAction.setPopup(popup)

      hint = new LightBulbHint(editor, project, expr)
      hint.createHint(firstPart, secondPart)

      false
    }

    if (editor.getSelectionModel.hasSelection) {
      val selectionStart = editor.getSelectionModel.getSelectionStart
      val selectionEnd = editor.getSelectionModel.getSelectionEnd
      val opt = ScalaRefactoringUtil.getExpression(project, editor, file, selectionStart, selectionEnd)
      opt match {
        case Some((expr, _)) =>
          if (forExpr(expr)) return
        case _ => return
      }
    } else {
      val offset = editor.getCaretModel.getOffset
      val element: PsiElement = file.findElementAt(offset) match {
        case w: PsiWhiteSpace if w.getTextRange.getStartOffset == offset &&
          w.getText.contains("\n") => file.findElementAt(offset - 1)
        case p => p
{'fraction_non_alphanumeric': 0.0900557348195952, 'fraction_numerical': 0.005573481959518921, 'mean_word_length': 3.2951181102362206, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 25, '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': '7061693', 'n_tokens_mistral': 3979, 'n_tokens_neox': 3889, 'n_words': 840}