Qualified expressions and safe calls
This commit is contained in:
committed by
Dmitry Petrov
parent
b80782c295
commit
3e11f35918
@@ -39,19 +39,21 @@ class IrExpressionGenerator(
|
||||
fun generateExpression(ktExpression: KtExpression) = ktExpression.generate()
|
||||
|
||||
private fun KtElement.generate(): IrExpression =
|
||||
accept(this@IrExpressionGenerator, null).applySmartCast(this)
|
||||
deparenthesize()
|
||||
.accept(this@IrExpressionGenerator, null)
|
||||
.smartCastIfNeeded(this)
|
||||
|
||||
private fun KtExpression.type() =
|
||||
getType(this) ?: TODO("no type for expression")
|
||||
|
||||
private fun IrExpression.applySmartCast(ktElement: KtElement): IrExpression {
|
||||
private fun IrExpression.smartCastIfNeeded(ktElement: KtElement): IrExpression {
|
||||
if (ktElement is KtExpression) {
|
||||
val smartCastType = get(BindingContext.SMARTCAST, ktElement)
|
||||
if (smartCastType != null) {
|
||||
return IrTypeOperatorExpressionImpl(
|
||||
ktElement.startOffset, ktElement.endOffset, smartCastType,
|
||||
IrTypeOperator.SMART_AS, smartCastType
|
||||
).apply { childExpression = this@applySmartCast }
|
||||
).apply { childExpression = this@smartCastIfNeeded }
|
||||
}
|
||||
}
|
||||
return this
|
||||
@@ -138,6 +140,24 @@ class IrExpressionGenerator(
|
||||
return generateCall(expression, resolvedCall, null, null)
|
||||
}
|
||||
|
||||
override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression, data: Nothing?): IrExpression =
|
||||
expression.selectorExpression!!.accept(this, data)
|
||||
|
||||
override fun visitSafeQualifiedExpression(expression: KtSafeQualifiedExpression, data: Nothing?): IrExpression =
|
||||
expression.selectorExpression!!.accept(this, data)
|
||||
|
||||
override fun visitThisExpression(expression: KtThisExpression, data: Nothing?): IrExpression {
|
||||
val referenceTarget = getOrFail(BindingContext.REFERENCE_TARGET, expression.instanceReference) { "No reference target for this" }
|
||||
return when (referenceTarget) {
|
||||
is ClassDescriptor ->
|
||||
IrThisExpressionImpl(expression.startOffset, expression.endOffset, expression.type(), referenceTarget)
|
||||
is CallableDescriptor ->
|
||||
IrExtensionReceiverReferenceImpl(expression.startOffset, expression.endOffset, expression.type(), referenceTarget)
|
||||
else ->
|
||||
error("Expected this or receiver: $referenceTarget")
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateCall(
|
||||
ktExpression: KtExpression,
|
||||
resolvedCall: ResolvedCall<out CallableDescriptor>,
|
||||
@@ -179,8 +199,7 @@ class IrExpressionGenerator(
|
||||
null ->
|
||||
null
|
||||
else ->
|
||||
IrDummyExpression(ktExpression.startOffset, ktExpression.endOffset, receiver.type,
|
||||
"Receiver: ${receiver.javaClass.simpleName}")
|
||||
TODO("Receiver: ${receiver.javaClass.simpleName}")
|
||||
}
|
||||
|
||||
private fun generateValueArgument(valueParameter: ValueParameterDescriptor, valueArgument: ResolvedValueArgument): IrExpression? {
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtPsiUtil
|
||||
|
||||
fun KtElement.deparenthesize(): KtElement =
|
||||
if (this is KtExpression) KtPsiUtil.safeDeparenthesize(this) else this
|
||||
|
||||
@@ -76,7 +76,7 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
|
||||
"THIS ${expression.classDescriptor.render()}"
|
||||
|
||||
override fun visitCallExpression(expression: IrCallExpression, data: Nothing?): String =
|
||||
"CALL ${expression.callee.name} ${expression.operator ?: ""}"
|
||||
"CALL ${if (expression.isSafe) "?." else "."}${expression.callee.name} ${expression.operator ?: ""}"
|
||||
|
||||
override fun visitDummyExpression(expression: IrDummyExpression, data: Nothing?): String =
|
||||
"DUMMY ${expression.description}"
|
||||
|
||||
Reference in New Issue
Block a user