From a31d383b4d4c1bec381105d5c5ae70de10c93d02 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Wed, 1 Jun 2022 09:04:01 +0200 Subject: [PATCH] Analysis API: add implementation of ReadWriteAccessChecker via descriptors --- .../ReadWriteAccessCheckerDescriptorsImpl.kt | 31 +++++++++++++++++++ .../AnalysisApiFe10TestServiceRegistrar.kt | 3 ++ .../idea/references/ReadWriteAccessChecker.kt | 17 +++++----- 3 files changed, 42 insertions(+), 9 deletions(-) create mode 100644 analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/references/ReadWriteAccessCheckerDescriptorsImpl.kt diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/references/ReadWriteAccessCheckerDescriptorsImpl.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/references/ReadWriteAccessCheckerDescriptorsImpl.kt new file mode 100644 index 00000000000..0d31a0461dd --- /dev/null +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/references/ReadWriteAccessCheckerDescriptorsImpl.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.analysis.api.descriptors.references + +import org.jetbrains.kotlin.analysis.api.analyze +import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisFacade +import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession +import org.jetbrains.kotlin.idea.references.ReadWriteAccessChecker +import org.jetbrains.kotlin.psi.KtBinaryExpression +import org.jetbrains.kotlin.psi.KtExpression +import org.jetbrains.kotlin.resolve.calls.util.getCall +import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall +import org.jetbrains.kotlin.resolve.references.ReferenceAccess +import org.jetbrains.kotlin.types.expressions.OperatorConventions + +class ReadWriteAccessCheckerDescriptorsImpl : ReadWriteAccessChecker { + override fun readWriteAccessWithFullExpressionByResolve(assignment: KtBinaryExpression): Pair { + val resolvedCall = analyze(assignment) { + with((this as KtFe10AnalysisSession).analysisContext.analyze(assignment, Fe10AnalysisFacade.AnalysisMode.PARTIAL)) { + assignment.getCall(this)?.getResolvedCall(this) ?: return ReferenceAccess.READ_WRITE to assignment + } + } + return if (resolvedCall.resultingDescriptor.name in OperatorConventions.ASSIGNMENT_OPERATIONS.values) + ReferenceAccess.READ to assignment + else + ReferenceAccess.READ_WRITE to assignment + } +} diff --git a/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/test/configurator/AnalysisApiFe10TestServiceRegistrar.kt b/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/test/configurator/AnalysisApiFe10TestServiceRegistrar.kt index d19abd1e126..011f594fc12 100644 --- a/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/test/configurator/AnalysisApiFe10TestServiceRegistrar.kt +++ b/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/test/configurator/AnalysisApiFe10TestServiceRegistrar.kt @@ -13,11 +13,13 @@ import org.jetbrains.kotlin.analysis.api.descriptors.CliFe10AnalysisFacade import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisFacade import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisHandlerExtension import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSessionProvider +import org.jetbrains.kotlin.analysis.api.descriptors.references.ReadWriteAccessCheckerDescriptorsImpl import org.jetbrains.kotlin.references.fe10.base.KtFe10KotlinReferenceProviderContributor import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestServiceRegistrar import org.jetbrains.kotlin.cli.common.CliModuleVisibilityManagerImpl import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.idea.references.KotlinReferenceProviderContributor +import org.jetbrains.kotlin.idea.references.ReadWriteAccessChecker import org.jetbrains.kotlin.light.classes.symbol.caches.SymbolLightClassFacadeCache import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager import org.jetbrains.kotlin.resolve.extensions.AnalysisHandlerExtension @@ -36,6 +38,7 @@ object AnalysisApiFe10TestServiceRegistrar : AnalysisApiTestServiceRegistrar() { registerService(ModuleVisibilityManager::class.java, CliModuleVisibilityManagerImpl(enabled = true)) registerService(SymbolLightClassFacadeCache::class.java) + registerService(ReadWriteAccessChecker::class.java, ReadWriteAccessCheckerDescriptorsImpl()) } AnalysisHandlerExtension.registerExtension(project, KtFe10AnalysisHandlerExtension()) KotlinCoreEnvironment.registerKotlinLightClassSupport(project) diff --git a/analysis/kt-references/src/org/jetbrains/kotlin/idea/references/ReadWriteAccessChecker.kt b/analysis/kt-references/src/org/jetbrains/kotlin/idea/references/ReadWriteAccessChecker.kt index e991d2fe9cf..526bfa9f91f 100644 --- a/analysis/kt-references/src/org/jetbrains/kotlin/idea/references/ReadWriteAccessChecker.kt +++ b/analysis/kt-references/src/org/jetbrains/kotlin/idea/references/ReadWriteAccessChecker.kt @@ -5,7 +5,7 @@ package org.jetbrains.kotlin.idea.references -import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.project.Project import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getAssignmentByLHS @@ -48,17 +48,16 @@ interface ReadWriteAccessChecker { } companion object { - fun getInstance(): ReadWriteAccessChecker = ApplicationManager.getApplication().getService(ReadWriteAccessChecker::class.java) + fun getInstance(project: Project): ReadWriteAccessChecker = project.getService(ReadWriteAccessChecker::class.java) } } +// Used in IDE +@Suppress("unused") fun KtExpression.readWriteAccessWithFullExpression(useResolveForReadWrite: Boolean): Pair = - ReadWriteAccessChecker.getInstance().readWriteAccessWithFullExpression(this, useResolveForReadWrite) + ReadWriteAccessChecker.getInstance(project).readWriteAccessWithFullExpression(this, useResolveForReadWrite) -fun KtExpression.readWriteAccess(useResolveForReadWrite: Boolean): ReferenceAccess = - object : ReadWriteAccessChecker { - override fun readWriteAccessWithFullExpressionByResolve( - assignment: KtBinaryExpression - ): Pair? = null - }.readWriteAccessWithFullExpression(this, useResolveForReadWrite).first +fun KtExpression.readWriteAccess(useResolveForReadWrite: Boolean): ReferenceAccess { + return ReadWriteAccessChecker.getInstance(project).readWriteAccessWithFullExpression(this, useResolveForReadWrite).first +}