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
|
if (DumbService.getInstance(project).isDumb()) return
|
||||||
|
|
||||||
val data = values.single()
|
val data = values.single()
|
||||||
|
|
||||||
if (data !is CopiedCode) return
|
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
|
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 jetEditorOptions = JetEditorOptions.getInstance()!!
|
||||||
val needConvert = jetEditorOptions.isEnableJavaToKotlinConversion() && (jetEditorOptions.isDonTShowConversionDialog() || okFromDialog(project))
|
val needConvert = jetEditorOptions.isEnableJavaToKotlinConversion() && (jetEditorOptions.isDonTShowConversionDialog() || okFromDialog(project))
|
||||||
if (needConvert) {
|
if (needConvert) {
|
||||||
val text = convertCopiedCodeToKotlin(data, sourceFile, data.fileText, targetFile)
|
if (conversionResult == null) {
|
||||||
if (!text.isEmpty()) {
|
conversionResult = doConversion() ?: return
|
||||||
ApplicationManager.getApplication()!!.runWriteAction {
|
}
|
||||||
val startOffset = bounds.getStartOffset()
|
ApplicationManager.getApplication()!!.runWriteAction {
|
||||||
editor.getDocument().replaceString(startOffset, bounds.getEndOffset(), text)
|
val startOffset = bounds.getStartOffset()
|
||||||
|
editor.getDocument().replaceString(startOffset, bounds.getEndOffset(), conversionResult!!)
|
||||||
|
|
||||||
val endOffsetAfterCopy = startOffset + text.length()
|
val endOffsetAfterCopy = startOffset + conversionResult!!.length()
|
||||||
editor.getCaretModel().moveToOffset(endOffsetAfterCopy)
|
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")
|
assert(code.startOffsets.size() == code.endOffsets.size(), "Must have the same size")
|
||||||
|
val sourceFileText = code.fileText
|
||||||
|
|
||||||
val list = ArrayList<Any>()
|
val list = ArrayList<Any>()
|
||||||
for (i in code.startOffsets.indices) {
|
for (i in code.startOffsets.indices) {
|
||||||
list.collectElementsToConvert(sourceFile, sourceFileText, TextRange(code.startOffsets[i], code.endOffsets[i]))
|
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(
|
val converter = JavaToKotlinConverter(
|
||||||
sourceFile.getProject(),
|
sourceFile.getProject(),
|
||||||
ConverterSettings.defaultSettings,
|
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) })
|
val results = converter.elementsToKotlin(list.filterIsInstance<PsiElement>().map { it to J2kPostProcessor(targetFile, formatCode = false) })
|
||||||
|
|
||||||
var resultIndex = 0
|
var resultIndex = 0
|
||||||
val text = StringBuilder {
|
val convertedCodeBuilder = StringBuilder()
|
||||||
for (o in list) {
|
val originalCodeBuilder = StringBuilder()
|
||||||
if (o is PsiElement) {
|
for (o in list) {
|
||||||
val result = results[resultIndex++]
|
if (o is PsiElement) {
|
||||||
if (!result.isEmpty()) {
|
val originalText = o.getText()
|
||||||
append(result)
|
val result = results[resultIndex++]
|
||||||
}
|
if (!result.isEmpty()) {
|
||||||
else { // failed to convert element to Kotlin, insert "as is"
|
convertedCodeBuilder.append(result)
|
||||||
append(o.getText())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else { // failed to convert element to Kotlin, insert "as is"
|
||||||
append(o as String)
|
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
|
// builds list consisting of PsiElement's to convert and plain String's
|
||||||
@@ -178,4 +199,9 @@ public class ConvertJavaCopyPastePostProcessor : CopyPastePostProcessor<TextBloc
|
|||||||
dialog.show()
|
dialog.show()
|
||||||
return dialog.isOK()
|
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>) {
|
No conversion performed
|
||||||
reference(arg)
|
|
||||||
somethingElse()
|
|
||||||
}
|
|
||||||
@@ -1 +1 @@
|
|||||||
}
|
No conversion performed
|
||||||
@@ -1,4 +1 @@
|
|||||||
fun main(args: Array<String>) {
|
No conversion performed
|
||||||
qualifier
|
|
||||||
somethingElse()
|
|
||||||
}
|
|
||||||
@@ -1 +1 @@
|
|||||||
class Some
|
No conversion performed
|
||||||
+23
-1
@@ -17,8 +17,10 @@
|
|||||||
package org.jetbrains.kotlin.idea.conversion.copy;
|
package org.jetbrains.kotlin.idea.conversion.copy;
|
||||||
|
|
||||||
import com.intellij.openapi.actionSystem.IdeActions;
|
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.LightProjectDescriptor;
|
||||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.kotlin.idea.JetLightCodeInsightFixtureTestCase;
|
import org.jetbrains.kotlin.idea.JetLightCodeInsightFixtureTestCase;
|
||||||
import org.jetbrains.kotlin.idea.JetWithJdkAndRuntimeLightProjectDescriptor;
|
import org.jetbrains.kotlin.idea.JetWithJdkAndRuntimeLightProjectDescriptor;
|
||||||
@@ -55,8 +57,28 @@ public abstract class AbstractJavaToKotlinCopyPasteConversionTest extends JetLig
|
|||||||
String testName = getTestName(false);
|
String testName = getTestName(false);
|
||||||
myFixture.configureByFile(testName + ".java");
|
myFixture.configureByFile(testName + ".java");
|
||||||
myFixture.performEditorAction(IdeActions.ACTION_COPY);
|
myFixture.performEditorAction(IdeActions.ACTION_COPY);
|
||||||
|
|
||||||
|
//noinspection AssignmentToStaticFieldFromInstanceMethod
|
||||||
|
ConvertJavaCopyPastePostProcessor.conversionPerformed = false;
|
||||||
|
|
||||||
myFixture.configureByFile(testName + ".to.kt");
|
myFixture.configureByFile(testName + ".to.kt");
|
||||||
myFixture.performEditorAction(IdeActions.ACTION_PASTE);
|
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");
|
myFixture.checkResultByFile(testName + ".expected.kt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user