Find Usages: Look for as-property usages of Java methods
This commit is contained in:
committed by
Alexey Sedunov
parent
7e9222f70a
commit
9c360ef05a
@@ -1047,7 +1047,7 @@ public class DescriptorResolver {
|
|||||||
else if (property.isVar()) {
|
else if (property.isVar()) {
|
||||||
Annotations setterAnnotations = annotationSplitter.getAnnotationsForTarget(PROPERTY_SETTER);
|
Annotations setterAnnotations = annotationSplitter.getAnnotationsForTarget(PROPERTY_SETTER);
|
||||||
setterDescriptor = DescriptorFactory.createSetter(propertyDescriptor, setterAnnotations, !property.hasDelegate(),
|
setterDescriptor = DescriptorFactory.createSetter(propertyDescriptor, setterAnnotations, !property.hasDelegate(),
|
||||||
/* isExternal = */ false);
|
/* isExternal = */ false, propertyDescriptor.getSource());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!property.isVar()) {
|
if (!property.isVar()) {
|
||||||
|
|||||||
+2
-2
@@ -76,7 +76,7 @@ public class JavaPropertyDescriptor extends PropertyDescriptorImpl implements Ja
|
|||||||
if (getter != null) {
|
if (getter != null) {
|
||||||
newGetter = new PropertyGetterDescriptorImpl(
|
newGetter = new PropertyGetterDescriptorImpl(
|
||||||
enhanced, getter.getAnnotations(), getter.getModality(), getter.getVisibility(),
|
enhanced, getter.getAnnotations(), getter.getModality(), getter.getVisibility(),
|
||||||
getter.hasBody(), getter.isDefault(), getter.isExternal(), getKind(), getter, SourceElement.NO_SOURCE);
|
getter.hasBody(), getter.isDefault(), getter.isExternal(), getKind(), getter, getter.getSource());
|
||||||
newGetter.initialize(enhancedReturnType);
|
newGetter.initialize(enhancedReturnType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +85,7 @@ public class JavaPropertyDescriptor extends PropertyDescriptorImpl implements Ja
|
|||||||
if (setter != null) {
|
if (setter != null) {
|
||||||
newSetter = new PropertySetterDescriptorImpl(
|
newSetter = new PropertySetterDescriptorImpl(
|
||||||
enhanced, setter.getAnnotations(), setter.getModality(), setter.getVisibility(),
|
enhanced, setter.getAnnotations(), setter.getModality(), setter.getVisibility(),
|
||||||
setter.hasBody(), setter.isDefault(), setter.isExternal(), getKind(), setter, SourceElement.NO_SOURCE);
|
setter.hasBody(), setter.isDefault(), setter.isExternal(), getKind(), setter, setter.getSource());
|
||||||
newSetter.initialize(setter.getValueParameters().get(0));
|
newSetter.initialize(setter.getValueParameters().get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -322,7 +322,7 @@ public class LazyJavaClassMemberScope(
|
|||||||
|
|
||||||
val setter = setterMethod?.let { setterMethod ->
|
val setter = setterMethod?.let { setterMethod ->
|
||||||
DescriptorFactory.createSetter(propertyDescriptor, setterMethod.annotations, /* isDefault = */false,
|
DescriptorFactory.createSetter(propertyDescriptor, setterMethod.annotations, /* isDefault = */false,
|
||||||
/* isExternal = */ false, setterMethod.visibility)
|
/* isExternal = */ false, setterMethod.visibility, setterMethod.source)
|
||||||
}
|
}
|
||||||
|
|
||||||
return propertyDescriptor.apply { initialize(getter, setter) }
|
return propertyDescriptor.apply { initialize(getter, setter) }
|
||||||
|
|||||||
@@ -50,17 +50,7 @@ public class DescriptorFactory {
|
|||||||
@NotNull PropertyDescriptor propertyDescriptor,
|
@NotNull PropertyDescriptor propertyDescriptor,
|
||||||
@NotNull Annotations annotations
|
@NotNull Annotations annotations
|
||||||
) {
|
) {
|
||||||
return createSetter(propertyDescriptor, annotations, true, false);
|
return createSetter(propertyDescriptor, annotations, true, false, propertyDescriptor.getSource());
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static PropertySetterDescriptorImpl createSetter(
|
|
||||||
@NotNull PropertyDescriptor propertyDescriptor,
|
|
||||||
@NotNull Annotations annotations,
|
|
||||||
boolean isDefault,
|
|
||||||
boolean isExternal
|
|
||||||
) {
|
|
||||||
return createSetter(propertyDescriptor, annotations, isDefault, isExternal, propertyDescriptor.getVisibility());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -69,12 +59,24 @@ public class DescriptorFactory {
|
|||||||
@NotNull Annotations annotations,
|
@NotNull Annotations annotations,
|
||||||
boolean isDefault,
|
boolean isDefault,
|
||||||
boolean isExternal,
|
boolean isExternal,
|
||||||
@NotNull Visibility visibility
|
@NotNull SourceElement sourceElement
|
||||||
|
) {
|
||||||
|
return createSetter(propertyDescriptor, annotations, isDefault, isExternal, propertyDescriptor.getVisibility(), sourceElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static PropertySetterDescriptorImpl createSetter(
|
||||||
|
@NotNull PropertyDescriptor propertyDescriptor,
|
||||||
|
@NotNull Annotations annotations,
|
||||||
|
boolean isDefault,
|
||||||
|
boolean isExternal,
|
||||||
|
@NotNull Visibility visibility,
|
||||||
|
@NotNull SourceElement sourceElement
|
||||||
) {
|
) {
|
||||||
PropertySetterDescriptorImpl setterDescriptor =
|
PropertySetterDescriptorImpl setterDescriptor =
|
||||||
new PropertySetterDescriptorImpl(propertyDescriptor, annotations, propertyDescriptor.getModality(),
|
new PropertySetterDescriptorImpl(propertyDescriptor, annotations, propertyDescriptor.getModality(),
|
||||||
visibility, !isDefault, isDefault, isExternal,
|
visibility, !isDefault, isDefault, isExternal,
|
||||||
CallableMemberDescriptor.Kind.DECLARATION, null, propertyDescriptor.getSource());
|
CallableMemberDescriptor.Kind.DECLARATION, null, sourceElement);
|
||||||
setterDescriptor.initializeDefault();
|
setterDescriptor.initializeDefault();
|
||||||
return setterDescriptor;
|
return setterDescriptor;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,12 +21,15 @@ import com.intellij.openapi.util.TextRange
|
|||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.util.PsiTreeUtil
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
import com.intellij.util.IncorrectOperationException
|
import com.intellij.util.IncorrectOperationException
|
||||||
|
import com.intellij.util.SmartList
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.shorten.addToShorteningWaitSet
|
import org.jetbrains.kotlin.idea.codeInsight.shorten.addToShorteningWaitSet
|
||||||
import org.jetbrains.kotlin.idea.intentions.OperatorToFunctionIntention
|
import org.jetbrains.kotlin.idea.intentions.OperatorToFunctionIntention
|
||||||
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
|
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
|
||||||
import org.jetbrains.kotlin.idea.util.ShortenReferences
|
import org.jetbrains.kotlin.idea.util.ShortenReferences
|
||||||
import org.jetbrains.kotlin.lexer.KtToken
|
import org.jetbrains.kotlin.lexer.KtToken
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
|
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.name.isOneSegmentFQN
|
import org.jetbrains.kotlin.name.isOneSegmentFQN
|
||||||
@@ -36,10 +39,37 @@ import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch
|
|||||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElement
|
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElement
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementSelector
|
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementSelector
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.dataClassUtils.isComponentLike
|
import org.jetbrains.kotlin.resolve.dataClassUtils.isComponentLike
|
||||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||||
|
|
||||||
class KtSimpleNameReference(expression: KtSimpleNameExpression) : KtSimpleReference<KtSimpleNameExpression>(expression) {
|
class KtSimpleNameReference(expression: KtSimpleNameExpression) : KtSimpleReference<KtSimpleNameExpression>(expression) {
|
||||||
|
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||||
|
return SmartList<DeclarationDescriptor>().apply {
|
||||||
|
// Replace Java property with its accessor(s)
|
||||||
|
for (descriptor in super.getTargetDescriptors(context)) {
|
||||||
|
val sizeBefore = size
|
||||||
|
|
||||||
|
if (descriptor !is JavaPropertyDescriptor) {
|
||||||
|
add(descriptor)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
val readWriteAccess = expression.readWriteAccess(true)
|
||||||
|
descriptor.getter?.let {
|
||||||
|
if (readWriteAccess.isRead) add(it)
|
||||||
|
}
|
||||||
|
descriptor.setter?.let {
|
||||||
|
if (readWriteAccess.isWrite) add(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size == sizeBefore) {
|
||||||
|
add(descriptor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun isReferenceTo(element: PsiElement?): Boolean {
|
override fun isReferenceTo(element: PsiElement?): Boolean {
|
||||||
if (element != null) {
|
if (element != null) {
|
||||||
if (!canBeReferenceTo(element)) return false
|
if (!canBeReferenceTo(element)) return false
|
||||||
|
|||||||
@@ -148,8 +148,8 @@ val KtElement.mainReference: KtReference?
|
|||||||
|
|
||||||
// ----------- Read/write access -----------------------------------------------------------------------------------------------------------------------
|
// ----------- Read/write access -----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
public enum class ReferenceAccess {
|
public enum class ReferenceAccess(val isRead: Boolean, val isWrite: Boolean) {
|
||||||
READ, WRITE, READ_WRITE
|
READ(true, false), WRITE(false, true), READ_WRITE(true, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun KtExpression.readWriteAccess(useResolveForReadWrite: Boolean): ReferenceAccess {
|
public fun KtExpression.readWriteAccess(useResolveForReadWrite: Boolean): ReferenceAccess {
|
||||||
|
|||||||
@@ -16,10 +16,13 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.search
|
package org.jetbrains.kotlin.idea.search
|
||||||
|
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.PsiFile
|
import com.intellij.psi.PsiFile
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import com.intellij.psi.search.LocalSearchScope
|
||||||
import com.intellij.psi.search.SearchScope
|
import com.intellij.psi.search.SearchScope
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
|
||||||
public fun SearchScope.and(otherScope: SearchScope): SearchScope = intersectWith(otherScope)
|
public fun SearchScope.and(otherScope: SearchScope): SearchScope = intersectWith(otherScope)
|
||||||
public fun SearchScope.or(otherScope: SearchScope): SearchScope = union(otherScope)
|
public fun SearchScope.or(otherScope: SearchScope): SearchScope = union(otherScope)
|
||||||
@@ -30,4 +33,19 @@ public fun Project.allScope(): GlobalSearchScope = GlobalSearchScope.allScope(th
|
|||||||
|
|
||||||
public fun Project.projectScope(): GlobalSearchScope = GlobalSearchScope.projectScope(this)
|
public fun Project.projectScope(): GlobalSearchScope = GlobalSearchScope.projectScope(this)
|
||||||
|
|
||||||
public fun PsiFile.fileScope(): GlobalSearchScope = GlobalSearchScope.fileScope(this)
|
public fun PsiFile.fileScope(): GlobalSearchScope = GlobalSearchScope.fileScope(this)
|
||||||
|
|
||||||
|
public fun SearchScope.restrictToKotlinSources(): SearchScope {
|
||||||
|
return when (this) {
|
||||||
|
is GlobalSearchScope -> GlobalSearchScope.getScopeRestrictedByFileTypes(this, KotlinFileType.INSTANCE)
|
||||||
|
is LocalSearchScope -> {
|
||||||
|
val ktElements = scope.filter { it.containingFile is KtFile }
|
||||||
|
when (ktElements.size) {
|
||||||
|
0 -> GlobalSearchScope.EMPTY_SCOPE
|
||||||
|
scope.size -> this
|
||||||
|
else -> LocalSearchScope(ktElements.toTypedArray())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> this
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,8 +21,10 @@ import com.intellij.psi.PsiElement
|
|||||||
import com.intellij.psi.PsiMethod
|
import com.intellij.psi.PsiMethod
|
||||||
import com.intellij.psi.PsiReference
|
import com.intellij.psi.PsiReference
|
||||||
import com.intellij.psi.search.SearchScope
|
import com.intellij.psi.search.SearchScope
|
||||||
|
import com.intellij.psi.util.MethodSignatureUtil
|
||||||
import org.jetbrains.kotlin.asJava.KotlinLightElement
|
import org.jetbrains.kotlin.asJava.KotlinLightElement
|
||||||
import org.jetbrains.kotlin.asJava.KotlinNoOriginLightMethod
|
import org.jetbrains.kotlin.asJava.KotlinNoOriginLightMethod
|
||||||
|
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.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
@@ -206,21 +208,28 @@ fun PsiReference.isUsageInContainingDeclaration(declaration: KtNamedDeclaration)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun PsiReference.isCallableOverrideUsage(declaration: KtNamedDeclaration): Boolean {
|
fun PsiReference.isCallableOverrideUsage(declaration: KtNamedDeclaration): Boolean {
|
||||||
val toDescriptor: (KtDeclaration) -> DeclarationDescriptor? = { declaration ->
|
val toDescriptor: (KtDeclaration) -> CallableDescriptor? = { declaration ->
|
||||||
if (declaration is KtParameter) {
|
if (declaration is KtParameter) {
|
||||||
// we don't treat parameters in overriding method as "override" here (overriding parameters usages are searched optionally and via searching of overriding methods first)
|
// we don't treat parameters in overriding method as "override" here (overriding parameters usages are searched optionally and via searching of overriding methods first)
|
||||||
if (declaration.hasValOrVar()) declaration.propertyDescriptor else null
|
if (declaration.hasValOrVar()) declaration.propertyDescriptor else null
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
declaration.descriptor
|
declaration.descriptor as? CallableDescriptor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val descriptor = toDescriptor(declaration) ?: return false
|
val targetDescriptor = toDescriptor(declaration) ?: return false
|
||||||
|
|
||||||
return checkUsageVsOriginalDescriptor(descriptor, toDescriptor) { usageDescriptor, targetDescriptor ->
|
return unwrappedTargets.any {
|
||||||
usageDescriptor is CallableDescriptor
|
when (it) {
|
||||||
&& targetDescriptor is CallableDescriptor
|
is KtDeclaration -> {
|
||||||
&& OverrideResolver.overrides(usageDescriptor, targetDescriptor)
|
val usageDescriptor = toDescriptor(it)
|
||||||
|
usageDescriptor != null && OverrideResolver.overrides(usageDescriptor, targetDescriptor)
|
||||||
|
}
|
||||||
|
is PsiMethod -> {
|
||||||
|
declaration.toLightMethods().any { superMethod -> MethodSignatureUtil.isSuperMethod(superMethod, it) }
|
||||||
|
}
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,11 @@ public fun runReadAction<T>(action: () -> T): T {
|
|||||||
return ApplicationManager.getApplication().runReadAction<T>(action)
|
return ApplicationManager.getApplication().runReadAction<T>(action)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fun <T> Project.runReadActionInSmartMode(action: () -> T): T {
|
||||||
|
if (ApplicationManager.getApplication().isReadAccessAllowed) return action()
|
||||||
|
return DumbService.getInstance(this).runReadActionInSmartMode<T>(action)
|
||||||
|
}
|
||||||
|
|
||||||
public fun runWriteAction<T>(action: () -> T): T {
|
public fun runWriteAction<T>(action: () -> T): T {
|
||||||
return ApplicationManager.getApplication().runWriteAction<T>(action)
|
return ApplicationManager.getApplication().runWriteAction<T>(action)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.findUsages
|
package org.jetbrains.kotlin.idea.findUsages
|
||||||
|
|
||||||
|
import com.intellij.find.findUsages.FindUsagesOptions
|
||||||
import com.intellij.find.findUsages.JavaClassFindUsagesOptions
|
import com.intellij.find.findUsages.JavaClassFindUsagesOptions
|
||||||
import com.intellij.find.findUsages.JavaMethodFindUsagesOptions
|
import com.intellij.find.findUsages.JavaMethodFindUsagesOptions
|
||||||
import com.intellij.find.findUsages.JavaVariableFindUsagesOptions
|
import com.intellij.find.findUsages.JavaVariableFindUsagesOptions
|
||||||
@@ -35,6 +36,8 @@ public class KotlinClassFindUsagesOptions(project: Project) : JavaClassFindUsage
|
|||||||
|
|
||||||
public interface KotlinCallableFindUsagesOptions {
|
public interface KotlinCallableFindUsagesOptions {
|
||||||
public var searchOverrides: Boolean
|
public var searchOverrides: Boolean
|
||||||
|
|
||||||
|
fun toJavaOptions(project: Project): FindUsagesOptions?
|
||||||
}
|
}
|
||||||
|
|
||||||
public class KotlinFunctionFindUsagesOptions(project: Project): KotlinCallableFindUsagesOptions, JavaMethodFindUsagesOptions(project) {
|
public class KotlinFunctionFindUsagesOptions(project: Project): KotlinCallableFindUsagesOptions, JavaMethodFindUsagesOptions(project) {
|
||||||
@@ -43,37 +46,36 @@ public class KotlinFunctionFindUsagesOptions(project: Project): KotlinCallableFi
|
|||||||
set(value: Boolean) {
|
set(value: Boolean) {
|
||||||
isOverridingMethods = value
|
isOverridingMethods = value
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fun KotlinFunctionFindUsagesOptions.toJavaMethodOptions(project: Project): JavaMethodFindUsagesOptions {
|
override fun toJavaOptions(project: Project): FindUsagesOptions? {
|
||||||
val javaOptions = JavaMethodFindUsagesOptions(project)
|
val javaOptions = JavaMethodFindUsagesOptions(project)
|
||||||
javaOptions.fastTrack = fastTrack
|
javaOptions.fastTrack = fastTrack
|
||||||
javaOptions.isCheckDeepInheritance = isCheckDeepInheritance
|
javaOptions.isCheckDeepInheritance = isCheckDeepInheritance
|
||||||
javaOptions.isImplementingMethods = isImplementingMethods
|
javaOptions.isImplementingMethods = isImplementingMethods
|
||||||
javaOptions.isIncludeInherited = isIncludeInherited
|
javaOptions.isIncludeInherited = isIncludeInherited
|
||||||
javaOptions.isIncludeOverloadUsages = isIncludeOverloadUsages
|
javaOptions.isIncludeOverloadUsages = isIncludeOverloadUsages
|
||||||
javaOptions.isOverridingMethods = isOverridingMethods
|
javaOptions.isOverridingMethods = isOverridingMethods
|
||||||
javaOptions.isSearchForTextOccurrences = isSearchForTextOccurrences
|
javaOptions.isSearchForTextOccurrences = isSearchForTextOccurrences
|
||||||
javaOptions.isSkipImportStatements = isSkipImportStatements
|
javaOptions.isSkipImportStatements = isSkipImportStatements
|
||||||
javaOptions.isUsages = isUsages
|
javaOptions.isUsages = isUsages
|
||||||
javaOptions.searchScope = searchScope
|
javaOptions.searchScope = searchScope
|
||||||
|
|
||||||
return javaOptions
|
|
||||||
}
|
|
||||||
|
|
||||||
fun KotlinPropertyFindUsagesOptions.toJavaVariableOptions(project: Project): JavaVariableFindUsagesOptions {
|
return javaOptions
|
||||||
val javaOptions = JavaVariableFindUsagesOptions(project)
|
}
|
||||||
javaOptions.fastTrack = fastTrack
|
|
||||||
javaOptions.isSearchForTextOccurrences = isSearchForTextOccurrences
|
|
||||||
javaOptions.isSkipImportStatements = isSkipImportStatements
|
|
||||||
javaOptions.isReadAccess = isReadAccess
|
|
||||||
javaOptions.isWriteAccess = isWriteAccess
|
|
||||||
javaOptions.isUsages = isUsages
|
|
||||||
javaOptions.searchScope = searchScope
|
|
||||||
return javaOptions
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class KotlinPropertyFindUsagesOptions(project: Project): KotlinCallableFindUsagesOptions, JavaVariableFindUsagesOptions(project) {
|
public class KotlinPropertyFindUsagesOptions(project: Project): KotlinCallableFindUsagesOptions, JavaVariableFindUsagesOptions(project) {
|
||||||
override var searchOverrides: Boolean = false
|
override var searchOverrides: Boolean = false
|
||||||
}
|
|
||||||
|
|
||||||
|
override fun toJavaOptions(project: Project): JavaVariableFindUsagesOptions {
|
||||||
|
val javaOptions = JavaVariableFindUsagesOptions(project)
|
||||||
|
javaOptions.fastTrack = fastTrack
|
||||||
|
javaOptions.isSearchForTextOccurrences = isSearchForTextOccurrences
|
||||||
|
javaOptions.isSkipImportStatements = isSkipImportStatements
|
||||||
|
javaOptions.isReadAccess = isReadAccess
|
||||||
|
javaOptions.isWriteAccess = isWriteAccess
|
||||||
|
javaOptions.isUsages = isUsages
|
||||||
|
javaOptions.searchScope = searchScope
|
||||||
|
return javaOptions
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-8
@@ -47,15 +47,9 @@ class DelegatingFindMemberUsagesHandler(
|
|||||||
is KtNamedDeclaration ->
|
is KtNamedDeclaration ->
|
||||||
HandlerAndOptions(KotlinFindMemberUsagesHandler.getInstance(element, elementsToSearch, factory), options)
|
HandlerAndOptions(KotlinFindMemberUsagesHandler.getInstance(element, elementsToSearch, factory), options)
|
||||||
|
|
||||||
is PsiMethod ->
|
is PsiMethod, is PsiParameter ->
|
||||||
/* Can't have KotlinPropertyFindUsagesOptions here since Kotlin properties do not override java methods, so
|
|
||||||
* elementsToSearch contains property declarations only */
|
|
||||||
HandlerAndOptions(JavaFindUsagesHandler(element, elementsToSearch.toTypedArray(), factory.javaHandlerFactory),
|
HandlerAndOptions(JavaFindUsagesHandler(element, elementsToSearch.toTypedArray(), factory.javaHandlerFactory),
|
||||||
(options as KotlinFunctionFindUsagesOptions?)?.toJavaMethodOptions(project))
|
(options as KotlinCallableFindUsagesOptions?)?.toJavaOptions(project))
|
||||||
|
|
||||||
is PsiParameter ->
|
|
||||||
HandlerAndOptions(JavaFindUsagesHandler(element, elementsToSearch.toTypedArray(), factory.javaHandlerFactory),
|
|
||||||
(options as KotlinPropertyFindUsagesOptions?)?.toJavaVariableOptions(project))
|
|
||||||
|
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-12
@@ -21,13 +21,11 @@ import com.intellij.find.findUsages.AbstractFindUsagesDialog
|
|||||||
import com.intellij.find.findUsages.FindUsagesOptions
|
import com.intellij.find.findUsages.FindUsagesOptions
|
||||||
import com.intellij.openapi.actionSystem.DataContext
|
import com.intellij.openapi.actionSystem.DataContext
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiMethod
|
|
||||||
import com.intellij.psi.PsiReference
|
import com.intellij.psi.PsiReference
|
||||||
import com.intellij.psi.search.searches.MethodReferencesSearch
|
import com.intellij.psi.search.searches.MethodReferencesSearch
|
||||||
import com.intellij.psi.search.searches.ReferencesSearch
|
import com.intellij.psi.search.searches.ReferencesSearch
|
||||||
import com.intellij.usageView.UsageInfo
|
import com.intellij.usageView.UsageInfo
|
||||||
import com.intellij.util.*
|
import com.intellij.util.*
|
||||||
import org.jetbrains.kotlin.asJava.LightClassUtil
|
|
||||||
import org.jetbrains.kotlin.asJava.toLightMethods
|
import org.jetbrains.kotlin.asJava.toLightMethods
|
||||||
import org.jetbrains.kotlin.idea.findUsages.KotlinCallableFindUsagesOptions
|
import org.jetbrains.kotlin.idea.findUsages.KotlinCallableFindUsagesOptions
|
||||||
import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory
|
import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory
|
||||||
@@ -128,17 +126,14 @@ public abstract class KotlinFindMemberUsagesHandler<T : KtNamedDeclaration>
|
|||||||
scope = options.searchScope,
|
scope = options.searchScope,
|
||||||
kotlinOptions = createKotlinReferencesSearchOptions(options))
|
kotlinOptions = createKotlinReferencesSearchOptions(options))
|
||||||
|
|
||||||
val query = applyQueryFilters(element, options, ReferencesSearch.search(searchParameters))
|
with(applyQueryFilters(element, options, ReferencesSearch.search(searchParameters))) {
|
||||||
if (!query.forEach(referenceProcessor)) return false
|
if (!forEach(referenceProcessor)) return false
|
||||||
|
|
||||||
val psiMethods = when (element) {
|
|
||||||
is PsiMethod -> listOf(element)
|
|
||||||
is KtFunction -> runReadAction { LightClassUtil.getLightClassMethods(element) }
|
|
||||||
else -> listOf<PsiMethod>()
|
|
||||||
}
|
}
|
||||||
for (psiMethod in psiMethods) {
|
|
||||||
val query = applyQueryFilters(element, options, MethodReferencesSearch.search(psiMethod, options.searchScope, true))
|
for (psiMethod in runReadAction { element.toLightMethods() }) {
|
||||||
if (!query.forEach(referenceProcessor)) return false
|
with(applyQueryFilters(element, options, MethodReferencesSearch.search(psiMethod, options.searchScope, true))) {
|
||||||
|
if (!forEach(referenceProcessor)) return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+53
-12
@@ -16,31 +16,72 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.search.ideaExtensions
|
package org.jetbrains.kotlin.idea.search.ideaExtensions
|
||||||
|
|
||||||
import com.intellij.openapi.application.QueryExecutorBase
|
import com.intellij.psi.*
|
||||||
import com.intellij.psi.PsiClass
|
|
||||||
import com.intellij.psi.PsiElement
|
|
||||||
import com.intellij.psi.PsiMethod
|
|
||||||
import com.intellij.psi.PsiReference
|
|
||||||
import com.intellij.psi.impl.search.MethodTextOccurrenceProcessor
|
import com.intellij.psi.impl.search.MethodTextOccurrenceProcessor
|
||||||
import com.intellij.psi.impl.search.MethodUsagesSearcher
|
import com.intellij.psi.impl.search.MethodUsagesSearcher
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import com.intellij.psi.search.UsageSearchContext
|
||||||
import com.intellij.psi.search.searches.MethodReferencesSearch
|
import com.intellij.psi.search.searches.MethodReferencesSearch
|
||||||
import com.intellij.util.Processor
|
import com.intellij.util.Processor
|
||||||
import org.jetbrains.kotlin.asJava.KotlinLightMethod
|
|
||||||
import org.jetbrains.kotlin.asJava.getRepresentativeLightMethod
|
|
||||||
import org.jetbrains.kotlin.asJava.toLightMethods
|
import org.jetbrains.kotlin.asJava.toLightMethods
|
||||||
|
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
||||||
|
import org.jetbrains.kotlin.idea.references.readWriteAccess
|
||||||
|
import org.jetbrains.kotlin.idea.search.restrictToKotlinSources
|
||||||
|
import org.jetbrains.kotlin.idea.util.application.runReadActionInSmartMode
|
||||||
|
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||||
|
import org.jetbrains.kotlin.load.java.getPropertyNamesCandidatesByAccessorName
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtCallableDeclaration
|
import org.jetbrains.kotlin.psi.KtCallableDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtParameter
|
||||||
import org.jetbrains.kotlin.psi.KtFunction
|
import org.jetbrains.kotlin.psi.KtProperty
|
||||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
import org.jetbrains.kotlin.utils.ifEmpty
|
||||||
|
|
||||||
public class KotlinOverridingMethodReferenceSearcher : MethodUsagesSearcher() {
|
public class KotlinOverridingMethodReferenceSearcher : MethodUsagesSearcher() {
|
||||||
|
override fun processQuery(p: MethodReferencesSearch.SearchParameters, consumer: Processor<PsiReference>) {
|
||||||
|
super.processQuery(p, consumer)
|
||||||
|
|
||||||
|
val method = p.method
|
||||||
|
p.project.runReadActionInSmartMode {
|
||||||
|
val containingClass = method.containingClass ?: return@runReadActionInSmartMode
|
||||||
|
|
||||||
|
val searchScope = p.effectiveSearchScope
|
||||||
|
.intersectWith(method.useScope)
|
||||||
|
.restrictToKotlinSources()
|
||||||
|
if (searchScope === GlobalSearchScope.EMPTY_SCOPE) return@runReadActionInSmartMode
|
||||||
|
|
||||||
|
for (name in getPropertyNamesCandidatesByAccessorName(Name.guess(method.name))) {
|
||||||
|
p.optimizer.searchWord(
|
||||||
|
name.asString(),
|
||||||
|
searchScope,
|
||||||
|
UsageSearchContext.IN_CODE,
|
||||||
|
true,
|
||||||
|
method,
|
||||||
|
getTextOccurrenceProcessor(arrayOf(method), containingClass, false)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun getTextOccurrenceProcessor(methods: Array<out PsiMethod>,
|
override fun getTextOccurrenceProcessor(methods: Array<out PsiMethod>,
|
||||||
aClass: PsiClass,
|
aClass: PsiClass,
|
||||||
strictSignatureSearch: Boolean): MethodTextOccurrenceProcessor? {
|
strictSignatureSearch: Boolean): MethodTextOccurrenceProcessor {
|
||||||
return object: MethodTextOccurrenceProcessor(aClass, strictSignatureSearch, *methods) {
|
return object: MethodTextOccurrenceProcessor(aClass, strictSignatureSearch, *methods) {
|
||||||
override fun processInexactReference(ref: PsiReference, refElement: PsiElement?, method: PsiMethod, consumer: Processor<PsiReference>): Boolean {
|
override fun processInexactReference(ref: PsiReference, refElement: PsiElement?, method: PsiMethod, consumer: Processor<PsiReference>): Boolean {
|
||||||
if (refElement !is KtCallableDeclaration) return true
|
if (refElement !is KtCallableDeclaration) return true
|
||||||
return refElement.getRepresentativeLightMethod()?.let { super.processInexactReference(ref, it, method, consumer) } ?: true
|
|
||||||
|
var lightMethods = refElement.toLightMethods()
|
||||||
|
.filterNot { it.hasModifierProperty(PsiModifier.FINAL) }
|
||||||
|
.ifEmpty { return true }
|
||||||
|
if (refElement is KtProperty || refElement is KtParameter) {
|
||||||
|
val isGetter = JvmAbi.isGetterName(method.name)
|
||||||
|
if (ref is KtSimpleNameReference) {
|
||||||
|
val readWriteAccess = ref.expression.readWriteAccess(true)
|
||||||
|
if (readWriteAccess.isRead != isGetter && readWriteAccess.isWrite == isGetter) return true
|
||||||
|
}
|
||||||
|
lightMethods = lightMethods.filter { JvmAbi.isGetterName(it.name) == isGetter }
|
||||||
|
}
|
||||||
|
|
||||||
|
return lightMethods.all { super.processInexactReference(ref, it, method, consumer) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-11
@@ -19,14 +19,12 @@ package org.jetbrains.kotlin.idea.search.ideaExtensions
|
|||||||
import com.intellij.openapi.application.QueryExecutorBase
|
import com.intellij.openapi.application.QueryExecutorBase
|
||||||
import com.intellij.psi.PsiMethod
|
import com.intellij.psi.PsiMethod
|
||||||
import com.intellij.psi.PsiReference
|
import com.intellij.psi.PsiReference
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
|
||||||
import com.intellij.psi.search.SearchScope
|
|
||||||
import com.intellij.psi.search.UsageSearchContext
|
import com.intellij.psi.search.UsageSearchContext
|
||||||
import com.intellij.psi.search.searches.MethodReferencesSearch
|
import com.intellij.psi.search.searches.MethodReferencesSearch
|
||||||
import com.intellij.util.Processor
|
import com.intellij.util.Processor
|
||||||
import org.jetbrains.kotlin.asJava.namedUnwrappedElement
|
import org.jetbrains.kotlin.asJava.namedUnwrappedElement
|
||||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.getJavaMethodDescriptor
|
import org.jetbrains.kotlin.idea.caches.resolve.getJavaMethodDescriptor
|
||||||
|
import org.jetbrains.kotlin.idea.search.restrictToKotlinSources
|
||||||
import org.jetbrains.kotlin.psi.KtProperty
|
import org.jetbrains.kotlin.psi.KtProperty
|
||||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||||
import org.jetbrains.kotlin.synthetic.JavaSyntheticPropertiesScope
|
import org.jetbrains.kotlin.synthetic.JavaSyntheticPropertiesScope
|
||||||
@@ -37,7 +35,7 @@ public class KotlinPropertyAccessorsReferenceSearcher() : QueryExecutorBase<PsiR
|
|||||||
val method = queryParameters.getMethod()
|
val method = queryParameters.getMethod()
|
||||||
val propertyName = propertyName(method) ?: return
|
val propertyName = propertyName(method) ?: return
|
||||||
|
|
||||||
val onlyKotlinFiles = restrictToKotlinSources(queryParameters.getEffectiveSearchScope())
|
val onlyKotlinFiles = queryParameters.getEffectiveSearchScope().restrictToKotlinSources()
|
||||||
|
|
||||||
queryParameters.getOptimizer()!!.searchWord(
|
queryParameters.getOptimizer()!!.searchWord(
|
||||||
propertyName,
|
propertyName,
|
||||||
@@ -58,11 +56,4 @@ public class KotlinPropertyAccessorsReferenceSearcher() : QueryExecutorBase<PsiR
|
|||||||
val property = SyntheticJavaPropertyDescriptor.findByGetterOrSetter(functionDescriptor, syntheticExtensionsScope) ?: return null
|
val property = SyntheticJavaPropertyDescriptor.findByGetterOrSetter(functionDescriptor, syntheticExtensionsScope) ?: return null
|
||||||
return property.getName().asString()
|
return property.getName().asString()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun restrictToKotlinSources(originalScope: SearchScope): SearchScope {
|
|
||||||
return when (originalScope) {
|
|
||||||
is GlobalSearchScope -> GlobalSearchScope.getScopeRestrictedByFileTypes(originalScope, KotlinFileType.INSTANCE)
|
|
||||||
else -> originalScope
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
// PSI_ELEMENT: com.intellij.psi.PsiMethod
|
||||||
|
// OPTIONS: usages
|
||||||
|
public class J extends A {
|
||||||
|
@Override
|
||||||
|
public int <caret>getP() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setP(int value) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
static void test() {
|
||||||
|
new A().getP();
|
||||||
|
new A().setP(1);
|
||||||
|
|
||||||
|
new AA().getP();
|
||||||
|
new AA().setP(1);
|
||||||
|
|
||||||
|
new J().getP();
|
||||||
|
new J().setP(1);
|
||||||
|
|
||||||
|
new B().getP();
|
||||||
|
new B().setP(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
open class A {
|
||||||
|
open var p: Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
class AA : A() {
|
||||||
|
override var p: Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
class B : J() {
|
||||||
|
override var p: Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val t = A().p
|
||||||
|
A().p = 1
|
||||||
|
|
||||||
|
val t = AA().p
|
||||||
|
AA().p = 1
|
||||||
|
|
||||||
|
val t = J().p
|
||||||
|
J().p = 1
|
||||||
|
|
||||||
|
val t = B().p
|
||||||
|
B().p = 1
|
||||||
|
}
|
||||||
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
[javaPropertyGetterUsagesKJ.0.java] Unclassified usage (23: 17) new J().getP();
|
||||||
|
[javaPropertyGetterUsagesKJ.0.java] Unclassified usage (26: 17) new B().getP();
|
||||||
|
[javaPropertyGetterUsagesKJ.1.kt] Value read (20: 17) val t = J().p
|
||||||
|
[javaPropertyGetterUsagesKJ.1.kt] Value read (23: 17) val t = B().p
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
// PSI_ELEMENT: com.intellij.psi.PsiMethod
|
||||||
|
// OPTIONS: usages
|
||||||
|
public class J extends A {
|
||||||
|
@Override
|
||||||
|
public int getP() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void <caret>setP(int value) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
static void test() {
|
||||||
|
new A().getP();
|
||||||
|
new A().setP(1);
|
||||||
|
|
||||||
|
new AA().getP();
|
||||||
|
new AA().setP(1);
|
||||||
|
|
||||||
|
new J().getP();
|
||||||
|
new J().setP(1);
|
||||||
|
|
||||||
|
new B().getP();
|
||||||
|
new B().setP(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
open class A {
|
||||||
|
open var p: Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
class AA : A() {
|
||||||
|
override var p: Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
class B : J() {
|
||||||
|
override var p: Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val t = A().p
|
||||||
|
A().p = 1
|
||||||
|
|
||||||
|
val t = AA().p
|
||||||
|
AA().p = 1
|
||||||
|
|
||||||
|
val t = J().p
|
||||||
|
J().p = 1
|
||||||
|
|
||||||
|
val t = B().p
|
||||||
|
B().p = 1
|
||||||
|
}
|
||||||
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
[javaPropertySetterUsagesKJ.0.java] Unclassified usage (24: 17) new J().setP(1);
|
||||||
|
[javaPropertySetterUsagesKJ.0.java] Unclassified usage (27: 17) new B().setP(1);
|
||||||
|
[javaPropertySetterUsagesKJ.1.kt] Value write (21: 9) J().p = 1
|
||||||
|
[javaPropertySetterUsagesKJ.1.kt] Value write (24: 9) B().p = 1
|
||||||
+2
-1
@@ -1,8 +1,9 @@
|
|||||||
// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtNamedFunction
|
// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtNamedFunction
|
||||||
// OPTIONS: usages
|
// OPTIONS: usages
|
||||||
|
// FIND_BY_REF
|
||||||
|
|
||||||
class A(val n: Int) {
|
class A(val n: Int) {
|
||||||
override fun <caret>equals(other: Any?): Boolean = other is A && other.n == n
|
override fun equals(other: Any?): Boolean = other is A && other.n <caret>== n
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Function call (10: 10) A(0) != A(1)
|
Function call (10: 10) A(0) == A(1)
|
||||||
Function call (11: 10) A(0) equals A(1)
|
Function call (11: 10) A(0) != A(1)
|
||||||
Function call (5: 71) override fun equals(other: Any?): Boolean = other is A && other.n == n
|
Function call (12: 10) A(0) equals A(1)
|
||||||
Function call (9: 10) A(0) == A(1)
|
Function call (6: 71) override fun equals(other: Any?): Boolean = other is A && other.n == n
|
||||||
+2
-2
@@ -6,11 +6,11 @@ interface A {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class B: A {
|
class B: A {
|
||||||
override fun <caret>foo() {} // Find usages gives no results
|
override fun foo() {} // Find usages gives no results
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main(a: A) {
|
fun main(a: A) {
|
||||||
a.foo()
|
a.<caret>foo()
|
||||||
}
|
}
|
||||||
|
|
||||||
// for KT-3769 Find usages gives no result for overrides
|
// for KT-3769 Find usages gives no result for overrides
|
||||||
|
|||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtProperty
|
||||||
|
// OPTIONS: usages
|
||||||
|
open class A {
|
||||||
|
open var <caret>p: Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
class AA : A() {
|
||||||
|
override var p: Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
class B : J() {
|
||||||
|
override var p: Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val t = A().p
|
||||||
|
A().p = 1
|
||||||
|
|
||||||
|
val t = AA().p
|
||||||
|
AA().p = 1
|
||||||
|
|
||||||
|
val t = J().p
|
||||||
|
J().p = 1
|
||||||
|
|
||||||
|
val t = B().p
|
||||||
|
B().p = 1
|
||||||
|
}
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
public class J extends A {
|
||||||
|
@Override
|
||||||
|
public int getP() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setP(int value) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
static void test() {
|
||||||
|
new A().getP();
|
||||||
|
new A().setP(1);
|
||||||
|
|
||||||
|
new AA().getP();
|
||||||
|
new AA().setP(1);
|
||||||
|
|
||||||
|
new J().getP();
|
||||||
|
new J().setP(1);
|
||||||
|
|
||||||
|
new B().getP();
|
||||||
|
new B().setP(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
[javaPropertyUsagesK.0.kt] Value read (16: 17) val t = A().p
|
||||||
|
[javaPropertyUsagesK.0.kt] Value read (19: 18) val t = AA().p
|
||||||
|
[javaPropertyUsagesK.0.kt] Value read (22: 17) val t = J().p
|
||||||
|
[javaPropertyUsagesK.0.kt] Value read (25: 17) val t = B().p
|
||||||
|
[javaPropertyUsagesK.0.kt] Value write (17: 9) A().p = 1
|
||||||
|
[javaPropertyUsagesK.0.kt] Value write (20: 10) AA().p = 1
|
||||||
|
[javaPropertyUsagesK.0.kt] Value write (23: 9) J().p = 1
|
||||||
|
[javaPropertyUsagesK.0.kt] Value write (26: 9) B().p = 1
|
||||||
|
[javaPropertyUsagesK.1.java] Unclassified usage (15: 17) new A().getP();
|
||||||
|
[javaPropertyUsagesK.1.java] Unclassified usage (16: 17) new A().setP(1);
|
||||||
|
[javaPropertyUsagesK.1.java] Unclassified usage (18: 18) new AA().getP();
|
||||||
|
[javaPropertyUsagesK.1.java] Unclassified usage (19: 18) new AA().setP(1);
|
||||||
|
[javaPropertyUsagesK.1.java] Unclassified usage (21: 17) new J().getP();
|
||||||
|
[javaPropertyUsagesK.1.java] Unclassified usage (22: 17) new J().setP(1);
|
||||||
|
[javaPropertyUsagesK.1.java] Unclassified usage (24: 17) new B().getP();
|
||||||
|
[javaPropertyUsagesK.1.java] Unclassified usage (25: 17) new B().setP(1);
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtProperty
|
||||||
|
// OPTIONS: usages
|
||||||
|
open class A {
|
||||||
|
open var p: Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
class AA : A() {
|
||||||
|
override var p: Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
class B : J() {
|
||||||
|
override var <caret>p: Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val t = A().p
|
||||||
|
A().p = 1
|
||||||
|
|
||||||
|
val t = AA().p
|
||||||
|
AA().p = 1
|
||||||
|
|
||||||
|
val t = J().p
|
||||||
|
J().p = 1
|
||||||
|
|
||||||
|
val t = B().p
|
||||||
|
B().p = 1
|
||||||
|
}
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
public class J extends A {
|
||||||
|
@Override
|
||||||
|
public int getP() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setP(int value) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
static void test() {
|
||||||
|
new A().getP();
|
||||||
|
new A().setP(1);
|
||||||
|
|
||||||
|
new AA().getP();
|
||||||
|
new AA().setP(1);
|
||||||
|
|
||||||
|
new J().getP();
|
||||||
|
new J().setP(1);
|
||||||
|
|
||||||
|
new B().getP();
|
||||||
|
new B().setP(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
[javaPropertyUsagesKJK.0.kt] Value read (25: 17) val t = B().p
|
||||||
|
[javaPropertyUsagesKJK.0.kt] Value write (26: 9) B().p = 1
|
||||||
|
[javaPropertyUsagesKJK.1.java] Unclassified usage (24: 17) new B().getP();
|
||||||
|
[javaPropertyUsagesKJK.1.java] Unclassified usage (25: 17) new B().setP(1);
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtProperty
|
||||||
|
// OPTIONS: usages
|
||||||
|
open class A {
|
||||||
|
open var p: Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
class AA : A() {
|
||||||
|
override var <caret>p: Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
class B : J() {
|
||||||
|
override var p: Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val t = A().p
|
||||||
|
A().p = 1
|
||||||
|
|
||||||
|
val t = AA().p
|
||||||
|
AA().p = 1
|
||||||
|
|
||||||
|
val t = J().p
|
||||||
|
J().p = 1
|
||||||
|
|
||||||
|
val t = B().p
|
||||||
|
B().p = 1
|
||||||
|
}
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
public class J extends A {
|
||||||
|
@Override
|
||||||
|
public int getP() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setP(int value) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
static void test() {
|
||||||
|
new A().getP();
|
||||||
|
new A().setP(1);
|
||||||
|
|
||||||
|
new AA().getP();
|
||||||
|
new AA().setP(1);
|
||||||
|
|
||||||
|
new J().getP();
|
||||||
|
new J().setP(1);
|
||||||
|
|
||||||
|
new B().getP();
|
||||||
|
new B().setP(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
[javaPropertyUsagesKK.0.kt] Value read (19: 18) val t = AA().p
|
||||||
|
[javaPropertyUsagesKK.0.kt] Value write (20: 10) AA().p = 1
|
||||||
|
[javaPropertyUsagesKK.1.java] Unclassified usage (18: 18) new AA().getP();
|
||||||
|
[javaPropertyUsagesKK.1.java] Unclassified usage (19: 18) new AA().setP(1);
|
||||||
@@ -34,7 +34,6 @@ import com.intellij.openapi.util.io.FileUtil;
|
|||||||
import com.intellij.openapi.util.io.FileUtilRt;
|
import com.intellij.openapi.util.io.FileUtilRt;
|
||||||
import com.intellij.openapi.util.text.StringUtil;
|
import com.intellij.openapi.util.text.StringUtil;
|
||||||
import com.intellij.psi.*;
|
import com.intellij.psi.*;
|
||||||
import com.intellij.psi.PsiPackage;
|
|
||||||
import com.intellij.psi.search.GlobalSearchScope;
|
import com.intellij.psi.search.GlobalSearchScope;
|
||||||
import com.intellij.psi.util.PsiTreeUtil;
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
import com.intellij.testFramework.LightProjectDescriptor;
|
import com.intellij.testFramework.LightProjectDescriptor;
|
||||||
@@ -53,6 +52,7 @@ import kotlin.jvm.functions.Function1;
|
|||||||
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.findUsages.KotlinClassFindUsagesOptions;
|
import org.jetbrains.kotlin.idea.findUsages.KotlinClassFindUsagesOptions;
|
||||||
|
import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory;
|
||||||
import org.jetbrains.kotlin.idea.findUsages.KotlinFunctionFindUsagesOptions;
|
import org.jetbrains.kotlin.idea.findUsages.KotlinFunctionFindUsagesOptions;
|
||||||
import org.jetbrains.kotlin.idea.findUsages.KotlinPropertyFindUsagesOptions;
|
import org.jetbrains.kotlin.idea.findUsages.KotlinPropertyFindUsagesOptions;
|
||||||
import org.jetbrains.kotlin.idea.test.JetLightCodeInsightFixtureTestCase;
|
import org.jetbrains.kotlin.idea.test.JetLightCodeInsightFixtureTestCase;
|
||||||
@@ -433,8 +433,17 @@ public abstract class AbstractJetFindUsagesTest extends JetLightCodeInsightFixtu
|
|||||||
|
|
||||||
protected Collection<UsageInfo> findUsages(@NotNull PsiElement targetElement, @Nullable FindUsagesOptions options) {
|
protected Collection<UsageInfo> findUsages(@NotNull PsiElement targetElement, @Nullable FindUsagesOptions options) {
|
||||||
Project project = getProject();
|
Project project = getProject();
|
||||||
FindUsagesHandler handler =
|
|
||||||
((FindManagerImpl) FindManager.getInstance(project)).getFindUsagesManager().getFindUsagesHandler(targetElement, false);
|
FindUsagesHandler handler;
|
||||||
|
if (targetElement instanceof PsiMember) {
|
||||||
|
handler = new JavaFindUsagesHandler(targetElement, new JavaFindUsagesHandlerFactory(project));
|
||||||
|
}
|
||||||
|
else if (targetElement instanceof KtDeclaration) {
|
||||||
|
handler = new KotlinFindUsagesHandlerFactory(project).createFindUsagesHandlerNoQuestions(targetElement);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
handler = ((FindManagerImpl) FindManager.getInstance(project)).getFindUsagesManager().getFindUsagesHandler(targetElement, false);
|
||||||
|
}
|
||||||
assert handler != null : "Cannot find handler for: " + targetElement;
|
assert handler != null : "Cannot find handler for: " + targetElement;
|
||||||
|
|
||||||
if (options == null) {
|
if (options == null) {
|
||||||
|
|||||||
@@ -685,6 +685,33 @@ public class JetFindUsagesTestGenerated extends AbstractJetFindUsagesTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/findUsages/kotlin/findJavaPropertyUsages")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class FindJavaPropertyUsages extends AbstractJetFindUsagesTest {
|
||||||
|
public void testAllFilesPresentInFindJavaPropertyUsages() throws Exception {
|
||||||
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/findUsages/kotlin/findJavaPropertyUsages"), Pattern.compile("^(.+)\\.0\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("javaPropertyUsagesK.0.kt")
|
||||||
|
public void testJavaPropertyUsagesK() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/kotlin/findJavaPropertyUsages/javaPropertyUsagesK.0.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("javaPropertyUsagesKJK.0.kt")
|
||||||
|
public void testJavaPropertyUsagesKJK() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/kotlin/findJavaPropertyUsages/javaPropertyUsagesKJK.0.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("javaPropertyUsagesKK.0.kt")
|
||||||
|
public void testJavaPropertyUsagesKK() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/kotlin/findJavaPropertyUsages/javaPropertyUsagesKK.0.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/findUsages/kotlin/findObjectUsages")
|
@TestMetadata("idea/testData/findUsages/kotlin/findObjectUsages")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
@@ -1341,6 +1368,27 @@ public class JetFindUsagesTestGenerated extends AbstractJetFindUsagesTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/findUsages/java/findJavaPropertyUsages")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class FindJavaPropertyUsages extends AbstractJetFindUsagesTest {
|
||||||
|
public void testAllFilesPresentInFindJavaPropertyUsages() throws Exception {
|
||||||
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/findUsages/java/findJavaPropertyUsages"), Pattern.compile("^(.+)\\.0\\.java$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("javaPropertyGetterUsagesKJ.0.java")
|
||||||
|
public void testJavaPropertyGetterUsagesKJ() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/java/findJavaPropertyUsages/javaPropertyGetterUsagesKJ.0.java");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("javaPropertySetterUsagesKJ.0.java")
|
||||||
|
public void testJavaPropertySetterUsagesKJ() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/java/findJavaPropertyUsages/javaPropertySetterUsagesKJ.0.java");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/findUsages/propertyFiles")
|
@TestMetadata("idea/testData/findUsages/propertyFiles")
|
||||||
|
|||||||
Reference in New Issue
Block a user