Uast: parsing primary constructors superCalls (KT-21409)

This commit is contained in:
Nicolay Mitropolsky
2017-11-24 13:02:01 +03:00
committed by xiexed
parent a39f2f8271
commit 3bfa5c4706
8 changed files with 149 additions and 13 deletions
@@ -23,6 +23,9 @@ import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.asJava.toLightMethods
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.utils.SmartList
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import org.jetbrains.uast.*
import org.jetbrains.uast.java.AbstractJavaUClass
import org.jetbrains.uast.kotlin.declarations.KotlinUMethod
@@ -108,9 +111,22 @@ class KotlinPrimaryConstructorUMethod(
override val uastParent: UElement?
): KotlinUMethod(psi, uastParent) {
override val uastBody: UExpression? by lz {
ktClass?.getAnonymousInitializers()
?.takeIf { it.isNotEmpty() }
?.let { KotlinUBlockExpression.create(it, this) }
val superTypeCallEntry = ktClass?.superTypeListEntries?.firstIsInstanceOrNull<KtSuperTypeCallEntry>()
val initializers = ktClass?.getAnonymousInitializers()?.takeIf { it.isNotEmpty() }
if (superTypeCallEntry != null || initializers != null)
KotlinUBlockExpression.KotlinLazyUBlockExpression(this) { uastParent ->
SmartList<UExpression>().apply {
superTypeCallEntry?.let {
add(KotlinUFunctionCallExpression(it, uastParent))
}
val languagePlugin = uastParent.getLanguagePlugin()
initializers?.forEach {
addIfNotNull(languagePlugin.convertOpt(it.body, uastParent))
}
}
}
else
null
}
}
@@ -27,9 +27,9 @@ class KotlinUBlockExpression(
) : KotlinAbstractUExpression(givenParent), UBlockExpression, KotlinUElementWithType {
override val expressions by lz { psi.statements.map { KotlinConverter.convertOrEmpty(it, this) } }
private class KotlinLazyUBlockExpression(
class KotlinLazyUBlockExpression(
override val uastParent: UElement?,
expressionProducer: (expressionParent: UElement?) -> List<UExpression>
expressionProducer: (expressionParent: UElement) -> List<UExpression>
) : UBlockExpression {
override val psi: PsiElement? = null
override val annotations: List<UAnnotation> = emptyList()
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.psi.KtAnnotationEntry
import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.psi.KtCallElement
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.psiUtil.parents
@@ -36,7 +36,7 @@ import org.jetbrains.uast.internal.acceptList
import org.jetbrains.uast.visitor.UastVisitor
class KotlinUFunctionCallExpression(
override val psi: KtCallExpression,
override val psi: KtCallElement,
givenParent: UElement?,
private val _resolvedCall: ResolvedCall<*>?
) : KotlinAbstractUExpression(givenParent), UCallExpression, KotlinUElementWithType {
@@ -56,7 +56,7 @@ class KotlinUFunctionCallExpression(
}
}
constructor(psi: KtCallExpression, uastParent: UElement?): this(psi, uastParent, null)
constructor(psi: KtCallElement, uastParent: UElement?) : this(psi, uastParent, null)
private val resolvedCall by lz {
_resolvedCall ?: psi.getResolvedCall(psi.analyze())
@@ -189,7 +189,7 @@ open class KotlinUSimpleReferenceExpression(
}
class KotlinClassViaConstructorUSimpleReferenceExpression(
override val psi: KtCallExpression,
override val psi: KtCallElement,
override val identifier: String,
givenParent: UElement?
) : KotlinAbstractUExpression(givenParent), USimpleNameReferenceExpression, KotlinUElementWithType {
+25
View File
@@ -0,0 +1,25 @@
open class A(val str: String) {
constructor(i: Int) : this(i.toString())
open fun foo(a: Long) {}
}
class B(param: String) : A(param)
class C : A {
constructor(p: String) : super(p)
constructor(i: Int) : super(i)
override fun foo(a: Long) {
super.foo(a)
}
}
object O : A("text")
val anon = object : A("textForAnon") {
fun bar() {}
}
+60
View File
@@ -0,0 +1,60 @@
UFile (package = )
UClass (name = SuperCallsKt)
UField (name = anon)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
UObjectLiteralExpression
ULiteralExpression (value = "textForAnon")
UClass (name = null)
UAnnotationMethod (name = bar)
UBlockExpression
UAnnotationMethod (name = SuperCallsKt$anon$1)
UAnnotationMethod (name = getAnon)
UClass (name = A)
UField (name = str)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
UAnnotationMethod (name = foo)
UParameter (name = a)
UAnnotation (fqName = null)
UBlockExpression
UAnnotationMethod (name = getStr)
UAnnotationMethod (name = A)
UParameter (name = str)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
UAnnotationMethod (name = A)
UParameter (name = i)
UAnnotation (fqName = null)
UClass (name = B)
UAnnotationMethod (name = B)
UParameter (name = param)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
UBlockExpression
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1))
UIdentifier (Identifier (A))
USimpleNameReferenceExpression (identifier = <init>)
USimpleNameReferenceExpression (identifier = param)
UClass (name = C)
UAnnotationMethod (name = foo)
UParameter (name = a)
UAnnotation (fqName = null)
UBlockExpression
UQualifiedReferenceExpression
USuperExpression (label = null)
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1))
UIdentifier (Identifier (foo))
USimpleNameReferenceExpression (identifier = foo)
USimpleNameReferenceExpression (identifier = a)
UAnnotationMethod (name = C)
UParameter (name = p)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
UAnnotationMethod (name = C)
UParameter (name = i)
UAnnotation (fqName = null)
UClass (name = O)
UField (name = INSTANCE)
UAnnotation (fqName = null)
UAnnotationMethod (name = O)
UBlockExpression
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1))
UIdentifier (Identifier (A))
USimpleNameReferenceExpression (identifier = <init>)
ULiteralExpression (value = "text")
+36
View File
@@ -0,0 +1,36 @@
public final class SuperCallsKt {
private static final var anon: A = anonymous object : A ("textForAnon"){
fun bar(){}
}
public static final fun getAnon() : A = UastEmptyExpression
}
public class A {
private final var str: java.lang.String
public fun foo(a: long) : void {
}
public final fun getStr() : java.lang.String = UastEmptyExpression
public fun A(str: java.lang.String) = UastEmptyExpression
public fun A(i: int) = UastEmptyExpression
}
public final class B : A {
public fun B(param: java.lang.String) {
<init>(param)
}
}
public final class C : A {
public fun foo(a: long) : void {
super.foo(a)
}
public fun C(p: java.lang.String) = UastEmptyExpression
public fun C(i: int) = UastEmptyExpression
}
public final class O : A {
public static final var INSTANCE: O
private fun O() {
<init>("text")
}
}
@@ -1,9 +1,5 @@
package org.jetbrains.uast.test.kotlin
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiElementVisitor
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtVisitor
import org.junit.Test
class SimpleKotlinRenderLogTest : AbstractKotlinRenderLogTest() {
@@ -57,4 +53,7 @@ class SimpleKotlinRenderLogTest : AbstractKotlinRenderLogTest() {
@Test
fun testWhenAndDestructing() = doTest("WhenAndDestructing") { testName, file -> check(testName, file, false) }
@Test
fun testSuperCalls() = doTest("SuperCalls") { testName, file -> check(testName, file, false) }
}