Find Usages: Look for as-property usages of Java methods

This commit is contained in:
Alexey Sedunov
2015-10-21 12:44:59 +03:00
committed by Alexey Sedunov
parent 7e9222f70a
commit 9c360ef05a
34 changed files with 555 additions and 108 deletions
@@ -1047,7 +1047,7 @@ public class DescriptorResolver {
else if (property.isVar()) {
Annotations setterAnnotations = annotationSplitter.getAnnotationsForTarget(PROPERTY_SETTER);
setterDescriptor = DescriptorFactory.createSetter(propertyDescriptor, setterAnnotations, !property.hasDelegate(),
/* isExternal = */ false);
/* isExternal = */ false, propertyDescriptor.getSource());
}
if (!property.isVar()) {
@@ -76,7 +76,7 @@ public class JavaPropertyDescriptor extends PropertyDescriptorImpl implements Ja
if (getter != null) {
newGetter = new PropertyGetterDescriptorImpl(
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);
}
@@ -85,7 +85,7 @@ public class JavaPropertyDescriptor extends PropertyDescriptorImpl implements Ja
if (setter != null) {
newSetter = new PropertySetterDescriptorImpl(
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));
}
@@ -322,7 +322,7 @@ public class LazyJavaClassMemberScope(
val setter = setterMethod?.let { setterMethod ->
DescriptorFactory.createSetter(propertyDescriptor, setterMethod.annotations, /* isDefault = */false,
/* isExternal = */ false, setterMethod.visibility)
/* isExternal = */ false, setterMethod.visibility, setterMethod.source)
}
return propertyDescriptor.apply { initialize(getter, setter) }
@@ -50,17 +50,7 @@ public class DescriptorFactory {
@NotNull PropertyDescriptor propertyDescriptor,
@NotNull Annotations annotations
) {
return createSetter(propertyDescriptor, annotations, true, false);
}
@NotNull
public static PropertySetterDescriptorImpl createSetter(
@NotNull PropertyDescriptor propertyDescriptor,
@NotNull Annotations annotations,
boolean isDefault,
boolean isExternal
) {
return createSetter(propertyDescriptor, annotations, isDefault, isExternal, propertyDescriptor.getVisibility());
return createSetter(propertyDescriptor, annotations, true, false, propertyDescriptor.getSource());
}
@NotNull
@@ -69,12 +59,24 @@ public class DescriptorFactory {
@NotNull Annotations annotations,
boolean isDefault,
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 =
new PropertySetterDescriptorImpl(propertyDescriptor, annotations, propertyDescriptor.getModality(),
visibility, !isDefault, isDefault, isExternal,
CallableMemberDescriptor.Kind.DECLARATION, null, propertyDescriptor.getSource());
CallableMemberDescriptor.Kind.DECLARATION, null, sourceElement);
setterDescriptor.initializeDefault();
return setterDescriptor;
}
@@ -21,12 +21,15 @@ import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiElement
import com.intellij.psi.util.PsiTreeUtil
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.intentions.OperatorToFunctionIntention
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
import org.jetbrains.kotlin.idea.util.ShortenReferences
import org.jetbrains.kotlin.lexer.KtToken
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.Name
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.getQualifiedElementSelector
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.dataClassUtils.isComponentLike
import org.jetbrains.kotlin.types.expressions.OperatorConventions
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 {
if (element != null) {
if (!canBeReferenceTo(element)) return false
@@ -148,8 +148,8 @@ val KtElement.mainReference: KtReference?
// ----------- Read/write access -----------------------------------------------------------------------------------------------------------------------
public enum class ReferenceAccess {
READ, WRITE, READ_WRITE
public enum class ReferenceAccess(val isRead: Boolean, val isWrite: Boolean) {
READ(true, false), WRITE(false, true), READ_WRITE(true, true)
}
public fun KtExpression.readWriteAccess(useResolveForReadWrite: Boolean): ReferenceAccess {
@@ -16,10 +16,13 @@
package org.jetbrains.kotlin.idea.search
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiFile
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.LocalSearchScope
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.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 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.PsiReference
import com.intellij.psi.search.SearchScope
import com.intellij.psi.util.MethodSignatureUtil
import org.jetbrains.kotlin.asJava.KotlinLightElement
import org.jetbrains.kotlin.asJava.KotlinNoOriginLightMethod
import org.jetbrains.kotlin.asJava.toLightMethods
import org.jetbrains.kotlin.asJava.unwrapped
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.caches.resolve.analyze
@@ -206,21 +208,28 @@ fun PsiReference.isUsageInContainingDeclaration(declaration: KtNamedDeclaration)
}
fun PsiReference.isCallableOverrideUsage(declaration: KtNamedDeclaration): Boolean {
val toDescriptor: (KtDeclaration) -> DeclarationDescriptor? = { declaration ->
val toDescriptor: (KtDeclaration) -> CallableDescriptor? = { declaration ->
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)
if (declaration.hasValOrVar()) declaration.propertyDescriptor else null
}
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 ->
usageDescriptor is CallableDescriptor
&& targetDescriptor is CallableDescriptor
&& OverrideResolver.overrides(usageDescriptor, targetDescriptor)
return unwrappedTargets.any {
when (it) {
is KtDeclaration -> {
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)
}
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 {
return ApplicationManager.getApplication().runWriteAction<T>(action)
}
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.idea.findUsages
import com.intellij.find.findUsages.FindUsagesOptions
import com.intellij.find.findUsages.JavaClassFindUsagesOptions
import com.intellij.find.findUsages.JavaMethodFindUsagesOptions
import com.intellij.find.findUsages.JavaVariableFindUsagesOptions
@@ -35,6 +36,8 @@ public class KotlinClassFindUsagesOptions(project: Project) : JavaClassFindUsage
public interface KotlinCallableFindUsagesOptions {
public var searchOverrides: Boolean
fun toJavaOptions(project: Project): FindUsagesOptions?
}
public class KotlinFunctionFindUsagesOptions(project: Project): KotlinCallableFindUsagesOptions, JavaMethodFindUsagesOptions(project) {
@@ -43,37 +46,36 @@ public class KotlinFunctionFindUsagesOptions(project: Project): KotlinCallableFi
set(value: Boolean) {
isOverridingMethods = value
}
}
fun KotlinFunctionFindUsagesOptions.toJavaMethodOptions(project: Project): JavaMethodFindUsagesOptions {
val javaOptions = JavaMethodFindUsagesOptions(project)
javaOptions.fastTrack = fastTrack
javaOptions.isCheckDeepInheritance = isCheckDeepInheritance
javaOptions.isImplementingMethods = isImplementingMethods
javaOptions.isIncludeInherited = isIncludeInherited
javaOptions.isIncludeOverloadUsages = isIncludeOverloadUsages
javaOptions.isOverridingMethods = isOverridingMethods
javaOptions.isSearchForTextOccurrences = isSearchForTextOccurrences
javaOptions.isSkipImportStatements = isSkipImportStatements
javaOptions.isUsages = isUsages
javaOptions.searchScope = searchScope
return javaOptions
}
override fun toJavaOptions(project: Project): FindUsagesOptions? {
val javaOptions = JavaMethodFindUsagesOptions(project)
javaOptions.fastTrack = fastTrack
javaOptions.isCheckDeepInheritance = isCheckDeepInheritance
javaOptions.isImplementingMethods = isImplementingMethods
javaOptions.isIncludeInherited = isIncludeInherited
javaOptions.isIncludeOverloadUsages = isIncludeOverloadUsages
javaOptions.isOverridingMethods = isOverridingMethods
javaOptions.isSearchForTextOccurrences = isSearchForTextOccurrences
javaOptions.isSkipImportStatements = isSkipImportStatements
javaOptions.isUsages = isUsages
javaOptions.searchScope = searchScope
fun KotlinPropertyFindUsagesOptions.toJavaVariableOptions(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
return javaOptions
}
}
public class KotlinPropertyFindUsagesOptions(project: Project): KotlinCallableFindUsagesOptions, JavaVariableFindUsagesOptions(project) {
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
}
}
@@ -47,15 +47,9 @@ class DelegatingFindMemberUsagesHandler(
is KtNamedDeclaration ->
HandlerAndOptions(KotlinFindMemberUsagesHandler.getInstance(element, elementsToSearch, factory), options)
is PsiMethod ->
/* Can't have KotlinPropertyFindUsagesOptions here since Kotlin properties do not override java methods, so
* elementsToSearch contains property declarations only */
is PsiMethod, is PsiParameter ->
HandlerAndOptions(JavaFindUsagesHandler(element, elementsToSearch.toTypedArray(), factory.javaHandlerFactory),
(options as KotlinFunctionFindUsagesOptions?)?.toJavaMethodOptions(project))
is PsiParameter ->
HandlerAndOptions(JavaFindUsagesHandler(element, elementsToSearch.toTypedArray(), factory.javaHandlerFactory),
(options as KotlinPropertyFindUsagesOptions?)?.toJavaVariableOptions(project))
(options as KotlinCallableFindUsagesOptions?)?.toJavaOptions(project))
else -> null
}
@@ -21,13 +21,11 @@ import com.intellij.find.findUsages.AbstractFindUsagesDialog
import com.intellij.find.findUsages.FindUsagesOptions
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiReference
import com.intellij.psi.search.searches.MethodReferencesSearch
import com.intellij.psi.search.searches.ReferencesSearch
import com.intellij.usageView.UsageInfo
import com.intellij.util.*
import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.asJava.toLightMethods
import org.jetbrains.kotlin.idea.findUsages.KotlinCallableFindUsagesOptions
import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory
@@ -128,17 +126,14 @@ public abstract class KotlinFindMemberUsagesHandler<T : KtNamedDeclaration>
scope = options.searchScope,
kotlinOptions = createKotlinReferencesSearchOptions(options))
val query = applyQueryFilters(element, options, ReferencesSearch.search(searchParameters))
if (!query.forEach(referenceProcessor)) return false
val psiMethods = when (element) {
is PsiMethod -> listOf(element)
is KtFunction -> runReadAction { LightClassUtil.getLightClassMethods(element) }
else -> listOf<PsiMethod>()
with(applyQueryFilters(element, options, ReferencesSearch.search(searchParameters))) {
if (!forEach(referenceProcessor)) return false
}
for (psiMethod in psiMethods) {
val query = applyQueryFilters(element, options, MethodReferencesSearch.search(psiMethod, options.searchScope, true))
if (!query.forEach(referenceProcessor)) return false
for (psiMethod in runReadAction { element.toLightMethods() }) {
with(applyQueryFilters(element, options, MethodReferencesSearch.search(psiMethod, options.searchScope, true))) {
if (!forEach(referenceProcessor)) return false
}
}
}
@@ -16,31 +16,72 @@
package org.jetbrains.kotlin.idea.search.ideaExtensions
import com.intellij.openapi.application.QueryExecutorBase
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiReference
import com.intellij.psi.*
import com.intellij.psi.impl.search.MethodTextOccurrenceProcessor
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.util.Processor
import org.jetbrains.kotlin.asJava.KotlinLightMethod
import org.jetbrains.kotlin.asJava.getRepresentativeLightMethod
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.KtDeclaration
import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.KtNamedDeclaration
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.utils.ifEmpty
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>,
aClass: PsiClass,
strictSignatureSearch: Boolean): MethodTextOccurrenceProcessor? {
strictSignatureSearch: Boolean): MethodTextOccurrenceProcessor {
return object: MethodTextOccurrenceProcessor(aClass, strictSignatureSearch, *methods) {
override fun processInexactReference(ref: PsiReference, refElement: PsiElement?, method: PsiMethod, consumer: Processor<PsiReference>): Boolean {
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) }
}
}
}
@@ -19,14 +19,12 @@ package org.jetbrains.kotlin.idea.search.ideaExtensions
import com.intellij.openapi.application.QueryExecutorBase
import com.intellij.psi.PsiMethod
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.searches.MethodReferencesSearch
import com.intellij.util.Processor
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.search.restrictToKotlinSources
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.synthetic.JavaSyntheticPropertiesScope
@@ -37,7 +35,7 @@ public class KotlinPropertyAccessorsReferenceSearcher() : QueryExecutorBase<PsiR
val method = queryParameters.getMethod()
val propertyName = propertyName(method) ?: return
val onlyKotlinFiles = restrictToKotlinSources(queryParameters.getEffectiveSearchScope())
val onlyKotlinFiles = queryParameters.getEffectiveSearchScope().restrictToKotlinSources()
queryParameters.getOptimizer()!!.searchWord(
propertyName,
@@ -58,11 +56,4 @@ public class KotlinPropertyAccessorsReferenceSearcher() : QueryExecutorBase<PsiR
val property = SyntheticJavaPropertyDescriptor.findByGetterOrSetter(functionDescriptor, syntheticExtensionsScope) ?: return null
return property.getName().asString()
}
private fun restrictToKotlinSources(originalScope: SearchScope): SearchScope {
return when (originalScope) {
is GlobalSearchScope -> GlobalSearchScope.getScopeRestrictedByFileTypes(originalScope, KotlinFileType.INSTANCE)
else -> originalScope
}
}
}
@@ -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);
}
}
@@ -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
}
@@ -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
@@ -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);
}
}
@@ -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
}
@@ -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
View File
@@ -1,8 +1,9 @@
// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtNamedFunction
// OPTIONS: usages
// FIND_BY_REF
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() {
@@ -1,4 +1,4 @@
Function call (10: 10) A(0) != A(1)
Function call (11: 10) A(0) equals A(1)
Function call (5: 71) override fun equals(other: Any?): Boolean = other is A && other.n == n
Function call (9: 10) A(0) == A(1)
Function call (10: 10) A(0) == A(1)
Function call (11: 10) A(0) != A(1)
Function call (12: 10) A(0) equals A(1)
Function call (6: 71) override fun equals(other: Any?): Boolean = other is A && other.n == n
@@ -6,11 +6,11 @@ interface 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) {
a.foo()
a.<caret>foo()
}
// for KT-3769 Find usages gives no result for overrides
@@ -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
}
@@ -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);
}
}
@@ -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);
@@ -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
}
@@ -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);
}
}
@@ -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);
@@ -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
}
@@ -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);
}
}
@@ -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.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.PsiPackage;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.testFramework.LightProjectDescriptor;
@@ -53,6 +52,7 @@ import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
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.KotlinPropertyFindUsagesOptions;
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) {
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;
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")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -1341,6 +1368,27 @@ public class JetFindUsagesTestGenerated extends AbstractJetFindUsagesTest {
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")