FIR: Support safe-calls in renderers

^KT-38444 In Progress
This commit is contained in:
Denis Zharkov
2020-06-01 15:25:12 +03:00
parent 9f793f1486
commit 755b846877
3 changed files with 59 additions and 4 deletions
@@ -1312,8 +1312,11 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
}
}
private fun FlowContent.generate(functionCall: FirFunctionCall) {
generateReceiver(functionCall)
private fun FlowContent.generate(functionCall: FirFunctionCall, skipReceiver: Boolean = false) {
if (!skipReceiver) {
generateReceiver(functionCall)
}
generate(functionCall.calleeReference)
generateTypeProjections(functionCall.typeArguments)
@@ -1567,6 +1570,10 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
is FirVarargArgumentsExpression -> generate(expression)
is FirResolvedReifiedParameterReference -> generate(expression)
is FirComparisonExpression -> generate(expression)
is FirSafeCallExpression -> generate(expression)
is FirCheckedSafeCallSubject -> {
+"\$subj\$"
}
else -> inlineUnsupported(expression)
}
}
@@ -1578,6 +1585,30 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
generate(comparisonExpression.right)
}
private fun FlowContent.generate(safeCallExpression: FirSafeCallExpression) {
generate(safeCallExpression.receiver)
+"?."
val nestedQualifier = safeCallExpression.regularQualifiedAccess
if (nestedQualifier.explicitReceiver == safeCallExpression.checkedSubject.value) {
when (nestedQualifier) {
is FirFunctionCall -> {
return generate(nestedQualifier, skipReceiver = true)
}
is FirQualifiedAccessExpression -> {
return generate(nestedQualifier, skipReceiver = true)
}
}
}
+"{ "
generate(nestedQualifier)
+" }"
}
private fun FlowContent.generate(resolvedReifiedParameterReference: FirResolvedReifiedParameterReference) {
val typeParameter = resolvedReifiedParameterReference.symbol.fir
+typeParameter.name.identifier
@@ -1593,8 +1624,10 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
generate(binaryLogicExpression.rightOperand)
}
private fun FlowContent.generate(qualifiedAccessExpression: FirQualifiedAccessExpression) {
generateReceiver(qualifiedAccessExpression)
private fun FlowContent.generate(qualifiedAccessExpression: FirQualifiedAccessExpression, skipReceiver: Boolean = false) {
if (!skipReceiver) {
generateReceiver(qualifiedAccessExpression)
}
generate(qualifiedAccessExpression.calleeReference)
}
@@ -510,6 +510,17 @@ class FirRenderer(builder: StringBuilder, private val mode: RenderMode = RenderM
}
}
override fun visitSafeCallExpression(safeCallExpression: FirSafeCallExpression) {
safeCallExpression.receiver.accept(this)
print("?.{ ")
safeCallExpression.regularQualifiedAccess.accept(this)
print(" }")
}
override fun visitCheckedSafeCallSubject(checkedSafeCallSubject: FirCheckedSafeCallSubject) {
print("\$subj\$")
}
override fun visitTypedDeclaration(typedDeclaration: FirTypedDeclaration) {
visitDeclaration(typedDeclaration)
}
@@ -406,6 +406,17 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() {
//skip rendering for as/as?/is/!is
}
override fun visitSafeCallExpression(safeCallExpression: FirSafeCallExpression, data: StringBuilder) {
safeCallExpression.receiver.accept(this, data)
data.append("?.{ ")
safeCallExpression.regularQualifiedAccess.accept(this, data)
data.append(" }")
}
override fun visitCheckedSafeCallSubject(checkedSafeCallSubject: FirCheckedSafeCallSubject, data: StringBuilder) {
data.append("\$subj\$")
}
override fun visitFunctionCall(functionCall: FirFunctionCall, data: StringBuilder) {
when (val callee = functionCall.calleeReference) {
is FirResolvedNamedReference -> {