From ab19669c4377fbbce1b5c9be0ed852916ee1696b Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Thu, 19 Dec 2013 21:42:27 +0400 Subject: [PATCH] Conversion on copy paste: Only convert elements that are wholly selected --- .../plugin/conversion/copy/CopiedCode.java | 8 +- .../copy/JavaCopyPastePostProcessor.kt | 94 +++++++++++++------ .../copyPaste/conversion/Imports3.expected.kt | 5 + .../copyPaste/conversion/Imports3.java | 4 + .../copyPaste/conversion/Imports3.to.kt | 5 + ...ethodReferenceWithoutQualifier.expected.kt | 4 + .../MethodReferenceWithoutQualifier.java | 5 + .../MethodReferenceWithoutQualifier.to.kt | 4 + .../conversion/OnlyClosingBrace.expected.kt | 1 + .../conversion/OnlyClosingBrace.java | 5 + .../conversion/OnlyClosingBrace.to.kt | 1 + .../conversion/OnlyQualifier.expected.kt | 4 + .../copyPaste/conversion/OnlyQualifier.java | 5 + .../copyPaste/conversion/OnlyQualifier.to.kt | 4 + ...otlinCopyPasteConversionTestGenerated.java | 20 ++++ 15 files changed, 135 insertions(+), 34 deletions(-) create mode 100644 idea/testData/copyPaste/conversion/Imports3.expected.kt create mode 100644 idea/testData/copyPaste/conversion/Imports3.java create mode 100644 idea/testData/copyPaste/conversion/Imports3.to.kt create mode 100644 idea/testData/copyPaste/conversion/MethodReferenceWithoutQualifier.expected.kt create mode 100644 idea/testData/copyPaste/conversion/MethodReferenceWithoutQualifier.java create mode 100644 idea/testData/copyPaste/conversion/MethodReferenceWithoutQualifier.to.kt create mode 100644 idea/testData/copyPaste/conversion/OnlyClosingBrace.expected.kt create mode 100644 idea/testData/copyPaste/conversion/OnlyClosingBrace.java create mode 100644 idea/testData/copyPaste/conversion/OnlyClosingBrace.to.kt create mode 100644 idea/testData/copyPaste/conversion/OnlyQualifier.expected.kt create mode 100644 idea/testData/copyPaste/conversion/OnlyQualifier.java create mode 100644 idea/testData/copyPaste/conversion/OnlyQualifier.to.kt diff --git a/idea/src/org/jetbrains/jet/plugin/conversion/copy/CopiedCode.java b/idea/src/org/jetbrains/jet/plugin/conversion/copy/CopiedCode.java index 9482f6a75f2..de2d7ad9733 100644 --- a/idea/src/org/jetbrains/jet/plugin/conversion/copy/CopiedCode.java +++ b/idea/src/org/jetbrains/jet/plugin/conversion/copy/CopiedCode.java @@ -17,7 +17,7 @@ package org.jetbrains.jet.plugin.conversion.copy; import com.intellij.codeInsight.editorActions.TextBlockTransferableData; -import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiJavaFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -26,11 +26,11 @@ import java.awt.datatransfer.DataFlavor; class CopiedCode implements TextBlockTransferableData { @NotNull public static final DataFlavor DATA_FLAVOR = new DataFlavor(JavaCopyPastePostProcessor.class, "class: JavaCopyPastePostProcessor"); - private final PsiFile file; + private final PsiJavaFile file; private final int[] startOffsets; private final int[] endOffsets; - public CopiedCode(@Nullable PsiFile file, @NotNull int[] startOffsets, @NotNull int[] endOffsets) { + public CopiedCode(@Nullable PsiJavaFile file, @NotNull int[] startOffsets, @NotNull int[] endOffsets) { this.file = file; this.startOffsets = startOffsets; this.endOffsets = endOffsets; @@ -58,7 +58,7 @@ class CopiedCode implements TextBlockTransferableData { } @Nullable - public PsiFile getFile() { + public PsiJavaFile getFile() { return file; } diff --git a/idea/src/org/jetbrains/jet/plugin/conversion/copy/JavaCopyPastePostProcessor.kt b/idea/src/org/jetbrains/jet/plugin/conversion/copy/JavaCopyPastePostProcessor.kt index a8cda388d31..116aad44de0 100644 --- a/idea/src/org/jetbrains/jet/plugin/conversion/copy/JavaCopyPastePostProcessor.kt +++ b/idea/src/org/jetbrains/jet/plugin/conversion/copy/JavaCopyPastePostProcessor.kt @@ -31,6 +31,7 @@ import org.jetbrains.jet.lang.psi.JetFile import org.jetbrains.jet.plugin.editor.JetEditorOptions import java.awt.datatransfer.Transferable import java.util.ArrayList +import com.intellij.openapi.util.TextRange public class JavaCopyPastePostProcessor() : CopyPastePostProcessor { @@ -52,7 +53,7 @@ public class JavaCopyPastePostProcessor() : CopyPastePostProcessor { - val buffer = ArrayList() + private fun convertCopiedCodeToKotlin(code: CopiedCode, fileToPaste: PsiFile): String { + val converter = Converter(fileToPaste.getProject(), PluginSettings) + val startOffsets = code.getStartOffsets() + val endOffsets = code.getEndOffsets() assert(startOffsets.size == endOffsets.size) { "Must have the same size" } + val result = StringBuilder() for (i in 0..startOffsets.size - 1) { val startOffset = startOffsets[i] val endOffset = endOffsets[i] - var elem = file.findElementAt(startOffset) - while (elem != null && - elem!!.getParent() != null && - !(elem!!.getParent() is PsiFile) && - elem!!.getParent()!!.getTextRange()!!.getEndOffset() <= endOffset) { - elem = elem!!.getParent() - } - if (elem != null) { - buffer.add(elem!!) - } - while (elem != null && elem!!.getTextRange()!!.getEndOffset() < endOffset) { - elem = elem!!.getNextSibling() - if (elem != null) { - buffer.add(elem!!) - } - } + result.append(convertRangeToKotlin(code.getFile()!!, TextRange(startOffset, endOffset), converter)) } - return buffer + return StringUtil.convertLineSeparators(result.toString()) + } + + private fun convertRangeToKotlin(file: PsiJavaFile, + range: TextRange, + converter: Converter): String { + val result = StringBuilder() + var currentRange = range + while (!currentRange.isEmpty()) { + val leafElement = findFirstLeafElementWhollyInRange(file, currentRange) + if (leafElement == null) { + break; + } + val elementToConvert = findTopMostParentWhollyInRange(currentRange, leafElement) + result.append(converter.elementToKotlin(elementToConvert)) + val endOfConverted = elementToConvert.getTextRange()!!.getEndOffset() + currentRange = TextRange(endOfConverted, currentRange.getEndOffset()) + } + return result.toString() + } + + private fun findFirstLeafElementWhollyInRange(file: PsiJavaFile, range: TextRange): PsiElement? { + var i = range.getStartOffset() + while (i < range.getEndOffset()) { + var element = file.findElementAt(i) + if (element == null) { + ++i + continue + } + val elemRange = element!!.getTextRange()!! + if (elemRange !in range) { + i = elemRange.getEndOffset() + continue + } + return element + } + return null + } + + private fun findTopMostParentWhollyInRange(range: TextRange, + base: PsiElement): PsiElement { + var elem = base + var parent = elem.getParent() + while (elem.getTextRange()!! in range && + parent != null && + parent !is PsiJavaFile && + parent!!.getTextRange()!! in range) { + elem = parent!! + parent = elem.getParent() + } + return elem } private fun okFromDialog(project: Project): Boolean { diff --git a/idea/testData/copyPaste/conversion/Imports3.expected.kt b/idea/testData/copyPaste/conversion/Imports3.expected.kt new file mode 100644 index 00000000000..d1cd2e834a8 --- /dev/null +++ b/idea/testData/copyPaste/conversion/Imports3.expected.kt @@ -0,0 +1,5 @@ +import g.e.v + +fun main(args: Array) { + +} diff --git a/idea/testData/copyPaste/conversion/Imports3.java b/idea/testData/copyPaste/conversion/Imports3.java new file mode 100644 index 00000000000..93df7dbd441 --- /dev/null +++ b/idea/testData/copyPaste/conversion/Imports3.java @@ -0,0 +1,4 @@ +import java.util.List; +import a.b.c; +import java.util.Set; +import g.e.v; diff --git a/idea/testData/copyPaste/conversion/Imports3.to.kt b/idea/testData/copyPaste/conversion/Imports3.to.kt new file mode 100644 index 00000000000..cbf22106ef9 --- /dev/null +++ b/idea/testData/copyPaste/conversion/Imports3.to.kt @@ -0,0 +1,5 @@ + + +fun main(args: Array) { + +} diff --git a/idea/testData/copyPaste/conversion/MethodReferenceWithoutQualifier.expected.kt b/idea/testData/copyPaste/conversion/MethodReferenceWithoutQualifier.expected.kt new file mode 100644 index 00000000000..636a2ba7a5d --- /dev/null +++ b/idea/testData/copyPaste/conversion/MethodReferenceWithoutQualifier.expected.kt @@ -0,0 +1,4 @@ +fun main(args: Array) { + reference(arg) + somethingElse() +} \ No newline at end of file diff --git a/idea/testData/copyPaste/conversion/MethodReferenceWithoutQualifier.java b/idea/testData/copyPaste/conversion/MethodReferenceWithoutQualifier.java new file mode 100644 index 00000000000..09ed4a6d46d --- /dev/null +++ b/idea/testData/copyPaste/conversion/MethodReferenceWithoutQualifier.java @@ -0,0 +1,5 @@ +class A { + public static void main(String[] args) { + qualifier.reference(arg); + } +} \ No newline at end of file diff --git a/idea/testData/copyPaste/conversion/MethodReferenceWithoutQualifier.to.kt b/idea/testData/copyPaste/conversion/MethodReferenceWithoutQualifier.to.kt new file mode 100644 index 00000000000..fc7ac3c9c51 --- /dev/null +++ b/idea/testData/copyPaste/conversion/MethodReferenceWithoutQualifier.to.kt @@ -0,0 +1,4 @@ +fun main(args: Array) { + + somethingElse() +} \ No newline at end of file diff --git a/idea/testData/copyPaste/conversion/OnlyClosingBrace.expected.kt b/idea/testData/copyPaste/conversion/OnlyClosingBrace.expected.kt new file mode 100644 index 00000000000..ff30235f076 --- /dev/null +++ b/idea/testData/copyPaste/conversion/OnlyClosingBrace.expected.kt @@ -0,0 +1 @@ +} \ No newline at end of file diff --git a/idea/testData/copyPaste/conversion/OnlyClosingBrace.java b/idea/testData/copyPaste/conversion/OnlyClosingBrace.java new file mode 100644 index 00000000000..8feec292e18 --- /dev/null +++ b/idea/testData/copyPaste/conversion/OnlyClosingBrace.java @@ -0,0 +1,5 @@ +class A { + public static void main(String[] args) { + //sdasd + } +} \ No newline at end of file diff --git a/idea/testData/copyPaste/conversion/OnlyClosingBrace.to.kt b/idea/testData/copyPaste/conversion/OnlyClosingBrace.to.kt new file mode 100644 index 00000000000..81389d50841 --- /dev/null +++ b/idea/testData/copyPaste/conversion/OnlyClosingBrace.to.kt @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/idea/testData/copyPaste/conversion/OnlyQualifier.expected.kt b/idea/testData/copyPaste/conversion/OnlyQualifier.expected.kt new file mode 100644 index 00000000000..0c1766e04c4 --- /dev/null +++ b/idea/testData/copyPaste/conversion/OnlyQualifier.expected.kt @@ -0,0 +1,4 @@ +fun main(args: Array) { + qualifier + somethingElse() +} \ No newline at end of file diff --git a/idea/testData/copyPaste/conversion/OnlyQualifier.java b/idea/testData/copyPaste/conversion/OnlyQualifier.java new file mode 100644 index 00000000000..300ee6e06f2 --- /dev/null +++ b/idea/testData/copyPaste/conversion/OnlyQualifier.java @@ -0,0 +1,5 @@ +class A { + public static void main(String[] args) { + qualifier.reference(arg); + } +} \ No newline at end of file diff --git a/idea/testData/copyPaste/conversion/OnlyQualifier.to.kt b/idea/testData/copyPaste/conversion/OnlyQualifier.to.kt new file mode 100644 index 00000000000..fc7ac3c9c51 --- /dev/null +++ b/idea/testData/copyPaste/conversion/OnlyQualifier.to.kt @@ -0,0 +1,4 @@ +fun main(args: Array) { + + somethingElse() +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/conversion/copy/JavaToKotlinCopyPasteConversionTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/conversion/copy/JavaToKotlinCopyPasteConversionTestGenerated.java index 7bb8a06432d..615ba08dd86 100644 --- a/idea/tests/org/jetbrains/jet/plugin/conversion/copy/JavaToKotlinCopyPasteConversionTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/conversion/copy/JavaToKotlinCopyPasteConversionTestGenerated.java @@ -51,6 +51,26 @@ public class JavaToKotlinCopyPasteConversionTestGenerated extends AbstractJavaTo doTest("idea/testData/copyPaste/conversion/Imports2.java"); } + @TestMetadata("Imports3.java") + public void testImports3() throws Exception { + doTest("idea/testData/copyPaste/conversion/Imports3.java"); + } + + @TestMetadata("MethodReferenceWithoutQualifier.java") + public void testMethodReferenceWithoutQualifier() throws Exception { + doTest("idea/testData/copyPaste/conversion/MethodReferenceWithoutQualifier.java"); + } + + @TestMetadata("OnlyClosingBrace.java") + public void testOnlyClosingBrace() throws Exception { + doTest("idea/testData/copyPaste/conversion/OnlyClosingBrace.java"); + } + + @TestMetadata("OnlyQualifier.java") + public void testOnlyQualifier() throws Exception { + doTest("idea/testData/copyPaste/conversion/OnlyQualifier.java"); + } + @TestMetadata("SampleBlock.java") public void testSampleBlock() throws Exception { doTest("idea/testData/copyPaste/conversion/SampleBlock.java");