Improve J2K progress reporting
This commit is contained in:
@@ -298,6 +298,7 @@ interface WithProgressProcessor {
|
||||
): List<TOutputItem>
|
||||
|
||||
fun updateState(fileIndex: Int?, phase: Int, description: String)
|
||||
fun updateState(phase: Int, subPhase: Int, subPhaseCount: Int, fileIndex: Int?, description: String)
|
||||
fun <T> process(action: () -> T): T
|
||||
}
|
||||
|
||||
@@ -348,6 +349,16 @@ class OldWithProgressProcessor(private val progress: ProgressIndicator?, private
|
||||
override fun updateState(fileIndex: Int?, phase: Int, description: String) {
|
||||
throw AbstractMethodError("Should not be called for old J2K")
|
||||
}
|
||||
|
||||
override fun updateState(
|
||||
phase: Int,
|
||||
subPhase: Int,
|
||||
subPhaseCount: Int,
|
||||
fileIndex: Int?,
|
||||
description: String
|
||||
) {
|
||||
error("Should not be called for old J2K")
|
||||
}
|
||||
}
|
||||
|
||||
class ProgressPortionReporter(
|
||||
|
||||
@@ -54,7 +54,7 @@ class NewJ2kPostProcessor : PostProcessor {
|
||||
) {
|
||||
if (converterContext !is NewJ2kConverterContext) error("Invalid converter context for new J2K")
|
||||
for ((i, group) in processings.withIndex()) {
|
||||
onPhaseChanged?.invoke(i + 1, group.description)
|
||||
onPhaseChanged?.invoke(i, group.description)
|
||||
for (processing in group.processings) {
|
||||
try {
|
||||
processing.runProcessingConsideringOptions(target, converterContext)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
progress.text={0} - phase {1,number,#} of {2,number,#}
|
||||
subphase.progress.text={0} ({1,number,#}/{2,number,#}) - phase {3,number,#} of {4,number,#}
|
||||
progress.searching.usages.to.update=Searching usages to update...
|
||||
|
||||
phase.converting.j2k=Converting Java code to Kotlin code
|
||||
@@ -18,13 +18,13 @@ interface Conversion {
|
||||
val typeFactory: JKTypeFactory
|
||||
get() = context.typeFactory
|
||||
|
||||
fun runConversion(treeRoots: List<JKTreeElement>, context: NewJ2kConverterContext): Boolean
|
||||
fun runConversion(treeRoots: Sequence<JKTreeElement>, context: NewJ2kConverterContext): Boolean
|
||||
}
|
||||
|
||||
interface SequentialBaseConversion : Conversion {
|
||||
fun runConversion(treeRoot: JKTreeElement, context: NewJ2kConverterContext): Boolean
|
||||
|
||||
override fun runConversion(treeRoots: List<JKTreeElement>, context: NewJ2kConverterContext): Boolean {
|
||||
override fun runConversion(treeRoots: Sequence<JKTreeElement>, context: NewJ2kConverterContext): Boolean {
|
||||
return treeRoots.asSequence().map { runConversion(it, context) }.max() ?: false
|
||||
}
|
||||
}
|
||||
@@ -85,10 +85,20 @@ object ConversionsRunner {
|
||||
AddElementsInfoConversion(context)
|
||||
)
|
||||
|
||||
fun doApply(trees: List<JKTreeRoot>, context: NewJ2kConverterContext) {
|
||||
|
||||
fun doApply(
|
||||
trees: List<JKTreeRoot>,
|
||||
context: NewJ2kConverterContext,
|
||||
updateProgress: (conversionIndex: Int, conversionCount: Int, fileIndex: Int, String) -> Unit
|
||||
) {
|
||||
|
||||
val conversions = createConversions(context)
|
||||
for (conversion in conversions) {
|
||||
conversion.runConversion(trees, context)
|
||||
for ((conversionIndex, conversion) in conversions.withIndex()) {
|
||||
val treeSequence = trees.asSequence().onEachIndexed { index, _ ->
|
||||
updateProgress(conversionIndex, conversions.size, index, conversion::class.simpleName ?: "Converting...")
|
||||
}
|
||||
|
||||
conversion.runConversion(treeSequence, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,14 +52,15 @@ class NewJavaToKotlinConverter(
|
||||
|
||||
private val LOG = Logger.getInstance("#org.jetbrains.kotlin.j2k.JavaToKotlinConverter")
|
||||
|
||||
private val phasesCount = J2KConversionPhase.values().size
|
||||
|
||||
override fun filesToKotlin(
|
||||
files: List<PsiJavaFile>,
|
||||
postProcessor: PostProcessor,
|
||||
progress: ProgressIndicator
|
||||
): FilesResult {
|
||||
progress.isIndeterminate = false
|
||||
val phasesCount = postProcessor.phasesCount + 1
|
||||
val withProgressProcessor = NewJ2kWithProgressProcessor(progress, files, phasesCount)
|
||||
val withProgressProcessor = NewJ2kWithProgressProcessor(progress, files, postProcessor.phasesCount + phasesCount)
|
||||
return withProgressProcessor.process {
|
||||
val (results, externalCodeProcessing, context) =
|
||||
ApplicationManager.getApplication().runReadAction(Computable {
|
||||
@@ -69,6 +70,11 @@ class NewJavaToKotlinConverter(
|
||||
val kotlinFiles = results.mapIndexed { i, result ->
|
||||
runUndoTransparentActionInEdt(inWriteAction = true) {
|
||||
val javaFile = files[i]
|
||||
withProgressProcessor.updateState(
|
||||
fileIndex = i,
|
||||
phase = J2KConversionPhase.CREATE_FILES,
|
||||
description = "Creating files..."
|
||||
)
|
||||
KtPsiFactory(project).createFileWithLightClassSupport(
|
||||
javaFile.name.replace(".java", ".kt"),
|
||||
result!!.text,
|
||||
@@ -84,7 +90,7 @@ class NewJavaToKotlinConverter(
|
||||
JKMultipleFilesPostProcessingTarget(kotlinFiles),
|
||||
context
|
||||
) { phase, description ->
|
||||
withProgressProcessor.updateState(fileIndex = null, phase = phase + 1, description = description)
|
||||
withProgressProcessor.updateState(fileIndex = null, phase = phase + phasesCount, description = description)
|
||||
}
|
||||
FilesResult(kotlinFiles.map { it.text }, externalCodeProcessing)
|
||||
}
|
||||
@@ -103,7 +109,7 @@ class NewJavaToKotlinConverter(
|
||||
if (importList == null) {
|
||||
addImportList(createdImportList)
|
||||
} else {
|
||||
val updatedList = if(importList.firstChild != null) {
|
||||
val updatedList = if (importList.firstChild != null) {
|
||||
createdImportList.addRangeBefore(importList.firstChild, importList.lastChild, createdImportList.firstChild)
|
||||
} else createdImportList
|
||||
importList.replace(updatedList)
|
||||
@@ -149,7 +155,7 @@ class NewJavaToKotlinConverter(
|
||||
}
|
||||
|
||||
val asts = inputElements.mapIndexed { i, element ->
|
||||
processor.updateState(i, 1, phaseDescription)
|
||||
processor.updateState(i, J2KConversionPhase.BUILD_AST, phaseDescription)
|
||||
element to treeBuilder.buildTree(element, saveImports)
|
||||
}
|
||||
val inConversionContext = { element: PsiElement ->
|
||||
@@ -172,13 +178,18 @@ class NewJavaToKotlinConverter(
|
||||
externalCodeProcessing,
|
||||
languageVersion.supportsFeature(LanguageFeature.FunctionalInterfaceConversion)
|
||||
)
|
||||
ConversionsRunner.doApply(asts.withIndex().mapNotNull { (i, ast) ->
|
||||
processor.updateState(i, 1, phaseDescription)
|
||||
ast.second
|
||||
}, context)
|
||||
ConversionsRunner.doApply(asts.mapNotNull { it.second }, context) { conversionIndex, conversionCount, i, desc ->
|
||||
processor.updateState(
|
||||
J2KConversionPhase.RUN_CONVERSIONS.phaseNumber,
|
||||
conversionIndex,
|
||||
conversionCount,
|
||||
i,
|
||||
desc
|
||||
)
|
||||
}
|
||||
|
||||
val results = asts.mapIndexed { i, elementWithAst ->
|
||||
processor.updateState(i, 1, phaseDescription)
|
||||
processor.updateState(i, J2KConversionPhase.PRINT_CODE, phaseDescription)
|
||||
val (element, ast) = elementWithAst
|
||||
if (ast == null) return@mapIndexed null
|
||||
val code = JKCodeBuilder(context).run { printCodeOut(ast) }
|
||||
@@ -215,9 +226,42 @@ class NewJ2kWithProgressProcessor(
|
||||
}
|
||||
|
||||
override fun updateState(fileIndex: Int?, phase: Int, description: String) {
|
||||
if (fileIndex == null)
|
||||
updateState(phase, 1, 1, fileIndex, description)
|
||||
else
|
||||
updateState(phase, 0, 1, fileIndex, description)
|
||||
}
|
||||
|
||||
override fun updateState(
|
||||
phase: Int,
|
||||
subPhase: Int,
|
||||
subPhaseCount: Int,
|
||||
fileIndex: Int?,
|
||||
description: String
|
||||
) {
|
||||
progress?.checkCanceled()
|
||||
progress?.fraction = phase / phasesCount.toDouble()
|
||||
progress?.text = KotlinNJ2KBundle.message("progress.text", description, phase, phasesCount)
|
||||
val singlePhaseFraction = 1.0 / phasesCount.toDouble()
|
||||
val singleSubPhaseFraction = singlePhaseFraction / subPhaseCount.toDouble()
|
||||
|
||||
var resultFraction = phase * singlePhaseFraction + subPhase * singleSubPhaseFraction
|
||||
if (files != null && fileIndex != null && files.isNotEmpty()) {
|
||||
val fileFraction = singleSubPhaseFraction / files.size.toDouble()
|
||||
resultFraction += fileFraction * fileIndex
|
||||
}
|
||||
progress?.fraction = resultFraction
|
||||
|
||||
if (subPhaseCount > 1) {
|
||||
progress?.text = KotlinNJ2KBundle.message(
|
||||
"subphase.progress.text",
|
||||
description,
|
||||
subPhase,
|
||||
subPhaseCount,
|
||||
phase + 1,
|
||||
phasesCount
|
||||
)
|
||||
} else {
|
||||
progress?.text = KotlinNJ2KBundle.message("progress.text", description, phase + 1, phasesCount)
|
||||
}
|
||||
progress?.text2 = when {
|
||||
files != null && files.isNotEmpty() && fileIndex != null -> files[fileIndex].virtualFile.presentableUrl + if (files.size > 1) " ($fileIndex/${files.size})" else ""
|
||||
else -> ""
|
||||
@@ -238,4 +282,15 @@ class NewJ2kWithProgressProcessor(
|
||||
return result!!
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal fun WithProgressProcessor.updateState(fileIndex: Int?, phase: J2KConversionPhase, description: String) {
|
||||
updateState(fileIndex, phase.phaseNumber, description)
|
||||
}
|
||||
|
||||
internal enum class J2KConversionPhase(val phaseNumber: Int) {
|
||||
BUILD_AST(0),
|
||||
RUN_CONVERSIONS(1),
|
||||
PRINT_CODE(2),
|
||||
CREATE_FILES(3)
|
||||
}
|
||||
Reference in New Issue
Block a user