[FIR IDE] Separate find usages logic from descriptors
This commit is contained in:
@@ -79,7 +79,6 @@ wrapped.into.a.reference.object.to.be.modified.when.captured.in.a.closure=Wrappe
|
|||||||
smart.cast.to.0.for.1.call=Smart cast to {0} (for {1} call)
|
smart.cast.to.0.for.1.call=Smart cast to {0} (for {1} call)
|
||||||
smart.cast.to.0=Smart cast to {0}
|
smart.cast.to.0=Smart cast to {0}
|
||||||
replace.overloaded.operator.with.function.call=Replace overloaded operator with function call
|
replace.overloaded.operator.with.function.call=Replace overloaded operator with function call
|
||||||
searching.for.implicit.usages=Searching for implicit usages...
|
|
||||||
class.initializer=<class initializer>
|
class.initializer=<class initializer>
|
||||||
object.0=object{0}
|
object.0=object{0}
|
||||||
show.non.public=Show non-public
|
show.non.public=Show non-public
|
||||||
|
|||||||
+32
-4
@@ -16,14 +16,14 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.search.usagesSearch
|
package org.jetbrains.kotlin.idea.search.usagesSearch
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiNamedElement
|
import com.intellij.psi.PsiNamedElement
|
||||||
import org.jetbrains.kotlin.asJava.LightClassUtil
|
import org.jetbrains.kotlin.asJava.LightClassUtil
|
||||||
import org.jetbrains.kotlin.asJava.LightClassUtil.PropertyAccessorsPsiMethods
|
import org.jetbrains.kotlin.asJava.LightClassUtil.PropertyAccessorsPsiMethods
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToParameterDescriptorIfAny
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
@@ -31,6 +31,11 @@ import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
|||||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.DataClassDescriptorResolver
|
import org.jetbrains.kotlin.resolve.DataClassDescriptorResolver
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||||
|
import org.jetbrains.kotlin.resolve.findOriginalTopMostOverriddenDescriptors
|
||||||
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
|
||||||
|
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
fun PsiNamedElement.getAccessorNames(readable: Boolean = true, writable: Boolean = true): List<String> {
|
fun PsiNamedElement.getAccessorNames(readable: Boolean = true, writable: Boolean = true): List<String> {
|
||||||
@@ -87,3 +92,26 @@ fun KtParameter.isDataClassProperty(): Boolean {
|
|||||||
return this.containingClassOrObject?.hasModifier(KtTokens.DATA_KEYWORD) ?: false
|
return this.containingClassOrObject?.hasModifier(KtTokens.DATA_KEYWORD) ?: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getTopMostOverriddenElementsToHighlight(target: PsiElement): List<PsiElement> {
|
||||||
|
val callableDescriptor = (target as? KtCallableDeclaration)?.resolveToDescriptorIfAny() as? CallableDescriptor
|
||||||
|
val descriptorsToHighlight = if (callableDescriptor is ParameterDescriptor)
|
||||||
|
listOf(callableDescriptor)
|
||||||
|
else
|
||||||
|
callableDescriptor?.findOriginalTopMostOverriddenDescriptors() ?: emptyList()
|
||||||
|
|
||||||
|
return descriptorsToHighlight.mapNotNull { it.source.getPsi() }.filter { it != target }
|
||||||
|
}
|
||||||
|
|
||||||
|
val KtDeclaration.descriptor: DeclarationDescriptor?
|
||||||
|
get() = if (this is KtParameter) this.descriptor else this.resolveToDescriptorIfAny(BodyResolveMode.FULL)
|
||||||
|
|
||||||
|
val KtParameter.descriptor: ValueParameterDescriptor?
|
||||||
|
get() = this.resolveToParameterDescriptorIfAny(BodyResolveMode.FULL)
|
||||||
|
|
||||||
|
fun isCallReceiverRefersToCompanionObject(element: KtElement, companionObject: KtObjectDeclaration): Boolean {
|
||||||
|
val companionObjectDescriptor = companionObject.descriptor
|
||||||
|
val bindingContext = element.analyze()
|
||||||
|
val resolvedCall = bindingContext[BindingContext.CALL, element]?.getResolvedCall(bindingContext) ?: return false
|
||||||
|
return (resolvedCall.dispatchReceiver as? ImplicitClassReceiver)?.declarationDescriptor == companionObjectDescriptor ||
|
||||||
|
(resolvedCall.extensionReceiver as? ImplicitClassReceiver)?.declarationDescriptor == companionObjectDescriptor
|
||||||
|
}
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ import org.jetbrains.kotlin.idea.core.extension.KotlinIndicesHelperExtension
|
|||||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||||
import org.jetbrains.kotlin.idea.resolve.frontendService
|
import org.jetbrains.kotlin.idea.resolve.frontendService
|
||||||
import org.jetbrains.kotlin.idea.search.excludeKotlinSources
|
import org.jetbrains.kotlin.idea.search.excludeKotlinSources
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
|
|
||||||
import org.jetbrains.kotlin.idea.stubindex.*
|
import org.jetbrains.kotlin.idea.stubindex.*
|
||||||
import org.jetbrains.kotlin.idea.util.CallType
|
import org.jetbrains.kotlin.idea.util.CallType
|
||||||
import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver
|
import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ dependencies {
|
|||||||
compileOnly(project(":kotlin-reflect-api"))
|
compileOnly(project(":kotlin-reflect-api"))
|
||||||
compileOnly(intellijCoreDep())
|
compileOnly(intellijCoreDep())
|
||||||
compileOnly(intellijDep())
|
compileOnly(intellijDep())
|
||||||
|
compileOnly(project(":compiler:light-classes"))
|
||||||
|
|
||||||
Platform[191].orLower {
|
Platform[191].orLower {
|
||||||
compileOnly(intellijDep()) { includeJars("java-api", "java-impl") }
|
compileOnly(intellijDep()) { includeJars("java-api", "java-impl") }
|
||||||
@@ -29,8 +30,14 @@ dependencies {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
"main" { projectDefault() }
|
"main" {
|
||||||
|
projectDefault()
|
||||||
|
resources.srcDirs(
|
||||||
|
"resources-en"
|
||||||
|
)
|
||||||
|
}
|
||||||
"test" { projectDefault() }
|
"test" { projectDefault() }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
testsJar()
|
testsJar()
|
||||||
|
|||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
find.declaration.implementing.methods.checkbox=&Implementing functions
|
||||||
|
find.declaration.overriding.methods.checkbox=Over&riding functions
|
||||||
|
find.declaration.implementing.properties.checkbox=&Implementing properties
|
||||||
|
find.declaration.overriding.properties.checkbox=Over&riding properties
|
||||||
|
find.declaration.property.readers.checkbox=Readers
|
||||||
|
find.declaration.property.writers.checkbox=Writers
|
||||||
|
find.declaration.include.overloaded.methods.checkbox=Include o&verloaded functions and extensions
|
||||||
|
find.declaration.functions.usages.checkbox=Usages of &functions
|
||||||
|
find.declaration.properties.usages.checkbox=Usages of &properties
|
||||||
|
find.declaration.constructor.usages.checkbox=Usages of &constructor
|
||||||
|
find.declaration.derived.classes.checkbox=&Derived classes
|
||||||
|
find.declaration.derived.interfaces.checkbox=Derived &interfaces
|
||||||
|
|
||||||
|
find.usages.class=class
|
||||||
|
find.usages.companion.object=companion object
|
||||||
|
find.usages.constructor=constructor
|
||||||
|
find.usages.facade.class=facade class
|
||||||
|
find.usages.for.property={0} for property
|
||||||
|
find.usages.function=function
|
||||||
|
find.usages.getter=getter
|
||||||
|
find.usages.import.alias=import alias
|
||||||
|
find.usages.interface=interface
|
||||||
|
find.usages.label=label
|
||||||
|
find.usages.lambda=lambda
|
||||||
|
find.usages.object=object
|
||||||
|
find.usages.parameter=parameter
|
||||||
|
find.usages.property.accessor=property accessor
|
||||||
|
find.usages.property=property
|
||||||
|
find.usages.setter=setter
|
||||||
|
find.usages.type.alias=type alias
|
||||||
|
find.usages.type.parameter=type parameter
|
||||||
|
find.usages.variable=variable
|
||||||
|
find.usages.checkbox.name.expected.classes=Expected classes
|
||||||
|
find.usages.class.name.anonymous=Anonymous
|
||||||
|
find.usages.checkbox.name.expected.functions=Expected functions
|
||||||
|
find.usages.text.find.usages.for.data.class.components.and.destruction.declarations=<p>Find usages for data class components and destructuring declarations<br/>could be <a href="{0}">disabled once</a> or <a href="{1}">disabled for a project</a>.</p>
|
||||||
|
find.usages.tool.tip.text.disable.search.for.data.class.components.and.destruction.declarations.project.wide.setting=Disable search for data class components and destructuring declarations. (Project wide setting)
|
||||||
|
find.usages.checkbox.text.fast.data.class.component.search=Fast data class component search
|
||||||
|
find.usages.checkbox.name.expected.properties=Expected properties
|
||||||
|
find.usages.action.text.find.usages.of=find usages of
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
searching.for.implicit.usages=Searching for implicit usages...
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
import com.intellij.DynamicBundle
|
||||||
|
|
||||||
|
abstract class AbstractKotlinBundleIndependent protected constructor(pathToBundle: String) : DynamicBundle(pathToBundle) {
|
||||||
|
protected fun String.withHtml(): String = "<html>$this</html>"
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
import com.intellij.AbstractBundle
|
||||||
|
|
||||||
|
abstract class AbstractKotlinBundleIndependent protected constructor(pathToBundle: String) : AbstractBundle(pathToBundle) {
|
||||||
|
protected fun String.withHtml(): String = "<html>$this</html>"
|
||||||
|
}
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
import org.jetbrains.annotations.PropertyKey
|
||||||
|
|
||||||
|
@NonNls
|
||||||
|
private const val BUNDLE = "messages.KotlinBundleIndependent"
|
||||||
|
|
||||||
|
//TODO Copy-pasted from KotlinBundle.kt
|
||||||
|
object KotlinBundleIndependent : AbstractKotlinBundleIndependent(BUNDLE) {
|
||||||
|
@JvmStatic
|
||||||
|
fun message(@NonNls @PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any): String = getMessage(key, *params)
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun htmlMessage(@NonNls @PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any): String =
|
||||||
|
getMessage(key, *params).withHtml()
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun lazyMessage(@PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any): () -> String = { getMessage(key, *params) }
|
||||||
|
}
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
import org.jetbrains.annotations.PropertyKey
|
||||||
|
|
||||||
|
@NonNls
|
||||||
|
private const val BUNDLE = "messages.KotlinIdeaAnalysisBundleIndependent"
|
||||||
|
|
||||||
|
object KotlinIdeaAnalysisBundleIndependent : AbstractKotlinBundleIndependent(BUNDLE) {
|
||||||
|
@JvmStatic
|
||||||
|
fun message(@NonNls @PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any): String = getMessage(key, *params)
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun htmlMessage(@NonNls @PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any): String =
|
||||||
|
getMessage(key, *params).withHtml()
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun lazyMessage(@PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any): () -> String = { getMessage(key, *params) }
|
||||||
|
}
|
||||||
+93
@@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* 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.asJava
|
||||||
|
|
||||||
|
import com.intellij.openapi.components.ServiceManager
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.psi.*
|
||||||
|
import com.intellij.psi.impl.light.AbstractLightClass
|
||||||
|
import com.intellij.psi.impl.light.LightMethod
|
||||||
|
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||||
|
import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||||
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport
|
||||||
|
import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||||
|
|
||||||
|
interface LightClassProvider {
|
||||||
|
|
||||||
|
fun getLightFieldForCompanionObject(companionObject: KtClassOrObject): PsiField?
|
||||||
|
|
||||||
|
fun getLightClassMethods(function: KtFunction): List<PsiMethod>
|
||||||
|
|
||||||
|
//getLightClassPropertyMethods.allDeclarations
|
||||||
|
fun getLightClassParameterDeclarations(parameter: KtParameter): List<PsiNamedElement>
|
||||||
|
|
||||||
|
//getLightClassPropertyMethods.allDeclarations
|
||||||
|
fun getLightClassPropertyDeclarations(property: KtProperty): List<PsiNamedElement>
|
||||||
|
|
||||||
|
fun toLightClassWithBuiltinMapping(classOrObject: KtClassOrObject): PsiClass?
|
||||||
|
|
||||||
|
fun toLightMethods(psiElement: PsiElement): List<PsiMethod>
|
||||||
|
|
||||||
|
fun toLightClass(classOrObject: KtClassOrObject): KtLightClass?
|
||||||
|
|
||||||
|
fun toLightElements(ktElement: KtElement): List<PsiNamedElement>
|
||||||
|
|
||||||
|
fun createKtFakeLightClass(kotlinOrigin: KtClassOrObject): PsiClass
|
||||||
|
|
||||||
|
fun getRepresentativeLightMethod(psiElement: PsiElement): PsiMethod?
|
||||||
|
|
||||||
|
fun isKtFakeLightClass(psiClass: PsiClass): Boolean
|
||||||
|
|
||||||
|
fun createKtFakeLightMethod(ktDeclaration: KtNamedDeclaration): PsiMethod?
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
fun getInstance(project: Project): LightClassProvider {
|
||||||
|
return ServiceManager.getService(project, LightClassProvider::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun providedGetLightFieldForCompanionObject(companionObject: KtClassOrObject): PsiField? =
|
||||||
|
getInstance(companionObject.project).getLightFieldForCompanionObject(companionObject)
|
||||||
|
|
||||||
|
fun providedGetLightClassMethods(function: KtFunction): List<PsiMethod> =
|
||||||
|
getInstance(function.project).getLightClassMethods(function)
|
||||||
|
|
||||||
|
//getLightClassPropertyMethods.allDeclarations
|
||||||
|
fun providedGetLightClassParameterDeclarations(parameter: KtParameter): List<PsiNamedElement> =
|
||||||
|
getInstance(parameter.project).getLightClassParameterDeclarations(parameter)
|
||||||
|
|
||||||
|
//getLightClassPropertyMethods.allDeclarations
|
||||||
|
fun providedGetLightClassPropertyDeclarations(property: KtProperty): List<PsiNamedElement> =
|
||||||
|
getInstance(property.project).getLightClassPropertyDeclarations(property)
|
||||||
|
|
||||||
|
fun KtClassOrObject.providedToLightClassWithBuiltinMapping(): PsiClass? =
|
||||||
|
getInstance(project).toLightClassWithBuiltinMapping(this)
|
||||||
|
|
||||||
|
fun PsiElement.providedToLightMethods(): List<PsiMethod> =
|
||||||
|
getInstance(project).toLightMethods(this)
|
||||||
|
|
||||||
|
fun KtClassOrObject.providedToLightClass(): KtLightClass? =
|
||||||
|
getInstance(project).toLightClass(this)
|
||||||
|
|
||||||
|
fun KtElement.providedToLightElements(): List<PsiNamedElement> =
|
||||||
|
getInstance(project).toLightElements(this)
|
||||||
|
|
||||||
|
fun providedCreateKtFakeLightClass(kotlinOrigin: KtClassOrObject): PsiClass? =
|
||||||
|
getInstance(kotlinOrigin.project).createKtFakeLightClass(kotlinOrigin)
|
||||||
|
|
||||||
|
fun PsiClass.providedIsKtFakeLightClass(): Boolean =
|
||||||
|
getInstance(project).isKtFakeLightClass(this)
|
||||||
|
|
||||||
|
fun providedCreateKtFakeLightMethod(ktDeclaration: KtNamedDeclaration): PsiMethod? =
|
||||||
|
getInstance(ktDeclaration.project).createKtFakeLightMethod(ktDeclaration)
|
||||||
|
|
||||||
|
fun PsiElement.providedGetRepresentativeLightMethod(): PsiMethod? =
|
||||||
|
getInstance(project).getRepresentativeLightMethod(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
+229
@@ -0,0 +1,229 @@
|
|||||||
|
/*
|
||||||
|
* 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.findUsages
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.highlighting.HighlightUsagesDescriptionLocation
|
||||||
|
import com.intellij.openapi.util.text.StringUtil
|
||||||
|
import com.intellij.psi.ElementDescriptionLocation
|
||||||
|
import com.intellij.psi.ElementDescriptionProvider
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.PsiNamedElement
|
||||||
|
import com.intellij.refactoring.util.CommonRefactoringUtil
|
||||||
|
import com.intellij.refactoring.util.RefactoringDescriptionLocation
|
||||||
|
import com.intellij.usageView.UsageViewLongNameLocation
|
||||||
|
import com.intellij.usageView.UsageViewShortNameLocation
|
||||||
|
import com.intellij.usageView.UsageViewTypeLocation
|
||||||
|
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
||||||
|
import org.jetbrains.kotlin.asJava.unwrapped
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinBundleIndependent
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||||
|
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
|
|
||||||
|
open class KotlinElementDescriptionProviderBase : ElementDescriptionProvider {
|
||||||
|
private tailrec fun KtNamedDeclaration.parentForFqName(): KtNamedDeclaration? {
|
||||||
|
val parent = getStrictParentOfType<KtNamedDeclaration>() ?: return null
|
||||||
|
if (parent is KtProperty && parent.isLocal) return parent.parentForFqName()
|
||||||
|
return parent
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun KtNamedDeclaration.name() = nameAsName ?: Name.special("<no name provided>")
|
||||||
|
|
||||||
|
private fun KtNamedDeclaration.fqName(): FqNameUnsafe {
|
||||||
|
containingClassOrObject?.let {
|
||||||
|
if (it is KtObjectDeclaration && it.isCompanion()) {
|
||||||
|
return it.fqName().child(name())
|
||||||
|
}
|
||||||
|
return FqNameUnsafe("${it.name()}.${name()}")
|
||||||
|
}
|
||||||
|
|
||||||
|
val internalSegments = generateSequence(this) { it.parentForFqName() }
|
||||||
|
.filterIsInstance<KtNamedDeclaration>()
|
||||||
|
.map { it.name ?: "<no name provided>" }
|
||||||
|
.toList()
|
||||||
|
.asReversed()
|
||||||
|
val packageSegments = containingKtFile.packageFqName.pathSegments()
|
||||||
|
return FqNameUnsafe((packageSegments + internalSegments).joinToString("."))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun KtTypeReference.renderShort(): String {
|
||||||
|
return accept(
|
||||||
|
object : KtVisitor<String, Unit>() {
|
||||||
|
private val visitor get() = this
|
||||||
|
|
||||||
|
override fun visitTypeReference(typeReference: KtTypeReference, data: Unit): String {
|
||||||
|
val typeText = typeReference.typeElement?.accept(this, data) ?: "???"
|
||||||
|
return if (typeReference.hasParentheses()) "($typeText)" else typeText
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitDynamicType(type: KtDynamicType, data: Unit) = type.text
|
||||||
|
|
||||||
|
override fun visitFunctionType(type: KtFunctionType, data: Unit): String {
|
||||||
|
return buildString {
|
||||||
|
type.receiverTypeReference?.let { append(it.accept(visitor, data)).append('.') }
|
||||||
|
type.parameters.joinTo(this, prefix = "(", postfix = ")") { it.accept(visitor, data) }
|
||||||
|
append(" -> ")
|
||||||
|
append(type.returnTypeReference?.accept(visitor, data) ?: "???")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitNullableType(nullableType: KtNullableType, data: Unit): String {
|
||||||
|
val innerTypeText = nullableType.innerType?.accept(this, data) ?: return "???"
|
||||||
|
return "$innerTypeText?"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitSelfType(type: KtSelfType, data: Unit) = type.text
|
||||||
|
|
||||||
|
override fun visitUserType(type: KtUserType, data: Unit): String {
|
||||||
|
return buildString {
|
||||||
|
append(type.referencedName ?: "???")
|
||||||
|
|
||||||
|
val arguments = type.typeArguments
|
||||||
|
if (arguments.isNotEmpty()) {
|
||||||
|
arguments.joinTo(this, prefix = "<", postfix = ">") {
|
||||||
|
it.typeReference?.accept(visitor, data) ?: it.text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitParameter(parameter: KtParameter, data: Unit) = parameter.typeReference?.accept(this, data) ?: "???"
|
||||||
|
},
|
||||||
|
Unit
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO Copied from stringUtil.kt
|
||||||
|
private fun String.collapseSpaces(): String {
|
||||||
|
val builder = StringBuilder()
|
||||||
|
var haveSpaces = false
|
||||||
|
for (c in this) {
|
||||||
|
if (c.isWhitespace()) {
|
||||||
|
haveSpaces = true
|
||||||
|
} else {
|
||||||
|
if (haveSpaces) {
|
||||||
|
builder.append(" ")
|
||||||
|
haveSpaces = false
|
||||||
|
}
|
||||||
|
builder.append(c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Implement in FIR
|
||||||
|
protected open val PsiElement.isRenameJavaSyntheticPropertyHandler get() = false
|
||||||
|
protected open val PsiElement.isRenameKotlinPropertyProcessor get() = false
|
||||||
|
|
||||||
|
override fun getElementDescription(element: PsiElement, location: ElementDescriptionLocation): String? {
|
||||||
|
val shouldUnwrap = location !is UsageViewShortNameLocation && location !is UsageViewLongNameLocation
|
||||||
|
val targetElement = if (shouldUnwrap) element.unwrapped ?: element else element
|
||||||
|
|
||||||
|
fun elementKind() = when (targetElement) {
|
||||||
|
is KtClass -> if (targetElement.isInterface())
|
||||||
|
KotlinBundleIndependent.message("find.usages.interface")
|
||||||
|
else
|
||||||
|
KotlinBundleIndependent.message("find.usages.class")
|
||||||
|
is KtObjectDeclaration -> if (targetElement.isCompanion())
|
||||||
|
KotlinBundleIndependent.message("find.usages.companion.object")
|
||||||
|
else
|
||||||
|
KotlinBundleIndependent.message("find.usages.object")
|
||||||
|
is KtNamedFunction -> KotlinBundleIndependent.message("find.usages.function")
|
||||||
|
is KtPropertyAccessor -> KotlinBundleIndependent.message(
|
||||||
|
"find.usages.for.property",
|
||||||
|
(if (targetElement.isGetter)
|
||||||
|
KotlinBundleIndependent.message("find.usages.getter")
|
||||||
|
else
|
||||||
|
KotlinBundleIndependent.message("find.usages.setter"))
|
||||||
|
) + " "
|
||||||
|
is KtFunctionLiteral -> KotlinBundleIndependent.message("find.usages.lambda")
|
||||||
|
is KtPrimaryConstructor, is KtSecondaryConstructor -> KotlinBundleIndependent.message("find.usages.constructor")
|
||||||
|
is KtProperty -> if (targetElement.isLocal)
|
||||||
|
KotlinBundleIndependent.message("find.usages.variable")
|
||||||
|
else
|
||||||
|
KotlinBundleIndependent.message("find.usages.property")
|
||||||
|
is KtTypeParameter -> KotlinBundleIndependent.message("find.usages.type.parameter")
|
||||||
|
is KtParameter -> KotlinBundleIndependent.message("find.usages.parameter")
|
||||||
|
is KtDestructuringDeclarationEntry -> KotlinBundleIndependent.message("find.usages.variable")
|
||||||
|
is KtTypeAlias -> KotlinBundleIndependent.message("find.usages.type.alias")
|
||||||
|
is KtLabeledExpression -> KotlinBundleIndependent.message("find.usages.label")
|
||||||
|
is KtImportAlias -> KotlinBundleIndependent.message("find.usages.import.alias")
|
||||||
|
is KtLightClassForFacade -> KotlinBundleIndependent.message("find.usages.facade.class")
|
||||||
|
else -> {
|
||||||
|
//TODO Implement in FIR
|
||||||
|
when {
|
||||||
|
targetElement.isRenameJavaSyntheticPropertyHandler -> KotlinBundleIndependent.message("find.usages.property")
|
||||||
|
targetElement.isRenameKotlinPropertyProcessor -> KotlinBundleIndependent.message("find.usages.property.accessor")
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val namedElement = if (targetElement is KtPropertyAccessor) {
|
||||||
|
targetElement.parent as? KtProperty
|
||||||
|
} else targetElement as? PsiNamedElement
|
||||||
|
|
||||||
|
@Suppress("FoldInitializerAndIfToElvis")
|
||||||
|
if (namedElement == null) {
|
||||||
|
return if (targetElement is KtElement) "'" + StringUtil.shortenTextWithEllipsis(
|
||||||
|
targetElement.text.collapseSpaces(),
|
||||||
|
53,
|
||||||
|
0
|
||||||
|
) + "'" else null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (namedElement.language != KotlinLanguage.INSTANCE) return null
|
||||||
|
|
||||||
|
return when (location) {
|
||||||
|
is UsageViewTypeLocation -> elementKind()
|
||||||
|
is UsageViewShortNameLocation, is UsageViewLongNameLocation -> namedElement.name
|
||||||
|
is RefactoringDescriptionLocation -> {
|
||||||
|
val kind = elementKind() ?: return null
|
||||||
|
if (namedElement !is KtNamedDeclaration) return null
|
||||||
|
val renderFqName = location.includeParent() &&
|
||||||
|
namedElement !is KtTypeParameter &&
|
||||||
|
namedElement !is KtParameter &&
|
||||||
|
namedElement !is KtConstructor<*>
|
||||||
|
val desc = when (namedElement) {
|
||||||
|
is KtFunction -> {
|
||||||
|
val baseText = buildString {
|
||||||
|
append(namedElement.name ?: "")
|
||||||
|
namedElement.valueParameters.joinTo(this, prefix = "(", postfix = ")") {
|
||||||
|
(if (it.isVarArg) "vararg " else "") + (it.typeReference?.renderShort() ?: "")
|
||||||
|
}
|
||||||
|
namedElement.receiverTypeReference?.let { append(" on ").append(it.renderShort()) }
|
||||||
|
}
|
||||||
|
val parentFqName = if (renderFqName) namedElement.fqName().parent() else null
|
||||||
|
if (parentFqName?.isRoot != false) baseText else "${parentFqName.asString()}.$baseText"
|
||||||
|
}
|
||||||
|
else -> (if (renderFqName) namedElement.fqName().asString() else namedElement.name) ?: ""
|
||||||
|
}
|
||||||
|
|
||||||
|
"$kind ${CommonRefactoringUtil.htmlEmphasize(desc)}"
|
||||||
|
}
|
||||||
|
is HighlightUsagesDescriptionLocation -> {
|
||||||
|
val kind = elementKind() ?: return null
|
||||||
|
if (namedElement !is KtNamedDeclaration) return null
|
||||||
|
"$kind ${namedElement.name}"
|
||||||
|
}
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
-7
@@ -27,15 +27,15 @@ import com.intellij.openapi.project.Project
|
|||||||
import com.intellij.openapi.ui.Messages
|
import com.intellij.openapi.ui.Messages
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.search.searches.OverridingMethodsSearch
|
import com.intellij.psi.search.searches.OverridingMethodsSearch
|
||||||
import org.jetbrains.kotlin.asJava.toLightMethods
|
import org.jetbrains.kotlin.idea.asJava.LightClassProvider.Companion.providedToLightMethods
|
||||||
import org.jetbrains.kotlin.asJava.unwrapped
|
import org.jetbrains.kotlin.asJava.unwrapped
|
||||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
import org.jetbrains.kotlin.idea.KotlinBundleIndependent
|
||||||
import org.jetbrains.kotlin.idea.core.isOverridable
|
import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesSupport.Companion.checkSuperMethods
|
||||||
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.isOverridable
|
||||||
import org.jetbrains.kotlin.idea.findUsages.handlers.DelegatingFindMemberUsagesHandler
|
import org.jetbrains.kotlin.idea.findUsages.handlers.DelegatingFindMemberUsagesHandler
|
||||||
import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinFindClassUsagesHandler
|
import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinFindClassUsagesHandler
|
||||||
import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinFindMemberUsagesHandler
|
import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinFindMemberUsagesHandler
|
||||||
import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinTypeParameterFindUsagesHandler
|
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.idea.references.mainReference
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementSelector
|
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementSelector
|
||||||
@@ -85,14 +85,14 @@ class KotlinFindUsagesHandlerFactory(project: Project) : FindUsagesHandlerFactor
|
|||||||
val declarationsToSearch = checkSuperMethods(
|
val declarationsToSearch = checkSuperMethods(
|
||||||
element,
|
element,
|
||||||
null,
|
null,
|
||||||
KotlinBundle.message("find.usages.action.text.find.usages.of")
|
KotlinBundleIndependent.message("find.usages.action.text.find.usages.of")
|
||||||
)
|
)
|
||||||
|
|
||||||
return handlerForMultiple(element, declarationsToSearch)
|
return handlerForMultiple(element, declarationsToSearch)
|
||||||
}
|
}
|
||||||
val function = element.ownerFunction
|
val function = element.ownerFunction
|
||||||
if (function != null && function.isOverridable()) {
|
if (function != null && function.isOverridable()) {
|
||||||
val psiMethod = function.toLightMethods().singleOrNull()
|
val psiMethod = function.providedToLightMethods().singleOrNull()
|
||||||
if (psiMethod != null) {
|
if (psiMethod != null) {
|
||||||
val hasOverridden = OverridingMethodsSearch.search(psiMethod).any()
|
val hasOverridden = OverridingMethodsSearch.search(psiMethod).any()
|
||||||
if (hasOverridden && askWhetherShouldSearchForParameterInOverridingMethods(element)) {
|
if (hasOverridden && askWhetherShouldSearchForParameterInOverridingMethods(element)) {
|
||||||
@@ -122,7 +122,7 @@ class KotlinFindUsagesHandlerFactory(project: Project) : FindUsagesHandlerFactor
|
|||||||
val declarationsToSearch = checkSuperMethods(
|
val declarationsToSearch = checkSuperMethods(
|
||||||
declaration,
|
declaration,
|
||||||
null,
|
null,
|
||||||
KotlinBundle.message("find.usages.action.text.find.usages.of")
|
KotlinBundleIndependent.message("find.usages.action.text.find.usages.of")
|
||||||
)
|
)
|
||||||
|
|
||||||
return handlerForMultiple(declaration, declarationsToSearch)
|
return handlerForMultiple(declaration, declarationsToSearch)
|
||||||
+81
@@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 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.findUsages
|
||||||
|
|
||||||
|
import com.intellij.lang.cacheBuilder.WordsScanner
|
||||||
|
import com.intellij.lang.findUsages.FindUsagesProvider
|
||||||
|
import com.intellij.lang.java.JavaFindUsagesProvider
|
||||||
|
import com.intellij.psi.*
|
||||||
|
import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinBundleIndependent
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.isPropertyParameter
|
||||||
|
|
||||||
|
open class KotlinFindUsagesProviderBase : FindUsagesProvider {
|
||||||
|
private val javaProvider by lazy { JavaFindUsagesProvider() }
|
||||||
|
|
||||||
|
override fun canFindUsagesFor(psiElement: PsiElement): Boolean =
|
||||||
|
psiElement is KtNamedDeclaration
|
||||||
|
|
||||||
|
override fun getWordsScanner(): WordsScanner? = KotlinWordsScanner()
|
||||||
|
|
||||||
|
override fun getHelpId(psiElement: PsiElement): String? = null
|
||||||
|
|
||||||
|
override fun getType(element: PsiElement): String {
|
||||||
|
return when (element) {
|
||||||
|
is KtNamedFunction -> KotlinBundleIndependent.message("find.usages.function")
|
||||||
|
is KtClass -> KotlinBundleIndependent.message("find.usages.class")
|
||||||
|
is KtParameter -> KotlinBundleIndependent.message("find.usages.parameter")
|
||||||
|
is KtProperty -> if (element.isLocal)
|
||||||
|
KotlinBundleIndependent.message("find.usages.variable")
|
||||||
|
else
|
||||||
|
KotlinBundleIndependent.message("find.usages.property")
|
||||||
|
is KtDestructuringDeclarationEntry -> KotlinBundleIndependent.message("find.usages.variable")
|
||||||
|
is KtTypeParameter -> KotlinBundleIndependent.message("find.usages.type.parameter")
|
||||||
|
is KtSecondaryConstructor -> KotlinBundleIndependent.message("find.usages.constructor")
|
||||||
|
is KtObjectDeclaration -> KotlinBundleIndependent.message("find.usages.object")
|
||||||
|
else -> ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected val KtDeclaration.containerDescription: String?
|
||||||
|
get() {
|
||||||
|
containingClassOrObject?.let { return getDescriptiveName(it) }
|
||||||
|
(parent as? KtFile)?.parent?.let { return getDescriptiveName(it) }
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getDescriptiveName(element: PsiElement): String {
|
||||||
|
return when (element) {
|
||||||
|
is PsiDirectory, is PsiPackage, is PsiFile -> javaProvider.getDescriptiveName(element)
|
||||||
|
is KtClassOrObject -> {
|
||||||
|
if (element is KtObjectDeclaration && element.isObjectLiteral()) return "<unnamed>"
|
||||||
|
element.fqName?.asString() ?: element.name ?: "<unnamed>"
|
||||||
|
}
|
||||||
|
is KtProperty -> (element.name ?: "") + (element.containerDescription?.let { " of $it" } ?: "")
|
||||||
|
is KtFunction -> {
|
||||||
|
//TODO: Correct FIR implementation
|
||||||
|
return element.name?.let { "$it(...)" } ?: ""
|
||||||
|
}
|
||||||
|
is KtLabeledExpression -> element.getLabelName() ?: ""
|
||||||
|
is KtImportAlias -> element.name ?: ""
|
||||||
|
is KtLightElement<*, *> -> element.kotlinOrigin?.let { getDescriptiveName(it) } ?: ""
|
||||||
|
is KtParameter -> {
|
||||||
|
if (element.isPropertyParameter()) {
|
||||||
|
(element.name ?: "") + (element.containerDescription?.let { " of $it" } ?: "")
|
||||||
|
} else {
|
||||||
|
element.name ?: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is PsiNamedElement -> element.name ?: ""
|
||||||
|
else -> ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getNodeText(element: PsiElement, useFullName: Boolean): String =
|
||||||
|
getDescriptiveName(element)
|
||||||
|
}
|
||||||
+65
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* 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.findUsages
|
||||||
|
|
||||||
|
import com.intellij.openapi.components.ServiceManager
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.PsiReference
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import org.jetbrains.annotations.Nls
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
|
||||||
|
interface KotlinFindUsagesSupport {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun getInstance(project: Project): KotlinFindUsagesSupport {
|
||||||
|
return ServiceManager.getService(project, KotlinFindUsagesSupport::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
val KtParameter.isDataClassComponentFunction: Boolean
|
||||||
|
get() = getInstance(project).isDataClassComponentFunction(this)
|
||||||
|
|
||||||
|
fun KtElement.isCallReceiverRefersToCompanionObject(companionObject: KtObjectDeclaration): Boolean =
|
||||||
|
getInstance(project).isCallReceiverRefersToCompanionObject(this, companionObject)
|
||||||
|
|
||||||
|
fun getTopMostOverriddenElementsToHighlight(target: PsiElement): List<PsiElement> =
|
||||||
|
getInstance(target.project).getTopMostOverriddenElementsToHighlight(target)
|
||||||
|
|
||||||
|
fun tryRenderDeclarationCompactStyle(declaration: KtDeclaration): String? =
|
||||||
|
getInstance(declaration.project).tryRenderDeclarationCompactStyle(declaration)
|
||||||
|
|
||||||
|
fun PsiReference.isConstructorUsage(ktClassOrObject: KtClassOrObject): Boolean =
|
||||||
|
getInstance(ktClassOrObject.project).isConstructorUsage(this, ktClassOrObject)
|
||||||
|
|
||||||
|
fun checkSuperMethods(
|
||||||
|
declaration: KtDeclaration,
|
||||||
|
ignore: Collection<PsiElement>?,
|
||||||
|
@Nls actionString: String
|
||||||
|
): List<PsiElement> = getInstance(declaration.project).checkSuperMethods(declaration, ignore, actionString)
|
||||||
|
|
||||||
|
fun sourcesAndLibraries(delegate: GlobalSearchScope, project: Project): GlobalSearchScope =
|
||||||
|
getInstance(project).sourcesAndLibraries(delegate, project)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isCallReceiverRefersToCompanionObject(element: KtElement, companionObject: KtObjectDeclaration): Boolean
|
||||||
|
|
||||||
|
fun isDataClassComponentFunction(element: KtParameter): Boolean
|
||||||
|
|
||||||
|
fun getTopMostOverriddenElementsToHighlight(target: PsiElement): List<PsiElement>
|
||||||
|
|
||||||
|
fun tryRenderDeclarationCompactStyle(declaration: KtDeclaration): String?
|
||||||
|
|
||||||
|
fun isConstructorUsage(psiReference: PsiReference, ktClassOrObject: KtClassOrObject): Boolean
|
||||||
|
|
||||||
|
fun checkSuperMethods(
|
||||||
|
declaration: KtDeclaration,
|
||||||
|
ignore: Collection<PsiElement>?,
|
||||||
|
@Nls actionString: String
|
||||||
|
): List<PsiElement>
|
||||||
|
|
||||||
|
fun sourcesAndLibraries(delegate: GlobalSearchScope, project: Project): GlobalSearchScope
|
||||||
|
}
|
||||||
+13
-15
@@ -31,19 +31,17 @@ import com.intellij.ui.SimpleColoredComponent;
|
|||||||
import com.intellij.ui.StateRestoringCheckBox;
|
import com.intellij.ui.StateRestoringCheckBox;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.LightClassProvider;
|
||||||
import org.jetbrains.kotlin.asJava.LightClassUtilsKt;
|
import org.jetbrains.kotlin.asJava.LightClassUtilsKt;
|
||||||
import org.jetbrains.kotlin.idea.KotlinBundle;
|
import org.jetbrains.kotlin.idea.KotlinBundleIndependent;
|
||||||
import org.jetbrains.kotlin.idea.core.PsiModificationUtilsKt;
|
|
||||||
import org.jetbrains.kotlin.idea.findUsages.KotlinClassFindUsagesOptions;
|
import org.jetbrains.kotlin.idea.findUsages.KotlinClassFindUsagesOptions;
|
||||||
import org.jetbrains.kotlin.idea.refactoring.RenderingUtilsKt;
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport;
|
||||||
import org.jetbrains.kotlin.psi.KtClass;
|
import org.jetbrains.kotlin.psi.KtClass;
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject;
|
import org.jetbrains.kotlin.psi.KtClassOrObject;
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
|
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.asJava.LightClassUtilsKt.toLightClass;
|
|
||||||
|
|
||||||
public class KotlinFindClassUsagesDialog extends FindClassUsagesDialog {
|
public class KotlinFindClassUsagesDialog extends FindClassUsagesDialog {
|
||||||
private StateRestoringCheckBox constructorUsages;
|
private StateRestoringCheckBox constructorUsages;
|
||||||
private StateRestoringCheckBox derivedClasses;
|
private StateRestoringCheckBox derivedClasses;
|
||||||
@@ -66,7 +64,7 @@ public class KotlinFindClassUsagesDialog extends FindClassUsagesDialog {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static PsiClass getRepresentingPsiClass(@NotNull KtClassOrObject classOrObject) {
|
private static PsiClass getRepresentingPsiClass(@NotNull KtClassOrObject classOrObject) {
|
||||||
PsiClass lightClass = toLightClass(classOrObject);
|
PsiClass lightClass = LightClassProvider.Companion.providedToLightClass(classOrObject);
|
||||||
if (lightClass != null) return lightClass;
|
if (lightClass != null) return lightClass;
|
||||||
|
|
||||||
// TODO: Remove this code when light classes are generated for builtins
|
// TODO: Remove this code when light classes are generated for builtins
|
||||||
@@ -74,7 +72,7 @@ public class KotlinFindClassUsagesDialog extends FindClassUsagesDialog {
|
|||||||
|
|
||||||
String name = classOrObject.getName();
|
String name = classOrObject.getName();
|
||||||
if (name == null || name.isEmpty()) {
|
if (name == null || name.isEmpty()) {
|
||||||
name = KotlinBundle.message("find.usages.class.name.anonymous");
|
name = KotlinBundleIndependent.message("find.usages.class.name.anonymous");
|
||||||
}
|
}
|
||||||
|
|
||||||
PsiClass javaClass;
|
PsiClass javaClass;
|
||||||
@@ -93,7 +91,7 @@ public class KotlinFindClassUsagesDialog extends FindClassUsagesDialog {
|
|||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
javaClass.getModifierList().setModifierProperty(
|
javaClass.getModifierList().setModifierProperty(
|
||||||
PsiModifier.FINAL,
|
PsiModifier.FINAL,
|
||||||
!(classOrObject instanceof KtClass && PsiModificationUtilsKt.isInheritable((KtClass) classOrObject))
|
!(classOrObject instanceof KtClass && KotlinSearchUsagesSupport.Companion.isInheritable((KtClass) classOrObject))
|
||||||
);
|
);
|
||||||
|
|
||||||
javaClass.putUserData(ORIGINAL_CLASS, classOrObject);
|
javaClass.putUserData(ORIGINAL_CLASS, classOrObject);
|
||||||
@@ -109,31 +107,31 @@ public class KotlinFindClassUsagesDialog extends FindClassUsagesDialog {
|
|||||||
Utils.renameCheckbox(
|
Utils.renameCheckbox(
|
||||||
findWhatPanel,
|
findWhatPanel,
|
||||||
FindBundle.message("find.what.methods.usages.checkbox"),
|
FindBundle.message("find.what.methods.usages.checkbox"),
|
||||||
KotlinBundle.message("find.declaration.functions.usages.checkbox")
|
KotlinBundleIndependent.message("find.declaration.functions.usages.checkbox")
|
||||||
);
|
);
|
||||||
Utils.renameCheckbox(
|
Utils.renameCheckbox(
|
||||||
findWhatPanel,
|
findWhatPanel,
|
||||||
FindBundle.message("find.what.fields.usages.checkbox"),
|
FindBundle.message("find.what.fields.usages.checkbox"),
|
||||||
KotlinBundle.message("find.declaration.properties.usages.checkbox")
|
KotlinBundleIndependent.message("find.declaration.properties.usages.checkbox")
|
||||||
);
|
);
|
||||||
Utils.removeCheckbox(findWhatPanel, FindBundle.message("find.what.implementing.classes.checkbox"));
|
Utils.removeCheckbox(findWhatPanel, FindBundle.message("find.what.implementing.classes.checkbox"));
|
||||||
Utils.removeCheckbox(findWhatPanel, FindBundle.message("find.what.derived.interfaces.checkbox"));
|
Utils.removeCheckbox(findWhatPanel, FindBundle.message("find.what.derived.interfaces.checkbox"));
|
||||||
Utils.removeCheckbox(findWhatPanel, FindBundle.message("find.what.derived.classes.checkbox"));
|
Utils.removeCheckbox(findWhatPanel, FindBundle.message("find.what.derived.classes.checkbox"));
|
||||||
|
|
||||||
derivedClasses = addCheckboxToPanel(
|
derivedClasses = addCheckboxToPanel(
|
||||||
KotlinBundle.message("find.declaration.derived.classes.checkbox"),
|
KotlinBundleIndependent.message("find.declaration.derived.classes.checkbox"),
|
||||||
getFindUsagesOptions().isDerivedClasses,
|
getFindUsagesOptions().isDerivedClasses,
|
||||||
findWhatPanel,
|
findWhatPanel,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
derivedTraits = addCheckboxToPanel(
|
derivedTraits = addCheckboxToPanel(
|
||||||
KotlinBundle.message("find.declaration.derived.interfaces.checkbox"),
|
KotlinBundleIndependent.message("find.declaration.derived.interfaces.checkbox"),
|
||||||
getFindUsagesOptions().isDerivedInterfaces,
|
getFindUsagesOptions().isDerivedInterfaces,
|
||||||
findWhatPanel,
|
findWhatPanel,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
constructorUsages = addCheckboxToPanel(
|
constructorUsages = addCheckboxToPanel(
|
||||||
KotlinBundle.message("find.declaration.constructor.usages.checkbox"),
|
KotlinBundleIndependent.message("find.declaration.constructor.usages.checkbox"),
|
||||||
getFindUsagesOptions().getSearchConstructorUsages(),
|
getFindUsagesOptions().getSearchConstructorUsages(),
|
||||||
findWhatPanel,
|
findWhatPanel,
|
||||||
true
|
true
|
||||||
@@ -165,7 +163,7 @@ public class KotlinFindClassUsagesDialog extends FindClassUsagesDialog {
|
|||||||
KotlinClassFindUsagesOptions options = getFindUsagesOptions();
|
KotlinClassFindUsagesOptions options = getFindUsagesOptions();
|
||||||
if (isActual) {
|
if (isActual) {
|
||||||
expectedUsages = addCheckboxToPanel(
|
expectedUsages = addCheckboxToPanel(
|
||||||
KotlinBundle.message("find.usages.checkbox.name.expected.classes"),
|
KotlinBundleIndependent.message("find.usages.checkbox.name.expected.classes"),
|
||||||
options.getSearchExpected(),
|
options.getSearchExpected(),
|
||||||
optionsPanel,
|
optionsPanel,
|
||||||
false
|
false
|
||||||
@@ -177,7 +175,7 @@ public class KotlinFindClassUsagesDialog extends FindClassUsagesDialog {
|
|||||||
public void configureLabelComponent(@NotNull SimpleColoredComponent coloredComponent) {
|
public void configureLabelComponent(@NotNull SimpleColoredComponent coloredComponent) {
|
||||||
KtClassOrObject originalClass = getOriginalClass();
|
KtClassOrObject originalClass = getOriginalClass();
|
||||||
if (originalClass != null) {
|
if (originalClass != null) {
|
||||||
coloredComponent.append(RenderingUtilsKt.formatClass(originalClass));
|
coloredComponent.append(KotlinSearchUsagesSupport.Companion.formatClass(originalClass));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+8
-8
@@ -29,9 +29,9 @@ import com.intellij.ui.StateRestoringCheckBox;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.kotlin.asJava.LightClassUtilsKt;
|
import org.jetbrains.kotlin.asJava.LightClassUtilsKt;
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod;
|
import org.jetbrains.kotlin.asJava.elements.KtLightMethod;
|
||||||
import org.jetbrains.kotlin.idea.KotlinBundle;
|
import org.jetbrains.kotlin.idea.KotlinBundleIndependent;
|
||||||
import org.jetbrains.kotlin.idea.findUsages.KotlinFunctionFindUsagesOptions;
|
import org.jetbrains.kotlin.idea.findUsages.KotlinFunctionFindUsagesOptions;
|
||||||
import org.jetbrains.kotlin.idea.refactoring.RenderingUtilsKt;
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport;
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration;
|
import org.jetbrains.kotlin.psi.KtDeclaration;
|
||||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration;
|
import org.jetbrains.kotlin.psi.KtNamedDeclaration;
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
|
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
|
||||||
@@ -61,7 +61,7 @@ public class KotlinFindFunctionUsagesDialog extends FindMethodUsagesDialog {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configureLabelComponent(@NotNull SimpleColoredComponent coloredComponent) {
|
public void configureLabelComponent(@NotNull SimpleColoredComponent coloredComponent) {
|
||||||
coloredComponent.append(RenderingUtilsKt.formatJavaOrLightMethod((PsiMethod) myPsiElement));
|
coloredComponent.append(KotlinSearchUsagesSupport.Companion.formatJavaOrLightMethod((PsiMethod) myPsiElement));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -72,12 +72,12 @@ public class KotlinFindFunctionUsagesDialog extends FindMethodUsagesDialog {
|
|||||||
Utils.renameCheckbox(
|
Utils.renameCheckbox(
|
||||||
findWhatPanel,
|
findWhatPanel,
|
||||||
FindBundle.message("find.what.implementing.methods.checkbox"),
|
FindBundle.message("find.what.implementing.methods.checkbox"),
|
||||||
KotlinBundle.message("find.declaration.implementing.methods.checkbox")
|
KotlinBundleIndependent.message("find.declaration.implementing.methods.checkbox")
|
||||||
);
|
);
|
||||||
Utils.renameCheckbox(
|
Utils.renameCheckbox(
|
||||||
findWhatPanel,
|
findWhatPanel,
|
||||||
FindBundle.message("find.what.overriding.methods.checkbox"),
|
FindBundle.message("find.what.overriding.methods.checkbox"),
|
||||||
KotlinBundle.message("find.declaration.overriding.methods.checkbox")
|
KotlinBundleIndependent.message("find.declaration.overriding.methods.checkbox")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,10 +91,10 @@ public class KotlinFindFunctionUsagesDialog extends FindMethodUsagesDialog {
|
|||||||
if (!Utils.renameCheckbox(
|
if (!Utils.renameCheckbox(
|
||||||
optionsPanel,
|
optionsPanel,
|
||||||
FindBundle.message("find.options.include.overloaded.methods.checkbox"),
|
FindBundle.message("find.options.include.overloaded.methods.checkbox"),
|
||||||
KotlinBundle.message("find.declaration.include.overloaded.methods.checkbox")
|
KotlinBundleIndependent.message("find.declaration.include.overloaded.methods.checkbox")
|
||||||
)) {
|
)) {
|
||||||
addCheckboxToPanel(
|
addCheckboxToPanel(
|
||||||
KotlinBundle.message("find.declaration.include.overloaded.methods.checkbox"),
|
KotlinBundleIndependent.message("find.declaration.include.overloaded.methods.checkbox"),
|
||||||
FindSettings.getInstance().isSearchOverloadedMethods(),
|
FindSettings.getInstance().isSearchOverloadedMethods(),
|
||||||
optionsPanel,
|
optionsPanel,
|
||||||
false
|
false
|
||||||
@@ -110,7 +110,7 @@ public class KotlinFindFunctionUsagesDialog extends FindMethodUsagesDialog {
|
|||||||
KotlinFunctionFindUsagesOptions options = getFindUsagesOptions();
|
KotlinFunctionFindUsagesOptions options = getFindUsagesOptions();
|
||||||
if (isActual) {
|
if (isActual) {
|
||||||
expectedUsages = addCheckboxToPanel(
|
expectedUsages = addCheckboxToPanel(
|
||||||
KotlinBundle.message("find.usages.checkbox.name.expected.functions"),
|
KotlinBundleIndependent.message("find.usages.checkbox.name.expected.functions"),
|
||||||
options.getSearchExpected(),
|
options.getSearchExpected(),
|
||||||
optionsPanel,
|
optionsPanel,
|
||||||
false
|
false
|
||||||
+8
-8
@@ -27,7 +27,7 @@ import com.intellij.ui.IdeBorderFactory;
|
|||||||
import com.intellij.ui.SimpleColoredComponent;
|
import com.intellij.ui.SimpleColoredComponent;
|
||||||
import com.intellij.ui.StateRestoringCheckBox;
|
import com.intellij.ui.StateRestoringCheckBox;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.kotlin.idea.KotlinBundle;
|
import org.jetbrains.kotlin.idea.KotlinBundleIndependent;
|
||||||
import org.jetbrains.kotlin.idea.findUsages.KotlinPropertyFindUsagesOptions;
|
import org.jetbrains.kotlin.idea.findUsages.KotlinPropertyFindUsagesOptions;
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
@@ -85,13 +85,13 @@ public class KotlinFindPropertyUsagesDialog extends JavaFindUsagesDialog<KotlinP
|
|||||||
KotlinPropertyFindUsagesOptions options = getFindUsagesOptions();
|
KotlinPropertyFindUsagesOptions options = getFindUsagesOptions();
|
||||||
|
|
||||||
readAccesses = addCheckboxToPanel(
|
readAccesses = addCheckboxToPanel(
|
||||||
KotlinBundle.message("find.declaration.property.readers.checkbox"),
|
KotlinBundleIndependent.message("find.declaration.property.readers.checkbox"),
|
||||||
options.isReadAccess,
|
options.isReadAccess,
|
||||||
findWhatPanel,
|
findWhatPanel,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
writeAccesses = addCheckboxToPanel(
|
writeAccesses = addCheckboxToPanel(
|
||||||
KotlinBundle.message("find.declaration.property.writers.checkbox"),
|
KotlinBundleIndependent.message("find.declaration.property.writers.checkbox"),
|
||||||
options.isWriteAccess,
|
options.isWriteAccess,
|
||||||
findWhatPanel,
|
findWhatPanel,
|
||||||
true
|
true
|
||||||
@@ -116,8 +116,8 @@ public class KotlinFindPropertyUsagesDialog extends JavaFindUsagesDialog<KotlinP
|
|||||||
if (isOpen || isAbstract) {
|
if (isOpen || isAbstract) {
|
||||||
overrideUsages = addCheckboxToPanel(
|
overrideUsages = addCheckboxToPanel(
|
||||||
isAbstract
|
isAbstract
|
||||||
? KotlinBundle.message("find.declaration.implementing.properties.checkbox")
|
? KotlinBundleIndependent.message("find.declaration.implementing.properties.checkbox")
|
||||||
: KotlinBundle.message("find.declaration.overriding.properties.checkbox"),
|
: KotlinBundleIndependent.message("find.declaration.overriding.properties.checkbox"),
|
||||||
FindSettings.getInstance().isSearchOverloadedMethods(),
|
FindSettings.getInstance().isSearchOverloadedMethods(),
|
||||||
optionsPanel,
|
optionsPanel,
|
||||||
false
|
false
|
||||||
@@ -127,7 +127,7 @@ public class KotlinFindPropertyUsagesDialog extends JavaFindUsagesDialog<KotlinP
|
|||||||
KotlinPropertyFindUsagesOptions options = getFindUsagesOptions();
|
KotlinPropertyFindUsagesOptions options = getFindUsagesOptions();
|
||||||
if (isActual) {
|
if (isActual) {
|
||||||
expectedUsages = addCheckboxToPanel(
|
expectedUsages = addCheckboxToPanel(
|
||||||
KotlinBundle.message("find.usages.checkbox.name.expected.properties"),
|
KotlinBundleIndependent.message("find.usages.checkbox.name.expected.properties"),
|
||||||
options.getSearchExpected(),
|
options.getSearchExpected(),
|
||||||
optionsPanel,
|
optionsPanel,
|
||||||
false
|
false
|
||||||
@@ -136,8 +136,8 @@ public class KotlinFindPropertyUsagesDialog extends JavaFindUsagesDialog<KotlinP
|
|||||||
|
|
||||||
if (isDataClassConstructorProperty(property)) {
|
if (isDataClassConstructorProperty(property)) {
|
||||||
JCheckBox dataClassComponentCheckBox =
|
JCheckBox dataClassComponentCheckBox =
|
||||||
new JCheckBox(KotlinBundle.message("find.usages.checkbox.text.fast.data.class.component.search"));
|
new JCheckBox(KotlinBundleIndependent.message("find.usages.checkbox.text.fast.data.class.component.search"));
|
||||||
dataClassComponentCheckBox.setToolTipText(KotlinBundle.message(
|
dataClassComponentCheckBox.setToolTipText(KotlinBundleIndependent.message(
|
||||||
"find.usages.tool.tip.text.disable.search.for.data.class.components.and.destruction.declarations.project.wide.setting"));
|
"find.usages.tool.tip.text.disable.search.for.data.class.components.and.destruction.declarations.project.wide.setting"));
|
||||||
Project project = property.getProject();
|
Project project = property.getProject();
|
||||||
dataClassComponentCheckBox.setSelected(getDisableComponentAndDestructionSearch(project));
|
dataClassComponentCheckBox.setSelected(getDisableComponentAndDestructionSearch(project));
|
||||||
+4
-6
@@ -18,10 +18,8 @@ package org.jetbrains.kotlin.idea.findUsages.dialogs;
|
|||||||
|
|
||||||
import com.intellij.ui.SimpleColoredComponent;
|
import com.intellij.ui.SimpleColoredComponent;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesSupport;
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.UtilsKt;
|
|
||||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration;
|
import org.jetbrains.kotlin.psi.KtNamedDeclaration;
|
||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
@@ -34,9 +32,9 @@ class Utils {
|
|||||||
@NotNull SimpleColoredComponent coloredComponent,
|
@NotNull SimpleColoredComponent coloredComponent,
|
||||||
@NotNull KtNamedDeclaration declaration
|
@NotNull KtNamedDeclaration declaration
|
||||||
) {
|
) {
|
||||||
DeclarationDescriptor descriptor = UtilsKt.getDescriptor(declaration);
|
String renderedDeclaration = KotlinFindUsagesSupport.Companion.tryRenderDeclarationCompactStyle(declaration);
|
||||||
if (descriptor != null) {
|
if (renderedDeclaration != null) {
|
||||||
coloredComponent.append(DescriptorRenderer.COMPACT.render(descriptor));
|
coloredComponent.append(renderedDeclaration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+4
-4
@@ -27,8 +27,8 @@ import com.intellij.psi.search.searches.ReferencesSearch
|
|||||||
import com.intellij.usageView.UsageInfo
|
import com.intellij.usageView.UsageInfo
|
||||||
import com.intellij.usages.UsageViewManager
|
import com.intellij.usages.UsageViewManager
|
||||||
import com.intellij.util.Query
|
import com.intellij.util.Query
|
||||||
import org.jetbrains.kotlin.asJava.toLightClass
|
import org.jetbrains.kotlin.idea.asJava.LightClassProvider.Companion.providedToLightClass
|
||||||
import org.jetbrains.kotlin.asJava.toLightElements
|
import org.jetbrains.kotlin.idea.asJava.LightClassProvider.Companion.providedToLightElements
|
||||||
import org.jetbrains.kotlin.idea.references.KtReference
|
import org.jetbrains.kotlin.idea.references.KtReference
|
||||||
import org.jetbrains.kotlin.psi.KtConstructor
|
import org.jetbrains.kotlin.psi.KtConstructor
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
@@ -44,9 +44,9 @@ fun KtDeclaration.processAllExactUsages(
|
|||||||
if (reference is KtReference) return listOf(this)
|
if (reference is KtReference) return listOf(this)
|
||||||
return SmartList<PsiElement>().also { list ->
|
return SmartList<PsiElement>().also { list ->
|
||||||
list += this
|
list += this
|
||||||
list += toLightElements()
|
list += providedToLightElements()
|
||||||
if (this is KtConstructor<*>) {
|
if (this is KtConstructor<*>) {
|
||||||
list.addIfNotNull(getContainingClassOrObject().toLightClass())
|
list.addIfNotNull(getContainingClassOrObject().providedToLightClass())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+9
-20
@@ -28,28 +28,24 @@ import com.intellij.psi.search.searches.MethodReferencesSearch
|
|||||||
import com.intellij.psi.search.searches.ReferencesSearch
|
import com.intellij.psi.search.searches.ReferencesSearch
|
||||||
import com.intellij.util.FilteredQuery
|
import com.intellij.util.FilteredQuery
|
||||||
import com.intellij.util.Processor
|
import com.intellij.util.Processor
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.LightClassProvider.Companion.providedToLightClass
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||||
import org.jetbrains.kotlin.asJava.toLightClass
|
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
|
||||||
import org.jetbrains.kotlin.idea.findUsages.KotlinClassFindUsagesOptions
|
import org.jetbrains.kotlin.idea.findUsages.KotlinClassFindUsagesOptions
|
||||||
import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory
|
import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory
|
||||||
|
import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesSupport.Companion.isCallReceiverRefersToCompanionObject
|
||||||
|
import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesSupport.Companion.isConstructorUsage
|
||||||
import org.jetbrains.kotlin.idea.findUsages.dialogs.KotlinFindClassUsagesDialog
|
import org.jetbrains.kotlin.idea.findUsages.dialogs.KotlinFindClassUsagesDialog
|
||||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest
|
import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest
|
||||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.searchInheritors
|
import org.jetbrains.kotlin.idea.search.declarationsSearch.searchInheritors
|
||||||
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions
|
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions
|
||||||
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchParameters
|
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchParameters
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
|
import org.jetbrains.kotlin.idea.search.isImportUsage
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.isConstructorUsage
|
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.isImportUsage
|
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
|
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.contains
|
import org.jetbrains.kotlin.psi.psiUtil.contains
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.effectiveDeclarations
|
import org.jetbrains.kotlin.psi.psiUtil.effectiveDeclarations
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class KotlinFindClassUsagesHandler(
|
class KotlinFindClassUsagesHandler(
|
||||||
@@ -97,7 +93,7 @@ class KotlinFindClassUsagesHandler(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (kotlinOptions.searchConstructorUsages) {
|
if (kotlinOptions.searchConstructorUsages) {
|
||||||
classOrObject.toLightClass()?.constructors?.filterIsInstance<KtLightMethod>()?.forEach { constructor ->
|
classOrObject.providedToLightClass()?.constructors?.filterIsInstance<KtLightMethod>()?.forEach { constructor ->
|
||||||
val scope = constructor.useScope.intersectWith(options.searchScope)
|
val scope = constructor.useScope.intersectWith(options.searchScope)
|
||||||
var query = MethodReferencesSearch.search(constructor, scope, true)
|
var query = MethodReferencesSearch.search(constructor, scope, true)
|
||||||
if (kotlinOptions.isSkipImportStatements) {
|
if (kotlinOptions.isSkipImportStatements) {
|
||||||
@@ -161,18 +157,11 @@ class KotlinFindClassUsagesHandler(
|
|||||||
|
|
||||||
private fun processCompanionObjectInternalReferences(companionObject: KtObjectDeclaration): Boolean {
|
private fun processCompanionObjectInternalReferences(companionObject: KtObjectDeclaration): Boolean {
|
||||||
val klass = companionObject.getStrictParentOfType<KtClass>() ?: return true
|
val klass = companionObject.getStrictParentOfType<KtClass>() ?: return true
|
||||||
val companionObjectDescriptor = companionObject.descriptor
|
|
||||||
return !klass.anyDescendantOfType(fun(element: KtElement): Boolean {
|
return !klass.anyDescendantOfType(fun(element: KtElement): Boolean {
|
||||||
if (element == companionObject) return false // skip companion object itself
|
if (element == companionObject) return false // skip companion object itself
|
||||||
|
return if (element.isCallReceiverRefersToCompanionObject(companionObject)) {
|
||||||
val bindingContext = element.analyze()
|
element.references.any { !referenceProcessor.process(it) }
|
||||||
val resolvedCall = bindingContext[BindingContext.CALL, element]?.getResolvedCall(bindingContext) ?: return false
|
} else false
|
||||||
if ((resolvedCall.dispatchReceiver as? ImplicitClassReceiver)?.declarationDescriptor == companionObjectDescriptor
|
|
||||||
|| (resolvedCall.extensionReceiver as? ImplicitClassReceiver)?.declarationDescriptor == companionObjectDescriptor
|
|
||||||
) {
|
|
||||||
return element.references.any { !referenceProcessor.process(it) }
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,7 +179,7 @@ class KotlinFindClassUsagesHandler(
|
|||||||
override fun getStringsToSearch(element: PsiElement): Collection<String> {
|
override fun getStringsToSearch(element: PsiElement): Collection<String> {
|
||||||
val psiClass = when (element) {
|
val psiClass = when (element) {
|
||||||
is PsiClass -> element
|
is PsiClass -> element
|
||||||
is KtClassOrObject -> getElement().toLightClass()
|
is KtClassOrObject -> getElement().providedToLightClass()
|
||||||
else -> null
|
else -> null
|
||||||
} ?: return Collections.emptyList()
|
} ?: return Collections.emptyList()
|
||||||
|
|
||||||
+14
-35
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
* 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.
|
||||||
* 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.findUsages.handlers
|
package org.jetbrains.kotlin.idea.findUsages.handlers
|
||||||
@@ -40,13 +29,12 @@ import com.intellij.psi.search.searches.MethodReferencesSearch
|
|||||||
import com.intellij.psi.search.searches.ReferencesSearch
|
import com.intellij.psi.search.searches.ReferencesSearch
|
||||||
import com.intellij.util.*
|
import com.intellij.util.*
|
||||||
import org.jetbrains.annotations.TestOnly
|
import org.jetbrains.annotations.TestOnly
|
||||||
import org.jetbrains.kotlin.asJava.toLightMethods
|
import org.jetbrains.kotlin.idea.asJava.LightClassProvider.Companion.providedToLightMethods
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.idea.KotlinBundleIndependent
|
||||||
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
|
||||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
|
||||||
import org.jetbrains.kotlin.idea.debugger.readAction
|
|
||||||
import org.jetbrains.kotlin.idea.findUsages.*
|
import org.jetbrains.kotlin.idea.findUsages.*
|
||||||
|
import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesSupport.Companion.getTopMostOverriddenElementsToHighlight
|
||||||
|
import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesSupport.Companion.isDataClassComponentFunction
|
||||||
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.filterDataClassComponentsIfDisabled
|
||||||
import org.jetbrains.kotlin.idea.findUsages.dialogs.KotlinFindFunctionUsagesDialog
|
import org.jetbrains.kotlin.idea.findUsages.dialogs.KotlinFindFunctionUsagesDialog
|
||||||
import org.jetbrains.kotlin.idea.findUsages.dialogs.KotlinFindPropertyUsagesDialog
|
import org.jetbrains.kotlin.idea.findUsages.dialogs.KotlinFindPropertyUsagesDialog
|
||||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest
|
import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest
|
||||||
@@ -55,14 +43,10 @@ import org.jetbrains.kotlin.idea.search.excludeKotlinSources
|
|||||||
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReadWriteAccessDetector
|
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReadWriteAccessDetector
|
||||||
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions
|
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions
|
||||||
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchParameters
|
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchParameters
|
||||||
|
import org.jetbrains.kotlin.idea.search.isImportUsage
|
||||||
import org.jetbrains.kotlin.idea.search.isOnlyKotlinSearch
|
import org.jetbrains.kotlin.idea.search.isOnlyKotlinSearch
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.dataClassComponentFunction
|
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.filterDataClassComponentsIfDisabled
|
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.isImportUsage
|
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.resolve.findOriginalTopMostOverriddenDescriptors
|
|
||||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
|
||||||
import javax.swing.event.HyperlinkEvent
|
import javax.swing.event.HyperlinkEvent
|
||||||
import javax.swing.event.HyperlinkListener
|
import javax.swing.event.HyperlinkListener
|
||||||
|
|
||||||
@@ -86,7 +70,7 @@ abstract class KotlinFindMemberUsagesHandler<T : KtNamedDeclaration> protected c
|
|||||||
mustOpenInNewTab: Boolean
|
mustOpenInNewTab: Boolean
|
||||||
): AbstractFindUsagesDialog {
|
): AbstractFindUsagesDialog {
|
||||||
val options = factory.findFunctionOptions
|
val options = factory.findFunctionOptions
|
||||||
val lightMethod = getElement().toLightMethods().firstOrNull()
|
val lightMethod = getElement().providedToLightMethods().firstOrNull()
|
||||||
if (lightMethod != null) {
|
if (lightMethod != null) {
|
||||||
return KotlinFindFunctionUsagesDialog(lightMethod, project, options, toShowInNewTab, mustOpenInNewTab, isSingleFile, this)
|
return KotlinFindFunctionUsagesDialog(lightMethod, project, options, toShowInNewTab, mustOpenInNewTab, isSingleFile, this)
|
||||||
}
|
}
|
||||||
@@ -134,7 +118,7 @@ abstract class KotlinFindMemberUsagesHandler<T : KtNamedDeclaration> protected c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val isPropertyOfDataClass = readAction {
|
private val isPropertyOfDataClass = runReadAction {
|
||||||
propertyDeclaration.parent is KtParameterList &&
|
propertyDeclaration.parent is KtParameterList &&
|
||||||
propertyDeclaration.parent.parent is KtPrimaryConstructor &&
|
propertyDeclaration.parent.parent is KtPrimaryConstructor &&
|
||||||
propertyDeclaration.parent.parent.parent.let { it is KtClass && it.isData() }
|
propertyDeclaration.parent.parent.parent.let { it is KtClass && it.isData() }
|
||||||
@@ -238,12 +222,12 @@ abstract class KotlinFindMemberUsagesHandler<T : KtNamedDeclaration> protected c
|
|||||||
if (element is KtElement && !isOnlyKotlinSearch(options.searchScope)) {
|
if (element is KtElement && !isOnlyKotlinSearch(options.searchScope)) {
|
||||||
// TODO: very bad code!! ReferencesSearch does not work correctly for constructors and annotation parameters
|
// TODO: very bad code!! ReferencesSearch does not work correctly for constructors and annotation parameters
|
||||||
val psiMethodScopeSearch = when {
|
val psiMethodScopeSearch = when {
|
||||||
element is KtParameter && element.dataClassComponentFunction() != null ->
|
element is KtParameter && element.isDataClassComponentFunction ->
|
||||||
options.searchScope.excludeKotlinSources()
|
options.searchScope.excludeKotlinSources()
|
||||||
else -> options.searchScope
|
else -> options.searchScope
|
||||||
}
|
}
|
||||||
|
|
||||||
for (psiMethod in element.toLightMethods().filterDataClassComponentsIfDisabled(kotlinSearchOptions)) {
|
for (psiMethod in element.providedToLightMethods().filterDataClassComponentsIfDisabled(kotlinSearchOptions)) {
|
||||||
addTask {
|
addTask {
|
||||||
applyQueryFilters(
|
applyQueryFilters(
|
||||||
element,
|
element,
|
||||||
@@ -284,13 +268,8 @@ abstract class KotlinFindMemberUsagesHandler<T : KtNamedDeclaration> protected c
|
|||||||
!isSingleFile && psiElement !is KtParameter
|
!isSingleFile && psiElement !is KtParameter
|
||||||
|
|
||||||
override fun findReferencesToHighlight(target: PsiElement, searchScope: SearchScope): Collection<PsiReference> {
|
override fun findReferencesToHighlight(target: PsiElement, searchScope: SearchScope): Collection<PsiReference> {
|
||||||
val callableDescriptor = (target as? KtCallableDeclaration)?.resolveToDescriptorIfAny() as? CallableDescriptor
|
|
||||||
val descriptorsToHighlight = if (callableDescriptor is ParameterDescriptor)
|
|
||||||
listOf(callableDescriptor)
|
|
||||||
else
|
|
||||||
callableDescriptor?.findOriginalTopMostOverriddenDescriptors() ?: emptyList()
|
|
||||||
|
|
||||||
val baseDeclarations = descriptorsToHighlight.map { it.source.getPsi() }.filter { it != null && it != target }
|
val baseDeclarations = getTopMostOverriddenElementsToHighlight(target)
|
||||||
|
|
||||||
return if (baseDeclarations.isNotEmpty()) {
|
return if (baseDeclarations.isNotEmpty()) {
|
||||||
baseDeclarations.flatMap {
|
baseDeclarations.flatMap {
|
||||||
@@ -311,7 +290,7 @@ abstract class KotlinFindMemberUsagesHandler<T : KtNamedDeclaration> protected c
|
|||||||
|
|
||||||
private const val DISABLE_ONCE = "DISABLE_ONCE"
|
private const val DISABLE_ONCE = "DISABLE_ONCE"
|
||||||
private const val DISABLE = "DISABLE"
|
private const val DISABLE = "DISABLE"
|
||||||
private val DISABLE_COMPONENT_AND_DESTRUCTION_SEARCH_TEXT = KotlinBundle.message(
|
private val DISABLE_COMPONENT_AND_DESTRUCTION_SEARCH_TEXT = KotlinBundleIndependent.message(
|
||||||
"find.usages.text.find.usages.for.data.class.components.and.destruction.declarations",
|
"find.usages.text.find.usages.for.data.class.components.and.destruction.declarations",
|
||||||
DISABLE_ONCE,
|
DISABLE_ONCE,
|
||||||
DISABLE
|
DISABLE
|
||||||
+1
-1
@@ -32,7 +32,7 @@ import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory
|
|||||||
import org.jetbrains.kotlin.idea.findUsages.KotlinReferencePreservingUsageInfo
|
import org.jetbrains.kotlin.idea.findUsages.KotlinReferencePreservingUsageInfo
|
||||||
import org.jetbrains.kotlin.idea.findUsages.KotlinReferenceUsageInfo
|
import org.jetbrains.kotlin.idea.findUsages.KotlinReferenceUsageInfo
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
import org.jetbrains.kotlin.idea.util.runReadActionInSmartMode
|
import org.jetbrains.kotlin.idea.util.application.runReadActionInSmartMode
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
abstract class KotlinFindUsagesHandler<T : PsiElement>(
|
abstract class KotlinFindUsagesHandler<T : PsiElement>(
|
||||||
+152
@@ -0,0 +1,152 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
import com.intellij.openapi.components.ServiceManager
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.psi.*
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import com.intellij.psi.search.SearchScope
|
||||||
|
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions
|
||||||
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.resolve.ImportPath
|
||||||
|
|
||||||
|
interface KotlinSearchUsagesSupport {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun getInstance(project: Project): KotlinSearchUsagesSupport {
|
||||||
|
return ServiceManager.getService(project, KotlinSearchUsagesSupport::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
val KtParameter.dataClassComponentMethodName: String?
|
||||||
|
get() = getInstance(project).dataClassComponentMethodName(this)
|
||||||
|
|
||||||
|
val KtExpression.hasType: Boolean
|
||||||
|
get() = getInstance(project).hasType(this)
|
||||||
|
|
||||||
|
val PsiClass.isSamInterface: Boolean
|
||||||
|
get() = getInstance(project).isSamInterface(this)
|
||||||
|
|
||||||
|
fun <T : PsiNamedElement> List<T>.filterDataClassComponentsIfDisabled(kotlinOptions: KotlinReferencesSearchOptions): List<T> =
|
||||||
|
firstOrNull()?.let {
|
||||||
|
getInstance(it.project).filterDataClassComponentsIfDisabled(this, kotlinOptions)
|
||||||
|
} ?: this
|
||||||
|
|
||||||
|
fun PsiReference.isCallableOverrideUsage(declaration: KtNamedDeclaration): Boolean =
|
||||||
|
getInstance(declaration.project).isCallableOverrideUsage(this, declaration)
|
||||||
|
|
||||||
|
fun PsiReference.isUsageInContainingDeclaration(declaration: KtNamedDeclaration): Boolean =
|
||||||
|
getInstance(declaration.project).isUsageInContainingDeclaration(this, declaration)
|
||||||
|
|
||||||
|
fun PsiReference.isExtensionOfDeclarationClassUsage(declaration: KtNamedDeclaration): Boolean =
|
||||||
|
getInstance(declaration.project).isExtensionOfDeclarationClassUsage(this, declaration)
|
||||||
|
|
||||||
|
fun PsiElement.getReceiverTypeSearcherInfo(isDestructionDeclarationSearch: Boolean): ReceiverTypeSearcherInfo? =
|
||||||
|
getInstance(project).getReceiverTypeSearcherInfo(this, isDestructionDeclarationSearch)
|
||||||
|
|
||||||
|
fun KtFile.forceResolveReferences(elements: List<KtElement>) =
|
||||||
|
getInstance(project).forceResolveReferences(this, elements)
|
||||||
|
|
||||||
|
fun PsiFile.scriptDefinitionExists(): Boolean =
|
||||||
|
getInstance(project).scriptDefinitionExists(this)
|
||||||
|
|
||||||
|
fun KtFile.getDefaultImports(): List<ImportPath> =
|
||||||
|
getInstance(project).getDefaultImports(this)
|
||||||
|
|
||||||
|
fun forEachKotlinOverride(
|
||||||
|
ktClass: KtClass,
|
||||||
|
members: List<KtNamedDeclaration>,
|
||||||
|
scope: SearchScope,
|
||||||
|
processor: (superMember: PsiElement, overridingMember: PsiElement) -> Boolean
|
||||||
|
): Boolean = getInstance(ktClass.project).forEachKotlinOverride(ktClass, members, scope, processor)
|
||||||
|
|
||||||
|
fun PsiMethod.forEachOverridingMethod(
|
||||||
|
scope: SearchScope = runReadAction { useScope },
|
||||||
|
processor: (PsiMethod) -> Boolean
|
||||||
|
): Boolean = getInstance(project).forEachOverridingMethod(this, scope, processor)
|
||||||
|
|
||||||
|
fun findDeepestSuperMethodsNoWrapping(method: PsiElement): List<PsiElement> =
|
||||||
|
getInstance(method.project).findDeepestSuperMethodsNoWrapping(method)
|
||||||
|
|
||||||
|
fun findTypeAliasByShortName(shortName: String, project: Project, scope: GlobalSearchScope): Collection<KtTypeAlias> =
|
||||||
|
getInstance(project).findTypeAliasByShortName(shortName, project, scope)
|
||||||
|
|
||||||
|
fun isInProjectSource(element: PsiElement, includeScriptsOutsideSourceRoots: Boolean = false): Boolean =
|
||||||
|
getInstance(element.project).isInProjectSource(element, includeScriptsOutsideSourceRoots)
|
||||||
|
|
||||||
|
fun KtDeclaration.isOverridable(): Boolean =
|
||||||
|
getInstance(project).isOverridable(this)
|
||||||
|
|
||||||
|
fun KtClass.isInheritable(): Boolean =
|
||||||
|
getInstance(project).isInheritable(this)
|
||||||
|
|
||||||
|
fun formatJavaOrLightMethod(method: PsiMethod): String =
|
||||||
|
getInstance(method.project).formatJavaOrLightMethod(method)
|
||||||
|
|
||||||
|
fun formatClass(classOrObject: KtClassOrObject): String =
|
||||||
|
getInstance(classOrObject.project).formatClass(classOrObject)
|
||||||
|
|
||||||
|
fun KtDeclaration.expectedDeclarationIfAny(): KtDeclaration? =
|
||||||
|
getInstance(project).expectedDeclarationIfAny(this)
|
||||||
|
|
||||||
|
fun KtDeclaration.isExpectDeclaration(): Boolean =
|
||||||
|
getInstance(project).isExpectDeclaration(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun dataClassComponentMethodName(element: KtParameter): String?
|
||||||
|
|
||||||
|
fun hasType(element: KtExpression): Boolean
|
||||||
|
|
||||||
|
fun isSamInterface(psiClass: PsiClass): Boolean
|
||||||
|
|
||||||
|
fun <T : PsiNamedElement> filterDataClassComponentsIfDisabled(elements: List<T>, kotlinOptions: KotlinReferencesSearchOptions): List<T>
|
||||||
|
|
||||||
|
fun isCallableOverrideUsage(reference: PsiReference, declaration: KtNamedDeclaration): Boolean
|
||||||
|
|
||||||
|
fun isUsageInContainingDeclaration(reference: PsiReference, declaration: KtNamedDeclaration): Boolean
|
||||||
|
|
||||||
|
fun isExtensionOfDeclarationClassUsage(reference: PsiReference, declaration: KtNamedDeclaration): Boolean
|
||||||
|
|
||||||
|
fun getReceiverTypeSearcherInfo(psiElement: PsiElement, isDestructionDeclarationSearch: Boolean): ReceiverTypeSearcherInfo?
|
||||||
|
|
||||||
|
fun forceResolveReferences(file: KtFile, elements: List<KtElement>)
|
||||||
|
|
||||||
|
fun scriptDefinitionExists(file: PsiFile): Boolean
|
||||||
|
|
||||||
|
fun getDefaultImports(file: KtFile): List<ImportPath>
|
||||||
|
|
||||||
|
fun forEachKotlinOverride(
|
||||||
|
ktClass: KtClass,
|
||||||
|
members: List<KtNamedDeclaration>,
|
||||||
|
scope: SearchScope,
|
||||||
|
processor: (superMember: PsiElement, overridingMember: PsiElement) -> Boolean
|
||||||
|
): Boolean
|
||||||
|
|
||||||
|
fun forEachOverridingMethod(
|
||||||
|
method: PsiMethod,
|
||||||
|
scope: SearchScope,
|
||||||
|
processor: (PsiMethod) -> Boolean
|
||||||
|
): Boolean
|
||||||
|
|
||||||
|
fun findDeepestSuperMethodsNoWrapping(method: PsiElement): List<PsiElement>
|
||||||
|
|
||||||
|
fun findTypeAliasByShortName(shortName: String, project: Project, scope: GlobalSearchScope): Collection<KtTypeAlias>
|
||||||
|
|
||||||
|
fun isInProjectSource(element: PsiElement, includeScriptsOutsideSourceRoots: Boolean = false): Boolean
|
||||||
|
|
||||||
|
fun isOverridable(declaration: KtDeclaration): Boolean
|
||||||
|
|
||||||
|
fun isInheritable(ktClass: KtClass): Boolean
|
||||||
|
|
||||||
|
fun formatJavaOrLightMethod(method: PsiMethod): String
|
||||||
|
|
||||||
|
fun formatClass(classOrObject: KtClassOrObject): String
|
||||||
|
|
||||||
|
fun expectedDeclarationIfAny(declaration: KtDeclaration): KtDeclaration?
|
||||||
|
|
||||||
|
fun isExpectDeclaration(declaration: KtDeclaration): Boolean
|
||||||
|
}
|
||||||
+5
-16
@@ -15,19 +15,15 @@ import com.intellij.psi.util.CachedValuesManager
|
|||||||
import org.jetbrains.annotations.TestOnly
|
import org.jetbrains.annotations.TestOnly
|
||||||
import org.jetbrains.kotlin.asJava.ImpreciseResolveResult
|
import org.jetbrains.kotlin.asJava.ImpreciseResolveResult
|
||||||
import org.jetbrains.kotlin.asJava.ImpreciseResolveResult.*
|
import org.jetbrains.kotlin.asJava.ImpreciseResolveResult.*
|
||||||
import org.jetbrains.kotlin.idea.caches.project.getNullableModuleInfo
|
|
||||||
import org.jetbrains.kotlin.idea.caches.trackers.KotlinCodeBlockModificationListener
|
import org.jetbrains.kotlin.idea.caches.trackers.KotlinCodeBlockModificationListener
|
||||||
import org.jetbrains.kotlin.idea.compiler.IDELanguageSettingsProvider
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.findTypeAliasByShortName
|
||||||
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.getDefaultImports
|
||||||
import org.jetbrains.kotlin.idea.project.findAnalyzerServices
|
|
||||||
import org.jetbrains.kotlin.idea.stubindex.KotlinTypeAliasShortNameIndex
|
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch
|
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
import org.jetbrains.kotlin.resolve.ImportPath
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -35,6 +31,7 @@ import java.util.concurrent.atomic.AtomicInteger
|
|||||||
* with the given qualified name.
|
* with the given qualified name.
|
||||||
*/
|
*/
|
||||||
class PsiBasedClassResolver @TestOnly constructor(private val targetClassFqName: String) {
|
class PsiBasedClassResolver @TestOnly constructor(private val targetClassFqName: String) {
|
||||||
|
|
||||||
private val targetShortName = targetClassFqName.substringAfterLast('.')
|
private val targetShortName = targetClassFqName.substringAfterLast('.')
|
||||||
private val targetPackage = targetClassFqName.substringBeforeLast('.', "")
|
private val targetPackage = targetClassFqName.substringBeforeLast('.', "")
|
||||||
|
|
||||||
@@ -125,7 +122,7 @@ class PsiBasedClassResolver @TestOnly constructor(private val targetClassFqName:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun findPotentialTypeAliasConflicts(target: PsiClass) {
|
private fun findPotentialTypeAliasConflicts(target: PsiClass) {
|
||||||
val candidates = KotlinTypeAliasShortNameIndex.getInstance().get(targetShortName, target.project, target.project.allScope())
|
val candidates = findTypeAliasByShortName(targetShortName, target.project, target.project.allScope())
|
||||||
for (candidate in candidates) {
|
for (candidate in candidates) {
|
||||||
packagesWithTypeAliases.add(candidate.containingKtFile.packageFqName.asString())
|
packagesWithTypeAliases.add(candidate.containingKtFile.packageFqName.asString())
|
||||||
}
|
}
|
||||||
@@ -244,12 +241,4 @@ class PsiBasedClassResolver @TestOnly constructor(private val targetClassFqName:
|
|||||||
}
|
}
|
||||||
return Result.Ambiguity
|
return Result.Ambiguity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KtFile.getDefaultImports(): List<ImportPath> {
|
|
||||||
val moduleInfo = getNullableModuleInfo() ?: return emptyList()
|
|
||||||
return TargetPlatformDetector.getPlatform(this).findAnalyzerServices(project).getDefaultImports(
|
|
||||||
IDELanguageSettingsProvider.getLanguageVersionSettings(moduleInfo, project),
|
|
||||||
includeLowPriorityImports = true
|
|
||||||
)
|
|
||||||
}
|
|
||||||
+3
-3
@@ -22,14 +22,14 @@ import com.intellij.psi.PsiModifier
|
|||||||
import com.intellij.psi.search.searches.ClassInheritorsSearch
|
import com.intellij.psi.search.searches.ClassInheritorsSearch
|
||||||
import com.intellij.util.EmptyQuery
|
import com.intellij.util.EmptyQuery
|
||||||
import com.intellij.util.Query
|
import com.intellij.util.Query
|
||||||
import org.jetbrains.kotlin.asJava.toLightClassWithBuiltinMapping
|
import org.jetbrains.kotlin.idea.asJava.LightClassProvider.Companion.providedCreateKtFakeLightClass
|
||||||
import org.jetbrains.kotlin.idea.caches.lightClasses.KtFakeLightClass
|
import org.jetbrains.kotlin.idea.asJava.LightClassProvider.Companion.providedToLightClassWithBuiltinMapping
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
|
|
||||||
fun HierarchySearchRequest<*>.searchInheritors(): Query<PsiClass> {
|
fun HierarchySearchRequest<*>.searchInheritors(): Query<PsiClass> {
|
||||||
val psiClass: PsiClass = when (originalElement) {
|
val psiClass: PsiClass = when (originalElement) {
|
||||||
is KtClassOrObject -> runReadAction { originalElement.toLightClassWithBuiltinMapping() ?: KtFakeLightClass(originalElement) }
|
is KtClassOrObject -> runReadAction { originalElement.providedToLightClassWithBuiltinMapping() ?: providedCreateKtFakeLightClass(originalElement) }
|
||||||
is PsiClass -> originalElement
|
is PsiClass -> originalElement
|
||||||
else -> null
|
else -> null
|
||||||
} ?: return EmptyQuery.getEmptyQuery()
|
} ?: return EmptyQuery.getEmptyQuery()
|
||||||
+15
-86
@@ -18,27 +18,20 @@ import com.intellij.util.EmptyQuery
|
|||||||
import com.intellij.util.MergeQuery
|
import com.intellij.util.MergeQuery
|
||||||
import com.intellij.util.Processor
|
import com.intellij.util.Processor
|
||||||
import com.intellij.util.Query
|
import com.intellij.util.Query
|
||||||
import org.jetbrains.kotlin.asJava.getRepresentativeLightMethod
|
import org.jetbrains.kotlin.asJava.*
|
||||||
import org.jetbrains.kotlin.asJava.toLightMethods
|
import org.jetbrains.kotlin.idea.asJava.LightClassProvider.Companion.providedCreateKtFakeLightMethod
|
||||||
import org.jetbrains.kotlin.asJava.unwrapped
|
import org.jetbrains.kotlin.idea.asJava.LightClassProvider.Companion.providedGetRepresentativeLightMethod
|
||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
import org.jetbrains.kotlin.idea.asJava.LightClassProvider.Companion.providedIsKtFakeLightClass
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.idea.asJava.LightClassProvider.Companion.providedToLightMethods
|
||||||
import org.jetbrains.kotlin.descriptors.isOverridable
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.findDeepestSuperMethodsNoWrapping
|
||||||
import org.jetbrains.kotlin.idea.caches.lightClasses.KtFakeLightClass
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.forEachKotlinOverride
|
||||||
import org.jetbrains.kotlin.idea.caches.lightClasses.KtFakeLightMethod
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.forEachOverridingMethod
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.isOverridable
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
|
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
|
||||||
import org.jetbrains.kotlin.idea.core.getDeepestSuperDeclarations
|
|
||||||
import org.jetbrains.kotlin.idea.core.isOverridable
|
|
||||||
import org.jetbrains.kotlin.idea.search.allScope
|
import org.jetbrains.kotlin.idea.search.allScope
|
||||||
import org.jetbrains.kotlin.idea.search.excludeKotlinSources
|
import org.jetbrains.kotlin.idea.search.excludeKotlinSources
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
|
||||||
import org.jetbrains.kotlin.types.substitutions.getTypeSubstitutor
|
|
||||||
import org.jetbrains.kotlin.util.findCallableMemberBySignature
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
fun PsiElement.isOverridableElement(): Boolean = when (this) {
|
fun PsiElement.isOverridableElement(): Boolean = when (this) {
|
||||||
@@ -48,7 +41,7 @@ fun PsiElement.isOverridableElement(): Boolean = when (this) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun HierarchySearchRequest<*>.searchOverriders(): Query<PsiMethod> {
|
fun HierarchySearchRequest<*>.searchOverriders(): Query<PsiMethod> {
|
||||||
val psiMethods = runReadAction { originalElement.toLightMethods() }
|
val psiMethods = runReadAction { originalElement.providedToLightMethods() }
|
||||||
if (psiMethods.isEmpty()) return EmptyQuery.getEmptyQuery()
|
if (psiMethods.isEmpty()) return EmptyQuery.getEmptyQuery()
|
||||||
|
|
||||||
return psiMethods
|
return psiMethods
|
||||||
@@ -111,44 +104,10 @@ fun PsiElement.toPossiblyFakeLightMethods(): List<PsiMethod> {
|
|||||||
|
|
||||||
val element = unwrapped ?: return emptyList()
|
val element = unwrapped ?: return emptyList()
|
||||||
|
|
||||||
val lightMethods = element.toLightMethods()
|
val lightMethods = element.providedToLightMethods()
|
||||||
if (lightMethods.isNotEmpty()) return lightMethods
|
if (lightMethods.isNotEmpty()) return lightMethods
|
||||||
|
|
||||||
return if (element is KtNamedDeclaration) listOfNotNull(KtFakeLightMethod.get(element)) else emptyList()
|
return if (element is KtNamedDeclaration) listOfNotNull(providedCreateKtFakeLightMethod(element)) else emptyList()
|
||||||
}
|
|
||||||
|
|
||||||
private fun forEachKotlinOverride(
|
|
||||||
ktClass: KtClass,
|
|
||||||
members: List<KtNamedDeclaration>,
|
|
||||||
scope: SearchScope,
|
|
||||||
processor: (superMember: PsiElement, overridingMember: PsiElement) -> Boolean
|
|
||||||
): Boolean {
|
|
||||||
val baseClassDescriptor = runReadAction { ktClass.unsafeResolveToDescriptor() as ClassDescriptor }
|
|
||||||
val baseDescriptors =
|
|
||||||
runReadAction { members.mapNotNull { it.unsafeResolveToDescriptor() as? CallableMemberDescriptor }.filter { it.isOverridable } }
|
|
||||||
if (baseDescriptors.isEmpty()) return true
|
|
||||||
|
|
||||||
HierarchySearchRequest(ktClass, scope, true).searchInheritors().forEach(Processor { psiClass ->
|
|
||||||
val inheritor = psiClass.unwrapped as? KtClassOrObject ?: return@Processor true
|
|
||||||
runReadAction {
|
|
||||||
val inheritorDescriptor = inheritor.unsafeResolveToDescriptor() as ClassDescriptor
|
|
||||||
val substitutor =
|
|
||||||
getTypeSubstitutor(baseClassDescriptor.defaultType, inheritorDescriptor.defaultType) ?: return@runReadAction true
|
|
||||||
baseDescriptors.forEach {
|
|
||||||
val superMember = it.source.getPsi()!!
|
|
||||||
val overridingDescriptor = (it.substitute(substitutor) as? CallableMemberDescriptor)?.let { memberDescriptor ->
|
|
||||||
inheritorDescriptor.findCallableMemberBySignature(memberDescriptor)
|
|
||||||
}
|
|
||||||
val overridingMember = overridingDescriptor?.source?.getPsi()
|
|
||||||
if (overridingMember != null) {
|
|
||||||
if (!processor(superMember, overridingMember)) return@runReadAction false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun KtNamedDeclaration.forEachOverridingElement(
|
fun KtNamedDeclaration.forEachOverridingElement(
|
||||||
@@ -157,29 +116,13 @@ fun KtNamedDeclaration.forEachOverridingElement(
|
|||||||
): Boolean {
|
): Boolean {
|
||||||
val ktClass = runReadAction { containingClassOrObject as? KtClass } ?: return true
|
val ktClass = runReadAction { containingClassOrObject as? KtClass } ?: return true
|
||||||
|
|
||||||
toLightMethods().forEach { baseMethod ->
|
providedToLightMethods().forEach { baseMethod ->
|
||||||
if (!OverridingMethodsSearch.search(baseMethod, scope.excludeKotlinSources(), true).all { processor(baseMethod, it) }) return false
|
if (!OverridingMethodsSearch.search(baseMethod, scope.excludeKotlinSources(), true).all { processor(baseMethod, it) }) return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return forEachKotlinOverride(ktClass, listOf(this), scope) { baseElement, overrider -> processor(baseElement, overrider) }
|
return forEachKotlinOverride(ktClass, listOf(this), scope) { baseElement, overrider -> processor(baseElement, overrider) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun PsiMethod.forEachOverridingMethod(
|
|
||||||
scope: SearchScope = runReadAction { useScope },
|
|
||||||
processor: (PsiMethod) -> Boolean
|
|
||||||
): Boolean {
|
|
||||||
if (this !is KtFakeLightMethod) {
|
|
||||||
if (!OverridingMethodsSearch.search(this, scope.excludeKotlinSources(), true).forEach(processor)) return false
|
|
||||||
}
|
|
||||||
|
|
||||||
val ktMember = this.unwrapped as? KtNamedDeclaration ?: return true
|
|
||||||
val ktClass = runReadAction { ktMember.containingClassOrObject as? KtClass } ?: return true
|
|
||||||
return forEachKotlinOverride(ktClass, listOf(ktMember), scope) { _, overrider ->
|
|
||||||
val lightMethods = runReadAction { overrider.toPossiblyFakeLightMethods().distinctBy { it.unwrapped } }
|
|
||||||
lightMethods.all { processor(it) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun PsiMethod.forEachImplementation(
|
fun PsiMethod.forEachImplementation(
|
||||||
scope: SearchScope = runReadAction { useScope },
|
scope: SearchScope = runReadAction { useScope },
|
||||||
processor: (PsiElement) -> Boolean
|
processor: (PsiElement) -> Boolean
|
||||||
@@ -191,7 +134,7 @@ fun PsiMethod.forEachImplementation(
|
|||||||
fun PsiClass.forEachDeclaredMemberOverride(processor: (superMember: PsiElement, overridingMember: PsiElement) -> Boolean) {
|
fun PsiClass.forEachDeclaredMemberOverride(processor: (superMember: PsiElement, overridingMember: PsiElement) -> Boolean) {
|
||||||
val scope = runReadAction { useScope }
|
val scope = runReadAction { useScope }
|
||||||
|
|
||||||
if (this !is KtFakeLightClass) {
|
if (!providedIsKtFakeLightClass()) {
|
||||||
AllOverridingMethodsSearch.search(this, scope.excludeKotlinSources()).all { processor(it.first, it.second) }
|
AllOverridingMethodsSearch.search(this, scope.excludeKotlinSources()).all { processor(it.first, it.second) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,19 +144,5 @@ fun PsiClass.forEachDeclaredMemberOverride(processor: (superMember: PsiElement,
|
|||||||
forEachKotlinOverride(ktClass, members, scope, processor)
|
forEachKotlinOverride(ktClass, members, scope, processor)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findDeepestSuperMethodsNoWrapping(method: PsiElement): List<PsiElement> {
|
|
||||||
val element = method.unwrapped
|
|
||||||
return when (element) {
|
|
||||||
is PsiMethod -> element.findDeepestSuperMethods().toList()
|
|
||||||
is KtCallableDeclaration -> {
|
|
||||||
val descriptor = element.resolveToDescriptorIfAny() as? CallableMemberDescriptor ?: return emptyList()
|
|
||||||
descriptor.getDeepestSuperDeclarations(false).mapNotNull {
|
|
||||||
it.source.getPsi() ?: DescriptorToSourceUtilsIde.getAnyDeclaration(element.project, it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> emptyList()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun findDeepestSuperMethodsKotlinAware(method: PsiElement) =
|
fun findDeepestSuperMethodsKotlinAware(method: PsiElement) =
|
||||||
findDeepestSuperMethodsNoWrapping(method).mapNotNull { it.getRepresentativeLightMethod() }
|
findDeepestSuperMethodsNoWrapping(method).mapNotNull { it.providedGetRepresentativeLightMethod() }
|
||||||
+58
-45
@@ -25,33 +25,31 @@ import com.intellij.psi.search.searches.MethodReferencesSearch
|
|||||||
import com.intellij.psi.search.searches.ReferencesSearch
|
import com.intellij.psi.search.searches.ReferencesSearch
|
||||||
import com.intellij.util.Processor
|
import com.intellij.util.Processor
|
||||||
import com.intellij.util.containers.nullize
|
import com.intellij.util.containers.nullize
|
||||||
import org.jetbrains.kotlin.asJava.LightClassUtil
|
import org.jetbrains.kotlin.idea.asJava.LightClassProvider.Companion.providedGetLightClassMethods
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.LightClassProvider.Companion.providedGetLightClassParameterDeclarations
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.LightClassProvider.Companion.providedGetLightClassPropertyDeclarations
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.LightClassProvider.Companion.providedGetLightFieldForCompanionObject
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.LightClassProvider.Companion.providedToLightClass
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.LightClassProvider.Companion.providedToLightElements
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightField
|
import org.jetbrains.kotlin.asJava.elements.KtLightField
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightMember
|
import org.jetbrains.kotlin.asJava.elements.KtLightMember
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightParameter
|
import org.jetbrains.kotlin.asJava.elements.KtLightParameter
|
||||||
import org.jetbrains.kotlin.asJava.namedUnwrappedElement
|
import org.jetbrains.kotlin.asJava.namedUnwrappedElement
|
||||||
import org.jetbrains.kotlin.asJava.toLightClass
|
import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesSupport.Companion.sourcesAndLibraries
|
||||||
import org.jetbrains.kotlin.asJava.toLightElements
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.dataClassComponentMethodName
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.expectedDeclarationIfAny
|
||||||
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.filterDataClassComponentsIfDisabled
|
||||||
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.isExpectDeclaration
|
||||||
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
||||||
import org.jetbrains.kotlin.idea.references.mainReference
|
import org.jetbrains.kotlin.idea.references.mainReference
|
||||||
import org.jetbrains.kotlin.idea.search.*
|
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.Empty
|
||||||
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions.Companion.calculateEffectiveScope
|
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
|
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.operators.OperatorReferenceSearcher
|
import org.jetbrains.kotlin.idea.search.usagesSearch.operators.OperatorReferenceSearcher
|
||||||
import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope
|
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
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.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementSelector
|
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.parents
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
data class KotlinReferencesSearchOptions(
|
data class KotlinReferencesSearchOptions(
|
||||||
@@ -76,7 +74,7 @@ data class KotlinReferencesSearchOptions(
|
|||||||
): SearchScope {
|
): SearchScope {
|
||||||
val kotlinOptions = (parameters as? KotlinAwareReferencesSearchParameters)?.kotlinOptions ?: Empty
|
val kotlinOptions = (parameters as? KotlinAwareReferencesSearchParameters)?.kotlinOptions ?: Empty
|
||||||
val elements = if (elementToSearch is KtDeclaration && !isOnlyKotlinSearch(parameters.scopeDeterminedByUser)) {
|
val elements = if (elementToSearch is KtDeclaration && !isOnlyKotlinSearch(parameters.scopeDeterminedByUser)) {
|
||||||
elementToSearch.toLightElements().filterDataClassComponentsIfDisabled(kotlinOptions).nullize()
|
elementToSearch.providedToLightElements().filterDataClassComponentsIfDisabled(kotlinOptions).nullize()
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
} ?: listOf(elementToSearch)
|
} ?: listOf(elementToSearch)
|
||||||
@@ -194,7 +192,6 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
val classNameForCompanionObject = elementToSearch.getClassNameForCompanionObject()
|
val classNameForCompanionObject = elementToSearch.getClassNameForCompanionObject()
|
||||||
if (classNameForCompanionObject != null) {
|
if (classNameForCompanionObject != null) {
|
||||||
queryParameters.optimizer.searchWord(
|
queryParameters.optimizer.searchWord(
|
||||||
@@ -220,25 +217,14 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (kotlinOptions.searchForComponentConventions) {
|
if (kotlinOptions.searchForComponentConventions) {
|
||||||
when (element) {
|
searchForComponentConventions(element)
|
||||||
is KtParameter -> {
|
|
||||||
val componentFunctionDescriptor = element.dataClassComponentFunction()
|
|
||||||
if (componentFunctionDescriptor != null) {
|
|
||||||
val containingClass = element.getStrictParentOfType<KtClassOrObject>()?.toLightClass()
|
|
||||||
searchDataClassComponentUsages(containingClass, componentFunctionDescriptor, kotlinOptions)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
is KtLightParameter -> {
|
|
||||||
val componentFunctionDescriptor = element.kotlinOrigin?.dataClassComponentFunction()
|
|
||||||
if (componentFunctionDescriptor != null) {
|
|
||||||
searchDataClassComponentUsages(element.method.containingClass, componentFunctionDescriptor, kotlinOptions)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun PsiNamedElement.getClassNameForCompanionObject(): String? =
|
||||||
|
(this is KtObjectDeclaration && this.isCompanion())
|
||||||
|
.ifTrue { getNonStrictParentOfType<KtClass>()?.name }
|
||||||
|
|
||||||
private fun searchNamedArguments(parameter: KtParameter) {
|
private fun searchNamedArguments(parameter: KtParameter) {
|
||||||
val parameterName = parameter.name ?: return
|
val parameterName = parameter.name ?: return
|
||||||
val function = parameter.ownerFunction as? KtFunction ?: return
|
val function = parameter.ownerFunction as? KtFunction ?: return
|
||||||
@@ -247,7 +233,7 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
|
|||||||
var namedArgsScope = function.useScope.intersectWith(queryParameters.scopeDeterminedByUser)
|
var namedArgsScope = function.useScope.intersectWith(queryParameters.scopeDeterminedByUser)
|
||||||
|
|
||||||
if (namedArgsScope is GlobalSearchScope) {
|
if (namedArgsScope is GlobalSearchScope) {
|
||||||
namedArgsScope = KotlinSourceFilterScope.sourcesAndLibraries(namedArgsScope, project)
|
namedArgsScope = sourcesAndLibraries(namedArgsScope, project)
|
||||||
|
|
||||||
val filesWithFunctionName = CacheManager.SERVICE.getInstance(project).getVirtualFilesWithWord(
|
val filesWithFunctionName = CacheManager.SERVICE.getInstance(project).getVirtualFilesWithWord(
|
||||||
function.name!!, UsageSearchContext.IN_CODE, namedArgsScope, true
|
function.name!!, UsageSearchContext.IN_CODE, namedArgsScope, true
|
||||||
@@ -275,7 +261,7 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
|
|||||||
is KtNamedFunction, is KtSecondaryConstructor -> {
|
is KtNamedFunction, is KtSecondaryConstructor -> {
|
||||||
val name = (element as KtFunction).name
|
val name = (element as KtFunction).name
|
||||||
if (name != null) {
|
if (name != null) {
|
||||||
val methods = LightClassUtil.getLightClassMethods(element)
|
val methods = providedGetLightClassMethods(element)
|
||||||
for (method in methods) {
|
for (method in methods) {
|
||||||
searchNamedElement(method)
|
searchNamedElement(method)
|
||||||
}
|
}
|
||||||
@@ -285,8 +271,8 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
|
|||||||
}
|
}
|
||||||
|
|
||||||
is KtProperty -> {
|
is KtProperty -> {
|
||||||
val propertyMethods = LightClassUtil.getLightClassPropertyMethods(element)
|
val propertyDeclarations = providedGetLightClassPropertyDeclarations(element)
|
||||||
propertyMethods.allDeclarations.forEach { searchNamedElement(it) }
|
propertyDeclarations.forEach { searchNamedElement(it) }
|
||||||
processStaticsFromCompanionObject(element)
|
processStaticsFromCompanionObject(element)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,8 +280,8 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
|
|||||||
searchPropertyAccessorMethods(element)
|
searchPropertyAccessorMethods(element)
|
||||||
if (element.getStrictParentOfType<KtPrimaryConstructor>() != null) {
|
if (element.getStrictParentOfType<KtPrimaryConstructor>() != null) {
|
||||||
// Simple parameters without val and var shouldn't be processed here because of local search scope
|
// Simple parameters without val and var shouldn't be processed here because of local search scope
|
||||||
val methods = LightClassUtil.getLightClassPropertyMethods(element)
|
val parameterDeclarations = providedGetLightClassParameterDeclarations(element)
|
||||||
methods.allDeclarations.filterDataClassComponentsIfDisabled(kotlinOptions).forEach { searchNamedElement(it) }
|
parameterDeclarations.filterDataClassComponentsIfDisabled(kotlinOptions).forEach { searchNamedElement(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,19 +309,19 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun searchPropertyAccessorMethods(origin: KtParameter) {
|
private fun searchPropertyAccessorMethods(origin: KtParameter) {
|
||||||
origin.toLightElements().filterDataClassComponentsIfDisabled(kotlinOptions).forEach { searchNamedElement(it) }
|
origin.providedToLightElements().filterDataClassComponentsIfDisabled(kotlinOptions).forEach { searchNamedElement(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun processKtClassOrObject(element: KtClassOrObject) {
|
private fun processKtClassOrObject(element: KtClassOrObject) {
|
||||||
val className = element.name ?: return
|
val className = element.name ?: return
|
||||||
val lightClass = element.toLightClass() ?: return
|
val lightClass = element.providedToLightClass() ?: return
|
||||||
searchNamedElement(lightClass, className)
|
searchNamedElement(lightClass, className)
|
||||||
|
|
||||||
if (element is KtObjectDeclaration && element.isCompanion()) {
|
if (element is KtObjectDeclaration && element.isCompanion()) {
|
||||||
LightClassUtil.getLightFieldForCompanionObject(element)?.let { searchNamedElement(it) }
|
providedGetLightFieldForCompanionObject(element)?.let { searchNamedElement(it) }
|
||||||
|
|
||||||
if (kotlinOptions.acceptCompanionObjectMembers) {
|
if (kotlinOptions.acceptCompanionObjectMembers) {
|
||||||
val originLightClass = element.getStrictParentOfType<KtClass>()?.toLightClass()
|
val originLightClass = element.getStrictParentOfType<KtClass>()?.providedToLightClass()
|
||||||
if (originLightClass != null) {
|
if (originLightClass != null) {
|
||||||
val lightDeclarations: List<KtLightMember<*>?> =
|
val lightDeclarations: List<KtLightMember<*>?> =
|
||||||
originLightClass.methods.map { it as? KtLightMethod } + originLightClass.fields.map { it as? KtLightField }
|
originLightClass.methods.map { it as? KtLightMethod } + originLightClass.fields.map { it as? KtLightField }
|
||||||
@@ -350,13 +336,40 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun searchForComponentConventions(element: PsiElement) {
|
||||||
|
when (element) {
|
||||||
|
is KtParameter -> {
|
||||||
|
val componentMethodName = element.dataClassComponentMethodName
|
||||||
|
if (componentMethodName != null) {
|
||||||
|
val containingClass = element.getStrictParentOfType<KtClassOrObject>()?.providedToLightClass()
|
||||||
|
searchDataClassComponentUsages(
|
||||||
|
containingClass = containingClass,
|
||||||
|
componentMethodName = componentMethodName,
|
||||||
|
kotlinOptions = kotlinOptions
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is KtLightParameter -> {
|
||||||
|
val componentMethodName = element.kotlinOrigin?.dataClassComponentMethodName
|
||||||
|
if (componentMethodName != null) {
|
||||||
|
searchDataClassComponentUsages(
|
||||||
|
containingClass = element.method.containingClass,
|
||||||
|
componentMethodName = componentMethodName,
|
||||||
|
kotlinOptions = kotlinOptions
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun searchDataClassComponentUsages(
|
private fun searchDataClassComponentUsages(
|
||||||
containingClass: PsiClass?,
|
containingClass: PsiClass?,
|
||||||
componentFunctionDescriptor: FunctionDescriptor,
|
componentMethodName: String,
|
||||||
kotlinOptions: KotlinReferencesSearchOptions
|
kotlinOptions: KotlinReferencesSearchOptions
|
||||||
) {
|
) {
|
||||||
val componentFunction = containingClass?.methods?.firstOrNull {
|
val componentFunction = containingClass?.methods?.firstOrNull {
|
||||||
it.name == componentFunctionDescriptor.name.asString() && it.parameterList.parametersCount == 0
|
it.name == componentMethodName && it.parameterList.parametersCount == 0
|
||||||
}
|
}
|
||||||
if (componentFunction != null) {
|
if (componentFunction != null) {
|
||||||
searchNamedElement(componentFunction)
|
searchNamedElement(componentFunction)
|
||||||
@@ -378,7 +391,7 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
|
|||||||
.firstOrNull() as? KtObjectDeclaration ?: return emptyList()
|
.firstOrNull() as? KtObjectDeclaration ?: return emptyList()
|
||||||
if (!originObject.isCompanion()) return emptyList()
|
if (!originObject.isCompanion()) return emptyList()
|
||||||
val originClass = originObject.getStrictParentOfType<KtClass>()
|
val originClass = originObject.getStrictParentOfType<KtClass>()
|
||||||
val originLightClass = originClass?.toLightClass() ?: return emptyList()
|
val originLightClass = originClass?.providedToLightClass() ?: return emptyList()
|
||||||
val allMethods = originLightClass.allMethods
|
val allMethods = originLightClass.allMethods
|
||||||
return allMethods.filter { it is KtLightMethod && it.kotlinOrigin == declaration }
|
return allMethods.filter { it is KtLightMethod && it.kotlinOrigin == declaration }
|
||||||
}
|
}
|
||||||
+3
-3
@@ -23,10 +23,10 @@ import com.intellij.psi.PsiReferenceService
|
|||||||
import com.intellij.psi.ReferenceRange
|
import com.intellij.psi.ReferenceRange
|
||||||
import com.intellij.psi.search.RequestResultProcessor
|
import com.intellij.psi.search.RequestResultProcessor
|
||||||
import com.intellij.util.Processor
|
import com.intellij.util.Processor
|
||||||
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.isCallableOverrideUsage
|
||||||
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.isExtensionOfDeclarationClassUsage
|
||||||
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.isUsageInContainingDeclaration
|
||||||
import org.jetbrains.kotlin.idea.references.KtDestructuringDeclarationReference
|
import org.jetbrains.kotlin.idea.references.KtDestructuringDeclarationReference
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.isCallableOverrideUsage
|
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.isExtensionOfDeclarationClassUsage
|
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.isUsageInContainingDeclaration
|
|
||||||
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
|
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||||
|
|
||||||
+30
-5
@@ -21,9 +21,7 @@ import com.intellij.openapi.fileTypes.FileTypeRegistry
|
|||||||
import com.intellij.openapi.progress.ProgressIndicator
|
import com.intellij.openapi.progress.ProgressIndicator
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.*
|
||||||
import com.intellij.psi.PsiFile
|
|
||||||
import com.intellij.psi.PsiManager
|
|
||||||
import com.intellij.psi.impl.cache.impl.id.IdIndex
|
import com.intellij.psi.impl.cache.impl.id.IdIndex
|
||||||
import com.intellij.psi.impl.cache.impl.id.IdIndexEntry
|
import com.intellij.psi.impl.cache.impl.id.IdIndexEntry
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
@@ -33,12 +31,17 @@ import com.intellij.psi.search.SearchScope
|
|||||||
import com.intellij.psi.search.searches.ReferencesSearch
|
import com.intellij.psi.search.searches.ReferencesSearch
|
||||||
import com.intellij.util.CommonProcessors
|
import com.intellij.util.CommonProcessors
|
||||||
import com.intellij.util.indexing.FileBasedIndex
|
import com.intellij.util.indexing.FileBasedIndex
|
||||||
|
import org.jetbrains.kotlin.asJava.namedUnwrappedElement
|
||||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||||
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.scriptDefinitionExists
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.psi.KtImportDirective
|
||||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||||
import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition
|
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -141,6 +144,28 @@ fun findScriptsWithUsages(declaration: KtNamedDeclaration): List<KtFile> {
|
|||||||
}
|
}
|
||||||
return collector.results
|
return collector.results
|
||||||
.mapNotNull { PsiManager.getInstance(project).findFile(it) as? KtFile }
|
.mapNotNull { PsiManager.getInstance(project).findFile(it) as? KtFile }
|
||||||
.filter { it.findScriptDefinition() != null }
|
.filter { it.scriptDefinitionExists() }
|
||||||
.toList()
|
.toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline fun <T> Boolean.ifTrue(body: () -> T?): T? = if (this) body() else null
|
||||||
|
|
||||||
|
data class ReceiverTypeSearcherInfo(
|
||||||
|
val psiClass: PsiClass?,
|
||||||
|
val containsTypeOrDerivedInside: ((KtDeclaration) -> Boolean)
|
||||||
|
)
|
||||||
|
|
||||||
|
fun PsiReference.isImportUsage(): Boolean =
|
||||||
|
element.getNonStrictParentOfType<KtImportDirective>() != null
|
||||||
|
|
||||||
|
//TODO: Copied from fqNameUtil.kt
|
||||||
|
fun PsiElement.getKotlinFqName(): FqName? = when (val element = namedUnwrappedElement) {
|
||||||
|
is PsiPackage -> FqName(element.qualifiedName)
|
||||||
|
is PsiClass -> element.qualifiedName?.let(::FqName)
|
||||||
|
is PsiMember -> element.getName()?.let { name ->
|
||||||
|
val prefix = element.containingClass?.qualifiedName
|
||||||
|
FqName(if (prefix != null) "$prefix.$name" else name)
|
||||||
|
}
|
||||||
|
is KtNamedDeclaration -> element.fqName
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
+13
-28
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.idea.search.usagesSearch
|
|||||||
|
|
||||||
import com.intellij.ide.highlighter.JavaFileType
|
import com.intellij.ide.highlighter.JavaFileType
|
||||||
import com.intellij.ide.highlighter.XmlFileType
|
import com.intellij.ide.highlighter.XmlFileType
|
||||||
|
import com.intellij.ide.projectView.impl.ProjectRootsUtil
|
||||||
import com.intellij.lang.java.JavaLanguage
|
import com.intellij.lang.java.JavaLanguage
|
||||||
import com.intellij.openapi.application.ApplicationManager
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
import com.intellij.openapi.diagnostic.Logger
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
@@ -22,37 +23,30 @@ import com.intellij.psi.search.searches.ReferencesSearch
|
|||||||
import com.intellij.util.Processor
|
import com.intellij.util.Processor
|
||||||
import org.jetbrains.annotations.TestOnly
|
import org.jetbrains.annotations.TestOnly
|
||||||
import org.jetbrains.kotlin.KtNodeTypes
|
import org.jetbrains.kotlin.KtNodeTypes
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.LightClassProvider.Companion.providedToLightClass
|
||||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||||
import org.jetbrains.kotlin.asJava.toLightClass
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
|
||||||
import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils
|
import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils
|
||||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.hasType
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.isInProjectSource
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaMemberDescriptor
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.isSamInterface
|
||||||
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
|
|
||||||
import org.jetbrains.kotlin.idea.references.KtDestructuringDeclarationReference
|
import org.jetbrains.kotlin.idea.references.KtDestructuringDeclarationReference
|
||||||
import org.jetbrains.kotlin.idea.search.excludeFileTypes
|
import org.jetbrains.kotlin.idea.search.excludeFileTypes
|
||||||
|
import org.jetbrains.kotlin.idea.search.getKotlinFqName
|
||||||
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions
|
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions
|
||||||
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchParameters
|
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchParameters
|
||||||
import org.jetbrains.kotlin.idea.search.restrictToKotlinSources
|
import org.jetbrains.kotlin.idea.search.restrictToKotlinSources
|
||||||
import org.jetbrains.kotlin.idea.util.FuzzyType
|
|
||||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
import org.jetbrains.kotlin.kdoc.psi.impl.KDocName
|
import org.jetbrains.kotlin.kdoc.psi.impl.KDocName
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
|
||||||
import org.jetbrains.kotlin.resolve.sam.getSingleAbstractMethodOrNull
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
//TODO: check if smart search is too expensive
|
//TODO: check if smart search is too expensive
|
||||||
|
|
||||||
class ExpressionsOfTypeProcessor(
|
class ExpressionsOfTypeProcessor(
|
||||||
private val typeToSearch: FuzzyType,
|
private val containsTypeOrDerivedInside: (KtDeclaration) -> Boolean,
|
||||||
private val classToSearch: PsiClass?,
|
private val classToSearch: PsiClass?,
|
||||||
private val searchScope: SearchScope,
|
private val searchScope: SearchScope,
|
||||||
private val project: Project,
|
private val project: Project,
|
||||||
@@ -132,7 +126,7 @@ class ExpressionsOfTypeProcessor(
|
|||||||
}) return
|
}) return
|
||||||
|
|
||||||
// for class from library always use plain search because we cannot search usages in compiled code (we could though)
|
// for class from library always use plain search because we cannot search usages in compiled code (we could though)
|
||||||
if (!runReadAction { classToSearch.isValid && ProjectRootsUtil.isInProjectSource(classToSearch) }) {
|
if (!runReadAction { classToSearch.isValid && isInProjectSource(classToSearch) }) {
|
||||||
possibleMatchesInScopeHandler(searchScope)
|
possibleMatchesInScopeHandler(searchScope)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -535,9 +529,7 @@ class ExpressionsOfTypeProcessor(
|
|||||||
|
|
||||||
if (element.getStrictParentOfType<KtImportDirective>() != null) return true // ignore usage in import
|
if (element.getStrictParentOfType<KtImportDirective>() != null) return true // ignore usage in import
|
||||||
|
|
||||||
val bindingContext = element.analyze(BodyResolveMode.PARTIAL)
|
if (element.hasType) { // access to object or companion object
|
||||||
val hasType = bindingContext.getType(element) != null
|
|
||||||
if (hasType) { // access to object or companion object
|
|
||||||
processSuspiciousExpression(element)
|
processSuspiciousExpression(element)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -590,7 +582,7 @@ class ExpressionsOfTypeProcessor(
|
|||||||
val parent = typeRefParent.parent
|
val parent = typeRefParent.parent
|
||||||
if (parent is KtSuperTypeCallEntry) {
|
if (parent is KtSuperTypeCallEntry) {
|
||||||
val classOrObject = (parent.parent as KtSuperTypeList).parent as KtClassOrObject
|
val classOrObject = (parent.parent as KtSuperTypeList).parent as KtClassOrObject
|
||||||
val psiClass = classOrObject.toLightClass()
|
val psiClass = classOrObject.providedToLightClass()
|
||||||
psiClass?.let { addClassToProcess(it) }
|
psiClass?.let { addClassToProcess(it) }
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -599,7 +591,7 @@ class ExpressionsOfTypeProcessor(
|
|||||||
is KtSuperTypeListEntry -> { // super-interface name in the list of bases
|
is KtSuperTypeListEntry -> { // super-interface name in the list of bases
|
||||||
if (typeRef == typeRefParent.typeReference) {
|
if (typeRef == typeRefParent.typeReference) {
|
||||||
val classOrObject = (typeRefParent.parent as KtSuperTypeList).parent as KtClassOrObject
|
val classOrObject = (typeRefParent.parent as KtSuperTypeList).parent as KtClassOrObject
|
||||||
val psiClass = classOrObject.toLightClass()
|
val psiClass = classOrObject.providedToLightClass()
|
||||||
psiClass?.let { addClassToProcess(it) }
|
psiClass?.let { addClassToProcess(it) }
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -762,8 +754,7 @@ class ExpressionsOfTypeProcessor(
|
|||||||
if (psiClass != null) {
|
if (psiClass != null) {
|
||||||
testLog { "Resolved java class to descriptor: ${psiClass.qualifiedName}" }
|
testLog { "Resolved java class to descriptor: ${psiClass.qualifiedName}" }
|
||||||
|
|
||||||
val classDescriptor = psiClass.getJavaMemberDescriptor() as? JavaClassDescriptor
|
if (psiClass.isSamInterface) {
|
||||||
if (classDescriptor != null && getSingleAbstractMethodOrNull(classDescriptor) != null) {
|
|
||||||
addSamInterfaceToProcess(psiClass)
|
addSamInterfaceToProcess(psiClass)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -838,9 +829,7 @@ class ExpressionsOfTypeProcessor(
|
|||||||
|
|
||||||
testLog { "Checked type of ${logPresentation(declaration)}" }
|
testLog { "Checked type of ${logPresentation(declaration)}" }
|
||||||
|
|
||||||
val descriptor = declaration.resolveToDescriptorIfAny() as? CallableDescriptor ?: return
|
if (containsTypeOrDerivedInside(declaration)) {
|
||||||
val type = descriptor.returnType
|
|
||||||
if (type != null && type.containsTypeOrDerivedInside(typeToSearch)) {
|
|
||||||
addCallableDeclarationOfOurType(declaration)
|
addCallableDeclarationOfOurType(declaration)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -907,10 +896,6 @@ class ExpressionsOfTypeProcessor(
|
|||||||
return true // we don't know
|
return true // we don't know
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KotlinType.containsTypeOrDerivedInside(type: FuzzyType): Boolean {
|
|
||||||
return type.checkIsSuperTypeOf(this) != null || arguments.any { !it.isStarProjection && it.type.containsTypeOrDerivedInside(type) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun isImplicitlyTyped(declaration: KtDeclaration): Boolean {
|
private fun isImplicitlyTyped(declaration: KtDeclaration): Boolean {
|
||||||
return when (declaration) {
|
return when (declaration) {
|
||||||
is KtFunction -> !declaration.hasDeclaredReturnType()
|
is KtFunction -> !declaration.hasDeclaredReturnType()
|
||||||
-11
@@ -22,10 +22,8 @@ import com.intellij.psi.search.SearchRequestCollector
|
|||||||
import com.intellij.psi.search.SearchScope
|
import com.intellij.psi.search.SearchScope
|
||||||
import com.intellij.util.Processor
|
import com.intellij.util.Processor
|
||||||
import org.jetbrains.kotlin.KtNodeTypes
|
import org.jetbrains.kotlin.KtNodeTypes
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
|
||||||
import org.jetbrains.kotlin.idea.references.KtDestructuringDeclarationReference
|
import org.jetbrains.kotlin.idea.references.KtDestructuringDeclarationReference
|
||||||
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions
|
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.dataClassComponentFunction
|
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
|
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
|
||||||
|
|
||||||
@@ -44,15 +42,6 @@ class DestructuringDeclarationReferenceSearcher(
|
|||||||
options,
|
options,
|
||||||
wordsToSearch = listOf("(")
|
wordsToSearch = listOf("(")
|
||||||
) {
|
) {
|
||||||
|
|
||||||
override fun resolveTargetToDescriptor(): FunctionDescriptor? {
|
|
||||||
return if (targetDeclaration is KtParameter) {
|
|
||||||
targetDeclaration.dataClassComponentFunction()
|
|
||||||
} else {
|
|
||||||
super.resolveTargetToDescriptor()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun extractReference(element: KtElement): PsiReference? {
|
override fun extractReference(element: KtElement): PsiReference? {
|
||||||
val destructuringDeclaration = element as? KtDestructuringDeclaration ?: return null
|
val destructuringDeclaration = element as? KtDestructuringDeclaration ?: return null
|
||||||
val entries = destructuringDeclaration.entries
|
val entries = destructuringDeclaration.entries
|
||||||
+12
-54
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.search.usagesSearch.operators
|
package org.jetbrains.kotlin.idea.search.usagesSearch.operators
|
||||||
|
|
||||||
import com.intellij.lang.java.JavaLanguage
|
|
||||||
import com.intellij.openapi.progress.ProgressIndicatorProvider
|
import com.intellij.openapi.progress.ProgressIndicatorProvider
|
||||||
import com.intellij.openapi.progress.util.ProgressWrapper
|
import com.intellij.openapi.progress.util.ProgressWrapper
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
@@ -13,36 +12,25 @@ import com.intellij.psi.search.*
|
|||||||
import com.intellij.util.Processor
|
import com.intellij.util.Processor
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||||
import org.jetbrains.kotlin.asJava.namedUnwrappedElement
|
import org.jetbrains.kotlin.asJava.namedUnwrappedElement
|
||||||
import org.jetbrains.kotlin.asJava.toLightClass
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
|
||||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||||
import org.jetbrains.kotlin.idea.KotlinIdeaAnalysisBundle
|
import org.jetbrains.kotlin.idea.KotlinIdeaAnalysisBundleIndependent
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.forceResolveReferences
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.getReceiverTypeSearcherInfo
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaOrKotlinMemberDescriptor
|
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.util.hasJavaResolutionFacade
|
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
|
||||||
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions
|
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions
|
||||||
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinRequestResultProcessor
|
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinRequestResultProcessor
|
||||||
|
import org.jetbrains.kotlin.idea.search.ifTrue
|
||||||
import org.jetbrains.kotlin.idea.search.restrictToKotlinSources
|
import org.jetbrains.kotlin.idea.search.restrictToKotlinSources
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.ExpressionsOfTypeProcessor
|
import org.jetbrains.kotlin.idea.search.usagesSearch.ExpressionsOfTypeProcessor
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.ExpressionsOfTypeProcessor.Companion.logPresentation
|
import org.jetbrains.kotlin.idea.search.usagesSearch.ExpressionsOfTypeProcessor.Companion.logPresentation
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.ExpressionsOfTypeProcessor.Companion.testLog
|
import org.jetbrains.kotlin.idea.search.usagesSearch.ExpressionsOfTypeProcessor.Companion.testLog
|
||||||
import org.jetbrains.kotlin.idea.util.FuzzyType
|
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
import org.jetbrains.kotlin.idea.util.fuzzyExtensionReceiverType
|
|
||||||
import org.jetbrains.kotlin.idea.util.toFuzzyType
|
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
|
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
|
||||||
import org.jetbrains.kotlin.resolve.DataClassDescriptorResolver
|
import org.jetbrains.kotlin.resolve.DataClassDescriptorResolver
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
|
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
|
||||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
import org.jetbrains.kotlin.util.isValidOperator
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
abstract class OperatorReferenceSearcher<TReferenceElement : KtElement>(
|
abstract class OperatorReferenceSearcher<TReferenceElement : KtElement>(
|
||||||
@@ -89,10 +77,9 @@ abstract class OperatorReferenceSearcher<TReferenceElement : KtElement>(
|
|||||||
options: KotlinReferencesSearchOptions
|
options: KotlinReferencesSearchOptions
|
||||||
): OperatorReferenceSearcher<*>? {
|
): OperatorReferenceSearcher<*>? {
|
||||||
return runReadAction {
|
return runReadAction {
|
||||||
if (declaration.isValid)
|
declaration.isValid.ifTrue {
|
||||||
createInReadAction(declaration, searchScope, consumer, optimizer, options)
|
createInReadAction(declaration, searchScope, consumer, optimizer, options)
|
||||||
else
|
}
|
||||||
null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,18 +190,10 @@ abstract class OperatorReferenceSearcher<TReferenceElement : KtElement>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun resolveTargetToDescriptor(): FunctionDescriptor? {
|
|
||||||
return when {
|
|
||||||
targetDeclaration is KtDeclaration -> targetDeclaration.resolveToDescriptorIfAny(BodyResolveMode.FULL)
|
|
||||||
targetDeclaration is PsiMember && targetDeclaration.hasJavaResolutionFacade() ->
|
|
||||||
targetDeclaration.getJavaOrKotlinMemberDescriptor()
|
|
||||||
else -> null
|
|
||||||
} as? FunctionDescriptor
|
|
||||||
}
|
|
||||||
|
|
||||||
fun run() {
|
fun run() {
|
||||||
val receiverType = runReadAction { extractReceiverType() } ?: return
|
|
||||||
val psiClass = runReadAction { receiverType.toPsiClass() }
|
val (psiClass, containsTypeOrDerivedInside) =
|
||||||
|
targetDeclaration.getReceiverTypeSearcherInfo(this is DestructuringDeclarationReferenceSearcher) ?: return
|
||||||
|
|
||||||
val inProgress = SearchesInProgress.get()
|
val inProgress = SearchesInProgress.get()
|
||||||
if (psiClass != null) {
|
if (psiClass != null) {
|
||||||
@@ -235,7 +214,7 @@ abstract class OperatorReferenceSearcher<TReferenceElement : KtElement>(
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
ExpressionsOfTypeProcessor(
|
ExpressionsOfTypeProcessor(
|
||||||
receiverType,
|
containsTypeOrDerivedInside,
|
||||||
psiClass,
|
psiClass,
|
||||||
searchScope,
|
searchScope,
|
||||||
project,
|
project,
|
||||||
@@ -247,27 +226,6 @@ abstract class OperatorReferenceSearcher<TReferenceElement : KtElement>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FuzzyType.toPsiClass(): PsiClass? {
|
|
||||||
val classDescriptor = type.constructor.declarationDescriptor ?: return null
|
|
||||||
val classDeclaration = DescriptorToSourceUtilsIde.getAnyDeclaration(project, classDescriptor)
|
|
||||||
return when (classDeclaration) {
|
|
||||||
is PsiClass -> classDeclaration
|
|
||||||
is KtClassOrObject -> classDeclaration.toLightClass()
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun extractReceiverType(): FuzzyType? {
|
|
||||||
val descriptor = resolveTargetToDescriptor()?.takeIf { it.isValidOperator() } ?: return null
|
|
||||||
|
|
||||||
return if (descriptor.isExtension) {
|
|
||||||
descriptor.fuzzyExtensionReceiverType()!!
|
|
||||||
} else {
|
|
||||||
val classDescriptor = descriptor.containingDeclaration as? ClassDescriptor ?: return null
|
|
||||||
classDescriptor.defaultType.toFuzzyType(classDescriptor.typeConstructor.parameters)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun doPlainSearch(scope: SearchScope) {
|
private fun doPlainSearch(scope: SearchScope) {
|
||||||
testLog { "Used plain search of ${logPresentation(targetDeclaration)} in ${scope.logPresentation()}" }
|
testLog { "Used plain search of ${logPresentation(targetDeclaration)} in ${scope.logPresentation()}" }
|
||||||
|
|
||||||
@@ -284,7 +242,7 @@ abstract class OperatorReferenceSearcher<TReferenceElement : KtElement>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// resolve all references at once
|
// resolve all references at once
|
||||||
(element.containingFile as KtFile).getResolutionFacade().analyze(elements, BodyResolveMode.PARTIAL)
|
(element.containingFile as? KtFile)?.forceResolveReferences(elements)
|
||||||
|
|
||||||
refs
|
refs
|
||||||
.filter { it.isReferenceTo(targetDeclaration) }
|
.filter { it.isReferenceTo(targetDeclaration) }
|
||||||
@@ -317,7 +275,7 @@ abstract class OperatorReferenceSearcher<TReferenceElement : KtElement>(
|
|||||||
// we must unwrap progress indicator because ProgressWrapper does not do anything on changing text and fraction
|
// we must unwrap progress indicator because ProgressWrapper does not do anything on changing text and fraction
|
||||||
val progress = ProgressWrapper.unwrap(ProgressIndicatorProvider.getGlobalProgressIndicator())
|
val progress = ProgressWrapper.unwrap(ProgressIndicatorProvider.getGlobalProgressIndicator())
|
||||||
progress?.pushState()
|
progress?.pushState()
|
||||||
progress?.text = KotlinIdeaAnalysisBundle.message("searching.for.implicit.usages")
|
progress?.text = KotlinIdeaAnalysisBundleIndependent.message("searching.for.implicit.usages")
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val files = runReadAction { FileTypeIndex.getFiles(KotlinFileType.INSTANCE, scope) }
|
val files = runReadAction { FileTypeIndex.getFiles(KotlinFileType.INSTANCE, scope) }
|
||||||
@@ -9,6 +9,7 @@ import com.intellij.openapi.application.ApplicationManager
|
|||||||
import com.intellij.openapi.command.CommandProcessor
|
import com.intellij.openapi.command.CommandProcessor
|
||||||
import com.intellij.openapi.components.ComponentManager
|
import com.intellij.openapi.components.ComponentManager
|
||||||
import com.intellij.openapi.progress.impl.CancellationCheck
|
import com.intellij.openapi.progress.impl.CancellationCheck
|
||||||
|
import com.intellij.openapi.project.DumbService
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
|
|
||||||
fun <T> runReadAction(action: () -> T): T {
|
fun <T> runReadAction(action: () -> T): T {
|
||||||
@@ -55,3 +56,8 @@ inline fun isUnitTestMode(): Boolean = ApplicationManager.getApplication().isUni
|
|||||||
|
|
||||||
inline fun <reified T : Any> ComponentManager.getServiceSafe(): T =
|
inline fun <reified T : Any> ComponentManager.getServiceSafe(): T =
|
||||||
this.getService(T::class.java) ?: error("Unable to locate service ${T::class.java.name}")
|
this.getService(T::class.java) ?: error("Unable to locate service ${T::class.java.name}")
|
||||||
|
|
||||||
|
fun <T> Project.runReadActionInSmartMode(action: () -> T): T {
|
||||||
|
if (ApplicationManager.getApplication().isReadAccessAllowed) return action()
|
||||||
|
return DumbService.getInstance(this).runReadActionInSmartMode<T>(action)
|
||||||
|
}
|
||||||
+6
@@ -10,6 +10,7 @@ import com.intellij.openapi.command.CommandProcessor
|
|||||||
import com.intellij.openapi.components.ComponentManager
|
import com.intellij.openapi.components.ComponentManager
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import org.jetbrains.annotations.Nls
|
import org.jetbrains.annotations.Nls
|
||||||
|
import com.intellij.openapi.project.DumbService
|
||||||
|
|
||||||
fun <T> runReadAction(action: () -> T): T {
|
fun <T> runReadAction(action: () -> T): T {
|
||||||
return ApplicationManager.getApplication().runReadAction<T>(action)
|
return ApplicationManager.getApplication().runReadAction<T>(action)
|
||||||
@@ -46,3 +47,8 @@ inline fun isUnitTestMode(): Boolean = ApplicationManager.getApplication().isUni
|
|||||||
|
|
||||||
inline fun <reified T : Any> ComponentManager.getServiceSafe(): T =
|
inline fun <reified T : Any> ComponentManager.getServiceSafe(): T =
|
||||||
this.getService(T::class.java) ?: error("Unable to locate service ${T::class.java.name}")
|
this.getService(T::class.java) ?: error("Unable to locate service ${T::class.java.name}")
|
||||||
|
|
||||||
|
fun <T> Project.runReadActionInSmartMode(action: () -> T): T {
|
||||||
|
if (ApplicationManager.getApplication().isReadAccessAllowed) return action()
|
||||||
|
return DumbService.getInstance(this).runReadActionInSmartMode<T>(action)
|
||||||
|
}
|
||||||
+7
-1
@@ -24,6 +24,7 @@ import com.intellij.openapi.progress.ProgressIndicator
|
|||||||
import com.intellij.openapi.progress.ProgressIndicatorProvider
|
import com.intellij.openapi.progress.ProgressIndicatorProvider
|
||||||
import com.intellij.openapi.progress.ProgressManager
|
import com.intellij.openapi.progress.ProgressManager
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.project.DumbService
|
||||||
|
|
||||||
fun <T> runReadAction(action: () -> T): T {
|
fun <T> runReadAction(action: () -> T): T {
|
||||||
return ApplicationManager.getApplication().runReadAction<T>(action)
|
return ApplicationManager.getApplication().runReadAction<T>(action)
|
||||||
@@ -62,4 +63,9 @@ inline fun <reified T : Any> ComponentManager.getServiceSafe(): T =
|
|||||||
this.getService(T::class.java) ?: error("Unable to locate service ${T::class.java.name}")
|
this.getService(T::class.java) ?: error("Unable to locate service ${T::class.java.name}")
|
||||||
|
|
||||||
fun <T> Project.getServiceIfCreated(serviceClass: Class<T>): T? =
|
fun <T> Project.getServiceIfCreated(serviceClass: Class<T>): T? =
|
||||||
ServiceManager.getServiceIfCreated(this, serviceClass)
|
ServiceManager.getServiceIfCreated(this, serviceClass)
|
||||||
|
|
||||||
|
fun <T> Project.runReadActionInSmartMode(action: () -> T): T {
|
||||||
|
if (ApplicationManager.getApplication().isReadAccessAllowed) return action()
|
||||||
|
return DumbService.getInstance(this).runReadActionInSmartMode<T>(action)
|
||||||
|
}
|
||||||
+1
-1
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
|||||||
import org.jetbrains.kotlin.idea.debugger.DebuggerClassNameProvider.Companion.getRelevantElement
|
import org.jetbrains.kotlin.idea.debugger.DebuggerClassNameProvider.Companion.getRelevantElement
|
||||||
import org.jetbrains.kotlin.idea.debugger.evaluate.KotlinDebuggerCaches
|
import org.jetbrains.kotlin.idea.debugger.evaluate.KotlinDebuggerCaches
|
||||||
import org.jetbrains.kotlin.idea.debugger.evaluate.KotlinDebuggerCaches.ComputedClassNames
|
import org.jetbrains.kotlin.idea.debugger.evaluate.KotlinDebuggerCaches.ComputedClassNames
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.isImportUsage
|
import org.jetbrains.kotlin.idea.search.isImportUsage
|
||||||
import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope
|
import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope
|
||||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
|
|||||||
@@ -214,19 +214,6 @@ override.declaration.choose.to.delete=Choose the ones you want to be deleted.
|
|||||||
override.declaration.member=Member
|
override.declaration.member=Member
|
||||||
override.declaration.delete.multiple.parameters={0} is a part of method hierarchy. Do you want to delete multiple parameters?
|
override.declaration.delete.multiple.parameters={0} is a part of method hierarchy. Do you want to delete multiple parameters?
|
||||||
|
|
||||||
find.declaration.implementing.methods.checkbox=&Implementing functions
|
|
||||||
find.declaration.overriding.methods.checkbox=Over&riding functions
|
|
||||||
find.declaration.implementing.properties.checkbox=&Implementing properties
|
|
||||||
find.declaration.overriding.properties.checkbox=Over&riding properties
|
|
||||||
find.declaration.property.readers.checkbox=Readers
|
|
||||||
find.declaration.property.writers.checkbox=Writers
|
|
||||||
find.declaration.include.overloaded.methods.checkbox=Include o&verloaded functions and extensions
|
|
||||||
find.declaration.functions.usages.checkbox=Usages of &functions
|
|
||||||
find.declaration.properties.usages.checkbox=Usages of &properties
|
|
||||||
find.declaration.constructor.usages.checkbox=Usages of &constructor
|
|
||||||
find.declaration.derived.classes.checkbox=&Derived classes
|
|
||||||
find.declaration.derived.interfaces.checkbox=Derived &interfaces
|
|
||||||
|
|
||||||
hierarchy.legend.member.is.defined.in.class=Member is defined in the class
|
hierarchy.legend.member.is.defined.in.class=Member is defined in the class
|
||||||
hierarchy.legend.member.defined.in.superclass=Member is not defined in the class but defined in superclass
|
hierarchy.legend.member.defined.in.superclass=Member is not defined in the class but defined in superclass
|
||||||
hierarchy.legend.member.should.be.defined=Member should be defined since the class is not abstract
|
hierarchy.legend.member.should.be.defined=Member should be defined since the class is not abstract
|
||||||
@@ -457,33 +444,6 @@ filters.text.inline.function.body=inline function body
|
|||||||
filters.text.inline.function.call.site=inline function call site
|
filters.text.inline.function.call.site=inline function call site
|
||||||
filters.title.navigate.to=Navigate to
|
filters.title.navigate.to=Navigate to
|
||||||
|
|
||||||
find.usages.class=class
|
|
||||||
find.usages.companion.object=companion object
|
|
||||||
find.usages.constructor=constructor
|
|
||||||
find.usages.facade.class=facade class
|
|
||||||
find.usages.for.property={0} for property
|
|
||||||
find.usages.function=function
|
|
||||||
find.usages.getter=getter
|
|
||||||
find.usages.import.alias=import alias
|
|
||||||
find.usages.interface=interface
|
|
||||||
find.usages.label=label
|
|
||||||
find.usages.lambda=lambda
|
|
||||||
find.usages.object=object
|
|
||||||
find.usages.parameter=parameter
|
|
||||||
find.usages.property.accessor=property accessor
|
|
||||||
find.usages.property=property
|
|
||||||
find.usages.setter=setter
|
|
||||||
find.usages.type.alias=type alias
|
|
||||||
find.usages.type.parameter=type parameter
|
|
||||||
find.usages.variable=variable
|
|
||||||
find.usages.checkbox.name.expected.classes=Expected classes
|
|
||||||
find.usages.class.name.anonymous=Anonymous
|
|
||||||
find.usages.checkbox.name.expected.functions=Expected functions
|
|
||||||
find.usages.text.find.usages.for.data.class.components.and.destruction.declarations=<p>Find usages for data class components and destructuring declarations<br/>could be <a href="{0}">disabled once</a> or <a href="{1}">disabled for a project</a>.</p>
|
|
||||||
find.usages.tool.tip.text.disable.search.for.data.class.components.and.destruction.declarations.project.wide.setting=Disable search for data class components and destructuring declarations. (Project wide setting)
|
|
||||||
find.usages.checkbox.text.fast.data.class.component.search=Fast data class component search
|
|
||||||
find.usages.checkbox.name.expected.properties=Expected properties
|
|
||||||
find.usages.action.text.find.usages.of=find usages of
|
|
||||||
find.usages.type.named.argument=Named argument
|
find.usages.type.named.argument=Named argument
|
||||||
find.usages.type.type.alias=Type alias
|
find.usages.type.type.alias=Type alias
|
||||||
find.usages.type.callable.reference=Callable reference
|
find.usages.type.callable.reference=Callable reference
|
||||||
|
|||||||
@@ -192,6 +192,12 @@ The Kotlin FIR plugin provides language support in IntelliJ IDEA and Android Stu
|
|||||||
|
|
||||||
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Registrar"/>
|
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Registrar"/>
|
||||||
|
|
||||||
|
<elementDescriptionProvider
|
||||||
|
implementation="org.jetbrains.kotlin.idea.findUsages.KotlinElementDescriptionProviderBase"
|
||||||
|
order="first"/>
|
||||||
|
|
||||||
|
<lang.findUsagesProvider language="kotlin" implementationClass="org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesProviderBase"/>
|
||||||
|
|
||||||
<fileType name="Kotlin"
|
<fileType name="Kotlin"
|
||||||
implementationClass="org.jetbrains.kotlin.idea.KotlinFileType"
|
implementationClass="org.jetbrains.kotlin.idea.KotlinFileType"
|
||||||
fieldName="INSTANCE"
|
fieldName="INSTANCE"
|
||||||
|
|||||||
@@ -211,6 +211,9 @@
|
|||||||
<projectService serviceInterface="org.jetbrains.kotlin.asJava.KotlinAsJavaSupport"
|
<projectService serviceInterface="org.jetbrains.kotlin.asJava.KotlinAsJavaSupport"
|
||||||
serviceImplementation="org.jetbrains.kotlin.idea.caches.resolve.IDEKotlinAsJavaSupport"/>
|
serviceImplementation="org.jetbrains.kotlin.idea.caches.resolve.IDEKotlinAsJavaSupport"/>
|
||||||
|
|
||||||
|
<projectService serviceInterface="org.jetbrains.kotlin.idea.asJava.LightClassProvider"
|
||||||
|
serviceImplementation="org.jetbrains.kotlin.idea.asJava.LightClassProviderImpl"/>
|
||||||
|
|
||||||
<projectService serviceInterface="org.jetbrains.kotlin.psi.KtFileClassProvider"
|
<projectService serviceInterface="org.jetbrains.kotlin.psi.KtFileClassProvider"
|
||||||
serviceImplementation="org.jetbrains.kotlin.idea.caches.resolve.KtFileClassProviderImpl"/>
|
serviceImplementation="org.jetbrains.kotlin.idea.caches.resolve.KtFileClassProviderImpl"/>
|
||||||
|
|
||||||
@@ -281,6 +284,12 @@
|
|||||||
<projectService serviceInterface="org.jetbrains.kotlin.idea.debugger.coroutine.DebuggerListener"
|
<projectService serviceInterface="org.jetbrains.kotlin.idea.debugger.coroutine.DebuggerListener"
|
||||||
serviceImplementation="org.jetbrains.kotlin.idea.debugger.coroutine.CoroutineDebuggerListener"/>
|
serviceImplementation="org.jetbrains.kotlin.idea.debugger.coroutine.CoroutineDebuggerListener"/>
|
||||||
|
|
||||||
|
<projectService serviceInterface="org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesSupport"
|
||||||
|
serviceImplementation="org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesSupportImpl"/>
|
||||||
|
|
||||||
|
<projectService serviceInterface="org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport"
|
||||||
|
serviceImplementation="org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupportImpl"/>
|
||||||
|
|
||||||
<errorHandler implementation="org.jetbrains.kotlin.idea.reporter.KotlinReportSubmitter"/>
|
<errorHandler implementation="org.jetbrains.kotlin.idea.reporter.KotlinReportSubmitter"/>
|
||||||
|
|
||||||
<registryKey
|
<registryKey
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* 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.asJava
|
||||||
|
|
||||||
|
import com.intellij.psi.*
|
||||||
|
import org.jetbrains.kotlin.asJava.*
|
||||||
|
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||||
|
import org.jetbrains.kotlin.idea.caches.lightClasses.KtFakeLightClass
|
||||||
|
import org.jetbrains.kotlin.idea.caches.lightClasses.KtFakeLightMethod
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
|
||||||
|
class LightClassProviderImpl : LightClassProvider {
|
||||||
|
override fun getLightFieldForCompanionObject(companionObject: KtClassOrObject): PsiField? =
|
||||||
|
LightClassUtil.getLightFieldForCompanionObject(companionObject)
|
||||||
|
|
||||||
|
override fun getLightClassMethods(function: KtFunction): List<PsiMethod> =
|
||||||
|
LightClassUtil.getLightClassMethods(function)
|
||||||
|
|
||||||
|
override fun getLightClassParameterDeclarations(parameter: KtParameter): List<PsiNamedElement> =
|
||||||
|
LightClassUtil.getLightClassPropertyMethods(parameter).allDeclarations
|
||||||
|
|
||||||
|
override fun getLightClassPropertyDeclarations(property: KtProperty): List<PsiNamedElement> =
|
||||||
|
LightClassUtil.getLightClassPropertyMethods(property).allDeclarations
|
||||||
|
|
||||||
|
override fun toLightClassWithBuiltinMapping(classOrObject: KtClassOrObject): PsiClass? =
|
||||||
|
classOrObject.toLightClassWithBuiltinMapping()
|
||||||
|
|
||||||
|
override fun toLightMethods(psiElement: PsiElement): List<PsiMethod> =
|
||||||
|
psiElement.toLightMethods()
|
||||||
|
|
||||||
|
override fun toLightClass(classOrObject: KtClassOrObject): KtLightClass? =
|
||||||
|
classOrObject.toLightClass()
|
||||||
|
|
||||||
|
override fun toLightElements(ktElement: KtElement): List<PsiNamedElement> =
|
||||||
|
ktElement.toLightElements()
|
||||||
|
|
||||||
|
override fun createKtFakeLightClass(kotlinOrigin: KtClassOrObject): PsiClass =
|
||||||
|
KtFakeLightClass(kotlinOrigin)
|
||||||
|
|
||||||
|
override fun getRepresentativeLightMethod(psiElement: PsiElement): PsiMethod? =
|
||||||
|
psiElement.getRepresentativeLightMethod()
|
||||||
|
|
||||||
|
override fun isKtFakeLightClass(psiClass: PsiClass): Boolean =
|
||||||
|
psiClass is KtFakeLightClass
|
||||||
|
|
||||||
|
override fun createKtFakeLightMethod(ktDeclaration: KtNamedDeclaration): PsiMethod? =
|
||||||
|
KtFakeLightMethod.get(ktDeclaration)
|
||||||
|
}
|
||||||
@@ -16,190 +16,15 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.findUsages
|
package org.jetbrains.kotlin.idea.findUsages
|
||||||
|
|
||||||
import com.intellij.codeInsight.highlighting.HighlightUsagesDescriptionLocation
|
|
||||||
import com.intellij.openapi.util.text.StringUtil
|
|
||||||
import com.intellij.psi.ElementDescriptionLocation
|
|
||||||
import com.intellij.psi.ElementDescriptionProvider
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiNamedElement
|
|
||||||
import com.intellij.refactoring.util.CommonRefactoringUtil
|
|
||||||
import com.intellij.refactoring.util.RefactoringDescriptionLocation
|
|
||||||
import com.intellij.usageView.UsageViewLongNameLocation
|
|
||||||
import com.intellij.usageView.UsageViewShortNameLocation
|
|
||||||
import com.intellij.usageView.UsageViewTypeLocation
|
|
||||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
|
||||||
import org.jetbrains.kotlin.asJava.unwrapped
|
|
||||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
|
||||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
|
||||||
import org.jetbrains.kotlin.idea.refactoring.rename.RenameJavaSyntheticPropertyHandler
|
import org.jetbrains.kotlin.idea.refactoring.rename.RenameJavaSyntheticPropertyHandler
|
||||||
import org.jetbrains.kotlin.idea.refactoring.rename.RenameKotlinPropertyProcessor
|
import org.jetbrains.kotlin.idea.refactoring.rename.RenameKotlinPropertyProcessor
|
||||||
import org.jetbrains.kotlin.idea.util.string.collapseSpaces
|
|
||||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
import org.jetbrains.kotlin.psi.*
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
|
||||||
|
|
||||||
class KotlinElementDescriptionProvider : ElementDescriptionProvider {
|
class KotlinElementDescriptionProvider : KotlinElementDescriptionProviderBase() {
|
||||||
private tailrec fun KtNamedDeclaration.parentForFqName(): KtNamedDeclaration? {
|
|
||||||
val parent = getStrictParentOfType<KtNamedDeclaration>() ?: return null
|
|
||||||
if (parent is KtProperty && parent.isLocal) return parent.parentForFqName()
|
|
||||||
return parent
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun KtNamedDeclaration.name() = nameAsName ?: Name.special("<no name provided>")
|
override val PsiElement.isRenameJavaSyntheticPropertyHandler: Boolean
|
||||||
|
get() = this is RenameJavaSyntheticPropertyHandler.SyntheticPropertyWrapper
|
||||||
|
|
||||||
private fun KtNamedDeclaration.fqName(): FqNameUnsafe {
|
override val PsiElement.isRenameKotlinPropertyProcessor: Boolean
|
||||||
containingClassOrObject?.let {
|
get() = this is RenameKotlinPropertyProcessor.PropertyMethodWrapper
|
||||||
if (it is KtObjectDeclaration && it.isCompanion()) {
|
|
||||||
return it.fqName().child(name())
|
|
||||||
}
|
|
||||||
return FqNameUnsafe("${it.name()}.${name()}")
|
|
||||||
}
|
|
||||||
|
|
||||||
val internalSegments = generateSequence(this) { it.parentForFqName() }
|
|
||||||
.filterIsInstance<KtNamedDeclaration>()
|
|
||||||
.map { it.name ?: "<no name provided>" }
|
|
||||||
.toList()
|
|
||||||
.asReversed()
|
|
||||||
val packageSegments = containingKtFile.packageFqName.pathSegments()
|
|
||||||
return FqNameUnsafe((packageSegments + internalSegments).joinToString("."))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun KtTypeReference.renderShort(): String {
|
|
||||||
return accept(
|
|
||||||
object : KtVisitor<String, Unit>() {
|
|
||||||
private val visitor get() = this
|
|
||||||
|
|
||||||
override fun visitTypeReference(typeReference: KtTypeReference, data: Unit): String {
|
|
||||||
val typeText = typeReference.typeElement?.accept(this, data) ?: "???"
|
|
||||||
return if (typeReference.hasParentheses()) "($typeText)" else typeText
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitDynamicType(type: KtDynamicType, data: Unit) = type.text
|
|
||||||
|
|
||||||
override fun visitFunctionType(type: KtFunctionType, data: Unit): String {
|
|
||||||
return buildString {
|
|
||||||
type.receiverTypeReference?.let { append(it.accept(visitor, data)).append('.') }
|
|
||||||
type.parameters.joinTo(this, prefix = "(", postfix = ")") { it.accept(visitor, data) }
|
|
||||||
append(" -> ")
|
|
||||||
append(type.returnTypeReference?.accept(visitor, data) ?: "???")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitNullableType(nullableType: KtNullableType, data: Unit): String {
|
|
||||||
val innerTypeText = nullableType.innerType?.accept(this, data) ?: return "???"
|
|
||||||
return "$innerTypeText?"
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitSelfType(type: KtSelfType, data: Unit) = type.text
|
|
||||||
|
|
||||||
override fun visitUserType(type: KtUserType, data: Unit): String {
|
|
||||||
return buildString {
|
|
||||||
append(type.referencedName ?: "???")
|
|
||||||
|
|
||||||
val arguments = type.typeArguments
|
|
||||||
if (arguments.isNotEmpty()) {
|
|
||||||
arguments.joinTo(this, prefix = "<", postfix = ">") {
|
|
||||||
it.typeReference?.accept(visitor, data) ?: it.text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitParameter(parameter: KtParameter, data: Unit) = parameter.typeReference?.accept(this, data) ?: "???"
|
|
||||||
},
|
|
||||||
Unit
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getElementDescription(element: PsiElement, location: ElementDescriptionLocation): String? {
|
|
||||||
val shouldUnwrap = location !is UsageViewShortNameLocation && location !is UsageViewLongNameLocation
|
|
||||||
val targetElement = if (shouldUnwrap) element.unwrapped ?: element else element
|
|
||||||
|
|
||||||
fun elementKind() = when (targetElement) {
|
|
||||||
is KtClass -> if (targetElement.isInterface())
|
|
||||||
KotlinBundle.message("find.usages.interface")
|
|
||||||
else
|
|
||||||
KotlinBundle.message("find.usages.class")
|
|
||||||
is KtObjectDeclaration -> if (targetElement.isCompanion())
|
|
||||||
KotlinBundle.message("find.usages.companion.object")
|
|
||||||
else
|
|
||||||
KotlinBundle.message("find.usages.object")
|
|
||||||
is KtNamedFunction -> KotlinBundle.message("find.usages.function")
|
|
||||||
is KtPropertyAccessor -> KotlinBundle.message(
|
|
||||||
"find.usages.for.property",
|
|
||||||
(if (targetElement.isGetter)
|
|
||||||
KotlinBundle.message("find.usages.getter")
|
|
||||||
else
|
|
||||||
KotlinBundle.message("find.usages.setter"))
|
|
||||||
) + " "
|
|
||||||
is KtFunctionLiteral -> KotlinBundle.message("find.usages.lambda")
|
|
||||||
is KtPrimaryConstructor, is KtSecondaryConstructor -> KotlinBundle.message("find.usages.constructor")
|
|
||||||
is KtProperty -> if (targetElement.isLocal)
|
|
||||||
KotlinBundle.message("find.usages.variable")
|
|
||||||
else
|
|
||||||
KotlinBundle.message("find.usages.property")
|
|
||||||
is KtTypeParameter -> KotlinBundle.message("find.usages.type.parameter")
|
|
||||||
is KtParameter -> KotlinBundle.message("find.usages.parameter")
|
|
||||||
is KtDestructuringDeclarationEntry -> KotlinBundle.message("find.usages.variable")
|
|
||||||
is KtTypeAlias -> KotlinBundle.message("find.usages.type.alias")
|
|
||||||
is KtLabeledExpression -> KotlinBundle.message("find.usages.label")
|
|
||||||
is KtImportAlias -> KotlinBundle.message("find.usages.import.alias")
|
|
||||||
is RenameJavaSyntheticPropertyHandler.SyntheticPropertyWrapper -> KotlinBundle.message("find.usages.property")
|
|
||||||
is KtLightClassForFacade -> KotlinBundle.message("find.usages.facade.class")
|
|
||||||
is RenameKotlinPropertyProcessor.PropertyMethodWrapper -> KotlinBundle.message("find.usages.property.accessor")
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
|
|
||||||
val namedElement = if (targetElement is KtPropertyAccessor) {
|
|
||||||
targetElement.parent as? KtProperty
|
|
||||||
} else targetElement as? PsiNamedElement
|
|
||||||
|
|
||||||
@Suppress("FoldInitializerAndIfToElvis")
|
|
||||||
if (namedElement == null) {
|
|
||||||
return if (targetElement is KtElement) "'" + StringUtil.shortenTextWithEllipsis(
|
|
||||||
targetElement.text.collapseSpaces(),
|
|
||||||
53,
|
|
||||||
0
|
|
||||||
) + "'" else null
|
|
||||||
}
|
|
||||||
|
|
||||||
if (namedElement.language != KotlinLanguage.INSTANCE) return null
|
|
||||||
|
|
||||||
return when (location) {
|
|
||||||
is UsageViewTypeLocation -> elementKind()
|
|
||||||
is UsageViewShortNameLocation, is UsageViewLongNameLocation -> namedElement.name
|
|
||||||
is RefactoringDescriptionLocation -> {
|
|
||||||
val kind = elementKind() ?: return null
|
|
||||||
if (namedElement !is KtNamedDeclaration) return null
|
|
||||||
val renderFqName = location.includeParent() &&
|
|
||||||
namedElement !is KtTypeParameter &&
|
|
||||||
namedElement !is KtParameter &&
|
|
||||||
namedElement !is KtConstructor<*>
|
|
||||||
val desc = when (namedElement) {
|
|
||||||
is KtFunction -> {
|
|
||||||
val baseText = buildString {
|
|
||||||
append(namedElement.name ?: "")
|
|
||||||
namedElement.valueParameters.joinTo(this, prefix = "(", postfix = ")") {
|
|
||||||
(if (it.isVarArg) "vararg " else "") + (it.typeReference?.renderShort() ?: "")
|
|
||||||
}
|
|
||||||
namedElement.receiverTypeReference?.let { append(" on ").append(it.renderShort()) }
|
|
||||||
}
|
|
||||||
val parentFqName = if (renderFqName) namedElement.fqName().parent() else null
|
|
||||||
if (parentFqName?.isRoot != false) baseText else "${parentFqName.asString()}.$baseText"
|
|
||||||
}
|
|
||||||
else -> (if (renderFqName) namedElement.fqName().asString() else namedElement.name) ?: ""
|
|
||||||
}
|
|
||||||
|
|
||||||
"$kind ${CommonRefactoringUtil.htmlEmphasize(desc)}"
|
|
||||||
}
|
|
||||||
is HighlightUsagesDescriptionLocation -> {
|
|
||||||
val kind = elementKind() ?: return null
|
|
||||||
if (namedElement !is KtNamedDeclaration) return null
|
|
||||||
"$kind ${namedElement.name}"
|
|
||||||
}
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,72 +19,21 @@ import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
|||||||
import org.jetbrains.kotlin.psi.psiUtil.isPropertyParameter
|
import org.jetbrains.kotlin.psi.psiUtil.isPropertyParameter
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||||
|
|
||||||
class KotlinFindUsagesProvider : FindUsagesProvider {
|
class KotlinFindUsagesProvider : KotlinFindUsagesProviderBase() {
|
||||||
private val javaProvider by lazy { JavaFindUsagesProvider() }
|
|
||||||
|
|
||||||
override fun canFindUsagesFor(psiElement: PsiElement): Boolean =
|
|
||||||
psiElement is KtNamedDeclaration
|
|
||||||
|
|
||||||
override fun getWordsScanner(): WordsScanner? = KotlinWordsScanner()
|
|
||||||
|
|
||||||
override fun getHelpId(psiElement: PsiElement): String? = null
|
|
||||||
|
|
||||||
override fun getType(element: PsiElement): String {
|
|
||||||
return when (element) {
|
|
||||||
is KtNamedFunction -> KotlinBundle.message("find.usages.function")
|
|
||||||
is KtClass -> KotlinBundle.message("find.usages.class")
|
|
||||||
is KtParameter -> KotlinBundle.message("find.usages.parameter")
|
|
||||||
is KtProperty -> if (element.isLocal)
|
|
||||||
KotlinBundle.message("find.usages.variable")
|
|
||||||
else
|
|
||||||
KotlinBundle.message("find.usages.property")
|
|
||||||
is KtDestructuringDeclarationEntry -> KotlinBundle.message("find.usages.variable")
|
|
||||||
is KtTypeParameter -> KotlinBundle.message("find.usages.type.parameter")
|
|
||||||
is KtSecondaryConstructor -> KotlinBundle.message("find.usages.constructor")
|
|
||||||
is KtObjectDeclaration -> KotlinBundle.message("find.usages.object")
|
|
||||||
else -> ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val KtDeclaration.containerDescription: String?
|
|
||||||
get() {
|
|
||||||
containingClassOrObject?.let { return getDescriptiveName(it) }
|
|
||||||
(parent as? KtFile)?.parent?.let { return getDescriptiveName(it) }
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getDescriptiveName(element: PsiElement): String {
|
override fun getDescriptiveName(element: PsiElement): String {
|
||||||
return when (element) {
|
|
||||||
is PsiDirectory, is PsiPackage, is PsiFile -> javaProvider.getDescriptiveName(element)
|
if (element !is KtFunction) return super.getDescriptiveName(element)
|
||||||
is KtClassOrObject -> {
|
|
||||||
if (element is KtObjectDeclaration && element.isObjectLiteral()) return "<unnamed>"
|
val name = element.name ?: ""
|
||||||
element.fqName?.asString() ?: element.name ?: "<unnamed>"
|
val descriptor = element.unsafeResolveToDescriptor() as FunctionDescriptor
|
||||||
}
|
val renderer = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_NO_ANNOTATIONS
|
||||||
is KtProperty -> (element.name ?: "") + (element.containerDescription?.let { " of $it" } ?: "")
|
val paramsDescription =
|
||||||
is KtFunction -> {
|
descriptor.valueParameters.joinToString(prefix = "(", postfix = ")") { renderer.renderType(it.type) }
|
||||||
val name = element.name ?: ""
|
val returnType = descriptor.returnType
|
||||||
val descriptor = element.unsafeResolveToDescriptor() as FunctionDescriptor
|
val returnTypeDescription = if (returnType != null && !returnType.isUnit()) renderer.renderType(returnType) else null
|
||||||
val renderer = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_NO_ANNOTATIONS
|
val funDescription = "$name$paramsDescription" + (returnTypeDescription?.let { ": $it" } ?: "")
|
||||||
val paramsDescription =
|
return funDescription + (element.containerDescription?.let { " of $it" } ?: "")
|
||||||
descriptor.valueParameters.joinToString(prefix = "(", postfix = ")") { renderer.renderType(it.type) }
|
|
||||||
val returnType = descriptor.returnType
|
|
||||||
val returnTypeDescription = if (returnType != null && !returnType.isUnit()) renderer.renderType(returnType) else null
|
|
||||||
val funDescription = "$name$paramsDescription" + (returnTypeDescription?.let { ": $it" } ?: "")
|
|
||||||
return funDescription + (element.containerDescription?.let { " of $it" } ?: "")
|
|
||||||
}
|
|
||||||
is KtLabeledExpression -> element.getLabelName() ?: ""
|
|
||||||
is KtImportAlias -> element.name ?: ""
|
|
||||||
is KtLightElement<*, *> -> element.kotlinOrigin?.let { getDescriptiveName(it) } ?: ""
|
|
||||||
is KtParameter -> {
|
|
||||||
if (element.isPropertyParameter()) {
|
|
||||||
(element.name ?: "") + (element.containerDescription?.let { " of $it" } ?: "")
|
|
||||||
} else {
|
|
||||||
element.name ?: ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is PsiNamedElement -> element.name ?: ""
|
|
||||||
else -> ""
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getNodeText(element: PsiElement, useFullName: Boolean): String =
|
override fun getNodeText(element: PsiElement, useFullName: Boolean): String =
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* 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.findUsages
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.PsiReference
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import org.jetbrains.kotlin.idea.search.usagesSearch.dataClassComponentFunction
|
||||||
|
import org.jetbrains.kotlin.idea.search.usagesSearch.isConstructorUsage
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
|
||||||
|
class KotlinFindUsagesSupportImpl : KotlinFindUsagesSupport {
|
||||||
|
override fun isCallReceiverRefersToCompanionObject(element: KtElement, companionObject: KtObjectDeclaration): Boolean =
|
||||||
|
org.jetbrains.kotlin.idea.search.usagesSearch.isCallReceiverRefersToCompanionObject(element, companionObject)
|
||||||
|
|
||||||
|
override fun isDataClassComponentFunction(element: KtParameter): Boolean =
|
||||||
|
element.dataClassComponentFunction() != null
|
||||||
|
|
||||||
|
override fun getTopMostOverriddenElementsToHighlight(target: PsiElement): List<PsiElement> =
|
||||||
|
org.jetbrains.kotlin.idea.search.usagesSearch.getTopMostOverriddenElementsToHighlight(target)
|
||||||
|
|
||||||
|
override fun tryRenderDeclarationCompactStyle(declaration: KtDeclaration): String? =
|
||||||
|
org.jetbrains.kotlin.idea.search.usagesSearch.tryRenderDeclarationCompactStyle(declaration)
|
||||||
|
|
||||||
|
override fun isConstructorUsage(psiReference: PsiReference, ktClassOrObject: KtClassOrObject): Boolean =
|
||||||
|
psiReference.isConstructorUsage(ktClassOrObject)
|
||||||
|
|
||||||
|
override fun checkSuperMethods(declaration: KtDeclaration, ignore: Collection<PsiElement>?, actionString: String): List<PsiElement> =
|
||||||
|
org.jetbrains.kotlin.idea.refactoring.checkSuperMethods(declaration, ignore, actionString)
|
||||||
|
|
||||||
|
override fun sourcesAndLibraries(delegate: GlobalSearchScope, project: Project): GlobalSearchScope =
|
||||||
|
org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope.sourcesAndLibraries(delegate, project)
|
||||||
|
}
|
||||||
+1
-1
@@ -46,7 +46,7 @@ import java.util.*
|
|||||||
import com.intellij.codeInsight.daemon.impl.quickfix.ClassKind as IdeaClassKind
|
import com.intellij.codeInsight.daemon.impl.quickfix.ClassKind as IdeaClassKind
|
||||||
|
|
||||||
enum class ClassKind(@NonNls val keyword: String, @Nls val description: String) {
|
enum class ClassKind(@NonNls val keyword: String, @Nls val description: String) {
|
||||||
PLAIN_CLASS("class", KotlinBundle.message("find.usages.class")),
|
PLAIN_CLASS("class", KotlinBundle.message("text.class")),
|
||||||
ENUM_CLASS("enum class", KotlinBundle.message("text.enum")),
|
ENUM_CLASS("enum class", KotlinBundle.message("text.enum")),
|
||||||
ENUM_ENTRY("", KotlinBundle.message("text.enum.constant")),
|
ENUM_ENTRY("", KotlinBundle.message("text.enum.constant")),
|
||||||
ANNOTATION_CLASS("annotation class", KotlinBundle.message("text.annotation")),
|
ANNOTATION_CLASS("annotation class", KotlinBundle.message("text.annotation")),
|
||||||
|
|||||||
+2
-2
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.idea.references.findPsiDeclarations
|
|||||||
import org.jetbrains.kotlin.idea.references.mainReference
|
import org.jetbrains.kotlin.idea.references.mainReference
|
||||||
import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
|
import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
|
||||||
import org.jetbrains.kotlin.idea.search.fileScope
|
import org.jetbrains.kotlin.idea.search.fileScope
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.isImportUsage
|
import org.jetbrains.kotlin.idea.search.isImportUsage
|
||||||
import org.jetbrains.kotlin.idea.util.ImportInsertHelperImpl
|
import org.jetbrains.kotlin.idea.util.ImportInsertHelperImpl
|
||||||
import org.jetbrains.kotlin.idea.util.getAllAccessibleFunctions
|
import org.jetbrains.kotlin.idea.util.getAllAccessibleFunctions
|
||||||
import org.jetbrains.kotlin.idea.util.getAllAccessibleVariables
|
import org.jetbrains.kotlin.idea.util.getAllAccessibleVariables
|
||||||
@@ -136,7 +136,7 @@ private fun invokeRename(
|
|||||||
private fun replaceUsages(usages: List<UsageContext>, newName: String) {
|
private fun replaceUsages(usages: List<UsageContext>, newName: String) {
|
||||||
// case: inner element
|
// case: inner element
|
||||||
for (usage in usages.asReversed()) {
|
for (usage in usages.asReversed()) {
|
||||||
val reference = usage.pointer.element?.safeAs<KtElement>()?.mainReference?.takeUnless(KtReference::isImportUsage) ?: continue
|
val reference = usage.pointer.element?.safeAs<KtElement>()?.mainReference?.takeUnless { it.isImportUsage() } ?: continue
|
||||||
val newExpression = reference.handleElementRename(newName) as? KtNameReferenceExpression ?: continue
|
val newExpression = reference.handleElementRename(newName) as? KtNameReferenceExpression ?: continue
|
||||||
if (usage.isExtension) {
|
if (usage.isExtension) {
|
||||||
newExpression.getQualifiedElementSelector()?.replace(newExpression)
|
newExpression.getQualifiedElementSelector()?.replace(newExpression)
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.psi.*
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import com.intellij.psi.search.SearchScope
|
||||||
|
import org.jetbrains.kotlin.idea.core.isInheritable
|
||||||
|
import org.jetbrains.kotlin.idea.core.isOverridable
|
||||||
|
import org.jetbrains.kotlin.idea.search.declarationsSearch.forEachOverridingMethod
|
||||||
|
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions
|
||||||
|
import org.jetbrains.kotlin.idea.search.usagesSearch.*
|
||||||
|
import org.jetbrains.kotlin.idea.stubindex.KotlinTypeAliasShortNameIndex
|
||||||
|
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||||
|
import org.jetbrains.kotlin.idea.util.expectedDeclarationIfAny
|
||||||
|
import org.jetbrains.kotlin.idea.util.isExpectDeclaration
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.resolve.ImportPath
|
||||||
|
|
||||||
|
class KotlinSearchUsagesSupportImpl : KotlinSearchUsagesSupport {
|
||||||
|
|
||||||
|
override fun dataClassComponentMethodName(element: KtParameter): String? =
|
||||||
|
element.dataClassComponentFunction()?.name?.asString()
|
||||||
|
|
||||||
|
override fun hasType(element: KtExpression): Boolean =
|
||||||
|
org.jetbrains.kotlin.idea.search.usagesSearch.hasType(element)
|
||||||
|
|
||||||
|
override fun isSamInterface(psiClass: PsiClass): Boolean =
|
||||||
|
org.jetbrains.kotlin.idea.search.usagesSearch.isSamInterface(psiClass)
|
||||||
|
|
||||||
|
override fun <T : PsiNamedElement> filterDataClassComponentsIfDisabled(
|
||||||
|
elements: List<T>,
|
||||||
|
kotlinOptions: KotlinReferencesSearchOptions
|
||||||
|
): List<T> =
|
||||||
|
elements.filterDataClassComponentsIfDisabled(kotlinOptions)
|
||||||
|
|
||||||
|
override fun isCallableOverrideUsage(reference: PsiReference, declaration: KtNamedDeclaration): Boolean =
|
||||||
|
reference.isCallableOverrideUsage(declaration)
|
||||||
|
|
||||||
|
override fun isUsageInContainingDeclaration(reference: PsiReference, declaration: KtNamedDeclaration): Boolean =
|
||||||
|
reference.isUsageInContainingDeclaration(declaration)
|
||||||
|
|
||||||
|
override fun isExtensionOfDeclarationClassUsage(reference: PsiReference, declaration: KtNamedDeclaration): Boolean =
|
||||||
|
reference.isExtensionOfDeclarationClassUsage(declaration)
|
||||||
|
|
||||||
|
override fun getReceiverTypeSearcherInfo(psiElement: PsiElement, isDestructionDeclarationSearch: Boolean): ReceiverTypeSearcherInfo? =
|
||||||
|
psiElement.getReceiverTypeSearcherInfo(isDestructionDeclarationSearch)
|
||||||
|
|
||||||
|
override fun forceResolveReferences(file: KtFile, elements: List<KtElement>) =
|
||||||
|
file.forceResolveReferences(elements)
|
||||||
|
|
||||||
|
override fun scriptDefinitionExists(file: PsiFile): Boolean =
|
||||||
|
file.scriptDefinitionExists()
|
||||||
|
|
||||||
|
override fun getDefaultImports(file: KtFile): List<ImportPath> =
|
||||||
|
file.getDefaultImports()
|
||||||
|
|
||||||
|
override fun forEachKotlinOverride(
|
||||||
|
ktClass: KtClass,
|
||||||
|
members: List<KtNamedDeclaration>,
|
||||||
|
scope: SearchScope,
|
||||||
|
processor: (superMember: PsiElement, overridingMember: PsiElement) -> Boolean
|
||||||
|
): Boolean =
|
||||||
|
org.jetbrains.kotlin.idea.search.declarationsSearch.forEachKotlinOverride(
|
||||||
|
ktClass,
|
||||||
|
members,
|
||||||
|
scope,
|
||||||
|
processor
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun forEachOverridingMethod(method: PsiMethod, scope: SearchScope, processor: (PsiMethod) -> Boolean): Boolean =
|
||||||
|
method.forEachOverridingMethod(scope, processor)
|
||||||
|
|
||||||
|
override fun findDeepestSuperMethodsNoWrapping(method: PsiElement): List<PsiElement> =
|
||||||
|
org.jetbrains.kotlin.idea.search.declarationsSearch.findDeepestSuperMethodsNoWrapping(method)
|
||||||
|
|
||||||
|
override fun findTypeAliasByShortName(shortName: String, project: Project, scope: GlobalSearchScope): Collection<KtTypeAlias> =
|
||||||
|
KotlinTypeAliasShortNameIndex.getInstance().get(shortName, project, scope)
|
||||||
|
|
||||||
|
override fun isInProjectSource(element: PsiElement, includeScriptsOutsideSourceRoots: Boolean): Boolean =
|
||||||
|
ProjectRootsUtil.isInProjectSource(element, includeScriptsOutsideSourceRoots)
|
||||||
|
|
||||||
|
override fun isOverridable(declaration: KtDeclaration): Boolean =
|
||||||
|
declaration.isOverridable()
|
||||||
|
|
||||||
|
override fun isInheritable(ktClass: KtClass): Boolean =
|
||||||
|
ktClass.isInheritable()
|
||||||
|
|
||||||
|
override fun formatJavaOrLightMethod(method: PsiMethod): String =
|
||||||
|
org.jetbrains.kotlin.idea.refactoring.formatJavaOrLightMethod(method)
|
||||||
|
|
||||||
|
override fun formatClass(classOrObject: KtClassOrObject): String =
|
||||||
|
org.jetbrains.kotlin.idea.refactoring.formatClass(classOrObject)
|
||||||
|
|
||||||
|
override fun expectedDeclarationIfAny(declaration: KtDeclaration): KtDeclaration? =
|
||||||
|
declaration.expectedDeclarationIfAny()
|
||||||
|
|
||||||
|
override fun isExpectDeclaration(declaration: KtDeclaration): Boolean =
|
||||||
|
declaration.isExpectDeclaration()
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2000-2017 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.declarationsSearch
|
||||||
|
|
||||||
|
import com.intellij.psi.*
|
||||||
|
import com.intellij.psi.search.SearchScope
|
||||||
|
import com.intellij.psi.search.searches.OverridingMethodsSearch
|
||||||
|
import com.intellij.util.Processor
|
||||||
|
import org.jetbrains.kotlin.asJava.*
|
||||||
|
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.isOverridable
|
||||||
|
import org.jetbrains.kotlin.idea.caches.lightClasses.KtFakeLightMethod
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
|
||||||
|
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
||||||
|
import org.jetbrains.kotlin.idea.core.getDeepestSuperDeclarations
|
||||||
|
import org.jetbrains.kotlin.idea.search.excludeKotlinSources
|
||||||
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||||
|
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||||
|
import org.jetbrains.kotlin.types.substitutions.getTypeSubstitutor
|
||||||
|
import org.jetbrains.kotlin.util.findCallableMemberBySignature
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
fun forEachKotlinOverride(
|
||||||
|
ktClass: KtClass,
|
||||||
|
members: List<KtNamedDeclaration>,
|
||||||
|
scope: SearchScope,
|
||||||
|
processor: (superMember: PsiElement, overridingMember: PsiElement) -> Boolean
|
||||||
|
): Boolean {
|
||||||
|
val baseClassDescriptor = runReadAction { ktClass.unsafeResolveToDescriptor() as ClassDescriptor }
|
||||||
|
val baseDescriptors =
|
||||||
|
runReadAction { members.mapNotNull { it.unsafeResolveToDescriptor() as? CallableMemberDescriptor }.filter { it.isOverridable } }
|
||||||
|
if (baseDescriptors.isEmpty()) return true
|
||||||
|
|
||||||
|
HierarchySearchRequest(ktClass, scope, true).searchInheritors().forEach(Processor { psiClass ->
|
||||||
|
val inheritor = psiClass.unwrapped as? KtClassOrObject ?: return@Processor true
|
||||||
|
runReadAction {
|
||||||
|
val inheritorDescriptor = inheritor.unsafeResolveToDescriptor() as ClassDescriptor
|
||||||
|
val substitutor =
|
||||||
|
getTypeSubstitutor(baseClassDescriptor.defaultType, inheritorDescriptor.defaultType) ?: return@runReadAction true
|
||||||
|
baseDescriptors.forEach {
|
||||||
|
val superMember = it.source.getPsi()!!
|
||||||
|
val overridingDescriptor = (it.substitute(substitutor) as? CallableMemberDescriptor)?.let { memberDescriptor ->
|
||||||
|
inheritorDescriptor.findCallableMemberBySignature(memberDescriptor)
|
||||||
|
}
|
||||||
|
val overridingMember = overridingDescriptor?.source?.getPsi()
|
||||||
|
if (overridingMember != null) {
|
||||||
|
if (!processor(superMember, overridingMember)) return@runReadAction false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun PsiMethod.forEachOverridingMethod(
|
||||||
|
scope: SearchScope = runReadAction { useScope },
|
||||||
|
processor: (PsiMethod) -> Boolean
|
||||||
|
): Boolean {
|
||||||
|
if (this !is KtFakeLightMethod) {
|
||||||
|
if (!OverridingMethodsSearch.search(this, scope.excludeKotlinSources(), true).forEach(processor)) return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val ktMember = this.unwrapped as? KtNamedDeclaration ?: return true
|
||||||
|
val ktClass = runReadAction { ktMember.containingClassOrObject as? KtClass } ?: return true
|
||||||
|
return forEachKotlinOverride(ktClass, listOf(ktMember), scope) { _, overrider ->
|
||||||
|
val lightMethods = runReadAction { overrider.toPossiblyFakeLightMethods().distinctBy { it.unwrapped } }
|
||||||
|
lightMethods.all { processor(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun findDeepestSuperMethodsNoWrapping(method: PsiElement): List<PsiElement> {
|
||||||
|
val element = method.unwrapped
|
||||||
|
return when (element) {
|
||||||
|
is PsiMethod -> element.findDeepestSuperMethods().toList()
|
||||||
|
is KtCallableDeclaration -> {
|
||||||
|
val descriptor = element.resolveToDescriptorIfAny() as? CallableMemberDescriptor ?: return emptyList()
|
||||||
|
descriptor.getDeepestSuperDeclarations(false).mapNotNull {
|
||||||
|
it.source.getPsi() ?: DescriptorToSourceUtilsIde.getAnyDeclaration(element.project, it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> emptyList()
|
||||||
|
}
|
||||||
|
}
|
||||||
+102
-9
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.idea.search.usagesSearch
|
package org.jetbrains.kotlin.idea.search.usagesSearch
|
||||||
|
|
||||||
import com.intellij.openapi.application.ApplicationManager
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
import com.intellij.psi.search.SearchScope
|
import com.intellij.psi.search.SearchScope
|
||||||
import com.intellij.psi.search.searches.MethodReferencesSearch
|
import com.intellij.psi.search.searches.MethodReferencesSearch
|
||||||
@@ -26,29 +27,59 @@ import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
|||||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||||
|
import org.jetbrains.kotlin.asJava.toLightClass
|
||||||
import org.jetbrains.kotlin.asJava.toLightMethods
|
import org.jetbrains.kotlin.asJava.toLightMethods
|
||||||
import org.jetbrains.kotlin.asJava.unwrapped
|
import org.jetbrains.kotlin.asJava.unwrapped
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.idea.caches.project.NotUnderContentRootModuleInfo.project
|
||||||
|
import org.jetbrains.kotlin.idea.caches.project.getNullableModuleInfo
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToParameterDescriptorIfAny
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToParameterDescriptorIfAny
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaMemberDescriptor
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaMethodDescriptor
|
import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaMethodDescriptor
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaOrKotlinMemberDescriptor
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.util.hasJavaResolutionFacade
|
||||||
|
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
||||||
|
import org.jetbrains.kotlin.idea.compiler.IDELanguageSettingsProvider
|
||||||
|
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||||
|
import org.jetbrains.kotlin.idea.project.findAnalyzerServices
|
||||||
import org.jetbrains.kotlin.idea.references.unwrappedTargets
|
import org.jetbrains.kotlin.idea.references.unwrappedTargets
|
||||||
|
import org.jetbrains.kotlin.idea.search.ReceiverTypeSearcherInfo
|
||||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest
|
import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest
|
||||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.searchInheritors
|
import org.jetbrains.kotlin.idea.search.declarationsSearch.searchInheritors
|
||||||
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions
|
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions
|
||||||
|
import org.jetbrains.kotlin.idea.util.FuzzyType
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
|
import org.jetbrains.kotlin.idea.util.fuzzyExtensionReceiverType
|
||||||
|
import org.jetbrains.kotlin.idea.util.toFuzzyType
|
||||||
|
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.contains
|
import org.jetbrains.kotlin.psi.psiUtil.contains
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||||
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||||
import org.jetbrains.kotlin.resolve.*
|
import org.jetbrains.kotlin.resolve.*
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isTypeRefinementEnabled
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isTypeRefinementEnabled
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
|
import org.jetbrains.kotlin.resolve.sam.getSingleAbstractMethodOrNull
|
||||||
|
import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import org.jetbrains.kotlin.util.isValidOperator
|
||||||
|
|
||||||
val KtDeclaration.descriptor: DeclarationDescriptor?
|
fun tryRenderDeclarationCompactStyle(declaration: KtDeclaration): String? =
|
||||||
get() = if (this is KtParameter) this.descriptor else this.resolveToDescriptorIfAny(BodyResolveMode.FULL)
|
declaration.descriptor?.let { DescriptorRenderer.COMPACT.render(it) }
|
||||||
|
|
||||||
|
fun isSamInterface(psiClass: PsiClass): Boolean {
|
||||||
|
val classDescriptor = psiClass.getJavaMemberDescriptor() as? JavaClassDescriptor
|
||||||
|
return classDescriptor != null && getSingleAbstractMethodOrNull(classDescriptor) != null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun hasType(element: KtExpression): Boolean =
|
||||||
|
element.analyze(BodyResolveMode.PARTIAL).getType(element) != null
|
||||||
|
|
||||||
val KtDeclaration.constructor: ConstructorDescriptor?
|
val KtDeclaration.constructor: ConstructorDescriptor?
|
||||||
get() {
|
get() {
|
||||||
@@ -60,9 +91,6 @@ val KtDeclaration.constructor: ConstructorDescriptor?
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val KtParameter.descriptor: ValueParameterDescriptor?
|
|
||||||
get() = this.resolveToParameterDescriptorIfAny(BodyResolveMode.FULL)
|
|
||||||
|
|
||||||
val KtParameter.propertyDescriptor: PropertyDescriptor?
|
val KtParameter.propertyDescriptor: PropertyDescriptor?
|
||||||
get() = this.resolveToDescriptorIfAny(BodyResolveMode.FULL) as? PropertyDescriptor
|
get() = this.resolveToDescriptorIfAny(BodyResolveMode.FULL) as? PropertyDescriptor
|
||||||
|
|
||||||
@@ -79,9 +107,6 @@ fun PsiReference.checkUsageVsOriginalDescriptor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun PsiReference.isImportUsage(): Boolean =
|
|
||||||
element.getNonStrictParentOfType<KtImportDirective>() != null
|
|
||||||
|
|
||||||
fun PsiReference.isConstructorUsage(ktClassOrObject: KtClassOrObject): Boolean = with(element) {
|
fun PsiReference.isConstructorUsage(ktClassOrObject: KtClassOrObject): Boolean = with(element) {
|
||||||
fun checkJavaUsage(): Boolean {
|
fun checkJavaUsage(): Boolean {
|
||||||
val call = getNonStrictParentOfType<PsiConstructorCall>()
|
val call = getNonStrictParentOfType<PsiConstructorCall>()
|
||||||
@@ -306,4 +331,72 @@ fun <T : PsiNamedElement> List<T>.filterDataClassComponentsIfDisabled(kotlinOpti
|
|||||||
}
|
}
|
||||||
|
|
||||||
return filter { !it.isComponentElement() }
|
return filter { !it.isComponentElement() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun KtFile.forceResolveReferences(elements: List<KtElement>) {
|
||||||
|
getResolutionFacade().analyze(elements, BodyResolveMode.PARTIAL)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun PsiElement.resolveTargetToDescriptor(isDestructionDeclarationSearch: Boolean): FunctionDescriptor? {
|
||||||
|
|
||||||
|
if (isDestructionDeclarationSearch && this is KtParameter) {
|
||||||
|
return dataClassComponentFunction()
|
||||||
|
}
|
||||||
|
|
||||||
|
return when {
|
||||||
|
this is KtDeclaration -> resolveToDescriptorIfAny(BodyResolveMode.FULL)
|
||||||
|
this is PsiMember && hasJavaResolutionFacade() ->
|
||||||
|
this.getJavaOrKotlinMemberDescriptor()
|
||||||
|
else -> null
|
||||||
|
} as? FunctionDescriptor
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun containsTypeOrDerivedInside(declaration: KtDeclaration, typeToSearch: FuzzyType): Boolean {
|
||||||
|
|
||||||
|
fun KotlinType.containsTypeOrDerivedInside(type: FuzzyType): Boolean {
|
||||||
|
return type.checkIsSuperTypeOf(this) != null || arguments.any { !it.isStarProjection && it.type.containsTypeOrDerivedInside(type) }
|
||||||
|
}
|
||||||
|
|
||||||
|
val descriptor = declaration.resolveToDescriptorIfAny() as? CallableDescriptor
|
||||||
|
val type = descriptor?.returnType
|
||||||
|
return type != null && type.containsTypeOrDerivedInside(typeToSearch)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FuzzyType.toPsiClass(project: Project): PsiClass? {
|
||||||
|
val classDescriptor = type.constructor.declarationDescriptor ?: return null
|
||||||
|
val classDeclaration = DescriptorToSourceUtilsIde.getAnyDeclaration(project, classDescriptor)
|
||||||
|
return when (classDeclaration) {
|
||||||
|
is PsiClass -> classDeclaration
|
||||||
|
is KtClassOrObject -> classDeclaration.toLightClass()
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun PsiElement.extractReceiverType(isDestructionDeclarationSearch: Boolean): FuzzyType? {
|
||||||
|
val descriptor = resolveTargetToDescriptor(isDestructionDeclarationSearch)?.takeIf { it.isValidOperator() } ?: return null
|
||||||
|
|
||||||
|
return if (descriptor.isExtension) {
|
||||||
|
descriptor.fuzzyExtensionReceiverType()!!
|
||||||
|
} else {
|
||||||
|
val classDescriptor = descriptor.containingDeclaration as? ClassDescriptor ?: return null
|
||||||
|
classDescriptor.defaultType.toFuzzyType(classDescriptor.typeConstructor.parameters)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun PsiElement.getReceiverTypeSearcherInfo(isDestructionDeclarationSearch: Boolean): ReceiverTypeSearcherInfo? {
|
||||||
|
val receiverType = runReadAction { extractReceiverType(isDestructionDeclarationSearch) } ?: return null
|
||||||
|
val psiClass = runReadAction { receiverType.toPsiClass(project) }
|
||||||
|
return ReceiverTypeSearcherInfo(psiClass) {
|
||||||
|
containsTypeOrDerivedInside(it, receiverType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun KtFile.getDefaultImports(): List<ImportPath> {
|
||||||
|
val moduleInfo = getNullableModuleInfo() ?: return emptyList()
|
||||||
|
return TargetPlatformDetector.getPlatform(this).findAnalyzerServices(project).getDefaultImports(
|
||||||
|
IDELanguageSettingsProvider.getLanguageVersionSettings(moduleInfo, project),
|
||||||
|
includeLowPriorityImports = true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun PsiFile.scriptDefinitionExists(): Boolean = findScriptDefinition() != null
|
||||||
@@ -11,7 +11,7 @@ import com.intellij.psi.PsiEnumConstant
|
|||||||
import com.intellij.psi.PsiMethod
|
import com.intellij.psi.PsiMethod
|
||||||
import com.intellij.psi.PsiModifierListOwner
|
import com.intellij.psi.PsiModifierListOwner
|
||||||
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
|
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
|
||||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.findDeepestSuperMethodsNoWrapping
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.findDeepestSuperMethodsNoWrapping
|
||||||
import org.jetbrains.kotlin.name.SpecialNames
|
import org.jetbrains.kotlin.name.SpecialNames
|
||||||
import org.jetbrains.kotlin.nj2k.isObjectOrCompanionObject
|
import org.jetbrains.kotlin.nj2k.isObjectOrCompanionObject
|
||||||
import org.jetbrains.kotlin.nj2k.psi
|
import org.jetbrains.kotlin.nj2k.psi
|
||||||
|
|||||||
Reference in New Issue
Block a user