Insert imports on copy/paste
Introduce KotlinCopyPasteReferenceProcessor
This commit is contained in:
@@ -90,6 +90,7 @@ import org.jetbrains.jet.completion.AbstractCompiledKotlinInJavaCompletionTest
|
||||
import org.jetbrains.jet.completion.AbstractKotlinSourceInJavaCompletionTest
|
||||
import org.jetbrains.jet.plugin.intentions.AbstractIntentionTest
|
||||
import org.jetbrains.jet.checkers.AbstractJetDiagnosticsTestWithStdLib
|
||||
import org.jetbrains.jet.plugin.codeInsight.AbstractInsertImportOnPasteTest
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
System.setProperty("java.awt.headless", "true")
|
||||
@@ -441,6 +442,11 @@ fun main(args: Array<String>) {
|
||||
model("copyPaste/conversion", extension = "java")
|
||||
}
|
||||
|
||||
testClass(javaClass<AbstractInsertImportOnPasteTest>()) {
|
||||
model("copyPaste/imports", pattern = """^([^\.]+)\.kt$""", testMethod = "doTestCopy", testClassName = "Copy", recursive = false)
|
||||
model("copyPaste/imports", pattern = """^([^\.]+)\.kt$""", testMethod = "doTestCut", testClassName = "Cut", recursive = false)
|
||||
}
|
||||
|
||||
testClass(javaClass<AbstractShortenRefsTest>()) {
|
||||
model("shortenRefs", pattern = """^([^\.]+)\.kt$""")
|
||||
}
|
||||
|
||||
@@ -250,6 +250,8 @@
|
||||
<backspaceHandlerDelegate implementation="org.jetbrains.jet.plugin.editor.KotlinBackspaceHandler"/>
|
||||
|
||||
<copyPastePostProcessor implementation="org.jetbrains.jet.plugin.conversion.copy.ConvertJavaCopyPastePostProcessor"/>
|
||||
<copyPastePostProcessor implementation="org.jetbrains.jet.plugin.codeInsight.KotlinCopyPasteReferenceProcessor"/>
|
||||
|
||||
<lang.documentationProvider language="JAVA" implementationClass="org.jetbrains.jet.plugin.JetQuickDocumentationProvider" order="first"/>
|
||||
<documentationProvider implementation="org.jetbrains.jet.plugin.JetQuickDocumentationProvider"/>
|
||||
<configurationType implementation="org.jetbrains.jet.plugin.run.JetRunConfigurationType"/>
|
||||
|
||||
@@ -0,0 +1,390 @@
|
||||
/*
|
||||
* Copyright 2010-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.plugin.codeInsight
|
||||
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.codeInsight.editorActions.ReferenceData
|
||||
import java.util.ArrayList
|
||||
import com.intellij.openapi.editor.RangeMarker
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.codeInsight.editorActions.ReferenceTransferableData
|
||||
import com.intellij.codeInsight.daemon.impl.CollectHighlightsUtil
|
||||
import org.jetbrains.jet.lang.psi.JetFile
|
||||
import org.jetbrains.jet.plugin.quickfix.ImportInsertHelper
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Ref
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import java.awt.datatransfer.Transferable
|
||||
import com.intellij.codeInsight.CodeInsightSettings
|
||||
import com.intellij.codeInsight.editorActions.CopyPastePostProcessor
|
||||
import org.jetbrains.jet.plugin.references.JetReference
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import java.util.Collections
|
||||
import org.jetbrains.jet.lang.psi.JetPsiFactory
|
||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.jet.lang.psi.JetCallExpression
|
||||
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.jet.lang.types.ErrorUtils
|
||||
import org.jetbrains.jet.lang.psi.JetImportDirective
|
||||
import org.jetbrains.jet.lang.psi.JetPackageDirective
|
||||
import org.jetbrains.jet.plugin.references.JetMultiReference
|
||||
import org.jetbrains.jet.lang.psi.JetElement
|
||||
import org.jetbrains.jet.lang.psi.JetThisExpression
|
||||
import org.jetbrains.jet.lang.psi.JetSuperExpression
|
||||
import org.jetbrains.jet.plugin.conversion.copy.*
|
||||
import java.awt.datatransfer.UnsupportedFlavorException
|
||||
import java.io.IOException
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor
|
||||
import org.jetbrains.jet.lang.psi.JetUserType
|
||||
import org.jetbrains.jet.lang.psi.JetTypeReference
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils
|
||||
import org.jetbrains.jet.lang.descriptors.PackageViewDescriptor
|
||||
|
||||
//NOTE: this class is based on CopyPasteReferenceProcessor and JavaCopyPasteReferenceProcessor
|
||||
public class KotlinCopyPasteReferenceProcessor() : CopyPastePostProcessor<ReferenceTransferableData?> {
|
||||
|
||||
override fun extractTransferableData(content: Transferable): ReferenceTransferableData? {
|
||||
//NOTE: copied code
|
||||
var referenceData: ReferenceTransferableData? = null
|
||||
if (CodeInsightSettings.getInstance()!!.ADD_IMPORTS_ON_PASTE != CodeInsightSettings.NO) {
|
||||
try {
|
||||
val flavor = ReferenceData.getDataFlavor()
|
||||
if (flavor != null) {
|
||||
referenceData = content.getTransferData(flavor) as ReferenceTransferableData
|
||||
}
|
||||
}
|
||||
catch (ignored: UnsupportedFlavorException) {
|
||||
}
|
||||
catch (ignored: IOException) {
|
||||
}
|
||||
}
|
||||
|
||||
if (referenceData != null) {
|
||||
// copy to prevent changing of original by convertLineSeparators
|
||||
return referenceData!!.clone()
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
override fun collectTransferableData(
|
||||
file: PsiFile,
|
||||
editor: Editor,
|
||||
startOffsets: IntArray,
|
||||
endOffsets: IntArray
|
||||
): ReferenceTransferableData? {
|
||||
if (file !is JetFile) {
|
||||
return null
|
||||
}
|
||||
|
||||
val collectedData = zip(startOffsets, endOffsets).toList().flatMap {
|
||||
val (startOffset, endOffset) = it
|
||||
CollectHighlightsUtil.getElementsInRange(file, startOffset, endOffset).flatMap { element ->
|
||||
collectReferenceDataFromElement(element, file, startOffset, startOffsets, endOffsets)
|
||||
}
|
||||
}
|
||||
if (collectedData.isEmpty()) {
|
||||
return null
|
||||
}
|
||||
|
||||
return ReferenceTransferableData(collectedData.copyToArray())
|
||||
}
|
||||
|
||||
private fun collectReferenceDataFromElement(
|
||||
element: PsiElement,
|
||||
file: JetFile,
|
||||
startOffset: Int,
|
||||
startOffsets: IntArray,
|
||||
endOffsets: IntArray
|
||||
): Collection<ReferenceData> {
|
||||
|
||||
fun collectReferenceData(referencedDeclaration: PsiElement, referencedDescriptor: DeclarationDescriptor): ReferenceData? {
|
||||
if (referencedDeclaration.isInCopiedArea(file, startOffsets, endOffsets)) {
|
||||
return null
|
||||
}
|
||||
val isExpressionWithReceiver = element is JetSimpleNameExpression && element.getReceiverExpression() != null
|
||||
if (isExpressionWithReceiver && !referencedDescriptor.isExtension) {
|
||||
return null
|
||||
}
|
||||
val fqName = referencedDescriptor.importableFqName
|
||||
if (fqName != null && referencedDescriptor.canBeReferencedViaImport()) {
|
||||
return createReferenceData(element, startOffset, fqName)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
val isInsideIgnoredElement = PsiTreeUtil.getParentOfType(element, *IGNORE_REFERENCES_INSIDE) != null
|
||||
if (isInsideIgnoredElement) {
|
||||
return Collections.emptyList()
|
||||
}
|
||||
val reference = element.getReference()
|
||||
if (reference !is JetReference) {
|
||||
return Collections.emptyList()
|
||||
}
|
||||
|
||||
val resolveMap = reference.resolveMap()
|
||||
//check whether this reference is unambiguous
|
||||
if (reference !is JetMultiReference<*> && resolveMap.size > 1) {
|
||||
return Collections.emptyList()
|
||||
}
|
||||
val collectedData = ArrayList<ReferenceData>()
|
||||
for ((referencedDescriptor, declarations) in resolveMap) {
|
||||
if (declarations.size != 1) {
|
||||
continue
|
||||
}
|
||||
collectedData.addIfNotNull(collectReferenceData(declarations.first(), referencedDescriptor))
|
||||
}
|
||||
return collectedData
|
||||
}
|
||||
|
||||
private fun DeclarationDescriptor.canBeReferencedViaImport(): Boolean {
|
||||
if (this is PackageViewDescriptor || DescriptorUtils.isTopLevelDeclaration(this)) {
|
||||
return true
|
||||
}
|
||||
val parent = getContainingDeclaration()!!
|
||||
if (parent !is ClassDescriptor || !parent.canBeReferencedViaImport()) {
|
||||
return false
|
||||
}
|
||||
// inner class constructors can't be referenced via import
|
||||
if (this is ConstructorDescriptor && parent.isInner()) {
|
||||
return false
|
||||
}
|
||||
return this is ClassDescriptor || this is ConstructorDescriptor
|
||||
}
|
||||
|
||||
private fun createReferenceData(element: PsiElement, startOffset: Int, fqName: FqName): ReferenceData {
|
||||
val range = element.range
|
||||
return ReferenceData(range.start - startOffset, range.end - startOffset, fqName.asString(), null)
|
||||
}
|
||||
|
||||
private data class ReferenceToRestoreData(
|
||||
val expression: JetElement,
|
||||
val fqName: FqName,
|
||||
val lengthenReference: Boolean = false
|
||||
)
|
||||
|
||||
override fun processTransferableData (
|
||||
project: Project,
|
||||
editor: Editor,
|
||||
bounds: RangeMarker,
|
||||
caretOffset: Int,
|
||||
indented: Ref<Boolean>,
|
||||
value: ReferenceTransferableData?
|
||||
) {
|
||||
if (DumbService.getInstance(project)!!.isDumb()) {
|
||||
return
|
||||
}
|
||||
val document = editor.getDocument()
|
||||
val file = PsiDocumentManager.getInstance(project).getPsiFile(document)
|
||||
if (file !is JetFile) {
|
||||
return
|
||||
}
|
||||
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val referenceData = value!!.getData()!!
|
||||
val referencesPossibleToRestore = findReferencesToRestore(file, bounds, referenceData)
|
||||
|
||||
val selectedReferencesToRestore = showRestoreReferencesDialog(project, referencesPossibleToRestore)
|
||||
if (selectedReferencesToRestore.isEmpty()) {
|
||||
return
|
||||
}
|
||||
ApplicationManager.getApplication()!!.runWriteAction(Runnable {
|
||||
restoreReferences(selectedReferencesToRestore, file)
|
||||
})
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
}
|
||||
|
||||
private fun findReferencesToRestore(file: PsiFile, bounds: RangeMarker, referenceData: Array<out ReferenceData>): List<ReferenceToRestoreData> {
|
||||
if (file !is JetFile) {
|
||||
return Collections.emptyList()
|
||||
}
|
||||
return referenceData.map {
|
||||
val referenceExpression = findReference(it, file, bounds)
|
||||
if (referenceExpression != null) createReferenceToRestoreData(referenceExpression, it.fqName) else null
|
||||
}.filterNotNull()
|
||||
}
|
||||
|
||||
private fun findReference(data: ReferenceData, file: JetFile, bounds: RangeMarker): JetElement? {
|
||||
val startOffset = data.startOffset + bounds.getStartOffset()
|
||||
val endOffset = data.endOffset + bounds.getStartOffset()
|
||||
val element = file.findElementAt(startOffset)
|
||||
val desiredRange = TextRange(startOffset, endOffset)
|
||||
var expression = element
|
||||
while (expression != null) {
|
||||
val range = expression!!.range
|
||||
if (range == desiredRange && expression!!.getReference() != null) {
|
||||
return expression as? JetElement
|
||||
}
|
||||
if (range in desiredRange) {
|
||||
expression = expression!!.getParent()
|
||||
}
|
||||
else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun createReferenceToRestoreData(expression: JetElement, originalReferencedFqName: FqName): ReferenceToRestoreData? {
|
||||
val reference = expression.getReference() as? JetReference
|
||||
if (reference == null) {
|
||||
return null
|
||||
}
|
||||
val referencedDescriptors = reference.resolveToDescriptors()
|
||||
val referencedFqNames = referencedDescriptors.filterNot { ErrorUtils.isError(it) } .map { it.importableFqName }
|
||||
val referencesSame = referencedFqNames any { it == originalReferencedFqName }
|
||||
val conflict = referencedFqNames any { it != originalReferencedFqName && (it?.shortName() == originalReferencedFqName.shortName()) }
|
||||
when {
|
||||
referencesSame && !conflict -> {
|
||||
return null
|
||||
}
|
||||
!referencesSame && !conflict -> {
|
||||
return ReferenceToRestoreData(expression, originalReferencedFqName)
|
||||
}
|
||||
conflict -> {
|
||||
val mustBeReferencedWithReceiver = referencedDescriptors.any { it.isExtension }
|
||||
if (!mustBeReferencedWithReceiver && LengthenReferences.canLengthenReferenceExpression(expression, originalReferencedFqName)) {
|
||||
return ReferenceToRestoreData(expression, originalReferencedFqName, lengthenReference = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun restoreReferences(referencesToRestore: Collection<ReferenceToRestoreData>, file: JetFile) {
|
||||
for ((referenceExpression, fqName, shouldLengthen) in referencesToRestore) {
|
||||
if (!shouldLengthen) {
|
||||
ImportInsertHelper.addImportDirectiveIfNeeded(fqName, file)
|
||||
}
|
||||
else {
|
||||
//TODO: try to shorten reference after (sometimes is possible), need shorten reference to support all relevant cases
|
||||
LengthenReferences.lengthenReference(referenceExpression, fqName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showRestoreReferencesDialog(project: Project, referencesToRestore: List<ReferenceToRestoreData>): Collection<ReferenceToRestoreData> {
|
||||
val shouldShowDialog = CodeInsightSettings.getInstance()!!.ADD_IMPORTS_ON_PASTE == CodeInsightSettings.ASK
|
||||
if (!shouldShowDialog || referencesToRestore.isEmpty()) {
|
||||
return referencesToRestore
|
||||
}
|
||||
val fqNames = referencesToRestore. map { it.fqName.asString() }.toSortedSet()
|
||||
val dialog = RestoreReferencesDialog(project, fqNames.copyToArray())
|
||||
dialog.show()
|
||||
val selectedFqNames = dialog.getSelectedElements()!!.toSet()
|
||||
return referencesToRestore.filter { ref -> selectedFqNames.contains(ref.fqName.asString()) }
|
||||
}
|
||||
|
||||
class object {
|
||||
private val IGNORE_REFERENCES_INSIDE: Array<Class<out JetElement>?> = array(
|
||||
javaClass<JetImportDirective>(),
|
||||
javaClass<JetPackageDirective>(),
|
||||
javaClass<JetSuperExpression>(),
|
||||
javaClass<JetThisExpression>()
|
||||
)
|
||||
}
|
||||
|
||||
private object LengthenReferences {
|
||||
private val LOG = Logger.getInstance(javaClass<KotlinCopyPasteReferenceProcessor>())
|
||||
|
||||
private fun createQualifiedExpression(project: Project, text: String): JetDotQualifiedExpression {
|
||||
val newExpression = JetPsiFactory.createExpression(project, text)
|
||||
LOG.assertTrue(newExpression is JetDotQualifiedExpression,
|
||||
"\"${newExpression.getText()}\" is ${newExpression.javaClass}," +
|
||||
"not ${javaClass<JetDotQualifiedExpression>().getSimpleName()}."
|
||||
)
|
||||
return newExpression as JetDotQualifiedExpression
|
||||
}
|
||||
|
||||
fun lengthenReference(expression: JetElement, fqName: FqName) {
|
||||
assert(canLengthenReferenceExpression(expression, fqName))
|
||||
val project = expression.getProject()
|
||||
val parent = expression.getParent()
|
||||
val prefixToInsert = fqName.parent().asString()
|
||||
if (parent is JetCallExpression) {
|
||||
val text = "$prefixToInsert.${parent.getText()}"
|
||||
parent.replace(createQualifiedExpression(project, text))
|
||||
}
|
||||
else if (parent is JetUserType) {
|
||||
val typeReference = PsiTreeUtil.getParentOfType(expression, javaClass<JetTypeReference>())
|
||||
LOG.assertTrue(typeReference != null, "JetUserType is expected to have parent of type JetTypeReference:\n" +
|
||||
"At: ${DiagnosticUtils.atLocation(expression)}\nFILE:\n${expression.getContainingFile()!!.getText()}")
|
||||
typeReference!!.replace(JetPsiFactory.createType(project, "$prefixToInsert.${typeReference.getText()}"))
|
||||
}
|
||||
else {
|
||||
expression.replace(createQualifiedExpression(project, fqName.asString()))
|
||||
}
|
||||
}
|
||||
|
||||
fun canLengthenReferenceExpression(expression: JetElement, fqName: FqName): Boolean {
|
||||
if (fqName.pathSegments().size() < 2) {
|
||||
return false
|
||||
}
|
||||
if (expression is JetSimpleNameExpression && expression.getReceiverExpression() == null) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val ReferenceData.fqName: FqName
|
||||
get() = FqName(qClassName!!)
|
||||
|
||||
private fun zip(first: IntArray, second: IntArray): Iterator<Pair<Int, Int>> {
|
||||
assert(first.size == second.size)
|
||||
return first.iterator().zip(second.iterator())
|
||||
}
|
||||
|
||||
private fun PsiElement.isInCopiedArea(fileCopiedFrom: JetFile, startOffsets: IntArray, endOffsets: IntArray): Boolean {
|
||||
if (getContainingFile() != fileCopiedFrom) {
|
||||
return false
|
||||
}
|
||||
return zip(startOffsets, endOffsets).any {
|
||||
val (start, end) = it
|
||||
range in TextRange(start, end)
|
||||
}
|
||||
}
|
||||
|
||||
private val DeclarationDescriptor.importableFqName: FqName?
|
||||
get() {
|
||||
if (this is ConstructorDescriptor) return getContainingDeclaration().importableFqName
|
||||
val mayBeUnsafe = DescriptorUtils.getFqName(this)
|
||||
return if (mayBeUnsafe.isSafe()) {
|
||||
mayBeUnsafe.toSafe()
|
||||
}
|
||||
else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private val DeclarationDescriptor.isExtension: Boolean
|
||||
get() = this is CallableDescriptor && getReceiverParameter() != null
|
||||
|
||||
private fun <T : Any> MutableCollection<T>.addIfNotNull(el: T?) = ContainerUtil.addIfNotNull(this, el)
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2010-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.plugin.codeInsight;
|
||||
|
||||
import com.intellij.CommonBundle;
|
||||
import com.intellij.codeInsight.CodeInsightBundle;
|
||||
import com.intellij.ide.util.FQNameCellRenderer;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.VerticalFlowLayout;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.intellij.ui.components.JBLabel;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
import static com.intellij.util.ui.UIUtil.ComponentStyle.SMALL;
|
||||
import static com.intellij.util.ui.UIUtil.FontColor.BRIGHTER;
|
||||
|
||||
//TODO: this is a copy of com.intellij.codeInsight.editorActions.RestoreReferencesDialog
|
||||
//consider improving rendering of list cells if you decide to submit pull request to idea (or improve this version)
|
||||
public class RestoreReferencesDialog extends DialogWrapper {
|
||||
private final Object[] myNamedElements;
|
||||
private JList myList;
|
||||
private Object[] mySelectedElements = PsiClass.EMPTY_ARRAY;
|
||||
private boolean myContainsClassesOnly = true;
|
||||
|
||||
public RestoreReferencesDialog(final Project project, final Object[] elements) {
|
||||
super(project, true);
|
||||
myNamedElements = elements;
|
||||
for (Object element : elements) {
|
||||
if (!(element instanceof PsiClass)) {
|
||||
myContainsClassesOnly = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (myContainsClassesOnly) {
|
||||
setTitle(CodeInsightBundle.message("dialog.import.on.paste.title"));
|
||||
}
|
||||
else {
|
||||
setTitle(CodeInsightBundle.message("dialog.import.on.paste.title2"));
|
||||
}
|
||||
init();
|
||||
|
||||
myList.setSelectionInterval(0, myNamedElements.length - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doOKAction() {
|
||||
Object[] values = myList.getSelectedValues();
|
||||
mySelectedElements = new Object[values.length];
|
||||
System.arraycopy(values, 0, mySelectedElements, 0, values.length);
|
||||
super.doOKAction();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent createCenterPanel() {
|
||||
final JPanel panel = new JPanel(new BorderLayout(UIUtil.DEFAULT_HGAP, UIUtil.DEFAULT_VGAP));
|
||||
myList = new JBList(myNamedElements);
|
||||
myList.setCellRenderer(new FQNameCellRenderer());
|
||||
panel.add(ScrollPaneFactory.createScrollPane(myList), BorderLayout.CENTER);
|
||||
|
||||
panel.add(new JBLabel(myContainsClassesOnly ?
|
||||
CodeInsightBundle.message("dialog.paste.on.import.text") :
|
||||
CodeInsightBundle.message("dialog.paste.on.import.text2"), SMALL, BRIGHTER), BorderLayout.NORTH);
|
||||
|
||||
final JPanel buttonPanel = new JPanel(new VerticalFlowLayout());
|
||||
final JButton okButton = new JButton(CommonBundle.getOkButtonText());
|
||||
getRootPane().setDefaultButton(okButton);
|
||||
buttonPanel.add(okButton);
|
||||
final JButton cancelButton = new JButton(CommonBundle.getCancelButtonText());
|
||||
buttonPanel.add(cancelButton);
|
||||
|
||||
panel.setPreferredSize(new Dimension(500, 400));
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected String getDimensionServiceKey(){
|
||||
return "#com.intellij.codeInsight.editorActions.RestoreReferencesDialog";
|
||||
}
|
||||
|
||||
public Object[] getSelectedElements(){
|
||||
return mySelectedElements;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package to
|
||||
|
||||
import a.*
|
||||
import a.E.ENTRY
|
||||
import a.Outer.Inner
|
||||
import a.Outer.Nested
|
||||
import a.Outer.NestedEnum
|
||||
import a.Outer.NestedObj
|
||||
import a.Outer.NestedTrait
|
||||
import a.Outer.NestedAnnotation
|
||||
|
||||
fun f(a: A, t: T) {
|
||||
g(A(c).ext())
|
||||
O1.f()
|
||||
O2
|
||||
ENTRY
|
||||
}
|
||||
|
||||
fun f2(i: Inner, n: Nested, e: NestedEnum, o: NestedObj, t: NestedTrait, a: NestedAnnotation) {
|
||||
ClassObject
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package a
|
||||
|
||||
import a.E.ENTRY
|
||||
import a.Outer.*
|
||||
|
||||
trait T
|
||||
|
||||
class A(i: Int) {}
|
||||
|
||||
val c = 0
|
||||
|
||||
fun g(a: A) {}
|
||||
|
||||
fun A.ext()
|
||||
|
||||
object O1 {
|
||||
fun f() {
|
||||
}
|
||||
}
|
||||
|
||||
object O2 {
|
||||
}
|
||||
|
||||
enum class E {
|
||||
ENTRY
|
||||
}
|
||||
|
||||
class Outer {
|
||||
inner class Inner {
|
||||
}
|
||||
class Nested {
|
||||
}
|
||||
enum class NestedEnum {
|
||||
}
|
||||
object NestedObj {
|
||||
}
|
||||
trait NestedTrait {
|
||||
}
|
||||
annotation class NestedAnnotation
|
||||
}
|
||||
|
||||
class ClassObject {
|
||||
class object {
|
||||
}
|
||||
}
|
||||
|
||||
<selection>fun f(a: A, t: T) {
|
||||
g(A(c).ext())
|
||||
O1.f()
|
||||
O2
|
||||
ENTRY
|
||||
}
|
||||
|
||||
fun f2(i: Inner, n: Nested, e: NestedEnum, o: NestedObj, t: NestedTrait, a: NestedAnnotation) {
|
||||
ClassObject
|
||||
}</selection>
|
||||
@@ -0,0 +1,5 @@
|
||||
package to
|
||||
|
||||
import a.*
|
||||
|
||||
<caret>
|
||||
@@ -0,0 +1,7 @@
|
||||
package b
|
||||
|
||||
import a.A
|
||||
|
||||
fun f(a: A) {
|
||||
A()
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package a
|
||||
|
||||
class A() {}
|
||||
|
||||
<selection>fun f(a: A) {
|
||||
A()
|
||||
}</selection>
|
||||
@@ -0,0 +1,5 @@
|
||||
package b
|
||||
|
||||
import a.A
|
||||
|
||||
<caret>
|
||||
@@ -0,0 +1,3 @@
|
||||
package to
|
||||
|
||||
fun f() = c + d + g + j()
|
||||
@@ -0,0 +1,14 @@
|
||||
package a
|
||||
|
||||
// ALLOW_UNRESOLVED
|
||||
|
||||
class A(val c: Int = 1) {
|
||||
var d = 2
|
||||
|
||||
val g: Int
|
||||
get() = d
|
||||
|
||||
fun j() = c
|
||||
|
||||
<selection>fun f() = c + d + g + j()</selection>
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package to
|
||||
|
||||
import a.T
|
||||
import a.A
|
||||
import a.B
|
||||
|
||||
fun g(t: T): Int {
|
||||
g(A)
|
||||
B.f()
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package a
|
||||
|
||||
trait T
|
||||
|
||||
class A {
|
||||
class object: T {
|
||||
}
|
||||
}
|
||||
|
||||
class B {
|
||||
class object {
|
||||
fun f(): Int
|
||||
}
|
||||
}
|
||||
|
||||
<selection>fun g(t: T): Int {
|
||||
g(A)
|
||||
B.f()
|
||||
}</selection>
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package to
|
||||
|
||||
fun g() {
|
||||
f()
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package a
|
||||
|
||||
// ALLOW_UNRESOLVED
|
||||
//NOTE: is is an unsupported case
|
||||
class A {
|
||||
<selection>fun g() {
|
||||
f()
|
||||
}</selection>
|
||||
|
||||
class object {
|
||||
fun f()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package to
|
||||
|
||||
import a.Outer.Inner
|
||||
import a.Outer.Nested
|
||||
import a.Outer.NestedEnum
|
||||
import a.Outer.NestedObj
|
||||
import a.Outer.NestedTrait
|
||||
import a.Outer.NestedAnnotation
|
||||
|
||||
fun f(i: Inner, n: Nested, e: NestedEnum, o: NestedObj, t: NestedTrait, a: NestedAnnotation) {
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package a
|
||||
|
||||
import a.Outer.*
|
||||
|
||||
class Outer {
|
||||
class object {
|
||||
inner class Inner {
|
||||
}
|
||||
class Nested {
|
||||
}
|
||||
enum class NestedEnum {
|
||||
}
|
||||
object NestedObj {
|
||||
}
|
||||
trait NestedTrait {
|
||||
}
|
||||
annotation class NestedAnnotation
|
||||
}
|
||||
}
|
||||
|
||||
<selection>fun f(i: Inner, n: Nested, e: NestedEnum, o: NestedObj, t: NestedTrait, a: NestedAnnotation) {
|
||||
}</selection>
|
||||
@@ -0,0 +1,6 @@
|
||||
package to
|
||||
|
||||
fun f(i: a.a) {
|
||||
a.a
|
||||
a.a()
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package a
|
||||
|
||||
//NOTE: this case can be improved by using shorten reference after importing
|
||||
class a {
|
||||
class object {
|
||||
}
|
||||
}
|
||||
|
||||
<selection>fun f(i: a) {
|
||||
a
|
||||
a()
|
||||
}</selection>
|
||||
@@ -0,0 +1,6 @@
|
||||
package to
|
||||
|
||||
import a.A
|
||||
|
||||
fun f(a: A) {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package a
|
||||
|
||||
class A() {}
|
||||
|
||||
<selection>fun f(a: A) {
|
||||
}</selection>
|
||||
@@ -0,0 +1,19 @@
|
||||
package to
|
||||
|
||||
class C {
|
||||
}
|
||||
|
||||
val c = 1
|
||||
|
||||
fun g() {
|
||||
}
|
||||
|
||||
fun C.ext() {
|
||||
}
|
||||
|
||||
fun f() {
|
||||
a.c
|
||||
a.g()
|
||||
a.C()
|
||||
a.C().ext()
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package a
|
||||
|
||||
// ALLOW_UNRESOLVED
|
||||
|
||||
class C {
|
||||
}
|
||||
|
||||
val c = 1
|
||||
|
||||
fun g() {
|
||||
}
|
||||
|
||||
fun C.ext() {
|
||||
}
|
||||
|
||||
<selection>fun f() {
|
||||
c
|
||||
g()
|
||||
C()
|
||||
C().ext()
|
||||
}</selection>
|
||||
@@ -0,0 +1,14 @@
|
||||
package to
|
||||
|
||||
class C {
|
||||
}
|
||||
|
||||
val c = 1
|
||||
|
||||
fun g() {
|
||||
}
|
||||
|
||||
fun C.ext() {
|
||||
}
|
||||
|
||||
<caret>
|
||||
@@ -0,0 +1,7 @@
|
||||
package to
|
||||
|
||||
class A<T> {
|
||||
}
|
||||
|
||||
fun f(b: a.A<Int>) {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package a
|
||||
|
||||
class A<T> {
|
||||
}
|
||||
|
||||
<selection>fun f(b: A<Int>) {
|
||||
}</selection>
|
||||
@@ -0,0 +1,6 @@
|
||||
package to
|
||||
|
||||
class A<T> {
|
||||
}
|
||||
|
||||
<caret>
|
||||
@@ -0,0 +1,7 @@
|
||||
package to
|
||||
|
||||
class A() {
|
||||
}
|
||||
|
||||
fun f(a: a.A) {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package a
|
||||
|
||||
class A() {
|
||||
}
|
||||
|
||||
<selection>fun f(a: A) {
|
||||
}</selection>
|
||||
@@ -0,0 +1,6 @@
|
||||
package to
|
||||
|
||||
class A() {
|
||||
}
|
||||
|
||||
<caret>
|
||||
@@ -0,0 +1,6 @@
|
||||
package to
|
||||
|
||||
fun f() {
|
||||
}
|
||||
|
||||
fun g() = a.f()
|
||||
@@ -0,0 +1,6 @@
|
||||
package a
|
||||
|
||||
fun f() {
|
||||
}
|
||||
|
||||
<selection>fun g() = f()</selection>
|
||||
@@ -0,0 +1,6 @@
|
||||
package to
|
||||
|
||||
fun f() {
|
||||
}
|
||||
|
||||
<caret>
|
||||
@@ -0,0 +1,7 @@
|
||||
package b
|
||||
|
||||
import a.A
|
||||
|
||||
fun b() {
|
||||
A()
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package a
|
||||
|
||||
class A() {}
|
||||
|
||||
val c = <selection>A()</selection>
|
||||
@@ -0,0 +1,5 @@
|
||||
package b
|
||||
|
||||
fun b() {
|
||||
<caret>
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package to
|
||||
|
||||
import a.Outer.Nested.NN
|
||||
import a.Outer.Nested.NI
|
||||
import a.Outer.Inner.IN
|
||||
import a.Outer.Inner.II
|
||||
import a.Outer.Nested.NN2
|
||||
import a.with
|
||||
import a.Outer
|
||||
import a.Outer.Inner.IN2
|
||||
|
||||
fun f(p1: NN, p2: NI, p3: IN, p4: II) {
|
||||
NN2()
|
||||
with(Outer.Nested()) {
|
||||
NI2()
|
||||
}
|
||||
IN2()
|
||||
with(Outer().Inner()) {
|
||||
II2()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package a
|
||||
|
||||
import a.Outer.Nested.*
|
||||
import a.Outer.Inner.*
|
||||
|
||||
class Outer {
|
||||
class Nested {
|
||||
class NN {
|
||||
}
|
||||
class NN2 {
|
||||
}
|
||||
inner class NI {
|
||||
}
|
||||
inner class NI2 {
|
||||
}
|
||||
}
|
||||
|
||||
inner class Inner {
|
||||
class IN {
|
||||
}
|
||||
class IN2 {
|
||||
}
|
||||
inner class II {
|
||||
}
|
||||
inner class II2 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> with(v: T, body: T.() -> Unit) = v.body()
|
||||
|
||||
<selection>fun f(p1: NN, p2: NI, p3: IN, p4: II) {
|
||||
NN2()
|
||||
with(Outer.Nested()) {
|
||||
NI2()
|
||||
}
|
||||
IN2()
|
||||
with(Outer().Inner()) {
|
||||
II2()
|
||||
}
|
||||
}</selection>
|
||||
@@ -0,0 +1,3 @@
|
||||
package to
|
||||
|
||||
val c = A()
|
||||
@@ -0,0 +1,6 @@
|
||||
// ALLOW_UNRESOLVED
|
||||
|
||||
class A {
|
||||
}
|
||||
|
||||
<selection>val c = A()</selection>
|
||||
@@ -0,0 +1,9 @@
|
||||
package to
|
||||
|
||||
import a.A
|
||||
import a.get
|
||||
import a.set
|
||||
|
||||
class B {
|
||||
var a by A()
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package a
|
||||
|
||||
trait T
|
||||
|
||||
fun T.get(thisRef: B, desc: PropertyMetadata): Int {
|
||||
return 3
|
||||
}
|
||||
|
||||
fun T.set(thisRef: B, desc: PropertyMetadata, value: Int) {
|
||||
}
|
||||
|
||||
class A(): T
|
||||
|
||||
<selection>class B {
|
||||
var a by A()
|
||||
}</selection>
|
||||
@@ -0,0 +1,16 @@
|
||||
package java;
|
||||
|
||||
public class JavaClass {
|
||||
public static int staticMethod() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
public void method() {
|
||||
}
|
||||
|
||||
public class InnerClass {
|
||||
}
|
||||
|
||||
public class NestedClass {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package to
|
||||
|
||||
import java.JavaClass
|
||||
import java.JavaClass.staticMethod
|
||||
import java.JavaClass.NestedClass
|
||||
|
||||
fun f(c: JavaClass) {
|
||||
staticMethod()
|
||||
c.method()
|
||||
c.InnerClass()
|
||||
NestedClass()
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package a
|
||||
|
||||
import java.JavaClass
|
||||
import java.JavaClass.NestedClass
|
||||
import java.JavaClass.staticMethod
|
||||
|
||||
|
||||
<selection>fun f(c: JavaClass) {
|
||||
staticMethod()
|
||||
c.method()
|
||||
c.InnerClass()
|
||||
NestedClass()
|
||||
}</selection>
|
||||
@@ -0,0 +1,28 @@
|
||||
package to
|
||||
|
||||
import d.A
|
||||
import d.T
|
||||
import d.g
|
||||
import d.c
|
||||
import d.ext
|
||||
import d.O1
|
||||
import d.O2
|
||||
import d.E.ENTRY
|
||||
import d.Outer.Inner
|
||||
import d.Outer.Nested
|
||||
import d.Outer.NestedEnum
|
||||
import d.Outer.NestedObj
|
||||
import d.Outer.NestedTrait
|
||||
import d.Outer.NestedAnnotation
|
||||
import d.ClassObject
|
||||
|
||||
fun f(a: A, t: T) {
|
||||
g(A(c).ext())
|
||||
O1.f()
|
||||
O2
|
||||
ENTRY
|
||||
}
|
||||
|
||||
fun f2(i: Inner, n: Nested, e: NestedEnum, o: NestedObj, t: NestedTrait, a: NestedAnnotation) {
|
||||
ClassObject
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// WITH_LIBRARY: copyPaste/imports/KotlinLibrary
|
||||
|
||||
package a
|
||||
|
||||
import d.*
|
||||
import d.E.ENTRY
|
||||
import d.Outer.*
|
||||
|
||||
<selection>fun f(a: A, t: T) {
|
||||
g(A(c).ext())
|
||||
O1.f()
|
||||
O2
|
||||
ENTRY
|
||||
}
|
||||
|
||||
fun f2(i: Inner, n: Nested, e: NestedEnum, o: NestedObj, t: NestedTrait, a: NestedAnnotation) {
|
||||
ClassObject
|
||||
}</selection>
|
||||
@@ -0,0 +1,5 @@
|
||||
package to
|
||||
|
||||
import kotlin.concurrent.FunctionalList
|
||||
|
||||
fun f(l: FunctionalList<Int>) {}
|
||||
@@ -0,0 +1,7 @@
|
||||
// RUNTIME
|
||||
|
||||
package g
|
||||
|
||||
import kotlin.concurrent.FunctionalList
|
||||
|
||||
<selection>fun f(l: FunctionalList<Int>) {}</selection>
|
||||
@@ -0,0 +1,11 @@
|
||||
package to
|
||||
|
||||
import a.A.A
|
||||
import a.A.B
|
||||
import a.A.C
|
||||
|
||||
fun f() {
|
||||
A
|
||||
B
|
||||
C
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package a
|
||||
|
||||
enum class A {
|
||||
A
|
||||
B
|
||||
C
|
||||
|
||||
<selection>fun f() {
|
||||
A
|
||||
B
|
||||
C
|
||||
}</selection>
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package to
|
||||
|
||||
import a.f
|
||||
import a.p
|
||||
import a.g
|
||||
|
||||
fun foo() {
|
||||
3.f()
|
||||
2.p
|
||||
3.g = 5
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package a
|
||||
|
||||
fun Int.f() {}
|
||||
|
||||
val Int.p: Int
|
||||
get() = 2
|
||||
|
||||
var Int.g: Int
|
||||
get() = 1
|
||||
set(i : Int) = Unit
|
||||
|
||||
<selection>fun foo() {
|
||||
3.f()
|
||||
2.p
|
||||
3.g = 5
|
||||
}</selection>
|
||||
@@ -0,0 +1,10 @@
|
||||
package to
|
||||
|
||||
import a.A
|
||||
import a.plus
|
||||
import a.infix
|
||||
|
||||
fun f(a: A) {
|
||||
a + a
|
||||
a infix 1
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package a
|
||||
|
||||
class A() {}
|
||||
|
||||
fun A.plus(a: A) = this
|
||||
|
||||
fun A.infix(i: Int) = i
|
||||
|
||||
<selection>fun f(a: A) {
|
||||
a + a
|
||||
a infix 1
|
||||
}</selection>
|
||||
@@ -0,0 +1,16 @@
|
||||
package to
|
||||
|
||||
import a.A
|
||||
|
||||
fun A.ext() {
|
||||
}
|
||||
|
||||
var A.p: Int
|
||||
get() = 2
|
||||
set(i: Int) = throw UnsupportedOperationException()
|
||||
|
||||
fun A.f() {
|
||||
ext()
|
||||
p
|
||||
p = 3
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package a
|
||||
|
||||
class A() {
|
||||
}
|
||||
|
||||
fun A.ext() {
|
||||
}
|
||||
|
||||
var A.p: Int
|
||||
get() = 2
|
||||
set(i: Int) = throw UnsupportedOperationException()
|
||||
|
||||
<selection>fun A.f() {
|
||||
ext()
|
||||
p
|
||||
p = 3
|
||||
}</selection>
|
||||
@@ -0,0 +1,12 @@
|
||||
package to
|
||||
|
||||
import a.A
|
||||
|
||||
fun A.ext() {
|
||||
}
|
||||
|
||||
var A.p: Int
|
||||
get() = 2
|
||||
set(i: Int) = throw UnsupportedOperationException()
|
||||
|
||||
<caret>
|
||||
@@ -0,0 +1,26 @@
|
||||
package to
|
||||
|
||||
import a.A
|
||||
|
||||
fun A.ext() {
|
||||
}
|
||||
|
||||
fun A.infix(a: A) {
|
||||
}
|
||||
|
||||
fun A.plus(a: A) {
|
||||
}
|
||||
|
||||
fun A.minus() {
|
||||
}
|
||||
|
||||
val A.p: Int
|
||||
get() = 2
|
||||
|
||||
fun f() {
|
||||
A().ext()
|
||||
A() + A()
|
||||
A() infix A()
|
||||
-A()
|
||||
A().p
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package a
|
||||
|
||||
class A {
|
||||
}
|
||||
|
||||
fun A.ext() {
|
||||
}
|
||||
|
||||
fun A.infix(a: A) {
|
||||
}
|
||||
|
||||
fun A.plus(a: A) {
|
||||
}
|
||||
|
||||
fun A.minus() {
|
||||
}
|
||||
|
||||
val A.p: Int
|
||||
get() = 2
|
||||
|
||||
<selection>fun f() {
|
||||
A().ext()
|
||||
A() + A()
|
||||
A() infix A()
|
||||
-A()
|
||||
A().p
|
||||
}</selection>
|
||||
@@ -0,0 +1,20 @@
|
||||
package to
|
||||
|
||||
import a.A
|
||||
|
||||
fun A.ext() {
|
||||
}
|
||||
|
||||
fun A.infix(a: A) {
|
||||
}
|
||||
|
||||
fun A.plus(a: A) {
|
||||
}
|
||||
|
||||
fun A.minus() {
|
||||
}
|
||||
|
||||
val A.p: Int
|
||||
get() = 2
|
||||
|
||||
<caret>
|
||||
@@ -0,0 +1,11 @@
|
||||
package to
|
||||
|
||||
import a.A
|
||||
import a.iterator
|
||||
import a.next
|
||||
import a.hasNext
|
||||
|
||||
fun f() {
|
||||
for (i in A()) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package a
|
||||
|
||||
class A() {
|
||||
}
|
||||
|
||||
class B() {
|
||||
}
|
||||
|
||||
fun B.next(): Int = 3
|
||||
|
||||
fun B.hasNext(): Boolean = false
|
||||
|
||||
fun A.iterator() = B()
|
||||
|
||||
<selection>fun f() {
|
||||
for (i in A()) {
|
||||
}
|
||||
}</selection>
|
||||
@@ -0,0 +1,3 @@
|
||||
package to
|
||||
|
||||
fun f(t: a.b.c.A): a.b.c.B = a.b.c.B()
|
||||
@@ -0,0 +1,7 @@
|
||||
package a.b.c
|
||||
|
||||
class A() {}
|
||||
|
||||
class B() {}
|
||||
|
||||
<selection>fun f(t: a.b.c.A): a.b.c.B = a.b.c.B()</selection>
|
||||
@@ -0,0 +1,7 @@
|
||||
package to
|
||||
|
||||
import a.g
|
||||
|
||||
fun f() {
|
||||
g()
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package a
|
||||
|
||||
fun g() {
|
||||
}
|
||||
|
||||
<selection>fun f() {
|
||||
g()
|
||||
}</selection>
|
||||
@@ -0,0 +1,7 @@
|
||||
package b
|
||||
|
||||
import a.g
|
||||
|
||||
fun f() {
|
||||
g()
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package a
|
||||
|
||||
fun g() {
|
||||
}
|
||||
|
||||
<selection>fun f() {
|
||||
g()
|
||||
}</selection>
|
||||
@@ -0,0 +1,5 @@
|
||||
package b
|
||||
|
||||
import a.g
|
||||
|
||||
<caret>
|
||||
@@ -0,0 +1,7 @@
|
||||
package to
|
||||
|
||||
fun f() {
|
||||
val r = arrayListOf<T>()
|
||||
r.addAll(b)
|
||||
val x = c
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
//RUNTIME
|
||||
// ALLOW_UNRESOLVED
|
||||
|
||||
package a
|
||||
|
||||
fun <T> f(c: Int, b: List<T>) {
|
||||
<selection>val r = arrayListOf<T>()
|
||||
r.addAll(b)
|
||||
val x = c</selection>
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package to
|
||||
|
||||
fun f() {
|
||||
<caret>
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package to
|
||||
|
||||
import a.A
|
||||
import a.get
|
||||
|
||||
fun f() {
|
||||
A()[""]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package a
|
||||
|
||||
class A {
|
||||
}
|
||||
|
||||
fun A.get(s: String) {
|
||||
}
|
||||
|
||||
<selection>fun f() {
|
||||
A()[""]
|
||||
}</selection>
|
||||
@@ -0,0 +1,42 @@
|
||||
package d
|
||||
|
||||
trait T
|
||||
|
||||
class A(i: Int) {}
|
||||
|
||||
val c = 0
|
||||
|
||||
fun g(a: A) {}
|
||||
|
||||
fun A.ext()
|
||||
|
||||
object O1 {
|
||||
fun f() {
|
||||
}
|
||||
}
|
||||
|
||||
object O2 {
|
||||
}
|
||||
|
||||
enum class E {
|
||||
ENTRY
|
||||
}
|
||||
|
||||
class Outer {
|
||||
inner class Inner {
|
||||
}
|
||||
class Nested {
|
||||
}
|
||||
enum class NestedEnum {
|
||||
}
|
||||
object NestedObj {
|
||||
}
|
||||
trait NestedTrait {
|
||||
}
|
||||
annotation class NestedAnnotation
|
||||
}
|
||||
|
||||
class ClassObject {
|
||||
class object {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package to
|
||||
|
||||
import d.A
|
||||
import d.T
|
||||
import d.g
|
||||
import d.c
|
||||
import d.ext
|
||||
import d.O1
|
||||
import d.O2
|
||||
import d.E.ENTRY
|
||||
import d.Outer.Inner
|
||||
import d.Outer.Nested
|
||||
import d.Outer.NestedEnum
|
||||
import d.Outer.NestedObj
|
||||
import d.Outer.NestedTrait
|
||||
import d.Outer.NestedAnnotation
|
||||
import d.ClassObject
|
||||
|
||||
fun f(a: A, t: T) {
|
||||
g(A(c).ext())
|
||||
O1.f()
|
||||
O2
|
||||
ENTRY
|
||||
}
|
||||
|
||||
fun f2(i: Inner, n: Nested, e: NestedEnum, o: NestedObj, t: NestedTrait, a: NestedAnnotation) {
|
||||
ClassObject
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package a
|
||||
|
||||
import d.*
|
||||
import d.E.ENTRY
|
||||
import d.Outer.*
|
||||
|
||||
<selection>fun f(a: A, t: T) {
|
||||
g(A(c).ext())
|
||||
O1.f()
|
||||
O2
|
||||
ENTRY
|
||||
}
|
||||
|
||||
fun f2(i: Inner, n: Nested, e: NestedEnum, o: NestedObj, t: NestedTrait, a: NestedAnnotation) {
|
||||
ClassObject
|
||||
}</selection>
|
||||
@@ -0,0 +1,5 @@
|
||||
package to
|
||||
|
||||
package a
|
||||
|
||||
import a.A
|
||||
@@ -0,0 +1,8 @@
|
||||
// ALLOW_UNRESOLVED
|
||||
|
||||
<selection>package a
|
||||
|
||||
import a.A</selection>
|
||||
|
||||
class A() {
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package to
|
||||
|
||||
<caret>
|
||||
@@ -0,0 +1,14 @@
|
||||
package to
|
||||
|
||||
import a.f
|
||||
import a.A.Nested
|
||||
import a.ext
|
||||
|
||||
fun g() {
|
||||
f {
|
||||
Inner()
|
||||
Nested()
|
||||
foo()
|
||||
ext()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package a
|
||||
|
||||
import a.A.Inner
|
||||
import a.A.Nested
|
||||
|
||||
class A {
|
||||
inner class Inner {
|
||||
}
|
||||
class Nested {
|
||||
}
|
||||
fun foo() {
|
||||
}
|
||||
}
|
||||
|
||||
fun A.ext() {
|
||||
}
|
||||
|
||||
fun f(body: A.() -> Unit) {
|
||||
}
|
||||
|
||||
<selection>fun g() {
|
||||
f {
|
||||
Inner()
|
||||
Nested()
|
||||
foo()
|
||||
ext()
|
||||
}
|
||||
}</selection>
|
||||
@@ -0,0 +1,22 @@
|
||||
package to
|
||||
|
||||
class Outer {
|
||||
inner class Inner {
|
||||
}
|
||||
class Nested {
|
||||
}
|
||||
enum class NestedEnum {
|
||||
}
|
||||
object NestedObj {
|
||||
}
|
||||
trait NestedTrait {
|
||||
}
|
||||
annotation class NestedAnnotation
|
||||
}
|
||||
|
||||
enum class E {
|
||||
ENTRY
|
||||
}
|
||||
|
||||
fun f2(i: Inner, n: Nested, e: NestedEnum, o: NestedObj, t: NestedTrait, a: NestedAnnotation) {
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package a
|
||||
|
||||
// ALLOW_UNRESOLVED
|
||||
//NOTE: This test shows a corner case which is not covered fully by current implementation
|
||||
// All we do now is avoid inserting wrong imports (we do not import anything for declaration from copied block)
|
||||
// To cover this case properly and insert good imports some other approach should be used (some sophisticated heuristic might do the job)
|
||||
|
||||
import a.Outer.*
|
||||
import a.E.ENTRY
|
||||
|
||||
<selection>class Outer {
|
||||
inner class Inner {
|
||||
}
|
||||
class Nested {
|
||||
}
|
||||
enum class NestedEnum {
|
||||
}
|
||||
object NestedObj {
|
||||
}
|
||||
trait NestedTrait {
|
||||
}
|
||||
annotation class NestedAnnotation
|
||||
}
|
||||
|
||||
enum class E {
|
||||
ENTRY
|
||||
}
|
||||
|
||||
fun f2(i: Inner, n: Nested, e: NestedEnum, o: NestedObj, t: NestedTrait, a: NestedAnnotation) {
|
||||
}</selection>
|
||||
@@ -0,0 +1,13 @@
|
||||
package to
|
||||
|
||||
import a.Outer.Inner
|
||||
import a.Outer.Nested
|
||||
import a.Outer.NestedEnum
|
||||
import a.Outer.NestedObj
|
||||
import a.Outer.NestedTrait
|
||||
import a.Outer.NestedAnnotation
|
||||
import a.Outer
|
||||
|
||||
fun f(i: Inner, n: Nested, e: NestedEnum, o: NestedObj, t: NestedTrait, a: NestedAnnotation) {
|
||||
Outer().Inner2()
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package a
|
||||
|
||||
import a.Outer.*
|
||||
|
||||
class Outer {
|
||||
inner class Inner {
|
||||
}
|
||||
inner class Inner2 {
|
||||
}
|
||||
class Nested {
|
||||
}
|
||||
enum class NestedEnum {
|
||||
}
|
||||
object NestedObj {
|
||||
}
|
||||
trait NestedTrait {
|
||||
}
|
||||
annotation class NestedAnnotation
|
||||
}
|
||||
|
||||
<selection>fun f(i: Inner, n: Nested, e: NestedEnum, o: NestedObj, t: NestedTrait, a: NestedAnnotation) {
|
||||
Outer().Inner2()
|
||||
}</selection>
|
||||
@@ -0,0 +1,8 @@
|
||||
package to
|
||||
|
||||
import a.A
|
||||
import a.invoke
|
||||
|
||||
fun f(a: A) {
|
||||
a()
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package a
|
||||
|
||||
class A {
|
||||
}
|
||||
|
||||
fun A.invoke() {
|
||||
}
|
||||
|
||||
<selection>fun f(a: A) {
|
||||
a()
|
||||
}</selection>
|
||||
@@ -0,0 +1,10 @@
|
||||
package a;
|
||||
|
||||
class JavaM {
|
||||
static void staticMethod() {
|
||||
}
|
||||
}
|
||||
|
||||
class JavaF {
|
||||
static int staticField = 0;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package to
|
||||
|
||||
import a.JavaM
|
||||
import a.JavaF
|
||||
|
||||
fun f() {
|
||||
JavaM.staticMethod()
|
||||
JavaF.staticField()
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package a
|
||||
|
||||
<selection>fun f() {
|
||||
JavaM.staticMethod()
|
||||
JavaF.staticField()
|
||||
}</selection>
|
||||
@@ -0,0 +1,43 @@
|
||||
package d
|
||||
|
||||
trait T
|
||||
|
||||
class A(i: Int) {}
|
||||
|
||||
val c: Int = 0
|
||||
|
||||
fun g(a: A) {}
|
||||
|
||||
fun A.ext() {
|
||||
}
|
||||
|
||||
object O1 {
|
||||
fun f() {
|
||||
}
|
||||
}
|
||||
|
||||
object O2 {
|
||||
}
|
||||
|
||||
enum class E {
|
||||
ENTRY
|
||||
}
|
||||
|
||||
class Outer {
|
||||
inner class Inner {
|
||||
}
|
||||
class Nested {
|
||||
}
|
||||
enum class NestedEnum {
|
||||
}
|
||||
object NestedObj {
|
||||
}
|
||||
trait NestedTrait {
|
||||
}
|
||||
annotation class NestedAnnotation
|
||||
}
|
||||
|
||||
class ClassObject {
|
||||
class object {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package to
|
||||
|
||||
fun f() {
|
||||
val b = A()
|
||||
val a = g()
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package a
|
||||
|
||||
// ALLOW_UNRESOLVED
|
||||
|
||||
fun f() {
|
||||
fun g(): Int {
|
||||
}
|
||||
|
||||
class A() {
|
||||
}
|
||||
|
||||
<selection>val b = A()
|
||||
val a = g()</selection>
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package to
|
||||
|
||||
fun f() {
|
||||
<caret>
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package to
|
||||
|
||||
import a.A
|
||||
import a.B
|
||||
import a.next
|
||||
import a.hasNext
|
||||
|
||||
fun A.iterator() = B()
|
||||
|
||||
fun f() {
|
||||
for (i in A()) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package a
|
||||
|
||||
class A() {
|
||||
}
|
||||
|
||||
class B() {
|
||||
}
|
||||
|
||||
fun B.next(): Int = 3
|
||||
|
||||
fun B.hasNext(): Boolean = false
|
||||
|
||||
<selection>fun A.iterator() = B()
|
||||
|
||||
fun f() {
|
||||
for (i in A()) {
|
||||
}
|
||||
}</selection>
|
||||
@@ -0,0 +1,6 @@
|
||||
package to
|
||||
|
||||
import a.d
|
||||
import a.b
|
||||
|
||||
fun f(c: IntRange) = d + b
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user