Uast: returning back secondary constructors bodies (KT-21575)
but secondary constructors without primary constructor will not contain initializers, it is still an issue
This commit is contained in:
committed by
xiexed
parent
962c512882
commit
b8069b48c5
@@ -128,27 +128,37 @@ class KotlinConstructorUMethod(
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
val initializers = ktClass?.getAnonymousInitializers().orEmpty()
|
||||
if (delegationCall == null && initializers.isEmpty()) return@lz null
|
||||
val bodyExpressions = getBodyExpressions()
|
||||
if (delegationCall == null && bodyExpressions.isEmpty()) return@lz null
|
||||
KotlinUBlockExpression.KotlinLazyUBlockExpression(this) { uastParent ->
|
||||
SmartList<UExpression>().apply {
|
||||
delegationCall?.let {
|
||||
add(KotlinUFunctionCallExpression(it, uastParent))
|
||||
}
|
||||
val languagePlugin = uastParent.getLanguagePlugin()
|
||||
initializers.forEach {
|
||||
addIfNotNull(languagePlugin.convertOpt(it.body, uastParent))
|
||||
bodyExpressions.forEach {
|
||||
addIfNotNull(languagePlugin.convertOpt(it, uastParent))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getBodyExpressions(): List<KtExpression> {
|
||||
if (isPrimary) return getInitializers()
|
||||
val bodyExpression = (psi.kotlinOrigin as? KtFunction)?.bodyExpression ?: return emptyList()
|
||||
if (bodyExpression is KtBlockExpression) return bodyExpression.statements
|
||||
return listOf(bodyExpression)
|
||||
}
|
||||
|
||||
private fun getInitializers() = ktClass?.getAnonymousInitializers()?.mapNotNull { it.body } ?: emptyList()
|
||||
|
||||
}
|
||||
|
||||
class KotlinUAnonymousClass(
|
||||
psi: PsiAnonymousClass,
|
||||
givenParent: UElement?
|
||||
) : AbstractKotlinUClass(givenParent), UAnonymousClass, PsiAnonymousClass by psi {
|
||||
|
||||
|
||||
override val psi: PsiAnonymousClass = unwrap<UAnonymousClass, PsiAnonymousClass>(psi)
|
||||
|
||||
override fun getOriginalElement(): PsiElement? = super<AbstractKotlinUClass>.getOriginalElement()
|
||||
@@ -163,7 +173,7 @@ class KotlinUAnonymousClass(
|
||||
|
||||
override val uastAnchor: UElement?
|
||||
get() {
|
||||
val ktClassOrObject = (psi.originalElement as? KtLightClass)?.kotlinOrigin as? KtObjectDeclaration ?: return null
|
||||
val ktClassOrObject = (psi.originalElement as? KtLightClass)?.kotlinOrigin as? KtObjectDeclaration ?: return null
|
||||
return UIdentifier(ktClassOrObject.getObjectKeyword(), this)
|
||||
}
|
||||
|
||||
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
class A(val str: String) {
|
||||
|
||||
constructor(i: Int) : this(i.toString())
|
||||
|
||||
}
|
||||
|
||||
class AWithInit(val str: String) {
|
||||
|
||||
init {
|
||||
println()
|
||||
}
|
||||
|
||||
constructor(i: Int) : this(i.toString())
|
||||
|
||||
}
|
||||
|
||||
class AWith2Init(val str: String) {
|
||||
|
||||
init {
|
||||
println(1)
|
||||
}
|
||||
|
||||
init {
|
||||
println(2)
|
||||
}
|
||||
|
||||
constructor(i: Int) : this(i.toString())
|
||||
|
||||
}
|
||||
|
||||
class AOnlyInit {
|
||||
|
||||
init {
|
||||
println(1)
|
||||
}
|
||||
|
||||
init {
|
||||
println(2)
|
||||
}
|
||||
}
|
||||
|
||||
class AWithSecondary {
|
||||
|
||||
lateinit var a: String
|
||||
|
||||
constructor(i: Int) {
|
||||
a = i.toString()
|
||||
}
|
||||
|
||||
constructor(s: String) {
|
||||
a = s
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class AWithSecondaryInit {
|
||||
|
||||
lateinit var a: String
|
||||
|
||||
init {
|
||||
// This body will not be picked by UAST because no lightMethod contains it.
|
||||
// Of course it is not a desired behaviour, so fix it if you know how
|
||||
println()
|
||||
}
|
||||
|
||||
constructor(i: Int) {
|
||||
a = i.toString()
|
||||
}
|
||||
|
||||
constructor(s: String) {
|
||||
a = s
|
||||
}
|
||||
|
||||
}
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
UFile (package = )
|
||||
UClass (name = A)
|
||||
UField (name = str)
|
||||
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
|
||||
UAnnotationMethod (name = getStr)
|
||||
UAnnotationMethod (name = A)
|
||||
UParameter (name = str)
|
||||
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
|
||||
UAnnotationMethod (name = A)
|
||||
UParameter (name = i)
|
||||
UAnnotation (fqName = null)
|
||||
UBlockExpression
|
||||
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1))
|
||||
UIdentifier (Identifier (this))
|
||||
USimpleNameReferenceExpression (identifier = <init>)
|
||||
UQualifiedReferenceExpression
|
||||
USimpleNameReferenceExpression (identifier = i)
|
||||
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))
|
||||
UIdentifier (Identifier (toString))
|
||||
USimpleNameReferenceExpression (identifier = toString)
|
||||
UClass (name = AWithInit)
|
||||
UField (name = str)
|
||||
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
|
||||
UAnnotationMethod (name = getStr)
|
||||
UAnnotationMethod (name = AWithInit)
|
||||
UParameter (name = str)
|
||||
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
|
||||
UBlockExpression
|
||||
UBlockExpression
|
||||
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))
|
||||
UIdentifier (Identifier (println))
|
||||
USimpleNameReferenceExpression (identifier = println)
|
||||
UAnnotationMethod (name = AWithInit)
|
||||
UParameter (name = i)
|
||||
UAnnotation (fqName = null)
|
||||
UBlockExpression
|
||||
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1))
|
||||
UIdentifier (Identifier (this))
|
||||
USimpleNameReferenceExpression (identifier = <init>)
|
||||
UQualifiedReferenceExpression
|
||||
USimpleNameReferenceExpression (identifier = i)
|
||||
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))
|
||||
UIdentifier (Identifier (toString))
|
||||
USimpleNameReferenceExpression (identifier = toString)
|
||||
UClass (name = AWith2Init)
|
||||
UField (name = str)
|
||||
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
|
||||
UAnnotationMethod (name = getStr)
|
||||
UAnnotationMethod (name = AWith2Init)
|
||||
UParameter (name = str)
|
||||
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
|
||||
UBlockExpression
|
||||
UBlockExpression
|
||||
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1))
|
||||
UIdentifier (Identifier (println))
|
||||
USimpleNameReferenceExpression (identifier = println)
|
||||
ULiteralExpression (value = 1)
|
||||
UBlockExpression
|
||||
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1))
|
||||
UIdentifier (Identifier (println))
|
||||
USimpleNameReferenceExpression (identifier = println)
|
||||
ULiteralExpression (value = 2)
|
||||
UAnnotationMethod (name = AWith2Init)
|
||||
UParameter (name = i)
|
||||
UAnnotation (fqName = null)
|
||||
UBlockExpression
|
||||
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1))
|
||||
UIdentifier (Identifier (this))
|
||||
USimpleNameReferenceExpression (identifier = <init>)
|
||||
UQualifiedReferenceExpression
|
||||
USimpleNameReferenceExpression (identifier = i)
|
||||
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))
|
||||
UIdentifier (Identifier (toString))
|
||||
USimpleNameReferenceExpression (identifier = toString)
|
||||
UClass (name = AOnlyInit)
|
||||
UAnnotationMethod (name = AOnlyInit)
|
||||
UBlockExpression
|
||||
UBlockExpression
|
||||
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1))
|
||||
UIdentifier (Identifier (println))
|
||||
USimpleNameReferenceExpression (identifier = println)
|
||||
ULiteralExpression (value = 1)
|
||||
UBlockExpression
|
||||
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1))
|
||||
UIdentifier (Identifier (println))
|
||||
USimpleNameReferenceExpression (identifier = println)
|
||||
ULiteralExpression (value = 2)
|
||||
UClass (name = AWithSecondary)
|
||||
UField (name = a)
|
||||
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
|
||||
UAnnotationMethod (name = getA)
|
||||
UAnnotationMethod (name = setA)
|
||||
UParameter (name = p)
|
||||
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
|
||||
UAnnotationMethod (name = AWithSecondary)
|
||||
UParameter (name = i)
|
||||
UAnnotation (fqName = null)
|
||||
UBlockExpression
|
||||
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0))
|
||||
UIdentifier (Identifier ())
|
||||
USimpleNameReferenceExpression (identifier = <init>)
|
||||
UBinaryExpression (operator = =)
|
||||
USimpleNameReferenceExpression (identifier = a)
|
||||
UQualifiedReferenceExpression
|
||||
USimpleNameReferenceExpression (identifier = i)
|
||||
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))
|
||||
UIdentifier (Identifier (toString))
|
||||
USimpleNameReferenceExpression (identifier = toString)
|
||||
UAnnotationMethod (name = AWithSecondary)
|
||||
UParameter (name = s)
|
||||
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
|
||||
UBlockExpression
|
||||
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0))
|
||||
UIdentifier (Identifier ())
|
||||
USimpleNameReferenceExpression (identifier = <init>)
|
||||
UBinaryExpression (operator = =)
|
||||
USimpleNameReferenceExpression (identifier = a)
|
||||
USimpleNameReferenceExpression (identifier = s)
|
||||
UClass (name = AWithSecondaryInit)
|
||||
UField (name = a)
|
||||
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
|
||||
UAnnotationMethod (name = getA)
|
||||
UAnnotationMethod (name = setA)
|
||||
UParameter (name = p)
|
||||
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
|
||||
UAnnotationMethod (name = AWithSecondaryInit)
|
||||
UParameter (name = i)
|
||||
UAnnotation (fqName = null)
|
||||
UBlockExpression
|
||||
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0))
|
||||
UIdentifier (Identifier ())
|
||||
USimpleNameReferenceExpression (identifier = <init>)
|
||||
UBinaryExpression (operator = =)
|
||||
USimpleNameReferenceExpression (identifier = a)
|
||||
UQualifiedReferenceExpression
|
||||
USimpleNameReferenceExpression (identifier = i)
|
||||
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))
|
||||
UIdentifier (Identifier (toString))
|
||||
USimpleNameReferenceExpression (identifier = toString)
|
||||
UAnnotationMethod (name = AWithSecondaryInit)
|
||||
UParameter (name = s)
|
||||
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
|
||||
UBlockExpression
|
||||
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0))
|
||||
UIdentifier (Identifier ())
|
||||
USimpleNameReferenceExpression (identifier = <init>)
|
||||
UBinaryExpression (operator = =)
|
||||
USimpleNameReferenceExpression (identifier = a)
|
||||
USimpleNameReferenceExpression (identifier = s)
|
||||
@@ -0,0 +1,76 @@
|
||||
public final class A {
|
||||
private final var str: java.lang.String
|
||||
public final fun getStr() : java.lang.String = UastEmptyExpression
|
||||
public fun A(str: java.lang.String) = UastEmptyExpression
|
||||
public fun A(i: int) {
|
||||
<init>(i.toString())
|
||||
}
|
||||
}
|
||||
|
||||
public final class AWithInit {
|
||||
private final var str: java.lang.String
|
||||
public final fun getStr() : java.lang.String = UastEmptyExpression
|
||||
public fun AWithInit(str: java.lang.String) {
|
||||
{
|
||||
println()
|
||||
}
|
||||
}
|
||||
public fun AWithInit(i: int) {
|
||||
<init>(i.toString())
|
||||
}
|
||||
}
|
||||
|
||||
public final class AWith2Init {
|
||||
private final var str: java.lang.String
|
||||
public final fun getStr() : java.lang.String = UastEmptyExpression
|
||||
public fun AWith2Init(str: java.lang.String) {
|
||||
{
|
||||
println(1)
|
||||
}
|
||||
{
|
||||
println(2)
|
||||
}
|
||||
}
|
||||
public fun AWith2Init(i: int) {
|
||||
<init>(i.toString())
|
||||
}
|
||||
}
|
||||
|
||||
public final class AOnlyInit {
|
||||
public fun AOnlyInit() {
|
||||
{
|
||||
println(1)
|
||||
}
|
||||
{
|
||||
println(2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final class AWithSecondary {
|
||||
public var a: java.lang.String
|
||||
public final fun getA() : java.lang.String = UastEmptyExpression
|
||||
public final fun setA(p: java.lang.String) : void = UastEmptyExpression
|
||||
public fun AWithSecondary(i: int) {
|
||||
<init>()
|
||||
a = i.toString()
|
||||
}
|
||||
public fun AWithSecondary(s: java.lang.String) {
|
||||
<init>()
|
||||
a = s
|
||||
}
|
||||
}
|
||||
|
||||
public final class AWithSecondaryInit {
|
||||
public var a: java.lang.String
|
||||
public final fun getA() : java.lang.String = UastEmptyExpression
|
||||
public final fun setA(p: java.lang.String) : void = UastEmptyExpression
|
||||
public fun AWithSecondaryInit(i: int) {
|
||||
<init>()
|
||||
a = i.toString()
|
||||
}
|
||||
public fun AWithSecondaryInit(s: java.lang.String) {
|
||||
<init>()
|
||||
a = s
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -11,7 +11,9 @@ class B(param: String) : A(param)
|
||||
class C : A {
|
||||
constructor(p: String) : super(p)
|
||||
|
||||
constructor(i: Int) : super(i)
|
||||
constructor(i: Int) : super(i) {
|
||||
println()
|
||||
}
|
||||
|
||||
override fun foo(a: Long) {
|
||||
super.foo(a)
|
||||
|
||||
@@ -95,6 +95,9 @@ UFile (package = )
|
||||
UIdentifier (Identifier (super))
|
||||
USimpleNameReferenceExpression (identifier = <init>)
|
||||
USimpleNameReferenceExpression (identifier = i)
|
||||
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))
|
||||
UIdentifier (Identifier (println))
|
||||
USimpleNameReferenceExpression (identifier = println)
|
||||
UClass (name = O)
|
||||
UField (name = INSTANCE)
|
||||
UAnnotation (fqName = null)
|
||||
|
||||
@@ -39,6 +39,7 @@ public final class C : A {
|
||||
}
|
||||
public fun C(i: int) {
|
||||
<init>(i)
|
||||
println()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ abstract class AbstractKotlinRenderLogTest : AbstractKotlinUastTest(), RenderLog
|
||||
if (expectedParents != null) {
|
||||
assertNotNull("Expected to be able to convert PSI element $element", uElement)
|
||||
val parents = generateSequence(uElement!!.uastParent) { it.uastParent }.joinToString { it.asLogString() }
|
||||
assertEquals("Inconsistent parents for ${uElement.asLogString()} (converted from $element)", expectedParents, parents)
|
||||
assertEquals("Inconsistent parents for ${uElement.asRenderString()}(${uElement.asLogString()})(${uElement.javaClass}) (converted from $element[${element.text}])", expectedParents, parents)
|
||||
}
|
||||
super.visitElement(element)
|
||||
}
|
||||
|
||||
@@ -56,4 +56,7 @@ class SimpleKotlinRenderLogTest : AbstractKotlinRenderLogTest() {
|
||||
|
||||
@Test
|
||||
fun testSuperCalls() = doTest("SuperCalls")
|
||||
|
||||
@Test
|
||||
fun testConstructors() = doTest("Constructors")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user