From 002312f98a4543a2912df3d2e98d78e7fb4781d7 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Wed, 27 May 2015 20:16:40 +0300 Subject: [PATCH] Import of KClass inserted when needed on conversion to Kotlin on paste --- .../copy/ConvertJavaCopyPastePostProcessor.kt | 43 +++++++++++++------ .../conversion/AddKClassImport.expected.kt | 5 +++ .../copyPaste/conversion/AddKClassImport.java | 6 +++ ...otlinCopyPasteConversionTestGenerated.java | 6 +++ .../org/jetbrains/kotlin/j2k/CodeBuilder.kt | 7 ++- j2k/src/org/jetbrains/kotlin/j2k/Converter.kt | 2 +- .../kotlin/j2k/JavaToKotlinConverter.kt | 2 +- 7 files changed, 51 insertions(+), 20 deletions(-) create mode 100644 idea/testData/copyPaste/conversion/AddKClassImport.expected.kt create mode 100644 idea/testData/copyPaste/conversion/AddKClassImport.java diff --git a/idea/src/org/jetbrains/kotlin/idea/conversion/copy/ConvertJavaCopyPastePostProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/conversion/copy/ConvertJavaCopyPastePostProcessor.kt index 7f93428594d..ba045b09d7c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/conversion/copy/ConvertJavaCopyPastePostProcessor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/conversion/copy/ConvertJavaCopyPastePostProcessor.kt @@ -30,16 +30,20 @@ import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile import com.intellij.psi.PsiJavaFile import org.jetbrains.annotations.TestOnly +import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.codeInsight.KotlinCopyPasteReferenceProcessor import org.jetbrains.kotlin.idea.codeInsight.KotlinReferenceData import org.jetbrains.kotlin.idea.editor.JetEditorOptions import org.jetbrains.kotlin.idea.j2k.IdeaResolverForConverter import org.jetbrains.kotlin.idea.j2k.J2kPostProcessor +import org.jetbrains.kotlin.idea.util.ImportInsertHelper import org.jetbrains.kotlin.idea.util.application.runWriteAction import org.jetbrains.kotlin.j2k.* +import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.JetFile import org.jetbrains.kotlin.psi.JetPsiFactory import java.awt.datatransfer.Transferable +import java.util.LinkedHashSet public class ConvertJavaCopyPastePostProcessor : CopyPastePostProcessor() { private val LOG = Logger.getInstance("#org.jetbrains.kotlin.idea.conversion.copy.ConvertJavaCopyPastePostProcessor") @@ -73,34 +77,44 @@ public class ConvertJavaCopyPastePostProcessor : CopyPastePostProcessor> { + @data class Result(val text: String?, val referenceData: Collection, val explicitImports: Set) + + fun doConversion(): Result { val dataForConversion = DataForConversion.prepare(data, project) val result = convertCopiedCodeToKotlin(dataForConversion.elementsAndTexts, project) val referenceData = buildReferenceData(result.text, result.parseContext, dataForConversion.importsAndPackage, targetFile) - return (if (result.textChanged) result.text else null) to referenceData + val text = if (result.textChanged) result.text else null + return Result(text, referenceData, result.importsToAdd) } - fun insertImports(bounds: TextRange, referenceData: Collection): TextRange? { - if (referenceData.isEmpty()) return bounds + fun insertImports(bounds: TextRange, referenceData: Collection, explicitImports: Collection): TextRange? { + if (referenceData.isEmpty() && explicitImports.isEmpty()) return bounds + + PsiDocumentManager.getInstance(project).commitAllDocuments() val rangeMarker = document.createRangeMarker(bounds) rangeMarker.setGreedyToLeft(true) rangeMarker.setGreedyToRight(true) + explicitImports.forEach { fqName -> + targetFile.getResolutionFacade().resolveImportReference(targetFile, fqName).firstOrNull()?.let { + ImportInsertHelper.getInstance(project).importDescriptor(targetFile, it) + } + } + KotlinCopyPasteReferenceProcessor().processReferenceData(project, targetFile, bounds.start, referenceData.copyToArray()) return rangeMarker.range } - var conversionResult: Pair>? = null + var conversionResult: Result? = null fun doConversionAndInsertImportsIfUnchanged(): Boolean { conversionResult = doConversion() - val text = conversionResult!!.first - if (text != null) return false + if (conversionResult!!.text != null) return false - insertImports(bounds.range ?: return true, conversionResult!!.second) + insertImports(bounds.range ?: return true, conversionResult!!.referenceData, conversionResult!!.explicitImports) return true } @@ -114,7 +128,7 @@ public class ConvertJavaCopyPastePostProcessor : CopyPastePostProcessor, val textChanged: Boolean ) @@ -150,6 +165,7 @@ public class ConvertJavaCopyPastePostProcessor : CopyPastePostProcessor() val results = converter.elementsToKotlin(inputElements).results + val importsToAdd = LinkedHashSet() var resultIndex = 0 val convertedCodeBuilder = StringBuilder() @@ -162,12 +178,11 @@ public class ConvertJavaCopyPastePostProcessor : CopyPastePostProcessor { @@ -225,7 +240,7 @@ public class ConvertJavaCopyPastePostProcessor : CopyPastePostProcessor) diff --git a/idea/testData/copyPaste/conversion/AddKClassImport.java b/idea/testData/copyPaste/conversion/AddKClassImport.java new file mode 100644 index 00000000000..5f2baffdd2a --- /dev/null +++ b/idea/testData/copyPaste/conversion/AddKClassImport.java @@ -0,0 +1,6 @@ +@interface Ann { + Class value(); +} + +class X { +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/conversion/copy/JavaToKotlinCopyPasteConversionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/conversion/copy/JavaToKotlinCopyPasteConversionTestGenerated.java index e70b7c18aaf..8c5436d5869 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/conversion/copy/JavaToKotlinCopyPasteConversionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/conversion/copy/JavaToKotlinCopyPasteConversionTestGenerated.java @@ -61,6 +61,12 @@ public class JavaToKotlinCopyPasteConversionTestGenerated extends AbstractJavaTo doTest(fileName); } + @TestMetadata("AddKClassImport.java") + public void testAddKClassImport() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/copyPaste/conversion/AddKClassImport.java"); + doTest(fileName); + } + public void testAllFilesPresentInConversion() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/copyPaste/conversion"), Pattern.compile("^([^\\.]+)\\.java$"), true); } diff --git a/j2k/src/org/jetbrains/kotlin/j2k/CodeBuilder.kt b/j2k/src/org/jetbrains/kotlin/j2k/CodeBuilder.kt index 66d59397733..cebbdabf9dd 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/CodeBuilder.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/CodeBuilder.kt @@ -23,8 +23,7 @@ import org.jetbrains.kotlin.j2k.ast.CommentsAndSpacesInheritance import org.jetbrains.kotlin.j2k.ast.Element import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.psiUtil.isAncestor -import java.util.ArrayList -import java.util.HashSet +import java.util.* import kotlin.platform.platformName fun CodeBuilder.append(generators: Collection<() -> T>, separator: String, prefix: String = "", suffix: String = ""): CodeBuilder { @@ -56,7 +55,7 @@ class CodeBuilder(private val topElement: PsiElement?) { private val commentsAndSpacesUsed = HashSet() - private val imports = ArrayList() + private val imports = LinkedHashSet() public fun append(text: String): CodeBuilder = append(text, false) @@ -93,7 +92,7 @@ class CodeBuilder(private val topElement: PsiElement?) { public val resultText: String get() = builder.toString() - public val importsToAdd: Collection + public val importsToAdd: Set get() = imports public fun append(element: Element): CodeBuilder { diff --git a/j2k/src/org/jetbrains/kotlin/j2k/Converter.kt b/j2k/src/org/jetbrains/kotlin/j2k/Converter.kt index a08e45a8c47..faae5f1ed6d 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/Converter.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/Converter.kt @@ -84,7 +84,7 @@ class Converter private( public data class Result( val text: String, - val importsToAdd: Collection + val importsToAdd: Set ) public fun convert(): IntermediateResult? { diff --git a/j2k/src/org/jetbrains/kotlin/j2k/JavaToKotlinConverter.kt b/j2k/src/org/jetbrains/kotlin/j2k/JavaToKotlinConverter.kt index e7fa64d98b2..80ae8ef87d3 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/JavaToKotlinConverter.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/JavaToKotlinConverter.kt @@ -89,7 +89,7 @@ public class JavaToKotlinConverter( public fun prepareWriteOperation(progress: ProgressIndicator): () -> Unit } - public data class ElementResult(val text: String, val importsToAdd: Collection, val parseContext: ParseContext) + public data class ElementResult(val text: String, val importsToAdd: Set, val parseContext: ParseContext) public data class Result(val results: List, val externalCodeProcessing: ExternalCodeProcessing?)