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.search.LocalSearchScope
|
||||
import com.intellij.psi.search.SearchScope
|
||||
import com.intellij.psi.search.searches.ReferencesSearch
|
||||
import com.intellij.slicer.SliceUsage
|
||||
import com.intellij.usageView.UsageInfo
|
||||
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.refactoring.changeSignature.KotlinValVar
|
||||
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.readWriteAccessWithFullExpression
|
||||
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.scopes.receivers.ExpressionReceiver
|
||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import java.util.*
|
||||
|
||||
private fun KtDeclaration.processHierarchyDownward(scope: SearchScope, processor: KtDeclaration.() -> Unit) {
|
||||
@@ -230,6 +233,16 @@ class InflowSlicer(
|
||||
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
|
||||
|
||||
(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);
|
||||
}
|
||||
|
||||
@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")
|
||||
public void testInflow_TopLevelVal() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/slicer/inflow/topLevelVal.kt");
|
||||
|
||||
Reference in New Issue
Block a user