diff --git a/idea/build.gradle.kts b/idea/build.gradle.kts index 0b1948b01af..ea827a552f0 100644 --- a/idea/build.gradle.kts +++ b/idea/build.gradle.kts @@ -78,6 +78,7 @@ dependencies { compile(project(":idea:idea-jps-common")) compile(project(":idea:kotlin-gradle-tooling")) compile(project(":idea:line-indent-provider")) + compile(project(":plugins:uast-kotlin-base")) compile(project(":plugins:uast-kotlin")) compile(project(":plugins:uast-kotlin-idea")) compile(project(":plugins:uast-kotlin-idea-base")) diff --git a/idea/resources-fir/META-INF/plugin.xml b/idea/resources-fir/META-INF/plugin.xml index 8d9e22d9d5f..8f669840174 100644 --- a/idea/resources-fir/META-INF/plugin.xml +++ b/idea/resources-fir/META-INF/plugin.xml @@ -128,6 +128,8 @@ The Kotlin FIR plugin provides language support in IntelliJ IDEA and Android Stu + diff --git a/idea/resources/META-INF/jvm-common.xml b/idea/resources/META-INF/jvm-common.xml index 24bef92f4a7..a3f2a18d2c5 100644 --- a/idea/resources/META-INF/jvm-common.xml +++ b/idea/resources/META-INF/jvm-common.xml @@ -137,6 +137,8 @@ displayName="Incompatible API usage" implementationClass="org.jetbrains.kotlin.idea.inspections.api.IncompatibleAPIInspection"/> + diff --git a/plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/BaseKotlinUastResolveProviderService.kt b/plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/BaseKotlinUastResolveProviderService.kt new file mode 100644 index 00000000000..b4d8b79534c --- /dev/null +++ b/plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/BaseKotlinUastResolveProviderService.kt @@ -0,0 +1,16 @@ +/* + * 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 com.intellij.psi.PsiElement +import org.jetbrains.uast.UElement + +interface BaseKotlinUastResolveProviderService { + fun isJvmElement(psiElement: PsiElement): Boolean + + fun convertParent(uElement: UElement): UElement? + +} diff --git a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/FirKotlinAbstractUElement.kt b/plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/KotlinAbstractUElement.kt similarity index 53% rename from plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/FirKotlinAbstractUElement.kt rename to plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/KotlinAbstractUElement.kt index e38c327a0a1..f4ef4159e88 100644 --- a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/FirKotlinAbstractUElement.kt +++ b/plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/KotlinAbstractUElement.kt @@ -5,21 +5,30 @@ package org.jetbrains.uast.kotlin -import com.intellij.psi.PsiElement +import com.intellij.openapi.components.ServiceManager import org.jetbrains.uast.UElement -import org.jetbrains.uast.UExpression +import org.jetbrains.uast.UastFacade +import org.jetbrains.uast.UastLanguagePlugin import org.jetbrains.uast.kotlin.internal.KotlinUElementWithComments -abstract class FirKotlinAbstractUElement( - private val givenParent: UElement? +abstract class KotlinAbstractUElement( + givenParent: UElement? ) : KotlinUElementWithComments { + protected val languagePlugin: UastLanguagePlugin? by lz { + psi?.let { UastFacade.findPlugin(it) } + } + + protected val baseResolveProviderService: BaseKotlinUastResolveProviderService? by lz { + psi?.project?.let { ServiceManager.getService(it, BaseKotlinUastResolveProviderService::class.java) } + } + final override val uastParent: UElement? by lz { givenParent ?: convertParent() } protected open fun convertParent(): UElement? { - TODO("Not yet implemented") + return baseResolveProviderService?.convertParent(this) } override fun equals(other: Any?): Boolean { @@ -27,21 +36,10 @@ abstract class FirKotlinAbstractUElement( return false } - return this.sourcePsi == other.sourcePsi + return this.psi == other.psi } override fun hashCode(): Int { - return sourcePsi?.hashCode() ?: 0 + return psi?.hashCode() ?: 0 } } - -abstract class FirKotlinAbstractUExpression( - givenParent: UElement? -) : FirKotlinAbstractUElement(givenParent), UExpression { - override val javaPsi: PsiElement? = null - - override val psi: PsiElement? - get() = sourcePsi - - // TODO: annotations -} diff --git a/plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/KotlinAbstractUExpression.kt b/plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/KotlinAbstractUExpression.kt new file mode 100644 index 00000000000..e9f6f958843 --- /dev/null +++ b/plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/KotlinAbstractUExpression.kt @@ -0,0 +1,29 @@ +/* + * 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 com.intellij.psi.PsiElement +import org.jetbrains.kotlin.psi.KtAnnotatedExpression +import org.jetbrains.uast.UAnnotation +import org.jetbrains.uast.UElement +import org.jetbrains.uast.UExpression +import org.jetbrains.uast.convertOpt + +abstract class KotlinAbstractUExpression( + givenParent: UElement? +) : KotlinAbstractUElement(givenParent), UExpression { + + override val javaPsi: PsiElement? = null + + override val psi + get() = sourcePsi + + override val uAnnotations: List + get() { + val annotatedExpression = sourcePsi?.parent as? KtAnnotatedExpression ?: return emptyList() + return annotatedExpression.annotationEntries.mapNotNull { languagePlugin?.convertOpt(it, this) } + } +} diff --git a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/FirKotlinUastLanguagePlugin.kt b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/FirKotlinUastLanguagePlugin.kt index 34b3380c698..113a7d7518a 100644 --- a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/FirKotlinUastLanguagePlugin.kt +++ b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/FirKotlinUastLanguagePlugin.kt @@ -6,6 +6,7 @@ package org.jetbrains.uast.kotlin import com.intellij.lang.Language +import com.intellij.openapi.components.ServiceManager import com.intellij.psi.PsiElement import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.psi.KtClassOrObject @@ -18,8 +19,10 @@ import org.jetbrains.uast.UExpression import org.jetbrains.uast.UastLanguagePlugin import org.jetbrains.uast.kotlin.FirKotlinConverter.convertDeclarationOrElement -interface FirKotlinUastResolveProviderService { - fun isJvmElement(psiElement: PsiElement): Boolean +interface FirKotlinUastResolveProviderService : BaseKotlinUastResolveProviderService { + override fun convertParent(uElement: UElement): UElement? { + TODO("Not yet implemented") + } } class FirKotlinUastLanguagePlugin : UastLanguagePlugin { @@ -33,7 +36,10 @@ class FirKotlinUastLanguagePlugin : UastLanguagePlugin { } private val PsiElement.isJvmElement: Boolean - get() = service.isJvmElement(this) + get() { + val resolveProvider = ServiceManager.getService(project, FirKotlinUastResolveProviderService::class.java) + return resolveProvider.isJvmElement(this) + } override fun convertElement(element: PsiElement, parent: UElement?, requiredType: Class?): UElement? { if (!element.isJvmElement) return null diff --git a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinUClass.kt b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinUClass.kt index 5ea05f84b95..c583bb86d0d 100644 --- a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinUClass.kt +++ b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinUClass.kt @@ -18,7 +18,7 @@ import org.jetbrains.uast.visitor.UastVisitor sealed class AbstractFirKotlinUClass( givenParent: UElement? -) : FirKotlinAbstractUElement(givenParent), UClass, UAnchorOwner { +) : KotlinAbstractUElement(givenParent), UClass, UAnchorOwner { override val uAnnotations: List get() { // TODO: Not yet implemented diff --git a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinUImportStatement.kt b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinUImportStatement.kt index 0402a98ecec..087325fddf0 100644 --- a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinUImportStatement.kt +++ b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinUImportStatement.kt @@ -19,7 +19,7 @@ import org.jetbrains.uast.USimpleNameReferenceExpression class FirKotlinUImportStatement( override val psi: KtImportDirective, givenParent: UElement? -): FirKotlinAbstractUElement(givenParent), UImportStatement { +) : KotlinAbstractUElement(givenParent), UImportStatement { override val javaPsi: PsiElement? = null override val sourcePsi: KtImportDirective = psi @@ -41,7 +41,7 @@ class FirKotlinUImportStatement( override val identifier: String, givenParent: UElement?, private val importDirective: KtImportDirective - ) : FirKotlinAbstractUExpression(givenParent), USimpleNameReferenceExpression { + ) : KotlinAbstractUExpression(givenParent), USimpleNameReferenceExpression { override val sourcePsi: KtExpression = psi override val resolvedName: String = identifier diff --git a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinUMethod.kt b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinUMethod.kt index d85706873db..becd1662c37 100644 --- a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinUMethod.kt +++ b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinUMethod.kt @@ -18,7 +18,7 @@ open class FirKotlinUMethod( psi: PsiMethod, final override val sourcePsi: KtDeclaration?, givenParent: UElement? -) : FirKotlinAbstractUElement(givenParent), UMethod, UAnchorOwner, PsiMethod by psi { +) : KotlinAbstractUElement(givenParent), UMethod, UAnchorOwner, PsiMethod by psi { constructor( psi: KtLightMethod, givenParent: UElement? diff --git a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinUVariable.kt b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinUVariable.kt index 5ca27792323..d42083678fa 100644 --- a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinUVariable.kt +++ b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinUVariable.kt @@ -14,7 +14,7 @@ import org.jetbrains.uast.visitor.UastVisitor sealed class AbstractFirKotlinUVariable( givenParent: UElement? -) : FirKotlinAbstractUElement(givenParent), PsiVariable, UVariableEx, UAnchorOwner { +) : KotlinAbstractUElement(givenParent), PsiVariable, UVariableEx, UAnchorOwner { override val uAnnotations: List get() { // TODO: Not yet implemented diff --git a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/expressions/FirKotlinUTypeReferenceExpression.kt b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/expressions/FirKotlinUTypeReferenceExpression.kt index ebd82a844ab..803a24d96e2 100644 --- a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/expressions/FirKotlinUTypeReferenceExpression.kt +++ b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/expressions/FirKotlinUTypeReferenceExpression.kt @@ -15,7 +15,7 @@ class FirKotlinUTypeReferenceExpression( override val sourcePsi: KtTypeReference, givenParent: UElement?, private val typeSupplier: (() -> PsiType)? = null, -) : FirKotlinAbstractUExpression(givenParent), UTypeReferenceExpression { +) : KotlinAbstractUExpression(givenParent), UTypeReferenceExpression { override val type: PsiType by lz { typeSupplier?.invoke() ?: sourcePsi.toPsiType(uastParent ?: this) } diff --git a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/expressions/FirUnknownKotlinExpression.kt b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/expressions/FirUnknownKotlinExpression.kt index cbb313df44f..9c67838a556 100644 --- a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/expressions/FirUnknownKotlinExpression.kt +++ b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/expressions/FirUnknownKotlinExpression.kt @@ -8,11 +8,10 @@ package org.jetbrains.uast.kotlin import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.uast.UElement import org.jetbrains.uast.UExpression -import org.jetbrains.uast.kotlin.FirKotlinAbstractUExpression class FirUnknownKotlinExpression( override val sourcePsi: KtExpression, givenParent: UElement? -) : FirKotlinAbstractUExpression(givenParent), UExpression { +) : KotlinAbstractUExpression(givenParent), UExpression { override fun asLogString() = "[!] FirUnknownKotlinExpression ($sourcePsi)" } diff --git a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/internal/firKotlinInternalUastUtils.kt b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/internal/firKotlinInternalUastUtils.kt index 9672a943642..4b536bd5d07 100644 --- a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/internal/firKotlinInternalUastUtils.kt +++ b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/internal/firKotlinInternalUastUtils.kt @@ -5,8 +5,6 @@ package org.jetbrains.uast.kotlin -import com.intellij.openapi.components.ServiceManager -import com.intellij.psi.PsiElement import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.uast.UastLanguagePlugin @@ -14,8 +12,3 @@ val firKotlinUastPlugin: UastLanguagePlugin by lz { UastLanguagePlugin.getInstances().find { it.language == KotlinLanguage.INSTANCE } ?: FirKotlinUastLanguagePlugin() } - -internal val PsiElement.service: FirKotlinUastResolveProviderService - get() { - return ServiceManager.getService(project, FirKotlinUastResolveProviderService::class.java) - } diff --git a/plugins/uast-kotlin-fir/tests/org/jetbrains/uast/test/env/kotlin/AbstractFirUastTest.kt b/plugins/uast-kotlin-fir/tests/org/jetbrains/uast/test/env/kotlin/AbstractFirUastTest.kt index c7e5911fd26..ec11e2301cd 100644 --- a/plugins/uast-kotlin-fir/tests/org/jetbrains/uast/test/env/kotlin/AbstractFirUastTest.kt +++ b/plugins/uast-kotlin-fir/tests/org/jetbrains/uast/test/env/kotlin/AbstractFirUastTest.kt @@ -19,6 +19,7 @@ import org.jetbrains.uast.UFile import org.jetbrains.uast.UastFacade import org.jetbrains.uast.UastLanguagePlugin import org.jetbrains.uast.common.kotlin.FirUastPluginSelection +import org.jetbrains.uast.kotlin.BaseKotlinUastResolveProviderService import org.jetbrains.uast.kotlin.FirKotlinUastResolveProviderService import org.jetbrains.uast.kotlin.firKotlinUastPlugin import org.jetbrains.uast.kotlin.internal.FirCliKotlinUastResolveProviderService @@ -45,9 +46,14 @@ abstract class AbstractFirUastTest : KotlinLightCodeInsightFixtureTestCase(), Fi ) area.getExtensionPoint(UastLanguagePlugin.extensionPointName) .registerExtension(firKotlinUastPlugin, testRootDisposable) + val service = FirCliKotlinUastResolveProviderService() + project.registerServiceInstance( + BaseKotlinUastResolveProviderService::class.java, + service + ) project.registerServiceInstance( FirKotlinUastResolveProviderService::class.java, - FirCliKotlinUastResolveProviderService() + service ) } diff --git a/plugins/uast-kotlin-idea-fir/build.gradle.kts b/plugins/uast-kotlin-idea-fir/build.gradle.kts index e04d0745bd5..d8c1cabb34b 100644 --- a/plugins/uast-kotlin-idea-fir/build.gradle.kts +++ b/plugins/uast-kotlin-idea-fir/build.gradle.kts @@ -11,8 +11,9 @@ dependencies { compile(project(":compiler:frontend.java")) compile(project(":idea:ide-common")) compile(project(":idea:idea-core")) - compile(project(":plugins:uast-kotlin-idea-base")) + compile(project(":plugins:uast-kotlin-base")) compile(project(":plugins:uast-kotlin-fir")) + compile(project(":plugins:uast-kotlin-idea-base")) compileOnly(intellijDep()) compileOnly(intellijPluginDep("java")) } diff --git a/plugins/uast-kotlin-idea/build.gradle.kts b/plugins/uast-kotlin-idea/build.gradle.kts index 25e9b490f18..ce091d09b95 100644 --- a/plugins/uast-kotlin-idea/build.gradle.kts +++ b/plugins/uast-kotlin-idea/build.gradle.kts @@ -11,6 +11,7 @@ dependencies { compile(project(":compiler:frontend.java")) compile(project(":idea:ide-common")) compile(project(":idea:idea-core")) + compile(project(":plugins:uast-kotlin-base")) compile(project(":plugins:uast-kotlin")) compile(project(":plugins:uast-kotlin-idea-base")) compileOnly(intellijDep()) diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastLanguagePlugin.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastLanguagePlugin.kt index 42cde1e9fba..4cce4329652 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastLanguagePlugin.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastLanguagePlugin.kt @@ -53,12 +53,15 @@ import org.jetbrains.uast.kotlin.declarations.KotlinUMethodWithFakeLightDelegate import org.jetbrains.uast.kotlin.expressions.* import org.jetbrains.uast.kotlin.psi.* -interface KotlinUastResolveProviderService { +interface KotlinUastResolveProviderService : BaseKotlinUastResolveProviderService { fun getBindingContext(element: KtElement): BindingContext fun getTypeMapper(element: KtElement): KotlinTypeMapper? fun getLanguageVersionSettings(element: KtElement): LanguageVersionSettings - fun isJvmElement(psiElement: PsiElement): Boolean fun getReferenceVariants(ktElement: KtElement, nameHint: String): Sequence + + override fun convertParent(uElement: UElement): UElement? { + return convertParentImpl(uElement) + } } var PsiElement.destructuringDeclarationInitializer: Boolean? by UserDataProperty(Key.create("kotlin.uast.destructuringDeclarationInitializer")) diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinAbstractUElement.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/kotlinConvertParentUtils.kt similarity index 55% rename from plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinAbstractUElement.kt rename to plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/kotlinConvertParentUtils.kt index de4d9391e29..da886e6491a 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinAbstractUElement.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/kotlinConvertParentUtils.kt @@ -33,122 +33,104 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.uast.* import org.jetbrains.uast.kotlin.expressions.KotlinLocalFunctionULambdaExpression import org.jetbrains.uast.kotlin.expressions.KotlinUElvisExpression -import org.jetbrains.uast.kotlin.internal.KotlinUElementWithComments import org.jetbrains.uast.kotlin.psi.UastKotlinPsiParameter import org.jetbrains.uast.kotlin.psi.UastKotlinPsiVariable -abstract class KotlinAbstractUElement(private val givenParent: UElement?) : KotlinUElementWithComments { +fun convertParentImpl(uElement: UElement): UElement? { + @Suppress("DEPRECATION") + val psi = uElement.psi //TODO: `psi` is deprecated but it seems that it couldn't be simply replaced for this case + var parent = psi?.parent ?: uElement.sourcePsi?.parent ?: psi?.containingFile + + if (psi is PsiMethod && psi !is KtLightMethod) { // handling of synthetic things not represented in lightclasses directly + when (parent) { + is KtClassBody -> { + val grandParent = parent.parent + doConvertParent(uElement, grandParent)?.let { return it } + parent = grandParent + } + is KtFile -> { + parent.toUElementOfType()?.let { return it } // mutlifile facade class + } + } - final override val uastParent: UElement? by lz { - givenParent ?: convertParent() } - protected open fun convertParent(): UElement? { - @Suppress("DEPRECATION") - val psi = psi //TODO: `psi` is deprecated but it seems that it couldn't be simply replaced for this case - var parent = psi?.parent ?: sourcePsi?.parent ?: psi?.containingFile - - if (psi is PsiMethod && psi !is KtLightMethod) { // handling of synthetic things not represented in lightclasses directly - when (parent) { - is KtClassBody -> { - val grandParent = parent.parent - doConvertParent(this, grandParent)?.let { return it } - parent = grandParent - } - is KtFile -> { - parent.toUElementOfType()?.let { return it } // mutlifile facade class - } - } - + if (psi is KtLightElement<*, *> && uElement.sourcePsi.safeAs()?.isLocal == true) { + val originParent = psi.kotlinOrigin?.parent + parent = when (originParent) { + null -> parent + is KtClassBody -> originParent.parent + else -> originParent } - - if (psi is KtLightElement<*, *> && sourcePsi.safeAs()?.isLocal == true) { - val originParent = psi.kotlinOrigin?.parent - parent = when (originParent) { - null -> parent - is KtClassBody -> originParent.parent - else -> originParent - } - } - - if (psi is KtAnnotationEntry) { - val parentUnwrapped = KotlinConverter.unwrapElements(parent) ?: return null - val target = psi.useSiteTarget?.getAnnotationUseSiteTarget() - when (target) { - AnnotationUseSiteTarget.PROPERTY_GETTER -> - parent = (parentUnwrapped as? KtProperty)?.getter - ?: (parentUnwrapped as? KtParameter)?.toLightGetter() - ?: parent - - AnnotationUseSiteTarget.PROPERTY_SETTER -> - parent = (parentUnwrapped as? KtProperty)?.setter - ?: (parentUnwrapped as? KtParameter)?.toLightSetter() - ?: parent - AnnotationUseSiteTarget.FIELD -> - parent = (parentUnwrapped as? KtProperty) - ?: (parentUnwrapped as? KtParameter) - ?.takeIf { it.isPropertyParameter() } - ?.let(LightClassUtil::getLightClassBackingField) - ?: parent - AnnotationUseSiteTarget.SETTER_PARAMETER -> - parent = (parentUnwrapped as? KtParameter) - ?.toLightSetter()?.parameterList?.parameters?.firstOrNull() ?: parent - } - } - if ((psi is UastKotlinPsiVariable || psi is UastKotlinPsiParameter) && parent != null) { - parent = parent.parent - } - - if (KotlinConverter.forceUInjectionHost) { - if (parent is KtBlockStringTemplateEntry) { - parent = parent.parent - } - } else - while (parent is KtStringTemplateEntryWithExpression || parent is KtStringTemplateExpression && parent.entries.size == 1) { - parent = parent.parent - } - - if (parent is KtWhenConditionWithExpression) { - parent = parent.parent - } - - if (parent is KtImportList) { - parent = parent.parent - } - - if (psi is KtFunctionLiteral && parent is KtLambdaExpression) { - parent = parent.parent - } - - if (parent is KtLambdaArgument) { - parent = parent.parent - } - - if (psi is KtSuperTypeCallEntry) { - parent = parent?.parent - } - - if (parent is KtPropertyDelegate) { - parent = parent.parent - } - - val result = doConvertParent(this, parent) - if (result == this) { - throw IllegalStateException("Loop in parent structure when converting a $psi of type ${psi?.javaClass} with parent $parent of type ${parent?.javaClass} text: [${parent?.text}], result = $result") - } - - return result } - override fun equals(other: Any?): Boolean { - if (other !is UElement) { - return false - } + if (psi is KtAnnotationEntry) { + val parentUnwrapped = KotlinConverter.unwrapElements(parent) ?: return null + val target = psi.useSiteTarget?.getAnnotationUseSiteTarget() + when (target) { + AnnotationUseSiteTarget.PROPERTY_GETTER -> + parent = (parentUnwrapped as? KtProperty)?.getter + ?: (parentUnwrapped as? KtParameter)?.toLightGetter() + ?: parent - return this.psi == other.psi + AnnotationUseSiteTarget.PROPERTY_SETTER -> + parent = (parentUnwrapped as? KtProperty)?.setter + ?: (parentUnwrapped as? KtParameter)?.toLightSetter() + ?: parent + AnnotationUseSiteTarget.FIELD -> + parent = (parentUnwrapped as? KtProperty) + ?: (parentUnwrapped as? KtParameter) + ?.takeIf { it.isPropertyParameter() } + ?.let(LightClassUtil::getLightClassBackingField) + ?: parent + AnnotationUseSiteTarget.SETTER_PARAMETER -> + parent = (parentUnwrapped as? KtParameter) + ?.toLightSetter()?.parameterList?.parameters?.firstOrNull() ?: parent + } + } + if ((psi is UastKotlinPsiVariable || psi is UastKotlinPsiParameter) && parent != null) { + parent = parent.parent } - override fun hashCode() = psi?.hashCode() ?: 0 + if (KotlinConverter.forceUInjectionHost) { + if (parent is KtBlockStringTemplateEntry) { + parent = parent.parent + } + } else + while (parent is KtStringTemplateEntryWithExpression || parent is KtStringTemplateExpression && parent.entries.size == 1) { + parent = parent.parent + } + + if (parent is KtWhenConditionWithExpression) { + parent = parent.parent + } + + if (parent is KtImportList) { + parent = parent.parent + } + + if (psi is KtFunctionLiteral && parent is KtLambdaExpression) { + parent = parent.parent + } + + if (parent is KtLambdaArgument) { + parent = parent.parent + } + + if (psi is KtSuperTypeCallEntry) { + parent = parent?.parent + } + + if (parent is KtPropertyDelegate) { + parent = parent.parent + } + + val result = doConvertParent(uElement, parent) + if (result == uElement) { + throw IllegalStateException("Loop in parent structure when converting a $psi of type ${psi?.javaClass} with parent $parent of type ${parent?.javaClass} text: [${parent?.text}], result = $result") + } + + return result } fun doConvertParent(element: UElement, parent: PsiElement?): UElement? { @@ -247,20 +229,3 @@ private fun findAnnotationClassFromConstructorParameter(parameter: KtParameter): } return null } - -abstract class KotlinAbstractUExpression(givenParent: UElement?) : - KotlinAbstractUElement(givenParent), - UExpression { - - override val javaPsi: PsiElement? = null - - override val psi - get() = sourcePsi - - override val annotations: List - get() { - val annotatedExpression = sourcePsi?.parent as? KtAnnotatedExpression ?: return emptyList() - return annotatedExpression.annotationEntries.map { KotlinUAnnotation(it, this) } - } -} - diff --git a/plugins/uast-kotlin/tests/AbstractKotlinUastTest.kt b/plugins/uast-kotlin/tests/AbstractKotlinUastTest.kt index a205b525d48..3071647cecb 100644 --- a/plugins/uast-kotlin/tests/AbstractKotlinUastTest.kt +++ b/plugins/uast-kotlin/tests/AbstractKotlinUastTest.kt @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.test.TestJdkKind import org.jetbrains.kotlin.test.testFramework.resetApplicationToNull import org.jetbrains.uast.UastLanguagePlugin import org.jetbrains.uast.evaluation.UEvaluatorExtension +import org.jetbrains.uast.kotlin.BaseKotlinUastResolveProviderService import org.jetbrains.uast.kotlin.KotlinUastLanguagePlugin import org.jetbrains.uast.kotlin.KotlinUastResolveProviderService import org.jetbrains.uast.kotlin.evaluation.KotlinEvaluatorExtension @@ -94,6 +95,10 @@ abstract class AbstractKotlinUastTest : AbstractUastTest() { area.getExtensionPoint(UEvaluatorExtension.EXTENSION_POINT_NAME) .registerExtension(KotlinEvaluatorExtension()) + project.registerService( + BaseKotlinUastResolveProviderService::class.java, + CliKotlinUastResolveProviderService::class.java + ) project.registerService( KotlinUastResolveProviderService::class.java, CliKotlinUastResolveProviderService::class.java