From cd4a08cb185cc4bb58c50b579506d28e42054f6e Mon Sep 17 00:00:00 2001 From: Jinseong Jeon Date: Thu, 26 Aug 2021 11:41:13 -0700 Subject: [PATCH] Migrate ReadWriteAccess and checker logic (from frontend-independent) --- .../kotlin/idea/references/referenceUtils.kt | 43 +++++++++++++++++-- .../resolve/references/ReferenceAccess.kt | 15 +++++++ 2 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 core/compiler.common/src/org/jetbrains/kotlin/resolve/references/ReferenceAccess.kt diff --git a/compiler/psi/src/org/jetbrains/kotlin/idea/references/referenceUtils.kt b/compiler/psi/src/org/jetbrains/kotlin/idea/references/referenceUtils.kt index 8aacfc0ced1..6fccada43c9 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/idea/references/referenceUtils.kt +++ b/compiler/psi/src/org/jetbrains/kotlin/idea/references/referenceUtils.kt @@ -6,9 +6,12 @@ package org.jetbrains.kotlin.idea.references import org.jetbrains.kotlin.kdoc.psi.impl.KDocName -import org.jetbrains.kotlin.psi.KtElement -import org.jetbrains.kotlin.psi.KtReferenceExpression -import org.jetbrains.kotlin.psi.KtSimpleNameExpression +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.getAssignmentByLHS +import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis +import org.jetbrains.kotlin.resolve.references.ReferenceAccess +import org.jetbrains.kotlin.utils.addToStdlib.constant import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull @@ -27,3 +30,37 @@ val KtElement.mainReference: KtReference? is KDocName -> mainReference else -> references.firstIsInstanceOrNull() } + +fun KtExpression.readWriteAccess(useResolveForReadWrite: Boolean) = + readWriteAccessWithFullExpression(useResolveForReadWrite).first + +fun KtExpression.readWriteAccessWithFullExpression( + useResolveForReadWrite: Boolean, + readWriteAccessWithFullExpressionByResolve: (KtBinaryExpression) -> Pair? = { null }, +): Pair { + var expression = getQualifiedExpressionForSelectorOrThis() + loop@ while (true) { + when (val parent = expression.parent) { + is KtParenthesizedExpression, is KtAnnotatedExpression, is KtLabeledExpression -> expression = parent as KtExpression + else -> break@loop + } + } + + val assignment = expression.getAssignmentByLHS() + if (assignment != null) { + return when (assignment.operationToken) { + KtTokens.EQ -> ReferenceAccess.WRITE to assignment + + else -> { + (if (useResolveForReadWrite) readWriteAccessWithFullExpressionByResolve(assignment) else null) + ?: (ReferenceAccess.READ_WRITE to assignment) + } + } + } + + val unaryExpression = expression.parent as? KtUnaryExpression + return if (unaryExpression != null && unaryExpression.operationToken in constant { setOf(KtTokens.PLUSPLUS, KtTokens.MINUSMINUS) }) + ReferenceAccess.READ_WRITE to unaryExpression + else + ReferenceAccess.READ to expression +} diff --git a/core/compiler.common/src/org/jetbrains/kotlin/resolve/references/ReferenceAccess.kt b/core/compiler.common/src/org/jetbrains/kotlin/resolve/references/ReferenceAccess.kt new file mode 100644 index 00000000000..b855a7dba1c --- /dev/null +++ b/core/compiler.common/src/org/jetbrains/kotlin/resolve/references/ReferenceAccess.kt @@ -0,0 +1,15 @@ +/* + * Copyright 2010-2021 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.resolve.references + +enum class ReferenceAccess( + val isRead: Boolean, + val isWrite: Boolean +) { + READ(true, false), + WRITE(false, true), + READ_WRITE(true, true) +}