KT-5203 Do not offer to convert from java on paste if conversion is trivial
#KT-5203 Fixed
This commit is contained in:
+54
-28
@@ -66,40 +66,54 @@ public class ConvertJavaCopyPastePostProcessor : CopyPastePostProcessor<TextBloc
|
||||
if (DumbService.getInstance(project).isDumb()) return
|
||||
|
||||
val data = values.single()
|
||||
|
||||
if (data !is CopiedCode) return
|
||||
|
||||
val sourceFile = PsiFileFactory.getInstance(project).
|
||||
createFileFromText(data.fileName, JavaLanguage.INSTANCE, data.fileText) as? PsiJavaFile ?: return
|
||||
|
||||
val targetFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()) as? JetFile ?: return
|
||||
|
||||
fun doConversion(): String? {
|
||||
val sourceFile = PsiFileFactory.getInstance(project).
|
||||
createFileFromText(data.fileName, JavaLanguage.INSTANCE, data.fileText) as PsiJavaFile
|
||||
return convertCopiedCodeToKotlin(data, sourceFile, targetFile)
|
||||
}
|
||||
|
||||
var conversionResult: String? = null
|
||||
|
||||
val textLength = data.startOffsets.indices.sumBy { data.endOffsets[it] - data.startOffsets[it] }
|
||||
if (textLength < 1000) { // if the text to convert is short enough, try to do conversion without permission from user and skip the dialog if nothing converted
|
||||
conversionResult = doConversion() ?: return
|
||||
}
|
||||
|
||||
val jetEditorOptions = JetEditorOptions.getInstance()!!
|
||||
val needConvert = jetEditorOptions.isEnableJavaToKotlinConversion() && (jetEditorOptions.isDonTShowConversionDialog() || okFromDialog(project))
|
||||
if (needConvert) {
|
||||
val text = convertCopiedCodeToKotlin(data, sourceFile, data.fileText, targetFile)
|
||||
if (!text.isEmpty()) {
|
||||
ApplicationManager.getApplication()!!.runWriteAction {
|
||||
val startOffset = bounds.getStartOffset()
|
||||
editor.getDocument().replaceString(startOffset, bounds.getEndOffset(), text)
|
||||
if (conversionResult == null) {
|
||||
conversionResult = doConversion() ?: return
|
||||
}
|
||||
ApplicationManager.getApplication()!!.runWriteAction {
|
||||
val startOffset = bounds.getStartOffset()
|
||||
editor.getDocument().replaceString(startOffset, bounds.getEndOffset(), conversionResult!!)
|
||||
|
||||
val endOffsetAfterCopy = startOffset + text.length()
|
||||
editor.getCaretModel().moveToOffset(endOffsetAfterCopy)
|
||||
val endOffsetAfterCopy = startOffset + conversionResult!!.length()
|
||||
editor.getCaretModel().moveToOffset(endOffsetAfterCopy)
|
||||
|
||||
CodeStyleManager.getInstance(project)!!.reformatText(targetFile, startOffset, endOffsetAfterCopy)
|
||||
}
|
||||
CodeStyleManager.getInstance(project)!!.reformatText(targetFile, startOffset, endOffsetAfterCopy)
|
||||
|
||||
conversionPerformed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun convertCopiedCodeToKotlin(code: CopiedCode, sourceFile: PsiJavaFile, sourceFileText: String, targetFile: JetFile): String {
|
||||
private fun convertCopiedCodeToKotlin(code: CopiedCode, sourceFile: PsiJavaFile, targetFile: JetFile): String? {
|
||||
assert(code.startOffsets.size() == code.endOffsets.size(), "Must have the same size")
|
||||
val sourceFileText = code.fileText
|
||||
|
||||
val list = ArrayList<Any>()
|
||||
for (i in code.startOffsets.indices) {
|
||||
list.collectElementsToConvert(sourceFile, sourceFileText, TextRange(code.startOffsets[i], code.endOffsets[i]))
|
||||
}
|
||||
|
||||
if (list.all { it is String }) return null // nothing to convert
|
||||
|
||||
val converter = JavaToKotlinConverter(
|
||||
sourceFile.getProject(),
|
||||
ConverterSettings.defaultSettings,
|
||||
@@ -110,24 +124,31 @@ public class ConvertJavaCopyPastePostProcessor : CopyPastePostProcessor<TextBloc
|
||||
val results = converter.elementsToKotlin(list.filterIsInstance<PsiElement>().map { it to J2kPostProcessor(targetFile, formatCode = false) })
|
||||
|
||||
var resultIndex = 0
|
||||
val text = StringBuilder {
|
||||
for (o in list) {
|
||||
if (o is PsiElement) {
|
||||
val result = results[resultIndex++]
|
||||
if (!result.isEmpty()) {
|
||||
append(result)
|
||||
}
|
||||
else { // failed to convert element to Kotlin, insert "as is"
|
||||
append(o.getText())
|
||||
}
|
||||
val convertedCodeBuilder = StringBuilder()
|
||||
val originalCodeBuilder = StringBuilder()
|
||||
for (o in list) {
|
||||
if (o is PsiElement) {
|
||||
val originalText = o.getText()
|
||||
val result = results[resultIndex++]
|
||||
if (!result.isEmpty()) {
|
||||
convertedCodeBuilder.append(result)
|
||||
}
|
||||
else {
|
||||
append(o as String)
|
||||
else { // failed to convert element to Kotlin, insert "as is"
|
||||
convertedCodeBuilder.append(originalText)
|
||||
}
|
||||
originalCodeBuilder.append(originalText)
|
||||
}
|
||||
}.toString()
|
||||
else {
|
||||
convertedCodeBuilder.append(o as String)
|
||||
originalCodeBuilder.append(o)
|
||||
}
|
||||
}
|
||||
|
||||
return StringUtil.convertLineSeparators(text)
|
||||
val convertedCode = convertedCodeBuilder.toString()
|
||||
val originalCode = originalCodeBuilder.toString()
|
||||
if (convertedCode == originalCode) return null
|
||||
|
||||
return convertedCode
|
||||
}
|
||||
|
||||
// builds list consisting of PsiElement's to convert and plain String's
|
||||
@@ -178,4 +199,9 @@ public class ConvertJavaCopyPastePostProcessor : CopyPastePostProcessor<TextBloc
|
||||
dialog.show()
|
||||
return dialog.isOK()
|
||||
}
|
||||
|
||||
companion object {
|
||||
// used for testing
|
||||
public var conversionPerformed: Boolean = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
b - c + d
|
||||
No conversion performed
|
||||
@@ -1 +1 @@
|
||||
<caret>
|
||||
val v = <caret>
|
||||
@@ -1,4 +1 @@
|
||||
fun main(args: Array<String>) {
|
||||
reference(arg)
|
||||
somethingElse()
|
||||
}
|
||||
No conversion performed
|
||||
@@ -1 +1 @@
|
||||
}
|
||||
No conversion performed
|
||||
@@ -1,4 +1 @@
|
||||
fun main(args: Array<String>) {
|
||||
qualifier
|
||||
somethingElse()
|
||||
}
|
||||
No conversion performed
|
||||
@@ -1 +1 @@
|
||||
class Some
|
||||
No conversion performed
|
||||
+23
-1
@@ -17,8 +17,10 @@
|
||||
package org.jetbrains.kotlin.idea.conversion.copy;
|
||||
|
||||
import com.intellij.openapi.actionSystem.IdeActions;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.idea.JetLightCodeInsightFixtureTestCase;
|
||||
import org.jetbrains.kotlin.idea.JetWithJdkAndRuntimeLightProjectDescriptor;
|
||||
@@ -55,8 +57,28 @@ public abstract class AbstractJavaToKotlinCopyPasteConversionTest extends JetLig
|
||||
String testName = getTestName(false);
|
||||
myFixture.configureByFile(testName + ".java");
|
||||
myFixture.performEditorAction(IdeActions.ACTION_COPY);
|
||||
|
||||
//noinspection AssignmentToStaticFieldFromInstanceMethod
|
||||
ConvertJavaCopyPastePostProcessor.conversionPerformed = false;
|
||||
|
||||
myFixture.configureByFile(testName + ".to.kt");
|
||||
myFixture.performEditorAction(IdeActions.ACTION_PASTE);
|
||||
|
||||
if (!ConvertJavaCopyPastePostProcessor.conversionPerformed) {
|
||||
CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Document document = myFixture.getEditor().getDocument();
|
||||
document.replaceString(0, document.getTextLength(), "No conversion performed");
|
||||
}
|
||||
});
|
||||
}
|
||||
}, "", null);
|
||||
}
|
||||
|
||||
myFixture.checkResultByFile(testName + ".expected.kt");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user