New J2K: add conversion progress bar
Relates to #KT-31812
This commit is contained in:
@@ -27,8 +27,8 @@ import kotlinx.coroutines.runBlocking
|
|||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
|
||||||
import org.jetbrains.kotlin.idea.core.util.range
|
|
||||||
import org.jetbrains.kotlin.idea.core.util.EDT
|
import org.jetbrains.kotlin.idea.core.util.EDT
|
||||||
|
import org.jetbrains.kotlin.idea.core.util.range
|
||||||
import org.jetbrains.kotlin.idea.util.ImportInsertHelper
|
import org.jetbrains.kotlin.idea.util.ImportInsertHelper
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
@@ -42,6 +42,9 @@ import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class J2kPostProcessor(private val formatCode: Boolean) : PostProcessor {
|
class J2kPostProcessor(private val formatCode: Boolean) : PostProcessor {
|
||||||
|
|
||||||
|
override val phasesCount: Int = 1
|
||||||
|
|
||||||
override fun insertImport(file: KtFile, fqName: FqName) {
|
override fun insertImport(file: KtFile, fqName: FqName) {
|
||||||
ApplicationManager.getApplication().invokeAndWait {
|
ApplicationManager.getApplication().invokeAndWait {
|
||||||
runWriteAction {
|
runWriteAction {
|
||||||
@@ -57,7 +60,12 @@ class J2kPostProcessor(private val formatCode: Boolean) : PostProcessor {
|
|||||||
PROCESS
|
PROCESS
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun doAdditionalProcessing(file: KtFile, converterContext: ConverterContext?, rangeMarker: RangeMarker?) =
|
override fun doAdditionalProcessing(
|
||||||
|
file: KtFile,
|
||||||
|
converterContext: ConverterContext?,
|
||||||
|
rangeMarker: RangeMarker?,
|
||||||
|
onPhaseChanged: ((Int, String) -> Unit)?
|
||||||
|
) =
|
||||||
runBlocking(EDT.ModalityStateElement(ModalityState.defaultModalityState())) {
|
runBlocking(EDT.ModalityStateElement(ModalityState.defaultModalityState())) {
|
||||||
do {
|
do {
|
||||||
var modificationStamp: Long? = file.modificationStamp
|
var modificationStamp: Long? = file.modificationStamp
|
||||||
|
|||||||
@@ -6,7 +6,9 @@
|
|||||||
package org.jetbrains.kotlin.idea.j2k
|
package org.jetbrains.kotlin.idea.j2k
|
||||||
|
|
||||||
import com.intellij.openapi.module.Module
|
import com.intellij.openapi.module.Module
|
||||||
|
import com.intellij.openapi.progress.ProgressIndicator
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.psi.PsiJavaFile
|
||||||
import org.jetbrains.kotlin.j2k.*
|
import org.jetbrains.kotlin.j2k.*
|
||||||
|
|
||||||
object JavaToKotlinConverterFactory {
|
object JavaToKotlinConverterFactory {
|
||||||
@@ -20,6 +22,17 @@ object JavaToKotlinConverterFactory {
|
|||||||
fun createPostProcessor(formatCode: Boolean): PostProcessor =
|
fun createPostProcessor(formatCode: Boolean): PostProcessor =
|
||||||
J2kConverterExtension.extension.createPostProcessor(formatCode)
|
J2kConverterExtension.extension.createPostProcessor(formatCode)
|
||||||
|
|
||||||
|
fun createWithProgressIndicator(
|
||||||
|
progress: ProgressIndicator?,
|
||||||
|
files: List<PsiJavaFile>?,
|
||||||
|
phasesCount: Int
|
||||||
|
): WithProgressProcessor =
|
||||||
|
J2kConverterExtension.extension.createWithProgressProcessor(progress, files, phasesCount)
|
||||||
|
|
||||||
|
|
||||||
fun doCheckBeforeConversion(project: Project, module: Module): Boolean =
|
fun doCheckBeforeConversion(project: Project, module: Module): Boolean =
|
||||||
J2kConverterExtension.extension.doCheckBeforeConversion(project, module)
|
J2kConverterExtension.extension.doCheckBeforeConversion(project, module)
|
||||||
|
|
||||||
|
val isNewJ2k: Boolean
|
||||||
|
get() = J2kConverterExtension.extension.isNewJ2k
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
package org.jetbrains.kotlin.idea.j2k
|
package org.jetbrains.kotlin.idea.j2k
|
||||||
|
|
||||||
|
import com.intellij.openapi.progress.ProgressIndicator
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.psi.PsiJavaFile
|
||||||
import org.jetbrains.kotlin.j2k.*
|
import org.jetbrains.kotlin.j2k.*
|
||||||
|
|
||||||
class OldJ2kConverterExtension : J2kConverterExtension() {
|
class OldJ2kConverterExtension : J2kConverterExtension() {
|
||||||
@@ -15,4 +17,11 @@ class OldJ2kConverterExtension : J2kConverterExtension() {
|
|||||||
|
|
||||||
override fun createPostProcessor(formatCode: Boolean): PostProcessor =
|
override fun createPostProcessor(formatCode: Boolean): PostProcessor =
|
||||||
J2kPostProcessor(formatCode)
|
J2kPostProcessor(formatCode)
|
||||||
|
|
||||||
|
override fun createWithProgressProcessor(
|
||||||
|
progress: ProgressIndicator?,
|
||||||
|
files: List<PsiJavaFile>?,
|
||||||
|
phasesCount: Int
|
||||||
|
): WithProgressProcessor =
|
||||||
|
OldWithProgressProcessor(progress, files)
|
||||||
}
|
}
|
||||||
+2
-1
@@ -257,7 +257,8 @@ class KotlinCodeFragmentFactory : CodeFragmentFactory() {
|
|||||||
.run(
|
.run(
|
||||||
convertedFragment!!,
|
convertedFragment!!,
|
||||||
conversionContext,
|
conversionContext,
|
||||||
range = null
|
range = null,
|
||||||
|
onPhaseChanged = null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
|
|||||||
+36
-7
@@ -33,8 +33,8 @@ import org.jetbrains.kotlin.idea.actions.JavaToKotlinAction
|
|||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.KotlinCopyPasteReferenceProcessor
|
import org.jetbrains.kotlin.idea.codeInsight.KotlinCopyPasteReferenceProcessor
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.KotlinReferenceData
|
import org.jetbrains.kotlin.idea.codeInsight.KotlinReferenceData
|
||||||
import org.jetbrains.kotlin.idea.core.util.start
|
|
||||||
import org.jetbrains.kotlin.idea.core.util.range
|
import org.jetbrains.kotlin.idea.core.util.range
|
||||||
|
import org.jetbrains.kotlin.idea.core.util.start
|
||||||
import org.jetbrains.kotlin.idea.editor.KotlinEditorOptions
|
import org.jetbrains.kotlin.idea.editor.KotlinEditorOptions
|
||||||
import org.jetbrains.kotlin.idea.j2k.IdeaJavaToKotlinServices
|
import org.jetbrains.kotlin.idea.j2k.IdeaJavaToKotlinServices
|
||||||
import org.jetbrains.kotlin.idea.j2k.JavaToKotlinConverterFactory
|
import org.jetbrains.kotlin.idea.j2k.JavaToKotlinConverterFactory
|
||||||
@@ -161,12 +161,7 @@ class ConvertJavaCopyPasteProcessor : CopyPastePostProcessor<TextBlockTransferab
|
|||||||
val newBounds = insertImports(boundsAfterReplace, referenceData, explicitImports)
|
val newBounds = insertImports(boundsAfterReplace, referenceData, explicitImports)
|
||||||
|
|
||||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||||
AfterConversionPass(project, JavaToKotlinConverterFactory.createPostProcessor(formatCode = true))
|
runPostProcessing(project, targetFile, newBounds, conversionResult?.converterContext)
|
||||||
.run(
|
|
||||||
targetFile,
|
|
||||||
conversionResult?.converterContext,
|
|
||||||
newBounds
|
|
||||||
)
|
|
||||||
|
|
||||||
conversionPerformed = true
|
conversionPerformed = true
|
||||||
}
|
}
|
||||||
@@ -304,3 +299,37 @@ internal fun confirmConvertJavaOnPaste(project: Project, isPlainText: Boolean):
|
|||||||
return dialog.isOK
|
return dialog.isOK
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun runPostProcessing(project: Project, file: KtFile, bounds: TextRange?, converterContext: ConverterContext?) {
|
||||||
|
val postProcessor = JavaToKotlinConverterFactory.createPostProcessor(formatCode = true)
|
||||||
|
if (JavaToKotlinConverterFactory.isNewJ2k) {
|
||||||
|
ProgressManager.getInstance().runProcessWithProgressSynchronously(
|
||||||
|
{
|
||||||
|
val processor =
|
||||||
|
JavaToKotlinConverterFactory.createWithProgressIndicator(
|
||||||
|
ProgressManager.getInstance().progressIndicator!!,
|
||||||
|
emptyList(),
|
||||||
|
postProcessor.phasesCount
|
||||||
|
)
|
||||||
|
AfterConversionPass(project, postProcessor)
|
||||||
|
.run(
|
||||||
|
file,
|
||||||
|
converterContext,
|
||||||
|
bounds
|
||||||
|
) { phase, description ->
|
||||||
|
processor.updateState(0, phase, description)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Convert Java to Kotlin",
|
||||||
|
true,
|
||||||
|
project
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
AfterConversionPass(project, postProcessor)
|
||||||
|
.run(
|
||||||
|
file,
|
||||||
|
converterContext,
|
||||||
|
bounds
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-8
@@ -36,9 +36,7 @@ import org.jetbrains.annotations.TestOnly
|
|||||||
import org.jetbrains.kotlin.asJava.toLightClass
|
import org.jetbrains.kotlin.asJava.toLightClass
|
||||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||||
import org.jetbrains.kotlin.idea.editor.KotlinEditorOptions
|
import org.jetbrains.kotlin.idea.editor.KotlinEditorOptions
|
||||||
import org.jetbrains.kotlin.idea.j2k.JavaToKotlinConverterFactory
|
|
||||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
import org.jetbrains.kotlin.j2k.AfterConversionPass
|
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
|
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
|
||||||
@@ -130,12 +128,7 @@ class ConvertTextJavaCopyPasteProcessor : CopyPastePostProcessor<TextBlockTransf
|
|||||||
}
|
}
|
||||||
|
|
||||||
psiDocumentManager.commitAllDocuments()
|
psiDocumentManager.commitAllDocuments()
|
||||||
AfterConversionPass(project, JavaToKotlinConverterFactory.createPostProcessor(formatCode = true))
|
runPostProcessing(project, targetFile, newBounds, convertedResult.converterContext)
|
||||||
.run(
|
|
||||||
targetFile,
|
|
||||||
convertedResult.converterContext,
|
|
||||||
newBounds
|
|
||||||
)
|
|
||||||
|
|
||||||
conversionPerformed = true
|
conversionPerformed = true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,20 +18,25 @@ package org.jetbrains.kotlin.j2k
|
|||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.util.TextRange
|
import com.intellij.openapi.util.TextRange
|
||||||
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
|
||||||
class AfterConversionPass(val project: Project, val postProcessor: PostProcessor) {
|
class AfterConversionPass(val project: Project, val postProcessor: PostProcessor) {
|
||||||
fun run(kotlinFile: KtFile, converterContext: ConverterContext?, range: TextRange?) {
|
@JvmOverloads
|
||||||
|
fun run(
|
||||||
|
kotlinFile: KtFile,
|
||||||
|
converterContext: ConverterContext?,
|
||||||
|
range: TextRange?,
|
||||||
|
onPhaseChanged: ((Int, String) -> Unit)? = null
|
||||||
|
) {
|
||||||
val rangeMarker = if (range != null) {
|
val rangeMarker = if (range != null) {
|
||||||
val document = kotlinFile.viewProvider.document!!
|
val document = kotlinFile.viewProvider.document!!
|
||||||
val marker = document.createRangeMarker(range.startOffset, range.endOffset)
|
val marker = runReadAction { document.createRangeMarker(range.startOffset, range.endOffset) }
|
||||||
marker.isGreedyToLeft = true
|
marker.isGreedyToLeft = true
|
||||||
marker.isGreedyToRight = true
|
marker.isGreedyToRight = true
|
||||||
marker
|
marker
|
||||||
} else {
|
} else null
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
postProcessor.doAdditionalProcessing(kotlinFile, converterContext, rangeMarker)
|
postProcessor.doAdditionalProcessing(kotlinFile, converterContext, rangeMarker, onPhaseChanged)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,10 @@ package org.jetbrains.kotlin.j2k
|
|||||||
import com.intellij.openapi.extensions.AbstractExtensionPointBean
|
import com.intellij.openapi.extensions.AbstractExtensionPointBean
|
||||||
import com.intellij.openapi.extensions.ExtensionPointName
|
import com.intellij.openapi.extensions.ExtensionPointName
|
||||||
import com.intellij.openapi.module.Module
|
import com.intellij.openapi.module.Module
|
||||||
|
import com.intellij.openapi.progress.ProgressIndicator
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.util.registry.Registry
|
import com.intellij.openapi.util.registry.Registry
|
||||||
|
import com.intellij.psi.PsiJavaFile
|
||||||
|
|
||||||
abstract class J2kConverterExtension : AbstractExtensionPointBean() {
|
abstract class J2kConverterExtension : AbstractExtensionPointBean() {
|
||||||
abstract val isNewJ2k: Boolean
|
abstract val isNewJ2k: Boolean
|
||||||
@@ -20,6 +22,12 @@ abstract class J2kConverterExtension : AbstractExtensionPointBean() {
|
|||||||
open fun doCheckBeforeConversion(project: Project, module: Module): Boolean =
|
open fun doCheckBeforeConversion(project: Project, module: Module): Boolean =
|
||||||
true
|
true
|
||||||
|
|
||||||
|
abstract fun createWithProgressProcessor(
|
||||||
|
progress: ProgressIndicator?,
|
||||||
|
files: List<PsiJavaFile>?,
|
||||||
|
phasesCount: Int
|
||||||
|
): WithProgressProcessor
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private fun useNewJ2k() = Registry.`is`("kotlin.use.new.j2k", false)
|
private fun useNewJ2k() = Registry.`is`("kotlin.use.new.j2k", false)
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,14 @@ import java.util.*
|
|||||||
interface PostProcessor {
|
interface PostProcessor {
|
||||||
fun insertImport(file: KtFile, fqName: FqName)
|
fun insertImport(file: KtFile, fqName: FqName)
|
||||||
|
|
||||||
fun doAdditionalProcessing(file: KtFile, converterContext: ConverterContext?, rangeMarker: RangeMarker?)
|
val phasesCount: Int
|
||||||
|
|
||||||
|
fun doAdditionalProcessing(
|
||||||
|
file: KtFile,
|
||||||
|
converterContext: ConverterContext?,
|
||||||
|
rangeMarker: RangeMarker?,
|
||||||
|
onPhaseChanged: ((Int, String) -> Unit)?
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class ParseContext {
|
enum class ParseContext {
|
||||||
@@ -73,9 +80,7 @@ abstract class JavaToKotlinConverter {
|
|||||||
progress: ProgressIndicator = EmptyProgressIndicator()
|
progress: ProgressIndicator = EmptyProgressIndicator()
|
||||||
): FilesResult
|
): FilesResult
|
||||||
|
|
||||||
fun elementsToKotlin(inputElements: List<PsiElement>): Result {
|
abstract fun elementsToKotlin(inputElements: List<PsiElement>): Result
|
||||||
return elementsToKotlin(inputElements, WithProgressProcessor.DEFAULT)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class OldJavaToKotlinConverter(
|
class OldJavaToKotlinConverter(
|
||||||
@@ -91,7 +96,7 @@ class OldJavaToKotlinConverter(
|
|||||||
postProcessor: PostProcessor,
|
postProcessor: PostProcessor,
|
||||||
progress: ProgressIndicator
|
progress: ProgressIndicator
|
||||||
): FilesResult {
|
): FilesResult {
|
||||||
val withProgressProcessor = WithProgressProcessor(progress, files)
|
val withProgressProcessor = OldWithProgressProcessor(progress, files)
|
||||||
val (results, externalCodeProcessing) = ApplicationManager.getApplication().runReadAction(Computable {
|
val (results, externalCodeProcessing) = ApplicationManager.getApplication().runReadAction(Computable {
|
||||||
elementsToKotlin(files, withProgressProcessor)
|
elementsToKotlin(files, withProgressProcessor)
|
||||||
})
|
})
|
||||||
@@ -106,7 +111,7 @@ class OldJavaToKotlinConverter(
|
|||||||
|
|
||||||
result!!.importsToAdd.forEach { postProcessor.insertImport(kotlinFile, it) }
|
result!!.importsToAdd.forEach { postProcessor.insertImport(kotlinFile, it) }
|
||||||
|
|
||||||
AfterConversionPass(project, postProcessor).run(kotlinFile, converterContext = null, range = null)
|
AfterConversionPass(project, postProcessor).run(kotlinFile, converterContext = null, range = null, onPhaseChanged = null)
|
||||||
|
|
||||||
kotlinFile.text
|
kotlinFile.text
|
||||||
} catch (e: ProcessCanceledException) {
|
} catch (e: ProcessCanceledException) {
|
||||||
@@ -157,6 +162,11 @@ class OldJavaToKotlinConverter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun elementsToKotlin(inputElements: List<PsiElement>): Result {
|
||||||
|
return elementsToKotlin(inputElements, OldWithProgressProcessor.DEFAULT)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private data class ReferenceInfo(
|
private data class ReferenceInfo(
|
||||||
val reference: PsiReference,
|
val reference: PsiReference,
|
||||||
val target: PsiElement,
|
val target: PsiElement,
|
||||||
@@ -252,10 +262,21 @@ class OldJavaToKotlinConverter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface WithProgressProcessor {
|
||||||
|
fun <TInputItem, TOutputItem> processItems(
|
||||||
|
fractionPortion: Double,
|
||||||
|
inputItems: Iterable<TInputItem>,
|
||||||
|
processItem: (TInputItem) -> TOutputItem
|
||||||
|
): List<TOutputItem>
|
||||||
|
|
||||||
class WithProgressProcessor(private val progress: ProgressIndicator?, private val files: List<PsiJavaFile>?) {
|
fun updateState(fileIndex: Int, phase: Int, description: String)
|
||||||
|
fun <T> process(action: () -> T): T
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class OldWithProgressProcessor(private val progress: ProgressIndicator?, private val files: List<PsiJavaFile>?) : WithProgressProcessor {
|
||||||
companion object {
|
companion object {
|
||||||
val DEFAULT = WithProgressProcessor(null, null)
|
val DEFAULT = OldWithProgressProcessor(null, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val progressText = "Converting Java to Kotlin"
|
private val progressText = "Converting Java to Kotlin"
|
||||||
@@ -264,7 +285,7 @@ class WithProgressProcessor(private val progress: ProgressIndicator?, private va
|
|||||||
private var fraction = 0.0
|
private var fraction = 0.0
|
||||||
private var pass = 1
|
private var pass = 1
|
||||||
|
|
||||||
fun <TInputItem, TOutputItem> processItems(
|
override fun <TInputItem, TOutputItem> processItems(
|
||||||
fractionPortion: Double,
|
fractionPortion: Double,
|
||||||
inputItems: Iterable<TInputItem>,
|
inputItems: Iterable<TInputItem>,
|
||||||
processItem: (TInputItem) -> TOutputItem
|
processItem: (TInputItem) -> TOutputItem
|
||||||
@@ -291,6 +312,14 @@ class WithProgressProcessor(private val progress: ProgressIndicator?, private va
|
|||||||
)
|
)
|
||||||
return outputItems
|
return outputItems
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun <T> process(action: () -> T): T {
|
||||||
|
throw AbstractMethodError("Should not be called for old J2K")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateState(fileIndex: Int, phase: Int, description: String) {
|
||||||
|
throw AbstractMethodError("Should not be called for old J2K")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ProgressPortionReporter(
|
private class ProgressPortionReporter(
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
package org.jetbrains.kotlin.nj2k
|
package org.jetbrains.kotlin.nj2k
|
||||||
|
|
||||||
import com.intellij.openapi.module.Module
|
import com.intellij.openapi.module.Module
|
||||||
|
import com.intellij.openapi.progress.ProgressIndicator
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.ui.Messages
|
import com.intellij.openapi.ui.Messages
|
||||||
|
import com.intellij.psi.PsiJavaFile
|
||||||
import org.jetbrains.kotlin.idea.configuration.getAbleToRunConfigurators
|
import org.jetbrains.kotlin.idea.configuration.getAbleToRunConfigurators
|
||||||
import org.jetbrains.kotlin.idea.configuration.hasAnyKotlinRuntimeInScope
|
import org.jetbrains.kotlin.idea.configuration.hasAnyKotlinRuntimeInScope
|
||||||
import org.jetbrains.kotlin.idea.configuration.isModuleConfigured
|
import org.jetbrains.kotlin.idea.configuration.isModuleConfigured
|
||||||
@@ -27,6 +29,13 @@ class NewJ2kConverterExtension : J2kConverterExtension() {
|
|||||||
override fun doCheckBeforeConversion(project: Project, module: Module): Boolean =
|
override fun doCheckBeforeConversion(project: Project, module: Module): Boolean =
|
||||||
checkKotlinIsConfigured(project, module)
|
checkKotlinIsConfigured(project, module)
|
||||||
|
|
||||||
|
override fun createWithProgressProcessor(
|
||||||
|
progress: ProgressIndicator?,
|
||||||
|
files: List<PsiJavaFile>?,
|
||||||
|
phasesCount: Int
|
||||||
|
): WithProgressProcessor =
|
||||||
|
NewJ2kWithProgressProcessor(progress, files, phasesCount)
|
||||||
|
|
||||||
private fun checkKotlinIsConfigured(project: Project, module: Module): Boolean {
|
private fun checkKotlinIsConfigured(project: Project, module: Module): Boolean {
|
||||||
val kotlinIsConfigured =
|
val kotlinIsConfigured =
|
||||||
hasAnyKotlinRuntimeInScope(module) || isModuleConfigured(module.toModuleGroup())
|
hasAnyKotlinRuntimeInScope(module) || isModuleConfigured(module.toModuleGroup())
|
||||||
|
|||||||
+17
-4
@@ -58,9 +58,17 @@ class NewJ2kPostProcessor : PostProcessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun doAdditionalProcessing(file: KtFile, converterContext: ConverterContext?, rangeMarker: RangeMarker?) {
|
override val phasesCount = processings.size
|
||||||
|
|
||||||
|
override fun doAdditionalProcessing(
|
||||||
|
file: KtFile,
|
||||||
|
converterContext: ConverterContext?,
|
||||||
|
rangeMarker: RangeMarker?,
|
||||||
|
onPhaseChanged: ((Int, String) -> Unit)?
|
||||||
|
) {
|
||||||
runBlocking(EDT.ModalityStateElement(ModalityState.defaultModalityState())) {
|
runBlocking(EDT.ModalityStateElement(ModalityState.defaultModalityState())) {
|
||||||
for (processing in processings) {
|
for ((i, processing) in processings.withIndex()) {
|
||||||
|
onPhaseChanged?.invoke(i, processing.description)
|
||||||
processing.runProcessing(file, rangeMarker, converterContext as NewJ2kConverterContext)
|
processing.runProcessing(file, rangeMarker, converterContext as NewJ2kConverterContext)
|
||||||
commitFile(file)
|
commitFile(file)
|
||||||
}
|
}
|
||||||
@@ -82,15 +90,20 @@ private val processings: List<GeneralPostProcessing> = listOf(
|
|||||||
nullabilityProcessing,
|
nullabilityProcessing,
|
||||||
formatCodeProcessing,
|
formatCodeProcessing,
|
||||||
shortenReferencesProcessing,
|
shortenReferencesProcessing,
|
||||||
InspectionLikeProcessingGroup(VarToValProcessing()),
|
InspectionLikeProcessingGroup(ConvertGettersAndSettersToPropertyProcessing.DESCRIPTION, VarToValProcessing()),
|
||||||
ConvertGettersAndSettersToPropertyProcessing(),
|
ConvertGettersAndSettersToPropertyProcessing(),
|
||||||
InspectionLikeProcessingGroup(MoveGetterAndSetterAnnotationsToPropertyProcessing()),
|
|
||||||
InspectionLikeProcessingGroup(
|
InspectionLikeProcessingGroup(
|
||||||
|
ConvertGettersAndSettersToPropertyProcessing.DESCRIPTION,
|
||||||
|
MoveGetterAndSetterAnnotationsToPropertyProcessing()
|
||||||
|
),
|
||||||
|
InspectionLikeProcessingGroup(
|
||||||
|
ConvertGettersAndSettersToPropertyProcessing.DESCRIPTION,
|
||||||
generalInspectionBasedProcessing(RedundantGetterInspection()),
|
generalInspectionBasedProcessing(RedundantGetterInspection()),
|
||||||
generalInspectionBasedProcessing(RedundantSetterInspection())
|
generalInspectionBasedProcessing(RedundantSetterInspection())
|
||||||
),
|
),
|
||||||
ConvertToDataClassProcessing(),
|
ConvertToDataClassProcessing(),
|
||||||
InspectionLikeProcessingGroup(
|
InspectionLikeProcessingGroup(
|
||||||
|
"Cleaning up Kotlin code",
|
||||||
RemoveRedundantVisibilityModifierProcessing(),
|
RemoveRedundantVisibilityModifierProcessing(),
|
||||||
RemoveRedundantModalityModifierProcessing(),
|
RemoveRedundantModalityModifierProcessing(),
|
||||||
RemoveRedundantConstructorKeywordProcessing(),
|
RemoveRedundantConstructorKeywordProcessing(),
|
||||||
|
|||||||
+10
-5
@@ -16,8 +16,8 @@ import kotlinx.coroutines.withContext
|
|||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
|
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||||
import org.jetbrains.kotlin.idea.core.util.range
|
|
||||||
import org.jetbrains.kotlin.idea.core.util.EDT
|
import org.jetbrains.kotlin.idea.core.util.EDT
|
||||||
|
import org.jetbrains.kotlin.idea.core.util.range
|
||||||
import org.jetbrains.kotlin.idea.formatter.commitAndUnblockDocument
|
import org.jetbrains.kotlin.idea.formatter.commitAndUnblockDocument
|
||||||
import org.jetbrains.kotlin.idea.inspections.AbstractApplicabilityBasedInspection
|
import org.jetbrains.kotlin.idea.inspections.AbstractApplicabilityBasedInspection
|
||||||
import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection
|
import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection
|
||||||
@@ -28,7 +28,7 @@ import org.jetbrains.kotlin.idea.quickfix.QuickFixActionBase
|
|||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
import org.jetbrains.kotlin.j2k.ConverterSettings
|
import org.jetbrains.kotlin.j2k.ConverterSettings
|
||||||
import org.jetbrains.kotlin.nj2k.*
|
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.elementsInRange
|
import org.jetbrains.kotlin.psi.psiUtil.elementsInRange
|
||||||
@@ -36,13 +36,18 @@ import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
|||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
||||||
import org.jetbrains.kotlin.utils.mapToIndex
|
import org.jetbrains.kotlin.utils.mapToIndex
|
||||||
import java.util.ArrayList
|
import java.util.*
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
import kotlin.reflect.full.isSubclassOf
|
import kotlin.reflect.full.isSubclassOf
|
||||||
|
|
||||||
|
|
||||||
class InspectionLikeProcessingGroup(val inspectionLikeProcessings: List<InspectionLikeProcessing>) : ProcessingGroup {
|
class InspectionLikeProcessingGroup(
|
||||||
constructor(vararg inspectionLikeProcessings: InspectionLikeProcessing) : this(inspectionLikeProcessings.toList())
|
override val description: String,
|
||||||
|
val inspectionLikeProcessings: List<InspectionLikeProcessing>
|
||||||
|
) : ProcessingGroup {
|
||||||
|
|
||||||
|
constructor(description: String, vararg inspectionLikeProcessings: InspectionLikeProcessing) :
|
||||||
|
this(description, inspectionLikeProcessings.toList())
|
||||||
|
|
||||||
private val processingsToPriorityMap = inspectionLikeProcessings.mapToIndex()
|
private val processingsToPriorityMap = inspectionLikeProcessings.mapToIndex()
|
||||||
fun priority(processing: InspectionLikeProcessing): Int = processingsToPriorityMap.getValue(processing)
|
fun priority(processing: InspectionLikeProcessing): Int = processingsToPriorityMap.getValue(processing)
|
||||||
|
|||||||
@@ -18,10 +18,11 @@ import org.jetbrains.kotlin.psi.psiUtil.elementsInRange
|
|||||||
|
|
||||||
|
|
||||||
interface GeneralPostProcessing {
|
interface GeneralPostProcessing {
|
||||||
|
val description: String
|
||||||
suspend fun runProcessing(file: KtFile, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext)
|
suspend fun runProcessing(file: KtFile, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class SimplePostProcessing : GeneralPostProcessing {
|
abstract class SimplePostProcessing(override val description: String) : GeneralPostProcessing {
|
||||||
final override suspend fun runProcessing(file: KtFile, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
final override suspend fun runProcessing(file: KtFile, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
||||||
withContext(EDT) {
|
withContext(EDT) {
|
||||||
CommandProcessor.getInstance().runUndoTransparentAction {
|
CommandProcessor.getInstance().runUndoTransparentAction {
|
||||||
@@ -35,7 +36,7 @@ abstract class SimplePostProcessing : GeneralPostProcessing {
|
|||||||
abstract fun applySimpleProcessing(file: KtFile, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext)
|
abstract fun applySimpleProcessing(file: KtFile, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class ElementsBasedPostProcessing : SimplePostProcessing() {
|
abstract class ElementsBasedPostProcessing(description: String) : SimplePostProcessing(description) {
|
||||||
final override fun applySimpleProcessing(file: KtFile, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
final override fun applySimpleProcessing(file: KtFile, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
||||||
val elements =
|
val elements =
|
||||||
rangeMarker?.let { marker ->
|
rangeMarker?.let { marker ->
|
||||||
@@ -49,8 +50,11 @@ abstract class ElementsBasedPostProcessing : SimplePostProcessing() {
|
|||||||
|
|
||||||
interface ProcessingGroup : GeneralPostProcessing
|
interface ProcessingGroup : GeneralPostProcessing
|
||||||
|
|
||||||
fun postProcessing(action: (file: KtFile, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) -> Unit): GeneralPostProcessing =
|
fun postProcessing(
|
||||||
object : SimplePostProcessing() {
|
description: String,
|
||||||
|
action: (file: KtFile, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) -> Unit
|
||||||
|
): GeneralPostProcessing =
|
||||||
|
object : SimplePostProcessing(description) {
|
||||||
override fun applySimpleProcessing(file: KtFile, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
override fun applySimpleProcessing(file: KtFile, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
||||||
action(file, rangeMarker, converterContext)
|
action(file, rangeMarker, converterContext)
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-4
@@ -11,7 +11,10 @@ import com.intellij.psi.search.searches.OverridingMethodsSearch
|
|||||||
import com.intellij.psi.search.searches.ReferencesSearch
|
import com.intellij.psi.search.searches.ReferencesSearch
|
||||||
import com.intellij.refactoring.rename.RenamePsiElementProcessor
|
import com.intellij.refactoring.rename.RenamePsiElementProcessor
|
||||||
import org.jetbrains.kotlin.asJava.toLightMethods
|
import org.jetbrains.kotlin.asJava.toLightMethods
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||||
import org.jetbrains.kotlin.idea.core.setVisibility
|
import org.jetbrains.kotlin.idea.core.setVisibility
|
||||||
import org.jetbrains.kotlin.idea.refactoring.isAbstract
|
import org.jetbrains.kotlin.idea.refactoring.isAbstract
|
||||||
@@ -21,11 +24,13 @@ import org.jetbrains.kotlin.idea.references.mainReference
|
|||||||
import org.jetbrains.kotlin.idea.references.readWriteAccess
|
import org.jetbrains.kotlin.idea.references.readWriteAccess
|
||||||
import org.jetbrains.kotlin.idea.util.CommentSaver
|
import org.jetbrains.kotlin.idea.util.CommentSaver
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.nj2k.*
|
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||||
|
import org.jetbrains.kotlin.nj2k.asGetterName
|
||||||
|
import org.jetbrains.kotlin.nj2k.asSetterName
|
||||||
|
import org.jetbrains.kotlin.nj2k.parentOfType
|
||||||
import org.jetbrains.kotlin.nj2k.postProcessing.*
|
import org.jetbrains.kotlin.nj2k.postProcessing.*
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperclassesWithoutAny
|
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
|
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperInterfaces
|
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperInterfaces
|
||||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||||
@@ -38,7 +43,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
|||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
import org.jetbrains.kotlin.utils.mapToIndex
|
import org.jetbrains.kotlin.utils.mapToIndex
|
||||||
|
|
||||||
class ConvertGettersAndSettersToPropertyProcessing : ElementsBasedPostProcessing() {
|
class ConvertGettersAndSettersToPropertyProcessing : ElementsBasedPostProcessing(DESCRIPTION) {
|
||||||
private fun KtNamedFunction.hasOverrides(): Boolean =
|
private fun KtNamedFunction.hasOverrides(): Boolean =
|
||||||
toLightMethods().singleOrNull()?.let { lightMethod ->
|
toLightMethods().singleOrNull()?.let { lightMethod ->
|
||||||
OverridingMethodsSearch.search(lightMethod).findFirst()
|
OverridingMethodsSearch.search(lightMethod).findFirst()
|
||||||
@@ -520,6 +525,9 @@ class ConvertGettersAndSettersToPropertyProcessing : ElementsBasedPostProcessing
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
companion object {
|
||||||
|
const val DESCRIPTION = "Converting POJOs to data classes"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.psi.psiUtil.containingClass
|
|||||||
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierTypeOrDefault
|
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierTypeOrDefault
|
||||||
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
||||||
|
|
||||||
class ConvertToDataClassProcessing : ElementsBasedPostProcessing() {
|
class ConvertToDataClassProcessing : ElementsBasedPostProcessing(ConvertGettersAndSettersToPropertyProcessing.DESCRIPTION) {
|
||||||
private fun KtCallableDeclaration.rename(newName: String) {
|
private fun KtCallableDeclaration.rename(newName: String) {
|
||||||
val factory = KtPsiFactory(this)
|
val factory = KtPsiFactory(this)
|
||||||
val escapedName = newName.escaped()
|
val escapedName = newName.escaped()
|
||||||
|
|||||||
+4
-4
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.psi.KtPackageDirective
|
|||||||
import org.jetbrains.kotlin.psi.psiUtil.elementsInRange
|
import org.jetbrains.kotlin.psi.psiUtil.elementsInRange
|
||||||
|
|
||||||
val formatCodeProcessing =
|
val formatCodeProcessing =
|
||||||
postProcessing { file, rangeMarker, _ ->
|
postProcessing("Formating code") { file, rangeMarker, _ ->
|
||||||
file.commitAndUnblockDocument()
|
file.commitAndUnblockDocument()
|
||||||
val codeStyleManager = CodeStyleManager.getInstance(file.project)
|
val codeStyleManager = CodeStyleManager.getInstance(file.project)
|
||||||
if (rangeMarker != null) {
|
if (rangeMarker != null) {
|
||||||
@@ -35,7 +35,7 @@ val formatCodeProcessing =
|
|||||||
}
|
}
|
||||||
|
|
||||||
val nullabilityProcessing =
|
val nullabilityProcessing =
|
||||||
postProcessing { file, rangeMarker, converterContext ->
|
postProcessing("Inferring declarations nullability") { file, rangeMarker, converterContext ->
|
||||||
NullabilityAnalysisFacade(
|
NullabilityAnalysisFacade(
|
||||||
converterContext,
|
converterContext,
|
||||||
getTypeElementNullability = ::nullabilityByUndefinedNullabilityComment,
|
getTypeElementNullability = ::nullabilityByUndefinedNullabilityComment,
|
||||||
@@ -45,7 +45,7 @@ val nullabilityProcessing =
|
|||||||
}
|
}
|
||||||
|
|
||||||
val shortenReferencesProcessing =
|
val shortenReferencesProcessing =
|
||||||
postProcessing { file, rangeMarker, _ ->
|
postProcessing("Shortening fully-qualified references") { file, rangeMarker, _ ->
|
||||||
if (rangeMarker != null) {
|
if (rangeMarker != null) {
|
||||||
ShortenReferences.DEFAULT.process(file, rangeMarker.startOffset, rangeMarker.endOffset)
|
ShortenReferences.DEFAULT.process(file, rangeMarker.startOffset, rangeMarker.endOffset)
|
||||||
} else {
|
} else {
|
||||||
@@ -54,7 +54,7 @@ val shortenReferencesProcessing =
|
|||||||
}
|
}
|
||||||
|
|
||||||
val optimizeImportsProcessing =
|
val optimizeImportsProcessing =
|
||||||
postProcessing { file, rangeMarker, _ ->
|
postProcessing("Optimizing imports") { file, rangeMarker, _ ->
|
||||||
val elements = if (rangeMarker != null) {
|
val elements = if (rangeMarker != null) {
|
||||||
file.elementsInRange(TextRange(rangeMarker.startOffset, rangeMarker.endOffset))
|
file.elementsInRange(TextRange(rangeMarker.startOffset, rangeMarker.endOffset))
|
||||||
} else file.children.asList()
|
} else file.children.asList()
|
||||||
|
|||||||
@@ -20,8 +20,10 @@ import com.intellij.openapi.application.ApplicationManager
|
|||||||
import com.intellij.openapi.application.ModalityState
|
import com.intellij.openapi.application.ModalityState
|
||||||
import com.intellij.openapi.command.CommandProcessor
|
import com.intellij.openapi.command.CommandProcessor
|
||||||
import com.intellij.openapi.diagnostic.Logger
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
|
import com.intellij.openapi.progress.EmptyProgressIndicator
|
||||||
import com.intellij.openapi.progress.ProcessCanceledException
|
import com.intellij.openapi.progress.ProcessCanceledException
|
||||||
import com.intellij.openapi.progress.ProgressIndicator
|
import com.intellij.openapi.progress.ProgressIndicator
|
||||||
|
import com.intellij.openapi.progress.ProgressManager
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.util.Computable
|
import com.intellij.openapi.util.Computable
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
@@ -50,13 +52,15 @@ class NewJavaToKotlinConverter(
|
|||||||
postProcessor: PostProcessor,
|
postProcessor: PostProcessor,
|
||||||
progress: ProgressIndicator
|
progress: ProgressIndicator
|
||||||
): FilesResult {
|
): FilesResult {
|
||||||
val withProgressProcessor = WithProgressProcessor(progress, files)
|
val phasesCount = postProcessor.phasesCount + 1
|
||||||
val (results, externalCodeProcessing, context) = ApplicationManager.getApplication().runReadAction(Computable {
|
val withProgressProcessor = NewJ2kWithProgressProcessor(progress, files, phasesCount)
|
||||||
elementsToKotlin(files, withProgressProcessor)
|
val (results, externalCodeProcessing, context) = withProgressProcessor.process {
|
||||||
})
|
ApplicationManager.getApplication().runReadAction(Computable {
|
||||||
|
elementsToKotlin(files, withProgressProcessor)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
val texts = withProgressProcessor.processItems(0.5, results.withIndex()) { pair ->
|
val texts = results.mapIndexed { i, result ->
|
||||||
val (i, result) = pair
|
|
||||||
try {
|
try {
|
||||||
val kotlinFile = ApplicationManager.getApplication().runReadAction(Computable {
|
val kotlinFile = ApplicationManager.getApplication().runReadAction(Computable {
|
||||||
KtPsiFactory(project).createFileWithLightClassSupport("dummy.kt", result!!.text, files[i])
|
KtPsiFactory(project).createFileWithLightClassSupport("dummy.kt", result!!.text, files[i])
|
||||||
@@ -71,9 +75,15 @@ class NewJavaToKotlinConverter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
withProgressProcessor.process {
|
||||||
AfterConversionPass(project, postProcessor).run(kotlinFile, context, range = null)
|
AfterConversionPass(project, postProcessor).run(
|
||||||
|
kotlinFile,
|
||||||
|
context,
|
||||||
|
range = null,
|
||||||
|
onPhaseChanged = { phase, description ->
|
||||||
|
withProgressProcessor.updateState(i, phase + 1, description)
|
||||||
|
})
|
||||||
|
}
|
||||||
kotlinFile.text
|
kotlinFile.text
|
||||||
} catch (e: ProcessCanceledException) {
|
} catch (e: ProcessCanceledException) {
|
||||||
throw e
|
throw e
|
||||||
@@ -87,12 +97,19 @@ class NewJavaToKotlinConverter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun elementsToKotlin(inputElements: List<PsiElement>, processor: WithProgressProcessor): Result {
|
override fun elementsToKotlin(inputElements: List<PsiElement>, processor: WithProgressProcessor): Result {
|
||||||
|
@Suppress("NAME_SHADOWING")
|
||||||
|
val processor = processor as NewJ2kWithProgressProcessor
|
||||||
|
|
||||||
|
val phaseDescription = "Converting Java code to Kotlin code"
|
||||||
val symbolProvider = JKSymbolProvider()
|
val symbolProvider = JKSymbolProvider()
|
||||||
symbolProvider.preBuildTree(inputElements)
|
symbolProvider.preBuildTree(inputElements)
|
||||||
val importStorage = ImportStorage()
|
val importStorage = ImportStorage()
|
||||||
val treeBuilder = JavaToJKTreeBuilder(symbolProvider, converterServices, importStorage)
|
val treeBuilder = JavaToJKTreeBuilder(symbolProvider, converterServices, importStorage)
|
||||||
val asts = inputElements.map { element ->
|
val asts = processor.process {
|
||||||
element to treeBuilder.buildTree(element)
|
inputElements.mapIndexed { i, element ->
|
||||||
|
processor.updateState(i, 1, phaseDescription)
|
||||||
|
element to treeBuilder.buildTree(element)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val context = NewJ2kConverterContext(
|
val context = NewJ2kConverterContext(
|
||||||
@@ -102,22 +119,69 @@ class NewJavaToKotlinConverter(
|
|||||||
importStorage,
|
importStorage,
|
||||||
JKElementInfoStorage()
|
JKElementInfoStorage()
|
||||||
)
|
)
|
||||||
|
processor.process {
|
||||||
ConversionsRunner.doApply(asts.mapNotNull { it.second }, context)
|
ConversionsRunner.doApply(asts.withIndex().mapNotNull { (i, ast) ->
|
||||||
val results = asts.map { (element, ast) ->
|
processor.updateState(i, 1, phaseDescription)
|
||||||
if (ast == null) return@map null
|
ast.second
|
||||||
val code = NewCodeBuilder(context).run { printCodeOut(ast) }
|
}, context)
|
||||||
val parseContext = when (element) {
|
}
|
||||||
is PsiStatement, is PsiExpression -> ParseContext.CODE_BLOCK
|
val results = processor.process {
|
||||||
else -> ParseContext.TOP_LEVEL
|
asts.mapIndexed { i, elementWithAst ->
|
||||||
|
processor.updateState(i, 1, phaseDescription)
|
||||||
|
val (element, ast) = elementWithAst
|
||||||
|
if (ast == null) return@mapIndexed null
|
||||||
|
val code = NewCodeBuilder(context).run { printCodeOut(ast) }
|
||||||
|
val parseContext = when (element) {
|
||||||
|
is PsiStatement, is PsiExpression -> ParseContext.CODE_BLOCK
|
||||||
|
else -> ParseContext.TOP_LEVEL
|
||||||
|
}
|
||||||
|
ElementResult(
|
||||||
|
code,
|
||||||
|
importsToAdd = importStorage.getImports(),
|
||||||
|
parseContext = parseContext
|
||||||
|
)
|
||||||
}
|
}
|
||||||
ElementResult(
|
|
||||||
code,
|
|
||||||
importsToAdd = importStorage.getImports(),
|
|
||||||
parseContext = parseContext
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result(results, null, context)
|
return Result(results, null, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun elementsToKotlin(inputElements: List<PsiElement>): Result {
|
||||||
|
return elementsToKotlin(inputElements, NewJ2kWithProgressProcessor.DEFAULT)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class NewJ2kWithProgressProcessor(
|
||||||
|
private val progress: ProgressIndicator?,
|
||||||
|
private val files: List<PsiJavaFile>?,
|
||||||
|
private val phasesCount: Int
|
||||||
|
) : WithProgressProcessor {
|
||||||
|
companion object {
|
||||||
|
val DEFAULT = NewJ2kWithProgressProcessor(null, null, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateState(fileIndex: Int, phase: Int, description: String) {
|
||||||
|
progress?.checkCanceled()
|
||||||
|
progress?.fraction = phase / phasesCount.toDouble()
|
||||||
|
progress?.text = "$description - phase $phase of $phasesCount"
|
||||||
|
if (files != null && files.isNotEmpty()) {
|
||||||
|
progress?.text2 = files[fileIndex].virtualFile.presentableUrl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <TInputItem, TOutputItem> processItems(
|
||||||
|
fractionPortion: Double,
|
||||||
|
inputItems: Iterable<TInputItem>,
|
||||||
|
processItem: (TInputItem) -> TOutputItem
|
||||||
|
): List<TOutputItem> {
|
||||||
|
throw AbstractMethodError("Should not be called for new J2K")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <T> process(action: () -> T): T {
|
||||||
|
// we use special process with EmptyProgressIndicator to avoid changing text in our progress by inheritors search inside etc
|
||||||
|
var result: T? = null
|
||||||
|
ProgressManager.getInstance().runProcess({ result = action() }, EmptyProgressIndicator())
|
||||||
|
return result!!
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user