Make quick evaluate work on receiver in qualified expressions (KT-13269)

(cherry picked from commit 970ac5a)

 #KT-13269 Fixed
This commit is contained in:
Nikolay Krasko
2016-08-05 15:09:24 +03:00
committed by Nikolay Krasko
parent 7325baa06a
commit 7a4d20b4cf
10 changed files with 108 additions and 26 deletions
+2 -1
View File
@@ -269,7 +269,8 @@ Using 'this' as function argument in constructor of non-final class
- [`KT-13037`](https://youtrack.jetbrains.com/issue/KT-13037) Fix possible deadlock in debugger in 2016.1 and exception in 2016.2
- [`KT-12651`](https://youtrack.jetbrains.com/issue/KT-12651) Fix exception in evaluate expression when bad identifier is used for marking object
- [`KT-12896`](https://youtrack.jetbrains.com/issue/KT-12896) Fix "Step In" to inline functions for Android
- [`KT-7549`](https://youtrack.jetbrains.com/issue/KT-13037) Allow to evaluate kotlin expressions in Java files
- [`KT-13269`](https://youtrack.jetbrains.com/issue/KT-13269) Make quick evaluate work on receiver in qualified expressions
- [`KT-7549`](https://youtrack.jetbrains.com/issue/KT-7549) Allow to evaluate kotlin expressions in Java files
### JS
@@ -61,40 +61,48 @@ class KotlinEditorTextProvider : EditorTextProvider {
fun findExpressionInner(element: PsiElement, allowMethodCalls: Boolean): KtExpression? {
if (!isAcceptedAsCodeFragmentContext(element)) return null
val jetElement = PsiTreeUtil.getParentOfType(element, KtElement::class.java)
if (jetElement == null) return null
val ktElement = PsiTreeUtil.getParentOfType(element, KtElement::class.java) ?: return null
if (jetElement is KtProperty) {
val nameIdentifier = jetElement.nameIdentifier
if (ktElement is KtProperty) {
val nameIdentifier = ktElement.nameIdentifier
if (nameIdentifier == element) {
return jetElement
return ktElement
}
}
val parent = jetElement.parent
if (parent == null) return null
val parent = ktElement.parent ?: return null
val newExpression = when (parent) {
is KtThisExpression,
is KtSuperExpression,
is KtReferenceExpression -> {
is KtThisExpression -> parent
is KtSuperExpression -> {
val pparent = parent.parent
when (pparent) {
is KtQualifiedExpression -> pparent
else -> parent
}
}
is KtQualifiedExpression -> {
if (parent.receiverExpression != jetElement) {
is KtReferenceExpression -> {
val pparent = parent.parent
if (pparent is KtQualifiedExpression && pparent.selectorExpression == parent) {
pparent
}
else {
parent
} else {
}
}
is KtQualifiedExpression -> {
if (parent.receiverExpression != ktElement) {
parent
}
else {
null
}
}
is KtOperationExpression -> {
if (parent.operationReference == jetElement) {
if (parent.operationReference == ktElement) {
parent
} else {
}
else {
null
}
}
@@ -104,22 +112,21 @@ class KotlinEditorTextProvider : EditorTextProvider {
if (!allowMethodCalls && newExpression != null) {
fun PsiElement.isCall() = this is KtCallExpression || this is KtOperationExpression || this is KtArrayAccessExpression
if (newExpression.isCall() ||
newExpression is KtQualifiedExpression && newExpression.selectorExpression!!.isCall()) {
if (newExpression.isCall() || newExpression is KtQualifiedExpression && newExpression.selectorExpression!!.isCall()) {
return null
}
}
return when {
newExpression is KtExpression -> newExpression
jetElement is KtSimpleNameExpression -> {
val context = jetElement.analyzeAndGetResult().bindingContext
val qualifier = context[BindingContext.QUALIFIER, jetElement]
ktElement is KtSimpleNameExpression -> {
val context = ktElement.analyzeAndGetResult().bindingContext
val qualifier = context[BindingContext.QUALIFIER, ktElement]
if (qualifier != null && !DescriptorUtils.isObject(qualifier.descriptor)) {
null
}
else {
jetElement
ktElement
}
}
else -> null
@@ -135,5 +142,4 @@ class KotlinEditorTextProvider : EditorTextProvider {
PsiTreeUtil.getParentOfType(element, *NOT_ACCEPTED_AS_CONTEXT_TYPES) == null
}
}
}
}
@@ -0,0 +1,11 @@
class Derived: Base() {
fun test() {
super.<caret>test()
}
}
open class Base {
fun test() {}
}
// EXPECTED: null
@@ -4,4 +4,4 @@ class MyClass {
}
}
// EXPECTED: null
// EXPECTED: this
@@ -0,0 +1,7 @@
class MyClass {
fun test() {
<caret>this.test()
}
}
// EXPECTED: this
@@ -0,0 +1,9 @@
fun one() = "one"
fun String.two() = this + "two"
fun String.three() = this + "three"
fun main(args: Array<String>) {
val s = <caret>one().two().three() // Can't select 'one()' with Alt in debugger, only 'one().two()' and 'one().two().three()' are available
}
// EXPECTED: one()
@@ -0,0 +1,11 @@
class Derived: Base() {
fun test() {
super.<caret>test()
}
}
open class Base {
fun test() {}
}
// EXPECTED: super.test()
+1 -1
View File
@@ -4,4 +4,4 @@ class MyClass {
}
}
// EXPECTED: this.test()
// EXPECTED: this
@@ -0,0 +1,7 @@
class MyClass {
fun test() {
this.<caret>test()
}
}
// EXPECTED: this.test()
@@ -79,6 +79,12 @@ public class SelectExpressionForDebuggerTestGenerated extends AbstractSelectExpr
doTest(fileName);
}
@TestMetadata("firstCallInChain.kt")
public void testFirstCallInChain() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/selectExpression/firstCallInChain.kt");
doTest(fileName);
}
@TestMetadata("fullyQualified.kt")
public void testFullyQualified() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/selectExpression/fullyQualified.kt");
@@ -205,12 +211,24 @@ public class SelectExpressionForDebuggerTestGenerated extends AbstractSelectExpr
doTest(fileName);
}
@TestMetadata("superSelector.kt")
public void testSuperSelector() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/selectExpression/superSelector.kt");
doTest(fileName);
}
@TestMetadata("this.kt")
public void testThis() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/selectExpression/this.kt");
doTest(fileName);
}
@TestMetadata("thisSelector.kt")
public void testThisSelector() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/selectExpression/thisSelector.kt");
doTest(fileName);
}
@TestMetadata("thisWithLabel.kt")
public void testThisWithLabel() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/selectExpression/thisWithLabel.kt");
@@ -340,12 +358,24 @@ public class SelectExpressionForDebuggerTestGenerated extends AbstractSelectExpr
doTestWoMethodCalls(fileName);
}
@TestMetadata("superSelector.kt")
public void testSuperSelector() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/selectExpression/disallowMethodCalls/superSelector.kt");
doTestWoMethodCalls(fileName);
}
@TestMetadata("this.kt")
public void testThis() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/selectExpression/disallowMethodCalls/this.kt");
doTestWoMethodCalls(fileName);
}
@TestMetadata("thisSelector.kt")
public void testThisSelector() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/selectExpression/disallowMethodCalls/thisSelector.kt");
doTestWoMethodCalls(fileName);
}
@TestMetadata("thisWithLabel.kt")
public void testThisWithLabel() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/selectExpression/disallowMethodCalls/thisWithLabel.kt");