Conversion on copy paste:

Refactor: prettify code
This commit is contained in:
Pavel V. Talanov
2013-12-20 18:35:18 +04:00
parent 5408c6ea77
commit 7049b4e17e
@@ -30,7 +30,6 @@ import org.jetbrains.jet.j2k.*
import org.jetbrains.jet.lang.psi.JetFile import org.jetbrains.jet.lang.psi.JetFile
import org.jetbrains.jet.plugin.editor.JetEditorOptions import org.jetbrains.jet.plugin.editor.JetEditorOptions
import java.awt.datatransfer.Transferable import java.awt.datatransfer.Transferable
import java.util.ArrayList
import com.intellij.openapi.util.TextRange import com.intellij.openapi.util.TextRange
public class JavaCopyPastePostProcessor() : CopyPastePostProcessor<TextBlockTransferableData> { public class JavaCopyPastePostProcessor() : CopyPastePostProcessor<TextBlockTransferableData> {
@@ -71,7 +70,7 @@ public class JavaCopyPastePostProcessor() : CopyPastePostProcessor<TextBlockTran
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(value, file) val text = convertCopiedCodeToKotlin(value, file.getProject())
if (text.isNotEmpty()) { if (text.isNotEmpty()) {
ApplicationManager.getApplication()!!.runWriteAction { ApplicationManager.getApplication()!!.runWriteAction {
editor.getDocument().replaceString(bounds!!.getStartOffset(), bounds.getEndOffset(), text) editor.getDocument().replaceString(bounds!!.getStartOffset(), bounds.getEndOffset(), text)
@@ -82,13 +81,13 @@ public class JavaCopyPastePostProcessor() : CopyPastePostProcessor<TextBlockTran
} }
} }
private fun convertCopiedCodeToKotlin(code: CopiedCode, fileToPaste: PsiFile): String { private fun convertCopiedCodeToKotlin(code: CopiedCode, project: Project): String {
val converter = Converter(fileToPaste.getProject(), PluginSettings) val converter = Converter(project, PluginSettings)
val startOffsets = code.getStartOffsets() val startOffsets = code.getStartOffsets()
val endOffsets = code.getEndOffsets() val endOffsets = code.getEndOffsets()
assert(startOffsets.size == endOffsets.size) { "Must have the same size" } assert(startOffsets.size == endOffsets.size) { "Must have the same size" }
val result = StringBuilder() val result = StringBuilder()
for (i in 0..startOffsets.size - 1) { for (i in startOffsets.indices) {
val startOffset = startOffsets[i] val startOffset = startOffsets[i]
val endOffset = endOffsets[i] val endOffset = endOffsets[i]
result.append(convertRangeToKotlin(code.getFile()!!, TextRange(startOffset, endOffset), converter)) result.append(convertRangeToKotlin(code.getFile()!!, TextRange(startOffset, endOffset), converter))
@@ -96,21 +95,30 @@ public class JavaCopyPastePostProcessor() : CopyPastePostProcessor<TextBlockTran
return StringUtil.convertLineSeparators(result.toString()) return StringUtil.convertLineSeparators(result.toString())
} }
private val TextRange.start: Int
get() = getStartOffset()
private val TextRange.end: Int
get() = getEndOffset()
//TODO: not private due to KT-4340
val PsiElement.range: TextRange
get() = getTextRange()!!
private fun convertRangeToKotlin(file: PsiJavaFile, private fun convertRangeToKotlin(file: PsiJavaFile,
range: TextRange, range: TextRange,
converter: Converter): String { converter: Converter): String {
val result = StringBuilder() val result = StringBuilder()
var currentRange = range var currentRange = range
//TODO: probably better to use document to get text by range
val fileText = file.getText()!! val fileText = file.getText()!!
while (!currentRange.isEmpty()) { while (!currentRange.isEmpty()) {
val leafElement = findFirstLeafElementWhollyInRange(file, currentRange) val leafElement = findFirstLeafElementWhollyInRange(file, currentRange)
if (leafElement == null) { if (leafElement == null) {
val unconvertedSuffix = fileText.substring(currentRange.getStartOffset(), currentRange.getEndOffset()) val unconvertedSuffix = fileText.substring(currentRange.start, currentRange.end)
result.append(unconvertedSuffix) result.append(unconvertedSuffix)
break break
} }
val elementToConvert = findTopMostParentWhollyInRange(currentRange, leafElement) val elementToConvert = findTopMostParentWhollyInRange(currentRange, leafElement)
val unconvertedPrefix = fileText.substring(currentRange.getStartOffset(), elementToConvert.getTextRange()!!.getStartOffset()) val unconvertedPrefix = fileText.substring(currentRange.start, elementToConvert.range.start)
result.append(unconvertedPrefix) result.append(unconvertedPrefix)
val converted = converter.elementToKotlin(elementToConvert) val converted = converter.elementToKotlin(elementToConvert)
if (converted.isNotEmpty()) { if (converted.isNotEmpty()) {
@@ -119,23 +127,23 @@ public class JavaCopyPastePostProcessor() : CopyPastePostProcessor<TextBlockTran
else { else {
result.append(elementToConvert.getText()) result.append(elementToConvert.getText())
} }
val endOfConverted = elementToConvert.getTextRange()!!.getEndOffset() val endOfConverted = elementToConvert.range.end
currentRange = TextRange(endOfConverted, currentRange.getEndOffset()) currentRange = TextRange(endOfConverted, currentRange.end)
} }
return result.toString() return result.toString()
} }
private fun findFirstLeafElementWhollyInRange(file: PsiJavaFile, range: TextRange): PsiElement? { private fun findFirstLeafElementWhollyInRange(file: PsiJavaFile, range: TextRange): PsiElement? {
var i = range.getStartOffset() var i = range.start
while (i < range.getEndOffset()) { while (i < range.end) {
var element = file.findElementAt(i) val element = file.findElementAt(i)
if (element == null) { if (element == null) {
++i ++i
continue continue
} }
val elemRange = element!!.getTextRange()!! val elemRange = element.range
if (elemRange !in range) { if (elemRange !in range) {
i = elemRange.getEndOffset() i = elemRange.end
continue continue
} }
return element return element
@@ -145,14 +153,16 @@ public class JavaCopyPastePostProcessor() : CopyPastePostProcessor<TextBlockTran
private fun findTopMostParentWhollyInRange(range: TextRange, private fun findTopMostParentWhollyInRange(range: TextRange,
base: PsiElement): PsiElement { base: PsiElement): PsiElement {
assert(base.range in range) {
"Base element out of range. Range: $range, element: ${base.getText()}, element's range: ${base.range}."
}
var elem = base var elem = base
var parent = elem.getParent() while (true) {
while (elem.getTextRange()!! in range && val parent = elem.getParent()
parent != null && if (parent == null || parent is PsiJavaFile || parent.range !in range) {
parent !is PsiJavaFile && break
parent!!.getTextRange()!! in range) { }
elem = parent!! elem = parent
parent = elem.getParent()
} }
return elem return elem
} }
@@ -165,6 +175,5 @@ public class JavaCopyPastePostProcessor() : CopyPastePostProcessor<TextBlockTran
class object { class object {
private val LOG = Logger.getInstance("#org.jetbrains.jet.plugin.conversion.copy.JavaCopyPastePostProcessor")!! private val LOG = Logger.getInstance("#org.jetbrains.jet.plugin.conversion.copy.JavaCopyPastePostProcessor")!!
private val EOL = System.getProperty("line.separator")!!
} }
} }