From 610b68c29d8d1632560fd27dd28c7dfc9b586c11 Mon Sep 17 00:00:00 2001 From: Jinseong Jeon Date: Wed, 9 Jun 2021 10:48:28 -0700 Subject: [PATCH] FIR/UAST: commonize expressions with label --- .../expressions/KotlinUSuperExpression.kt | 26 ++++++++++ .../expressions/KotlinUThisExpression.kt | 26 ++++++++++ .../uast/kotlin/FirKotlinConverter.kt | 2 + .../FirKotlinUastResolveProviderService.kt | 10 ++-- .../testData/declaration/facade.log.fir.txt | 2 +- .../declaration/facade.render.fir.txt | 2 +- .../testData/declaration/labeledExpression.kt | 26 ++++++++++ .../labeledExpression.log.fe10.txt | 49 +++++++++++++++++++ .../declaration/labeledExpression.log.fir.txt | 22 +++++++++ .../labeledExpression.render.fe10.txt | 28 +++++++++++ .../labeledExpression.render.fir.txt | 22 +++++++++ .../PropertyAccessors.log.fir.txt | 2 +- .../PropertyAccessors.render.fir.txt | 2 +- .../legacyRenderLog/ReceiverFun.log.fir.txt | 2 +- .../ReceiverFun.render.fir.txt | 2 +- .../legacyRenderLog/SuperCalls.log.fir.txt | 2 +- .../legacyRenderLog/SuperCalls.render.fir.txt | 2 +- .../PropertyAccessors.types.fir.txt | 6 +-- .../legacyTypes/ReceiverFun.types.fir.txt | 6 +-- .../legacyTypes/SuperCalls.types.fir.txt | 4 +- .../PropertyAccessors.values.fir.txt | 6 +-- .../legacyValues/ReceiverFun.values.fir.txt | 6 +-- .../legacyValues/SuperCalls.values.fir.txt | 4 +- .../arrayGetAssignMultiIndex.types.fir.txt | 6 +-- .../FE1UastDeclarationTestGenerated.java | 5 ++ .../FirUastDeclarationTestGenerated.java | 5 ++ .../uast/test/kotlin/FirUastResolveApiTest.kt | 30 ++++++++++-- .../KotlinUastResolveProviderService.kt | 8 +-- .../expressions/KotlinUSuperExpression.kt | 37 -------------- .../expressions/KotlinUThisExpression.kt | 37 -------------- 30 files changed, 274 insertions(+), 113 deletions(-) create mode 100644 plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/expressions/KotlinUSuperExpression.kt create mode 100644 plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/expressions/KotlinUThisExpression.kt create mode 100644 plugins/uast-kotlin-fir/testData/declaration/labeledExpression.kt create mode 100644 plugins/uast-kotlin-fir/testData/declaration/labeledExpression.log.fe10.txt create mode 100644 plugins/uast-kotlin-fir/testData/declaration/labeledExpression.log.fir.txt create mode 100644 plugins/uast-kotlin-fir/testData/declaration/labeledExpression.render.fe10.txt create mode 100644 plugins/uast-kotlin-fir/testData/declaration/labeledExpression.render.fir.txt delete mode 100644 plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSuperExpression.kt delete mode 100644 plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUThisExpression.kt diff --git a/plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/expressions/KotlinUSuperExpression.kt b/plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/expressions/KotlinUSuperExpression.kt new file mode 100644 index 00000000000..63a8d074395 --- /dev/null +++ b/plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/expressions/KotlinUSuperExpression.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.uast.kotlin + +import org.jetbrains.kotlin.psi.KtSuperExpression +import org.jetbrains.uast.UElement +import org.jetbrains.uast.UIdentifier +import org.jetbrains.uast.USuperExpression +import org.jetbrains.uast.kotlin.internal.DelegatedMultiResolve + +class KotlinUSuperExpression( + override val sourcePsi: KtSuperExpression, + givenParent: UElement? +) : KotlinAbstractUExpression(givenParent), USuperExpression, DelegatedMultiResolve, KotlinUElementWithType, KotlinEvaluatableUElement { + override val label: String? + get() = sourcePsi.getLabelName() + + override val labelIdentifier: UIdentifier? + get() = sourcePsi.getTargetLabel()?.let { KotlinUIdentifier(it, this) } + + override fun resolve() = + baseResolveProviderService.resolveToDeclaration(sourcePsi) +} diff --git a/plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/expressions/KotlinUThisExpression.kt b/plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/expressions/KotlinUThisExpression.kt new file mode 100644 index 00000000000..eaf3bbc3296 --- /dev/null +++ b/plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/expressions/KotlinUThisExpression.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.uast.kotlin + +import org.jetbrains.kotlin.psi.KtThisExpression +import org.jetbrains.uast.UElement +import org.jetbrains.uast.UIdentifier +import org.jetbrains.uast.UThisExpression +import org.jetbrains.uast.kotlin.internal.DelegatedMultiResolve + +class KotlinUThisExpression( + override val sourcePsi: KtThisExpression, + givenParent: UElement? +) : KotlinAbstractUExpression(givenParent), UThisExpression, DelegatedMultiResolve, KotlinUElementWithType, KotlinEvaluatableUElement { + override val label: String? + get() = sourcePsi.getLabelName() + + override val labelIdentifier: UIdentifier? + get() = sourcePsi.getTargetLabel()?.let { KotlinUIdentifier(it, this) } + + override fun resolve() = + baseResolveProviderService.resolveToDeclaration(sourcePsi) +} diff --git a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/FirKotlinConverter.kt b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/FirKotlinConverter.kt index 225b25fd1be..17654c69888 100644 --- a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/FirKotlinConverter.kt +++ b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/FirKotlinConverter.kt @@ -309,6 +309,8 @@ internal object FirKotlinConverter : BaseKotlinConverter { is KtArrayAccessExpression -> expr(build(::FirKotlinUArrayAccessExpression)) + is KtThisExpression -> expr(build(::KotlinUThisExpression)) + is KtSuperExpression -> expr(build(::KotlinUSuperExpression)) is KtCallableReferenceExpression -> expr(build(::KotlinUCallableReferenceExpression)) is KtClassLiteralExpression -> expr(build(::KotlinUClassLiteralExpression)) is KtDotQualifiedExpression -> expr(build(::KotlinUQualifiedReferenceExpression)) diff --git a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/FirKotlinUastResolveProviderService.kt b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/FirKotlinUastResolveProviderService.kt index 02588a3082b..3c2e45cf161 100644 --- a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/FirKotlinUastResolveProviderService.kt +++ b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/FirKotlinUastResolveProviderService.kt @@ -10,10 +10,7 @@ import com.intellij.psi.PsiType import org.jetbrains.kotlin.idea.frontend.api.analyseForUast import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.load.kotlin.TypeMappingMode -import org.jetbrains.kotlin.psi.KtDoubleColonExpression -import org.jetbrains.kotlin.psi.KtExpression -import org.jetbrains.kotlin.psi.KtReferenceExpression -import org.jetbrains.kotlin.psi.KtTypeReference +import org.jetbrains.kotlin.psi.* import org.jetbrains.uast.UElement import org.jetbrains.uast.UExpression @@ -27,6 +24,11 @@ interface FirKotlinUastResolveProviderService : BaseKotlinUastResolveProviderSer override fun resolveToDeclaration(ktExpression: KtExpression): PsiElement? { when (ktExpression) { + is KtExpressionWithLabel -> { + analyseForUast(ktExpression) { + return ktExpression.getTargetLabel()?.mainReference?.resolve() + } + } is KtReferenceExpression -> { analyseForUast(ktExpression) { return ktExpression.mainReference.resolve() diff --git a/plugins/uast-kotlin-fir/testData/declaration/facade.log.fir.txt b/plugins/uast-kotlin-fir/testData/declaration/facade.log.fir.txt index 863c3498732..d11b36a6216 100644 --- a/plugins/uast-kotlin-fir/testData/declaration/facade.log.fir.txt +++ b/plugins/uast-kotlin-fir/testData/declaration/facade.log.fir.txt @@ -9,5 +9,5 @@ UFile (package = declaration) UBlockExpression UReturnExpression UPolyadicExpression (operator = +) - [!] UnknownKotlinExpression (THIS_EXPRESSION) + UThisExpression (label = null) ULiteralExpression (value = "... zzz...") diff --git a/plugins/uast-kotlin-fir/testData/declaration/facade.render.fir.txt b/plugins/uast-kotlin-fir/testData/declaration/facade.render.fir.txt index e6df32f86ec..3b6b12ebec3 100644 --- a/plugins/uast-kotlin-fir/testData/declaration/facade.render.fir.txt +++ b/plugins/uast-kotlin-fir/testData/declaration/facade.render.fir.txt @@ -5,6 +5,6 @@ public final class Utils { return 42 } public static final fun buzz($this$buzz: java.lang.String) : java.lang.String { - return [!] UnknownKotlinExpression (THIS_EXPRESSION) + "... zzz..." + return this + "... zzz..." } } diff --git a/plugins/uast-kotlin-fir/testData/declaration/labeledExpression.kt b/plugins/uast-kotlin-fir/testData/declaration/labeledExpression.kt new file mode 100644 index 00000000000..d580e1ca5d5 --- /dev/null +++ b/plugins/uast-kotlin-fir/testData/declaration/labeledExpression.kt @@ -0,0 +1,26 @@ +interface I { + fun foo(): Int +} + +abstract class Base { + fun foo(): Int { + return 42 + } +} + +class Foo : I, Base() { + val p: String = "42" + + fun bar(other: I): Int { + with(other) { + return super@Foo.foo() + } + } + + fun baz(other: I): String { + with(other) { + return this@Foo.p + } + } +} + diff --git a/plugins/uast-kotlin-fir/testData/declaration/labeledExpression.log.fe10.txt b/plugins/uast-kotlin-fir/testData/declaration/labeledExpression.log.fe10.txt new file mode 100644 index 00000000000..033b508c75b --- /dev/null +++ b/plugins/uast-kotlin-fir/testData/declaration/labeledExpression.log.fe10.txt @@ -0,0 +1,49 @@ +UFile (package = ) + UClass (name = I) + UMethod (name = foo) + UClass (name = Base) + UMethod (name = foo) + UBlockExpression + UReturnExpression + ULiteralExpression (value = 42) + UMethod (name = Base) + UClass (name = Foo) + UField (name = p) + UAnnotation (fqName = org.jetbrains.annotations.NotNull) + ULiteralExpression (value = "42") + UMethod (name = getP) + UMethod (name = bar) + UParameter (name = other) + UAnnotation (fqName = org.jetbrains.annotations.NotNull) + UBlockExpression + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) + UIdentifier (Identifier (with)) + USimpleNameReferenceExpression (identifier = with, resolvesTo = null) + USimpleNameReferenceExpression (identifier = other) + ULambdaExpression + UBlockExpression + UReturnExpression + UQualifiedReferenceExpression + USuperExpression (label = Foo) + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) + UIdentifier (Identifier (foo)) + USimpleNameReferenceExpression (identifier = foo, resolvesTo = null) + UMethod (name = baz) + UParameter (name = other) + UAnnotation (fqName = org.jetbrains.annotations.NotNull) + UBlockExpression + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) + UIdentifier (Identifier (with)) + USimpleNameReferenceExpression (identifier = with, resolvesTo = null) + USimpleNameReferenceExpression (identifier = other) + ULambdaExpression + UBlockExpression + UReturnExpression + UQualifiedReferenceExpression + UThisExpression (label = Foo) + USimpleNameReferenceExpression (identifier = p) + UMethod (name = Foo) + UBlockExpression + UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) + UIdentifier (Identifier (Base)) + USimpleNameReferenceExpression (identifier = , resolvesTo = PsiClass: Base) diff --git a/plugins/uast-kotlin-fir/testData/declaration/labeledExpression.log.fir.txt b/plugins/uast-kotlin-fir/testData/declaration/labeledExpression.log.fir.txt new file mode 100644 index 00000000000..775ed71d914 --- /dev/null +++ b/plugins/uast-kotlin-fir/testData/declaration/labeledExpression.log.fir.txt @@ -0,0 +1,22 @@ +UFile (package = ) + UClass (name = I) + UMethod (name = foo) + UClass (name = Base) + UMethod (name = Base) + UMethod (name = foo) + UBlockExpression + UReturnExpression + ULiteralExpression (value = 42) + UClass (name = Foo) + UField (name = p) + ULiteralExpression (value = "42") + UMethod (name = Foo) + UMethod (name = getP) + UMethod (name = bar) + UParameter (name = other) + UBlockExpression + [!] UnknownKotlinExpression (CALL_EXPRESSION) + UMethod (name = baz) + UParameter (name = other) + UBlockExpression + [!] UnknownKotlinExpression (CALL_EXPRESSION) diff --git a/plugins/uast-kotlin-fir/testData/declaration/labeledExpression.render.fe10.txt b/plugins/uast-kotlin-fir/testData/declaration/labeledExpression.render.fe10.txt new file mode 100644 index 00000000000..e7b1df4a532 --- /dev/null +++ b/plugins/uast-kotlin-fir/testData/declaration/labeledExpression.render.fe10.txt @@ -0,0 +1,28 @@ +public abstract interface I { + public abstract fun foo() : int = UastEmptyExpression +} + +public abstract class Base { + public final fun foo() : int { + return 42 + } + public fun Base() = UastEmptyExpression +} + +public final class Foo : I, Base { + @org.jetbrains.annotations.NotNull private final var p: java.lang.String = "42" + public final fun getP() : java.lang.String = UastEmptyExpression + public final fun bar(@org.jetbrains.annotations.NotNull other: I) : int { + with(other, { + return super.foo() + }) + } + public final fun baz(@org.jetbrains.annotations.NotNull other: I) : java.lang.String { + with(other, { + return this.p + }) + } + public fun Foo() { + () + } +} diff --git a/plugins/uast-kotlin-fir/testData/declaration/labeledExpression.render.fir.txt b/plugins/uast-kotlin-fir/testData/declaration/labeledExpression.render.fir.txt new file mode 100644 index 00000000000..b593019829f --- /dev/null +++ b/plugins/uast-kotlin-fir/testData/declaration/labeledExpression.render.fir.txt @@ -0,0 +1,22 @@ +public abstract interface I { + public abstract fun foo() : int = UastEmptyExpression +} + +public abstract class Base { + public fun Base() = UastEmptyExpression + public final fun foo() : int { + return 42 + } +} + +public final class Foo : I, Base { + private final var p: java.lang.String = "42" + public fun Foo() = UastEmptyExpression + public final fun getP() : java.lang.String = UastEmptyExpression + public final fun bar(other: I) : int { + [!] UnknownKotlinExpression (CALL_EXPRESSION) + } + public final fun baz(other: I) : java.lang.String { + [!] UnknownKotlinExpression (CALL_EXPRESSION) + } +} diff --git a/plugins/uast-kotlin-fir/testData/legacyRenderLog/PropertyAccessors.log.fir.txt b/plugins/uast-kotlin-fir/testData/legacyRenderLog/PropertyAccessors.log.fir.txt index addb7476fd9..9b8e654b4fa 100644 --- a/plugins/uast-kotlin-fir/testData/legacyRenderLog/PropertyAccessors.log.fir.txt +++ b/plugins/uast-kotlin-fir/testData/legacyRenderLog/PropertyAccessors.log.fir.txt @@ -5,7 +5,7 @@ UFile (package = ) UBlockExpression UReturnExpression UQualifiedReferenceExpression - [!] UnknownKotlinExpression (THIS_EXPRESSION) + UThisExpression (label = null) [!] UnknownKotlinExpression (CALL_EXPRESSION) UMethod (name = setStringRepresentation) UParameter (name = value) diff --git a/plugins/uast-kotlin-fir/testData/legacyRenderLog/PropertyAccessors.render.fir.txt b/plugins/uast-kotlin-fir/testData/legacyRenderLog/PropertyAccessors.render.fir.txt index f65fec5c987..f150761ade2 100644 --- a/plugins/uast-kotlin-fir/testData/legacyRenderLog/PropertyAccessors.render.fir.txt +++ b/plugins/uast-kotlin-fir/testData/legacyRenderLog/PropertyAccessors.render.fir.txt @@ -1,7 +1,7 @@ public final class PropertyTest { public fun PropertyTest() = UastEmptyExpression public final fun getStringRepresentation() : java.lang.String { - return [!] UnknownKotlinExpression (THIS_EXPRESSION).[!] UnknownKotlinExpression (CALL_EXPRESSION) + return this.[!] UnknownKotlinExpression (CALL_EXPRESSION) } public final fun setStringRepresentation(value: java.lang.String) : void { [!] UnknownKotlinExpression (CALL_EXPRESSION) diff --git a/plugins/uast-kotlin-fir/testData/legacyRenderLog/ReceiverFun.log.fir.txt b/plugins/uast-kotlin-fir/testData/legacyRenderLog/ReceiverFun.log.fir.txt index ac14b6aaccd..139c485a5e2 100644 --- a/plugins/uast-kotlin-fir/testData/legacyRenderLog/ReceiverFun.log.fir.txt +++ b/plugins/uast-kotlin-fir/testData/legacyRenderLog/ReceiverFun.log.fir.txt @@ -5,7 +5,7 @@ UFile (package = ) UBlockExpression UReturnExpression UQualifiedReferenceExpression - [!] UnknownKotlinExpression (THIS_EXPRESSION) + UThisExpression (label = null) USimpleNameReferenceExpression (identifier = length) UMethod (name = getRx) UParameter (name = $this$rx) diff --git a/plugins/uast-kotlin-fir/testData/legacyRenderLog/ReceiverFun.render.fir.txt b/plugins/uast-kotlin-fir/testData/legacyRenderLog/ReceiverFun.render.fir.txt index b8661ad79bc..814aeee5546 100644 --- a/plugins/uast-kotlin-fir/testData/legacyRenderLog/ReceiverFun.render.fir.txt +++ b/plugins/uast-kotlin-fir/testData/legacyRenderLog/ReceiverFun.render.fir.txt @@ -1,6 +1,6 @@ public final class ReceiverFunKt { public static final fun foo($this$foo: java.lang.String) : int { - return [!] UnknownKotlinExpression (THIS_EXPRESSION).length + return this.length } public static final fun getRx($this$rx: java.lang.String) : kotlin.text.Regex { return [!] UnknownKotlinExpression (CALL_EXPRESSION) diff --git a/plugins/uast-kotlin-fir/testData/legacyRenderLog/SuperCalls.log.fir.txt b/plugins/uast-kotlin-fir/testData/legacyRenderLog/SuperCalls.log.fir.txt index 4880e44a670..9c6aa0c3b7a 100644 --- a/plugins/uast-kotlin-fir/testData/legacyRenderLog/SuperCalls.log.fir.txt +++ b/plugins/uast-kotlin-fir/testData/legacyRenderLog/SuperCalls.log.fir.txt @@ -37,7 +37,7 @@ UFile (package = ) UParameter (name = a) UBlockExpression UQualifiedReferenceExpression - [!] UnknownKotlinExpression (SUPER_EXPRESSION) + USuperExpression (label = null) [!] UnknownKotlinExpression (CALL_EXPRESSION) UClass (name = O) UField (name = INSTANCE) diff --git a/plugins/uast-kotlin-fir/testData/legacyRenderLog/SuperCalls.render.fir.txt b/plugins/uast-kotlin-fir/testData/legacyRenderLog/SuperCalls.render.fir.txt index 2c036e7a4a2..41302646267 100644 --- a/plugins/uast-kotlin-fir/testData/legacyRenderLog/SuperCalls.render.fir.txt +++ b/plugins/uast-kotlin-fir/testData/legacyRenderLog/SuperCalls.render.fir.txt @@ -31,7 +31,7 @@ public final class C : A { [!] UnknownKotlinExpression (CALL_EXPRESSION) } public fun foo(a: long) : void { - [!] UnknownKotlinExpression (SUPER_EXPRESSION).[!] UnknownKotlinExpression (CALL_EXPRESSION) + super.[!] UnknownKotlinExpression (CALL_EXPRESSION) } } diff --git a/plugins/uast-kotlin-fir/testData/legacyTypes/PropertyAccessors.types.fir.txt b/plugins/uast-kotlin-fir/testData/legacyTypes/PropertyAccessors.types.fir.txt index dc5aad6bffc..25a209ac092 100644 --- a/plugins/uast-kotlin-fir/testData/legacyTypes/PropertyAccessors.types.fir.txt +++ b/plugins/uast-kotlin-fir/testData/legacyTypes/PropertyAccessors.types.fir.txt @@ -3,9 +3,9 @@ UFile (package = ) [public final class PropertyTest {...] UMethod (name = PropertyTest) [public fun PropertyTest() = UastEmptyExpression] UMethod (name = getStringRepresentation) [public final fun getStringRepresentation() : java.lang.String {...}] UBlockExpression [{...}] - UReturnExpression [return [!] UnknownKotlinExpression (THIS_EXPRESSION).[!] UnknownKotlinExpression (CALL_EXPRESSION)] - UQualifiedReferenceExpression [[!] UnknownKotlinExpression (THIS_EXPRESSION).[!] UnknownKotlinExpression (CALL_EXPRESSION)] : PsiType:String - [!] UnknownKotlinExpression (THIS_EXPRESSION) [[!] UnknownKotlinExpression (THIS_EXPRESSION)] + UReturnExpression [return this.[!] UnknownKotlinExpression (CALL_EXPRESSION)] + UQualifiedReferenceExpression [this.[!] UnknownKotlinExpression (CALL_EXPRESSION)] : PsiType:String + UThisExpression (label = null) [this] : PsiType:PropertyTest [!] UnknownKotlinExpression (CALL_EXPRESSION) [[!] UnknownKotlinExpression (CALL_EXPRESSION)] UMethod (name = setStringRepresentation) [public final fun setStringRepresentation(value: java.lang.String) : void {...}] UParameter (name = value) [var value: java.lang.String] diff --git a/plugins/uast-kotlin-fir/testData/legacyTypes/ReceiverFun.types.fir.txt b/plugins/uast-kotlin-fir/testData/legacyTypes/ReceiverFun.types.fir.txt index 1a39dc9aa14..3953e1481e5 100644 --- a/plugins/uast-kotlin-fir/testData/legacyTypes/ReceiverFun.types.fir.txt +++ b/plugins/uast-kotlin-fir/testData/legacyTypes/ReceiverFun.types.fir.txt @@ -3,9 +3,9 @@ UFile (package = ) [public final class ReceiverFunKt {...] UMethod (name = foo) [public static final fun foo($this$foo: java.lang.String) : int {...}] UParameter (name = $this$foo) [var $this$foo: java.lang.String] UBlockExpression [{...}] - UReturnExpression [return [!] UnknownKotlinExpression (THIS_EXPRESSION).length] - UQualifiedReferenceExpression [[!] UnknownKotlinExpression (THIS_EXPRESSION).length] : PsiType:int - [!] UnknownKotlinExpression (THIS_EXPRESSION) [[!] UnknownKotlinExpression (THIS_EXPRESSION)] + UReturnExpression [return this.length] + UQualifiedReferenceExpression [this.length] : PsiType:int + UThisExpression (label = null) [this] : PsiType:String USimpleNameReferenceExpression (identifier = length) [length] : PsiType:int UMethod (name = getRx) [public static final fun getRx($this$rx: java.lang.String) : kotlin.text.Regex {...}] UParameter (name = $this$rx) [var $this$rx: java.lang.String] diff --git a/plugins/uast-kotlin-fir/testData/legacyTypes/SuperCalls.types.fir.txt b/plugins/uast-kotlin-fir/testData/legacyTypes/SuperCalls.types.fir.txt index 92076d0ab9d..4568f491a3b 100644 --- a/plugins/uast-kotlin-fir/testData/legacyTypes/SuperCalls.types.fir.txt +++ b/plugins/uast-kotlin-fir/testData/legacyTypes/SuperCalls.types.fir.txt @@ -36,8 +36,8 @@ UFile (package = ) [public final class SuperCallsKt {...] UMethod (name = foo) [public fun foo(a: long) : void {...}] UParameter (name = a) [var a: long] UBlockExpression [{...}] : PsiType:Unit - UQualifiedReferenceExpression [[!] UnknownKotlinExpression (SUPER_EXPRESSION).[!] UnknownKotlinExpression (CALL_EXPRESSION)] : PsiType:Unit - [!] UnknownKotlinExpression (SUPER_EXPRESSION) [[!] UnknownKotlinExpression (SUPER_EXPRESSION)] + UQualifiedReferenceExpression [super.[!] UnknownKotlinExpression (CALL_EXPRESSION)] : PsiType:Unit + USuperExpression (label = null) [super] : PsiType:A [!] UnknownKotlinExpression (CALL_EXPRESSION) [[!] UnknownKotlinExpression (CALL_EXPRESSION)] UClass (name = O) [public final class O : A {...}] UField (name = INSTANCE) [public static final var INSTANCE: O] diff --git a/plugins/uast-kotlin-fir/testData/legacyValues/PropertyAccessors.values.fir.txt b/plugins/uast-kotlin-fir/testData/legacyValues/PropertyAccessors.values.fir.txt index 622a053ca36..0042d8ad98d 100644 --- a/plugins/uast-kotlin-fir/testData/legacyValues/PropertyAccessors.values.fir.txt +++ b/plugins/uast-kotlin-fir/testData/legacyValues/PropertyAccessors.values.fir.txt @@ -3,9 +3,9 @@ UFile (package = ) [public final class PropertyTest {...] UMethod (name = PropertyTest) [public fun PropertyTest() = UastEmptyExpression] UMethod (name = getStringRepresentation) [public final fun getStringRepresentation() : java.lang.String {...}] UBlockExpression [{...}] = Nothing - UReturnExpression [return [!] UnknownKotlinExpression (THIS_EXPRESSION).[!] UnknownKotlinExpression (CALL_EXPRESSION)] = Nothing - UQualifiedReferenceExpression [[!] UnknownKotlinExpression (THIS_EXPRESSION).[!] UnknownKotlinExpression (CALL_EXPRESSION)] = Undetermined - [!] UnknownKotlinExpression (THIS_EXPRESSION) [[!] UnknownKotlinExpression (THIS_EXPRESSION)] = Undetermined + UReturnExpression [return this.[!] UnknownKotlinExpression (CALL_EXPRESSION)] = Nothing + UQualifiedReferenceExpression [this.[!] UnknownKotlinExpression (CALL_EXPRESSION)] = Undetermined + UThisExpression (label = null) [this] = Undetermined [!] UnknownKotlinExpression (CALL_EXPRESSION) [[!] UnknownKotlinExpression (CALL_EXPRESSION)] = Undetermined UMethod (name = setStringRepresentation) [public final fun setStringRepresentation(value: java.lang.String) : void {...}] UParameter (name = value) [var value: java.lang.String] diff --git a/plugins/uast-kotlin-fir/testData/legacyValues/ReceiverFun.values.fir.txt b/plugins/uast-kotlin-fir/testData/legacyValues/ReceiverFun.values.fir.txt index 0e7c6a7fc19..79daedfa8e9 100644 --- a/plugins/uast-kotlin-fir/testData/legacyValues/ReceiverFun.values.fir.txt +++ b/plugins/uast-kotlin-fir/testData/legacyValues/ReceiverFun.values.fir.txt @@ -3,9 +3,9 @@ UFile (package = ) [public final class ReceiverFunKt {...] UMethod (name = foo) [public static final fun foo($this$foo: java.lang.String) : int {...}] UParameter (name = $this$foo) [var $this$foo: java.lang.String] UBlockExpression [{...}] = Nothing - UReturnExpression [return [!] UnknownKotlinExpression (THIS_EXPRESSION).length] = Nothing - UQualifiedReferenceExpression [[!] UnknownKotlinExpression (THIS_EXPRESSION).length] = external length() - [!] UnknownKotlinExpression (THIS_EXPRESSION) [[!] UnknownKotlinExpression (THIS_EXPRESSION)] = Undetermined + UReturnExpression [return this.length] = Nothing + UQualifiedReferenceExpression [this.length] = external length() + UThisExpression (label = null) [this] = Undetermined USimpleNameReferenceExpression (identifier = length) [length] = external length() UMethod (name = getRx) [public static final fun getRx($this$rx: java.lang.String) : kotlin.text.Regex {...}] UParameter (name = $this$rx) [var $this$rx: java.lang.String] diff --git a/plugins/uast-kotlin-fir/testData/legacyValues/SuperCalls.values.fir.txt b/plugins/uast-kotlin-fir/testData/legacyValues/SuperCalls.values.fir.txt index 70d13b174fc..c38124be934 100644 --- a/plugins/uast-kotlin-fir/testData/legacyValues/SuperCalls.values.fir.txt +++ b/plugins/uast-kotlin-fir/testData/legacyValues/SuperCalls.values.fir.txt @@ -36,8 +36,8 @@ UFile (package = ) [public final class SuperCallsKt {...] UMethod (name = foo) [public fun foo(a: long) : void {...}] UParameter (name = a) [var a: long] UBlockExpression [{...}] = Undetermined - UQualifiedReferenceExpression [[!] UnknownKotlinExpression (SUPER_EXPRESSION).[!] UnknownKotlinExpression (CALL_EXPRESSION)] = Undetermined - [!] UnknownKotlinExpression (SUPER_EXPRESSION) [[!] UnknownKotlinExpression (SUPER_EXPRESSION)] = Undetermined + UQualifiedReferenceExpression [super.[!] UnknownKotlinExpression (CALL_EXPRESSION)] = Undetermined + USuperExpression (label = null) [super] = Undetermined [!] UnknownKotlinExpression (CALL_EXPRESSION) [[!] UnknownKotlinExpression (CALL_EXPRESSION)] = Undetermined UClass (name = O) [public final class O : A {...}] UField (name = INSTANCE) [public static final var INSTANCE: O] diff --git a/plugins/uast-kotlin-fir/testData/type/arrayGetAssignMultiIndex.types.fir.txt b/plugins/uast-kotlin-fir/testData/type/arrayGetAssignMultiIndex.types.fir.txt index d484a43625e..e59f14bedc6 100644 --- a/plugins/uast-kotlin-fir/testData/type/arrayGetAssignMultiIndex.types.fir.txt +++ b/plugins/uast-kotlin-fir/testData/type/arrayGetAssignMultiIndex.types.fir.txt @@ -5,9 +5,9 @@ UFile (package = ) [public final class ArrayGetAssignMultiIndexKt {...] UParameter (name = index1) [var index1: int] UParameter (name = index2) [var index2: int] UBlockExpression [{...}] - UReturnExpression [return [!] UnknownKotlinExpression (THIS_EXPRESSION)[[!] UnknownKotlinExpression (BINARY_EXPRESSION)]] - UArrayAccessExpression [[!] UnknownKotlinExpression (THIS_EXPRESSION)[[!] UnknownKotlinExpression (BINARY_EXPRESSION)]] : PsiType:String - [!] UnknownKotlinExpression (THIS_EXPRESSION) [[!] UnknownKotlinExpression (THIS_EXPRESSION)] + UReturnExpression [return this[[!] UnknownKotlinExpression (BINARY_EXPRESSION)]] + UArrayAccessExpression [this[[!] UnknownKotlinExpression (BINARY_EXPRESSION)]] : PsiType:String + UThisExpression (label = null) [this] : PsiType:String[] [!] UnknownKotlinExpression (BINARY_EXPRESSION) [[!] UnknownKotlinExpression (BINARY_EXPRESSION)] UMethod (name = set) [public static final fun set($this$set: java.lang.String[], index1: int, index2: int, elem: java.lang.String) : void {...}] UParameter (name = $this$set) [var $this$set: java.lang.String[]] diff --git a/plugins/uast-kotlin-fir/tests/org/jetbrains/uast/test/kotlin/FE1UastDeclarationTestGenerated.java b/plugins/uast-kotlin-fir/tests/org/jetbrains/uast/test/kotlin/FE1UastDeclarationTestGenerated.java index 49d593a4682..94d8fe31e0a 100644 --- a/plugins/uast-kotlin-fir/tests/org/jetbrains/uast/test/kotlin/FE1UastDeclarationTestGenerated.java +++ b/plugins/uast-kotlin-fir/tests/org/jetbrains/uast/test/kotlin/FE1UastDeclarationTestGenerated.java @@ -49,6 +49,11 @@ public class FE1UastDeclarationTestGenerated extends AbstractFE1UastDeclarationT runTest("plugins/uast-kotlin-fir/testData/declaration/importOnDemand.kt"); } + @TestMetadata("labeledExpression.kt") + public void testLabeledExpression() throws Exception { + runTest("plugins/uast-kotlin-fir/testData/declaration/labeledExpression.kt"); + } + @TestMetadata("objects.kt") public void testObjects() throws Exception { runTest("plugins/uast-kotlin-fir/testData/declaration/objects.kt"); diff --git a/plugins/uast-kotlin-fir/tests/org/jetbrains/uast/test/kotlin/FirUastDeclarationTestGenerated.java b/plugins/uast-kotlin-fir/tests/org/jetbrains/uast/test/kotlin/FirUastDeclarationTestGenerated.java index 1f760d2e049..a90bbf1ea1b 100644 --- a/plugins/uast-kotlin-fir/tests/org/jetbrains/uast/test/kotlin/FirUastDeclarationTestGenerated.java +++ b/plugins/uast-kotlin-fir/tests/org/jetbrains/uast/test/kotlin/FirUastDeclarationTestGenerated.java @@ -49,6 +49,11 @@ public class FirUastDeclarationTestGenerated extends AbstractFirUastDeclarationT runTest("plugins/uast-kotlin-fir/testData/declaration/importOnDemand.kt"); } + @TestMetadata("labeledExpression.kt") + public void testLabeledExpression() throws Exception { + runTest("plugins/uast-kotlin-fir/testData/declaration/labeledExpression.kt"); + } + @TestMetadata("objects.kt") public void testObjects() throws Exception { runTest("plugins/uast-kotlin-fir/testData/declaration/objects.kt"); diff --git a/plugins/uast-kotlin-fir/tests/org/jetbrains/uast/test/kotlin/FirUastResolveApiTest.kt b/plugins/uast-kotlin-fir/tests/org/jetbrains/uast/test/kotlin/FirUastResolveApiTest.kt index d41347d65c1..0ef10dad103 100644 --- a/plugins/uast-kotlin-fir/tests/org/jetbrains/uast/test/kotlin/FirUastResolveApiTest.kt +++ b/plugins/uast-kotlin-fir/tests/org/jetbrains/uast/test/kotlin/FirUastResolveApiTest.kt @@ -13,9 +13,7 @@ import com.intellij.testFramework.TestDataPath import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.test.JUnit3RunnerWithInners import org.jetbrains.kotlin.test.TestMetadata -import org.jetbrains.uast.UCallableReferenceExpression -import org.jetbrains.uast.UElement -import org.jetbrains.uast.UFile +import org.jetbrains.uast.* import org.jetbrains.uast.test.common.kotlin.asRefNames import org.jetbrains.uast.test.env.kotlin.AbstractFirUastTest import org.jetbrains.uast.visitor.UastVisitor @@ -31,6 +29,8 @@ class FirUastResolveApiTest : AbstractFirUastTest() { // Bogus } + // TODO: once call is supported, test labeledExpression.kt for labeled this and super + @TestMetadata("plugins/uast-kotlin/testData") @TestDataPath("\$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners::class) @@ -65,7 +65,6 @@ class FirUastResolveApiTest : AbstractFirUastTest() { } } - @TestMetadata("Imports.kt") fun testImports() { doCheck("plugins/uast-kotlin/testData/Imports.kt") { _, uFile -> @@ -105,5 +104,28 @@ class FirUastResolveApiTest : AbstractFirUastTest() { } } } + + @TestMetadata("ReceiverFun.kt") + fun testReceiverFun() { + doCheck("plugins/uast-kotlin/testData/ReceiverFun.kt") { _, uFile -> + val facade = uFile.findFacade() + ?: throw IllegalStateException("No facade found at ${uFile.asRefNames()}") + // ... String.foo() = this.length + val foo = facade.methods.find { it.name == "foo" } + ?: throw IllegalStateException("Target function not found at ${uFile.asRefNames()}") + var thisReference: PsiElement? = foo + foo.accept(object : UastVisitor { + override fun visitElement(node: UElement): Boolean { + return false + } + + override fun visitThisExpression(node: UThisExpression): Boolean { + thisReference = node.resolve() + return false + } + }) + Assert.assertNull("plain `this` has `null` label", thisReference) + } + } } } diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastResolveProviderService.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastResolveProviderService.kt index 977ae6ec870..e4b923fa8c0 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastResolveProviderService.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastResolveProviderService.kt @@ -9,10 +9,7 @@ import com.intellij.psi.PsiElement import com.intellij.psi.PsiType import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper import org.jetbrains.kotlin.config.LanguageVersionSettings -import org.jetbrains.kotlin.psi.KtDoubleColonExpression -import org.jetbrains.kotlin.psi.KtElement -import org.jetbrains.kotlin.psi.KtExpression -import org.jetbrains.kotlin.psi.KtTypeReference +import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.constants.UnsignedErrorValueTypeConstant import org.jetbrains.kotlin.types.TypeUtils @@ -32,6 +29,9 @@ interface KotlinUastResolveProviderService : BaseKotlinUastResolveProviderServic } override fun resolveToDeclaration(ktExpression: KtExpression): PsiElement? { + if (ktExpression is KtExpressionWithLabel) { + return ktExpression.analyze()[BindingContext.LABEL_TARGET, ktExpression.getTargetLabel()] + } return resolveToDeclarationImpl(ktExpression) } diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSuperExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSuperExpression.kt deleted file mode 100644 index be62ed5dca6..00000000000 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSuperExpression.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2010-2016 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.uast.kotlin - -import org.jetbrains.kotlin.psi.KtSuperExpression -import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.uast.UElement -import org.jetbrains.uast.UIdentifier -import org.jetbrains.uast.USuperExpression -import org.jetbrains.uast.kotlin.internal.DelegatedMultiResolve - -class KotlinUSuperExpression( - override val sourcePsi: KtSuperExpression, - givenParent: UElement? -) : KotlinAbstractUExpression(givenParent), USuperExpression, DelegatedMultiResolve, KotlinUElementWithType, KotlinEvaluatableUElement { - override val label: String? - get() = sourcePsi.getLabelName() - - override val labelIdentifier: UIdentifier? - get() = sourcePsi.getTargetLabel()?.let { KotlinUIdentifier(it, this) } - - override fun resolve() = sourcePsi.analyze()[BindingContext.LABEL_TARGET, sourcePsi.getTargetLabel()] -} diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUThisExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUThisExpression.kt deleted file mode 100644 index c0745472f17..00000000000 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUThisExpression.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2010-2016 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.uast.kotlin - -import org.jetbrains.kotlin.psi.KtThisExpression -import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.uast.UElement -import org.jetbrains.uast.UIdentifier -import org.jetbrains.uast.UThisExpression -import org.jetbrains.uast.kotlin.internal.DelegatedMultiResolve - -class KotlinUThisExpression( - override val sourcePsi: KtThisExpression, - givenParent: UElement? -) : KotlinAbstractUExpression(givenParent), UThisExpression, DelegatedMultiResolve, KotlinUElementWithType, KotlinEvaluatableUElement { - override val label: String? - get() = sourcePsi.getLabelName() - - override val labelIdentifier: UIdentifier? - get() = sourcePsi.getTargetLabel()?.let { KotlinUIdentifier(it, this) } - - override fun resolve() = sourcePsi.analyze()[BindingContext.LABEL_TARGET, sourcePsi.getTargetLabel()] -}