From 1837b05b9e6d6e9b79f045b177ff02bdd46460b1 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 15 Nov 2024 19:19:30 +0100 Subject: [PATCH] [kotlin] detection of read/write access ^KTIJ-32177 fixed (cherry picked from commit c32ff924a9508fa573eb40a3b784ed7217719d77) IJ-CR-149523 GitOrigin-RevId: 4f8068d773d4053f24c4c531bc0516630c5a6782 --- .../KotlinReadWriteAccessDetector.kt | 2 +- ...ompilerReferenceIndexFirTestGenerated.java | 19 +++++++++++++++++ ...thCompilerReferenceIndexTestGenerated.java | 19 +++++++++++++++++ .../FindUsagesFirTestGenerated.java | 5 +++++ .../findUsages/AbstractFindUsagesTest.kt | 21 ++++++++++++++----- .../findUsages/FindUsagesTestGenerated.java | 5 +++++ .../JKFieldUsagesReadWriteAccess.0.java | 10 +++++++++ .../JKFieldUsagesReadWriteAccess.1.kt | 3 +++ .../JKFieldUsagesReadWriteAccess.results.txt | 2 ++ .../common/resources/META-INF/kotlin-core.xml | 4 +++- 10 files changed, 83 insertions(+), 7 deletions(-) create mode 100644 plugins/kotlin/idea/tests/testData/findUsages/java/findJavaFieldUsages/JKFieldUsagesReadWriteAccess.0.java create mode 100644 plugins/kotlin/idea/tests/testData/findUsages/java/findJavaFieldUsages/JKFieldUsagesReadWriteAccess.1.kt create mode 100644 plugins/kotlin/idea/tests/testData/findUsages/java/findJavaFieldUsages/JKFieldUsagesReadWriteAccess.results.txt diff --git a/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinReadWriteAccessDetector.kt b/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinReadWriteAccessDetector.kt index dcd38895a4b8..9ee5ffce3e97 100644 --- a/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinReadWriteAccessDetector.kt +++ b/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinReadWriteAccessDetector.kt @@ -18,7 +18,7 @@ class KotlinReadWriteAccessDetector : ReadWriteAccessDetector() { val INSTANCE = KotlinReadWriteAccessDetector() } - private val javaReadWriteAccessDetector = JavaReadWriteAccessDetector() + private val javaReadWriteAccessDetector by lazy { EP_NAME.extensionList.filterIsInstance().first() } override fun isReadWriteAccessible(element: PsiElement) = element is KtVariableDeclaration || element is KtParameter || javaReadWriteAccessDetector.isReadWriteAccessible(element) diff --git a/plugins/kotlin/compiler-reference-index/tests.k2/test/org/jetbrains/kotlin/idea/fir/search/refIndex/FindUsagesWithCompilerReferenceIndexFirTestGenerated.java b/plugins/kotlin/compiler-reference-index/tests.k2/test/org/jetbrains/kotlin/idea/fir/search/refIndex/FindUsagesWithCompilerReferenceIndexFirTestGenerated.java index 6fcb399bb25d..318be4b7b0db 100644 --- a/plugins/kotlin/compiler-reference-index/tests.k2/test/org/jetbrains/kotlin/idea/fir/search/refIndex/FindUsagesWithCompilerReferenceIndexFirTestGenerated.java +++ b/plugins/kotlin/compiler-reference-index/tests.k2/test/org/jetbrains/kotlin/idea/fir/search/refIndex/FindUsagesWithCompilerReferenceIndexFirTestGenerated.java @@ -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) diff --git a/plugins/kotlin/compiler-reference-index/tests/test/org/jetbrains/kotlin/idea/search/refIndex/FindUsagesWithCompilerReferenceIndexTestGenerated.java b/plugins/kotlin/compiler-reference-index/tests/test/org/jetbrains/kotlin/idea/search/refIndex/FindUsagesWithCompilerReferenceIndexTestGenerated.java index 57551e678ae9..d5e83194fd08 100644 --- a/plugins/kotlin/compiler-reference-index/tests/test/org/jetbrains/kotlin/idea/search/refIndex/FindUsagesWithCompilerReferenceIndexTestGenerated.java +++ b/plugins/kotlin/compiler-reference-index/tests/test/org/jetbrains/kotlin/idea/search/refIndex/FindUsagesWithCompilerReferenceIndexTestGenerated.java @@ -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) diff --git a/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/findUsages/FindUsagesFirTestGenerated.java b/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/findUsages/FindUsagesFirTestGenerated.java index 9e33abac6eae..71b8ab57a719 100644 --- a/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/findUsages/FindUsagesFirTestGenerated.java +++ b/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/findUsages/FindUsagesFirTestGenerated.java @@ -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) diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/findUsages/AbstractFindUsagesTest.kt b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/findUsages/AbstractFindUsagesTest.kt index a89b4024c805..ad7a10b373d4 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/findUsages/AbstractFindUsagesTest.kt +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/findUsages/AbstractFindUsagesTest.kt @@ -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, + filters: Collection<(UsageInfo2UsageAdapter) -> Boolean>, usageInfos: Collection ): Collection = 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 = 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 findUsagesAndCheckResults( ExpressionsOfTypeProcessor.mode = ExpressionsOfTypeProcessor.Mode.ALWAYS_SMART } - val filteringRules = AbstractFindUsagesTest.instantiateClasses(mainFileText, "// FILTERING_RULES: ") + val importFilteringRules: List<(UsageInfo2UsageAdapter) -> Boolean> = AbstractFindUsagesTest.instantiateClasses(mainFileText, "// FILTERING_RULES: ") + .map { rule -> { usageInfo -> rule.isVisible(usageInfo) } } + val filteringRules: List<(UsageInfo2UsageAdapter) -> Boolean> = AbstractFindUsagesTest.instantiateClasses(mainFileText, "// USAGE_FILTERING_RULES: ") + .map { rule -> { usageInfo -> rule.isVisible(usageInfo, emptyArray()) } } + val groupingRules = AbstractFindUsagesTest.instantiateClasses(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 diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/findUsages/FindUsagesTestGenerated.java b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/findUsages/FindUsagesTestGenerated.java index d42a940dfd23..bff3647760d7 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/findUsages/FindUsagesTestGenerated.java +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/findUsages/FindUsagesTestGenerated.java @@ -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) diff --git a/plugins/kotlin/idea/tests/testData/findUsages/java/findJavaFieldUsages/JKFieldUsagesReadWriteAccess.0.java b/plugins/kotlin/idea/tests/testData/findUsages/java/findJavaFieldUsages/JKFieldUsagesReadWriteAccess.0.java new file mode 100644 index 000000000000..d4f85f5cd0dc --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/findUsages/java/findJavaFieldUsages/JKFieldUsagesReadWriteAccess.0.java @@ -0,0 +1,10 @@ +// PSI_ELEMENT: com.intellij.psi.PsiField +// USAGE_FILTERING_RULES: com.intellij.usages.impl.rules.WriteAccessFilteringRule +public class Foo { + public String foo; + + public Foo(String foo) { + this.foo = foo; + } +} + diff --git a/plugins/kotlin/idea/tests/testData/findUsages/java/findJavaFieldUsages/JKFieldUsagesReadWriteAccess.1.kt b/plugins/kotlin/idea/tests/testData/findUsages/java/findJavaFieldUsages/JKFieldUsagesReadWriteAccess.1.kt new file mode 100644 index 000000000000..15ebf923bcd7 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/findUsages/java/findJavaFieldUsages/JKFieldUsagesReadWriteAccess.1.kt @@ -0,0 +1,3 @@ +fun bar() { + Foo("abc").foo = "foo" +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/findUsages/java/findJavaFieldUsages/JKFieldUsagesReadWriteAccess.results.txt b/plugins/kotlin/idea/tests/testData/findUsages/java/findJavaFieldUsages/JKFieldUsagesReadWriteAccess.results.txt new file mode 100644 index 000000000000..a3de9ea8a3ee --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/findUsages/java/findJavaFieldUsages/JKFieldUsagesReadWriteAccess.results.txt @@ -0,0 +1,2 @@ +[JKFieldUsagesReadWriteAccess.0.java] Unclassified 7 this.foo = foo; +[JKFieldUsagesReadWriteAccess.1.kt] Value write 2 Foo("abc").foo = "foo" diff --git a/plugins/kotlin/plugin/common/resources/META-INF/kotlin-core.xml b/plugins/kotlin/plugin/common/resources/META-INF/kotlin-core.xml index dfce6e05d719..f5a1abda4766 100644 --- a/plugins/kotlin/plugin/common/resources/META-INF/kotlin-core.xml +++ b/plugins/kotlin/plugin/common/resources/META-INF/kotlin-core.xml @@ -548,7 +548,9 @@ - +