assorted Find Usages fixes: add missing read actions, better cancellation, fix search of componentN() usages for data class primary constructor parameter, remove workaround for usage of IDEA API which is now public

This commit is contained in:
Dmitry Jemerov
2015-09-04 18:07:08 +02:00
parent ccf78b6fa4
commit 55640ac885
9 changed files with 125 additions and 91 deletions
@@ -24,6 +24,7 @@ import com.intellij.psi.search.*
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 org.jetbrains.kotlin.asJava.* import org.jetbrains.kotlin.asJava.*
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.JetFileType import org.jetbrains.kotlin.idea.JetFileType
import org.jetbrains.kotlin.idea.references.JetSimpleNameReference import org.jetbrains.kotlin.idea.references.JetSimpleNameReference
import org.jetbrains.kotlin.idea.search.KOTLIN_NAMED_ARGUMENT_SEARCH_CONTEXT import org.jetbrains.kotlin.idea.search.KOTLIN_NAMED_ARGUMENT_SEARCH_CONTEXT
@@ -47,7 +48,7 @@ data class KotlinReferencesSearchOptions(val acceptCallableOverrides: Boolean =
} }
public class KotlinReferencesSearchParameters(elementToSearch: PsiElement, public class KotlinReferencesSearchParameters(elementToSearch: PsiElement,
scope: SearchScope = elementToSearch.project.allScope(), scope: SearchScope = runReadAction { elementToSearch.project.allScope() },
ignoreAccessScope: Boolean = false, ignoreAccessScope: Boolean = false,
optimizer: SearchRequestCollector? = null, optimizer: SearchRequestCollector? = null,
val kotlinOptions: KotlinReferencesSearchOptions = KotlinReferencesSearchOptions.Empty) val kotlinOptions: KotlinReferencesSearchOptions = KotlinReferencesSearchOptions.Empty)
@@ -61,8 +62,8 @@ public class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, Referenc
val unwrappedElement = element.namedUnwrappedElement ?: return val unwrappedElement = element.namedUnwrappedElement ?: return
val classNameForCompanionObject = unwrappedElement.getClassNameForCompanionObject()
val words = runReadAction { val words = runReadAction {
val classNameForCompanionObject = unwrappedElement.getClassNameForCompanionObject()
unwrappedElement.getSpecialNamesToSearch() + unwrappedElement.getSpecialNamesToSearch() +
(if (classNameForCompanionObject != null) listOf(classNameForCompanionObject) else emptyList()) (if (classNameForCompanionObject != null) listOf(classNameForCompanionObject) else emptyList())
} }
@@ -185,17 +186,19 @@ public class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, Referenc
val kotlinReferencesSearchOptions = (queryParameters as? KotlinReferencesSearchParameters)?.kotlinOptions val kotlinReferencesSearchOptions = (queryParameters as? KotlinReferencesSearchParameters)?.kotlinOptions
if (kotlinReferencesSearchOptions?.acceptCompanionObjectMembers == true) { if (kotlinReferencesSearchOptions?.acceptCompanionObjectMembers == true) {
val originClass = element.getStrictParentOfType<JetClass>() runReadAction {
val originLightClass = LightClassUtil.getPsiClass(originClass) val originClass = element.getStrictParentOfType<JetClass>()
if (originLightClass != null) { val originLightClass = LightClassUtil.getPsiClass(originClass)
val lightDeclarations: List<KotlinLightElement<*, *>?> = if (originLightClass != null) {
originLightClass.methods.map { it as? KotlinLightMethod } + val lightDeclarations: List<KotlinLightElement<*, *>?> =
originLightClass.fields.map { it as? KotlinLightFieldForDeclaration } originLightClass.methods.map { it as? KotlinLightMethod } +
originLightClass.fields.map { it as? KotlinLightFieldForDeclaration }
for (declaration in element.declarations) { for (declaration in element.declarations) {
val lightDeclaration = lightDeclarations.find { it?.getOrigin() == declaration } val lightDeclaration = lightDeclarations.find { it?.getOrigin() == declaration }
if (lightDeclaration != null) { if (lightDeclaration != null) {
searchNamedElement(queryParameters, lightDeclaration) searchNamedElement(queryParameters, lightDeclaration)
}
} }
} }
} }
@@ -224,6 +227,17 @@ public class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, Referenc
searchNamedElement(queryParameters, propertyMethods.setter) searchNamedElement(queryParameters, propertyMethods.setter)
} }
private fun searchDataClassComponentUsages(queryParameters: ReferencesSearch.SearchParameters,
containingClass: PsiClass?,
componentFunctionDescriptor: FunctionDescriptor) {
val componentFunction = containingClass?.methods?.find {
it.name == componentFunctionDescriptor.name.asString() && it.parameterList.parametersCount == 0
}
if (componentFunction != null) {
searchNamedElement(queryParameters, componentFunction)
}
}
private fun searchLightElements(queryParameters: ReferencesSearch.SearchParameters, element: PsiElement) { private fun searchLightElements(queryParameters: ReferencesSearch.SearchParameters, element: PsiElement) {
when (element) { when (element) {
is JetClassOrObject -> processJetClassOrObject(element, queryParameters) is JetClassOrObject -> processJetClassOrObject(element, queryParameters)
@@ -235,7 +249,7 @@ public class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, Referenc
searchNamedElement(queryParameters, method) searchNamedElement(queryParameters, method)
} }
val staticFromCompanionObject = findStaticMethodFromCompanionObject(element) val staticFromCompanionObject = runReadAction { findStaticMethodFromCompanionObject(element) }
if (staticFromCompanionObject != null) { if (staticFromCompanionObject != null) {
searchNamedElement(queryParameters, staticFromCompanionObject) searchNamedElement(queryParameters, staticFromCompanionObject)
} }
@@ -246,10 +260,18 @@ public class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, Referenc
searchNamedElement(queryParameters, propertyMethods.getter) searchNamedElement(queryParameters, propertyMethods.getter)
searchNamedElement(queryParameters, propertyMethods.setter) searchNamedElement(queryParameters, propertyMethods.setter)
searchNamedElement(queryParameters, propertyMethods.backingField) searchNamedElement(queryParameters, propertyMethods.backingField)
} }
is JetParameter -> { is JetParameter -> {
searchPropertyMethods(queryParameters, element) searchPropertyMethods(queryParameters, element)
runReadAction {
val componentFunctionDescriptor = element.dataClassComponentFunction()
if (componentFunctionDescriptor != null) {
val containingClass = LightClassUtil.getPsiClass(element.getStrictParentOfType<JetClassOrObject>())
searchDataClassComponentUsages(queryParameters, containingClass, componentFunctionDescriptor)
}
}
} }
is KotlinLightMethod -> { is KotlinLightMethod -> {
@@ -262,7 +284,7 @@ public class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, Referenc
searchNamedElement(queryParameters, property) searchNamedElement(queryParameters, property)
} }
else if (declaration is JetFunction) { else if (declaration is JetFunction) {
val staticFromCompanionObject = findStaticMethodFromCompanionObject(declaration) val staticFromCompanionObject = runReadAction { findStaticMethodFromCompanionObject(declaration) }
if (staticFromCompanionObject != null) { if (staticFromCompanionObject != null) {
searchNamedElement(queryParameters, staticFromCompanionObject) searchNamedElement(queryParameters, staticFromCompanionObject)
} }
@@ -271,24 +293,21 @@ public class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, Referenc
is KotlinLightParameter -> { is KotlinLightParameter -> {
val origin = element.getOrigin() ?: return val origin = element.getOrigin() ?: return
val componentFunctionDescriptor = origin.dataClassComponentFunction() runReadAction {
if (componentFunctionDescriptor != null) { val componentFunctionDescriptor = origin.dataClassComponentFunction()
val containingClass = element.method.containingClass if (componentFunctionDescriptor != null) {
val componentFunction = containingClass?.methods?.find { searchDataClassComponentUsages(queryParameters, element.method.containingClass, componentFunctionDescriptor)
it.name == componentFunctionDescriptor.name.asString() && it.parameterList.parametersCount == 0
}
if (componentFunction != null) {
searchNamedElement(queryParameters, componentFunction)
} }
} }
searchPropertyMethods(queryParameters, origin) searchPropertyMethods(queryParameters, origin)
} }
} }
} }
private fun isOnlyKotlinSearch(searchScope: SearchScope) = private fun isOnlyKotlinSearch(searchScope: SearchScope) =
searchScope is LocalSearchScope && searchScope.getScope().all { it.getContainingFile().getFileType() == JetFileType.INSTANCE } searchScope is LocalSearchScope && runReadAction {
searchScope.getScope().all { it.getContainingFile().getFileType() == JetFileType.INSTANCE }
}
private fun searchNamedElement(queryParameters: ReferencesSearch.SearchParameters, private fun searchNamedElement(queryParameters: ReferencesSearch.SearchParameters,
element: PsiNamedElement?, element: PsiNamedElement?,
@@ -106,34 +106,34 @@ private fun JetElement.getConstructorCallDescriptor(): DeclarationDescriptor? {
return null return null
} }
public fun PsiElement.processDelegationCallConstructorUsages(scope: SearchScope, process: (JetCallElement) -> Unit) { public fun PsiElement.processDelegationCallConstructorUsages(scope: SearchScope, process: (JetCallElement) -> Boolean): Boolean {
processDelegationCallKotlinConstructorUsages(scope, process) if (!processDelegationCallKotlinConstructorUsages(scope, process)) return false
processDelegationCallJavaConstructorUsages(scope, process) return processDelegationCallJavaConstructorUsages(scope, process)
} }
private fun PsiElement.processDelegationCallKotlinConstructorUsages(scope: SearchScope, process: (JetCallElement) -> Unit) { private fun PsiElement.processDelegationCallKotlinConstructorUsages(scope: SearchScope, process: (JetCallElement) -> Boolean): Boolean {
val element = unwrapped val element = unwrapped
val klass = when (element) { val klass = when (element) {
is JetConstructor<*> -> element.getContainingClassOrObject() is JetConstructor<*> -> element.getContainingClassOrObject()
is JetClass -> element is JetClass -> element
else -> return else -> return true
} }
if (klass !is JetClass || element !is JetDeclaration) return if (klass !is JetClass || element !is JetDeclaration) return true
val descriptor = element.constructor ?: return val descriptor = element.constructor ?: return true
processClassDelegationCallsToSpecifiedConstructor(klass, descriptor, process) if (!processClassDelegationCallsToSpecifiedConstructor(klass, descriptor, process)) return false
processInheritorsDelegatingCallToSpecifiedConstructor(klass, scope, descriptor, process) return processInheritorsDelegatingCallToSpecifiedConstructor(klass, scope, descriptor, process)
} }
private fun PsiElement.processDelegationCallJavaConstructorUsages(scope: SearchScope, process: (JetCallElement) -> Unit) { private fun PsiElement.processDelegationCallJavaConstructorUsages(scope: SearchScope, process: (JetCallElement) -> Boolean): Boolean {
if (this is KotlinLightElement<*, *>) return if (this is KotlinLightElement<*, *>) return true
// TODO: Temporary hack to avoid NPE while KotlinNoOriginLightMethod is around // TODO: Temporary hack to avoid NPE while KotlinNoOriginLightMethod is around
if (this is KotlinNoOriginLightMethod) return if (this is KotlinNoOriginLightMethod) return true
if (!(this is PsiMethod && isConstructor())) return if (!(this is PsiMethod && isConstructor())) return true
val klass = getContainingClass() ?: return val klass = getContainingClass() ?: return true
val descriptor = getJavaMethodDescriptor() as? ConstructorDescriptor ?: return val descriptor = getJavaMethodDescriptor() as? ConstructorDescriptor ?: return true
processInheritorsDelegatingCallToSpecifiedConstructor(klass, scope, descriptor, process) return processInheritorsDelegatingCallToSpecifiedConstructor(klass, scope, descriptor, process)
} }
@@ -141,34 +141,36 @@ private fun processInheritorsDelegatingCallToSpecifiedConstructor(
klass: PsiElement, klass: PsiElement,
scope: SearchScope, scope: SearchScope,
descriptor: ConstructorDescriptor, descriptor: ConstructorDescriptor,
process: (JetCallElement) -> Unit process: (JetCallElement) -> Boolean
) { ): Boolean {
HierarchySearchRequest(klass, scope, false).searchInheritors().forEach() { return HierarchySearchRequest(klass, scope, false).searchInheritors().all {
val unwrapped = it.unwrapped val unwrapped = it.unwrapped
if (unwrapped is JetClass) { if (unwrapped is JetClass) {
processClassDelegationCallsToSpecifiedConstructor(unwrapped, descriptor, process) processClassDelegationCallsToSpecifiedConstructor(unwrapped, descriptor, process)
} } else
true
} }
} }
private fun processClassDelegationCallsToSpecifiedConstructor( private fun processClassDelegationCallsToSpecifiedConstructor(
klass: JetClass, constructor: DeclarationDescriptor, process: (JetCallElement) -> Unit klass: JetClass, constructor: DeclarationDescriptor, process: (JetCallElement) -> Boolean
) { ): Boolean {
for (secondaryConstructor in klass.getSecondaryConstructors()) { for (secondaryConstructor in klass.getSecondaryConstructors()) {
val delegationCallDescriptor = secondaryConstructor.getDelegationCall().getConstructorCallDescriptor() val delegationCallDescriptor = secondaryConstructor.getDelegationCall().getConstructorCallDescriptor()
if (constructor == delegationCallDescriptor) { if (constructor == delegationCallDescriptor) {
process(secondaryConstructor.getDelegationCall()) if (!process(secondaryConstructor.getDelegationCall())) return false
} }
} }
if (!klass.isEnum()) return if (!klass.isEnum()) return true
for (declaration in klass.declarations) { for (declaration in klass.declarations) {
if (declaration is JetEnumEntry) { if (declaration is JetEnumEntry) {
val delegationCall = declaration.getDelegationSpecifiers().firstOrNull() val delegationCall = declaration.getDelegationSpecifiers().firstOrNull()
if (delegationCall is JetDelegatorToSuperCall && constructor == delegationCall.calleeExpression.getConstructorCallDescriptor()) { if (delegationCall is JetDelegatorToSuperCall && constructor == delegationCall.calleeExpression.getConstructorCallDescriptor()) {
process(delegationCall) if (!process(delegationCall)) return false
} }
} }
} }
return true
} }
// Check if reference resolves to extension function whose receiver is the same as declaration's parent (or its superclass) // Check if reference resolves to extension function whose receiver is the same as declaration's parent (or its superclass)
@@ -16,10 +16,7 @@
package org.jetbrains.kotlin.idea.findUsages.handlers package org.jetbrains.kotlin.idea.findUsages.handlers
import com.intellij.find.findUsages.AbstractFindUsagesDialog import com.intellij.find.findUsages.*
import com.intellij.find.findUsages.FindUsagesOptions
import com.intellij.find.findUsages.JavaFindUsagesHandler
import com.intellij.find.findUsages.JavaFindUsagesHandlerFactory
import com.intellij.openapi.actionSystem.DataContext import com.intellij.openapi.actionSystem.DataContext
import com.intellij.psi.PsiClass import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
@@ -47,6 +44,7 @@ import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
import org.jetbrains.kotlin.idea.search.usagesSearch.isConstructorUsage import org.jetbrains.kotlin.idea.search.usagesSearch.isConstructorUsage
import org.jetbrains.kotlin.idea.search.usagesSearch.isImportUsage import org.jetbrains.kotlin.idea.search.usagesSearch.isImportUsage
import org.jetbrains.kotlin.idea.search.usagesSearch.processDelegationCallConstructorUsages import org.jetbrains.kotlin.idea.search.usagesSearch.processDelegationCallConstructorUsages
import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
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
@@ -110,13 +108,15 @@ public class KotlinFindClassUsagesHandler(
} }
if (kotlinOptions.searchConstructorUsages) { if (kotlinOptions.searchConstructorUsages) {
val constructors = classOrObject.toLightClass()?.getConstructors() ?: PsiMethod.EMPTY_ARRAY val result = runReadAction {
for (constructor in constructors) { val constructors = classOrObject.toLightClass()?.getConstructors() ?: PsiMethod.EMPTY_ARRAY
if (constructor !is KotlinLightMethod) continue constructors.filterIsInstance<KotlinLightMethod>().all { constructor ->
constructor.processDelegationCallConstructorUsages(constructor.getUseScope()) { constructor.processDelegationCallConstructorUsages(constructor.getUseScope()) {
it.getCalleeExpression()?.mainReference?.let { referenceProcessor.process(it) } it.getCalleeExpression()?.mainReference?.let { referenceProcessor.process(it) } ?: false
}
} }
} }
if (!result) return false
} }
if (options.isDerivedClasses || options.isDerivedInterfaces) { if (options.isDerivedClasses || options.isDerivedInterfaces) {
@@ -148,27 +148,29 @@ public class KotlinFindClassUsagesHandler(
private fun processCompanionObjectInternalReferences(companionObject: JetObjectDeclaration, private fun processCompanionObjectInternalReferences(companionObject: JetObjectDeclaration,
processor: Processor<PsiReference>): Boolean { processor: Processor<PsiReference>): Boolean {
val klass = companionObject.getStrictParentOfType<JetClass>() ?: return true
val companionObjectDescriptor = companionObject.descriptor
var stop: Boolean = false var stop: Boolean = false
klass.acceptChildren(object : JetVisitorVoid() { runReadAction {
override fun visitJetElement(element: JetElement) { val klass = companionObject.getStrictParentOfType<JetClass>() ?: return@runReadAction
if (element == companionObject) return // skip companion object itself val companionObjectDescriptor = companionObject.descriptor
if (stop) return klass.acceptChildren(object : JetVisitorVoid() {
element.acceptChildren(this) override fun visitJetElement(element: JetElement) {
if (element == companionObject) return // skip companion object itself
if (stop) return
element.acceptChildren(this)
val bindingContext = element.analyze() val bindingContext = element.analyze()
val resolvedCall = bindingContext[BindingContext.CALL, element]?.getResolvedCall(bindingContext) ?: return val resolvedCall = bindingContext[BindingContext.CALL, element]?.getResolvedCall(bindingContext) ?: return
if ((resolvedCall.getDispatchReceiver() as? ClassReceiver)?.getDeclarationDescriptor() == companionObjectDescriptor if ((resolvedCall.getDispatchReceiver() as? ClassReceiver)?.getDeclarationDescriptor() == companionObjectDescriptor
|| (resolvedCall.getExtensionReceiver() as? ClassReceiver)?.getDeclarationDescriptor() == companionObjectDescriptor) { || (resolvedCall.getExtensionReceiver() as? ClassReceiver)?.getDeclarationDescriptor() == companionObjectDescriptor) {
element.getReferences().forEach { element.getReferences().forEach {
if (!stop && !processor.process(it)) { if (!stop && !processor.process(it)) {
stop = true stop = true
}
} }
} }
} }
} })
}) }
return !stop return !stop
} }
@@ -191,15 +193,7 @@ public class KotlinFindClassUsagesHandler(
else -> null else -> null
} ?: return Collections.emptyList() } ?: return Collections.emptyList()
// Work around the protected method in JavaFindUsagesHandler return JavaFindUsagesHelper.getElementNames(psiClass)
// todo: Use JavaFindUsagesHelper.getElementNames() when it becomes public in IDEA
var stringsToSearch: Collection<String>
object: JavaFindUsagesHandler(psiClass, JavaFindUsagesHandlerFactory.getInstance(element.getProject())) {
init {
stringsToSearch = getStringsToSearch(psiClass)!!
}
}
return stringsToSearch
} }
protected override fun isSearchForTextOccurencesAvailable(psiElement: PsiElement, isSingleFile: Boolean): Boolean { protected override fun isSearchForTextOccurencesAvailable(psiElement: PsiElement, isSingleFile: Boolean): Boolean {
@@ -39,7 +39,6 @@ import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashSet; import com.intellij.util.containers.HashSet;
import com.intellij.util.containers.MultiMap; import com.intellij.util.containers.MultiMap;
import kotlin.KotlinPackage; import kotlin.KotlinPackage;
import kotlin.Unit;
import kotlin.jvm.functions.Function1; 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;
@@ -330,9 +329,9 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
UsagesSearchPackage.processDelegationCallConstructorUsages( UsagesSearchPackage.processDelegationCallConstructorUsages(
functionPsi, functionPsi,
functionPsi.getUseScope(), functionPsi.getUseScope(),
new Function1<JetCallElement, Unit>() { new Function1<JetCallElement, Boolean>() {
@Override @Override
public Unit invoke(JetCallElement element) { public Boolean invoke(JetCallElement element) {
if (element instanceof JetConstructorDelegationCall) { if (element instanceof JetConstructorDelegationCall) {
result.add(new JetConstructorDelegationCallUsage((JetConstructorDelegationCall) element, changeInfo)); result.add(new JetConstructorDelegationCallUsage((JetConstructorDelegationCall) element, changeInfo));
} }
@@ -340,7 +339,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
result.add(new JetFunctionCallUsage(element, functionUsageInfo)); result.add(new JetFunctionCallUsage(element, functionUsageInfo));
} }
return null; return true;
} }
} }
); );
@@ -481,13 +480,13 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
UsagesSearchPackage.processDelegationCallConstructorUsages( UsagesSearchPackage.processDelegationCallConstructorUsages(
psiMethod, psiMethod,
psiMethod.getUseScope(), psiMethod.getUseScope(),
new Function1<JetCallElement, Unit>() { new Function1<JetCallElement, Boolean>() {
@Override @Override
public Unit invoke(JetCallElement element) { public Boolean invoke(JetCallElement element) {
if (element instanceof JetConstructorDelegationCall) { if (element instanceof JetConstructorDelegationCall) {
result.add(new JavaConstructorDeferredUsageInDelegationCall((JetConstructorDelegationCall) element)); result.add(new JavaConstructorDeferredUsageInDelegationCall((JetConstructorDelegationCall) element));
} }
return null; return true;
} }
} }
); );
@@ -28,7 +28,7 @@ public class KotlinConstructorDelegationCallReferenceSearcher() : QueryExecutorB
if (!method.isConstructor()) return if (!method.isConstructor()) return
method.processDelegationCallConstructorUsages(method.getUseScope()) { method.processDelegationCallConstructorUsages(method.getUseScope()) {
it.getCalleeExpression()?.getReference()?.let { consumer.process(it) } it.getCalleeExpression()?.getReference()?.let { consumer.process(it) } ?: true
} }
} }
} }
@@ -0,0 +1,6 @@
// PSI_ELEMENT: org.jetbrains.kotlin.psi.JetParameter
// OPTIONS: usages
package test
public data class KotlinDataClass(val <caret>foo: Int, val bar: String) {
}
@@ -0,0 +1,7 @@
package test;
public class JavaUser {
int use(KotlinDataClass dataClass) {
return dataClass.component1();
}
}
@@ -0,0 +1 @@
Unclassified usage (5: 26) return dataClass.component1();
@@ -735,6 +735,12 @@ public class JetFindUsagesTestGenerated extends AbstractJetFindUsagesTest {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/findUsages/kotlin/findParameterUsages"), Pattern.compile("^(.+)\\.0\\.kt$"), true); JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/findUsages/kotlin/findParameterUsages"), Pattern.compile("^(.+)\\.0\\.kt$"), true);
} }
@TestMetadata("kotlinComponentFunctionParameterUsages.0.kt")
public void testKotlinComponentFunctionParameterUsages() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/kotlin/findParameterUsages/kotlinComponentFunctionParameterUsages.0.kt");
doTest(fileName);
}
@TestMetadata("kotlinConstructorParameterUsages.0.kt") @TestMetadata("kotlinConstructorParameterUsages.0.kt")
public void testKotlinConstructorParameterUsages() throws Exception { public void testKotlinConstructorParameterUsages() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/kotlin/findParameterUsages/kotlinConstructorParameterUsages.0.kt"); String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/kotlin/findParameterUsages/kotlinConstructorParameterUsages.0.kt");