JVM_IR KT-45103 optimize direct invoke for lambdas and callable refs
This commit is contained in:
committed by
teamcityserver
parent
bfb1a06f3d
commit
851980e36f
@@ -8,9 +8,7 @@ package org.jetbrains.kotlin.asJava
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.psi.PsiClass
|
||||
import junit.framework.TestCase
|
||||
import org.jetbrains.kotlin.asJava.PsiClassRenderer.renderClass
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import java.io.File
|
||||
import java.util.regex.Pattern
|
||||
|
||||
@@ -22,6 +20,7 @@ object LightClassTestCommon {
|
||||
testDataFile: File,
|
||||
findLightClass: (String) -> PsiClass?,
|
||||
normalizeText: (String) -> String,
|
||||
membersFilter: PsiClassRenderer.MembersFilter = PsiClassRenderer.MembersFilter.DEFAULT
|
||||
): String {
|
||||
val text = FileUtil.loadFile(testDataFile, true)
|
||||
val matcher = SUBJECT_FQ_NAME_PATTERN.matcher(text)
|
||||
@@ -30,15 +29,20 @@ object LightClassTestCommon {
|
||||
|
||||
val lightClass = findLightClass(fqName)
|
||||
|
||||
return actualText(fqName, lightClass, normalizeText)
|
||||
return actualText(fqName, lightClass, normalizeText, membersFilter)
|
||||
}
|
||||
|
||||
private fun actualText(fqName: String?, lightClass: PsiClass?, normalizeText: (String) -> String): String {
|
||||
private fun actualText(
|
||||
fqName: String?,
|
||||
lightClass: PsiClass?,
|
||||
normalizeText: (String) -> String,
|
||||
membersFilter: PsiClassRenderer.MembersFilter
|
||||
): String {
|
||||
if (lightClass == null) {
|
||||
return NOT_GENERATED_DIRECTIVE
|
||||
}
|
||||
TestCase.assertTrue("Not a light class: $lightClass ($fqName)", lightClass is KtLightClass)
|
||||
return normalizeText(lightClass.renderClass(renderInner = true))
|
||||
return normalizeText(PsiClassRenderer.renderClass(lightClass, renderInner = true, membersFilter = membersFilter))
|
||||
}
|
||||
|
||||
// Actual text for light class is generated with ClsElementImpl.appendMirrorText() that can find empty DefaultImpl inner class in stubs
|
||||
|
||||
@@ -14,11 +14,67 @@ import org.jetbrains.kotlin.load.kotlin.NON_EXISTENT_CLASS_NAME
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
fun PsiClass.renderClass() = PsiClassRenderer.renderClass(this)
|
||||
|
||||
|
||||
object PsiClassRenderer {
|
||||
class PsiClassRenderer private constructor(
|
||||
private val renderInner: Boolean,
|
||||
private val membersFilter: MembersFilter
|
||||
) {
|
||||
|
||||
var extendedTypeRenderer = false
|
||||
interface MembersFilter {
|
||||
fun includeEnumConstant(psiEnumConstant: PsiEnumConstant): Boolean = true
|
||||
fun includeField(psiField: PsiField): Boolean = true
|
||||
fun includeMethod(psiMethod: PsiMethod): Boolean = true
|
||||
fun includeClass(psiClass: PsiClass): Boolean = true
|
||||
|
||||
companion object {
|
||||
val DEFAULT = object : MembersFilter {}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
var extendedTypeRenderer = false
|
||||
|
||||
fun renderClass(
|
||||
psiClass: PsiClass,
|
||||
renderInner: Boolean = false,
|
||||
membersFilter: MembersFilter = MembersFilter.DEFAULT
|
||||
): String =
|
||||
PsiClassRenderer(renderInner, membersFilter).renderClass(psiClass)
|
||||
}
|
||||
|
||||
private fun renderClass(psiClass: PsiClass): String =
|
||||
buildString {
|
||||
val classWord = when {
|
||||
psiClass.isAnnotationType -> "@interface"
|
||||
psiClass.isInterface -> "interface"
|
||||
psiClass.isEnum -> "enum"
|
||||
else -> "class"
|
||||
}
|
||||
|
||||
append(psiClass.renderModifiers())
|
||||
append("$classWord ")
|
||||
append("${psiClass.name} /* ${psiClass.qualifiedName}*/")
|
||||
append(psiClass.typeParameters.renderTypeParams())
|
||||
append(psiClass.extendsList.renderRefList("extends"))
|
||||
append(psiClass.implementsList.renderRefList("implements"))
|
||||
appendLine(" {")
|
||||
|
||||
if (psiClass.isEnum) {
|
||||
append(
|
||||
psiClass.fields
|
||||
.filterIsInstance<PsiEnumConstant>()
|
||||
.filter { membersFilter.includeEnumConstant(it) }
|
||||
.joinToString(",\n") { it.renderEnumConstant() }.prependDefaultIndent()
|
||||
)
|
||||
append(";\n\n")
|
||||
}
|
||||
|
||||
append(psiClass.renderMembers())
|
||||
|
||||
append("}")
|
||||
}
|
||||
|
||||
private fun PsiType.renderType() = StringBuffer().also { renderType(it) }.toString()
|
||||
private fun PsiType.renderType(sb: StringBuffer) {
|
||||
@@ -126,69 +182,41 @@ object PsiClassRenderer {
|
||||
return "$typeParams $name$paramTypes"
|
||||
}
|
||||
|
||||
private fun PsiEnumConstant.renderEnumConstant(renderInner: Boolean): String {
|
||||
private fun PsiEnumConstant.renderEnumConstant(): String {
|
||||
val initializingClass = initializingClass ?: return name
|
||||
|
||||
return buildString {
|
||||
appendLine("$name {")
|
||||
append(initializingClass.renderMembers(renderInner))
|
||||
append(initializingClass.renderMembers())
|
||||
append("}")
|
||||
}
|
||||
}
|
||||
|
||||
fun PsiClass.renderClass(renderInner: Boolean = false): String {
|
||||
val classWord = when {
|
||||
isAnnotationType -> "@interface"
|
||||
isInterface -> "interface"
|
||||
isEnum -> "enum"
|
||||
else -> "class"
|
||||
}
|
||||
|
||||
return buildString {
|
||||
append(renderModifiers())
|
||||
append("$classWord ")
|
||||
append("$name /* $qualifiedName*/")
|
||||
append(typeParameters.renderTypeParams())
|
||||
append(extendsList.renderRefList("extends"))
|
||||
append(implementsList.renderRefList("implements"))
|
||||
appendLine(" {")
|
||||
|
||||
if (isEnum) {
|
||||
append(
|
||||
fields
|
||||
.filterIsInstance<PsiEnumConstant>()
|
||||
.joinToString(",\n") { it.renderEnumConstant(renderInner) }.prependDefaultIndent()
|
||||
)
|
||||
append(";\n\n")
|
||||
}
|
||||
|
||||
append(renderMembers(renderInner))
|
||||
|
||||
append("}")
|
||||
}
|
||||
}
|
||||
|
||||
private fun PsiClass.renderMembers(renderInner: Boolean): String {
|
||||
private fun PsiClass.renderMembers(): String {
|
||||
return buildString {
|
||||
appendSorted(
|
||||
fields
|
||||
.filterNot { it is PsiEnumConstant }
|
||||
.filter { membersFilter.includeField(it) }
|
||||
.map { it.renderVar().prependDefaultIndent() + ";\n\n" }
|
||||
)
|
||||
|
||||
appendSorted(
|
||||
methods
|
||||
.filter { membersFilter.includeMethod(it) }
|
||||
.map { it.renderMethod().prependDefaultIndent() + "\n\n" }
|
||||
)
|
||||
|
||||
appendSorted(
|
||||
innerClasses.map {
|
||||
appendLine()
|
||||
if (renderInner)
|
||||
it.renderClass(renderInner)
|
||||
else
|
||||
"class ${it.name} ...\n\n".prependDefaultIndent()
|
||||
}
|
||||
innerClasses
|
||||
.filter { membersFilter.includeClass(it) }
|
||||
.map {
|
||||
appendLine()
|
||||
if (renderInner)
|
||||
renderClass(it, renderInner)
|
||||
else
|
||||
"class ${it.name} ...\n\n".prependDefaultIndent()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user