Find Usages and Go to declaration of element used via import alias

#KT-18619 Fixed
This commit is contained in:
Vladimir Dolzhenko
2020-03-20 14:59:24 +00:00
parent ced8a92629
commit e951f1a43a
42 changed files with 677 additions and 32 deletions
@@ -242,6 +242,10 @@ fun KtElement.resolveMainReferenceToDescriptors(): Collection<DeclarationDescrip
return mainReference?.resolveToDescriptors(bindingContext) ?: emptyList()
}
fun PsiReference.getImportAlias(): KtImportAlias? {
return (this as? KtSimpleNameReference)?.getImportAlias()
}
// ----------- Read/write access -----------------------------------------------------------------------------------------------------------------------
enum class ReferenceAccess(val isRead: Boolean, val isWrite: Boolean) {
@@ -0,0 +1,27 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.search.ideaExtensions
import com.intellij.codeInsight.navigation.actions.GotoDeclarationHandler
import com.intellij.openapi.editor.Editor
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.psi.KtImportAlias
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementSelector
class KotlinImportAliasGotoDeclarationHandler : GotoDeclarationHandler {
override fun getGotoDeclarationTargets(sourceElement: PsiElement?, offset: Int, editor: Editor?): Array<PsiElement>? {
val importAlias = sourceElement?.parent as? KtImportAlias ?: return null
val result =
runReadAction {
importAlias.importDirective?.importedReference?.getQualifiedElementSelector()?.mainReference?.multiResolve(false)
} ?: return null
return result.mapNotNull { it.element }.toTypedArray()
}
}
@@ -17,12 +17,10 @@
package org.jetbrains.kotlin.idea.search.ideaExtensions
import com.intellij.openapi.application.QueryExecutorBase
import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.*
import com.intellij.psi.impl.cache.CacheManager
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.SearchRequestCollector
import com.intellij.psi.search.SearchScope
import com.intellij.psi.search.UsageSearchContext
import com.intellij.psi.search.*
import com.intellij.psi.search.searches.ReferencesSearch
import com.intellij.util.Processor
import com.intellij.util.containers.nullize
@@ -36,8 +34,10 @@ import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.asJava.toLightElements
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.idea.search.*
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions.Companion.Empty
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions.Companion.calculateEffectiveScope
import org.jetbrains.kotlin.idea.search.usagesSearch.dataClassComponentFunction
import org.jetbrains.kotlin.idea.search.usagesSearch.filterDataClassComponentsIfDisabled
import org.jetbrains.kotlin.idea.search.usagesSearch.getClassNameForCompanionObject
@@ -47,6 +47,7 @@ import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.idea.util.expectedDeclarationIfAny
import org.jetbrains.kotlin.idea.util.isExpectDeclaration
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementSelector
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier
import org.jetbrains.kotlin.psi.psiUtil.parents
@@ -57,6 +58,7 @@ data class KotlinReferencesSearchOptions(
val acceptOverloads: Boolean = false,
val acceptExtensionsOfDeclarationClass: Boolean = false,
val acceptCompanionObjectMembers: Boolean = false,
val acceptImportAlias: Boolean = true,
val searchForComponentConventions: Boolean = true,
val searchForOperatorConventions: Boolean = true,
val searchNamedArguments: Boolean = true,
@@ -66,6 +68,22 @@ data class KotlinReferencesSearchOptions(
companion object {
val Empty = KotlinReferencesSearchOptions()
internal fun calculateEffectiveScope(
unwrappedElement: PsiNamedElement,
parameters: ReferencesSearch.SearchParameters
): SearchScope {
val kotlinOptions = (parameters as? KotlinReferencesSearchParameters)?.kotlinOptions ?: Empty
val elements = if (unwrappedElement is KtDeclaration && !isOnlyKotlinSearch(parameters.scopeDeterminedByUser)) {
unwrappedElement.toLightElements().filterDataClassComponentsIfDisabled(kotlinOptions).nullize()
} else {
null
} ?: listOf(unwrappedElement)
return elements.fold(parameters.effectiveSearchScope) { scope, e ->
scope.unionSafe(parameters.effectiveSearchScope(e))
}
}
}
}
@@ -77,6 +95,43 @@ class KotlinReferencesSearchParameters(
val kotlinOptions: KotlinReferencesSearchOptions = Empty
) : ReferencesSearch.SearchParameters(elementToSearch, scope, ignoreAccessScope, optimizer)
class KotlinAliasedImportedElementSearcher : QueryExecutorBase<PsiReference, ReferencesSearch.SearchParameters>(true) {
override fun processQuery(parameters: ReferencesSearch.SearchParameters, consumer: Processor<in PsiReference?>) {
val kotlinOptions = (parameters as? KotlinReferencesSearchParameters)?.kotlinOptions ?: Empty
if (!kotlinOptions.acceptImportAlias) return
val element = parameters.elementToSearch
if (!element.isValid) return
val unwrappedElement = element.namedUnwrappedElement ?: return
val name = unwrappedElement.name
if (name == null || StringUtil.isEmptyOrSpaces(name)) return
val effectiveSearchScope = calculateEffectiveScope(unwrappedElement, parameters)
val collector = parameters.optimizer
val session = collector.searchSession
collector.searchWord(name, effectiveSearchScope, UsageSearchContext.IN_CODE, true, element, AliasProcessor(element, session))
}
private class AliasProcessor(
private val myTarget: PsiElement,
private val mySession: SearchSession
) : RequestResultProcessor(myTarget) {
override fun processTextOccurrence(element: PsiElement, offsetInElement: Int, consumer: Processor<in PsiReference>): Boolean {
val importStatement = element.parent as? KtImportDirective ?: return true
val importAlias = importStatement.alias?.name ?: return true
val reference = importStatement.importedReference?.getQualifiedElementSelector()?.mainReference ?: return true
if (!reference.isReferenceTo(myTarget)) {
return true
}
val collector = SearchRequestCollector(mySession)
val fileScope: SearchScope = LocalSearchScope(element.containingFile)
collector.searchWord(importAlias, fileScope, UsageSearchContext.IN_CODE, true, myTarget)
return PsiSearchHelper.getInstance(element.project).processRequests(collector, consumer)
}
}
}
class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearch.SearchParameters>() {
override fun processQuery(queryParameters: ReferencesSearch.SearchParameters, consumer: Processor<in PsiReference>) {
@@ -108,17 +163,7 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
null
} ?: unwrappedElement
val effectiveSearchScope = run {
val elements = if (elementToSearch is KtDeclaration && !isOnlyKotlinSearch(queryParameters.scopeDeterminedByUser)) {
elementToSearch.toLightElements().filterDataClassComponentsIfDisabled(kotlinOptions).nullize()
} else {
null
} ?: listOf(elementToSearch)
elements.fold(queryParameters.effectiveSearchScope) { scope, e ->
scope.unionSafe(queryParameters.effectiveSearchScope(e))
}
}
val effectiveSearchScope = calculateEffectiveScope(unwrappedElement, queryParameters)
val refFilter: (PsiReference) -> Boolean = when (elementToSearch) {
is KtParameter -> ({ ref: PsiReference -> !ref.isNamedArgumentReference()/* they are processed later*/ })
@@ -462,6 +462,11 @@
<refactoring.moveClassHandler
implementation="org.jetbrains.kotlin.idea.refactoring.move.moveFilesOrDirectories.MoveKotlinClassHandler"
order="first"/>
<refactoring.moveClassHandler
implementation="org.jetbrains.kotlin.idea.refactoring.move.moveFilesOrDirectories.MoveKotlinAliasClassHandler"
order="first"/>
<refactoring.moveMemberHandler language="kotlin"
implementationClass="org.jetbrains.kotlin.idea.refactoring.move.MoveKotlinMemberHandler"/>
<refactoring.moveInnerClassUsagesHandler
implementationClass="org.jetbrains.kotlin.idea.refactoring.move.MoveJavaInnerClassKotlinUsagesHandler"
language="kotlin" />
@@ -771,7 +776,9 @@
<attachSourcesProvider implementation="org.jetbrains.kotlin.idea.actions.DecompileKotlinToJavaActionProvider"/>
<gotoDeclarationHandler implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinImportAliasGotoDeclarationHandler"/>
<referencesSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearcher"/>
<referencesSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinAliasedImportedElementSearcher"/>
<directClassInheritorsSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinDirectInheritorsSearcher"/>
<overridingMethodsSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinOverridingMethodsWithGenericsSearcher"/>
<definitionsScopedSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinDefinitionsSearcher"/>
@@ -471,6 +471,11 @@
<refactoring.moveClassHandler
implementation="org.jetbrains.kotlin.idea.refactoring.move.moveFilesOrDirectories.MoveKotlinClassHandler"
order="first"/>
<refactoring.moveClassHandler
implementation="org.jetbrains.kotlin.idea.refactoring.move.moveFilesOrDirectories.MoveKotlinAliasClassHandler"
order="first"/>
<refactoring.moveMemberHandler language="kotlin"
implementationClass="org.jetbrains.kotlin.idea.refactoring.move.MoveKotlinMemberHandler"/>
<refactoring.moveInnerClassUsagesHandler
implementationClass="org.jetbrains.kotlin.idea.refactoring.move.MoveJavaInnerClassKotlinUsagesHandler"
language="kotlin" />
@@ -780,7 +785,9 @@
<attachSourcesProvider implementation="org.jetbrains.kotlin.idea.actions.DecompileKotlinToJavaActionProvider"/>
<gotoDeclarationHandler implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinImportAliasGotoDeclarationHandler"/>
<referencesSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearcher"/>
<referencesSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinAliasedImportedElementSearcher"/>
<directClassInheritorsSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinDirectInheritorsSearcher"/>
<overridingMethodsSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinOverridingMethodsWithGenericsSearcher"/>
<definitionsScopedSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinDefinitionsSearcher"/>
@@ -471,6 +471,11 @@
<refactoring.moveClassHandler
implementation="org.jetbrains.kotlin.idea.refactoring.move.moveFilesOrDirectories.MoveKotlinClassHandler"
order="first"/>
<refactoring.moveClassHandler
implementation="org.jetbrains.kotlin.idea.refactoring.move.moveFilesOrDirectories.MoveKotlinAliasClassHandler"
order="first"/>
<refactoring.moveMemberHandler language="kotlin"
implementationClass="org.jetbrains.kotlin.idea.refactoring.move.MoveKotlinMemberHandler"/>
<refactoring.moveInnerClassUsagesHandler
implementationClass="org.jetbrains.kotlin.idea.refactoring.move.MoveJavaInnerClassKotlinUsagesHandler"
language="kotlin" />
@@ -780,7 +785,9 @@
<attachSourcesProvider implementation="org.jetbrains.kotlin.idea.actions.DecompileKotlinToJavaActionProvider"/>
<gotoDeclarationHandler implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinImportAliasGotoDeclarationHandler"/>
<referencesSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearcher"/>
<referencesSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinAliasedImportedElementSearcher"/>
<directClassInheritorsSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinDirectInheritorsSearcher"/>
<overridingMethodsSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinOverridingMethodsWithGenericsSearcher"/>
<definitionsScopedSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinDefinitionsSearcher"/>
+3
View File
@@ -90,5 +90,8 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
<completion.ml.model implementation="org.jetbrains.kotlin.idea.completion.ml.KotlinMLRankingProvider"/>
<suggestedRefactoringSupport language="kotlin" implementationClass="org.jetbrains.kotlin.idea.refactoring.suggested.KotlinSuggestedRefactoringSupport"/>
<refactoring.moveInnerHandler language="kotlin"
implementationClass="org.jetbrains.kotlin.idea.refactoring.move.MoveKotlinInnerHandler"/>
</extensions>
</idea-plugin>
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.idea.findUsages
import com.intellij.CommonBundle
import com.intellij.find.FindBundle
import com.intellij.find.findUsages.FindUsagesHandler
import com.intellij.find.findUsages.FindUsagesHandler.NULL_HANDLER
import com.intellij.find.findUsages.FindUsagesHandlerFactory
import com.intellij.find.findUsages.FindUsagesOptions
import com.intellij.find.findUsages.JavaFindUsagesHandlerFactory
@@ -35,7 +36,9 @@ import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinFindClassUsagesHandle
import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinFindMemberUsagesHandler
import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinTypeParameterFindUsagesHandler
import org.jetbrains.kotlin.idea.refactoring.checkSuperMethods
import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementSelector
import org.jetbrains.kotlin.psi.psiUtil.parameterIndex
class KotlinFindUsagesHandlerFactory(project: Project) : FindUsagesHandlerFactory() {
@@ -52,10 +55,27 @@ class KotlinFindUsagesHandlerFactory(project: Project) : FindUsagesHandlerFactor
element is KtProperty ||
element is KtParameter ||
element is KtTypeParameter ||
element is KtConstructor<*>
element is KtConstructor<*> ||
(element is KtImportAlias &&
// TODO: it is ambiguous case: ImportAlias does not have any reference to be resolved
element.importDirective?.importedReference?.getQualifiedElementSelector()?.mainReference?.resolve() != null)
override fun createFindUsagesHandler(element: PsiElement, forHighlightUsages: Boolean): FindUsagesHandler {
when (element) {
is KtImportAlias -> {
return when (val resolvedElement =
element.importDirective?.importedReference?.getQualifiedElementSelector()?.mainReference?.resolve()) {
is KtClassOrObject ->
if (!forHighlightUsages) {
createFindUsagesHandler(resolvedElement, forHighlightUsages)
} else NULL_HANDLER
is KtNamedFunction, is KtProperty, is KtConstructor<*> ->
createFindUsagesHandler(resolvedElement, forHighlightUsages)
else -> NULL_HANDLER
}
}
is KtClassOrObject ->
return KotlinFindClassUsagesHandler(element, this)
@@ -118,10 +138,10 @@ class KotlinFindUsagesHandlerFactory(project: Project) : FindUsagesHandlerFactor
private fun handlerForMultiple(originalDeclaration: KtNamedDeclaration, declarations: Collection<PsiElement>): FindUsagesHandler {
return when (declarations.size) {
0 -> FindUsagesHandler.NULL_HANDLER
0 -> NULL_HANDLER
1 -> {
val target = declarations.single().unwrapped ?: return FindUsagesHandler.NULL_HANDLER
val target = declarations.single().unwrapped ?: return NULL_HANDLER
if (target is KtNamedDeclaration) {
KotlinFindMemberUsagesHandler.getInstance(target, factory = this)
} else {
@@ -0,0 +1,19 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.refactoring.move
import com.intellij.refactoring.move.moveInner.MoveJavaInnerHandler
import com.intellij.usageView.UsageInfo
import org.jetbrains.kotlin.idea.references.getImportAlias
class MoveKotlinInnerHandler : MoveJavaInnerHandler() {
override fun preprocessUsages(results: MutableCollection<UsageInfo>?) {
results?.removeAll { usageInfo ->
usageInfo.element?.references?.any { it.getImportAlias() != null } == true
}
}
}
@@ -0,0 +1,35 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.refactoring.move
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiMember
import com.intellij.psi.PsiReference
import com.intellij.refactoring.move.moveMembers.MoveJavaMemberHandler
import com.intellij.refactoring.move.moveMembers.MoveMembersOptions
import com.intellij.refactoring.move.moveMembers.MoveMembersProcessor
import org.jetbrains.kotlin.idea.references.getImportAlias
class MoveKotlinMemberHandler : MoveJavaMemberHandler() {
override fun getUsage(
member: PsiMember,
psiReference: PsiReference,
membersToMove: MutableSet<PsiMember>,
targetClass: PsiClass
): MoveMembersProcessor.MoveMembersUsageInfo? {
psiReference?.getImportAlias()?.let {
return null
}
return super.getUsage(member, psiReference, membersToMove, targetClass)
}
override fun changeExternalUsage(options: MoveMembersOptions, usage: MoveMembersProcessor.MoveMembersUsageInfo): Boolean {
val reference = usage.getReference()
reference?.getImportAlias()?.let { return true }
return super.changeExternalUsage(options, usage)
}
}
@@ -222,8 +222,8 @@ class MoveKotlinDeclarationsProcessor(
)
}
MoveClassHandler.EP_NAME.extensions.forEach { handler ->
if (handler !is MoveKotlinClassHandler) handler.preprocessUsages(results)
MoveClassHandler.EP_NAME.extensions.filter { it !is MoveKotlinClassHandler }.forEach { handler ->
handler.preprocessUsages(results)
}
results
@@ -0,0 +1,42 @@
/*
* Copyright 2010-2016 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.refactoring.move.moveFilesOrDirectories
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiDirectory
import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassHandler
import com.intellij.refactoring.util.MoveRenameUsageInfo
import com.intellij.usageView.UsageInfo
import org.jetbrains.kotlin.idea.references.getImportAlias
class MoveKotlinAliasClassHandler : MoveClassHandler {
override fun doMoveClass(aClass: PsiClass, moveDestination: PsiDirectory): PsiClass? = null
override fun getName(clazz: PsiClass?): String? = null
override fun preprocessUsages(results: MutableCollection<UsageInfo>) {
results.removeAll { usageInfo ->
usageInfo is MoveRenameUsageInfo && usageInfo.reference?.getImportAlias() != null
}
}
override fun prepareMove(aClass: PsiClass) {
}
override fun finishMoveClass(aClass: PsiClass) {
}
}
@@ -0,0 +1,18 @@
// PSI_ELEMENT: com.intellij.psi.PsiClass
// OPTIONS: usages
public class <caret>AAA {
public String bar = "bar";
public static String BAR = "BAR";
public AAA() {
}
public void foo() {
}
public static void foos() {
}
}
@@ -0,0 +1,39 @@
import AAA as A
public class X(bar: String? = A.BAR): A() {
var next: A? = A()
val myBar: String? = A.BAR
init {
A.BAR = ""
AAA.foos()
}
fun foo(a: A) {
val aa: AAA = a
aa.bar = ""
}
fun getNext(): A? {
return next
}
public override fun foo() {
super<A>.foo()
}
companion object: AAA() {
}
}
object O: A() {
}
fun X.bar(a: A = A()) {
}
fun Any.toA(): A? {
return if (this is A) this as A else null
}
@@ -0,0 +1,17 @@
Class/object property type 3 var next: A? = A()
Function return types 16 fun getNext(): A? {
Function return types 37 fun Any.toA(): A? {
Nested class/object 2 public class X(bar: String? = A.BAR): A() {
Nested class/object 4 val myBar: String? = A.BAR
Nested class/object 7 A.BAR = ""
Nested class/object 8 AAA.foos()
New instance creation 3 var next: A? = A()
New instance creation 33 fun X.bar(a: A = A()) {
Parameter type 11 fun foo(a: A) {
Parameter type 33 fun X.bar(a: A = A()) {
Super type qualifier 21 super<A>.foo()
Supertype 2 public class X(bar: String? = A.BAR): A() {
Supertype 29 object O: A() {
Target type of 'is' operation 38 return if (this is A) this as A else null
Usage in cast target type 38 return if (this is A) this as A else null
Usage in import 1 import AAA as A
@@ -0,0 +1,13 @@
// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtClass
// OPTIONS: usages, constructorUsages
package server
open class <caret>Server {
companion object {
val NAME = "Server"
}
open fun work() {
println("Server")
}
}
@@ -0,0 +1,55 @@
package client
import server.Server as Srv
import server.Server
class Client(name: String = Server.NAME): Srv() {
var nextServer: Server? = new Server()
val name = Server.NAME
/**
* [Srv] parameter
*/
fun foo(s: Srv) {
val server: Server = s
println("Server: $server")
}
fun getNextServer(): Server? {
return nextServer
}
override fun work() {
super<Server>.work()
println("Client")
}
companion object: Server() {
}
}
object ClientObject: Server() {
}
class Servers: Iterator<Server> {
}
fun Iterator<Server>.f(p: Iterator<Server>): Iterator<Server> = this
fun Client.bar(s: Server = Server.NAME) {
foo(s)
}
fun Client.hasNextServer(): Boolean {
return getNextServer() != null
}
fun Any.asServer(): Server? {
when (this) {
is Server -> println("Server!")
}
return if (this is Server) this as Server else this as? Server
}
@@ -0,0 +1,24 @@
Class/object property type 7 var nextServer: Server? = new Server()
Companion object 42 fun Client.bar(s: Server = Server.NAME) {
Companion object 6 class Client(name: String = Server.NAME): Srv() {
Companion object 8 val name = Server.NAME
Function return types 18 fun getNextServer(): Server? {
Function return types 50 fun Any.asServer(): Server? {
Local variable declaration 14 val server: Server = s
Parameter type 13 fun foo(s: Srv) {
Parameter type 42 fun Client.bar(s: Server = Server.NAME) {
Super type qualifier 23 super<Server>.work()
Supertype 27 companion object: Server() {
Supertype 32 object ClientObject: Server() {
Supertype 6 class Client(name: String = Server.NAME): Srv() {
Target type of 'is' operation 52 is Server -> println("Server!")
Target type of 'is' operation 54 return if (this is Server) this as Server else this as? Server
Type parameter 36 class Servers: Iterator<Server> {
Type parameter 40 fun Iterator<Server>.f(p: Iterator<Server>): Iterator<Server> = this
Type parameter 40 fun Iterator<Server>.f(p: Iterator<Server>): Iterator<Server> = this
Type parameter 40 fun Iterator<Server>.f(p: Iterator<Server>): Iterator<Server> = this
Usage in cast target type 54 return if (this is Server) this as Server else this as? Server
Usage in cast target type 54 return if (this is Server) this as Server else this as? Server
Usage in comments 11 * [Srv] parameter
Usage in import 3 import server.Server as Srv
Usage in import 4 import server.Server
@@ -0,0 +1,57 @@
// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtImportAlias
// OPTIONS: usages, constructorUsages
package client
import server.Server as Srv<caret>
import server.Server
class Client(name: String = Server.NAME): Srv() {
var nextServer: Server? = new Server()
val name = Server.NAME
/**
* [Srv] parameter
*/
fun foo(s: Srv) {
val server: Server = s
println("Server: $server")
}
fun getNextServer(): Server? {
return nextServer
}
override fun work() {
super<Server>.work()
println("Client")
}
companion object: Server() {
}
}
object ClientObject: Server() {
}
class Servers: Iterator<Server> {
}
fun Iterator<Server>.f(p: Iterator<Server>): Iterator<Server> = this
fun Client.bar(s: Server = Server.NAME) {
foo(s)
}
fun Client.hasNextServer(): Boolean {
return getNextServer() != null
}
fun Any.asServer(): Server? {
when (this) {
is Server -> println("Server!")
}
return if (this is Server) this as Server else this as? Server
}
@@ -0,0 +1,11 @@
package server
open class Server {
companion object {
val NAME = "Server"
}
open fun work() {
println("Server")
}
}
@@ -0,0 +1,24 @@
Class/object property type 9 var nextServer: Server? = new Server()
Companion object 10 val name = Server.NAME
Companion object 44 fun Client.bar(s: Server = Server.NAME) {
Companion object 8 class Client(name: String = Server.NAME): Srv() {
Function return types 20 fun getNextServer(): Server? {
Function return types 52 fun Any.asServer(): Server? {
Local variable declaration 16 val server: Server = s
Parameter type 15 fun foo(s: Srv) {
Parameter type 44 fun Client.bar(s: Server = Server.NAME) {
Super type qualifier 25 super<Server>.work()
Supertype 29 companion object: Server() {
Supertype 34 object ClientObject: Server() {
Supertype 8 class Client(name: String = Server.NAME): Srv() {
Target type of 'is' operation 54 is Server -> println("Server!")
Target type of 'is' operation 56 return if (this is Server) this as Server else this as? Server
Type parameter 38 class Servers: Iterator<Server> {
Type parameter 42 fun Iterator<Server>.f(p: Iterator<Server>): Iterator<Server> = this
Type parameter 42 fun Iterator<Server>.f(p: Iterator<Server>): Iterator<Server> = this
Type parameter 42 fun Iterator<Server>.f(p: Iterator<Server>): Iterator<Server> = this
Usage in cast target type 56 return if (this is Server) this as Server else this as? Server
Usage in cast target type 56 return if (this is Server) this as Server else this as? Server
Usage in comments 13 * [Srv] parameter
Usage in import 5 import server.Server as Srv
Usage in import 6 import server.Server
@@ -0,0 +1,5 @@
// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtNamedFunction
// OPTIONS: usages
package server
fun <caret>processRequest() = "foo"
@@ -0,0 +1,7 @@
import server.processRequest as process
class Client {
public fun foo() {
process()
}
}
@@ -0,0 +1,2 @@
Function call 5 process()
Usage in import 1 import server.processRequest as process
@@ -0,0 +1,15 @@
// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtImportAlias
// OPTIONS: usages
import server.processRequest as process<caret>
import server.processRequest
class Client {
fun foo() {
process()
}
fun foo2() {
processRequest()
}
}
@@ -0,0 +1,3 @@
package server
fun processRequest() = "foo"
@@ -0,0 +1,4 @@
Function call 13 processRequest()
Function call 9 process()
Usage in import 4 import server.processRequest as process
Usage in import 5 import server.processRequest
@@ -0,0 +1,18 @@
// IGNORE: see KotlinFindUsagesHandlerFactory: it is ambiguous case: ImportAlias does not have any reference to be resolved
// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtImportAlias
// OPTIONS: usages
package c
import c.a
import c.a as b<caret>
fun a() = Unit
fun a(i: Int) = Unit
fun test() {
a()
a(1)
b()
b(1)
}
@@ -0,0 +1,8 @@
Function call 13 a()
Function call 14 a(1)
Function call 15 b()
Function call 16 b(1)
Usage in import 6 import c.a
Usage in import 6 import c.a
Usage in import 7 import c.a as b
Usage in import 7 import c.a as b
@@ -0,0 +1,17 @@
// FILE: before.kt
package c
import c.I1 as I<caret>
interface I1
fun foo(i: I){}
// FILE: after.kt
package c
import c.I1 as I
interface <caret>I1
fun foo(i: I){}
@@ -0,0 +1,27 @@
// FILE: before.kt
package c
import c.a
import c.a as b<caret> // caret stays here as it results into multiple results
fun a() = Unit
fun a(i: Int) = Unit
fun test() {
a()
b()
}
// FILE: after.kt
package c
import c.a
import c.a as b<caret> // caret stays here as it results into multiple results
fun a() = Unit
fun a(i: Int) = Unit
fun test() {
a()
b()
}
@@ -1,7 +1,5 @@
package a
import b.X as XX
fun bar() {
val t: XX = XX()
val t: b.X = b.X()
}
@@ -0,0 +1,7 @@
package a
import b.X as XX
fun bar() {
val t: XX = XX()
}
@@ -1,7 +1,5 @@
package b
import b.X as XX
fun bar() {
val t: XX = XX()
val t: b.X = b.X()
}
@@ -0,0 +1,7 @@
package b
import b.X as XX
fun bar() {
val t: XX = XX()
}
@@ -1,7 +1,5 @@
package a
import a.X as XX
fun bar(s: String) {
val t: XX = XX()
val t: a.X = a.X()
}
@@ -0,0 +1,7 @@
package a
import a.X as XX
fun bar(s: String) {
val t: XX = XX()
}
@@ -1,7 +1,5 @@
package a
import a.Y as XX
fun bar(s: String) {
val t: XX = XX()
val t: a.Y = a.Y()
}
@@ -0,0 +1,7 @@
package a
import a.Y as XX
fun bar(s: String) {
val t: XX = XX()
}
@@ -89,6 +89,11 @@ abstract class AbstractFindUsagesTest : KotlinLightCodeInsightFixtureTestCase()
val isPropertiesFile = FileUtilRt.getExtension(path) == "properties"
InTextDirectivesUtils.findStringWithPrefixes(mainFileText, "// IGNORE: ")?.let {
println("test $mainFileName is ignored")
return
}
val isFindFileUsages = InTextDirectivesUtils.isDirectiveDefined(mainFileText, "## FIND_FILE_USAGES")
@Suppress("UNCHECKED_CAST")
@@ -351,6 +351,11 @@ public class FindUsagesTestGenerated extends AbstractFindUsagesTest {
runTest("idea/testData/findUsages/kotlin/findClassUsages/javaDerivedInterfaceUsages2.0.kt");
}
@TestMetadata("kotlinAliasedClassAllUsages.0.kt")
public void testKotlinAliasedClassAllUsages() throws Exception {
runTest("idea/testData/findUsages/kotlin/findClassUsages/kotlinAliasedClassAllUsages.0.kt");
}
@TestMetadata("kotlinClassAllUsages.0.kt")
public void testKotlinClassAllUsages() throws Exception {
runTest("idea/testData/findUsages/kotlin/findClassUsages/kotlinClassAllUsages.0.kt");
@@ -431,6 +436,11 @@ public class FindUsagesTestGenerated extends AbstractFindUsagesTest {
runTest("idea/testData/findUsages/kotlin/findClassUsages/kotlinClassFunctionUsages2.0.kt");
}
@TestMetadata("kotlinClassImportAliasAllUsages.0.kt")
public void testKotlinClassImportAliasAllUsages() throws Exception {
runTest("idea/testData/findUsages/kotlin/findClassUsages/kotlinClassImportAliasAllUsages.0.kt");
}
@TestMetadata("kotlinClassNonConstructorUsages.0.kt")
public void testKotlinClassNonConstructorUsages() throws Exception {
runTest("idea/testData/findUsages/kotlin/findClassUsages/kotlinClassNonConstructorUsages.0.kt");
@@ -614,6 +624,11 @@ public class FindUsagesTestGenerated extends AbstractFindUsagesTest {
runTest("idea/testData/findUsages/kotlin/findFunctionUsages/jvmStaticJvmOverloadsFun.0.kt");
}
@TestMetadata("kotlinAliasedMethodUsages.0.kt")
public void testKotlinAliasedMethodUsages() throws Exception {
runTest("idea/testData/findUsages/kotlin/findFunctionUsages/kotlinAliasedMethodUsages.0.kt");
}
@TestMetadata("kotlinInternalMethodUsages.0.kt")
public void testKotlinInternalMethodUsages() throws Exception {
runTest("idea/testData/findUsages/kotlin/findFunctionUsages/kotlinInternalMethodUsages.0.kt");
@@ -629,6 +644,16 @@ public class FindUsagesTestGenerated extends AbstractFindUsagesTest {
runTest("idea/testData/findUsages/kotlin/findFunctionUsages/kotlinLocalMethodUsages2.0.kt");
}
@TestMetadata("kotlinMethodAliasedUsages.0.kt")
public void testKotlinMethodAliasedUsages() throws Exception {
runTest("idea/testData/findUsages/kotlin/findFunctionUsages/kotlinMethodAliasedUsages.0.kt");
}
@TestMetadata("kotlinMethodsAliasedUsages.0.kt")
public void testKotlinMethodsAliasedUsages() throws Exception {
runTest("idea/testData/findUsages/kotlin/findFunctionUsages/kotlinMethodsAliasedUsages.0.kt");
}
@TestMetadata("kotlinMethodUsages.0.kt")
public void testKotlinMethodUsages() throws Exception {
runTest("idea/testData/findUsages/kotlin/findFunctionUsages/kotlinMethodUsages.0.kt");
@@ -1538,6 +1563,11 @@ public class FindUsagesTestGenerated extends AbstractFindUsagesTest {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/findUsages/java/findJavaClassUsages"), Pattern.compile("^(.+)\\.0\\.java$"), null, true);
}
@TestMetadata("JKAliasedClassAllUsages.0.java")
public void testJKAliasedClassAllUsages() throws Exception {
runTest("idea/testData/findUsages/java/findJavaClassUsages/JKAliasedClassAllUsages.0.java");
}
@TestMetadata("JKClassAllUsages.0.java")
public void testJKClassAllUsages() throws Exception {
runTest("idea/testData/findUsages/java/findJavaClassUsages/JKClassAllUsages.0.java");
@@ -28,6 +28,16 @@ public class GotoDeclarationTestGenerated extends AbstractGotoDeclarationTest {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/navigation/gotoDeclaration"), Pattern.compile("^(.+)\\.test$"), null, true);
}
@TestMetadata("importAlias.test")
public void testImportAlias() throws Exception {
runTest("idea/testData/navigation/gotoDeclaration/importAlias.test");
}
@TestMetadata("importAliasMultiDeclarations.test")
public void testImportAliasMultiDeclarations() throws Exception {
runTest("idea/testData/navigation/gotoDeclaration/importAliasMultiDeclarations.test");
}
@TestMetadata("itExtensionLambda.test")
public void testItExtensionLambda() throws Exception {
runTest("idea/testData/navigation/gotoDeclaration/itExtensionLambda.test");