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 7bd41bfd340..50b9ac78c90 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastLanguagePlugin.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastLanguagePlugin.kt @@ -19,7 +19,6 @@ package org.jetbrains.uast.kotlin import com.intellij.lang.Language import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile -import com.intellij.psi.PsiVariable import com.intellij.psi.impl.source.tree.LeafPsiElement import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.kotlin.asJava.LightClassUtil @@ -39,7 +38,6 @@ import org.jetbrains.uast.* import org.jetbrains.uast.java.JavaUastLanguagePlugin import org.jetbrains.uast.kotlin.declarations.KotlinUMethod import org.jetbrains.uast.kotlin.expressions.* -import org.jetbrains.uast.kotlin.kinds.KotlinSpecialExpressionKinds import org.jetbrains.uast.kotlin.psi.UastKotlinPsiParameter import org.jetbrains.uast.kotlin.psi.UastKotlinPsiVariable @@ -62,7 +60,8 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin { override fun convertElement(element: PsiElement, parent: UElement?, requiredType: Class?): UElement? { if (element !is PsiElement) return null - return convertDeclaration(element, parent, requiredType) ?: KotlinConverter.convertPsiElement(element, parent, requiredType) + return convertDeclaration(element, parent.toCallback(), requiredType) + ?: KotlinConverter.convertPsiElement(element, parent.toCallback(), requiredType) } override fun convertElementWithParent(element: PsiElement, requiredType: Class?): UElement? { @@ -70,9 +69,12 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin { if (element is PsiFile) return convertDeclaration(element, null, requiredType) if (element is KtLightClassForFacade) return convertDeclaration(element, null, requiredType) - val parent = KotlinConverter.unwrapElements(element.parent) ?: return null - val parentUElement = convertElementWithParent(parent, null) ?: return null - return convertElement(element, parentUElement, requiredType) + val parentCallback = fun(): UElement? { + val parent = KotlinConverter.unwrapElements(element.parent) ?: return null + return convertElementWithParent(parent, null) + } + return convertDeclaration(element, parentCallback, requiredType) + ?: KotlinConverter.convertPsiElement(element, parentCallback, requiredType) } override fun getMethodCallExpression( @@ -115,35 +117,53 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin { return UastLanguagePlugin.ResolvedConstructor(uExpression, method, containingClass) } - private fun convertDeclaration(element: PsiElement, parent: UElement?, requiredType: Class?): UElement? { + private fun convertDeclaration(element: PsiElement, + parentCallback: (() -> UElement?)?, + requiredType: Class?): UElement? { if (element is UElement) return element if (element.isValid) element.getUserData(KOTLIN_CACHED_UELEMENT_KEY)?.let { ref -> ref.get()?.let { return it } } - + + fun

build(ctor: (P, UElement?) -> UElement): () -> UElement? { + return fun(): UElement? { + val parent = if (parentCallback == null) null else (parentCallback() ?: return null) + return ctor(element as P, parent) + } + } + val original = element.originalElement return with(requiredType) { when (original) { - is KtLightMethod -> el { KotlinUMethod.create(original, parent) } - is KtLightClass -> el { KotlinUClass.create(original, parent) } - is KtLightField, is KtLightParameter, is UastKotlinPsiParameter, is UastKotlinPsiVariable -> el { - KotlinUVariable.create(original as PsiVariable, parent) - } + is KtLightMethod -> el(build(KotlinUMethod.Companion::create)) // .Companion is needed because of KT-13934 + is KtLightClass -> el(build(KotlinUClass.Companion::create)) - is KtClassOrObject -> el { original.toLightClass()?.let { lightClass -> KotlinUClass.create(lightClass, parent) } } + is KtLightFieldImpl.KtLightEnumConstant -> el(build(::KotlinUEnumConstant)) + is KtLightField -> el(build(::KotlinUField)) + is KtLightParameter, is UastKotlinPsiParameter -> el(build(::KotlinUParameter)) + is UastKotlinPsiVariable -> el(build(::KotlinUVariable)) + + is KtClassOrObject -> el { + original.toLightClass()?.let { lightClass -> + val parent = if (parentCallback == null) null else (parentCallback() ?: return null) + KotlinUClass.create(lightClass, parent) + } + } is KtFunction -> el { val lightMethod = LightClassUtil.getLightClassMethod(original) ?: return null - convertDeclaration(lightMethod, parent, requiredType) + convertDeclaration(lightMethod, parentCallback, requiredType) } is KtPropertyAccessor -> el { + val parent = if (parentCallback == null) null else (parentCallback() ?: return null) javaPlugin.convertOpt( LightClassUtil.getLightClassAccessorMethod(original), parent) } is KtProperty -> el { + val parent = if (parentCallback == null) null else (parentCallback() ?: return null) javaPlugin.convertOpt( LightClassUtil.getLightClassBackingField(original), parent) - ?: convertDeclaration(element.parent, parent, requiredType) + ?: convertDeclaration(element.parent, parentCallback, requiredType) } is KtFile -> el { KotlinUFile(original, this@KotlinUastLanguagePlugin) } @@ -166,14 +186,16 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin { } } -internal inline fun Class?.el(f: () -> UElement?): UElement? { - return if (this == null || T::class.java == this) f() else null +internal inline fun Class?.el(f: () -> UElement?): UElement? { + return if (this == null || isAssignableFrom(ActualT::class.java)) f() else null } -internal inline fun Class?.expr(f: () -> UExpression): UExpression? { - return if (this == null || UExpression::class.java == this || T::class.java == this) f() else null +internal inline fun Class?.expr(f: () -> UExpression?): UExpression? { + return if (this == null || isAssignableFrom(ActualT::class.java)) f() else null } +internal fun UElement?.toCallback() = if (this != null) fun(): UElement? { return this } else null + internal object KotlinConverter { internal tailrec fun unwrapElements(element: PsiElement?): PsiElement? = when (element) { is KtValueArgumentList -> unwrapElements(element.parent) @@ -181,69 +203,77 @@ internal object KotlinConverter { else -> element } - internal fun convertPsiElement(element: PsiElement?, parent: UElement?, requiredType: Class?): UElement? { + internal fun convertPsiElement(element: PsiElement?, + parentCallback: (() -> UElement?)?, + requiredType: Class?): UElement? { + fun

build(ctor: (P, UElement?) -> UElement): () -> UElement? { + return fun(): UElement? { + val parent = if (parentCallback == null) null else (parentCallback() ?: return null) + return ctor(element as P, parent) + } + } + return with (requiredType) { when (element) { is KtParameterList -> el { + val parent = if (parentCallback == null) null else (parentCallback() ?: return null) KotlinUDeclarationsExpression(parent).apply { declarations = element.parameters.mapIndexed { i, p -> KotlinUVariable.create(UastKotlinPsiParameter.create(p, element, parent!!, i), this) } } } - is KtClassBody -> el { - KotlinUExpressionList(element, KotlinSpecialExpressionKinds.CLASS_BODY, parent).apply { - expressions = emptyList() - } - } - is KtCatchClause -> el { KotlinUCatchClause(element, parent) } - is KtExpression -> KotlinConverter.convertExpression(element, parent, requiredType) - is KtLambdaArgument -> KotlinConverter.convertExpression(element.getLambdaExpression(), parent, requiredType) + is KtClassBody -> el(build(KotlinUExpressionList.Companion::createClassBody)) + is KtCatchClause -> el(build(::KotlinUCatchClause)) + is KtExpression -> KotlinConverter.convertExpression(element, parentCallback, requiredType) + is KtLambdaArgument -> KotlinConverter.convertExpression(element.getLambdaExpression(), parentCallback, requiredType) is KtContainerNode -> element.getExpression()?.let { - KotlinConverter.convertExpression(it, parent, requiredType) + KotlinConverter.convertExpression(it, parentCallback, requiredType) } ?: el { UastEmptyExpression } is KtLightAnnotation.LightExpressionValue<*> -> { val expression = element.originalExpression when (expression) { - is KtExpression -> KotlinConverter.convertExpression(expression, parent, requiredType) + is KtExpression -> KotlinConverter.convertExpression(expression, parentCallback, requiredType) else -> el { UastEmptyExpression } } } - is KtLiteralStringTemplateEntry -> expr { KotlinStringULiteralExpression(element, parent, element.getText()) } - is KtEscapeStringTemplateEntry -> expr { KotlinStringULiteralExpression(element, parent, element.unescapedValue) } - is KtStringTemplateEntry -> element.expression?.let { convertExpression(it, parent, requiredType) } ?: expr { UastEmptyExpression } + is KtLiteralStringTemplateEntry, is KtEscapeStringTemplateEntry -> el(build(::KotlinStringULiteralExpression)) + is KtStringTemplateEntry -> element.expression?.let { convertExpression(it, parentCallback, requiredType) } ?: expr { UastEmptyExpression } else -> { if (element is LeafPsiElement && element.elementType == KtTokens.IDENTIFIER) { - el { UIdentifier(element, parent) } + el(build(::UIdentifier)) } else { null } } }} } - - private fun convertVariablesDeclaration( - psi: KtVariableDeclaration, - parent: UElement? - ): UDeclarationsExpression { - val parentPsiElement = parent?.psi - val variable = KotlinUVariable.create(UastKotlinPsiVariable.create(psi, parentPsiElement, parent!!), parent) - return KotlinUDeclarationsExpression(parent).apply { declarations = listOf(variable) } - } + internal fun convert(entry: KtStringTemplateEntry, parent: UElement?): UExpression = when (entry) { - is KtStringTemplateEntryWithExpression -> convertOrEmpty(entry.expression, parent) + is KtStringTemplateEntryWithExpression -> KotlinConverter.convertOrEmpty(entry.expression, parent) is KtEscapeStringTemplateEntry -> KotlinStringULiteralExpression(entry, parent, entry.unescapedValue) else -> { KotlinStringULiteralExpression(entry, parent) } } - internal fun convertExpression(expression: KtExpression, parent: UElement?, requiredType: Class? = null): UExpression? { + + internal fun convertExpression(expression: KtExpression, + parentCallback: (() -> UElement?)?, + requiredType: Class? = null): UExpression? { + fun

build(ctor: (P, UElement?) -> UExpression): () -> UExpression? { + return fun(): UExpression? { + val parent = if (parentCallback == null) null else (parentCallback() ?: return null) + return ctor(expression as P, parent) + } + } + return with (requiredType) { when (expression) { - is KtVariableDeclaration -> expr { convertVariablesDeclaration(expression, parent) } + is KtVariableDeclaration -> expr(build(::convertVariablesDeclaration)) is KtStringTemplateExpression -> expr { + val parent = if (parentCallback == null) null else (parentCallback() ?: return null) if (expression.entries.isEmpty()) KotlinStringULiteralExpression(expression, parent, "") else if (expression.entries.size == 1) @@ -252,6 +282,7 @@ internal object KotlinConverter { KotlinStringTemplateUPolyadicExpression(expression, parent) } is KtDestructuringDeclaration -> expr { + val parent = if (parentCallback == null) null else (parentCallback() ?: return null) KotlinUDeclarationsExpression(parent).apply { val tempAssignment = KotlinUVariable.create(UastKotlinPsiVariable.create(expression, parent!!), parent) val destructuringAssignments = expression.entries.mapIndexed { i, entry -> @@ -264,68 +295,67 @@ internal object KotlinConverter { declarations = listOf(tempAssignment) + destructuringAssignments } } - is KtLabeledExpression -> expr { KotlinULabeledExpression(expression, parent) } - is KtClassLiteralExpression -> expr { KotlinUClassLiteralExpression(expression, parent) } - is KtObjectLiteralExpression -> expr { KotlinUObjectLiteralExpression(expression, parent) } - is KtDotQualifiedExpression -> expr { KotlinUQualifiedReferenceExpression(expression, parent) } - is KtSafeQualifiedExpression -> expr { KotlinUSafeQualifiedExpression(expression, parent) } - is KtSimpleNameExpression -> expr { - KotlinUSimpleReferenceExpression(expression, expression.getReferencedName(), parent) - } - is KtCallExpression -> expr { KotlinUFunctionCallExpression(expression, parent) } + is KtLabeledExpression -> expr(build(::KotlinULabeledExpression)) + is KtClassLiteralExpression -> expr(build(::KotlinUClassLiteralExpression)) + is KtObjectLiteralExpression -> expr(build(::KotlinUObjectLiteralExpression)) + is KtDotQualifiedExpression -> expr(build(::KotlinUQualifiedReferenceExpression)) + is KtSafeQualifiedExpression -> expr(build(::KotlinUSafeQualifiedExpression)) + is KtSimpleNameExpression -> expr(build(::KotlinUSimpleReferenceExpression)) + is KtCallExpression -> expr(build(::KotlinUFunctionCallExpression)) is KtBinaryExpression -> { if (expression.operationToken == KtTokens.ELVIS) { - expr { createElvisExpression(expression, parent) ?: UastEmptyExpression } + expr(build(::createElvisExpression)) } - else expr { KotlinUBinaryExpression(expression, parent) } + else expr(build(::KotlinUBinaryExpression)) } - is KtParenthesizedExpression -> expr { KotlinUParenthesizedExpression(expression, parent) } - is KtPrefixExpression -> expr { KotlinUPrefixExpression(expression, parent) } - is KtPostfixExpression -> expr { KotlinUPostfixExpression(expression, parent) } - is KtThisExpression -> expr { KotlinUThisExpression(expression, parent) } - is KtSuperExpression -> expr { KotlinUSuperExpression(expression, parent) } - is KtCallableReferenceExpression -> expr { KotlinUCallableReferenceExpression(expression, parent) } - is KtIsExpression -> expr { KotlinUTypeCheckExpression(expression, parent) } - is KtIfExpression -> expr { KotlinUIfExpression(expression, parent) } - is KtWhileExpression -> expr { KotlinUWhileExpression(expression, parent) } - is KtDoWhileExpression -> expr { KotlinUDoWhileExpression(expression, parent) } - is KtForExpression -> expr { KotlinUForEachExpression(expression, parent) } - is KtWhenExpression -> expr { KotlinUSwitchExpression(expression, parent) } - is KtBreakExpression -> expr { KotlinUBreakExpression(expression, parent) } - is KtContinueExpression -> expr { KotlinUContinueExpression(expression, parent) } - is KtReturnExpression -> expr { KotlinUReturnExpression(expression, parent) } - is KtThrowExpression -> expr { KotlinUThrowExpression(expression, parent) } - is KtBlockExpression -> expr { KotlinUBlockExpression(expression, parent) } - is KtConstantExpression -> expr { KotlinULiteralExpression(expression, parent) } - is KtTryExpression -> expr { KotlinUTryExpression(expression, parent) } - is KtArrayAccessExpression -> expr { KotlinUArrayAccessExpression(expression, parent) } - is KtLambdaExpression -> expr { KotlinULambdaExpression(expression, parent) } - is KtBinaryExpressionWithTypeRHS -> expr { KotlinUBinaryExpressionWithType(expression, parent) } + is KtParenthesizedExpression -> expr(build(::KotlinUParenthesizedExpression)) + is KtPrefixExpression -> expr(build(::KotlinUPrefixExpression)) + is KtPostfixExpression -> expr(build(::KotlinUPostfixExpression)) + is KtThisExpression -> expr(build(::KotlinUThisExpression)) + is KtSuperExpression -> expr(build(::KotlinUSuperExpression)) + is KtCallableReferenceExpression -> expr(build(::KotlinUCallableReferenceExpression)) + is KtIsExpression -> expr(build(::KotlinUTypeCheckExpression)) + is KtIfExpression -> expr(build(::KotlinUIfExpression)) + is KtWhileExpression -> expr(build(::KotlinUWhileExpression)) + is KtDoWhileExpression -> expr(build(::KotlinUDoWhileExpression)) + is KtForExpression -> expr(build(::KotlinUForEachExpression)) + is KtWhenExpression -> expr(build(::KotlinUSwitchExpression)) + is KtBreakExpression -> expr(build(::KotlinUBreakExpression)) + is KtContinueExpression -> expr(build(::KotlinUContinueExpression)) + is KtReturnExpression -> expr(build(::KotlinUReturnExpression)) + is KtThrowExpression -> expr(build(::KotlinUThrowExpression)) + is KtBlockExpression -> expr(build(::KotlinUBlockExpression)) + is KtConstantExpression -> expr(build(::KotlinULiteralExpression)) + is KtTryExpression -> expr(build(::KotlinUTryExpression)) + is KtArrayAccessExpression -> expr(build(::KotlinUArrayAccessExpression)) + is KtLambdaExpression -> expr(build(::KotlinULambdaExpression)) + is KtBinaryExpressionWithTypeRHS -> expr(build(::KotlinUBinaryExpressionWithType)) is KtClassOrObject -> expr { expression.toLightClass()?.let { lightClass -> + val parent = if (parentCallback == null) null else (parentCallback() ?: return null) KotlinUDeclarationsExpression(parent).apply { declarations = listOf(KotlinUClass.create(lightClass, this)) } } ?: UastEmptyExpression } is KtFunction -> if (expression.name.isNullOrEmpty()) { - expr { createLocalFunctionLambdaExpression(expression, parent) } + expr(build(::createLocalFunctionLambdaExpression)) } else { - expr { createLocalFunctionDeclaration(expression, parent) } + expr(build(::createLocalFunctionDeclaration)) } - else -> UnknownKotlinExpression(expression, parent) + else -> expr(build(::UnknownKotlinExpression)) }} } internal fun convertOrEmpty(expression: KtExpression?, parent: UElement?): UExpression { - return expression?.let { convertExpression(it, parent, null) } ?: UastEmptyExpression + return expression?.let { convertExpression(it, parent.toCallback(), null) } ?: UastEmptyExpression } internal fun convertOrNull(expression: KtExpression?, parent: UElement?): UExpression? { - return if (expression != null) convertExpression(expression, parent, null) else null + return if (expression != null) convertExpression(expression, parent.toCallback(), null) else null } internal fun KtPsiFactory.createAnalyzableExpression(text: String, context: PsiElement): KtExpression = @@ -345,4 +375,13 @@ internal object KotlinConverter { internal fun KtContainerNode.getExpression(): KtExpression? = PsiTreeUtil.getChildOfType(this, KtExpression::class.java) -} \ No newline at end of file +} + +private fun convertVariablesDeclaration( + psi: KtVariableDeclaration, + parent: UElement? +): UDeclarationsExpression { + val parentPsiElement = parent?.psi + val variable = KotlinUVariable.create(UastKotlinPsiVariable.create(psi, parentPsiElement, parent!!), parent) + return KotlinUDeclarationsExpression(parent).apply { declarations = listOf(variable) } +} diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/ElvisExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/ElvisExpression.kt index 081dd4147ac..f827b8f399a 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/ElvisExpression.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/ElvisExpression.kt @@ -56,7 +56,7 @@ private fun createElvisExpressions( override val uastParent: UElement? = containingElement override val condition: UExpression by lz { createNotEqWithNullExpression(tempVariable, this) } override val thenExpression: UExpression? by lz { createVariableReferenceExpression(tempVariable, this) } - override val elseExpression: UExpression? by lz { KotlinConverter.convertExpression(right, this) } + override val elseExpression: UExpression? by lz { KotlinConverter.convertExpression(right, this.toCallback() ) } override val isTernary: Boolean = false override val annotations: List = emptyList() override val ifIdentifier: UIdentifier = UIdentifier(null, this) @@ -66,9 +66,9 @@ private fun createElvisExpressions( return listOf(declaration, ifExpression) } -fun createElvisExpression(elvisExpression: KtBinaryExpression, containingElement: UElement?): UExpressionList? { - val left = elvisExpression.left ?: return null - val right = elvisExpression.right ?: return null +fun createElvisExpression(elvisExpression: KtBinaryExpression, containingElement: UElement?): UExpression { + val left = elvisExpression.left ?: return UastEmptyExpression + val right = elvisExpression.right ?: return UastEmptyExpression return object : UExpressionList, KotlinEvaluatableUElement, KotlinUElementWithType { override val psi: PsiElement? = elvisExpression diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUCallableReferenceExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUCallableReferenceExpression.kt index 34704bb9e9f..e1c6210b907 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUCallableReferenceExpression.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUCallableReferenceExpression.kt @@ -31,7 +31,7 @@ class KotlinUCallableReferenceExpression( get() { if (qualifierType != null) return null val receiverExpression = psi.receiverExpression ?: return null - return KotlinConverter.convertExpression(receiverExpression, this) + return KotlinConverter.convertExpression(receiverExpression, { this }) } override val qualifierType by lz { diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUClassLiteralExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUClassLiteralExpression.kt index 7d69abf1360..f8693061035 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUClassLiteralExpression.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUClassLiteralExpression.kt @@ -35,6 +35,6 @@ class KotlinUClassLiteralExpression( get() { if (type != null) return null val receiverExpression = psi.receiverExpression ?: return null - return KotlinConverter.convertExpression(receiverExpression, this) + return KotlinConverter.convertExpression(receiverExpression, { this }) } } \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUDeclarationsExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUDeclarationsExpression.kt index 3a2cf36bef0..329c63381fb 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUDeclarationsExpression.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUDeclarationsExpression.kt @@ -19,10 +19,11 @@ import com.intellij.psi.PsiElement import org.jetbrains.uast.kotlin.KotlinAbstractUExpression class KotlinUDeclarationsExpression( + override val psi: PsiElement?, override val uastParent: UElement? ) : KotlinAbstractUExpression(), UDeclarationsExpression { - override val psi: PsiElement? - get() = null + + constructor(uastParent: UElement?) : this(null, uastParent) override lateinit var declarations: List internal set diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUExpressionList.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUExpressionList.kt index 3ee39d5eda5..1c7fe3114f8 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUExpressionList.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUExpressionList.kt @@ -24,6 +24,7 @@ import org.jetbrains.uast.UElement import org.jetbrains.uast.UExpression import org.jetbrains.uast.UExpressionList import org.jetbrains.uast.UastSpecialExpressionKind +import org.jetbrains.uast.kotlin.kinds.KotlinSpecialExpressionKinds open class KotlinUExpressionList( override val psi: PsiElement?, @@ -38,4 +39,11 @@ open class KotlinUExpressionList( val compileTimeConst = ktElement.analyze()[BindingContext.COMPILE_TIME_VALUE, ktElement] return compileTimeConst?.getValue(TypeUtils.NO_EXPECTED_TYPE) } -} \ No newline at end of file + + companion object { + fun createClassBody(psi: PsiElement?, uastParent: UElement?): KotlinUExpressionList = + KotlinUExpressionList(psi, KotlinSpecialExpressionKinds.CLASS_BODY, uastParent).apply { + expressions = emptyList() + } + } +} diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUFunctionCallExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUFunctionCallExpression.kt index 5280616238a..323c58b4132 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUFunctionCallExpression.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUFunctionCallExpression.kt @@ -35,7 +35,7 @@ import org.jetbrains.uast.visitor.UastVisitor class KotlinUFunctionCallExpression( override val psi: KtCallExpression, override val uastParent: UElement?, - private val _resolvedCall: ResolvedCall<*>? = null + private val _resolvedCall: ResolvedCall<*>? ) : KotlinAbstractUExpression(), UCallExpression, KotlinUElementWithType { companion object { fun resolveSource(descriptor: DeclarationDescriptor, source: PsiElement?): PsiMethod? { @@ -53,6 +53,8 @@ class KotlinUFunctionCallExpression( } } + constructor(psi: KtCallExpression, uastParent: UElement?): this(psi, uastParent, null) + private val resolvedCall by lz { _resolvedCall ?: psi.getResolvedCall(psi.analyze()) } diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinULiteralExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinULiteralExpression.kt index 9bd9823262e..d3ab8189a7a 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinULiteralExpression.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinULiteralExpression.kt @@ -16,10 +16,10 @@ package org.jetbrains.uast.kotlin -import com.intellij.openapi.util.text.StringUtil import com.intellij.psi.PsiElement import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.psi.KtConstantExpression +import org.jetbrains.kotlin.psi.KtEscapeStringTemplateEntry import org.jetbrains.uast.UElement import org.jetbrains.uast.ULiteralExpression @@ -36,10 +36,13 @@ class KotlinULiteralExpression( class KotlinStringULiteralExpression( override val psi: PsiElement, override val uastParent: UElement?, - val text: String? = null + val text: String ) : KotlinAbstractUExpression(), ULiteralExpression, KotlinUElementWithType{ + constructor(psi: PsiElement, uastParent: UElement?) + : this(psi, uastParent, if (psi is KtEscapeStringTemplateEntry) psi.unescapedValue else psi.text) + override val value: String - get() = text ?: StringUtil.unescapeStringCharacters(psi.text) + get() = text override fun evaluate() = value } \ No newline at end of file diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSimpleReferenceExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSimpleReferenceExpression.kt index b401dbe0bb4..d2f3c5fc563 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSimpleReferenceExpression.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSimpleReferenceExpression.kt @@ -35,11 +35,12 @@ import org.jetbrains.uast.visitor.UastVisitor open class KotlinUSimpleReferenceExpression( override val psi: KtSimpleNameExpression, - override val identifier: String, override val uastParent: UElement? ) : KotlinAbstractUExpression(), USimpleNameReferenceExpression, KotlinUElementWithType, KotlinEvaluatableUElement { private val resolvedDeclaration by lz { psi.resolveCallToDeclaration(this) } + override val identifier get() = psi.getReferencedName() + override fun resolve() = resolvedDeclaration override val resolvedName: String? diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSwitchExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSwitchExpression.kt index 484f26d60ae..a024605f8e3 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSwitchExpression.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSwitchExpression.kt @@ -28,7 +28,7 @@ class KotlinUSwitchExpression( override val expression by lz { KotlinConverter.convertOrNull(psi.subjectExpression, this) } override val body: UExpressionList by lz { - object : KotlinUExpressionList(psi, KotlinSpecialExpressionKinds.WHEN, this) { + object : KotlinUExpressionList(psi, KotlinSpecialExpressionKinds.WHEN, this@KotlinUSwitchExpression) { override fun asRenderString() = expressions.joinToString("\n") { it.asRenderString().withMargin } }.apply { expressions = this@KotlinUSwitchExpression.psi.entries.map { KotlinUSwitchEntry(it, this) } @@ -77,7 +77,7 @@ class KotlinUSwitchEntry( } override val body: UExpressionList by lz { - object : KotlinUExpressionList(psi, KotlinSpecialExpressionKinds.WHEN_ENTRY, this) { + object : KotlinUExpressionList(psi, KotlinSpecialExpressionKinds.WHEN_ENTRY, this@KotlinUSwitchEntry) { override fun asRenderString() = buildString { appendln("{") expressions.forEach { appendln(it.asRenderString().withMargin) } diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUTryExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUTryExpression.kt index 0cfe44ec173..b9d3ef20544 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUTryExpression.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUTryExpression.kt @@ -28,7 +28,7 @@ class KotlinUTryExpression( ) : KotlinAbstractUExpression(), UTryExpression, KotlinUElementWithType { override val tryClause by lz { KotlinConverter.convertOrEmpty(psi.tryBlock, this) } override val catchClauses by lz { psi.catchClauses.map { KotlinUCatchClause(it, this) } } - override val finallyClause by lz { psi.finallyBlock?.finalExpression?.let { KotlinConverter.convertExpression(it, this) } } + override val finallyClause by lz { psi.finallyBlock?.finalExpression?.let { KotlinConverter.convertExpression(it, { this }) } } override val resourceVariables: List get() = emptyList()