Data Inflow: Support delegated assignments
#KT-19089 Fixed
This commit is contained in:
@@ -21,6 +21,7 @@ import com.intellij.codeInsight.highlighting.ReadWriteAccessDetector.Access
|
|||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.search.LocalSearchScope
|
import com.intellij.psi.search.LocalSearchScope
|
||||||
import com.intellij.psi.search.SearchScope
|
import com.intellij.psi.search.SearchScope
|
||||||
|
import com.intellij.psi.search.searches.ReferencesSearch
|
||||||
import com.intellij.slicer.SliceUsage
|
import com.intellij.slicer.SliceUsage
|
||||||
import com.intellij.usageView.UsageInfo
|
import com.intellij.usageView.UsageInfo
|
||||||
import com.intellij.util.Processor
|
import com.intellij.util.Processor
|
||||||
@@ -48,6 +49,7 @@ import org.jetbrains.kotlin.idea.findUsages.KotlinPropertyFindUsagesOptions
|
|||||||
import org.jetbrains.kotlin.idea.findUsages.processAllExactUsages
|
import org.jetbrains.kotlin.idea.findUsages.processAllExactUsages
|
||||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinValVar
|
import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinValVar
|
||||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.toValVar
|
import org.jetbrains.kotlin.idea.refactoring.changeSignature.toValVar
|
||||||
|
import org.jetbrains.kotlin.idea.references.KtPropertyDelegationMethodsReference
|
||||||
import org.jetbrains.kotlin.idea.references.ReferenceAccess
|
import org.jetbrains.kotlin.idea.references.ReferenceAccess
|
||||||
import org.jetbrains.kotlin.idea.references.readWriteAccessWithFullExpression
|
import org.jetbrains.kotlin.idea.references.readWriteAccessWithFullExpression
|
||||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest
|
import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest
|
||||||
@@ -63,6 +65,7 @@ import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument
|
|||||||
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument
|
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||||
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
private fun KtDeclaration.processHierarchyDownward(scope: SearchScope, processor: KtDeclaration.() -> Unit) {
|
private fun KtDeclaration.processHierarchyDownward(scope: SearchScope, processor: KtDeclaration.() -> Unit) {
|
||||||
@@ -230,6 +233,16 @@ class InflowSlicer(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (function is KtNamedFunction
|
||||||
|
&& function.name == OperatorNameConventions.SET_VALUE.asString()
|
||||||
|
&& function.hasModifier(KtTokens.OPERATOR_KEYWORD)) {
|
||||||
|
|
||||||
|
ReferencesSearch
|
||||||
|
.search(function, parentUsage.scope.toSearchScope())
|
||||||
|
.filterIsInstance<KtPropertyDelegationMethodsReference>()
|
||||||
|
.forEach { (it.element?.parent as? KtProperty)?.processPropertyAssignments() }
|
||||||
|
}
|
||||||
|
|
||||||
val parameterDescriptor = analyze()[BindingContext.VALUE_PARAMETER, this] ?: return
|
val parameterDescriptor = analyze()[BindingContext.VALUE_PARAMETER, this] ?: return
|
||||||
|
|
||||||
(function as? KtFunction)?.processCalls(parentUsage.scope.toSearchScope()) body@ {
|
(function as? KtFunction)?.processCalls(parentUsage.scope.toSearchScope()) body@ {
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
// FLOW: IN
|
||||||
|
|
||||||
|
class Delegate {
|
||||||
|
private var _value: String = ""
|
||||||
|
operator fun getValue(thisRef: Any?, property: KProperty<*>) = _value
|
||||||
|
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
|
||||||
|
_value = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AClass(name1: String){
|
||||||
|
var name by Delegate()
|
||||||
|
init {
|
||||||
|
name = name1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun uses(){
|
||||||
|
name = "bye"
|
||||||
|
println("Now my name is '$name'")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val a = AClass("hello")
|
||||||
|
println("My name is '${a.<caret>name}'")
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
25 println("My name is '${a.<bold>name</bold>}'")
|
||||||
|
12 var <bold>name by Delegate()</bold>
|
||||||
|
5 operator fun <bold>getValue(thisRef: Any?, property: KProperty<*>) = _value</bold>
|
||||||
|
5 operator fun getValue(thisRef: Any?, property: KProperty<*>) = <bold>_value</bold>
|
||||||
|
4 private var <bold>_value: String = ""</bold>
|
||||||
|
4 private var _value: String = <bold>""</bold>
|
||||||
|
7 _value = <bold>value</bold>
|
||||||
|
6 operator fun setValue(thisRef: Any?, property: KProperty<*>, <bold>value: String</bold>) {
|
||||||
|
14 name = <bold>name1</bold>
|
||||||
|
11 class AClass(<bold>name1: String</bold>){
|
||||||
|
24 val a = AClass(<bold>"hello"</bold>)
|
||||||
|
18 name = <bold>"bye"</bold>
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
// FLOW: IN
|
||||||
|
|
||||||
|
class Delegate {
|
||||||
|
private var _value: String = ""
|
||||||
|
operator fun getValue(thisRef: Any?, property: KProperty<*>) = _value
|
||||||
|
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
|
||||||
|
_value = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AClass(name1: String){
|
||||||
|
var name by Delegate()
|
||||||
|
init {
|
||||||
|
name = name1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun uses(){
|
||||||
|
name = "bye"
|
||||||
|
println("Now my name is '$<caret>name'")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val a = AClass("hello")
|
||||||
|
println("My name is '${a.name}'")
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
19 println("Now my name is '$<bold>name</bold>'")
|
||||||
|
12 var <bold>name by Delegate()</bold>
|
||||||
|
5 operator fun <bold>getValue(thisRef: Any?, property: KProperty<*>) = _value</bold>
|
||||||
|
5 operator fun getValue(thisRef: Any?, property: KProperty<*>) = <bold>_value</bold>
|
||||||
|
4 private var <bold>_value: String = ""</bold>
|
||||||
|
4 private var _value: String = <bold>""</bold>
|
||||||
|
7 _value = <bold>value</bold>
|
||||||
|
6 operator fun setValue(thisRef: Any?, property: KProperty<*>, <bold>value: String</bold>) {
|
||||||
|
14 name = <bold>name1</bold>
|
||||||
|
11 class AClass(<bold>name1: String</bold>){
|
||||||
|
24 val a = AClass(<bold>"hello"</bold>)
|
||||||
|
18 name = <bold>"bye"</bold>
|
||||||
@@ -306,6 +306,18 @@ public class SlicerTestGenerated extends AbstractSlicerTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inflow/settersViaDelegateForQualifiedRef.kt")
|
||||||
|
public void testInflow_SettersViaDelegateForQualifiedRef() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/slicer/inflow/settersViaDelegateForQualifiedRef.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inflow/settersViaDelegateForSimpleRef.kt")
|
||||||
|
public void testInflow_SettersViaDelegateForSimpleRef() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/slicer/inflow/settersViaDelegateForSimpleRef.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("inflow/topLevelVal.kt")
|
@TestMetadata("inflow/topLevelVal.kt")
|
||||||
public void testInflow_TopLevelVal() throws Exception {
|
public void testInflow_TopLevelVal() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/slicer/inflow/topLevelVal.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/slicer/inflow/topLevelVal.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user