[kotlin] detection of read/write access

^KTIJ-32177 fixed


(cherry picked from commit c32ff924a9508fa573eb40a3b784ed7217719d77)

IJ-CR-149523

GitOrigin-RevId: 4f8068d773d4053f24c4c531bc0516630c5a6782
This commit is contained in:
Anna Kozlova
2024-11-15 19:19:30 +01:00
committed by intellij-monorepo-bot
parent 6c93365378
commit 1837b05b9e
10 changed files with 83 additions and 7 deletions

View File

@@ -18,7 +18,7 @@ class KotlinReadWriteAccessDetector : ReadWriteAccessDetector() {
val INSTANCE = KotlinReadWriteAccessDetector()
}
private val javaReadWriteAccessDetector = JavaReadWriteAccessDetector()
private val javaReadWriteAccessDetector by lazy { EP_NAME.extensionList.filterIsInstance<JavaReadWriteAccessDetector>().first() }
override fun isReadWriteAccessible(element: PsiElement) = element is KtVariableDeclaration || element is KtParameter || javaReadWriteAccessDetector.isReadWriteAccessible(element)

View File

@@ -6125,6 +6125,25 @@ public abstract class FindUsagesWithCompilerReferenceIndexFirTestGenerated exten
runTest("../../idea/tests/testData/findUsages/java/findJavaFieldUsages/JKFieldUsages.0.java");
}
}
@RunWith(JUnit3RunnerWithInners.class)
@TestMetadata("../../idea/tests/testData/findUsages/java/findJavaFieldUsages")
public static class TestJKFieldUsagesReadWriteAccess extends AbstractFindUsagesWithCompilerReferenceIndexFirTest {
@java.lang.Override
@org.jetbrains.annotations.NotNull
public final KotlinPluginMode getPluginMode() {
return KotlinPluginMode.K2;
}
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
@TestMetadata("JKFieldUsagesReadWriteAccess.0.java")
public void testJKFieldUsagesReadWriteAccess() throws Exception {
runTest("../../idea/tests/testData/findUsages/java/findJavaFieldUsages/JKFieldUsagesReadWriteAccess.0.java");
}
}
}
@RunWith(JUnit3RunnerWithInners.class)

View File

@@ -6125,6 +6125,25 @@ public abstract class FindUsagesWithCompilerReferenceIndexTestGenerated extends
runTest("../../idea/tests/testData/findUsages/java/findJavaFieldUsages/JKFieldUsages.0.java");
}
}
@RunWith(JUnit3RunnerWithInners.class)
@TestMetadata("../../idea/tests/testData/findUsages/java/findJavaFieldUsages")
public static class TestJKFieldUsagesReadWriteAccess extends AbstractFindUsagesWithCompilerReferenceIndexTest {
@java.lang.Override
@org.jetbrains.annotations.NotNull
public final KotlinPluginMode getPluginMode() {
return KotlinPluginMode.K1;
}
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
@TestMetadata("JKFieldUsagesReadWriteAccess.0.java")
public void testJKFieldUsagesReadWriteAccess() throws Exception {
runTest("../../idea/tests/testData/findUsages/java/findJavaFieldUsages/JKFieldUsagesReadWriteAccess.0.java");
}
}
}
@RunWith(JUnit3RunnerWithInners.class)

View File

@@ -1999,6 +1999,11 @@ public abstract class FindUsagesFirTestGenerated extends AbstractFindUsagesFirTe
public void testJKFieldUsages() throws Exception {
runTest("../../idea/tests/testData/findUsages/java/findJavaFieldUsages/JKFieldUsages.0.java");
}
@TestMetadata("JKFieldUsagesReadWriteAccess.0.java")
public void testJKFieldUsagesReadWriteAccess() throws Exception {
runTest("../../idea/tests/testData/findUsages/java/findJavaFieldUsages/JKFieldUsagesReadWriteAccess.0.java");
}
}
@RunWith(JUnit3RunnerWithInners.class)

View File

@@ -36,9 +36,11 @@ import com.intellij.usages.impl.FileStructureGroupRuleProvider
import com.intellij.usages.impl.rules.UsageType
import com.intellij.usages.impl.rules.UsageTypeProvider
import com.intellij.usages.rules.ImportFilteringRule
import com.intellij.usages.rules.UsageFilteringRule
import com.intellij.usages.rules.UsageGroupingRule
import com.intellij.util.CommonProcessors
import org.jetbrains.kotlin.asJava.unwrapped
import org.jetbrains.kotlin.config.AnalysisFlag
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.executeOnPooledThreadInReadAction
import org.jetbrains.kotlin.findUsages.AbstractFindUsagesTest.Companion.FindUsageTestType
@@ -331,12 +333,12 @@ abstract class AbstractFindUsagesTest : KotlinLightCodeInsightFixtureTestCase(),
private val SUPPORTED_EXTENSIONS = setOf("kt", "kts", "java", "xml", "properties", "txt", "groovy")
internal fun getUsageAdapters(
filters: Collection<ImportFilteringRule>,
filters: Collection<(UsageInfo2UsageAdapter) -> Boolean>,
usageInfos: Collection<UsageInfo>
): Collection<UsageInfo2UsageAdapter> = usageInfos
.map(::UsageInfo2UsageAdapter)
.onEach { it.updateCachedPresentation() }
.filter { usageAdapter -> filters.all { it.isVisible(usageAdapter) } }
.filter { usageAdapter -> filters.all { it(usageAdapter) } }
val KtDeclaration.descriptor: DeclarationDescriptor?
get() = if (this is KtParameter) this.resolveToParameterDescriptorIfAny(BodyResolveMode.FULL) else this.resolveToDescriptorIfAny(BodyResolveMode.FULL)
@@ -356,7 +358,11 @@ abstract class AbstractFindUsagesTest : KotlinLightCodeInsightFixtureTestCase(),
it as T
}): Collection<T> =
InTextDirectivesUtils.findLinesWithPrefixesRemoved(mainFileText, directive).map {
mapper(Class.forName(it).getDeclaredConstructor().newInstance())
try {
mapper(Class.forName(it).getDeclaredConstructor().newInstance())
} catch (e: Throwable) {
mapper(Class.forName(it).kotlin.objectInstance as Any)
}
}
}
}
@@ -401,13 +407,18 @@ internal fun <T : PsiElement> findUsagesAndCheckResults(
ExpressionsOfTypeProcessor.mode = ExpressionsOfTypeProcessor.Mode.ALWAYS_SMART
}
val filteringRules = AbstractFindUsagesTest.instantiateClasses<ImportFilteringRule>(mainFileText, "// FILTERING_RULES: ")
val importFilteringRules: List<(UsageInfo2UsageAdapter) -> Boolean> = AbstractFindUsagesTest.instantiateClasses<ImportFilteringRule>(mainFileText, "// FILTERING_RULES: ")
.map { rule -> { usageInfo -> rule.isVisible(usageInfo) } }
val filteringRules: List<(UsageInfo2UsageAdapter) -> Boolean> = AbstractFindUsagesTest.instantiateClasses<UsageFilteringRule>(mainFileText, "// USAGE_FILTERING_RULES: ")
.map { rule -> { usageInfo -> rule.isVisible(usageInfo, emptyArray()) } }
val groupingRules =
AbstractFindUsagesTest.instantiateClasses<UsageGroupingRule>(mainFileText, "// GROUPING_RULES: ") {
(it as? UsageGroupingRule) ?: (it as? FileStructureGroupRuleProvider)?.getUsageGroupingRule(project) ?: error("UsageGroupingRule is expected, actual is ${it.javaClass.name}")
}
val filteredUsages = AbstractFindUsagesTest.getUsageAdapters(filteringRules, usageInfos)
val filteredUsages = AbstractFindUsagesTest.getUsageAdapters(filteringRules + importFilteringRules, usageInfos)
val usageFiles = filteredUsages.map { it.file.name }.distinct()
val appendFileName = alwaysAppendFileName || usageFiles.size > 1

View File

@@ -1999,6 +1999,11 @@ public abstract class FindUsagesTestGenerated extends AbstractFindUsagesTest {
public void testJKFieldUsages() throws Exception {
runTest("testData/findUsages/java/findJavaFieldUsages/JKFieldUsages.0.java");
}
@TestMetadata("JKFieldUsagesReadWriteAccess.0.java")
public void testJKFieldUsagesReadWriteAccess() throws Exception {
runTest("testData/findUsages/java/findJavaFieldUsages/JKFieldUsagesReadWriteAccess.0.java");
}
}
@RunWith(JUnit3RunnerWithInners.class)

View File

@@ -0,0 +1,10 @@
// PSI_ELEMENT: com.intellij.psi.PsiField
// USAGE_FILTERING_RULES: com.intellij.usages.impl.rules.WriteAccessFilteringRule
public class Foo {
public String <caret>foo;
public Foo(String foo) {
this.foo = foo;
}
}

View File

@@ -0,0 +1,3 @@
fun bar() {
Foo("abc").foo = "foo"
}

View File

@@ -0,0 +1,2 @@
[JKFieldUsagesReadWriteAccess.0.java] Unclassified 7 this.foo = foo;
[JKFieldUsagesReadWriteAccess.1.kt] Value write 2 Foo("abc").foo = "foo"

View File

@@ -548,7 +548,9 @@
<usageFeaturesProvider implementation="org.jetbrains.kotlin.idea.findUsages.similarity.KotlinUsageSimilarityFeaturesProvider"/>
<readWriteAccessDetector implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReadWriteAccessDetector" id="kotlin"/>
<readWriteAccessDetector implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReadWriteAccessDetector"
id="kotlin"
order="first"/> <!--before lombok -->
<projectFileScanner implementation="org.jetbrains.kotlin.idea.base.platforms.LibraryEffectiveKindProvider$LibraryKindScanner"/>