in src/main/kotlin/org/arend/refactoring/changeSignature/ArendChangeSignatureUtils.kt [254:317]
fun printPattern(pattern: Concrete.Pattern, psiElement: ArendPattern, refactoringContext: ChangeSignatureRefactoringContext): IntermediatePrintResult {
val isInsideAppExprLeaf = !(pattern.data == psiElement ||
(pattern.data as? ArendPattern)?.let{ it.constructorReference != null && it.parent == psiElement } == true)
if (pattern is Concrete.ConstructorPattern && !isInsideAppExprLeaf) {
val constructor = (pattern.constructor as DataLocatedReferable).data?.element
val constructorIsInfix = constructor is GlobalReferable && constructor.precedence.isInfix
val asTextWithWhitespace = (psiElement.asPattern?.getWhitespace(SpaceDirection.LeadingSpace) ?: "") + (psiElement.asPattern?.text ?: "")
val descriptor = if (constructor is Referable) refactoringContext.identifyDescriptor(constructor) else null
val patternEntry = PatternEntry(refactoringContext, psiElement, descriptor, pattern)
return if (descriptor != null) {
val processResult = patternEntry.printUsageEntry(constructor as? GlobalReferable)
val baseText = processResult.text + asTextWithWhitespace
IntermediatePrintResult(baseText, processResult.parenthesizedPrefixText,
isAtomic = false,
isLambda = false,
referable = constructor as? GlobalReferable
)
} else {
val builder = StringBuilder()
var explicitArgCount = 0
val processedFunction = refactoringContext.textGetter(pattern.constructorData as ArendPattern)
val (strippedFunc, isAtomic) = if (patternEntry.blocks.size == 1 && patternEntry.blocks[0] == FUNCTION_INDEX) getStrippedPsi(pattern.data as PsiElement) else Pair(null, false)
val strippedText = strippedFunc?.let { refactoringContext.textGetter(it) }
for (block in patternEntry.blocks) when (block) {
is Int -> if (block == FUNCTION_INDEX) builder.append(processedFunction) else patternEntry.getArguments()[block].let {
if (it.isExplicit) explicitArgCount++
val textInBrackets = "{${it.printResult.text}}"
val text = if (it.isExplicit) (if (explicitArgCount == 2 && constructorIsInfix && it.printResult.parenthesizedPrefixText != null) it.printResult.parenthesizedPrefixText else it.printResult.text) else textInBrackets
builder.append(text)
}
is PsiElement -> builder.append(refactoringContext.textGetter(block))
}
IntermediatePrintResult(strippedText ?: builder.toString().let { if (isAtomic && constructorIsInfix) "($it)" else it}, null, isAtomic, false, constructor as? GlobalReferable
)
}
}
fun textGetterForPatterns(exprData: PsiElement, preferStrippedVersion: Boolean): String {
val replacementTextEntry = refactoringContext.textReplacements[exprData]
if (replacementTextEntry != null) {
if (!preferStrippedVersion && exprData is ArendPattern && !exprData.isExplicit) return "{$replacementTextEntry}"
return replacementTextEntry
}
if (exprData.firstChild == null) return exprData.text
val childRange = if (exprData is ArendPattern && !exprData.isExplicit) {
val lbrace = exprData.childrenWithLeaves.indexOfFirst { it.elementType == LBRACE }
val rbrace = exprData.childrenWithLeaves.indexOfFirst { it.elementType == RBRACE }
if (lbrace == -1 || rbrace == -1 || lbrace - 1 > rbrace)
exprData.childrenWithLeaves.toList() else
exprData.childrenWithLeaves.toList().subList(lbrace + 1, rbrace)
} else exprData.childrenWithLeaves.toList()
return buildString {
for (c in childRange)
append(textGetterForPatterns(c, false))
}
}
val (exprData, isAtomic) = getStrippedPsi(pattern.data as PsiElement)
return IntermediatePrintResult(textGetterForPatterns(exprData, true), null, isAtomic, false, null)
}