FIR UAST: implement constructors/delegations

But, the logic is identical to the counterpart in FE1.0 UAST
Many declaration abstractions, such as (primary|secondary) constructor
methods and class, are very similar, and thus can be commonized soon
once the remaining parts (in particular, annotations) are done.
This commit is contained in:
Jinseong Jeon
2021-06-14 16:22:46 -07:00
committed by Ilya Kirillov
parent 8b3c6489da
commit 31d1c002c5
25 changed files with 399 additions and 106 deletions
@@ -5,11 +5,18 @@
package org.jetbrains.uast.kotlin
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.psi.*
import org.jetbrains.uast.*
interface BaseKotlinConverter {
fun convertDeclaration(
element: PsiElement,
givenParent: UElement?,
requiredTypes: Array<out Class<out UElement>>
): UElement?
fun convertReceiverParameter(receiver: KtTypeReference): UParameter? {
val call = (receiver.parent as? KtCallableDeclaration) ?: return null
if (call.receiverTypeReference != receiver) return null
@@ -0,0 +1,38 @@
/*
* 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.KtDelegatedSuperTypeEntry
import org.jetbrains.uast.*
import org.jetbrains.uast.kotlin.kinds.KotlinSpecialExpressionKinds
class KotlinSupertypeDelegationUExpression(
override val sourcePsi: KtDelegatedSuperTypeEntry,
givenParent: UElement?
) : KotlinAbstractUExpression(givenParent), UExpressionList {
override val psi: PsiElement
get() = sourcePsi
val typeReference: UTypeReferenceExpression? by lz {
sourcePsi.typeReference?.let {
KotlinUTypeReferenceExpression(it, this) {
baseResolveProviderService.resolveToType(it, this) ?: UastErrorType
}
}
}
val delegateExpression: UExpression? by lz {
sourcePsi.delegateExpression?.let { languagePlugin?.convertElement(it, this, UExpression::class.java) as? UExpression }
}
override val expressions: List<UExpression>
get() = listOfNotNull(typeReference, delegateExpression)
override val kind: UastSpecialExpressionKind
get() = KotlinSpecialExpressionKinds.SUPER_DELEGATION
}
@@ -5,8 +5,10 @@
package org.jetbrains.uast.kotlin
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass
import org.jetbrains.kotlin.asJava.elements.KtLightElement
import org.jetbrains.kotlin.asJava.elements.KtLightMember
@@ -52,3 +54,6 @@ fun KtElement.canAnalyze(): Boolean {
if (containingFile.doNotAnalyze != null) return false // To prevent exceptions during analysis
return true
}
val PsiClass.isEnumEntryLightClass: Boolean
get() = (this as? KtLightClass)?.kotlinOrigin is KtEnumEntry
@@ -6,9 +6,11 @@
package org.jetbrains.uast.kotlin
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtBlockExpression
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
import org.jetbrains.uast.*
import org.jetbrains.uast.kotlin.internal.KotlinFakeUElement
@@ -66,3 +68,19 @@ fun wrapExpressionBody(function: UElement, bodyExpression: KtExpression): UExpre
}
else -> function.getLanguagePlugin().convertElement(bodyExpression, function) as? UExpression
}
fun reportConvertFailure(psiMethod: PsiMethod): Nothing {
val isValid = psiMethod.isValid
val report = KotlinExceptionWithAttachments(
"cant convert $psiMethod of ${psiMethod.javaClass} to UMethod" + if (!isValid) " (method is not valid)" else ""
)
if (isValid) {
report.withAttachment("method", psiMethod.text)
psiMethod.containingFile?.let {
report.withAttachment("file", it.text)
}
}
throw report
}