Create isCallee utility function

This commit is contained in:
Nikolay Krasko
2017-07-26 15:26:13 +03:00
parent 142a64e039
commit 1b93e2030f
4 changed files with 84 additions and 3 deletions
@@ -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<KtUserType>()
?.getStrictParentOfType<KtTypeReference>()
?.getStrictParentOfType<KtConstructorCalleeExpression>()
?.getStrictParentOfType<KtCallElement>()
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)
+46
View File
@@ -0,0 +1,46 @@
package aa
annotation class A(val b: B)
annotation class B
annotation class C
open class D<T>(a: Any) {
open fun test() {}
}
open class E
class F
interface G
@aa./*true*/A(/*true*/B())
@C
class I<T>: /*true*/D<T>(/*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)
}
@@ -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<KtSimpleNameExpression, Boolean> 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));
}
}
}
@@ -82,8 +82,6 @@ class RenameUnresolvedReferenceFix(element: KtNameReferenceExpression): KotlinQu
&& element.getStrictParentOfType<KtTypeReference>() == null
}
private fun KtExpression.isCallee() = getParentOfTypeAndBranch<KtCallElement> { calleeExpression } != null
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
val element = element ?: return
if (editor == null) return