Working on new imports insertion on copy/paste

This commit is contained in:
Valentin Kipyatkov
2015-02-11 20:33:55 +03:00
parent 4031357ae4
commit 6acba00599
35 changed files with 279 additions and 245 deletions
@@ -22,11 +22,12 @@ import org.jetbrains.kotlin.psi.JetElement
import org.jetbrains.kotlin.psi.UserDataProperty
import com.intellij.openapi.util.Key
import org.jetbrains.kotlin.psi.NotNullableUserDataProperty
import java.util.HashSet
import com.intellij.openapi.application.ApplicationManager
import com.intellij.psi.SmartPointerManager
import com.intellij.openapi.diagnostic.Logger
import org.jetbrains.kotlin.idea.util.ShortenReferences.Options
import org.jetbrains.kotlin.idea.util.ShortenReferences
import java.util.*
class ShorteningRequest(val pointer: SmartPsiElementPointer<JetElement>, val options: Options)
@@ -43,7 +44,7 @@ public var Project.ensureElementsToShortenIsEmptyBeforeRefactoring: Boolean
private fun Project.getOrCreateElementsToShorten(): MutableSet<ShorteningRequest> {
var elements = elementsToShorten
if (elements == null) {
elements = HashSet()
elements = LinkedHashSet()
elementsToShorten = elements
}
@@ -57,12 +58,14 @@ public fun JetElement.addToShorteningWaitSet(options: Options = Options.DEFAULT)
project.getOrCreateElementsToShorten().add(ShorteningRequest(elementPointer, options))
}
public fun withElementsToShorten(project: Project, f: (Set<ShorteningRequest>) -> Unit) {
public fun performDelayedShortening(project: Project) {
project.elementsToShorten?.let { requests ->
project.elementsToShorten = null
f(requests)
val elements = requests.map { it.pointer.getElement() }
val options = requests.map { it.options }
val elementToOptions = (elements zip options).toMap()
ShortenReferences({ elementToOptions[it] ?: ShortenReferences.Options.DEFAULT }).process(elements.filterNotNull())
}
}
private val LOG = Logger.getInstance(javaClass<Project>().getCanonicalName())
@@ -16,54 +16,42 @@
package org.jetbrains.kotlin.idea.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.kotlin.psi.JetFile
import org.jetbrains.kotlin.idea.util.ImportInsertHelper
import org.jetbrains.kotlin.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.kotlin.idea.references.JetReference
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.psi.JetPsiFactory
import org.jetbrains.kotlin.psi.JetSimpleNameExpression
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.psi.JetCallExpression
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.psi.JetImportDirective
import org.jetbrains.kotlin.psi.JetPackageDirective
import org.jetbrains.kotlin.idea.references.JetMultiReference
import org.jetbrains.kotlin.psi.JetElement
import org.jetbrains.kotlin.idea.conversion.copy.*
import java.awt.datatransfer.UnsupportedFlavorException
import java.io.IOException
import com.intellij.openapi.diagnostic.Logger
import org.jetbrains.kotlin.psi.JetDotQualifiedExpression
import org.jetbrains.kotlin.psi.JetUserType
import org.jetbrains.kotlin.psi.JetTypeReference
import org.jetbrains.kotlin.idea.imports.*
import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression
import org.jetbrains.kotlin.utils.*
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
import com.intellij.openapi.progress.ProcessCanceledException
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.idea.references.*
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.resolve.QualifiedExpressionResolver.LookupMode
import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.idea.caches.resolve.*
import org.jetbrains.kotlin.idea.util.*
import org.jetbrains.kotlin.utils.*
import org.jetbrains.kotlin.idea.codeInsight.shorten.performDelayedShortening
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.descriptorUtil.*
import com.intellij.psi.*
import java.util.*
//NOTE: this class is based on CopyPasteReferenceProcessor and JavaCopyPasteReferenceProcessor
public class KotlinCopyPasteReferenceProcessor() : CopyPastePostProcessor<ReferenceTransferableData>() {
public class KotlinCopyPasteReferenceProcessor() : CopyPastePostProcessor<KotlinReferenceTransferableData>() {
private val LOG = Logger.getInstance(javaClass<KotlinCopyPasteReferenceProcessor>())
private val IGNORE_REFERENCES_INSIDE: Array<Class<out JetElement>?> = array(
@@ -71,17 +59,13 @@ public class KotlinCopyPasteReferenceProcessor() : CopyPastePostProcessor<Refere
javaClass<JetPackageDirective>()
)
override fun extractTransferableData(content: Transferable): List<ReferenceTransferableData> {
override fun extractTransferableData(content: Transferable): List<KotlinReferenceTransferableData> {
if (CodeInsightSettings.getInstance().ADD_IMPORTS_ON_PASTE != CodeInsightSettings.NO) {
try {
val flavor = ReferenceData.getDataFlavor()
if (flavor != null) {
val referenceData = content.getTransferData(flavor) as? ReferenceTransferableData
if (referenceData != null) {
// copy to prevent changing of original by convertLineSeparators
return listOf(referenceData.clone())
}
}
val flavor = KotlinReferenceData.dataFlavor ?: return listOf()
val data = content.getTransferData(flavor) as? KotlinReferenceTransferableData ?: return listOf()
// copy to prevent changing of original by convertLineSeparators
return listOf(data.clone())
}
catch (ignored: UnsupportedFlavorException) {
}
@@ -97,7 +81,7 @@ public class KotlinCopyPasteReferenceProcessor() : CopyPastePostProcessor<Refere
editor: Editor,
startOffsets: IntArray,
endOffsets: IntArray
): List<ReferenceTransferableData> {
): List<KotlinReferenceTransferableData> {
if (file !is JetFile || DumbService.getInstance(file.getProject()).isDumb()) return listOf()
val collectedData = try {
@@ -120,7 +104,7 @@ public class KotlinCopyPasteReferenceProcessor() : CopyPastePostProcessor<Refere
if (collectedData.isEmpty()) return listOf()
return listOf(ReferenceTransferableData(collectedData.copyToArray()))
return listOf(KotlinReferenceTransferableData(collectedData.copyToArray()))
}
private fun collectReferenceDataFromElement(
@@ -129,44 +113,51 @@ public class KotlinCopyPasteReferenceProcessor() : CopyPastePostProcessor<Refere
startOffset: Int,
startOffsets: IntArray,
endOffsets: IntArray
): Collection<ReferenceData> {
): Collection<KotlinReferenceData> {
fun collectReferenceData(referencedDeclaration: PsiElement, referencedDescriptor: DeclarationDescriptor): ReferenceData? {
if (referencedDeclaration.isInCopiedArea(file, startOffsets, endOffsets)) return null
if (isInReceiverScope(element, referencedDescriptor)) return null
if (PsiTreeUtil.getParentOfType(element, *IGNORE_REFERENCES_INSIDE) != null) return listOf()
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 listOf()
val reference = element.getReference()
if (reference !is JetReference) return listOf()
val reference = element.getReference() as? JetReference ?: return listOf()
val resolveMap = reference.resolveMap()
//check whether this reference is unambiguous
if (reference !is JetMultiReference<*> && resolveMap.size() > 1) return listOf()
val collectedData = ArrayList<ReferenceData>()
for ((referencedDescriptor, declarations) in resolveMap) {
if (declarations.size() != 1) continue
collectedData.addIfNotNull(collectReferenceData(declarations.first(), referencedDescriptor))
val collectedData = ArrayList<KotlinReferenceData>()
for ((descriptor, declarations) in resolveMap) {
val declaration = declarations.singleOrNull() ?: continue
if (declaration.isInCopiedArea(file, startOffsets, endOffsets)) continue
if (!descriptor.isExtension) {
if (element !is JetNameReferenceExpression) continue
if (element.getIdentifier() == null) continue // skip 'this' etc
if (element.getReceiverExpression() != null) continue
}
val fqName = descriptor.importableFqName ?: continue
if (!descriptor.canBeReferencedViaImport()) continue
val kind = when (descriptor.getImportableDescriptor()) {
is ClassDescriptor ->
KotlinReferenceData.Kind.CLASS
is PackageViewDescriptor ->
KotlinReferenceData.Kind.PACKAGE
is CallableDescriptor ->
if (descriptor.isExtension) KotlinReferenceData.Kind.EXTENSION_CALLABLE else KotlinReferenceData.Kind.NON_EXTENSION_CALLABLE
else ->
continue
}
collectedData.add(KotlinReferenceData(element.range.start - startOffset, element.range.end - startOffset, fqName.asString(), kind))
}
return collectedData
}
private fun createReferenceData(element: PsiElement, startOffset: Int, fqName: FqName)
= ReferenceData(element.range.start - startOffset, element.range.end - startOffset, fqName.asString(), null)
private data class ReferenceToRestoreData(
val expression: JetElement,
val fqName: FqName,
val lengthenReference: Boolean = false
val reference: JetReference,
val refData: KotlinReferenceData
)
override fun processTransferableData (
@@ -175,7 +166,7 @@ public class KotlinCopyPasteReferenceProcessor() : CopyPastePostProcessor<Refere
bounds: RangeMarker,
caretOffset: Int,
indented: Ref<Boolean>,
values: List<ReferenceTransferableData>
values: List<KotlinReferenceTransferableData>
) {
if (DumbService.getInstance(project).isDumb()) return
@@ -187,7 +178,7 @@ public class KotlinCopyPasteReferenceProcessor() : CopyPastePostProcessor<Refere
assert(values.size() == 1)
val referenceData = values.single().getData()!!
val referenceData = values.single().data
val referencesPossibleToRestore = findReferencesToRestore(file, bounds, referenceData)
val selectedReferencesToRestore = showRestoreReferencesDialog(project, referencesPossibleToRestore)
@@ -199,24 +190,19 @@ public class KotlinCopyPasteReferenceProcessor() : CopyPastePostProcessor<Refere
PsiDocumentManager.getInstance(project).commitAllDocuments()
}
private fun findReferencesToRestore(file: PsiFile, bounds: RangeMarker, referenceData: Array<out ReferenceData>): List<ReferenceToRestoreData> {
private fun findReferencesToRestore(file: PsiFile, bounds: RangeMarker, referenceData: Array<out KotlinReferenceData>): List<ReferenceToRestoreData> {
if (file !is JetFile) return listOf()
return referenceData.map {
if (ImportInsertHelper.getInstance(file.getProject()).needImport(it.fqName, file)) {
val referenceExpression = findReference(it, file, bounds)
if (referenceExpression != null)
createReferenceToRestoreData(referenceExpression, it.fqName)
else
null
}
else {
val referenceElement = findReference(it, file, bounds)
if (referenceElement != null)
createReferenceToRestoreData(referenceElement, it)
else
null
}
}.filterNotNull()
}
private fun findReference(data: ReferenceData, file: JetFile, bounds: RangeMarker): JetElement? {
private fun findReference(data: KotlinReferenceData, file: JetFile, bounds: RangeMarker): JetElement? {
val startOffset = data.startOffset + bounds.getStartOffset()
val endOffset = data.endOffset + bounds.getStartOffset()
val element = file.findElementAt(startOffset)
@@ -237,47 +223,65 @@ public class KotlinCopyPasteReferenceProcessor() : CopyPastePostProcessor<Refere
return null
}
private fun createReferenceToRestoreData(expression: JetElement, originalReferencedFqName: FqName): ReferenceToRestoreData? {
val reference = expression.getReference() as? JetReference ?: return null
private fun createReferenceToRestoreData(element: JetElement, refData: KotlinReferenceData): ReferenceToRestoreData? {
val reference = element.getReference() as? JetReference ?: return null
val referencedDescriptors = try {
reference.resolveToDescriptors()
}
catch (e: Throwable) {
LOG.error("Failed to analyze reference (${expression.getText()}) after copy paste", e)
LOG.error("Failed to analyze reference (${element.getText()}) after copy paste", e)
return null
}
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 && canLengthenReferenceExpression(expression, originalReferencedFqName)) {
return ReferenceToRestoreData(expression, originalReferencedFqName, lengthenReference = true)
}
}
}
return null
val referencedFqNames = referencedDescriptors.filterNot { ErrorUtils.isError(it) }.map { it.importableFqName }.filterNotNull()
val originalFqName = FqName(refData.fqName)
val referencesSame = referencedFqNames.any { it == originalFqName }
val conflict = referencedFqNames.any { it != originalFqName && it.shortName() == originalFqName.shortName() }
if (referencesSame && !conflict) return null
return ReferenceToRestoreData(reference, refData)
}
private fun restoreReferences(referencesToRestore: Collection<ReferenceToRestoreData>, file: JetFile) {
for ((referenceExpression, fqName, shouldLengthen) in referencesToRestore) {
if (!shouldLengthen) {
ImportInsertHelper.getInstance(file.getProject()).addImportDirectiveIfNeeded(fqName, file)
val importHelper = ImportInsertHelper.getInstance(file.getProject())
val smartPointerManager = SmartPointerManager.getInstance(file.getProject())
[data] class BindingRequest(
val pointer: SmartPsiElementPointer<JetSimpleNameExpression>,
val fqName: FqName
)
val bindingRequests = ArrayList<BindingRequest>()
val descriptorsToImport = ArrayList<CallableDescriptor>()
for ((reference, refData) in referencesToRestore) {
val fqName = FqName(refData.fqName)
if (refData.kind != KotlinReferenceData.Kind.EXTENSION_CALLABLE && reference is JetSimpleNameReference) {
val pointer = smartPointerManager.createSmartPsiElementPointer(reference.getElement(), file)
bindingRequests.add(BindingRequest(pointer, fqName))
}
else {
//TODO: try to shorten reference after (sometimes is possible), need shorten reference to support all relevant cases
lengthenReference(referenceExpression, fqName)
if (refData.kind == KotlinReferenceData.Kind.NON_EXTENSION_CALLABLE || refData.kind == KotlinReferenceData.Kind.EXTENSION_CALLABLE) {
descriptorsToImport.addIfNotNull(findCallableToImport(fqName, file))
}
}
for (descriptor in descriptorsToImport) {
importHelper.importDescriptor(file, descriptor)
}
for ((pointer, fqName) in bindingRequests) {
val reference = pointer.getElement().getReference() as JetSimpleNameReference
reference.bindToFqName(fqName, JetSimpleNameReference.ShorteningMode.DELAYED_SHORTENING)
}
performDelayedShortening(file.getProject())
}
private fun findCallableToImport(fqName: FqName, file: JetFile): CallableDescriptor? {
val importDirective = JetPsiFactory(file.getProject()).createImportDirective(ImportPath(fqName, false))
val moduleDescriptor = file.getResolutionFacade().findModuleDescriptor(file)
val scope = JetModuleUtil.getSubpackagesOfRootScope(moduleDescriptor)
val descriptors = QualifiedExpressionResolver()
.processImportReference(importDirective, scope, scope, null, BindingTraceContext(), LookupMode.EVERYTHING)
.filterIsInstance<CallableDescriptor>()
return descriptors.singleOrNull()
}
private fun showRestoreReferencesDialog(project: Project, referencesToRestore: List<ReferenceToRestoreData>): Collection<ReferenceToRestoreData> {
@@ -285,45 +289,16 @@ public class KotlinCopyPasteReferenceProcessor() : CopyPastePostProcessor<Refere
if (!shouldShowDialog || referencesToRestore.isEmpty()) {
return referencesToRestore
}
val fqNames = referencesToRestore. map { it.fqName.asString() }.toSortedSet()
val fqNames = referencesToRestore.map { it.refData.fqName }.toSortedSet()
val dialog = RestoreReferencesDialog(project, fqNames.copyToArray())
dialog.show()
val selectedFqNames = dialog.getSelectedElements()!!.toSet()
return referencesToRestore.filter { ref -> selectedFqNames.contains(ref.fqName.asString()) }
return referencesToRestore.filter { selectedFqNames.contains(it.refData.fqName) }
}
private fun createQualifiedExpression(psiFactory: JetPsiFactory, text: String)
= psiFactory.createExpression(text) as JetDotQualifiedExpression
private fun lengthenReference(expression: JetElement, fqName: FqName) {
assert(canLengthenReferenceExpression(expression, fqName))
val parent = expression.getParent()
val prefixToInsert = IdeDescriptorRenderers.SOURCE_CODE.renderFqName(fqName.parent())
val psiFactory = JetPsiFactory(expression)
if (parent is JetCallExpression) {
val text = prefixToInsert + "." + parent.getText()
parent.replace(createQualifiedExpression(psiFactory, text))
}
else if (parent is JetUserType) {
val typeReference = expression.getStrictParentOfType<JetTypeReference>()!!
typeReference.replace(psiFactory.createType(prefixToInsert + "." + typeReference.getText()))
}
else {
expression.replace(createQualifiedExpression(psiFactory, IdeDescriptorRenderers.SOURCE_CODE.renderFqName(fqName)))
}
}
private fun canLengthenReferenceExpression(expression: JetElement, fqName: FqName): Boolean {
return when {
fqName.pathSegments().size() < 2 -> false
expression is JetSimpleNameExpression && expression.getReceiverExpression() == null -> true
else -> false
}
}
private val ReferenceData.fqName: FqName
get() = FqName(qClassName!!)
private fun toTextRanges(startOffsets: IntArray, endOffsets: IntArray): List<TextRange> {
assert(startOffsets.size() == endOffsets.size())
return startOffsets.indices.map { TextRange(startOffsets[it], endOffsets[it]) }
@@ -331,6 +306,6 @@ public class KotlinCopyPasteReferenceProcessor() : CopyPastePostProcessor<Refere
private fun PsiElement.isInCopiedArea(fileCopiedFrom: JetFile, startOffsets: IntArray, endOffsets: IntArray): Boolean {
if (getContainingFile() != fileCopiedFrom) return false
return toTextRanges(startOffsets, endOffsets).contains(range)
return toTextRanges(startOffsets, endOffsets).any { this.range in it }
}
}
@@ -0,0 +1,89 @@
/*
* Copyright 2010-2015 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.kotlin.idea.codeInsight
import com.intellij.codeInsight.editorActions.*
import java.io.*
import java.awt.datatransfer.*
import kotlin.properties.*
public class KotlinReferenceTransferableData(
val data: Array<KotlinReferenceData>
) : TextBlockTransferableData, Cloneable, Serializable {
override fun getFlavor() = KotlinReferenceData.dataFlavor
override fun getOffsetCount() = data.size() * 2
override fun getOffsets(offsets: IntArray, index: Int): Int {
var i = index
for (d in data) {
offsets[i++] = d.startOffset
offsets[i++] = d.endOffset
}
return i
}
override fun setOffsets(offsets: IntArray, index: Int): Int {
var i = index
for (d in data) {
d.startOffset = offsets[i++]
d.endOffset = offsets[i++]
}
return i
}
public override fun clone() = KotlinReferenceTransferableData(Array(data.size(), { data[it].clone() }))
}
public class KotlinReferenceData(
public var startOffset: Int,
public var endOffset: Int,
public val fqName: String,
public val kind: KotlinReferenceData.Kind
) : Cloneable, Serializable {
public enum class Kind {
CLASS
PACKAGE
NON_EXTENSION_CALLABLE
EXTENSION_CALLABLE
}
public override fun clone(): KotlinReferenceData {
try {
return super<Cloneable>.clone() as KotlinReferenceData
}
catch (e: CloneNotSupportedException) {
throw RuntimeException()
}
}
class object {
public val dataFlavor: DataFlavor? by Delegates.lazy {
try {
DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + ";class=" + javaClass<KotlinReferenceData>().getName(), "KotlinReferenceData")
}
catch (e: NoClassDefFoundError) {
null
}
catch (e: IllegalArgumentException) {
null
}
}
}
}
@@ -20,9 +20,8 @@ import com.intellij.refactoring.RefactoringHelper
import com.intellij.usageView.UsageInfo
import com.intellij.openapi.project.Project
import com.intellij.openapi.application.ApplicationManager
import org.jetbrains.kotlin.idea.codeInsight.shorten.prepareElementsToShorten
import org.jetbrains.kotlin.idea.codeInsight.shorten.withElementsToShorten
import org.jetbrains.kotlin.idea.util.ShortenReferences
import org.jetbrains.kotlin.idea.codeInsight.shorten.*
public class KotlinShortenReferencesRefactoringHelper: RefactoringHelper<Any> {
override fun prepareOperation(usages: Array<out UsageInfo>?): Any? {
@@ -35,12 +34,7 @@ public class KotlinShortenReferencesRefactoringHelper: RefactoringHelper<Any> {
override fun performOperation(project: Project, operationData: Any?) {
ApplicationManager.getApplication()!!.runWriteAction {
withElementsToShorten(project) { requests ->
val elements = requests.map { it.pointer.getElement() }
val options = requests.map { it.options }
val elementToOptions = (elements zip options).toMap()
ShortenReferences({ elementToOptions[it] ?: ShortenReferences.Options.DEFAULT }).process(elements.filterNotNull())
}
performDelayedShortening(project)
}
}
}
@@ -1,21 +1,14 @@
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) {
fun f(p: A, t: T) {
g(A(c).ext())
O1.f()
O2
ENTRY
E.ENTRY
}
fun f2(i: Inner, n: Nested, e: NestedEnum, o: NestedObj, t: NestedTrait, a: NestedAnnotation) {
fun f2(i: Outer.Inner, n: Outer.Nested, e: Outer.NestedEnum, o: Outer.NestedObj, t: Outer.NestedTrait, a: Outer.NestedAnnotation) {
ClassObject
}
@@ -44,7 +44,7 @@ class ClassObject {
}
}
<selection>fun f(a: A, t: T) {
<selection>fun f(p: A, t: T) {
g(A(c).ext())
O1.f()
O2
@@ -1,11 +1,6 @@
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) {
fun f(i: Outer.Inner, n: Outer.Nested, e: Outer.NestedEnum, o: Outer.NestedObj, t: Outer.NestedTrait, a: Outer.NestedAnnotation) {
}
@@ -3,6 +3,6 @@ package to
import a.a
fun f(i: a) {
a.a
a
a()
}
@@ -3,5 +3,7 @@ package to
class A<T> {
}
val a: A<String>? = null
fun f(b: a.A<Int>) {
}
@@ -3,4 +3,6 @@ package to
class A<T> {
}
val a: A<String>? = null
<caret>
@@ -3,5 +3,7 @@ package to
class A() {
}
val a: A? = null
fun f(a: a.A) {
}
@@ -3,4 +3,6 @@ package to
class A() {
}
val a: A? = null
<caret>
@@ -1,20 +1,14 @@
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()
fun f(p1: Outer.Nested.NN, p2: Outer.Nested.NI, p3: Outer.Inner.IN, p4: Outer.Inner.II) {
Outer.Nested.NN2()
with(Outer.Nested()) {
NI2()
}
IN2()
Outer.Inner.IN2()
with(Outer().Inner()) {
II2()
}
@@ -1,9 +1,9 @@
package to
import a.A
import a.get
import a.set
import a.A
class B {
var a by A()
var v by A()
}
@@ -12,5 +12,5 @@ fun T.set(thisRef: B, desc: PropertyMetadata, value: Int) {
class A(): T
<selection>class B {
var a by A()
var v by A()
}</selection>
@@ -11,6 +11,6 @@ public class JavaClass {
public class InnerClass {
}
public class NestedClass {
public static class NestedClass {
}
}
@@ -1,12 +1,10 @@
package to
import java.JavaClass
import java.JavaClass.staticMethod
import java.JavaClass.NestedClass
fun f(c: JavaClass) {
staticMethod()
JavaClass.staticMethod()
c.method()
c.InnerClass()
NestedClass()
JavaClass.NestedClass()
}
@@ -1,28 +1,23 @@
package to
import d.A
import d.T
import d.g
import d.c
import d.ext
import d.A
import d.T
import d.Outer
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.E
import d.ClassObject
fun f(a: A, t: T) {
g(A(c).ext())
O1.f()
O2
ENTRY
E.ENTRY
}
fun f2(i: Inner, n: Nested, e: NestedEnum, o: NestedObj, t: NestedTrait, a: NestedAnnotation) {
fun f2(i: Outer.Inner, n: Outer.Nested, e: Outer.NestedEnum, o: Outer.NestedObj, t: Outer.NestedTrait, a: Outer.NestedAnnotation) {
ClassObject
}
@@ -1,11 +1,9 @@
package to
import a.A.A
import a.A.B
import a.A.C
import a.A
fun f() {
A
B
C
A.A
A.B
A.C
}
@@ -1,8 +1,8 @@
package to
import a.A
import a.plus
import a.infix
import a.A
fun f(a: A) {
a + a
@@ -1,6 +1,8 @@
package to
import a.A
import a.ext
import a.p
fun A.ext() {
}
@@ -1,6 +1,11 @@
package to
import a.A
import a.ext
import a.plus
import a.infix
import a.minus
import a.p
fun A.ext() {
}
@@ -1,9 +1,9 @@
package to
import a.A
import a.iterator
import a.next
import a.hasNext
import a.A
fun f() {
for (i in A()) {
@@ -1,7 +1,7 @@
package to
import a.A
import a.get
import a.A
fun f() {
A()[""]
@@ -1,28 +1,23 @@
package to
import d.A
import d.T
import d.g
import d.c
import d.ext
import d.A
import d.T
import d.Outer
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.E
import d.ClassObject
fun f(a: A, t: T) {
g(A(c).ext())
O1.f()
O2
ENTRY
E.ENTRY
}
fun f2(i: Inner, n: Nested, e: NestedEnum, o: NestedObj, t: NestedTrait, a: NestedAnnotation) {
fun f2(i: Outer.Inner, n: Outer.Nested, e: Outer.NestedEnum, o: Outer.NestedObj, t: Outer.NestedTrait, a: Outer.NestedAnnotation) {
ClassObject
}
@@ -1,13 +1,7 @@
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) {
fun f(i: Outer.Inner, n: Outer.Nested, e: Outer.NestedEnum, o: Outer.NestedObj, t: Outer.NestedTrait, aa: Outer.NestedAnnotation) {
Outer().Inner2()
}
+1 -1
View File
@@ -18,6 +18,6 @@ class Outer {
annotation class NestedAnnotation
}
<selection>fun f(i: Inner, n: Nested, e: NestedEnum, o: NestedObj, t: NestedTrait, a: NestedAnnotation) {
<selection>fun f(i: Inner, n: Nested, e: NestedEnum, o: NestedObj, t: NestedTrait, aa: NestedAnnotation) {
Outer().Inner2()
}</selection>
@@ -1,7 +1,7 @@
package to
import a.A
import a.invoke
import a.A
fun f(a: A) {
a()
@@ -1,8 +1,8 @@
package to
import a.A
import a.component1
import a.component2
import a.A
fun f() {
val (a, b) = A()
@@ -1,9 +1,9 @@
package to
import a.A
import a.B
import a.next
import a.hasNext
import a.A
import a.B
fun A.iterator() = B()
@@ -1,20 +1,12 @@
package 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) {
fun f(p: A, t: T) {
g(A(c).ext())
O1.f()
O2
ENTRY
E.ENTRY
}
fun f2(i: Inner, n: Nested, e: NestedEnum, o: NestedObj, t: NestedTrait, a: NestedAnnotation) {
fun f2(i: Outer.Inner, n: Outer.Nested, e: Outer.NestedEnum, o: Outer.NestedObj, t: Outer.NestedTrait, a: Outer.NestedAnnotation) {
ClassObject
}
@@ -44,7 +44,7 @@ class ClassObject {
}
}
<selection>fun f(a: A, t: T) {
<selection>fun f(p: A, t: T) {
g(A(c).ext())
O1.f()
O2
@@ -5,5 +5,7 @@ class A {
}
}
val v: A? = null
fun f(p: a.A.B) {
}
@@ -5,4 +5,6 @@ class A {
}
}
val v: A? = null
<caret>
@@ -1,6 +1,6 @@
package to
import a.T
import a.A
import a.T
fun f(): T<A>