<commit_before>package io.gitlab.arturbosch.detekt.core.suppressors

import io.gitlab.arturbosch.detekt.api.ConfigAware
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.resolve.BindingContext

/*
 * Possible improvement: don't only check name but also check for parameters.
 * ```yaml
 * ignoreFunctions:
 *   - 'toString()' # only functions called toString without parameter
 *   - 'compare(String)' # only functions called compare with one parameter of type String
 *   - 'equals' # every function called function (it doesn't matter it's parameters is ignored)
 * ```
 * This would not be a breaking change.
 */
internal fun functionSuppressorFactory(rule: ConfigAware, bindingContext: BindingContext): Suppressor? {
    val names = rule.valueOrDefault("ignoreFunction", emptyList<String>())
    return if (names.isNotEmpty()) {
        { finding ->
            val element = finding.entity.ktElement
            element != null && functionSuppressor(element, bindingContext, names)
        }
    } else {
        null
    }
}

private fun functionSuppressor(
    element: KtElement,
    bindingContext: BindingContext,
    names: List<String>,
): Boolean {
    return element.isInFunctionNamed(bindingContext, names)
}

private fun KtElement.isInFunctionNamed(
    bindingContext: BindingContext,
    names: List<String>,
): Boolean {
    return if (this is KtNamedFunction && name in names) {
        true
    } else {
        getStrictParentOfType<KtNamedFunction>()?.isInFunctionNamed(bindingContext, names) ?: false
    }
}<commit_msg>Use FunctionSignature instead<commit_after>package io.gitlab.arturbosch.detekt.core.suppressors

import io.github.detekt.tooling.api.FunctionSignature
import io.gitlab.arturbosch.detekt.api.ConfigAware
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.resolve.BindingContext

internal fun functionSuppressorFactory(rule: ConfigAware, bindingContext: BindingContext): Suppressor? {
    val signatures = rule.valueOrDefault("ignoreFunction", emptyList<String>()).map(FunctionSignature::fromString)
    return if (signatures.isNotEmpty()) {
        { finding ->
            val element = finding.entity.ktElement
            element != null && functionSuppressor(element, bindingContext, signatures)
        }
    } else {
        null
    }
}

private fun functionSuppressor(
    element: KtElement,
    bindingContext: BindingContext,
    functionSignatures: List<FunctionSignature>,
): Boolean {
    return element.isInFunctionNamed(bindingContext, functionSignatures)
}

private fun KtElement.isInFunctionNamed(
    bindingContext: BindingContext,
    methodSignatures: List<FunctionSignature>,
): Boolean {
    return if (this is KtNamedFunction && methodSignatures.any { it.match(this, bindingContext) }) {
        true
    } else {
        getStrictParentOfType<KtNamedFunction>()?.isInFunctionNamed(bindingContext, methodSignatures) ?: false
    }
}
{'fraction_non_alphanumeric': 0.09629394995248654, 'fraction_numerical': 0.0, 'mean_word_length': 4.228476821192053, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 13, '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': '7325884', 'n_tokens_mistral': 909, 'n_tokens_neox': 885, 'n_words': 196}