From fa8c6e7fb69f3cb6446ab080619b62a11fd6aa7e Mon Sep 17 00:00:00 2001 From: Kevin Bierhoff Date: Tue, 28 Jul 2020 00:03:22 -0700 Subject: [PATCH] Uast: KT-40578: resolve Kotlin property writes to setters (#3597) * KT-40578: resolve Kotlin property writes to setters * limit to non-constructor properties * Uast: `KotlinIDERenderLogTest.testConstructors` fix Co-authored-by: Nicolay Mitropolsky --- .../internal/kotlinInternalUastUtils.kt | 16 ++--- .../testData/Constructors.identifiers.txt | 9 +++ plugins/uast-kotlin/testData/Constructors.kt | 9 ++- .../testData/Constructors.log-ide.txt | 18 +++++- .../uast-kotlin/testData/Constructors.log.txt | 16 +++++ .../testData/Constructors.refNames.txt | 6 ++ .../testData/Constructors.render-ide.txt | 10 ++++ .../testData/Constructors.render.txt | 10 ++++ .../testData/Constructors.resolved.txt | 15 +++-- .../testData/PropertyReferences.kt | 30 ++++++++++ .../testData/PropertyReferences.resolved.txt | 58 +++++++++++++++++++ .../tests/KotlinUastResolveEverythingTest.kt | 3 + 12 files changed, 187 insertions(+), 13 deletions(-) create mode 100644 plugins/uast-kotlin/testData/PropertyReferences.kt create mode 100644 plugins/uast-kotlin/testData/PropertyReferences.resolved.txt diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/internal/kotlinInternalUastUtils.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/internal/kotlinInternalUastUtils.kt index 5aa117e49f2..632e3616da5 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/internal/kotlinInternalUastUtils.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/internal/kotlinInternalUastUtils.kt @@ -26,12 +26,9 @@ import com.intellij.psi.impl.compiled.ClsTypeElementImpl import com.intellij.psi.impl.compiled.SignatureParsing import com.intellij.psi.impl.compiled.StubBuildingVisitor import com.intellij.psi.util.PsiTypesUtil -import org.jetbrains.kotlin.asJava.LightClassUtil +import org.jetbrains.kotlin.asJava.* import org.jetbrains.kotlin.asJava.classes.KtLightClass import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass -import org.jetbrains.kotlin.asJava.findFacadeClass -import org.jetbrains.kotlin.asJava.toLightClass -import org.jetbrains.kotlin.asJava.toLightElements import org.jetbrains.kotlin.builtins.isBuiltinFunctionalTypeOrSubtype import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter import org.jetbrains.kotlin.descriptors.* @@ -334,7 +331,7 @@ internal fun resolveToDeclaration(sourcePsi: KtExpression): PsiElement? = } internal fun resolveToDeclaration(sourcePsi: KtExpression, declarationDescriptor: DeclarationDescriptor): PsiElement? { - declarationDescriptor.toSource()?.getMaybeLightElement()?.let { return it } + declarationDescriptor.toSource()?.getMaybeLightElement(sourcePsi)?.let { return it } var declarationDescriptor = declarationDescriptor if (declarationDescriptor is ImportedFromObjectCallableDescriptor<*>) { @@ -446,8 +443,8 @@ private fun resolveDeserialized( if (propertySignature != null) { with(propertySignature) { when { + hasSetter() && accessHint?.isWrite == true -> setter // treat += etc. as write as was done elsewhere hasGetter() && accessHint?.isRead != false -> getter - hasSetter() && accessHint?.isWrite != false -> setter else -> null // it should have been handled by the previous case } }?.let { methodSignature -> @@ -513,7 +510,12 @@ private fun KotlinType.containsLocalTypes(): Boolean { return arguments.any { !it.isStarProjection && it.type.containsLocalTypes() } } -private fun PsiElement.getMaybeLightElement(): PsiElement? { +private fun PsiElement.getMaybeLightElement(sourcePsi: KtExpression? = null): PsiElement? { + if (this is KtProperty && sourcePsi?.readWriteAccess()?.isWrite == true) { + with(getAccessorLightMethods()) { + (setter ?: backingField)?.let { return it } // backingField is for val property assignments in init blocks + } + } return when (this) { is KtDeclaration -> { val lightElement = toLightElements().firstOrNull() diff --git a/plugins/uast-kotlin/testData/Constructors.identifiers.txt b/plugins/uast-kotlin/testData/Constructors.identifiers.txt index 5ed4bcca246..0685e7136d3 100644 --- a/plugins/uast-kotlin/testData/Constructors.identifiers.txt +++ b/plugins/uast-kotlin/testData/Constructors.identifiers.txt @@ -69,3 +69,12 @@ String -> USimpleNameReferenceExpression (identifier = String) s -> USimpleNameReferenceExpression (identifier = s) local -> USimpleNameReferenceExpression (identifier = local) toString -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) +AWithFieldInit -> UClass (name = AWithFieldInit) +i -> UParameter (name = i) +Int -> USimpleNameReferenceExpression (identifier = Int) +a -> UField (name = a) +String -> USimpleNameReferenceExpression (identifier = String) + a -> USimpleNameReferenceExpression (identifier = a) + = -> USimpleNameReferenceExpression (identifier = =) + i -> USimpleNameReferenceExpression (identifier = i) + toString -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) diff --git a/plugins/uast-kotlin/testData/Constructors.kt b/plugins/uast-kotlin/testData/Constructors.kt index d3d0411c719..728ba7aee4c 100644 --- a/plugins/uast-kotlin/testData/Constructors.kt +++ b/plugins/uast-kotlin/testData/Constructors.kt @@ -71,4 +71,11 @@ class AWithSecondaryInit { local.toString() } -} \ No newline at end of file +} + +class AWithFieldInit(i: Int) { + val a: String + init { + a = i.toString() + } +} diff --git a/plugins/uast-kotlin/testData/Constructors.log-ide.txt b/plugins/uast-kotlin/testData/Constructors.log-ide.txt index fb2909007fb..162a2b9bb57 100644 --- a/plugins/uast-kotlin/testData/Constructors.log-ide.txt +++ b/plugins/uast-kotlin/testData/Constructors.log-ide.txt @@ -158,4 +158,20 @@ UFile (package = ) USimpleNameReferenceExpression (identifier = local) UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) UIdentifier (Identifier (toString)) - USimpleNameReferenceExpression (identifier = toString, resolvesTo = null) \ No newline at end of file + USimpleNameReferenceExpression (identifier = toString, resolvesTo = null) + UClass (name = AWithFieldInit) + UField (name = a) + UAnnotation (fqName = org.jetbrains.annotations.NotNull) + UMethod (name = getA) + UMethod (name = AWithFieldInit) + UParameter (name = i) + UAnnotation (fqName = org.jetbrains.annotations.NotNull) + UBlockExpression + UBlockExpression + UBinaryExpression (operator = =) + USimpleNameReferenceExpression (identifier = a) + UQualifiedReferenceExpression + USimpleNameReferenceExpression (identifier = i) + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) + UIdentifier (Identifier (toString)) + USimpleNameReferenceExpression (identifier = toString, resolvesTo = null) diff --git a/plugins/uast-kotlin/testData/Constructors.log.txt b/plugins/uast-kotlin/testData/Constructors.log.txt index 198f7e53b44..d2485ac2278 100644 --- a/plugins/uast-kotlin/testData/Constructors.log.txt +++ b/plugins/uast-kotlin/testData/Constructors.log.txt @@ -159,3 +159,19 @@ UFile (package = ) UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) UIdentifier (Identifier (toString)) USimpleNameReferenceExpression (identifier = toString, resolvesTo = null) + UClass (name = AWithFieldInit) + UField (name = a) + UAnnotation (fqName = org.jetbrains.annotations.NotNull) + UMethod (name = getA) + UMethod (name = AWithFieldInit) + UParameter (name = i) + UAnnotation (fqName = org.jetbrains.annotations.NotNull) + UBlockExpression + UBlockExpression + UBinaryExpression (operator = =) + USimpleNameReferenceExpression (identifier = a) + UQualifiedReferenceExpression + USimpleNameReferenceExpression (identifier = i) + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) + UIdentifier (Identifier (toString)) + USimpleNameReferenceExpression (identifier = toString, resolvesTo = null) diff --git a/plugins/uast-kotlin/testData/Constructors.refNames.txt b/plugins/uast-kotlin/testData/Constructors.refNames.txt index 6f62d7cb1c5..debcfaa0f7f 100644 --- a/plugins/uast-kotlin/testData/Constructors.refNames.txt +++ b/plugins/uast-kotlin/testData/Constructors.refNames.txt @@ -42,3 +42,9 @@ s -> USimpleNameReferenceExpression (identifier = s) from KtNameReferenceExpress toString -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from KtDotQualifiedExpression local -> USimpleNameReferenceExpression (identifier = local) from KtNameReferenceExpression toString -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from KtNameReferenceExpression +Int -> USimpleNameReferenceExpression (identifier = Int) from KtNameReferenceExpression +String -> USimpleNameReferenceExpression (identifier = String) from KtNameReferenceExpression +a -> USimpleNameReferenceExpression (identifier = a) from KtNameReferenceExpression +toString -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from KtDotQualifiedExpression +i -> USimpleNameReferenceExpression (identifier = i) from KtNameReferenceExpression +toString -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from KtNameReferenceExpression diff --git a/plugins/uast-kotlin/testData/Constructors.render-ide.txt b/plugins/uast-kotlin/testData/Constructors.render-ide.txt index 62bb3df0075..08fbd4652bc 100644 --- a/plugins/uast-kotlin/testData/Constructors.render-ide.txt +++ b/plugins/uast-kotlin/testData/Constructors.render-ide.txt @@ -79,3 +79,13 @@ public final class AWithSecondaryInit { local.toString() } } + +public final class AWithFieldInit { + @org.jetbrains.annotations.NotNull private final var a: java.lang.String + public final fun getA() : java.lang.String = UastEmptyExpression + public fun AWithFieldInit(@org.jetbrains.annotations.NotNull i: int) { + { + a = i.toString() + } + } +} diff --git a/plugins/uast-kotlin/testData/Constructors.render.txt b/plugins/uast-kotlin/testData/Constructors.render.txt index d519454d6b9..8e1c3c133f8 100644 --- a/plugins/uast-kotlin/testData/Constructors.render.txt +++ b/plugins/uast-kotlin/testData/Constructors.render.txt @@ -79,3 +79,13 @@ public final class AWithSecondaryInit { local.toString() } } + +public final class AWithFieldInit { + @org.jetbrains.annotations.NotNull private final var a: java.lang.String + public final fun getA() : java.lang.String = UastEmptyExpression + public fun AWithFieldInit(@org.jetbrains.annotations.NotNull i: int) { + { + a = i.toString() + } + } +} diff --git a/plugins/uast-kotlin/testData/Constructors.resolved.txt b/plugins/uast-kotlin/testData/Constructors.resolved.txt index 57103eda78b..151191af691 100644 --- a/plugins/uast-kotlin/testData/Constructors.resolved.txt +++ b/plugins/uast-kotlin/testData/Constructors.resolved.txt @@ -24,28 +24,28 @@ UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))(resolve UTypeReferenceExpression (name = java.lang.String) -> USimpleNameReferenceExpression (identifier = String) -> PsiClass:String: String UTypeReferenceExpression (name = int) -> USimpleNameReferenceExpression (identifier = Int) -> PsiClass:Integer: Integer UBlockExpression -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) -> PsiMethod:Object: - UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = a) -> KtLightMethodImpl:getA: getA + UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = a) -> KtLightMethodImpl:setA: setA UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = =) -> null: null UBinaryExpression (operator = =) -> UQualifiedReferenceExpression -> null: null UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = i) -> Light Parameter: i UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))(resolves to null) -> USimpleNameReferenceExpression (identifier = toString) -> null: null UTypeReferenceExpression (name = java.lang.String) -> USimpleNameReferenceExpression (identifier = String) -> PsiClass:String: String UBlockExpression -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) -> PsiMethod:Object: - UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = a) -> KtLightMethodImpl:getA: getA + UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = a) -> KtLightMethodImpl:setA: setA UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = =) -> null: null UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = s) -> Light Parameter: s UTypeReferenceExpression (name = java.lang.String) -> USimpleNameReferenceExpression (identifier = String) -> PsiClass:String: String UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))(resolves to PsiMethod:println) -> USimpleNameReferenceExpression (identifier = println) -> PsiMethod:println: println UTypeReferenceExpression (name = int) -> USimpleNameReferenceExpression (identifier = Int) -> PsiClass:Integer: Integer UBlockExpression -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) -> PsiMethod:Object: - UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = a) -> KtLightMethodImpl:getA: getA + UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = a) -> KtLightMethodImpl:setA: setA UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = =) -> null: null UBinaryExpression (operator = =) -> UQualifiedReferenceExpression -> null: null UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = i) -> Light Parameter: i UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))(resolves to null) -> USimpleNameReferenceExpression (identifier = toString) -> null: null UTypeReferenceExpression (name = java.lang.String) -> USimpleNameReferenceExpression (identifier = String) -> PsiClass:String: String UBlockExpression -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) -> PsiMethod:Object: - UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = a) -> KtLightMethodImpl:getA: getA + UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = a) -> KtLightMethodImpl:setA: setA UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = =) -> null: null UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = s) -> Light Parameter: s UTypeReferenceExpression (name = java.lang.String) -> USimpleNameReferenceExpression (identifier = String) -> PsiClass:String: String @@ -53,3 +53,10 @@ UBlockExpression -> UCallExpression (kind = UastCallKind(name='constructor_call' UBlockExpression -> UQualifiedReferenceExpression -> PsiMethod:toString: toString UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = local) -> LightVariableBuilder:local: local UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))(resolves to PsiMethod:toString) -> USimpleNameReferenceExpression (identifier = toString) -> PsiMethod:toString: toString +UTypeReferenceExpression (name = int) -> USimpleNameReferenceExpression (identifier = Int) -> PsiClass:Integer: Integer +UTypeReferenceExpression (name = java.lang.String) -> USimpleNameReferenceExpression (identifier = String) -> PsiClass:String: String + UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = a) -> KtLightFieldForSourceDeclaration:a: a + UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = =) -> null: null + UBinaryExpression (operator = =) -> UQualifiedReferenceExpression -> null: null + UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = i) -> Light Parameter: i + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))(resolves to null) -> USimpleNameReferenceExpression (identifier = toString) -> null: null diff --git a/plugins/uast-kotlin/testData/PropertyReferences.kt b/plugins/uast-kotlin/testData/PropertyReferences.kt new file mode 100644 index 00000000000..08f3120b27c --- /dev/null +++ b/plugins/uast-kotlin/testData/PropertyReferences.kt @@ -0,0 +1,30 @@ +class A(init: Int) { + private var privateProp = 0 // accesses should be field accesses + var mutableProp: Int + init { + mutableProp = init + } + + fun add(x: Int): Int { + val result = privateProp + privateProp = x + return privateProp + } +} + +fun properties() { + val a = A(17) + val x = -a.mutableProp + a.mutableProp = 1 + a.mutableProp += x + ++a.mutableProp + a.mutableProp-- +} + +fun A.ext() { + val x = -mutableProp + mutableProp = 1 + mutableProp += x + ++mutableProp + mutableProp-- +} diff --git a/plugins/uast-kotlin/testData/PropertyReferences.resolved.txt b/plugins/uast-kotlin/testData/PropertyReferences.resolved.txt new file mode 100644 index 00000000000..251d48973ea --- /dev/null +++ b/plugins/uast-kotlin/testData/PropertyReferences.resolved.txt @@ -0,0 +1,58 @@ +UTypeReferenceExpression (name = int) -> USimpleNameReferenceExpression (identifier = Int) -> PsiClass:Integer: Integer +UTypeReferenceExpression (name = int) -> USimpleNameReferenceExpression (identifier = Int) -> PsiClass:Integer: Integer + UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = mutableProp) -> KtLightMethodImpl:setMutableProp: setMutableProp + UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = =) -> null: null + UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = init) -> Light Parameter: init +UTypeReferenceExpression (name = int) -> USimpleNameReferenceExpression (identifier = Int) -> PsiClass:Integer: Integer +UTypeReferenceExpression (name = int) -> USimpleNameReferenceExpression (identifier = Int) -> PsiClass:Integer: Integer + ULocalVariable (name = result) -> USimpleNameReferenceExpression (identifier = privateProp) -> KtLightFieldForSourceDeclaration:privateProp: privateProp + UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = privateProp) -> KtLightFieldForSourceDeclaration:privateProp: privateProp + UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = =) -> null: null + UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = x) -> Light Parameter: x + UReturnExpression -> USimpleNameReferenceExpression (identifier = privateProp) -> KtLightFieldForSourceDeclaration:privateProp: privateProp + UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1))(resolves to KtLightMethodImpl:A) -> USimpleNameReferenceExpression (identifier = A) -> KtLightMethodImpl:A: A + UPrefixExpression (operator = -) -> USimpleNameReferenceExpression (identifier = -) -> null: null + UPrefixExpression (operator = -) -> UQualifiedReferenceExpression -> KtLightMethodImpl:getMutableProp: getMutableProp + UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = a) -> LightVariableBuilder:a: a + UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = mutableProp) -> KtLightMethodImpl:getMutableProp: getMutableProp + UBinaryExpression (operator = =) -> UQualifiedReferenceExpression -> KtLightMethodImpl:setMutableProp: setMutableProp + UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = a) -> LightVariableBuilder:a: a + UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = mutableProp) -> KtLightMethodImpl:setMutableProp: setMutableProp + UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = =) -> null: null + UBinaryExpression (operator = +=) -> UQualifiedReferenceExpression -> KtLightMethodImpl:setMutableProp: setMutableProp + UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = a) -> LightVariableBuilder:a: a + UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = mutableProp) -> KtLightMethodImpl:setMutableProp: setMutableProp + UBinaryExpression (operator = +=) -> USimpleNameReferenceExpression (identifier = +=) -> null: null + UBinaryExpression (operator = +=) -> USimpleNameReferenceExpression (identifier = x) -> LightVariableBuilder:x: x + UPrefixExpression (operator = ++) -> USimpleNameReferenceExpression (identifier = ++) -> null: null + UPrefixExpression (operator = ++) -> UQualifiedReferenceExpression -> KtLightMethodImpl:setMutableProp: setMutableProp + UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = a) -> LightVariableBuilder:a: a + UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = mutableProp) -> KtLightMethodImpl:setMutableProp: setMutableProp + UPostfixExpression (operator = --) -> UQualifiedReferenceExpression -> KtLightMethodImpl:setMutableProp: setMutableProp + UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = a) -> LightVariableBuilder:a: a + UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = mutableProp) -> KtLightMethodImpl:setMutableProp: setMutableProp + UPostfixExpression (operator = --) -> USimpleNameReferenceExpression (identifier = --) -> null: null +UTypeReferenceExpression (name = A) -> USimpleNameReferenceExpression (identifier = A) -> KtLightClassImpl:class A(init: Int) { + private var privateProp = 0 // accesses should be field accesses + var mutableProp: Int + init { + mutableProp = init + } + + fun add(x: Int): Int { + val result = privateProp + privateProp = x + return privateProp + } +}: A + UPrefixExpression (operator = -) -> USimpleNameReferenceExpression (identifier = -) -> null: null + UPrefixExpression (operator = -) -> USimpleNameReferenceExpression (identifier = mutableProp) -> KtLightMethodImpl:getMutableProp: getMutableProp + UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = mutableProp) -> KtLightMethodImpl:setMutableProp: setMutableProp + UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = =) -> null: null + UBinaryExpression (operator = +=) -> USimpleNameReferenceExpression (identifier = mutableProp) -> KtLightMethodImpl:setMutableProp: setMutableProp + UBinaryExpression (operator = +=) -> USimpleNameReferenceExpression (identifier = +=) -> null: null + UBinaryExpression (operator = +=) -> USimpleNameReferenceExpression (identifier = x) -> LightVariableBuilder:x: x + UPrefixExpression (operator = ++) -> USimpleNameReferenceExpression (identifier = ++) -> null: null + UPrefixExpression (operator = ++) -> USimpleNameReferenceExpression (identifier = mutableProp) -> KtLightMethodImpl:setMutableProp: setMutableProp + UPostfixExpression (operator = --) -> USimpleNameReferenceExpression (identifier = mutableProp) -> KtLightMethodImpl:setMutableProp: setMutableProp + UPostfixExpression (operator = --) -> USimpleNameReferenceExpression (identifier = --) -> null: null diff --git a/plugins/uast-kotlin/tests/KotlinUastResolveEverythingTest.kt b/plugins/uast-kotlin/tests/KotlinUastResolveEverythingTest.kt index d266767d990..7346c1f11c7 100644 --- a/plugins/uast-kotlin/tests/KotlinUastResolveEverythingTest.kt +++ b/plugins/uast-kotlin/tests/KotlinUastResolveEverythingTest.kt @@ -33,4 +33,7 @@ class KotlinUastResolveEverythingTest : AbstractKotlinResolveEverythingTest() { @Test fun testResolve() = doTest("Resolve") + @Test + fun testPropertyReferences() = doTest("PropertyReferences") + } \ No newline at end of file