JavaToKotlinAction converts all files at once with cross usage processing

This commit is contained in:
Valentin Kipyatkov
2014-10-21 13:53:35 +04:00
committed by valentin
parent f100015e58
commit 927fe9d2cb
6 changed files with 27 additions and 31 deletions
@@ -26,7 +26,6 @@ import org.jetbrains.jet.j2k.ConverterSettings
import org.jetbrains.jet.j2k.FilesConversionScope import org.jetbrains.jet.j2k.FilesConversionScope
import org.jetbrains.jet.j2k.IdeaReferenceSearcher import org.jetbrains.jet.j2k.IdeaReferenceSearcher
import org.jetbrains.jet.j2k.JavaToKotlinConverter import org.jetbrains.jet.j2k.JavaToKotlinConverter
import java.util.LinkedList
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.PsiJavaFile import com.intellij.psi.PsiJavaFile
import com.intellij.psi.PsiManager import com.intellij.psi.PsiManager
@@ -35,10 +34,7 @@ import com.intellij.openapi.application.ApplicationManager
import com.intellij.psi.codeStyle.CodeStyleManager import com.intellij.psi.codeStyle.CodeStyleManager
import java.io.IOException import java.io.IOException
import com.intellij.openapi.ui.ex.MessagesEx import com.intellij.openapi.ui.ex.MessagesEx
import com.intellij.psi.PsiFile
import org.jetbrains.jet.plugin.j2k.J2kPostProcessor import org.jetbrains.jet.plugin.j2k.J2kPostProcessor
import com.intellij.psi.PsiElement
import org.jetbrains.jet.j2k.PostProcessor
import com.intellij.openapi.vfs.CharsetToolkit import com.intellij.openapi.vfs.CharsetToolkit
import org.jetbrains.jet.lang.psi.JetFile import org.jetbrains.jet.lang.psi.JetFile
@@ -49,10 +45,9 @@ public class JavaToKotlinAction : AnAction() {
val selectedJavaFiles = allJavaFiles(virtualFiles, project) val selectedJavaFiles = allJavaFiles(virtualFiles, project)
if (selectedJavaFiles.isEmpty()) return if (selectedJavaFiles.isEmpty()) return
val converter = JavaToKotlinConverter(project, ConverterSettings.defaultSettings, FilesConversionScope(selectedJavaFiles), IdeaReferenceSearcher)
CommandProcessor.getInstance().executeCommand(project, object : Runnable { CommandProcessor.getInstance().executeCommand(project, object : Runnable {
override fun run() { override fun run() {
val newFiles = convertFiles(converter, selectedJavaFiles) val newFiles = convertFiles(selectedJavaFiles, project)
deleteFiles(selectedJavaFiles) deleteFiles(selectedJavaFiles)
reformatFiles(newFiles, project) reformatFiles(newFiles, project)
@@ -109,11 +104,15 @@ public class JavaToKotlinAction : AnAction() {
} }
} }
private fun convertFiles(converter: JavaToKotlinConverter, javaFiles: List<PsiJavaFile>): List<VirtualFile> { private fun convertFiles(javaFiles: List<PsiJavaFile>, project: Project): List<VirtualFile> {
val converter = JavaToKotlinConverter(project, ConverterSettings.defaultSettings, FilesConversionScope(javaFiles), IdeaReferenceSearcher)
val convertedTexts = converter.elementsToKotlin(javaFiles.map { it to J2kPostProcessor(it) })
val result = ArrayList<VirtualFile>() val result = ArrayList<VirtualFile>()
for (psiFile in javaFiles) { for ((i, psiFile) in javaFiles.withIndices()) {
ApplicationManager.getApplication().runWriteAction { ApplicationManager.getApplication().runWriteAction {
val file = convertOneFile(converter, psiFile) val file = saveConversionResult(psiFile.getVirtualFile(), convertedTexts[i], project)
if (file != null) { if (file != null) {
result.add(file) result.add(file)
} }
@@ -122,6 +121,18 @@ public class JavaToKotlinAction : AnAction() {
return result return result
} }
private fun saveConversionResult(javaFile: VirtualFile, text: String, project: Project): VirtualFile? {
try {
val kotlinFile = javaFile.copy(this, javaFile.getParent(), javaFile.getNameWithoutExtension() + ".kt")
kotlinFile.setBinaryContent(CharsetToolkit.getUtf8Bytes(text))
return kotlinFile
}
catch (e: IOException) {
MessagesEx.error(project, e.getMessage()).showLater()
return null
}
}
private fun deleteFiles(javaFiles: List<PsiJavaFile>) { private fun deleteFiles(javaFiles: List<PsiJavaFile>) {
for (psiFile in javaFiles) { for (psiFile in javaFiles) {
ApplicationManager.getApplication().runWriteAction { ApplicationManager.getApplication().runWriteAction {
@@ -134,19 +145,4 @@ public class JavaToKotlinAction : AnAction() {
} }
} }
} }
private fun convertOneFile(converter: JavaToKotlinConverter, psiFile: PsiJavaFile): VirtualFile? {
try {
val virtualFile = psiFile.getVirtualFile()!!
val postProcessor = J2kPostProcessor(psiFile)
val result = converter.elementsToKotlin(Pair<PsiElement, PostProcessor>(psiFile, postProcessor)).get(0) //TODO: convert all files in one call!
val kotlinFile = virtualFile.copy(this, virtualFile.getParent(), virtualFile.getNameWithoutExtension() + ".kt")
kotlinFile.setBinaryContent(CharsetToolkit.getUtf8Bytes(result))
return kotlinFile
}
catch (e: IOException) {
MessagesEx.error(psiFile.getProject(), e.getMessage()).showLater()
return null
}
}
} }
@@ -120,7 +120,7 @@ public class ConvertJavaCopyPastePostProcessor() : CopyPastePostProcessor<TextBl
val elementToConvert = findTopMostParentWhollyInRange(currentRange, leafElement) val elementToConvert = findTopMostParentWhollyInRange(currentRange, leafElement)
val unconvertedPrefix = fileText.substring(currentRange.start, elementToConvert.range.start) val unconvertedPrefix = fileText.substring(currentRange.start, elementToConvert.range.start)
result.append(unconvertedPrefix) result.append(unconvertedPrefix)
val converted = converter.elementsToKotlin(elementToConvert to J2kPostProcessor(fileCopiedTo))[0] val converted = converter.elementsToKotlin(listOf(elementToConvert to J2kPostProcessor(fileCopiedTo)))[0]
if (converted.isNotEmpty()) { if (converted.isNotEmpty()) {
result.append(converted) result.append(converted)
} }
@@ -47,7 +47,7 @@ public class JavaToKotlinConverter(private val project: Project,
private val referenceSearcher: ReferenceSearcher) { private val referenceSearcher: ReferenceSearcher) {
private val LOG = Logger.getInstance("#org.jetbrains.jet.j2k.JavaToKotlinConverter") private val LOG = Logger.getInstance("#org.jetbrains.jet.j2k.JavaToKotlinConverter")
public fun elementsToKotlin(vararg psiElementsAndProcessors: Pair<PsiElement, PostProcessor?>): List<String> { public fun elementsToKotlin(psiElementsAndProcessors: List<Pair<PsiElement, PostProcessor?>>): List<String> {
try { try {
val intermediateResults = ArrayList<Converter.IntermediateResult?>(psiElementsAndProcessors.size) val intermediateResults = ArrayList<Converter.IntermediateResult?>(psiElementsAndProcessors.size)
val usageProcessings = ArrayList<UsageProcessing>() val usageProcessings = ArrayList<UsageProcessing>()
@@ -89,7 +89,7 @@ public class JavaToKotlinConverter(private val project: Project,
// if we got this exception then we need to turn element creation stack traces on to get better diagnostic // if we got this exception then we need to turn element creation stack traces on to get better diagnostic
Element.saveCreationStacktraces = true Element.saveCreationStacktraces = true
try { try {
return elementsToKotlin(*psiElementsAndProcessors) return elementsToKotlin(psiElementsAndProcessors)
} }
finally { finally {
Element.saveCreationStacktraces = false Element.saveCreationStacktraces = false
@@ -91,7 +91,7 @@ public object JavaToKotlinTranslator {
val file = createFile(javaCode) val file = createFile(javaCode)
if (file is PsiJavaFile) { if (file is PsiJavaFile) {
val converter = JavaToKotlinConverter(file.getProject(), ConverterSettings.defaultSettings, FilesConversionScope(listOf(file)), EmptyReferenceSearcher) val converter = JavaToKotlinConverter(file.getProject(), ConverterSettings.defaultSettings, FilesConversionScope(listOf(file)), EmptyReferenceSearcher)
return prettify(converter.elementsToKotlin(file to null)[0]) return prettify(converter.elementsToKotlin(listOf(file to null))[0])
} }
return "" return ""
} }
@@ -45,7 +45,7 @@ public abstract class AbstractJavaToKotlinConverterMultiFileTest() : AbstractJav
} }
val converter = JavaToKotlinConverter(project, ConverterSettings.defaultSettings, FilesConversionScope(psiFiles), IdeaReferenceSearcher) val converter = JavaToKotlinConverter(project, ConverterSettings.defaultSettings, FilesConversionScope(psiFiles), IdeaReferenceSearcher)
val results: List<String> = converter.elementsToKotlin(*psiFiles.map { it to J2kPostProcessor(it) }.copyToArray()) val results: List<String> = converter.elementsToKotlin(psiFiles.map { it to J2kPostProcessor(it) })
.map { reformat(it, project) } .map { reformat(it, project) }
for ((i, javaFile) in javaFiles.withIndices()) { for ((i, javaFile) in javaFiles.withIndices()) {
@@ -106,13 +106,13 @@ public abstract class AbstractJavaToKotlinConverterSingleFileTest() : AbstractJa
val fileWithText = createJavaFile(text) val fileWithText = createJavaFile(text)
val converter = JavaToKotlinConverter(project, settings, FilesConversionScope(listOf(fileWithText)), IdeaReferenceSearcher) val converter = JavaToKotlinConverter(project, settings, FilesConversionScope(listOf(fileWithText)), IdeaReferenceSearcher)
val element = fileWithText.getFirstChild()!! val element = fileWithText.getFirstChild()!!
return converter.elementsToKotlin(element to J2kPostProcessor(fileWithText))[0] return converter.elementsToKotlin(listOf(element to J2kPostProcessor(fileWithText)))[0]
} }
private fun fileToKotlin(text: String, settings: ConverterSettings, project: Project): String { private fun fileToKotlin(text: String, settings: ConverterSettings, project: Project): String {
val file = createJavaFile(text) val file = createJavaFile(text)
val converter = JavaToKotlinConverter(project, settings, FilesConversionScope(listOf(file)), IdeaReferenceSearcher) val converter = JavaToKotlinConverter(project, settings, FilesConversionScope(listOf(file)), IdeaReferenceSearcher)
return converter.elementsToKotlin(file to J2kPostProcessor(file))[0] return converter.elementsToKotlin(listOf(file to J2kPostProcessor(file)))[0]
} }
private fun methodToKotlin(text: String, settings: ConverterSettings, project: Project): String { private fun methodToKotlin(text: String, settings: ConverterSettings, project: Project): String {