<commit_before>package org.jetbrains.plugins.scala
package codeInspection.parameters

import lang.psi.api.ScalaElementVisitor
import codeInspection.InspectionBundle
import com.intellij.codeInspection.{LocalInspectionTool, ProblemHighlightType, ProblemsHolder}
import lang.lexer.ScalaTokenTypes
import org.jetbrains.plugins.scala.util.IntentionUtils
import lang.psi.types.result.TypingContext
import com.intellij.psi.{PsiElementVisitor, PsiElement}
import org.jetbrains.plugins.scala.extensions._
import com.intellij.psi.util.PsiTreeUtil
import collection.Seq
import lang.psi.types.nonvalue.Parameter
import lang.psi.api.base.ScLiteral
import lang.psi.api.expr._
import com.intellij.openapi.diagnostic.Logger
import javax.swing.{JCheckBox, JPanel, JComponent}
import java.awt._
import javax.swing.event.{ChangeListener, ChangeEvent}
import scala.Some
import lang.psi.api.statements.ScFunction

/**
 * @author Ksenia.Sautina
 * @since 5/10/12
 */

class NameBooleanParametersInspection extends LocalInspectionTool {

  override def buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor = {
    new ScalaElementVisitor {
      override def visitMethodCallExpression(mc: ScMethodCall) {
        if (mc == null || mc.args == null || mc.args.exprs.isEmpty) return
        mc.getInvokedExpr match {
          case ref: ScReferenceExpression => ref.resolve() match {
            case fun: ScFunction =>
              //todo
              if (fun.name.startsWith("set") && mc.args.exprs.size == 1 && isBooleanType(mc.args.exprs(0)) &&
                IGNORE_SETTERS) return
            case _ =>
          }
          case _ =>
        }
        for (expr <- mc.args.exprs) {
          expr match {
            case literal: ScLiteral if isBooleanType(expr) &&
                    IntentionUtils.check(literal, onlyBoolean = true).isDefined &&
                    (expr.getNode.getFirstChildNode.getElementType == ScalaTokenTypes.kTRUE ||
                    expr.getNode.getFirstChildNode.getElementType == ScalaTokenTypes.kFALSE) =>
              holder.registerProblem(holder.getManager.createProblemDescriptor(expr,
                InspectionBundle.message("name.boolean"),
                new NameBooleanParametersQuickFix(mc, literal),
                ProblemHighlightType.GENERIC_ERROR_OR_WARNING, isOnTheFly))
            case _ =>
          }
        }
      }

      def isBooleanType(element: PsiElement): Boolean = {
        val containingArgList: Option[ScArgumentExprList] = element.parents.collectFirst {
          case al: ScArgumentExprList if !al.isBraceArgs => al
        }
        containingArgList match {
          case Some(al) =>
            val index = al.exprs.indexWhere(argExpr => PsiTreeUtil.isAncestor(argExpr, element, false))
            index match {
              case -1 => false
              case i =>
                val argExprsToNamify = al.exprs.drop(index)
                val argsAndMatchingParams: Seq[(ScExpression, Option[Parameter])] = argExprsToNamify.map {
                  arg => (arg, al.parameterOf(arg))
                }
                argsAndMatchingParams.exists {
                  case (expr, Some(param)) => {
                    val paramInCode = param.paramInCode.getOrElse(null)
                    if (paramInCode == null) return false
                    if (!paramInCode.isValid) return false //todo: find why it can be invalid?
                    val realParameterType = paramInCode.getRealParameterType(TypingContext.empty).getOrElse(null)
                    if (realParameterType == null) return false
                    else if (realParameterType.canonicalText == "Boolean") return true
                    else return false
                  }
                  case _ => return false
                }
            }
          case None => false
        }
      }
    }
  }

  override def createOptionsPanel: JComponent = {
    val ignoreSettersCheckbox = new JCheckBox(InspectionBundle.message("name.boolean.ignore.setters"))
    ignoreSettersCheckbox.setSelected(IGNORE_SETTERS)
    ignoreSettersCheckbox.getModel.addChangeListener(new ChangeListener {
      def stateChanged(e: ChangeEvent) {
        IGNORE_SETTERS = ignoreSettersCheckbox.isSelected
      }
    })
    val panel: JPanel = new JPanel(new FlowLayout(FlowLayout.LEFT))
    panel.add(ignoreSettersCheckbox)
    panel
  }

  var IGNORE_SETTERS: Boolean = true
}

object NameBooleanParametersInspection {
  private val LOG = Logger.getInstance(getClass)
}<commit_msg>Ignore setters setting was not persistent: fixed<commit_after>package org.jetbrains.plugins.scala
package codeInspection.parameters

import lang.psi.api.ScalaElementVisitor
import codeInspection.InspectionBundle
import com.intellij.codeInspection.{LocalInspectionTool, ProblemHighlightType, ProblemsHolder}
import lang.lexer.ScalaTokenTypes
import org.jetbrains.plugins.scala.util.IntentionUtils
import lang.psi.types.result.TypingContext
import com.intellij.psi.{PsiElementVisitor, PsiElement}
import org.jetbrains.plugins.scala.extensions._
import com.intellij.psi.util.PsiTreeUtil
import collection.Seq
import lang.psi.types.nonvalue.Parameter
import lang.psi.api.base.ScLiteral
import lang.psi.api.expr._
import com.intellij.openapi.diagnostic.Logger
import javax.swing.{JCheckBox, JPanel, JComponent}
import java.awt._
import javax.swing.event.{ChangeListener, ChangeEvent}
import scala.Some
import lang.psi.api.statements.ScFunction
import com.intellij.ide.util.PropertiesComponent

/**
 * @author Ksenia.Sautina
 * @since 5/10/12
 */

class NameBooleanParametersInspection extends LocalInspectionTool {

  override def buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor = {
    new ScalaElementVisitor {
      override def visitMethodCallExpression(mc: ScMethodCall) {
        if (mc == null || mc.args == null || mc.args.exprs.isEmpty) return
        mc.getInvokedExpr match {
          case ref: ScReferenceExpression => ref.resolve() match {
            case fun: ScFunction =>
              //todo
              if (fun.name.startsWith("set") && mc.args.exprs.size == 1 && isBooleanType(mc.args.exprs(0)) &&
                ignoreSetters) return
            case _ =>
          }
          case _ =>
        }
        for (expr <- mc.args.exprs) {
          expr match {
            case literal: ScLiteral if isBooleanType(expr) &&
                    IntentionUtils.check(literal, onlyBoolean = true).isDefined &&
                    (expr.getNode.getFirstChildNode.getElementType == ScalaTokenTypes.kTRUE ||
                    expr.getNode.getFirstChildNode.getElementType == ScalaTokenTypes.kFALSE) =>
              holder.registerProblem(holder.getManager.createProblemDescriptor(expr,
                InspectionBundle.message("name.boolean"),
                new NameBooleanParametersQuickFix(mc, literal),
                ProblemHighlightType.GENERIC_ERROR_OR_WARNING, isOnTheFly))
            case _ =>
          }
        }
      }

      def isBooleanType(element: PsiElement): Boolean = {
        val containingArgList: Option[ScArgumentExprList] = element.parents.collectFirst {
          case al: ScArgumentExprList if !al.isBraceArgs => al
        }
        containingArgList match {
          case Some(al) =>
            val index = al.exprs.indexWhere(argExpr => PsiTreeUtil.isAncestor(argExpr, element, false))
            index match {
              case -1 => false
              case i =>
                val argExprsToNamify = al.exprs.drop(index)
                val argsAndMatchingParams: Seq[(ScExpression, Option[Parameter])] = argExprsToNamify.map {
                  arg => (arg, al.parameterOf(arg))
                }
                argsAndMatchingParams.exists {
                  case (expr, Some(param)) => {
                    val paramInCode = param.paramInCode.getOrElse(null)
                    if (paramInCode == null) return false
                    if (!paramInCode.isValid) return false //todo: find why it can be invalid?
                    val realParameterType = paramInCode.getRealParameterType(TypingContext.empty).getOrElse(null)
                    if (realParameterType == null) return false
                    else if (realParameterType.canonicalText == "Boolean") return true
                    else return false
                  }
                  case _ => return false
                }
            }
          case None => false
        }
      }
    }
  }

  //persistent storage of "ignore setters" setting
  private val properties = PropertiesComponent.getInstance()
  private var ignoreSettersCached: Option[Boolean] = None
  def ignoreSetters: Boolean = ignoreSettersCached.getOrElse(properties.getBoolean("name.boolean.ignore.setters", true))
  def ignoreSetters_= (b: Boolean) {
    properties.setValue("name.boolean.ignore.setters", b.toString)
    ignoreSettersCached = Some(b)
  }

  override def createOptionsPanel: JComponent = {
    val ignoreSettersCheckbox = new JCheckBox(InspectionBundle.message("name.boolean.ignore.setters"))
    ignoreSettersCheckbox.setSelected(ignoreSetters)
    ignoreSettersCheckbox.getModel.addChangeListener(new ChangeListener {
      def stateChanged(e: ChangeEvent) {
        ignoreSetters = ignoreSettersCheckbox.isSelected
      }
    })
    val panel: JPanel = new JPanel(new FlowLayout(FlowLayout.LEFT))
    panel.add(ignoreSettersCheckbox)
    panel
  }

}

object NameBooleanParametersInspection {
  private val LOG = Logger.getInstance(getClass)
}
{'fraction_non_alphanumeric': 0.0898970804452846, 'fraction_numerical': 0.0016803192606595252, 'mean_word_length': 2.5773854244928627, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 33, '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': '6277502', 'n_tokens_mistral': 2695, 'n_tokens_neox': 2593, 'n_words': 518}