KT-5203 Do not offer to convert from java on paste if conversion is trivial

#KT-5203 Fixed
This commit is contained in:
Valentin Kipyatkov
2015-04-02 20:59:19 +03:00
parent 0ed7d228f6
commit 2227452e7a
8 changed files with 83 additions and 41 deletions
@@ -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
@@ -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");
} }
} }