New J2K: Split convert file method in converters

This commit is contained in:
Ilya Kirillov
2019-04-08 18:55:00 +03:00
parent af17db5f45
commit d4f6558e8a
2 changed files with 77 additions and 51 deletions
@@ -16,23 +16,16 @@
package org.jetbrains.kotlin.j2k package org.jetbrains.kotlin.j2k
import com.intellij.codeInsight.documentation.DocumentationManager
import com.intellij.lang.java.JavaLanguage import com.intellij.lang.java.JavaLanguage
import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.command.CommandProcessor
import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.editor.Document
import com.intellij.openapi.editor.RangeMarker import com.intellij.openapi.editor.RangeMarker
import com.intellij.openapi.progress.* import com.intellij.openapi.progress.*
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.* import com.intellij.psi.*
import com.intellij.psi.impl.source.DummyHolder import com.intellij.psi.impl.source.DummyHolder
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.idea.core.util.EDT
import org.jetbrains.kotlin.j2k.ast.Element import org.jetbrains.kotlin.j2k.ast.Element
import org.jetbrains.kotlin.j2k.usageProcessing.ExternalCodeProcessor import org.jetbrains.kotlin.j2k.usageProcessing.ExternalCodeProcessor
import org.jetbrains.kotlin.j2k.usageProcessing.UsageProcessing import org.jetbrains.kotlin.j2k.usageProcessing.UsageProcessing
@@ -42,8 +35,6 @@ import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.psi.psiUtil.isAncestor import org.jetbrains.kotlin.psi.psiUtil.isAncestor
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import java.util.* import java.util.*
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
import org.jetbrains.kotlin.idea.util.application.runWriteAction
interface PostProcessor { interface PostProcessor {
@@ -69,39 +60,46 @@ data class Result(val results: List<ElementResult?>, val externalCodeProcessing:
data class FilesResult(val results: List<String>, val externalCodeProcessing: ExternalCodeProcessing?) data class FilesResult(val results: List<String>, val externalCodeProcessing: ExternalCodeProcessing?)
abstract class JavaToKotlinConverter(private val project: Project) { abstract class JavaToKotlinConverter {
protected abstract fun elementsToKotlin(inputElements: List<PsiElement>, processor: WithProgressProcessor): Result protected abstract fun elementsToKotlin(inputElements: List<PsiElement>, processor: WithProgressProcessor): Result
protected abstract fun createDummyKtFile(text: String, project: Project, context: PsiElement): KtFile abstract fun filesToKotlin(
private val LOG = Logger.getInstance("#org.jetbrains.kotlin.j2k.JavaToKotlinConverter")
fun filesToKotlin(
files: List<PsiJavaFile>, files: List<PsiJavaFile>,
postProcessor: PostProcessor, postProcessor: PostProcessor,
progress: ProgressIndicator = EmptyProgressIndicator() progress: ProgressIndicator = EmptyProgressIndicator()
): FilesResult
fun elementsToKotlin(inputElements: List<PsiElement>): Result {
return elementsToKotlin(inputElements, WithProgressProcessor.DEFAULT)
}
}
class OldJavaToKotlinConverter(
private val project: Project,
private val settings: ConverterSettings,
private val services: JavaToKotlinConverterServices
) : JavaToKotlinConverter() {
private val LOG = Logger.getInstance("#org.jetbrains.kotlin.j2k.JavaToKotlinConverter")
override fun filesToKotlin(
files: List<PsiJavaFile>,
postProcessor: PostProcessor,
progress: ProgressIndicator
): FilesResult { ): FilesResult {
val withProgressProcessor = WithProgressProcessor(progress, files) val withProgressProcessor = WithProgressProcessor(progress, files)
val (results, externalCodeProcessing) = ApplicationManager.getApplication().runReadAction(Computable { val (results, externalCodeProcessing) = ApplicationManager.getApplication().runReadAction(Computable {
elementsToKotlin(files, withProgressProcessor) elementsToKotlin(files, withProgressProcessor)
}) })
val texts = withProgressProcessor.processItems(0.5, results.withIndex()) { pair -> val texts = withProgressProcessor.processItems(0.5, results.withIndex()) { pair ->
val (i, result) = pair val (i, result) = pair
try { try {
val kotlinFile = ApplicationManager.getApplication().runReadAction(Computable { val kotlinFile = ApplicationManager.getApplication().runReadAction(Computable {
createDummyKtFile(result!!.text, project, files[i]) KtPsiFactory(project).createAnalyzableFile("dummy.kt", result!!.text, files[i])
}) })
result!!.importsToAdd.forEach { postProcessor.insertImport(kotlinFile, it) }
CommandProcessor.getInstance().runUndoTransparentAction {
runBlocking(EDT.ModalityStateElement(ModalityState.defaultModalityState())) {
withContext(EDT) {
result!!.importsToAdd.forEach {
postProcessor.insertImport(kotlinFile, it)
}
}
}
}
AfterConversionPass(project, postProcessor).run(kotlinFile, range = null) AfterConversionPass(project, postProcessor).run(kotlinFile, range = null)
@@ -117,20 +115,6 @@ abstract class JavaToKotlinConverter(private val project: Project) {
return FilesResult(texts, externalCodeProcessing) return FilesResult(texts, externalCodeProcessing)
} }
fun elementsToKotlin(inputElements: List<PsiElement>): Result {
return elementsToKotlin(inputElements, WithProgressProcessor.DEFAULT)
}
}
class OldJavaToKotlinConverter(
project: Project,
private val settings: ConverterSettings,
private val services: JavaToKotlinConverterServices
) : JavaToKotlinConverter(project) {
override fun createDummyKtFile(text: String, project: Project, context: PsiElement): KtFile =
KtPsiFactory(project).createAnalyzableFile("dummy.kt", text, context)
override fun elementsToKotlin(inputElements: List<PsiElement>, processor: WithProgressProcessor): Result { override fun elementsToKotlin(inputElements: List<PsiElement>, processor: WithProgressProcessor): Result {
try { try {
val usageProcessings = LinkedHashMap<PsiElement, MutableCollection<UsageProcessing>>() val usageProcessings = LinkedHashMap<PsiElement, MutableCollection<UsageProcessing>>()
@@ -16,34 +16,76 @@
package org.jetbrains.kotlin.nj2k package org.jetbrains.kotlin.nj2k
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.command.CommandProcessor
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Computable
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.PsiExpression import com.intellij.psi.PsiExpression
import com.intellij.psi.PsiJavaFile
import com.intellij.psi.PsiStatement import com.intellij.psi.PsiStatement
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import org.jetbrains.kotlin.idea.core.util.EDT
import org.jetbrains.kotlin.j2k.* import org.jetbrains.kotlin.j2k.*
import org.jetbrains.kotlin.nj2k.tree.JKTreeElement
import org.jetbrains.kotlin.nj2k.tree.prettyDebugPrintTree
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtPsiFactory import org.jetbrains.kotlin.psi.KtPsiFactory
class NewJavaToKotlinConverter( class NewJavaToKotlinConverter(
val project: Project, val project: Project,
val settings: ConverterSettings, val settings: ConverterSettings,
val oldConverterServices: JavaToKotlinConverterServices val oldConverterServices: JavaToKotlinConverterServices
) : JavaToKotlinConverter(project) { ) : JavaToKotlinConverter() {
val converterServices = object : NewJavaToKotlinServices { val converterServices = object : NewJavaToKotlinServices {
override val oldServices = oldConverterServices override val oldServices = oldConverterServices
} }
override fun createDummyKtFile(text: String, project: Project, context: PsiElement): KtFile = private val LOG = Logger.getInstance("#org.jetbrains.kotlin.j2k.JavaToKotlinConverter")
KtPsiFactory(project).createFileWithLightClassSupport("dummy.kt", text, context)
private fun List<JKTreeElement>.prettyPrintTrees() = buildString { override fun filesToKotlin(
for (tree in this@prettyPrintTrees) { files: List<PsiJavaFile>,
appendln() postProcessor: PostProcessor,
appendln(tree.prettyDebugPrintTree()) progress: ProgressIndicator
appendln() ): FilesResult {
val withProgressProcessor = WithProgressProcessor(progress, files)
val (results, externalCodeProcessing) = ApplicationManager.getApplication().runReadAction(Computable {
elementsToKotlin(files, withProgressProcessor)
})
val texts = withProgressProcessor.processItems(0.5, results.withIndex()) { pair ->
val (i, result) = pair
try {
val kotlinFile = ApplicationManager.getApplication().runReadAction(Computable {
KtPsiFactory(project).createFileWithLightClassSupport("dummy.kt", result!!.text, files[i])
})
runBlocking(EDT.ModalityStateElement(ModalityState.defaultModalityState())) {
withContext(EDT) {
CommandProcessor.getInstance().runUndoTransparentAction {
result!!.importsToAdd.forEach {
postProcessor.insertImport(kotlinFile, it)
}
}
}
}
CommandProcessor.getInstance().runUndoTransparentAction {
AfterConversionPass(project, postProcessor).run(kotlinFile, range = null)
}
kotlinFile.text
} catch (e: ProcessCanceledException) {
throw e
} catch (t: Throwable) {
LOG.error(t)
result!!.text
}
} }
return FilesResult(texts, externalCodeProcessing)
} }
override fun elementsToKotlin(inputElements: List<PsiElement>, processor: WithProgressProcessor): Result { override fun elementsToKotlin(inputElements: List<PsiElement>, processor: WithProgressProcessor): Result {