New J2K: make post-processing aware of other files which are being converted

Before post-processing was able to handle only one converting file at once
So, some conversions (like (field, getter, setter) to Kotlin property)
was not able to work when converting class hierarchy was split into
multiple files.
Also, inferring nullability for a set of files was broken

#KT-19569 fixed
#KT-34266 fixed
#KT-32518 fixed
This commit is contained in:
Ilya Kirillov
2019-10-11 00:33:10 +03:00
parent 999918d499
commit b350515237
29 changed files with 498 additions and 165 deletions
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.j2k
import com.intellij.openapi.editor.RangeMarker
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.idea.util.application.runReadAction
@@ -29,14 +30,19 @@ class AfterConversionPass(val project: Project, val postProcessor: PostProcessor
range: TextRange?,
onPhaseChanged: ((Int, String) -> Unit)? = null
) {
val rangeMarker = if (range != null) {
val document = kotlinFile.viewProvider.document!!
val marker = runReadAction { document.createRangeMarker(range.startOffset, range.endOffset) }
marker.isGreedyToLeft = true
marker.isGreedyToRight = true
marker
} else null
postProcessor.doAdditionalProcessing(kotlinFile, converterContext, rangeMarker, onPhaseChanged)
postProcessor.doAdditionalProcessing(
when {
range != null -> JKPieceOfCodePostProcessingTarget(kotlinFile, range.toRangeMarker(kotlinFile))
else -> JKMultipleFilesPostProcessingTarget(listOf(kotlinFile))
},
converterContext,
onPhaseChanged
)
}
}
fun TextRange.toRangeMarker(file: KtFile): RangeMarker =
runReadAction { file.viewProvider.document!!.createRangeMarker(startOffset, endOffset) }.apply {
isGreedyToLeft = true
isGreedyToRight = true
}
@@ -26,12 +26,15 @@ import com.intellij.openapi.util.Computable
import com.intellij.psi.*
import com.intellij.psi.impl.source.DummyHolder
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.idea.core.util.range
import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.j2k.ast.Element
import org.jetbrains.kotlin.j2k.usageProcessing.ExternalCodeProcessor
import org.jetbrains.kotlin.j2k.usageProcessing.UsageProcessing
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.psi.psiUtil.elementsInRange
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import java.util.*
@@ -43,13 +46,37 @@ interface PostProcessor {
val phasesCount: Int
fun doAdditionalProcessing(
file: KtFile,
target: JKPostProcessingTarget,
converterContext: ConverterContext?,
rangeMarker: RangeMarker?,
onPhaseChanged: ((Int, String) -> Unit)?
)
}
sealed class JKPostProcessingTarget
data class JKPieceOfCodePostProcessingTarget(
val file: KtFile,
val rangeMarker: RangeMarker
) : JKPostProcessingTarget()
data class JKMultipleFilesPostProcessingTarget(
val files: List<KtFile>
) : JKPostProcessingTarget()
fun JKPostProcessingTarget.elements() = when (this) {
is JKPieceOfCodePostProcessingTarget -> runReadAction {
val range = rangeMarker.range ?: return@runReadAction emptyList()
file.elementsInRange(range)
}
is JKMultipleFilesPostProcessingTarget -> files
}
fun JKPostProcessingTarget.files() = when (this) {
is JKPieceOfCodePostProcessingTarget -> listOf(file)
is JKMultipleFilesPostProcessingTarget -> files
}
enum class ParseContext {
TOP_LEVEL,
CODE_BLOCK
@@ -270,7 +297,7 @@ interface WithProgressProcessor {
processItem: (TInputItem) -> TOutputItem
): List<TOutputItem>
fun updateState(fileIndex: Int, phase: Int, description: String)
fun updateState(fileIndex: Int?, phase: Int, description: String)
fun <T> process(action: () -> T): T
}
@@ -318,7 +345,7 @@ class OldWithProgressProcessor(private val progress: ProgressIndicator?, private
throw AbstractMethodError("Should not be called for old J2K")
}
override fun updateState(fileIndex: Int, phase: Int, description: String) {
override fun updateState(fileIndex: Int?, phase: Int, description: String) {
throw AbstractMethodError("Should not be called for old J2K")
}
}