Make quick evaluate work on receiver in qualified expressions (KT-13269)
(cherry picked from commit 970ac5a) #KT-13269 Fixed
This commit is contained in:
committed by
Nikolay Krasko
parent
7325baa06a
commit
7a4d20b4cf
+2
-1
@@ -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-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-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-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
|
### JS
|
||||||
|
|
||||||
|
|||||||
@@ -61,40 +61,48 @@ class KotlinEditorTextProvider : EditorTextProvider {
|
|||||||
fun findExpressionInner(element: PsiElement, allowMethodCalls: Boolean): KtExpression? {
|
fun findExpressionInner(element: PsiElement, allowMethodCalls: Boolean): KtExpression? {
|
||||||
if (!isAcceptedAsCodeFragmentContext(element)) return null
|
if (!isAcceptedAsCodeFragmentContext(element)) return null
|
||||||
|
|
||||||
val jetElement = PsiTreeUtil.getParentOfType(element, KtElement::class.java)
|
val ktElement = PsiTreeUtil.getParentOfType(element, KtElement::class.java) ?: return null
|
||||||
if (jetElement == null) return null
|
|
||||||
|
|
||||||
if (jetElement is KtProperty) {
|
if (ktElement is KtProperty) {
|
||||||
val nameIdentifier = jetElement.nameIdentifier
|
val nameIdentifier = ktElement.nameIdentifier
|
||||||
if (nameIdentifier == element) {
|
if (nameIdentifier == element) {
|
||||||
return jetElement
|
return ktElement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val parent = jetElement.parent
|
val parent = ktElement.parent ?: return null
|
||||||
if (parent == null) return null
|
|
||||||
|
|
||||||
val newExpression = when (parent) {
|
val newExpression = when (parent) {
|
||||||
is KtThisExpression,
|
is KtThisExpression -> parent
|
||||||
is KtSuperExpression,
|
is KtSuperExpression -> {
|
||||||
is KtReferenceExpression -> {
|
|
||||||
val pparent = parent.parent
|
val pparent = parent.parent
|
||||||
when (pparent) {
|
when (pparent) {
|
||||||
is KtQualifiedExpression -> pparent
|
is KtQualifiedExpression -> pparent
|
||||||
else -> parent
|
else -> parent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is KtQualifiedExpression -> {
|
is KtReferenceExpression -> {
|
||||||
if (parent.receiverExpression != jetElement) {
|
val pparent = parent.parent
|
||||||
|
if (pparent is KtQualifiedExpression && pparent.selectorExpression == parent) {
|
||||||
|
pparent
|
||||||
|
}
|
||||||
|
else {
|
||||||
parent
|
parent
|
||||||
} else {
|
}
|
||||||
|
}
|
||||||
|
is KtQualifiedExpression -> {
|
||||||
|
if (parent.receiverExpression != ktElement) {
|
||||||
|
parent
|
||||||
|
}
|
||||||
|
else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is KtOperationExpression -> {
|
is KtOperationExpression -> {
|
||||||
if (parent.operationReference == jetElement) {
|
if (parent.operationReference == ktElement) {
|
||||||
parent
|
parent
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,22 +112,21 @@ class KotlinEditorTextProvider : EditorTextProvider {
|
|||||||
if (!allowMethodCalls && newExpression != null) {
|
if (!allowMethodCalls && newExpression != null) {
|
||||||
fun PsiElement.isCall() = this is KtCallExpression || this is KtOperationExpression || this is KtArrayAccessExpression
|
fun PsiElement.isCall() = this is KtCallExpression || this is KtOperationExpression || this is KtArrayAccessExpression
|
||||||
|
|
||||||
if (newExpression.isCall() ||
|
if (newExpression.isCall() || newExpression is KtQualifiedExpression && newExpression.selectorExpression!!.isCall()) {
|
||||||
newExpression is KtQualifiedExpression && newExpression.selectorExpression!!.isCall()) {
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
newExpression is KtExpression -> newExpression
|
newExpression is KtExpression -> newExpression
|
||||||
jetElement is KtSimpleNameExpression -> {
|
ktElement is KtSimpleNameExpression -> {
|
||||||
val context = jetElement.analyzeAndGetResult().bindingContext
|
val context = ktElement.analyzeAndGetResult().bindingContext
|
||||||
val qualifier = context[BindingContext.QUALIFIER, jetElement]
|
val qualifier = context[BindingContext.QUALIFIER, ktElement]
|
||||||
if (qualifier != null && !DescriptorUtils.isObject(qualifier.descriptor)) {
|
if (qualifier != null && !DescriptorUtils.isObject(qualifier.descriptor)) {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
jetElement
|
ktElement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> null
|
else -> null
|
||||||
@@ -135,5 +142,4 @@ class KotlinEditorTextProvider : EditorTextProvider {
|
|||||||
PsiTreeUtil.getParentOfType(element, *NOT_ACCEPTED_AS_CONTEXT_TYPES) == null
|
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
@@ -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()
|
||||||
+30
@@ -79,6 +79,12 @@ public class SelectExpressionForDebuggerTestGenerated extends AbstractSelectExpr
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("fullyQualified.kt")
|
||||||
public void testFullyQualified() throws Exception {
|
public void testFullyQualified() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/selectExpression/fullyQualified.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/selectExpression/fullyQualified.kt");
|
||||||
@@ -205,12 +211,24 @@ public class SelectExpressionForDebuggerTestGenerated extends AbstractSelectExpr
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("this.kt")
|
||||||
public void testThis() throws Exception {
|
public void testThis() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/selectExpression/this.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/selectExpression/this.kt");
|
||||||
doTest(fileName);
|
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")
|
@TestMetadata("thisWithLabel.kt")
|
||||||
public void testThisWithLabel() throws Exception {
|
public void testThisWithLabel() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/selectExpression/thisWithLabel.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/selectExpression/thisWithLabel.kt");
|
||||||
@@ -340,12 +358,24 @@ public class SelectExpressionForDebuggerTestGenerated extends AbstractSelectExpr
|
|||||||
doTestWoMethodCalls(fileName);
|
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")
|
@TestMetadata("this.kt")
|
||||||
public void testThis() throws Exception {
|
public void testThis() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/selectExpression/disallowMethodCalls/this.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/selectExpression/disallowMethodCalls/this.kt");
|
||||||
doTestWoMethodCalls(fileName);
|
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")
|
@TestMetadata("thisWithLabel.kt")
|
||||||
public void testThisWithLabel() throws Exception {
|
public void testThisWithLabel() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/selectExpression/disallowMethodCalls/thisWithLabel.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/selectExpression/disallowMethodCalls/thisWithLabel.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user