in src/main/kotlin/org/arend/refactoring/changeSignature/ArendChangeSignatureUtils.kt [30:106]
fun modifyExternalParameters(oldParameters: List<ParameterDescriptor>,
newParameters: List<ParameterDescriptor>,
affectedDefinition: PsiReferable,
affectedDefinitionOldParameters: List<ParameterDescriptor>): ChangeSignatureRefactoringDescriptor? {
val relevantParameters = oldParameters.filter { !it.isExternal() && it.getReferable() != null }.map { it.getReferable() }.toSet()
var relevantSegmentStartIndex = -1
var relevantSegmentEndIndex = -1
var externalSegmentEndIndex = -1
for ((index, parameter) in affectedDefinitionOldParameters.withIndex()) {
if (parameter.isExternal()) {
if (relevantParameters.contains(parameter.getReferable())) {
if (relevantSegmentStartIndex == -1) relevantSegmentStartIndex = index
continue
}
} else {
if (externalSegmentEndIndex == -1) externalSegmentEndIndex = index
}
if (relevantSegmentStartIndex != -1) {
if (relevantSegmentEndIndex == -1) relevantSegmentEndIndex = index
}
}
if (relevantSegmentEndIndex == -1) {
if (relevantSegmentStartIndex == -1) return null
relevantSegmentEndIndex = affectedDefinitionOldParameters.size
}
if (externalSegmentEndIndex == -1) {
externalSegmentEndIndex = affectedDefinitionOldParameters.size
}
val relevantReferables = LinkedHashMap<PsiElement, ParameterDescriptor>()
affectedDefinitionOldParameters.subList(relevantSegmentStartIndex, relevantSegmentEndIndex).forEach {
relevantReferables[it.getReferable()!!] = it
}
val newRelevantSegment = ArrayList<ParameterDescriptor>()
val internalizedSegment = ArrayList<ParameterDescriptor>()
for (parameter in newParameters) if (parameter.oldParameter != null) {
val oldReferable = parameter.oldParameter.getReferable()!!
if (relevantReferables.keys.contains(oldReferable)) {
val oldParameter = relevantReferables[oldReferable]!!
val isData = oldParameter.isDataParameter
val newParameter = if (isData)
DefaultParameterDescriptorFactory.createDataParameter(oldParameter, oldParameter.getExternalScope(), parameter.getNameOrNull(), parameter.typeGetter, oldReferable as? PsiReferable) else
DefaultParameterDescriptorFactory.createNewParameter(false, oldParameter, oldParameter.getExternalScope(), parameter.getNameOrNull(), parameter.typeGetter)
newRelevantSegment.add(newParameter)
relevantReferables.remove(oldReferable)
}
}
for (entry in relevantReferables) {
val isData = entry.value.isDataParameter
val newParameter = if (isData)
DefaultParameterDescriptorFactory.createDataParameter(entry.value, null, null, entry.value.typeGetter, entry.value.oldParameter?.getReferable() as? PsiReferable) else
DefaultParameterDescriptorFactory.createNewParameter(entry.value.isExplicit, entry.value, null, null, entry.value.typeGetter)
internalizedSegment.add(newParameter)
}
val headExternalSegment = affectedDefinitionOldParameters.subList(0, relevantSegmentStartIndex)
assert (relevantSegmentEndIndex <= externalSegmentEndIndex)
val tailExternalSegment = affectedDefinitionOldParameters.subList(relevantSegmentEndIndex, externalSegmentEndIndex)
val internalSegment = affectedDefinitionOldParameters.subList(externalSegmentEndIndex, affectedDefinitionOldParameters.size)
val definitionNewSignature =
DefaultParameterDescriptorFactory.identityTransform(headExternalSegment) +
newRelevantSegment +
DefaultParameterDescriptorFactory.identityTransform(tailExternalSegment) +
internalizedSegment +
DefaultParameterDescriptorFactory.identityTransform(internalSegment)
val descriptor = ChangeSignatureRefactoringDescriptor(affectedDefinition, affectedDefinitionOldParameters, definitionNewSignature, null)
return if (descriptor.isTrivial()) null else descriptor
}