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