From 1b93e2030f765f614d7dd3185af70b307b1987f3 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Wed, 26 Jul 2017 15:26:13 +0300 Subject: [PATCH] Create isCallee utility function --- .../jetbrains/kotlin/psi/psiUtil/ktPsiUtil.kt | 27 +++++++++++ compiler/testData/psiUtil/isCallee.kt | 46 +++++++++++++++++++ .../jetbrains/kotlin/psi/KtPsiUtilTest.java | 12 ++++- .../quickfix/RenameUnresolvedReferenceFix.kt | 2 - 4 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/psiUtil/isCallee.kt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/ktPsiUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/ktPsiUtil.kt index 94a6e49cd45..122e1ed2e8f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/ktPsiUtil.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/ktPsiUtil.kt @@ -357,6 +357,33 @@ fun KtStringTemplateExpression.getContentRange(): TextRange { return TextRange(start, if (lastChild.elementType == KtTokens.CLOSING_QUOTE) length - lastChild.textLength else length) } +/** + * Check expression might be a callee of call with the same name. + * Note that 'this' in 'this(args)' isn't considered to be a callee, also 'name' is not a callee in 'name++'. + */ +fun KtSimpleNameExpression.isCallee(): Boolean { + val parent = parent + return when (parent) { + is KtCallElement -> parent.calleeExpression == this + is KtBinaryExpression -> parent.operationReference == this + else -> { + val callElement = + getStrictParentOfType() + ?.getStrictParentOfType() + ?.getStrictParentOfType() + ?.getStrictParentOfType() + + if (callElement != null) { + val ktConstructorCalleeExpression = callElement.calleeExpression as? KtConstructorCalleeExpression + (ktConstructorCalleeExpression?.typeReference?.typeElement as? KtUserType)?.referenceExpression == this + } + else { + false + } + } + } +} + val KtStringTemplateExpression.plainContent: String get() = getContentRange().substring(text) diff --git a/compiler/testData/psiUtil/isCallee.kt b/compiler/testData/psiUtil/isCallee.kt new file mode 100644 index 00000000000..3e21782eb32 --- /dev/null +++ b/compiler/testData/psiUtil/isCallee.kt @@ -0,0 +1,46 @@ +package aa + +annotation class A(val b: B) +annotation class B +annotation class C +open class D(a: Any) { + open fun test() {} +} +open class E +class F +interface G + +@aa./*true*/A(/*true*/B()) +@C +class I: /*true*/D(/*true*/E()) { + override fun test() { + /*false*/super./*true*/test() + /*false*/this@I() + } + + operator fun invoke() {} +} + +class K constructor(): /*false*/G { + constructor(i: Int): this() +} + +class L: /*false*/E { + constructor(i: Int): super() +} + +fun a() = 12 +fun Int.b() = 12 +infix fun Int.c(i: Int) = 12 + +fun foo(a: Int = /*true*/a()) { + 12./*true*/b() + /*false*/aa./*true*/a() + 12 /*true*/c 12 + var b = 12 + /*false*/b++ +} + +fun ((i: Int) -> Int).f() { + /*false*/this(12) +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/psi/KtPsiUtilTest.java b/compiler/tests/org/jetbrains/kotlin/psi/KtPsiUtilTest.java index a14f8f15f26..da339cdb9db 100644 --- a/compiler/tests/org/jetbrains/kotlin/psi/KtPsiUtilTest.java +++ b/compiler/tests/org/jetbrains/kotlin/psi/KtPsiUtilTest.java @@ -18,11 +18,13 @@ package org.jetbrains.kotlin.psi; import com.intellij.openapi.util.io.FileUtil; import com.intellij.psi.util.PsiTreeUtil; +import kotlin.jvm.functions.Function1; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles; import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.Name; +import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt; import org.jetbrains.kotlin.resolve.ImportPath; import org.jetbrains.kotlin.test.KotlinTestUtils; import org.jetbrains.kotlin.test.KotlinTestWithEnvironment; @@ -107,6 +109,10 @@ public class KtPsiUtilTest extends KotlinTestWithEnvironment { checkIsSelectorInQualified(); } + public void testIsCallee() { + checkExpression(KtPsiUtilKt::isCallee); + } + @Override protected KotlinCoreEnvironment createEnvironment() { return KotlinCoreEnvironment.createForTests( @@ -124,6 +130,10 @@ public class KtPsiUtilTest extends KotlinTestWithEnvironment { } private void checkIsSelectorInQualified() { + checkExpression(KtPsiUtil::isSelectorInQualified); + } + + private void checkExpression(Function1 checkedFunction) { String trueResultString = "/*true*/"; String falseResultString = "/*false*/"; @@ -144,7 +154,7 @@ public class KtPsiUtilTest extends KotlinTestWithEnvironment { Assert.assertNotNull("Can't find expression in text:\n" + modifiedWithOffset, expression); Assert.assertSame(expected + " result was expected at\n" + modifiedWithOffset, - expected, KtPsiUtil.isSelectorInQualified(expression)); + expected, checkedFunction.invoke(expression)); } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/RenameUnresolvedReferenceFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/RenameUnresolvedReferenceFix.kt index b0ad6a13f48..7bab2f50e55 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/RenameUnresolvedReferenceFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/RenameUnresolvedReferenceFix.kt @@ -82,8 +82,6 @@ class RenameUnresolvedReferenceFix(element: KtNameReferenceExpression): KotlinQu && element.getStrictParentOfType() == null } - private fun KtExpression.isCallee() = getParentOfTypeAndBranch { calleeExpression } != null - override fun invoke(project: Project, editor: Editor?, file: KtFile) { val element = element ?: return if (editor == null) return