<commit_before>/*
 * Minecraft Dev for IntelliJ
 *
 * https://minecraftdev.org
 *
 * Copyright (c) 2017 minecraft-dev
 *
 * MIT License
 */

package com.demonwav.mcdev.util

import com.demonwav.mcdev.i18n.translations.Translation
import com.demonwav.mcdev.i18n.translations.Translation.Companion.FormattingError
import com.intellij.psi.JavaTokenType
import com.intellij.psi.PsiAnnotationMemberValue
import com.intellij.psi.PsiExpression
import com.intellij.psi.PsiLiteral
import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.PsiParameter
import com.intellij.psi.PsiParameterList
import com.intellij.psi.PsiPolyadicExpression
import com.intellij.psi.PsiReferenceExpression
import com.intellij.psi.PsiTypeCastExpression
import com.intellij.psi.PsiVariable

fun PsiAnnotationMemberValue.evaluate(defaultValue: String?, parameterReplacement: String?): String? {
    if (this is PsiTypeCastExpression && this.operand != null) {
        return this.operand!!.evaluate(defaultValue, parameterReplacement)
    }
    if (this is PsiReferenceExpression) {
        val reference = this.advancedResolve(false).element
        if (reference is PsiParameter) {
            return parameterReplacement
        }
        if (reference is PsiVariable && reference.initializer != null) {
            return reference.initializer!!.evaluate(null, parameterReplacement)
        }
    } else if (this is PsiLiteral) {
        return this.value.toString()
    } else if (this is PsiPolyadicExpression) {
        var value = ""
        for (operand in this.operands) {
            val operandResult = operand.evaluate(defaultValue, parameterReplacement) ?: return defaultValue
            when (this.operationTokenType) {
                JavaTokenType.PLUS -> value += operandResult
            }
        }
        return value
    }
    return defaultValue
}

fun PsiExpression.substituteParameter(substitutions: Map<Int, Array<String?>?>, allowReferences: Boolean, allowTranslations: Boolean): Array<String?>? {
    if (this is PsiTypeCastExpression && this.operand != null) {
        return this.operand!!.substituteParameter(substitutions, allowReferences, allowTranslations)
    }
    if (this is PsiReferenceExpression) {
        val reference = this.advancedResolve(false).element
        if (reference is PsiParameter && reference.parent is PsiParameterList) {
            val paramIndex = (reference.parent as PsiParameterList).getParameterIndex(reference)
            if (substitutions.containsKey(paramIndex)) {
                return substitutions[paramIndex]
            }
        }
        if (reference is PsiVariable && reference.initializer != null) {
            return reference.initializer!!.substituteParameter(substitutions, allowReferences, allowTranslations)
        }
    } else if (this is PsiLiteral) {
        return arrayOf(this.value.toString())
    } else if (this is PsiPolyadicExpression) {
        var value = ""
        for (operand in this.operands) {
            val operandResult = operand.evaluate(null, null) ?: return null
            when (this.operationTokenType) {
                JavaTokenType.PLUS -> value += operandResult
            }
        }
        return arrayOf(value)
    } else if (this is PsiMethodCallExpression && allowTranslations) {
        for (argument in this.argumentList.expressions) {
            val translation = Translation.find(argument) ?: continue
            if (translation.formattingError == FormattingError.MISSING) {
                return arrayOf("{${translation.text}}")
            }
            return arrayOf(translation.text)
        }
    }
    if (allowReferences) {
        return arrayOf("\${${this.text}}")
    } else {
        return null
    }
}
<commit_msg>Allow all calls (including constructor calls) in nested translations<commit_after>/*
 * Minecraft Dev for IntelliJ
 *
 * https://minecraftdev.org
 *
 * Copyright (c) 2017 minecraft-dev
 *
 * MIT License
 */

package com.demonwav.mcdev.util

import com.demonwav.mcdev.i18n.translations.Translation
import com.demonwav.mcdev.i18n.translations.Translation.Companion.FormattingError
import com.intellij.psi.JavaTokenType
import com.intellij.psi.PsiAnnotationMemberValue
import com.intellij.psi.PsiCall
import com.intellij.psi.PsiCallExpression
import com.intellij.psi.PsiExpression
import com.intellij.psi.PsiLiteral
import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.PsiParameter
import com.intellij.psi.PsiParameterList
import com.intellij.psi.PsiPolyadicExpression
import com.intellij.psi.PsiReferenceExpression
import com.intellij.psi.PsiTypeCastExpression
import com.intellij.psi.PsiVariable

fun PsiAnnotationMemberValue.evaluate(defaultValue: String?, parameterReplacement: String?): String? {
    if (this is PsiTypeCastExpression && this.operand != null) {
        return this.operand!!.evaluate(defaultValue, parameterReplacement)
    }
    if (this is PsiReferenceExpression) {
        val reference = this.advancedResolve(false).element
        if (reference is PsiParameter) {
            return parameterReplacement
        }
        if (reference is PsiVariable && reference.initializer != null) {
            return reference.initializer!!.evaluate(null, parameterReplacement)
        }
    } else if (this is PsiLiteral) {
        return this.value.toString()
    } else if (this is PsiPolyadicExpression) {
        var value = ""
        for (operand in this.operands) {
            val operandResult = operand.evaluate(defaultValue, parameterReplacement) ?: return defaultValue
            when (this.operationTokenType) {
                JavaTokenType.PLUS -> value += operandResult
            }
        }
        return value
    }
    return defaultValue
}

fun PsiExpression.substituteParameter(substitutions: Map<Int, Array<String?>?>, allowReferences: Boolean, allowTranslations: Boolean): Array<String?>? {
    if (this is PsiTypeCastExpression && this.operand != null) {
        return this.operand!!.substituteParameter(substitutions, allowReferences, allowTranslations)
    }
    if (this is PsiReferenceExpression) {
        val reference = this.advancedResolve(false).element
        if (reference is PsiParameter && reference.parent is PsiParameterList) {
            val paramIndex = (reference.parent as PsiParameterList).getParameterIndex(reference)
            if (substitutions.containsKey(paramIndex)) {
                return substitutions[paramIndex]
            }
        }
        if (reference is PsiVariable && reference.initializer != null) {
            return reference.initializer!!.substituteParameter(substitutions, allowReferences, allowTranslations)
        }
    } else if (this is PsiLiteral) {
        return arrayOf(this.value.toString())
    } else if (this is PsiPolyadicExpression) {
        var value = ""
        for (operand in this.operands) {
            val operandResult = operand.evaluate(null, null) ?: return null
            when (this.operationTokenType) {
                JavaTokenType.PLUS -> value += operandResult
            }
        }
        return arrayOf(value)
    } else if (this is PsiCall && allowTranslations) {
        for (argument in this.argumentList?.expressions ?: emptyArray()) {
            val translation = Translation.find(argument) ?: continue
            if (translation.formattingError == FormattingError.MISSING) {
                return arrayOf("{ERROR: Missing formatting arguments for '${translation.text}'}")
            }
            return arrayOf(translation.text)
        }
    }
    return if (allowReferences) {
        arrayOf("\${${this.text}}")
    } else {
        null
    }
}

{'fraction_non_alphanumeric': 0.0932480083583649, 'fraction_numerical': 0.0020895912237168606, 'mean_word_length': 2.9864653826132224, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, 'https://': 2, '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': '3869978', 'n_tokens_mistral': 2137, 'n_tokens_neox': 2080, 'n_words': 459}