Refactor desugaring (& operator conventions generation), step 1.
This commit is contained in:
committed by
Dmitry Petrov
parent
c0d521266b
commit
f787f8ecbf
@@ -23,24 +23,5 @@ import org.jetbrains.kotlin.types.KotlinType
|
|||||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||||
import org.jetbrains.kotlin.types.isNullabilityFlexible
|
import org.jetbrains.kotlin.types.isNullabilityFlexible
|
||||||
|
|
||||||
fun IrExpression.toExpectedType(expectedType: KotlinType?): IrExpression {
|
fun IrVariable.defaultLoad(): IrExpression =
|
||||||
if (expectedType == null) return this
|
IrGetVariableImpl(startOffset, endOffset, descriptor)
|
||||||
if (KotlinBuiltIns.isUnit(expectedType)) return this // TODO expose coercion to Unit in IR?
|
|
||||||
|
|
||||||
val valueType = type ?: throw AssertionError("expectedType != null, valueType == null: $this")
|
|
||||||
|
|
||||||
if (valueType.isNullabilityFlexible() && !expectedType.isMarkedNullable) {
|
|
||||||
return IrUnaryOperatorExpressionImpl(startOffset, endOffset, expectedType,
|
|
||||||
IrOperator.IMPLICIT_NOTNULL, null, this)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!KotlinTypeChecker.DEFAULT.isSubtypeOf(valueType, expectedType)) {
|
|
||||||
return IrTypeOperatorExpressionImpl(startOffset, endOffset, expectedType,
|
|
||||||
IrTypeOperator.IMPLICIT_CAST, expectedType, this)
|
|
||||||
}
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun IrVariable.load(): IrExpression =
|
|
||||||
IrGetVariableExpressionImpl(startOffset, endOffset, descriptor)
|
|
||||||
@@ -17,77 +17,18 @@
|
|||||||
package org.jetbrains.kotlin.psi2ir.generators
|
package org.jetbrains.kotlin.psi2ir.generators
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.values.VariableLValue
|
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.values.IrValue
|
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.values.createRematerializableValue
|
|
||||||
import org.jetbrains.kotlin.psi2ir.toExpectedType
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall
|
import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.*
|
import org.jetbrains.kotlin.resolve.scopes.receivers.*
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class CallGenerator(val statementGenerator: StatementGenerator) : IrGenerator {
|
class CallGenerator(statementGenerator: StatementGenerator) : IrChildBodyGeneratorBase<StatementGenerator>(statementGenerator) {
|
||||||
override val context: GeneratorContext get() =
|
|
||||||
statementGenerator.context
|
|
||||||
|
|
||||||
private val temporaryVariableFactory: TemporaryVariableFactory get() =
|
|
||||||
statementGenerator.temporaryVariableFactory
|
|
||||||
|
|
||||||
private val expressionValues = HashMap<KtExpression, IrValue>()
|
|
||||||
private val receiverValues = HashMap<ReceiverValue, IrValue>()
|
|
||||||
private val valueArgumentValues = HashMap<ValueParameterDescriptor, IrValue>()
|
|
||||||
|
|
||||||
fun introduceTemporary(ktExpression: KtExpression, irExpression: IrExpression, nameHint: String? = null): IrVariable? {
|
|
||||||
val rematerializable = createRematerializableValue(irExpression)
|
|
||||||
if (rematerializable != null) {
|
|
||||||
putValue(ktExpression, rematerializable)
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
return createTemporary(ktExpression, irExpression, nameHint)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createTemporary(ktExpression: KtExpression, irExpression: IrExpression, nameHint: String?): IrVariable {
|
|
||||||
val irTmpVar = temporaryVariableFactory.createTemporaryVariable(irExpression, nameHint)
|
|
||||||
putValue(ktExpression, VariableLValue(irTmpVar))
|
|
||||||
return irTmpVar
|
|
||||||
}
|
|
||||||
|
|
||||||
fun introduceTemporary(valueParameterDescriptor: ValueParameterDescriptor, irExpression: IrExpression): IrVariable? {
|
|
||||||
val rematerializable = createRematerializableValue(irExpression)
|
|
||||||
if (rematerializable != null) {
|
|
||||||
putValue(valueParameterDescriptor, rematerializable)
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
val irTmpVar = temporaryVariableFactory.createTemporaryVariable(irExpression, valueParameterDescriptor.name.asString())
|
|
||||||
putValue(valueParameterDescriptor, VariableLValue(irTmpVar))
|
|
||||||
return irTmpVar
|
|
||||||
}
|
|
||||||
|
|
||||||
fun putValue(ktExpression: KtExpression, irValue: IrValue) {
|
|
||||||
expressionValues[ktExpression] = irValue
|
|
||||||
}
|
|
||||||
|
|
||||||
fun putValue(receiver: ReceiverValue, irValue: IrValue) {
|
|
||||||
receiverValues[receiver] = irValue
|
|
||||||
}
|
|
||||||
|
|
||||||
fun putValue(parameter: ValueParameterDescriptor, irValue: IrValue) {
|
|
||||||
valueArgumentValues[parameter] = irValue
|
|
||||||
}
|
|
||||||
|
|
||||||
fun valueOf(ktExpression: KtExpression) = expressionValues[ktExpression]?.load()
|
|
||||||
fun valueOf(receiver: ReceiverValue) = receiverValues[receiver]?.load()
|
|
||||||
fun valueOf(parameter: ValueParameterDescriptor) = valueArgumentValues[parameter]?.load()
|
|
||||||
|
|
||||||
fun generateCall(
|
fun generateCall(
|
||||||
ktElement: KtElement,
|
ktElement: KtElement,
|
||||||
resolvedCall: ResolvedCall<out CallableDescriptor>,
|
resolvedCall: ResolvedCall<out CallableDescriptor>,
|
||||||
@@ -110,13 +51,13 @@ class CallGenerator(val statementGenerator: StatementGenerator) : IrGenerator {
|
|||||||
descriptor: PropertyDescriptor,
|
descriptor: PropertyDescriptor,
|
||||||
ktElement: KtElement,
|
ktElement: KtElement,
|
||||||
resolvedCall: ResolvedCall<*>
|
resolvedCall: ResolvedCall<*>
|
||||||
): IrGetterCallExpressionImpl {
|
): IrGetterCallImpl {
|
||||||
val returnType = getReturnType(resolvedCall)
|
val returnType = getReturnType(resolvedCall)
|
||||||
val dispatchReceiver = generateReceiver(ktElement, resolvedCall.dispatchReceiver, descriptor.dispatchReceiverParameter)
|
val dispatchReceiver = generateReceiver(ktElement, resolvedCall.dispatchReceiver, descriptor.dispatchReceiverParameter)
|
||||||
val extensionReceiver = generateReceiver(ktElement, resolvedCall.extensionReceiver, descriptor.extensionReceiverParameter)
|
val extensionReceiver = generateReceiver(ktElement, resolvedCall.extensionReceiver, descriptor.extensionReceiverParameter)
|
||||||
return IrGetterCallExpressionImpl(ktElement.startOffset, ktElement.endOffset,
|
return IrGetterCallImpl(ktElement.startOffset, ktElement.endOffset,
|
||||||
returnType, descriptor.getter!!, resolvedCall.call.isSafeCall(),
|
returnType, descriptor.getter!!, resolvedCall.call.isSafeCall(),
|
||||||
dispatchReceiver, extensionReceiver, IrOperator.GET_PROPERTY)
|
dispatchReceiver, extensionReceiver, IrOperator.GET_PROPERTY)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ResolvedCall<*>.requiresArgumentReordering(): Boolean {
|
private fun ResolvedCall<*>.requiresArgumentReordering(): Boolean {
|
||||||
@@ -142,7 +83,7 @@ class CallGenerator(val statementGenerator: StatementGenerator) : IrGenerator {
|
|||||||
): IrExpression {
|
): IrExpression {
|
||||||
val returnType = descriptor.returnType
|
val returnType = descriptor.returnType
|
||||||
|
|
||||||
val irCall = IrCallExpressionImpl(
|
val irCall = IrCallImpl(
|
||||||
ktElement.startOffset, ktElement.endOffset, returnType,
|
ktElement.startOffset, ktElement.endOffset, returnType,
|
||||||
descriptor, resolvedCall.call.isSafeCall(), operator, superQualifier
|
descriptor, resolvedCall.call.isSafeCall(), operator, superQualifier
|
||||||
)
|
)
|
||||||
@@ -166,7 +107,7 @@ class CallGenerator(val statementGenerator: StatementGenerator) : IrGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun generateCallWithArgumentReordering(
|
private fun generateCallWithArgumentReordering(
|
||||||
irCall: IrCallExpression,
|
irCall: IrCall,
|
||||||
ktElement: KtElement,
|
ktElement: KtElement,
|
||||||
resolvedCall: ResolvedCall<out CallableDescriptor>,
|
resolvedCall: ResolvedCall<out CallableDescriptor>,
|
||||||
resultType: KotlinType?
|
resultType: KotlinType?
|
||||||
@@ -177,8 +118,8 @@ class CallGenerator(val statementGenerator: StatementGenerator) : IrGenerator {
|
|||||||
val valueParameters = resolvedCall.resultingDescriptor.valueParameters
|
val valueParameters = resolvedCall.resultingDescriptor.valueParameters
|
||||||
|
|
||||||
val hasResult = isUsedAsExpression(ktElement)
|
val hasResult = isUsedAsExpression(ktElement)
|
||||||
val irBlock = IrBlockExpressionImpl(ktElement.startOffset, ktElement.endOffset, resultType, hasResult,
|
val irBlock = IrBlockImpl(ktElement.startOffset, ktElement.endOffset, resultType, hasResult,
|
||||||
IrOperator.SYNTHETIC_BLOCK)
|
IrOperator.SYNTHETIC_BLOCK)
|
||||||
|
|
||||||
val valueArgumentsToValueParameters = HashMap<ResolvedValueArgument, ValueParameterDescriptor>()
|
val valueArgumentsToValueParameters = HashMap<ResolvedValueArgument, ValueParameterDescriptor>()
|
||||||
for ((index, valueArgument) in resolvedCall.valueArgumentsByIndex!!.withIndex()) {
|
for ((index, valueArgument) in resolvedCall.valueArgumentsByIndex!!.withIndex()) {
|
||||||
@@ -186,17 +127,19 @@ class CallGenerator(val statementGenerator: StatementGenerator) : IrGenerator {
|
|||||||
valueArgumentsToValueParameters[valueArgument] = valueParameter
|
valueArgumentsToValueParameters[valueArgument] = valueParameter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val reorderingScope = Scope(this.scope)
|
||||||
|
|
||||||
for (valueArgument in valueArgumentsInEvaluationOrder) {
|
for (valueArgument in valueArgumentsInEvaluationOrder) {
|
||||||
val valueParameter = valueArgumentsToValueParameters[valueArgument]!!
|
val valueParameter = valueArgumentsToValueParameters[valueArgument]!!
|
||||||
val irArgument = generateValueArgument(valueArgument, valueParameter) ?: continue
|
val irArgument = generateValueArgument(valueArgument, valueParameter) ?: continue
|
||||||
val irTmpArg = introduceTemporary(valueParameter, irArgument)
|
val irTmpArg = reorderingScope.introduceTemporary(valueParameter, irArgument)
|
||||||
irBlock.addIfNotNull(irTmpArg)
|
irBlock.addIfNotNull(irTmpArg)
|
||||||
}
|
}
|
||||||
|
|
||||||
for ((index, valueArgument) in resolvedCall.valueArgumentsByIndex!!.withIndex()) {
|
for ((index, valueArgument) in resolvedCall.valueArgumentsByIndex!!.withIndex()) {
|
||||||
val valueParameter = valueParameters[index]
|
val valueParameter = valueParameters[index]
|
||||||
val irGetTemporary = valueArgumentValues[valueParameter]!!.load()
|
val irGetTemporary = reorderingScope.valueOf(valueParameter)!!
|
||||||
irCall.putArgument(index, irGetTemporary.toExpectedType(valueParameter.type))
|
irCall.putArgument(index, toExpectedType(irGetTemporary, valueParameter.type))
|
||||||
}
|
}
|
||||||
|
|
||||||
irBlock.addStatement(irCall)
|
irBlock.addStatement(irCall)
|
||||||
@@ -208,30 +151,30 @@ class CallGenerator(val statementGenerator: StatementGenerator) : IrGenerator {
|
|||||||
generateReceiver(ktElement, receiver, receiverParameterDescriptor?.type)
|
generateReceiver(ktElement, receiver, receiverParameterDescriptor?.type)
|
||||||
|
|
||||||
fun generateReceiver(ktElement: KtElement, receiver: ReceiverValue?, expectedType: KotlinType?) =
|
fun generateReceiver(ktElement: KtElement, receiver: ReceiverValue?, expectedType: KotlinType?) =
|
||||||
generateReceiver(ktElement, receiver)?.toExpectedType(expectedType)
|
toExpectedTypeOrNull(generateReceiver(ktElement, receiver), expectedType)
|
||||||
|
|
||||||
fun generateReceiver(ktElement: KtElement, receiver: ReceiverValue?): IrExpression? =
|
fun generateReceiver(ktElement: KtElement, receiver: ReceiverValue?): IrExpression? =
|
||||||
if (receiver == null)
|
if (receiver == null)
|
||||||
null
|
null
|
||||||
else
|
else
|
||||||
receiverValues[receiver]?.load() ?: doGenerateReceiver(ktElement, receiver)
|
scope.valueOf(receiver) ?: doGenerateReceiver(ktElement, receiver)
|
||||||
|
|
||||||
fun doGenerateReceiver(ktElement: KtElement, receiver: ReceiverValue?): IrExpression? =
|
fun doGenerateReceiver(ktElement: KtElement, receiver: ReceiverValue?): IrExpression? =
|
||||||
when (receiver) {
|
when (receiver) {
|
||||||
is ImplicitClassReceiver ->
|
is ImplicitClassReceiver ->
|
||||||
IrThisExpressionImpl(ktElement.startOffset, ktElement.startOffset, receiver.type, receiver.classDescriptor)
|
IrThisReferenceImpl(ktElement.startOffset, ktElement.startOffset, receiver.type, receiver.classDescriptor)
|
||||||
is ThisClassReceiver ->
|
is ThisClassReceiver ->
|
||||||
(receiver as? ExpressionReceiver)?.expression?.let { receiverExpression ->
|
(receiver as? ExpressionReceiver)?.expression?.let { receiverExpression ->
|
||||||
IrThisExpressionImpl(receiverExpression.startOffset, receiverExpression.endOffset, receiver.type, receiver.classDescriptor)
|
IrThisReferenceImpl(receiverExpression.startOffset, receiverExpression.endOffset, receiver.type, receiver.classDescriptor)
|
||||||
} ?: TODO("Non-implicit ThisClassReceiver should be an expression receiver")
|
} ?: TODO("Non-implicit ThisClassReceiver should be an expression receiver")
|
||||||
is ExpressionReceiver ->
|
is ExpressionReceiver ->
|
||||||
generateExpression(receiver.expression)
|
generateExpression(receiver.expression)
|
||||||
is ClassValueReceiver ->
|
is ClassValueReceiver ->
|
||||||
IrGetObjectValueExpressionImpl(receiver.expression.startOffset, receiver.expression.endOffset, receiver.type,
|
IrGetObjectValueImpl(receiver.expression.startOffset, receiver.expression.endOffset, receiver.type,
|
||||||
receiver.classQualifier.descriptor)
|
receiver.classQualifier.descriptor)
|
||||||
is ExtensionReceiver ->
|
is ExtensionReceiver ->
|
||||||
IrGetExtensionReceiverExpressionImpl(ktElement.startOffset, ktElement.startOffset, receiver.type,
|
IrGetExtensionReceiverImpl(ktElement.startOffset, ktElement.startOffset, receiver.type,
|
||||||
receiver.declarationDescriptor.extensionReceiverParameter!!)
|
receiver.declarationDescriptor.extensionReceiverParameter!!)
|
||||||
null ->
|
null ->
|
||||||
null
|
null
|
||||||
else ->
|
else ->
|
||||||
@@ -245,13 +188,13 @@ class CallGenerator(val statementGenerator: StatementGenerator) : IrGenerator {
|
|||||||
if (valueParameterDescriptor.varargElementType != null)
|
if (valueParameterDescriptor.varargElementType != null)
|
||||||
doGenerateValueArgument(valueArgument, valueParameterDescriptor)
|
doGenerateValueArgument(valueArgument, valueParameterDescriptor)
|
||||||
else
|
else
|
||||||
doGenerateValueArgument(valueArgument, valueParameterDescriptor)?.toExpectedType(expectedType)
|
toExpectedTypeOrNull(doGenerateValueArgument(valueArgument, valueParameterDescriptor), expectedType)
|
||||||
|
|
||||||
private fun doGenerateValueArgument(valueArgument: ResolvedValueArgument, valueParameterDescriptor: ValueParameterDescriptor): IrExpression? =
|
private fun doGenerateValueArgument(valueArgument: ResolvedValueArgument, valueParameterDescriptor: ValueParameterDescriptor): IrExpression? =
|
||||||
if (valueArgument is DefaultValueArgument)
|
if (valueArgument is DefaultValueArgument)
|
||||||
null
|
null
|
||||||
else
|
else
|
||||||
valueArgumentValues[valueParameterDescriptor]?.load() ?: doGenerateValueArgument(valueArgument)
|
scope.valueOf(valueParameterDescriptor) ?: doGenerateValueArgument(valueArgument)
|
||||||
|
|
||||||
private fun doGenerateValueArgument(valueArgument: ResolvedValueArgument): IrExpression? =
|
private fun doGenerateValueArgument(valueArgument: ResolvedValueArgument): IrExpression? =
|
||||||
when (valueArgument) {
|
when (valueArgument) {
|
||||||
@@ -264,6 +207,6 @@ class CallGenerator(val statementGenerator: StatementGenerator) : IrGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun generateExpression(ktExpression: KtExpression): IrExpression =
|
private fun generateExpression(ktExpression: KtExpression): IrExpression =
|
||||||
expressionValues[ktExpression]?.load() ?: statementGenerator.generateExpression(ktExpression)
|
scope.valueOf(ktExpression) ?: parentGenerator.generateExpression(ktExpression)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-31
@@ -64,20 +64,6 @@ class DeclarationGenerator(override val context: GeneratorContext) : IrGenerator
|
|||||||
return createFunction(ktNamedFunction, functionDescriptor, body)
|
return createFunction(ktNamedFunction, functionDescriptor, body)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generateLocalVariable(scopeOwner: DeclarationDescriptor, ktProperty: KtProperty): IrVariable {
|
|
||||||
if (ktProperty.delegateExpression != null) TODO("Local delegated property")
|
|
||||||
|
|
||||||
val variableDescriptor = getOrFail(BindingContext.VARIABLE, ktProperty)
|
|
||||||
|
|
||||||
val irLocalVariable = IrVariableImpl(ktProperty.startOffset, ktProperty.endOffset, IrDeclarationOriginKind.DEFINED, variableDescriptor)
|
|
||||||
|
|
||||||
irLocalVariable.initializer = ktProperty.initializer?.let {
|
|
||||||
generateExpressionWithinContext(it, scopeOwner)
|
|
||||||
}
|
|
||||||
|
|
||||||
return irLocalVariable
|
|
||||||
}
|
|
||||||
|
|
||||||
fun generatePropertyDeclaration(ktProperty: KtProperty): IrProperty {
|
fun generatePropertyDeclaration(ktProperty: KtProperty): IrProperty {
|
||||||
val propertyDescriptor = getPropertyDescriptor(ktProperty)
|
val propertyDescriptor = getPropertyDescriptor(ktProperty)
|
||||||
if (ktProperty.hasDelegate()) TODO("handle delegated property")
|
if (ktProperty.hasDelegate()) TODO("handle delegated property")
|
||||||
@@ -135,22 +121,11 @@ class DeclarationGenerator(override val context: GeneratorContext) : IrGenerator
|
|||||||
return propertyDescriptor
|
return propertyDescriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateExpressionWithinContext(ktExpression: KtExpression, scopeOwner: DeclarationDescriptor): IrExpression =
|
private fun generateFunctionBody(scopeOwner: CallableDescriptor, ktBody: KtExpression): IrBody =
|
||||||
FunctionBodyGenerator(context).generateFunctionBody(scopeOwner, ktExpression)
|
|
||||||
|
|
||||||
private fun generateFunctionBody(scopeOwner: CallableDescriptor, ktBody: KtExpression): IrBody {
|
|
||||||
val irRhs = generateExpressionWithinContext(ktBody, scopeOwner)
|
|
||||||
val irExpressionBody =
|
|
||||||
if (ktBody is KtBlockExpression)
|
|
||||||
irRhs
|
|
||||||
else
|
|
||||||
IrBlockExpressionImpl(ktBody.startOffset, ktBody.endOffset, null, false).apply {
|
|
||||||
addStatement(IrReturnExpressionImpl(ktBody.startOffset, ktBody.endOffset, scopeOwner, irRhs))
|
|
||||||
}
|
|
||||||
return IrExpressionBodyImpl(ktBody.startOffset, ktBody.endOffset, irExpressionBody)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun generateInitializerBody(scopeOwner: DeclarationDescriptor, ktBody: KtExpression): IrBody =
|
|
||||||
IrExpressionBodyImpl(ktBody.startOffset, ktBody.endOffset,
|
IrExpressionBodyImpl(ktBody.startOffset, ktBody.endOffset,
|
||||||
generateExpressionWithinContext(ktBody, scopeOwner))
|
ExoressionBodyGenerator(scopeOwner, context).generateFunctionBody(ktBody))
|
||||||
|
|
||||||
|
private fun generateInitializerBody(scopeOwner: CallableDescriptor, ktBody: KtExpression): IrBody =
|
||||||
|
IrExpressionBodyImpl(ktBody.startOffset, ktBody.endOffset,
|
||||||
|
ExoressionBodyGenerator(scopeOwner, context).generatePropertyInitializerBody(ktBody))
|
||||||
}
|
}
|
||||||
+60
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* 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.generators
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrBlockImpl
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrReturnImpl
|
||||||
|
import org.jetbrains.kotlin.psi.KtBlockExpression
|
||||||
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
|
|
||||||
|
class ExoressionBodyGenerator(val scopeOwner: CallableDescriptor, override val context: GeneratorContext): IrBodyGenerator {
|
||||||
|
override val scope = Scope.rootScope(scopeOwner, this)
|
||||||
|
|
||||||
|
fun generateFunctionBody(ktBody: KtExpression): IrExpression {
|
||||||
|
resetInternalContext()
|
||||||
|
|
||||||
|
val irBodyExpression = createStatementGenerator().generateExpressionWithExpectedType(ktBody, scopeOwner.returnType)
|
||||||
|
|
||||||
|
val irBodyExpressionAsBlock =
|
||||||
|
if (ktBody is KtBlockExpression)
|
||||||
|
irBodyExpression
|
||||||
|
else IrBlockImpl(ktBody.startOffset, ktBody.endOffset, null, false).apply {
|
||||||
|
addStatement(IrReturnImpl(ktBody.startOffset, ktBody.endOffset, scopeOwner, irBodyExpression))
|
||||||
|
}
|
||||||
|
|
||||||
|
postprocessFunctionBody()
|
||||||
|
|
||||||
|
return irBodyExpressionAsBlock
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resetInternalContext() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun postprocessFunctionBody() {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun generatePropertyInitializerBody(ktInitializer: KtExpression): IrExpression =
|
||||||
|
createStatementGenerator().generateExpressionWithExpectedType(ktInitializer, scopeOwner.returnType!!)
|
||||||
|
|
||||||
|
private fun createStatementGenerator() =
|
||||||
|
StatementGenerator(context, scopeOwner, this, scope)
|
||||||
|
}
|
||||||
|
|
||||||
-40
@@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.generators
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
|
||||||
import org.jetbrains.kotlin.psi2ir.toExpectedType
|
|
||||||
|
|
||||||
class FunctionBodyGenerator(override val context: GeneratorContext): IrGenerator {
|
|
||||||
fun generateFunctionBody(scopeOwner: DeclarationDescriptor, ktExpression: KtExpression): IrExpression {
|
|
||||||
resetInternalContext()
|
|
||||||
val irExpression = StatementGenerator(context, scopeOwner, this)
|
|
||||||
.generateExpression(ktExpression)
|
|
||||||
.toExpectedType(getExpectedTypeForLastInferredCall(ktExpression))
|
|
||||||
postprocessFunctionBody()
|
|
||||||
return irExpression
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun resetInternalContext() {
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun postprocessFunctionBody() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* 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.generators
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrBlockImpl
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrOperator
|
||||||
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import org.jetbrains.kotlin.utils.SmartList
|
||||||
|
|
||||||
|
class IrBlockBuilder(val startOffset: Int, val endOffset: Int, val irOperator: IrOperator, val generator: IrBodyGenerator) {
|
||||||
|
private val statements = SmartList<IrStatement>()
|
||||||
|
private var resultType: KotlinType? = null
|
||||||
|
private var hasResult = false
|
||||||
|
val scope: Scope get() = generator.scope
|
||||||
|
|
||||||
|
fun <T : IrStatement?> add(irStatement: T): T {
|
||||||
|
if (irStatement != null) {
|
||||||
|
statements.add(irStatement)
|
||||||
|
}
|
||||||
|
return irStatement
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T : IrExpression> result(irExpression: T): T {
|
||||||
|
resultType = irExpression.type
|
||||||
|
hasResult = true
|
||||||
|
return irExpression
|
||||||
|
}
|
||||||
|
|
||||||
|
fun build() =
|
||||||
|
if (statements.size == 1)
|
||||||
|
statements[0]
|
||||||
|
else
|
||||||
|
IrBlockImpl(startOffset, endOffset, resultType, hasResult, irOperator).apply {
|
||||||
|
statements.forEach { addStatement(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun IrBodyGenerator.block(ktElement: KtElement, irOperator: IrOperator, body: IrBlockBuilder.() -> Unit) =
|
||||||
|
IrBlockBuilder(ktElement.startOffset, ktElement.endOffset, irOperator, this).apply(body).build()
|
||||||
|
|
||||||
|
fun IrBodyGenerator.block(irExpression: IrExpression, irOperator: IrOperator, body: IrBlockBuilder.() -> Unit) =
|
||||||
|
IrBlockBuilder(irExpression.startOffset, irExpression.endOffset, irOperator, this).apply(body).build()
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* 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.generators
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||||
|
import org.jetbrains.kotlin.types.isNullabilityFlexible
|
||||||
|
|
||||||
|
interface IrBodyGenerator : IrGenerator {
|
||||||
|
val scope: Scope
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class IrChildBodyGeneratorBase<out T : IrBodyGenerator>(val parentGenerator: T) : IrBodyGenerator {
|
||||||
|
override val context: GeneratorContext get() = parentGenerator.context
|
||||||
|
override val scope: Scope get() = parentGenerator.scope
|
||||||
|
}
|
||||||
|
|
||||||
|
fun IrBodyGenerator.toExpectedType(irExpression: IrExpression, expectedType: KotlinType?): IrExpression {
|
||||||
|
if (irExpression is IrBlock && !irExpression.hasResult) return irExpression
|
||||||
|
|
||||||
|
if (expectedType == null) return irExpression
|
||||||
|
if (KotlinBuiltIns.isUnit(expectedType)) return irExpression // TODO expose coercion to Unit in IR?
|
||||||
|
|
||||||
|
val valueType = irExpression.type ?: throw AssertionError("expectedType != null, valueType == null: $this")
|
||||||
|
|
||||||
|
if (valueType.isNullabilityFlexible() && !expectedType.isMarkedNullable) {
|
||||||
|
return IrUnaryOperatorImpl(irExpression.startOffset, irExpression.endOffset, IrOperator.IMPLICIT_NOTNULL,
|
||||||
|
context.irBuiltIns.implicitNotNull,
|
||||||
|
irExpression)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!KotlinTypeChecker.DEFAULT.isSubtypeOf(valueType, expectedType)) {
|
||||||
|
return IrTypeOperatorCallImpl(irExpression.startOffset, irExpression.endOffset, expectedType,
|
||||||
|
IrTypeOperator.IMPLICIT_CAST, expectedType, irExpression)
|
||||||
|
}
|
||||||
|
|
||||||
|
return irExpression
|
||||||
|
}
|
||||||
|
|
||||||
|
fun StatementGenerator.generateExpressionWithExpectedType(ktExpression: KtExpression, expectedType: KotlinType?) =
|
||||||
|
toExpectedType(generateExpression(ktExpression), expectedType)
|
||||||
|
|
||||||
|
fun IrBodyGenerator.toExpectedTypeOrNull(irExpression: IrExpression?, expectedType: KotlinType?): IrExpression? =
|
||||||
|
irExpression?.let { toExpectedType(it, expectedType) }
|
||||||
@@ -32,6 +32,8 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.classValueType
|
|||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||||
import org.jetbrains.kotlin.util.slicedMap.ReadOnlySlice
|
import org.jetbrains.kotlin.util.slicedMap.ReadOnlySlice
|
||||||
|
import java.lang.AssertionError
|
||||||
|
import java.lang.RuntimeException
|
||||||
|
|
||||||
interface IrGenerator {
|
interface IrGenerator {
|
||||||
val context: GeneratorContext
|
val context: GeneratorContext
|
||||||
|
|||||||
+92
-92
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.psi2ir.generators
|
package org.jetbrains.kotlin.psi2ir.generators
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
@@ -26,17 +24,15 @@ import org.jetbrains.kotlin.lexer.KtTokens
|
|||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
|
import org.jetbrains.kotlin.psi2ir.defaultLoad
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.values.*
|
import org.jetbrains.kotlin.psi2ir.generators.values.*
|
||||||
import org.jetbrains.kotlin.psi2ir.load
|
|
||||||
import org.jetbrains.kotlin.psi2ir.toExpectedType
|
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall
|
import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall
|
||||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||||
|
import java.lang.AssertionError
|
||||||
|
|
||||||
|
|
||||||
class OperatorExpressionGenerator(val statementGenerator: StatementGenerator): IrGenerator {
|
class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : IrChildBodyGeneratorBase<StatementGenerator>(statementGenerator) {
|
||||||
override val context: GeneratorContext get() = statementGenerator.context
|
|
||||||
|
|
||||||
fun generatePrefixExpression(expression: KtPrefixExpression): IrExpression {
|
fun generatePrefixExpression(expression: KtPrefixExpression): IrExpression {
|
||||||
val ktOperator = expression.operationReference.getReferencedNameElementType()
|
val ktOperator = expression.operationReference.getReferencedNameElementType()
|
||||||
val irOperator = getIrPrefixOperator(ktOperator)
|
val irOperator = getIrPrefixOperator(ktOperator)
|
||||||
@@ -66,8 +62,8 @@ class OperatorExpressionGenerator(val statementGenerator: StatementGenerator): I
|
|||||||
throw AssertionError("Unexpected IrTypeOperator: $irOperator")
|
throw AssertionError("Unexpected IrTypeOperator: $irOperator")
|
||||||
}
|
}
|
||||||
|
|
||||||
return IrTypeOperatorExpressionImpl(expression.startOffset, expression.endOffset, resultType, irOperator, rhsType,
|
return IrTypeOperatorCallImpl(expression.startOffset, expression.endOffset, resultType, irOperator, rhsType,
|
||||||
statementGenerator.generateExpression(expression.left))
|
parentGenerator.generateExpression(expression.left))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generateInstanceOfExpression(expression: KtIsExpression): IrStatement {
|
fun generateInstanceOfExpression(expression: KtIsExpression): IrStatement {
|
||||||
@@ -75,8 +71,8 @@ class OperatorExpressionGenerator(val statementGenerator: StatementGenerator): I
|
|||||||
val irOperator = getIrTypeOperator(ktOperator)!!
|
val irOperator = getIrTypeOperator(ktOperator)!!
|
||||||
val againstType = getOrFail(BindingContext.TYPE, expression.typeReference)
|
val againstType = getOrFail(BindingContext.TYPE, expression.typeReference)
|
||||||
|
|
||||||
return IrTypeOperatorExpressionImpl(expression.startOffset, expression.endOffset, context.builtIns.booleanType, irOperator,
|
return IrTypeOperatorCallImpl(expression.startOffset, expression.endOffset, context.builtIns.booleanType, irOperator,
|
||||||
againstType, statementGenerator.generateExpression(expression.leftHandSide))
|
againstType, parentGenerator.generateExpression(expression.leftHandSide))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generateBinaryExpression(expression: KtBinaryExpression): IrExpression {
|
fun generateBinaryExpression(expression: KtBinaryExpression): IrExpression {
|
||||||
@@ -103,105 +99,108 @@ class OperatorExpressionGenerator(val statementGenerator: StatementGenerator): I
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun generateElvis(expression: KtBinaryExpression): IrExpression {
|
private fun generateElvis(expression: KtBinaryExpression): IrExpression {
|
||||||
// TODO desugar '?:' to 'if'?
|
// TODO desugar '?:' to 'if'
|
||||||
val specialCallForElvis = getResolvedCall(expression)!!
|
val specialCallForElvis = getResolvedCall(expression)!!
|
||||||
val returnType = specialCallForElvis.resultingDescriptor.returnType!!
|
val returnType = specialCallForElvis.resultingDescriptor.returnType!!
|
||||||
val irArgument0 = statementGenerator.generateExpression(expression.left!!).toExpectedType(returnType.makeNullable())
|
val irArgument0 = toExpectedType(parentGenerator.generateExpression(expression.left!!), returnType.makeNullable())
|
||||||
val irArgument1 = statementGenerator.generateExpression(expression.right!!).toExpectedType(returnType)
|
val irArgument1 = toExpectedType(parentGenerator.generateExpression(expression.right!!), returnType)
|
||||||
return IrBinaryOperatorExpressionImpl(
|
// return IrBinaryOperatorImpl(
|
||||||
expression.startOffset, expression.endOffset, returnType,
|
// expression.startOffset, expression.endOffset, returnType,
|
||||||
IrOperator.ELVIS, null, irArgument0, irArgument1
|
// IrOperator.ELVIS, null, irArgument0, irArgument1
|
||||||
)
|
// )
|
||||||
|
return createDummyExpression(expression, "elvis")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateBinaryBooleanOperator(expression: KtBinaryExpression, irOperator: IrOperator): IrExpression {
|
private fun generateBinaryBooleanOperator(expression: KtBinaryExpression, irOperator: IrOperator): IrExpression {
|
||||||
val irArgument0 = statementGenerator.generateExpression(expression.left!!).toExpectedType(context.builtIns.booleanType)
|
val irArgument0 = toExpectedType(parentGenerator.generateExpression(expression.left!!), context.builtIns.booleanType)
|
||||||
val irArgument1 = statementGenerator.generateExpression(expression.right!!).toExpectedType(context.builtIns.booleanType)
|
val irArgument1 = toExpectedType(parentGenerator.generateExpression(expression.right!!), context.builtIns.booleanType)
|
||||||
return IrBinaryOperatorExpressionImpl(
|
return when (irOperator) {
|
||||||
expression.startOffset, expression.endOffset, context.builtIns.booleanType,
|
IrOperator.OROR ->
|
||||||
irOperator, getResolvedCall(expression)?.resultingDescriptor, irArgument0, irArgument1
|
IrIfThenElseImpl.oror(expression.startOffset, expression.endOffset, irArgument0, irArgument1)
|
||||||
)
|
IrOperator.ANDAND ->
|
||||||
|
IrIfThenElseImpl.andand(expression.startOffset, expression.endOffset, irArgument0, irArgument1)
|
||||||
|
else ->
|
||||||
|
throw AssertionError("Unexpected binary boolean operator $irOperator")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateInOperator(expression: KtBinaryExpression, irOperator: IrOperator): IrExpression {
|
private fun generateInOperator(expression: KtBinaryExpression, irOperator: IrOperator): IrExpression {
|
||||||
val operatorCall = getResolvedCall(expression)!!
|
val containsCall = getResolvedCall(expression)!!
|
||||||
|
|
||||||
val irOperatorCall = CallGenerator(statementGenerator).generateCall(expression, operatorCall, irOperator)
|
val irContainsCall = CallGenerator(parentGenerator).generateCall(expression, containsCall, irOperator)
|
||||||
|
|
||||||
|
return when (irOperator) {
|
||||||
|
IrOperator.IN ->
|
||||||
|
irContainsCall
|
||||||
|
IrOperator.NOT_IN ->
|
||||||
|
IrUnaryOperatorImpl(expression.startOffset, expression.endOffset, IrOperator.EXCL, context.irBuiltIns.booleanNot,
|
||||||
|
irContainsCall)
|
||||||
|
else ->
|
||||||
|
throw AssertionError("Unexpected in-operator $irOperator")
|
||||||
|
}
|
||||||
|
|
||||||
return if (irOperator == IrOperator.IN)
|
|
||||||
irOperatorCall
|
|
||||||
else
|
|
||||||
IrUnaryOperatorExpressionImpl(expression.startOffset, expression.endOffset, context.builtIns.booleanType,
|
|
||||||
IrOperator.EXCL, null, irOperatorCall)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateIdentityOperator(expression: KtBinaryExpression, irOperator: IrOperator): IrExpression {
|
private fun generateIdentityOperator(expression: KtBinaryExpression, irOperator: IrOperator): IrExpression {
|
||||||
val irArgument0 = statementGenerator.generateExpression(expression.left!!)
|
val irArgument0 = parentGenerator.generateExpression(expression.left!!)
|
||||||
val irArgument1 = statementGenerator.generateExpression(expression.right!!)
|
val irArgument1 = parentGenerator.generateExpression(expression.right!!)
|
||||||
return IrBinaryOperatorExpressionImpl(
|
|
||||||
expression.startOffset, expression.endOffset, context.builtIns.booleanType,
|
|
||||||
irOperator, null, irArgument0, irArgument1
|
val irIdentityEquals = IrBinaryOperatorImpl(expression.startOffset, expression.endOffset, irOperator, context.irBuiltIns.eqeqeq,
|
||||||
)
|
irArgument0, irArgument1)
|
||||||
|
|
||||||
|
return when (irOperator) {
|
||||||
|
IrOperator.EQEQEQ ->
|
||||||
|
irIdentityEquals
|
||||||
|
IrOperator.EXCLEQEQ ->
|
||||||
|
IrUnaryOperatorImpl(expression.startOffset, expression.endOffset, IrOperator.EXCL, context.irBuiltIns.booleanNot,
|
||||||
|
irIdentityEquals)
|
||||||
|
else ->
|
||||||
|
throw AssertionError("Unexpected identity operator $irOperator")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateEqualityOperator(expression: KtBinaryExpression, irOperator: IrOperator): IrExpression {
|
private fun generateEqualityOperator(expression: KtBinaryExpression, irOperator: IrOperator): IrExpression {
|
||||||
val relatedCall = getResolvedCall(expression)!!
|
val irArgument0 = parentGenerator.generateExpression(expression.left!!)
|
||||||
val relatedDescriptor = relatedCall.resultingDescriptor
|
val irArgument1 = parentGenerator.generateExpression(expression.right!!)
|
||||||
|
|
||||||
val irCallGenerator = CallGenerator(statementGenerator)
|
val irEquals = IrBinaryOperatorImpl(expression.startOffset, expression.endOffset,
|
||||||
|
irOperator, context.irBuiltIns.eqeq, irArgument0, irArgument1)
|
||||||
|
|
||||||
// NB special typing rules for equality operators: both arguments are nullable
|
return when (irOperator) {
|
||||||
|
IrOperator.EQEQ ->
|
||||||
|
irEquals
|
||||||
|
IrOperator.EXCLEQ ->
|
||||||
|
IrUnaryOperatorImpl(expression.startOffset, expression.endOffset, IrOperator.EXCLEQ,
|
||||||
|
context.irBuiltIns.booleanNot, irEquals)
|
||||||
|
else ->
|
||||||
|
throw AssertionError("Unexpected equality operator $irOperator")
|
||||||
|
}
|
||||||
|
|
||||||
val irArgument0 =
|
|
||||||
irCallGenerator.generateReceiver(expression.left!!, relatedCall.dispatchReceiver)!!
|
|
||||||
.toExpectedType(relatedDescriptor.dispatchReceiverParameter!!.type.makeNullable())
|
|
||||||
|
|
||||||
val valueParameter0 = relatedDescriptor.valueParameters[0]
|
|
||||||
val irArgument1 =
|
|
||||||
irCallGenerator.generateValueArgument(
|
|
||||||
relatedCall.valueArgumentsByIndex!![0],
|
|
||||||
valueParameter0, valueParameter0.type.makeNullable()
|
|
||||||
)!!
|
|
||||||
|
|
||||||
return IrBinaryOperatorExpressionImpl(
|
|
||||||
expression.startOffset, expression.endOffset, context.builtIns.booleanType,
|
|
||||||
irOperator, relatedDescriptor, irArgument0, irArgument1
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateComparisonOperator(expression: KtBinaryExpression, irOperator: IrOperator): IrExpression {
|
private fun generateComparisonOperator(expression: KtBinaryExpression, irOperator: IrOperator): IrExpression {
|
||||||
val compareToCall = getResolvedCall(expression)!!
|
val compareToCall = getResolvedCall(expression)!!
|
||||||
val compareToDescriptor = compareToCall.resultingDescriptor
|
|
||||||
|
|
||||||
val irCallGenerator = CallGenerator(statementGenerator)
|
val irCallGenerator = CallGenerator(parentGenerator)
|
||||||
|
val irCompareToCall = irCallGenerator.generateCall(expression, compareToCall, irOperator)
|
||||||
|
|
||||||
return if (shouldKeepComparisonAsBinaryOperation(compareToDescriptor)) {
|
val compareToZeroDescriptor = when (irOperator) {
|
||||||
val irArgument0 = irCallGenerator.generateReceiver(expression.left!!, compareToCall.dispatchReceiver, compareToDescriptor.dispatchReceiverParameter!!)!!
|
IrOperator.LT -> context.irBuiltIns.lt0
|
||||||
val valueParameter0 = compareToDescriptor.valueParameters[0]
|
IrOperator.LTEQ -> context.irBuiltIns.lteq0
|
||||||
val irArgument1 = irCallGenerator.generateValueArgument(compareToCall.valueArgumentsByIndex!![0], valueParameter0)!!
|
IrOperator.GT -> context.irBuiltIns.gt0
|
||||||
IrBinaryOperatorExpressionImpl(
|
IrOperator.GTEQ -> context.irBuiltIns.gteq0
|
||||||
expression.startOffset, expression.endOffset, context.builtIns.booleanType,
|
else -> throw AssertionError("Unexpected comparison operator: $irOperator")
|
||||||
irOperator, compareToDescriptor, irArgument0, irArgument1
|
|
||||||
)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
val irCompareToCall = irCallGenerator.generateCall(expression, compareToCall, irOperator)
|
|
||||||
IrBinaryOperatorExpressionImpl(
|
|
||||||
expression.startOffset, expression.endOffset, context.builtIns.booleanType,
|
|
||||||
irOperator, null, irCompareToCall,
|
|
||||||
IrConstExpressionImpl.int(expression.startOffset, expression.endOffset, context.builtIns.intType, 0)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return IrUnaryOperatorImpl(expression.startOffset, expression.endOffset, irOperator, compareToZeroDescriptor, irCompareToCall)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun shouldKeepComparisonAsBinaryOperation(compareToDescriptor: CallableDescriptor) =
|
|
||||||
compareToDescriptor.dispatchReceiverParameter?.type.let {
|
|
||||||
it != null && (KotlinBuiltIns.isPrimitiveType(it) || KotlinBuiltIns.isString(it))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun generateBinaryOperatorWithConventionalCall(expression: KtBinaryExpression, irOperator: IrOperator?): IrExpression {
|
private fun generateBinaryOperatorWithConventionalCall(expression: KtBinaryExpression, irOperator: IrOperator?): IrExpression {
|
||||||
val operatorCall = getResolvedCall(expression)!!
|
val operatorCall = getResolvedCall(expression)!!
|
||||||
return CallGenerator(statementGenerator).generateCall(expression, operatorCall, irOperator)
|
return CallGenerator(parentGenerator).generateCall(expression, operatorCall, irOperator)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generatePrefixIncrementDecrementOperator(expression: KtPrefixExpression, irOperator: IrOperator): IrExpression {
|
private fun generatePrefixIncrementDecrementOperator(expression: KtPrefixExpression, irOperator: IrOperator): IrExpression {
|
||||||
@@ -213,13 +212,13 @@ class OperatorExpressionGenerator(val statementGenerator: StatementGenerator): I
|
|||||||
return irLValue.prefixAugmentedStore(operatorCall, irOperator)
|
return irLValue.prefixAugmentedStore(operatorCall, irOperator)
|
||||||
}
|
}
|
||||||
|
|
||||||
val opCallGenerator = CallGenerator(statementGenerator).apply { putValue(ktBaseExpression, irLValue) }
|
val opCallGenerator = CallGenerator(parentGenerator).apply { scope.putValue(ktBaseExpression, irLValue) }
|
||||||
val irBlock = IrBlockExpressionImpl(expression.startOffset, expression.endOffset, irLValue.type, true, irOperator)
|
val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, irLValue.type, true, irOperator)
|
||||||
val irOpCall = opCallGenerator.generateCall(expression, operatorCall, irOperator)
|
val irOpCall = opCallGenerator.generateCall(expression, operatorCall, irOperator)
|
||||||
val irTmp = statementGenerator.temporaryVariableFactory.createTemporaryVariable(irOpCall)
|
val irTmp = parentGenerator.scope.createTemporaryVariable(irOpCall)
|
||||||
irBlock.addStatement(irTmp)
|
irBlock.addStatement(irTmp)
|
||||||
irBlock.addStatement(irLValue.store(irTmp.load()))
|
irBlock.addStatement(irLValue.store(irTmp.defaultLoad()))
|
||||||
irBlock.addStatement(irTmp.load())
|
irBlock.addStatement(irTmp.defaultLoad())
|
||||||
return irBlock
|
return irBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,10 +230,10 @@ class OperatorExpressionGenerator(val statementGenerator: StatementGenerator): I
|
|||||||
val isSimpleAssignment = get(BindingContext.VARIABLE_REASSIGNMENT, expression) ?: false
|
val isSimpleAssignment = get(BindingContext.VARIABLE_REASSIGNMENT, expression) ?: false
|
||||||
|
|
||||||
if (isSimpleAssignment && irLValue is IrLValueWithAugmentedStore) {
|
if (isSimpleAssignment && irLValue is IrLValueWithAugmentedStore) {
|
||||||
return irLValue.augmentedStore(operatorCall, irOperator, statementGenerator.generateExpression(expression.right!!))
|
return irLValue.augmentedStore(operatorCall, irOperator, parentGenerator.generateExpression(expression.right!!))
|
||||||
}
|
}
|
||||||
|
|
||||||
val opCallGenerator = CallGenerator(statementGenerator).apply { putValue(ktLeft, irLValue) }
|
val opCallGenerator = CallGenerator(parentGenerator).apply { scope.putValue(ktLeft, irLValue) }
|
||||||
val irOpCall = opCallGenerator.generateCall(expression, operatorCall, irOperator)
|
val irOpCall = opCallGenerator.generateCall(expression, operatorCall, irOperator)
|
||||||
|
|
||||||
return if (isSimpleAssignment) {
|
return if (isSimpleAssignment) {
|
||||||
@@ -251,19 +250,19 @@ class OperatorExpressionGenerator(val statementGenerator: StatementGenerator): I
|
|||||||
val ktLeft = expression.left!!
|
val ktLeft = expression.left!!
|
||||||
val ktRight = expression.right!!
|
val ktRight = expression.right!!
|
||||||
val irLValue = generateLValue(ktLeft, IrOperator.EQ)
|
val irLValue = generateLValue(ktLeft, IrOperator.EQ)
|
||||||
return irLValue.store(statementGenerator.generateExpression(ktRight))
|
return irLValue.store(parentGenerator.generateExpression(ktRight))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateLValue(ktLeft: KtExpression, irOperator: IrOperator?): IrLValue {
|
private fun generateLValue(ktLeft: KtExpression, irOperator: IrOperator?): IrLValue {
|
||||||
if (ktLeft is KtArrayAccessExpression) {
|
if (ktLeft is KtArrayAccessExpression) {
|
||||||
val irArrayValue = statementGenerator.generateExpression(ktLeft.arrayExpression!!)
|
val irArrayValue = parentGenerator.generateExpression(ktLeft.arrayExpression!!)
|
||||||
val indexExpressions = ktLeft.indexExpressions.map { it to statementGenerator.generateExpression(it) }
|
val indexExpressions = ktLeft.indexExpressions.map { it to parentGenerator.generateExpression(it) }
|
||||||
val indexedGetCall = get(BindingContext.INDEXED_LVALUE_GET, ktLeft)
|
val indexedGetCall = get(BindingContext.INDEXED_LVALUE_GET, ktLeft)
|
||||||
val indexedSetCall = get(BindingContext.INDEXED_LVALUE_SET, ktLeft)
|
val indexedSetCall = get(BindingContext.INDEXED_LVALUE_SET, ktLeft)
|
||||||
val type = indexedGetCall?.run { resultingDescriptor.returnType }
|
val type = indexedGetCall?.run { resultingDescriptor.returnType }
|
||||||
?: indexedSetCall?.run { resultingDescriptor.valueParameters.last().type }
|
?: indexedSetCall?.run { resultingDescriptor.valueParameters.last().type }
|
||||||
?: throw AssertionError("Either 'get' or 'set' call should be present for an indexed LValue: ${ktLeft.text}")
|
?: throw AssertionError("Either 'get' or 'set' call should be present for an indexed LValue: ${ktLeft.text}")
|
||||||
return IndexedLValue(statementGenerator, ktLeft, irOperator,
|
return IndexedLValue(parentGenerator, ktLeft, irOperator,
|
||||||
irArrayValue, type, indexExpressions, indexedGetCall, indexedSetCall)
|
irArrayValue, type, indexExpressions, indexedGetCall, indexedSetCall)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,10 +274,11 @@ class OperatorExpressionGenerator(val statementGenerator: StatementGenerator): I
|
|||||||
if (descriptor.isDelegated)
|
if (descriptor.isDelegated)
|
||||||
TODO("Delegated local variable")
|
TODO("Delegated local variable")
|
||||||
else
|
else
|
||||||
VariableLValue(ktLeft.startOffset, ktLeft.endOffset, descriptor, irOperator)
|
VariableLValue(this, ktLeft.startOffset, ktLeft.endOffset, descriptor, irOperator)
|
||||||
is PropertyDescriptor ->
|
is PropertyDescriptor ->
|
||||||
CallGenerator(statementGenerator).run {
|
CallGenerator(parentGenerator).run {
|
||||||
PropertyLValue(
|
PropertyLValue(
|
||||||
|
this,
|
||||||
ktLeft, irOperator, descriptor,
|
ktLeft, irOperator, descriptor,
|
||||||
generateReceiver(ktLeft, resolvedCall.dispatchReceiver, descriptor.dispatchReceiverParameter),
|
generateReceiver(ktLeft, resolvedCall.dispatchReceiver, descriptor.dispatchReceiverParameter),
|
||||||
generateReceiver(ktLeft, resolvedCall.extensionReceiver, descriptor.extensionReceiverParameter),
|
generateReceiver(ktLeft, resolvedCall.extensionReceiver, descriptor.extensionReceiverParameter),
|
||||||
|
|||||||
@@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
* 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.generators
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginKind
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrVariableImpl
|
||||||
|
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptor
|
||||||
|
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
|
import org.jetbrains.kotlin.psi2ir.generators.values.IrValue
|
||||||
|
import org.jetbrains.kotlin.psi2ir.generators.values.VariableLValue
|
||||||
|
import org.jetbrains.kotlin.psi2ir.generators.values.createRematerializableValue
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class Scope private constructor(val scopeOwner: DeclarationDescriptor, val parent: Scope? = null) {
|
||||||
|
internal lateinit var generator: IrBodyGenerator
|
||||||
|
|
||||||
|
constructor(parent: Scope) : this(parent.scopeOwner, parent) {
|
||||||
|
this.generator = parent.generator
|
||||||
|
}
|
||||||
|
|
||||||
|
private var lastTemporaryIndex: Int = parent?.lastTemporaryIndex ?: 0
|
||||||
|
private fun nextTemporaryIndex(): Int = parent?.nextTemporaryIndex() ?: lastTemporaryIndex++
|
||||||
|
|
||||||
|
private val expressionValues = HashMap<KtExpression, IrValue>()
|
||||||
|
private val receiverValues = HashMap<ReceiverValue, IrValue>()
|
||||||
|
private val valueArgumentValues = HashMap<ValueParameterDescriptor, IrValue>()
|
||||||
|
|
||||||
|
private fun createDescriptorForTemporaryVariable(type: KotlinType, nameHint: String? = null): IrTemporaryVariableDescriptor =
|
||||||
|
IrTemporaryVariableDescriptorImpl(
|
||||||
|
scopeOwner,
|
||||||
|
Name.identifier(
|
||||||
|
if (nameHint != null)
|
||||||
|
"tmp${nextTemporaryIndex()}_$nameHint"
|
||||||
|
else
|
||||||
|
"tmp${nextTemporaryIndex()}"
|
||||||
|
),
|
||||||
|
type)
|
||||||
|
|
||||||
|
fun createTemporaryVariable(irExpression: IrExpression, nameHint: String? = null): IrVariable =
|
||||||
|
IrVariableImpl(irExpression.startOffset, irExpression.endOffset, IrDeclarationOriginKind.IR_TEMPORARY_VARIABLE,
|
||||||
|
createDescriptorForTemporaryVariable(
|
||||||
|
irExpression.type ?: throw AssertionError("No type for $irExpression"),
|
||||||
|
nameHint
|
||||||
|
),
|
||||||
|
irExpression)
|
||||||
|
|
||||||
|
fun introduceTemporary(ktExpression: KtExpression, irExpression: IrExpression, nameHint: String? = null): IrVariable? {
|
||||||
|
val rematerializable = createRematerializableValue(irExpression)
|
||||||
|
if (rematerializable != null) {
|
||||||
|
putValue(ktExpression, rematerializable)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return createTemporary(ktExpression, irExpression, nameHint)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createTemporary(ktExpression: KtExpression, irExpression: IrExpression, nameHint: String?): IrVariable {
|
||||||
|
val irTmpVar = createTemporaryVariable(irExpression, nameHint)
|
||||||
|
putValue(ktExpression, VariableLValue(generator, irTmpVar))
|
||||||
|
return irTmpVar
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createTemporary(irExpression: IrExpression, nameHint: String?): IrVariable =
|
||||||
|
createTemporaryVariable(irExpression, nameHint)
|
||||||
|
|
||||||
|
fun introduceTemporary(valueParameterDescriptor: ValueParameterDescriptor, irExpression: IrExpression): IrVariable? {
|
||||||
|
val rematerializable = createRematerializableValue(irExpression)
|
||||||
|
if (rematerializable != null) {
|
||||||
|
putValue(valueParameterDescriptor, rematerializable)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
val irTmpVar = createTemporaryVariable(irExpression, valueParameterDescriptor.name.asString())
|
||||||
|
putValue(valueParameterDescriptor, VariableLValue(generator, irTmpVar))
|
||||||
|
return irTmpVar
|
||||||
|
}
|
||||||
|
|
||||||
|
fun putValue(ktExpression: KtExpression, irValue: IrValue) {
|
||||||
|
expressionValues[ktExpression] = irValue
|
||||||
|
}
|
||||||
|
|
||||||
|
fun putValue(receiver: ReceiverValue, irValue: IrValue) {
|
||||||
|
receiverValues[receiver] = irValue
|
||||||
|
}
|
||||||
|
|
||||||
|
fun putValue(parameter: ValueParameterDescriptor, irValue: IrValue) {
|
||||||
|
valueArgumentValues[parameter] = irValue
|
||||||
|
}
|
||||||
|
|
||||||
|
fun valueOf(ktExpression: KtExpression): IrExpression? =
|
||||||
|
expressionValues[ktExpression]?.load() ?: parent?.valueOf(ktExpression)
|
||||||
|
fun valueOf(receiver: ReceiverValue): IrExpression? =
|
||||||
|
receiverValues[receiver]?.load() ?: parent?.valueOf(receiver)
|
||||||
|
fun valueOf(parameter: ValueParameterDescriptor): IrExpression? =
|
||||||
|
valueArgumentValues[parameter]?.load() ?: parent?.valueOf(parameter)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun rootScope(scopeOwner: DeclarationDescriptor, generator: IrBodyGenerator): Scope {
|
||||||
|
val scope = Scope(scopeOwner)
|
||||||
|
scope.generator = generator
|
||||||
|
return scope
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+31
-33
@@ -1,4 +1,4 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
|||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
import org.jetbrains.kotlin.psi2ir.deparenthesize
|
import org.jetbrains.kotlin.psi2ir.deparenthesize
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.values.VariableLValue
|
import org.jetbrains.kotlin.psi2ir.generators.values.VariableLValue
|
||||||
import org.jetbrains.kotlin.psi2ir.toExpectedType
|
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.BindingContextUtils
|
import org.jetbrains.kotlin.resolve.BindingContextUtils
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
@@ -44,10 +43,9 @@ import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
|
|||||||
class StatementGenerator(
|
class StatementGenerator(
|
||||||
override val context: GeneratorContext,
|
override val context: GeneratorContext,
|
||||||
val scopeOwner: DeclarationDescriptor,
|
val scopeOwner: DeclarationDescriptor,
|
||||||
val functionBodyGenerator: FunctionBodyGenerator
|
val declarationBodyGenerator: ExoressionBodyGenerator,
|
||||||
) : KtVisitor<IrStatement, Nothing?>(), IrGenerator {
|
override val scope: Scope
|
||||||
val temporaryVariableFactory: TemporaryVariableFactory = TemporaryVariableFactory(scopeOwner)
|
) : KtVisitor<IrStatement, Nothing?>(), IrBodyGenerator {
|
||||||
|
|
||||||
fun generateExpression(ktExpression: KtExpression): IrExpression =
|
fun generateExpression(ktExpression: KtExpression): IrExpression =
|
||||||
ktExpression.genExpr()
|
ktExpression.genExpr()
|
||||||
|
|
||||||
@@ -67,7 +65,7 @@ class StatementGenerator(
|
|||||||
|
|
||||||
val irLocalVariable = IrVariableImpl(property.startOffset, property.endOffset, IrDeclarationOriginKind.DEFINED, variableDescriptor)
|
val irLocalVariable = IrVariableImpl(property.startOffset, property.endOffset, IrDeclarationOriginKind.DEFINED, variableDescriptor)
|
||||||
irLocalVariable.initializer = property.initializer?.let {
|
irLocalVariable.initializer = property.initializer?.let {
|
||||||
it.genExpr().toExpectedType(variableDescriptor.type)
|
toExpectedType(it.genExpr(), variableDescriptor.type)
|
||||||
}
|
}
|
||||||
|
|
||||||
return irLocalVariable
|
return irLocalVariable
|
||||||
@@ -76,13 +74,13 @@ class StatementGenerator(
|
|||||||
override fun visitDestructuringDeclaration(multiDeclaration: KtDestructuringDeclaration, data: Nothing?): IrStatement {
|
override fun visitDestructuringDeclaration(multiDeclaration: KtDestructuringDeclaration, data: Nothing?): IrStatement {
|
||||||
// TODO use some special form that introduces multiple declarations into surrounding scope?
|
// TODO use some special form that introduces multiple declarations into surrounding scope?
|
||||||
|
|
||||||
val irBlock = IrBlockExpressionImpl(multiDeclaration.startOffset, multiDeclaration.endOffset, null, false, IrOperator.SYNTHETIC_BLOCK)
|
val irBlock = IrBlockImpl(multiDeclaration.startOffset, multiDeclaration.endOffset, null, false, IrOperator.SYNTHETIC_BLOCK)
|
||||||
val ktInitializer = multiDeclaration.initializer!!
|
val ktInitializer = multiDeclaration.initializer!!
|
||||||
val irTmpInitializer = temporaryVariableFactory.createTemporaryVariable(ktInitializer.genExpr())
|
val irTmpInitializer = scope.createTemporaryVariable(ktInitializer.genExpr())
|
||||||
irBlock.addStatement(irTmpInitializer)
|
irBlock.addStatement(irTmpInitializer)
|
||||||
|
|
||||||
val irCallGenerator = CallGenerator(this)
|
val irCallGenerator = CallGenerator(this)
|
||||||
irCallGenerator.putValue(ktInitializer, VariableLValue(irTmpInitializer))
|
irCallGenerator.scope.putValue(ktInitializer, VariableLValue(this, irTmpInitializer))
|
||||||
|
|
||||||
for ((index, ktEntry) in multiDeclaration.entries.withIndex()) {
|
for ((index, ktEntry) in multiDeclaration.entries.withIndex()) {
|
||||||
val componentResolvedCall = getOrFail(BindingContext.COMPONENT_RESOLVED_CALL, ktEntry)
|
val componentResolvedCall = getOrFail(BindingContext.COMPONENT_RESOLVED_CALL, ktEntry)
|
||||||
@@ -97,8 +95,8 @@ class StatementGenerator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitBlockExpression(expression: KtBlockExpression, data: Nothing?): IrStatement {
|
override fun visitBlockExpression(expression: KtBlockExpression, data: Nothing?): IrStatement {
|
||||||
val irBlock = IrBlockExpressionImpl(expression.startOffset, expression.endOffset,
|
val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset,
|
||||||
getReturnType(expression), isUsedAsExpression(expression))
|
getReturnType(expression), isUsedAsExpression(expression))
|
||||||
expression.statements.forEach { irBlock.addStatement(it.genStmt()) }
|
expression.statements.forEach { irBlock.addStatement(it.genStmt()) }
|
||||||
return irBlock
|
return irBlock
|
||||||
}
|
}
|
||||||
@@ -106,9 +104,9 @@ class StatementGenerator(
|
|||||||
override fun visitReturnExpression(expression: KtReturnExpression, data: Nothing?): IrStatement {
|
override fun visitReturnExpression(expression: KtReturnExpression, data: Nothing?): IrStatement {
|
||||||
val returnTarget = getReturnExpressionTarget(expression)
|
val returnTarget = getReturnExpressionTarget(expression)
|
||||||
val irReturnedExpression = expression.returnedExpression?.let {
|
val irReturnedExpression = expression.returnedExpression?.let {
|
||||||
it.genExpr().toExpectedType(returnTarget.returnType)
|
toExpectedType(it.genExpr(), returnTarget.returnType)
|
||||||
}
|
}
|
||||||
return IrReturnExpressionImpl(
|
return IrReturnImpl(
|
||||||
expression.startOffset, expression.endOffset,
|
expression.startOffset, expression.endOffset,
|
||||||
returnTarget, irReturnedExpression
|
returnTarget, irReturnedExpression
|
||||||
)
|
)
|
||||||
@@ -141,11 +139,11 @@ class StatementGenerator(
|
|||||||
|
|
||||||
return when (constantValue) {
|
return when (constantValue) {
|
||||||
is StringValue ->
|
is StringValue ->
|
||||||
IrConstExpressionImpl.string(expression.startOffset, expression.endOffset, constantType, constantValue.value)
|
IrConstImpl.string(expression.startOffset, expression.endOffset, constantType, constantValue.value)
|
||||||
is IntValue ->
|
is IntValue ->
|
||||||
IrConstExpressionImpl.int(expression.startOffset, expression.endOffset, constantType, constantValue.value)
|
IrConstImpl.int(expression.startOffset, expression.endOffset, constantType, constantValue.value)
|
||||||
is NullValue ->
|
is NullValue ->
|
||||||
IrConstExpressionImpl.constNull(expression.startOffset, expression.endOffset, constantType)
|
IrConstImpl.constNull(expression.startOffset, expression.endOffset, constantType)
|
||||||
else ->
|
else ->
|
||||||
TODO("handle other literal types: ${constantValue.type}")
|
TODO("handle other literal types: ${constantValue.type}")
|
||||||
}
|
}
|
||||||
@@ -160,16 +158,16 @@ class StatementGenerator(
|
|||||||
return entry0.genExpr()
|
return entry0.genExpr()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
entries.size == 0 -> return IrConstExpressionImpl.string(expression.startOffset, expression.endOffset, getInferredTypeWithSmarcastsOrFail(expression), "")
|
entries.size == 0 -> return IrConstImpl.string(expression.startOffset, expression.endOffset, getInferredTypeWithSmarcastsOrFail(expression), "")
|
||||||
}
|
}
|
||||||
|
|
||||||
val irStringTemplate = IrStringConcatenationExpressionImpl(expression.startOffset, expression.endOffset, getInferredTypeWithSmartcasts(expression))
|
val irStringTemplate = IrStringConcatenationImpl(expression.startOffset, expression.endOffset, getInferredTypeWithSmartcasts(expression))
|
||||||
entries.forEach { it.expression!!.let { irStringTemplate.addArgument(it.genExpr()) } }
|
entries.forEach { it.expression!!.let { irStringTemplate.addArgument(it.genExpr()) } }
|
||||||
return irStringTemplate
|
return irStringTemplate
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitLiteralStringTemplateEntry(entry: KtLiteralStringTemplateEntry, data: Nothing?): IrStatement =
|
override fun visitLiteralStringTemplateEntry(entry: KtLiteralStringTemplateEntry, data: Nothing?): IrStatement =
|
||||||
IrConstExpressionImpl.string(entry.startOffset, entry.endOffset, context.builtIns.stringType, entry.text)
|
IrConstImpl.string(entry.startOffset, entry.endOffset, context.builtIns.stringType, entry.text)
|
||||||
|
|
||||||
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression, data: Nothing?): IrExpression {
|
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression, data: Nothing?): IrExpression {
|
||||||
val resolvedCall = getResolvedCall(expression)!!
|
val resolvedCall = getResolvedCall(expression)!!
|
||||||
@@ -189,21 +187,21 @@ class StatementGenerator(
|
|||||||
generateExpressionForReferencedDescriptor(descriptor.getReferencedDescriptor(), expression, resolvedCall)
|
generateExpressionForReferencedDescriptor(descriptor.getReferencedDescriptor(), expression, resolvedCall)
|
||||||
is ClassDescriptor ->
|
is ClassDescriptor ->
|
||||||
if (DescriptorUtils.isObject(descriptor))
|
if (DescriptorUtils.isObject(descriptor))
|
||||||
IrGetObjectValueExpressionImpl(expression.startOffset, expression.endOffset, descriptor.classValueType, descriptor)
|
IrGetObjectValueImpl(expression.startOffset, expression.endOffset, descriptor.classValueType, descriptor)
|
||||||
else if (DescriptorUtils.isEnumEntry(descriptor))
|
else if (DescriptorUtils.isEnumEntry(descriptor))
|
||||||
IrGetEnumValueExpressionImpl(expression.startOffset, expression.endOffset, descriptor.classValueType, descriptor)
|
IrGetEnumValueImpl(expression.startOffset, expression.endOffset, descriptor.classValueType, descriptor)
|
||||||
else {
|
else {
|
||||||
val companionObjectDescriptor = descriptor.companionObjectDescriptor
|
val companionObjectDescriptor = descriptor.companionObjectDescriptor
|
||||||
?: error("Class value without companion object: $descriptor")
|
?: error("Class value without companion object: $descriptor")
|
||||||
IrGetObjectValueExpressionImpl(expression.startOffset, expression.endOffset,
|
IrGetObjectValueImpl(expression.startOffset, expression.endOffset,
|
||||||
descriptor.classValueType,
|
descriptor.classValueType,
|
||||||
companionObjectDescriptor)
|
companionObjectDescriptor)
|
||||||
}
|
}
|
||||||
is PropertyDescriptor -> {
|
is PropertyDescriptor -> {
|
||||||
CallGenerator(this).generateCall(expression, resolvedCall)
|
CallGenerator(this).generateCall(expression, resolvedCall)
|
||||||
}
|
}
|
||||||
is VariableDescriptor ->
|
is VariableDescriptor ->
|
||||||
IrGetVariableExpressionImpl(expression.startOffset, expression.endOffset, descriptor)
|
IrGetVariableImpl(expression.startOffset, expression.endOffset, descriptor)
|
||||||
else ->
|
else ->
|
||||||
IrDummyExpression(
|
IrDummyExpression(
|
||||||
expression.startOffset, expression.endOffset, getInferredTypeWithSmartcasts(expression),
|
expression.startOffset, expression.endOffset, getInferredTypeWithSmartcasts(expression),
|
||||||
@@ -231,14 +229,14 @@ class StatementGenerator(
|
|||||||
val referenceTarget = getOrFail(BindingContext.REFERENCE_TARGET, expression.instanceReference) { "No reference target for this" }
|
val referenceTarget = getOrFail(BindingContext.REFERENCE_TARGET, expression.instanceReference) { "No reference target for this" }
|
||||||
return when (referenceTarget) {
|
return when (referenceTarget) {
|
||||||
is ClassDescriptor ->
|
is ClassDescriptor ->
|
||||||
IrThisExpressionImpl(
|
IrThisReferenceImpl(
|
||||||
expression.startOffset, expression.endOffset,
|
expression.startOffset, expression.endOffset,
|
||||||
referenceTarget.defaultType, // TODO substituted type for 'this'?
|
referenceTarget.defaultType, // TODO substituted type for 'this'?
|
||||||
referenceTarget
|
referenceTarget
|
||||||
)
|
)
|
||||||
is CallableDescriptor -> {
|
is CallableDescriptor -> {
|
||||||
val extensionReceiver = referenceTarget.extensionReceiverParameter ?: TODO("No extension receiver: $referenceTarget")
|
val extensionReceiver = referenceTarget.extensionReceiverParameter ?: TODO("No extension receiver: $referenceTarget")
|
||||||
IrGetExtensionReceiverExpressionImpl(
|
IrGetExtensionReceiverImpl(
|
||||||
expression.startOffset, expression.endOffset,
|
expression.startOffset, expression.endOffset,
|
||||||
extensionReceiver.type,
|
extensionReceiver.type,
|
||||||
extensionReceiver
|
extensionReceiver
|
||||||
@@ -266,11 +264,11 @@ class StatementGenerator(
|
|||||||
|
|
||||||
override fun visitIfExpression(expression: KtIfExpression, data: Nothing?): IrStatement {
|
override fun visitIfExpression(expression: KtIfExpression, data: Nothing?): IrStatement {
|
||||||
val resultType = getInferredTypeWithSmartcasts(expression)
|
val resultType = getInferredTypeWithSmartcasts(expression)
|
||||||
val irCondition = expression.condition!!.genExpr().toExpectedType(context.builtIns.booleanType)
|
val irCondition = toExpectedType(expression.condition!!.genExpr(), context.builtIns.booleanType)
|
||||||
val irThenBranch = expression.then!!.genExpr().toExpectedType(resultType)
|
val irThenBranch = toExpectedType(expression.then!!.genExpr(), resultType)
|
||||||
val irElseBranch = expression.`else`?.let { it.genExpr().toExpectedType(resultType) }
|
val irElseBranch = toExpectedTypeOrNull(expression.`else`?.genExpr(), resultType)
|
||||||
return IrIfExpressionImpl(expression.startOffset, expression.endOffset, resultType,
|
return IrIfThenElseImpl(expression.startOffset, expression.endOffset, resultType,
|
||||||
irCondition, irThenBranch, irElseBranch, IrOperator.IF)
|
irCondition, irThenBranch, irElseBranch, IrOperator.IF)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitWhenExpression(expression: KtWhenExpression, data: Nothing?): IrStatement =
|
override fun visitWhenExpression(expression: KtWhenExpression, data: Nothing?): IrStatement =
|
||||||
|
|||||||
-19
@@ -27,25 +27,6 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
class TemporaryVariableFactory(val scopeOwner: DeclarationDescriptor) {
|
class TemporaryVariableFactory(val scopeOwner: DeclarationDescriptor) {
|
||||||
private var lastTemporaryIndex = 0
|
|
||||||
private fun nextTemporaryIndex() = lastTemporaryIndex++
|
|
||||||
|
|
||||||
private fun createDescriptorForTemporaryVariable(type: KotlinType, nameHint: String? = null): IrTemporaryVariableDescriptor =
|
|
||||||
IrTemporaryVariableDescriptorImpl(
|
|
||||||
scopeOwner,
|
|
||||||
Name.identifier(
|
|
||||||
if (nameHint != null)
|
|
||||||
"tmp${nextTemporaryIndex()}_$nameHint"
|
|
||||||
else
|
|
||||||
"tmp${nextTemporaryIndex()}"
|
|
||||||
),
|
|
||||||
type)
|
|
||||||
|
|
||||||
fun createTemporaryVariable(irExpression: IrExpression, nameHint: String? = null): IrVariable =
|
|
||||||
IrVariableImpl(irExpression.startOffset, irExpression.endOffset, IrDeclarationOriginKind.IR_TEMPORARY_VARIABLE,
|
|
||||||
createDescriptorForTemporaryVariable(
|
|
||||||
irExpression.type ?: throw AssertionError("No type for $irExpression"),
|
|
||||||
nameHint
|
|
||||||
),
|
|
||||||
irExpression)
|
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-28
@@ -21,19 +21,16 @@ import org.jetbrains.kotlin.ir.expressions.*
|
|||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
import org.jetbrains.kotlin.psi2ir.load
|
import org.jetbrains.kotlin.psi2ir.defaultLoad
|
||||||
import org.jetbrains.kotlin.psi2ir.toExpectedType
|
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class WhenExpressionGenerator(val statementGenerator: StatementGenerator) : IrGenerator {
|
class WhenExpressionGenerator(statementGenerator: StatementGenerator) : IrChildBodyGeneratorBase<StatementGenerator>(statementGenerator) {
|
||||||
override val context: GeneratorContext get() = statementGenerator.context
|
|
||||||
|
|
||||||
fun generate(expression: KtWhenExpression): IrExpression {
|
fun generate(expression: KtWhenExpression): IrExpression {
|
||||||
val conditionsGenerator = CallGenerator(statementGenerator)
|
val conditionsGenerator = CallGenerator(parentGenerator)
|
||||||
|
|
||||||
val irSubject = expression.subjectExpression?.let {
|
val irSubject = expression.subjectExpression?.let {
|
||||||
conditionsGenerator.createTemporary(it, statementGenerator.generateExpression(it), "subject")
|
conditionsGenerator.scope.createTemporary(it, parentGenerator.generateExpression(it), "subject")
|
||||||
}
|
}
|
||||||
|
|
||||||
val resultType = getInferredTypeWithSmartcasts(expression)
|
val resultType = getInferredTypeWithSmartcasts(expression)
|
||||||
@@ -43,7 +40,7 @@ class WhenExpressionGenerator(val statementGenerator: StatementGenerator) : IrGe
|
|||||||
|
|
||||||
for (ktEntry in expression.entries) {
|
for (ktEntry in expression.entries) {
|
||||||
if (ktEntry.isElse) {
|
if (ktEntry.isElse) {
|
||||||
irElseExpression = statementGenerator.generateExpression(ktEntry.expression!!).toExpectedType(resultType)
|
irElseExpression = parentGenerator.generateExpressionWithExpectedType(ktEntry.expression!!, resultType)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,11 +51,11 @@ class WhenExpressionGenerator(val statementGenerator: StatementGenerator) : IrGe
|
|||||||
generateWhenConditionWithSubject(ktCondition, conditionsGenerator, irSubject)
|
generateWhenConditionWithSubject(ktCondition, conditionsGenerator, irSubject)
|
||||||
else
|
else
|
||||||
generateWhenConditionNoSubject(ktCondition)
|
generateWhenConditionNoSubject(ktCondition)
|
||||||
irBranchCondition = irBranchCondition?.let { IrIfExpressionImpl.whenComma(it, irCondition) } ?: irCondition
|
irBranchCondition = irBranchCondition?.let { IrIfThenElseImpl.whenComma(it, irCondition) } ?: irCondition
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val irBranchResult = statementGenerator.generateExpression(ktEntry.expression!!).toExpectedType(resultType)
|
val irBranchResult = parentGenerator.generateExpressionWithExpectedType(ktEntry.expression!!, resultType)
|
||||||
irBranches.add(Pair(irBranchCondition!!, irBranchResult))
|
irBranches.add(Pair(irBranchCondition!!, irBranchResult))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,32 +64,32 @@ class WhenExpressionGenerator(val statementGenerator: StatementGenerator) : IrGe
|
|||||||
irBranches.reverse()
|
irBranches.reverse()
|
||||||
|
|
||||||
val (irLastCondition, irLastResult) = irBranches[0]
|
val (irLastCondition, irLastResult) = irBranches[0]
|
||||||
var irTopBranch = IrIfExpressionImpl(irLastCondition.startOffset, irLastCondition.endOffset, resultType,
|
var irTopBranch = IrIfThenElseImpl(irLastCondition.startOffset, irLastCondition.endOffset, resultType,
|
||||||
irLastCondition, irLastResult, irElseExpression, IrOperator.WHEN)
|
irLastCondition, irLastResult, irElseExpression, IrOperator.WHEN)
|
||||||
|
|
||||||
for ((irBranchCondition, irBranchResult) in irBranches.subList(1, irBranches.size)) {
|
for ((irBranchCondition, irBranchResult) in irBranches.subList(1, irBranches.size)) {
|
||||||
irTopBranch = IrIfExpressionImpl(irBranchCondition.startOffset, irBranchCondition.endOffset, resultType,
|
irTopBranch = IrIfThenElseImpl(irBranchCondition.startOffset, irBranchCondition.endOffset, resultType,
|
||||||
irBranchCondition, irBranchResult, irTopBranch, IrOperator.WHEN)
|
irBranchCondition, irBranchResult, irTopBranch, IrOperator.WHEN)
|
||||||
}
|
}
|
||||||
|
|
||||||
return generateWhenBody(expression, irSubject, irTopBranch)
|
return generateWhenBody(expression, irSubject, irTopBranch)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateWhenBody(expression: KtWhenExpression, irSubject: IrVariable?, irTopBranch: IrIfExpression? = null): IrExpression {
|
private fun generateWhenBody(expression: KtWhenExpression, irSubject: IrVariable?, irTopBranch: IrIfThenElse? = null): IrExpression {
|
||||||
if (irSubject == null) {
|
if (irSubject == null) {
|
||||||
if (irTopBranch == null)
|
if (irTopBranch == null)
|
||||||
return IrBlockExpressionImpl(expression.startOffset, expression.endOffset, null, false, IrOperator.WHEN)
|
return IrBlockImpl(expression.startOffset, expression.endOffset, null, false, IrOperator.WHEN)
|
||||||
else
|
else
|
||||||
return irTopBranch
|
return irTopBranch
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (irTopBranch == null) {
|
if (irTopBranch == null) {
|
||||||
val irBlock = IrBlockExpressionImpl(expression.startOffset, expression.endOffset, null, false, IrOperator.WHEN)
|
val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, null, false, IrOperator.WHEN)
|
||||||
irBlock.addStatement(irSubject)
|
irBlock.addStatement(irSubject)
|
||||||
return irBlock
|
return irBlock
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
val irBlock = IrBlockExpressionImpl(expression.startOffset, expression.endOffset, irTopBranch.type, true, IrOperator.WHEN)
|
val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, irTopBranch.type, true, IrOperator.WHEN)
|
||||||
irBlock.addStatement(irSubject)
|
irBlock.addStatement(irSubject)
|
||||||
irBlock.addStatement(irTopBranch)
|
irBlock.addStatement(irTopBranch)
|
||||||
return irBlock
|
return irBlock
|
||||||
@@ -101,8 +98,8 @@ class WhenExpressionGenerator(val statementGenerator: StatementGenerator) : IrGe
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun generateWhenConditionNoSubject(ktCondition: KtWhenCondition): IrExpression =
|
private fun generateWhenConditionNoSubject(ktCondition: KtWhenCondition): IrExpression =
|
||||||
statementGenerator.generateExpression((ktCondition as KtWhenConditionWithExpression).expression!!)
|
parentGenerator.generateExpressionWithExpectedType((ktCondition as KtWhenConditionWithExpression).expression!!,
|
||||||
.toExpectedType(context.builtIns.booleanType)
|
context.builtIns.booleanType)
|
||||||
|
|
||||||
private fun generateWhenConditionWithSubject(
|
private fun generateWhenConditionWithSubject(
|
||||||
ktCondition: KtWhenCondition,
|
ktCondition: KtWhenCondition,
|
||||||
@@ -123,9 +120,9 @@ class WhenExpressionGenerator(val statementGenerator: StatementGenerator) : IrGe
|
|||||||
|
|
||||||
private fun generateIsPatternCondition(irSubject: IrVariable, ktCondition: KtWhenConditionIsPattern): IrExpression {
|
private fun generateIsPatternCondition(irSubject: IrVariable, ktCondition: KtWhenConditionIsPattern): IrExpression {
|
||||||
val isType = getOrFail(BindingContext.TYPE, ktCondition.typeReference)
|
val isType = getOrFail(BindingContext.TYPE, ktCondition.typeReference)
|
||||||
return IrTypeOperatorExpressionImpl(
|
return IrTypeOperatorCallImpl(
|
||||||
ktCondition.startOffset, ktCondition.endOffset, context.builtIns.booleanType,
|
ktCondition.startOffset, ktCondition.endOffset, context.builtIns.booleanType,
|
||||||
IrTypeOperator.INSTANCEOF, isType, irSubject.load()
|
IrTypeOperator.INSTANCEOF, isType, irSubject.defaultLoad()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,16 +133,15 @@ class WhenExpressionGenerator(val statementGenerator: StatementGenerator) : IrGe
|
|||||||
return when (inOperator) {
|
return when (inOperator) {
|
||||||
IrOperator.IN -> irInCall
|
IrOperator.IN -> irInCall
|
||||||
IrOperator.NOT_IN ->
|
IrOperator.NOT_IN ->
|
||||||
IrUnaryOperatorExpressionImpl(ktCondition.startOffset, ktCondition.endOffset, context.builtIns.booleanType,
|
IrUnaryOperatorImpl(ktCondition.startOffset, ktCondition.endOffset, IrOperator.EXCL, context.irBuiltIns.booleanNot, irInCall)
|
||||||
IrOperator.EXCL, null, irInCall)
|
|
||||||
else -> throw AssertionError("Expected 'in' or '!in', got $inOperator")
|
else -> throw AssertionError("Expected 'in' or '!in', got $inOperator")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateEqualsCondition(irSubject: IrVariable, ktCondition: KtWhenConditionWithExpression): IrBinaryOperatorExpressionImpl =
|
private fun generateEqualsCondition(irSubject: IrVariable, ktCondition: KtWhenConditionWithExpression): IrBinaryOperatorImpl =
|
||||||
IrBinaryOperatorExpressionImpl(
|
IrBinaryOperatorImpl(
|
||||||
ktCondition.startOffset, ktCondition.endOffset,
|
ktCondition.startOffset, ktCondition.endOffset,
|
||||||
context.builtIns.booleanType, IrOperator.EQEQ, null,
|
IrOperator.EQEQ, context.irBuiltIns.eqeq,
|
||||||
irSubject.load(), statementGenerator.generateExpression(ktCondition.expression!!)
|
irSubject.defaultLoad(), parentGenerator.generateExpression(ktCondition.expression!!)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
+24
-23
@@ -21,8 +21,9 @@ import org.jetbrains.kotlin.psi.KtArrayAccessExpression
|
|||||||
import org.jetbrains.kotlin.psi.KtExpression
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
import org.jetbrains.kotlin.psi2ir.load
|
import org.jetbrains.kotlin.psi2ir.defaultLoad
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.CallGenerator
|
import org.jetbrains.kotlin.psi2ir.generators.CallGenerator
|
||||||
|
import org.jetbrains.kotlin.psi2ir.generators.Scope
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.StatementGenerator
|
import org.jetbrains.kotlin.psi2ir.generators.StatementGenerator
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
@@ -51,10 +52,10 @@ class IndexedLValue(
|
|||||||
|
|
||||||
private fun generateGetOrSetCallAsDesugaredBlock(call: ResolvedCall<*>, irArgument: IrExpression? = null): IrExpression {
|
private fun generateGetOrSetCallAsDesugaredBlock(call: ResolvedCall<*>, irArgument: IrExpression? = null): IrExpression {
|
||||||
val callGenerator = CallGenerator(statementGenerator)
|
val callGenerator = CallGenerator(statementGenerator)
|
||||||
setupCallGeneratorContext(callGenerator)
|
setupCallGeneratorContext(callGenerator.scope)
|
||||||
|
|
||||||
if (irArgument != null) {
|
if (irArgument != null) {
|
||||||
callGenerator.putValue(call.resultingDescriptor.valueParameters.last(), IrSingleExpressionValue(irArgument))
|
callGenerator.scope.putValue(call.resultingDescriptor.valueParameters.last(), IrSingleExpressionValue(irArgument))
|
||||||
}
|
}
|
||||||
|
|
||||||
return callGenerator.generateCall(ktArrayAccessExpression, call, irOperator)
|
return callGenerator.generateCall(ktArrayAccessExpression, call, irOperator)
|
||||||
@@ -69,18 +70,18 @@ class IndexedLValue(
|
|||||||
val irBlock = createDesugaredBlockWithTemporaries(indexedSetCall, callGenerator, true, irOperator)
|
val irBlock = createDesugaredBlockWithTemporaries(indexedSetCall, callGenerator, true, irOperator)
|
||||||
|
|
||||||
val operatorCallReceiver = operatorCall.extensionReceiver ?: operatorCall.dispatchReceiver
|
val operatorCallReceiver = operatorCall.extensionReceiver ?: operatorCall.dispatchReceiver
|
||||||
callGenerator.putValue(operatorCallReceiver!!,
|
callGenerator.scope.putValue(operatorCallReceiver!!,
|
||||||
IrSingleExpressionValue(callGenerator.generateCall(ktArrayAccessExpression, indexedGetCall, irOperator)))
|
IrSingleExpressionValue(callGenerator.generateCall(ktArrayAccessExpression, indexedGetCall, irOperator)))
|
||||||
val irTmp = statementGenerator.temporaryVariableFactory.createTemporaryVariable(
|
val irTmp = statementGenerator.scope.createTemporaryVariable(
|
||||||
callGenerator.generateCall(ktArrayAccessExpression, operatorCall, irOperator))
|
callGenerator.generateCall(ktArrayAccessExpression, operatorCall, irOperator))
|
||||||
irBlock.addStatement(irTmp)
|
irBlock.addStatement(irTmp)
|
||||||
|
|
||||||
callGenerator.putValue(indexedSetCall.resultingDescriptor.valueParameters.last(),
|
callGenerator.scope.putValue(indexedSetCall.resultingDescriptor.valueParameters.last(),
|
||||||
VariableLValue(irTmp))
|
VariableLValue(statementGenerator, irTmp))
|
||||||
|
|
||||||
irBlock.addStatement(callGenerator.generateCall(ktArrayAccessExpression, indexedSetCall, irOperator))
|
irBlock.addStatement(callGenerator.generateCall(ktArrayAccessExpression, indexedSetCall, irOperator))
|
||||||
|
|
||||||
irBlock.addStatement(irTmp.load())
|
irBlock.addStatement(irTmp.defaultLoad())
|
||||||
|
|
||||||
return irBlock
|
return irBlock
|
||||||
}
|
}
|
||||||
@@ -93,13 +94,13 @@ class IndexedLValue(
|
|||||||
|
|
||||||
val irBlock = createDesugaredBlockWithTemporaries(indexedSetCall, callGenerator, false, irOperator)
|
val irBlock = createDesugaredBlockWithTemporaries(indexedSetCall, callGenerator, false, irOperator)
|
||||||
|
|
||||||
callGenerator.putValue(operatorCall.resultingDescriptor.valueParameters[0], IrSingleExpressionValue(irOperatorArgument))
|
callGenerator.scope.putValue(operatorCall.resultingDescriptor.valueParameters[0], IrSingleExpressionValue(irOperatorArgument))
|
||||||
|
|
||||||
val operatorCallReceiver = operatorCall.extensionReceiver ?: operatorCall.dispatchReceiver
|
val operatorCallReceiver = operatorCall.extensionReceiver ?: operatorCall.dispatchReceiver
|
||||||
callGenerator.putValue(operatorCallReceiver!!,
|
callGenerator.scope.putValue(operatorCallReceiver!!,
|
||||||
IrSingleExpressionValue(callGenerator.generateCall(ktArrayAccessExpression, indexedGetCall, irOperator)))
|
IrSingleExpressionValue(callGenerator.generateCall(ktArrayAccessExpression, indexedGetCall, irOperator)))
|
||||||
|
|
||||||
callGenerator.putValue(indexedSetCall.resultingDescriptor.valueParameters.last(),
|
callGenerator.scope.putValue(indexedSetCall.resultingDescriptor.valueParameters.last(),
|
||||||
IrSingleExpressionValue(callGenerator.generateCall(ktArrayAccessExpression, operatorCall, irOperator)))
|
IrSingleExpressionValue(callGenerator.generateCall(ktArrayAccessExpression, operatorCall, irOperator)))
|
||||||
|
|
||||||
irBlock.addStatement(callGenerator.generateCall(ktArrayAccessExpression, indexedSetCall, irOperator))
|
irBlock.addStatement(callGenerator.generateCall(ktArrayAccessExpression, indexedSetCall, irOperator))
|
||||||
@@ -112,32 +113,32 @@ class IndexedLValue(
|
|||||||
callGenerator: CallGenerator,
|
callGenerator: CallGenerator,
|
||||||
hasResult: Boolean,
|
hasResult: Boolean,
|
||||||
operator: IrOperator?
|
operator: IrOperator?
|
||||||
): IrBlockExpressionImpl {
|
): IrBlockImpl {
|
||||||
val irBlock = createDesugaredBlock(call, hasResult, operator)
|
val irBlock = createDesugaredBlock(call, hasResult, operator)
|
||||||
defineTemporaryVariables(irBlock, callGenerator)
|
defineTemporaryVariables(irBlock, callGenerator.scope)
|
||||||
return irBlock
|
return irBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createDesugaredBlock(call: ResolvedCall<*>, hasResult: Boolean, operator: IrOperator?): IrBlockExpressionImpl {
|
private fun createDesugaredBlock(call: ResolvedCall<*>, hasResult: Boolean, operator: IrOperator?): IrBlockImpl {
|
||||||
return IrBlockExpressionImpl(ktArrayAccessExpression.startOffset, ktArrayAccessExpression.endOffset,
|
return IrBlockImpl(ktArrayAccessExpression.startOffset, ktArrayAccessExpression.endOffset,
|
||||||
if (hasResult) type else call.resultingDescriptor.returnType,
|
if (hasResult) type else call.resultingDescriptor.returnType,
|
||||||
hasResult, operator)
|
hasResult, operator)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun defineTemporaryVariables(irBlock: IrBlockExpressionImpl, callGenerator: CallGenerator) {
|
private fun defineTemporaryVariables(irBlock: IrBlockImpl, scope: Scope) {
|
||||||
irBlock.addIfNotNull(callGenerator.introduceTemporary(ktArrayAccessExpression.arrayExpression!!, irArray, "array"))
|
irBlock.addIfNotNull(scope.introduceTemporary(ktArrayAccessExpression.arrayExpression!!, irArray, "array"))
|
||||||
|
|
||||||
var index = 0
|
var index = 0
|
||||||
for ((ktIndexExpression, irIndexValue) in indexValues) {
|
for ((ktIndexExpression, irIndexValue) in indexValues) {
|
||||||
irBlock.addIfNotNull(callGenerator.introduceTemporary(ktIndexExpression, irIndexValue, "index${index++}"))
|
irBlock.addIfNotNull(scope.introduceTemporary(ktIndexExpression, irIndexValue, "index${index++}"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupCallGeneratorContext(callGenerator: CallGenerator) {
|
private fun setupCallGeneratorContext(scope: Scope) {
|
||||||
callGenerator.putValue(ktArrayAccessExpression.arrayExpression!!, IrSingleExpressionValue(irArray))
|
scope.putValue(ktArrayAccessExpression.arrayExpression!!, IrSingleExpressionValue(irArray))
|
||||||
|
|
||||||
for ((ktIndexExpression, irIndexValue) in indexValues) {
|
for ((ktIndexExpression, irIndexValue) in indexValues) {
|
||||||
callGenerator.putValue(ktIndexExpression, IrSingleExpressionValue(irIndexValue))
|
scope.putValue(ktIndexExpression, IrSingleExpressionValue(irIndexValue))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+8
-6
@@ -21,10 +21,12 @@ import org.jetbrains.kotlin.ir.expressions.*
|
|||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
import org.jetbrains.kotlin.psi2ir.toExpectedType
|
import org.jetbrains.kotlin.psi2ir.generators.IrBodyGenerator
|
||||||
|
import org.jetbrains.kotlin.psi2ir.generators.toExpectedType
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
class PropertyLValue(
|
class PropertyLValue(
|
||||||
|
val irBodyGenerator: IrBodyGenerator,
|
||||||
val ktElement: KtElement,
|
val ktElement: KtElement,
|
||||||
val irOperator: IrOperator?,
|
val irOperator: IrOperator?,
|
||||||
val descriptor: PropertyDescriptor,
|
val descriptor: PropertyDescriptor,
|
||||||
@@ -37,7 +39,7 @@ class PropertyLValue(
|
|||||||
|
|
||||||
override fun load(): IrExpression {
|
override fun load(): IrExpression {
|
||||||
val getter = descriptor.getter!!
|
val getter = descriptor.getter!!
|
||||||
return IrGetterCallExpressionImpl(
|
return IrGetterCallImpl(
|
||||||
ktElement.startOffset, ktElement.endOffset,
|
ktElement.startOffset, ktElement.endOffset,
|
||||||
getter.returnType, getter, isSafe,
|
getter.returnType, getter, isSafe,
|
||||||
dispatchReceiver, extensionReceiver, IrOperator.GET_PROPERTY
|
dispatchReceiver, extensionReceiver, IrOperator.GET_PROPERTY
|
||||||
@@ -46,10 +48,10 @@ class PropertyLValue(
|
|||||||
|
|
||||||
override fun store(irExpression: IrExpression): IrExpression {
|
override fun store(irExpression: IrExpression): IrExpression {
|
||||||
val setter = descriptor.setter!!
|
val setter = descriptor.setter!!
|
||||||
val irArgument = irExpression.toExpectedType(descriptor.type)
|
val irArgument = irBodyGenerator.toExpectedType(irExpression, descriptor.type)
|
||||||
val irCall = IrSetterCallExpressionImpl(ktElement.startOffset, ktElement.endOffset,
|
val irCall = IrSetterCallImpl(ktElement.startOffset, ktElement.endOffset,
|
||||||
setter.returnType, setter, isSafe,
|
setter.returnType, setter, isSafe,
|
||||||
dispatchReceiver, extensionReceiver, irArgument, irOperator)
|
dispatchReceiver, extensionReceiver, irArgument, irOperator)
|
||||||
return irCall
|
return irCall
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+13
-13
@@ -28,30 +28,30 @@ interface IrRematerializableValue : IrValue {
|
|||||||
|
|
||||||
fun createRematerializableValue(irExpression: IrExpression): IrRematerializableValue? =
|
fun createRematerializableValue(irExpression: IrExpression): IrRematerializableValue? =
|
||||||
when (irExpression) {
|
when (irExpression) {
|
||||||
is IrConstExpression<*> -> IrRematerializableLiteralValue(irExpression)
|
is IrConst<*> -> IrRematerializableLiteralValue(irExpression)
|
||||||
is IrGetVariableExpression -> IrRematerializableVariableValue(irExpression)
|
is IrGetVariable -> IrRematerializableVariableValue(irExpression)
|
||||||
is IrGetExtensionReceiverExpression -> IrRematerializableExtensionReceiverValue(irExpression)
|
is IrGetExtensionReceiver -> IrRematerializableExtensionReceiverValue(irExpression)
|
||||||
is IrThisExpression -> IrRematerializableThisValue(irExpression)
|
is IrThisReference -> IrRematerializableThisValue(irExpression)
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
class IrRematerializableLiteralValue(override val irExpression: IrConstExpression<*>): IrRematerializableValue {
|
class IrRematerializableLiteralValue(override val irExpression: IrConst<*>): IrRematerializableValue {
|
||||||
override fun load(): IrExpression =
|
override fun load(): IrExpression =
|
||||||
IrConstExpressionImpl(irExpression.startOffset, irExpression.endOffset, irExpression.type,
|
IrConstImpl(irExpression.startOffset, irExpression.endOffset, irExpression.type,
|
||||||
irExpression.kind, irExpression.kind.valueOf(irExpression))
|
irExpression.kind, irExpression.kind.valueOf(irExpression))
|
||||||
}
|
}
|
||||||
|
|
||||||
class IrRematerializableVariableValue(override val irExpression: IrGetVariableExpression) : IrRematerializableValue {
|
class IrRematerializableVariableValue(override val irExpression: IrGetVariable) : IrRematerializableValue {
|
||||||
override fun load(): IrExpression =
|
override fun load(): IrExpression =
|
||||||
IrGetVariableExpressionImpl(irExpression.startOffset, irExpression.endOffset, irExpression.descriptor)
|
IrGetVariableImpl(irExpression.startOffset, irExpression.endOffset, irExpression.descriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
class IrRematerializableExtensionReceiverValue(override val irExpression: IrGetExtensionReceiverExpression) : IrRematerializableValue {
|
class IrRematerializableExtensionReceiverValue(override val irExpression: IrGetExtensionReceiver) : IrRematerializableValue {
|
||||||
override fun load(): IrExpression =
|
override fun load(): IrExpression =
|
||||||
IrGetExtensionReceiverExpressionImpl(irExpression.startOffset, irExpression.endOffset, irExpression.type, irExpression.descriptor)
|
IrGetExtensionReceiverImpl(irExpression.startOffset, irExpression.endOffset, irExpression.type, irExpression.descriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
class IrRematerializableThisValue(override val irExpression: IrThisExpression): IrRematerializableValue {
|
class IrRematerializableThisValue(override val irExpression: IrThisReference): IrRematerializableValue {
|
||||||
override fun load(): IrExpression =
|
override fun load(): IrExpression =
|
||||||
IrThisExpressionImpl(irExpression.startOffset, irExpression.endOffset, irExpression.type, irExpression.classDescriptor)
|
IrThisReferenceImpl(irExpression.startOffset, irExpression.endOffset, irExpression.type, irExpression.classDescriptor)
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-7
@@ -19,29 +19,32 @@ package org.jetbrains.kotlin.psi2ir.generators.values
|
|||||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrGetVariableExpressionImpl
|
import org.jetbrains.kotlin.ir.expressions.IrGetVariableImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrOperator
|
import org.jetbrains.kotlin.ir.expressions.IrOperator
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrSetVariableExpressionImpl
|
import org.jetbrains.kotlin.ir.expressions.IrSetVariableImpl
|
||||||
import org.jetbrains.kotlin.psi2ir.toExpectedType
|
import org.jetbrains.kotlin.psi2ir.generators.IrBodyGenerator
|
||||||
|
import org.jetbrains.kotlin.psi2ir.generators.toExpectedType
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
class VariableLValue(
|
class VariableLValue(
|
||||||
|
val irBodyGenerator: IrBodyGenerator,
|
||||||
val startOffset: Int,
|
val startOffset: Int,
|
||||||
val endOffset: Int,
|
val endOffset: Int,
|
||||||
val descriptor: VariableDescriptor,
|
val descriptor: VariableDescriptor,
|
||||||
val irOperator: IrOperator? = null
|
val irOperator: IrOperator? = null
|
||||||
) : IrLValue {
|
) : IrLValue {
|
||||||
constructor(
|
constructor(
|
||||||
|
irBodyGenerator: IrBodyGenerator,
|
||||||
irVariable: IrVariable,
|
irVariable: IrVariable,
|
||||||
irOperator: IrOperator? = null
|
irOperator: IrOperator? = null
|
||||||
) : this(irVariable.startOffset, irVariable.endOffset, irVariable.descriptor, irOperator)
|
) : this(irBodyGenerator, irVariable.startOffset, irVariable.endOffset, irVariable.descriptor, irOperator)
|
||||||
|
|
||||||
override val type: KotlinType? get() = descriptor.type
|
override val type: KotlinType? get() = descriptor.type
|
||||||
|
|
||||||
override fun load(): IrExpression =
|
override fun load(): IrExpression =
|
||||||
IrGetVariableExpressionImpl(startOffset, endOffset, descriptor, irOperator)
|
IrGetVariableImpl(startOffset, endOffset, descriptor, irOperator)
|
||||||
|
|
||||||
override fun store(irExpression: IrExpression): IrExpression =
|
override fun store(irExpression: IrExpression): IrExpression =
|
||||||
IrSetVariableExpressionImpl(startOffset, endOffset, descriptor,
|
IrSetVariableImpl(startOffset, endOffset, descriptor,
|
||||||
irExpression.toExpectedType(descriptor.type), irOperator)
|
irBodyGenerator.toExpectedType(irExpression, descriptor.type), irOperator)
|
||||||
}
|
}
|
||||||
+7
-7
@@ -20,10 +20,10 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.detach
|
import org.jetbrains.kotlin.ir.detach
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrCallExpression
|
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrStringConcatenationExpression
|
import org.jetbrains.kotlin.ir.expressions.IrStringConcatenation
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrStringConcatenationExpressionImpl
|
import org.jetbrains.kotlin.ir.expressions.IrStringConcatenationImpl
|
||||||
import org.jetbrains.kotlin.ir.replaceWith
|
import org.jetbrains.kotlin.ir.replaceWith
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
@@ -38,7 +38,7 @@ class FoldStringConcatenation : IrElementVisitor<Unit, Nothing?> {
|
|||||||
element.acceptChildren(this, data)
|
element.acceptChildren(this, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitCallExpression(expression: IrCallExpression, data: Nothing?) {
|
override fun visitCall(expression: IrCall, data: Nothing?) {
|
||||||
if (!isStringPlus(expression.descriptor)) {
|
if (!isStringPlus(expression.descriptor)) {
|
||||||
visitElement(expression, data)
|
visitElement(expression, data)
|
||||||
return
|
return
|
||||||
@@ -46,7 +46,7 @@ class FoldStringConcatenation : IrElementVisitor<Unit, Nothing?> {
|
|||||||
|
|
||||||
val arguments = ArrayList<IrExpression>()
|
val arguments = ArrayList<IrExpression>()
|
||||||
collectStringConcatenationArguments(expression, arguments)
|
collectStringConcatenationArguments(expression, arguments)
|
||||||
val irStringConcatenation = IrStringConcatenationExpressionImpl(expression.startOffset, expression.endOffset, expression.type)
|
val irStringConcatenation = IrStringConcatenationImpl(expression.startOffset, expression.endOffset, expression.type)
|
||||||
arguments.forEach { irStringConcatenation.addArgument(it) }
|
arguments.forEach { irStringConcatenation.addArgument(it) }
|
||||||
|
|
||||||
expression.replaceWith(irStringConcatenation)
|
expression.replaceWith(irStringConcatenation)
|
||||||
@@ -54,11 +54,11 @@ class FoldStringConcatenation : IrElementVisitor<Unit, Nothing?> {
|
|||||||
|
|
||||||
private fun collectStringConcatenationArguments(expression: IrExpression, arguments: ArrayList<IrExpression>) {
|
private fun collectStringConcatenationArguments(expression: IrExpression, arguments: ArrayList<IrExpression>) {
|
||||||
when {
|
when {
|
||||||
expression is IrCallExpression && isStringPlus(expression.descriptor)-> {
|
expression is IrCall && isStringPlus(expression.descriptor)-> {
|
||||||
collectStringConcatenationArguments(expression.dispatchReceiver!!, arguments)
|
collectStringConcatenationArguments(expression.dispatchReceiver!!, arguments)
|
||||||
collectStringConcatenationArguments(expression.getArgument(0)!!, arguments)
|
collectStringConcatenationArguments(expression.getArgument(0)!!, arguments)
|
||||||
}
|
}
|
||||||
expression is IrStringConcatenationExpression -> {
|
expression is IrStringConcatenation -> {
|
||||||
arguments.addAll(expression.arguments)
|
arguments.addAll(expression.arguments)
|
||||||
expression.arguments.forEach { it.detach() }
|
expression.arguments.forEach { it.detach() }
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -18,8 +18,8 @@ package org.jetbrains.kotlin.psi2ir.transformations
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.detach
|
import org.jetbrains.kotlin.ir.detach
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrBlockExpression
|
import org.jetbrains.kotlin.ir.expressions.IrBlock
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrBlockExpressionImpl
|
import org.jetbrains.kotlin.ir.expressions.IrBlockImpl
|
||||||
import org.jetbrains.kotlin.ir.replaceWith
|
import org.jetbrains.kotlin.ir.replaceWith
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
|
|
||||||
@@ -32,14 +32,14 @@ class InlineDesugaredBlocks : IrElementVisitor<Unit, Nothing?> {
|
|||||||
element.acceptChildren(this, data)
|
element.acceptChildren(this, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitBlockExpression(expression: IrBlockExpression, data: Nothing?) {
|
override fun visitBlock(expression: IrBlock, data: Nothing?) {
|
||||||
val transformedBlock = IrBlockExpressionImpl(
|
val transformedBlock = IrBlockImpl(
|
||||||
expression.startOffset, expression.endOffset, expression.type,
|
expression.startOffset, expression.endOffset, expression.type,
|
||||||
expression.hasResult, expression.operator
|
expression.hasResult, expression.operator
|
||||||
)
|
)
|
||||||
for (statement in expression.statements) {
|
for (statement in expression.statements) {
|
||||||
statement.accept(this, data)
|
statement.accept(this, data)
|
||||||
if (statement is IrBlockExpression && statement.operator != null) {
|
if (statement is IrBlock && statement.operator != null) {
|
||||||
statement.statements.forEach {
|
statement.statements.forEach {
|
||||||
transformedBlock.addStatement(it.detach())
|
transformedBlock.addStatement(it.detach())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ fun <T : IrElement?> T.detach(): T {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun IrElement.replaceWith(otherElement: IrElement) {
|
fun IrElement.replaceWith(otherElement: IrElement) {
|
||||||
|
if (otherElement == this) return
|
||||||
val parent = this.parent ?: throw AssertionError("Can't replace a non-root element $this")
|
val parent = this.parent ?: throw AssertionError("Can't replace a non-root element $this")
|
||||||
parent.replaceChild(slot, otherElement.detach())
|
parent.replaceChild(slot, otherElement.detach())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,23 +17,36 @@
|
|||||||
package org.jetbrains.kotlin.ir.descriptors
|
package org.jetbrains.kotlin.ir.descriptors
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import org.jetbrains.kotlin.types.TypeSubstitution
|
||||||
|
|
||||||
class IrBuiltIns(val builtIns: KotlinBuiltIns) {
|
class IrBuiltIns(val builtIns: KotlinBuiltIns) {
|
||||||
val packageFragment = IrBuiltinsPackageFragmentDescriptorImpl(builtIns.builtInsModule)
|
val packageFragment = IrBuiltinsPackageFragmentDescriptorImpl(builtIns.builtInsModule)
|
||||||
|
|
||||||
val eqeqeq: IrBuiltinOperatorDescriptor
|
val eqeqeq: FunctionDescriptor
|
||||||
val eqeq: IrBuiltinOperatorDescriptor
|
val eqeq: FunctionDescriptor
|
||||||
val lt0: IrBuiltinOperatorDescriptor
|
val lt0: FunctionDescriptor
|
||||||
val lteq0: IrBuiltinOperatorDescriptor
|
val lteq0: FunctionDescriptor
|
||||||
val gt0: IrBuiltinOperatorDescriptor
|
val gt0: FunctionDescriptor
|
||||||
val gteq0: IrBuiltinOperatorDescriptor
|
val gteq0: FunctionDescriptor
|
||||||
|
val notNull: FunctionDescriptor
|
||||||
|
val throwNpe: FunctionDescriptor
|
||||||
|
|
||||||
|
val booleanNot: FunctionDescriptor
|
||||||
|
|
||||||
|
val implicitNotNull: CallableDescriptor // TODO drop
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val bool = builtIns.booleanType
|
val bool = builtIns.booleanType
|
||||||
|
val any = builtIns.anyType
|
||||||
val anyN = builtIns.nullableAnyType
|
val anyN = builtIns.nullableAnyType
|
||||||
val int = builtIns.intType
|
val int = builtIns.intType
|
||||||
|
val nothing = builtIns.nothingType
|
||||||
|
|
||||||
eqeqeq = defineOperator("EQEQEQ", bool, listOf(anyN, anyN))
|
eqeqeq = defineOperator("EQEQEQ", bool, listOf(anyN, anyN))
|
||||||
eqeq = defineOperator("EQEQ", bool, listOf(anyN, anyN))
|
eqeq = defineOperator("EQEQ", bool, listOf(anyN, anyN))
|
||||||
@@ -41,6 +54,13 @@ class IrBuiltIns(val builtIns: KotlinBuiltIns) {
|
|||||||
lteq0 = defineOperator("LTEQ0", bool, listOf(int))
|
lteq0 = defineOperator("LTEQ0", bool, listOf(int))
|
||||||
gt0 = defineOperator("GT0", bool, listOf(int))
|
gt0 = defineOperator("GT0", bool, listOf(int))
|
||||||
gteq0 = defineOperator("GTEQ0", bool, listOf(int))
|
gteq0 = defineOperator("GTEQ0", bool, listOf(int))
|
||||||
|
notNull = defineOperator("NOT_NULL", bool, listOf(anyN))
|
||||||
|
throwNpe = defineOperator("THROW_NPE", nothing, listOf())
|
||||||
|
|
||||||
|
implicitNotNull = defineOperator("IMPLICIT_NOT_NULL", any, listOf(anyN))
|
||||||
|
|
||||||
|
// booleanNot = builtIns.boolean.findSingleFunction("not") // TODO requires receiver
|
||||||
|
booleanNot = defineOperator("NOT", bool, listOf(bool))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun defineOperator(name: String, returnType: KotlinType, valueParameterTypes: List<KotlinType>): IrBuiltinOperatorDescriptor {
|
private fun defineOperator(name: String, returnType: KotlinType, valueParameterTypes: List<KotlinType>): IrBuiltinOperatorDescriptor {
|
||||||
@@ -51,4 +71,9 @@ class IrBuiltIns(val builtIns: KotlinBuiltIns) {
|
|||||||
}
|
}
|
||||||
return operatorDescriptor
|
return operatorDescriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun ClassDescriptor.findSingleFunction(name: String): FunctionDescriptor =
|
||||||
|
getMemberScope(TypeSubstitution.EMPTY).getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BUILTINS).single()
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -22,24 +22,24 @@ import org.jetbrains.kotlin.types.KotlinType
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
interface IrBlockExpression : IrExpression {
|
interface IrBlock : IrExpression {
|
||||||
val hasResult: Boolean
|
val hasResult: Boolean
|
||||||
val operator: IrOperator?
|
val operator: IrOperator?
|
||||||
|
|
||||||
val statements: List<IrStatement>
|
val statements: List<IrStatement>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun IrBlockExpressionImpl.addIfNotNull(statement: IrStatement?) {
|
fun IrBlockImpl.addIfNotNull(statement: IrStatement?) {
|
||||||
if (statement != null) addStatement(statement)
|
if (statement != null) addStatement(statement)
|
||||||
}
|
}
|
||||||
|
|
||||||
class IrBlockExpressionImpl(
|
class IrBlockImpl(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
type: KotlinType?,
|
type: KotlinType?,
|
||||||
override val hasResult: Boolean,
|
override val hasResult: Boolean,
|
||||||
override val operator: IrOperator? = null
|
override val operator: IrOperator? = null
|
||||||
) : IrExpressionBase(startOffset, endOffset, type), IrBlockExpression {
|
) : IrExpressionBase(startOffset, endOffset, type), IrBlock {
|
||||||
override val statements: MutableList<IrStatement> = ArrayList()
|
override val statements: MutableList<IrStatement> = ArrayList()
|
||||||
|
|
||||||
fun addStatement(statement: IrStatement) {
|
fun addStatement(statement: IrStatement) {
|
||||||
@@ -61,7 +61,7 @@ class IrBlockExpressionImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||||
visitor.visitBlockExpression(this, data)
|
visitor.visitBlock(this, data)
|
||||||
|
|
||||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||||
statements.forEach { it.accept(visitor, data) }
|
statements.forEach { it.accept(visitor, data) }
|
||||||
+11
-11
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.ir.*
|
|||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
interface IrCallExpression : IrMemberAccessExpression {
|
interface IrCall : IrMemberAccessExpression {
|
||||||
val superQualifier: ClassDescriptor?
|
val superQualifier: ClassDescriptor?
|
||||||
val operator: IrOperator?
|
val operator: IrOperator?
|
||||||
override val descriptor: CallableDescriptor
|
override val descriptor: CallableDescriptor
|
||||||
@@ -32,7 +32,7 @@ interface IrCallExpression : IrMemberAccessExpression {
|
|||||||
fun removeArgument(index: Int)
|
fun removeArgument(index: Int)
|
||||||
}
|
}
|
||||||
|
|
||||||
class IrCallExpressionImpl(
|
class IrCallImpl(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
type: KotlinType?,
|
type: KotlinType?,
|
||||||
@@ -40,7 +40,7 @@ class IrCallExpressionImpl(
|
|||||||
isSafe: Boolean,
|
isSafe: Boolean,
|
||||||
override val operator: IrOperator? = null,
|
override val operator: IrOperator? = null,
|
||||||
override val superQualifier: ClassDescriptor? = null
|
override val superQualifier: ClassDescriptor? = null
|
||||||
) : IrMemberAccessExpressionBase(startOffset, endOffset, type, isSafe), IrCallExpression {
|
) : IrMemberAccessExpressionBase(startOffset, endOffset, type, isSafe), IrCall {
|
||||||
private val argumentsByParameterIndex =
|
private val argumentsByParameterIndex =
|
||||||
arrayOfNulls<IrExpression>(descriptor.valueParameters.size)
|
arrayOfNulls<IrExpression>(descriptor.valueParameters.size)
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ class IrCallExpressionImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||||
visitor.visitCallExpression(this, data)
|
visitor.visitCall(this, data)
|
||||||
|
|
||||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||||
super.acceptChildren(visitor, data)
|
super.acceptChildren(visitor, data)
|
||||||
@@ -84,7 +84,7 @@ class IrCallExpressionImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class IrPropertyAccessorCallExpressionBase(
|
abstract class IrPropertyAccessorCallBase(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
type: KotlinType?,
|
type: KotlinType?,
|
||||||
@@ -92,13 +92,13 @@ abstract class IrPropertyAccessorCallExpressionBase(
|
|||||||
isSafe: Boolean,
|
isSafe: Boolean,
|
||||||
override val operator: IrOperator? = null,
|
override val operator: IrOperator? = null,
|
||||||
override val superQualifier: ClassDescriptor? = null
|
override val superQualifier: ClassDescriptor? = null
|
||||||
) : IrMemberAccessExpressionBase(startOffset, endOffset, type, isSafe), IrCallExpression {
|
) : IrMemberAccessExpressionBase(startOffset, endOffset, type, isSafe), IrCall {
|
||||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||||
return visitor.visitCallExpression(this, data)
|
return visitor.visitCall(this, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class IrGetterCallExpressionImpl(
|
class IrGetterCallImpl(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
type: KotlinType?,
|
type: KotlinType?,
|
||||||
@@ -106,7 +106,7 @@ class IrGetterCallExpressionImpl(
|
|||||||
isSafe: Boolean,
|
isSafe: Boolean,
|
||||||
operator: IrOperator? = null,
|
operator: IrOperator? = null,
|
||||||
superQualifier: ClassDescriptor? = null
|
superQualifier: ClassDescriptor? = null
|
||||||
) : IrPropertyAccessorCallExpressionBase(startOffset, endOffset, type, descriptor, isSafe, operator, superQualifier), IrCallExpression {
|
) : IrPropertyAccessorCallBase(startOffset, endOffset, type, descriptor, isSafe, operator, superQualifier), IrCall {
|
||||||
constructor(
|
constructor(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
@@ -133,7 +133,7 @@ class IrGetterCallExpressionImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class IrSetterCallExpressionImpl(
|
class IrSetterCallImpl(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
type: KotlinType?,
|
type: KotlinType?,
|
||||||
@@ -141,7 +141,7 @@ class IrSetterCallExpressionImpl(
|
|||||||
isSafe: Boolean,
|
isSafe: Boolean,
|
||||||
operator: IrOperator? = null,
|
operator: IrOperator? = null,
|
||||||
superQualifier: ClassDescriptor? = null
|
superQualifier: ClassDescriptor? = null
|
||||||
) : IrPropertyAccessorCallExpressionBase(startOffset, endOffset, type, descriptor, isSafe, operator, superQualifier), IrCallExpression {
|
) : IrPropertyAccessorCallBase(startOffset, endOffset, type, descriptor, isSafe, operator, superQualifier), IrCall {
|
||||||
constructor(
|
constructor(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
+15
-15
@@ -19,15 +19,15 @@ package org.jetbrains.kotlin.ir.expressions
|
|||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
interface IrConstExpression<out T> : IrExpression {
|
interface IrConst<out T> : IrExpression {
|
||||||
val kind: IrLiteralKind<T>
|
val kind: IrLiteralKind<T>
|
||||||
val value: T
|
val value: T
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class IrLiteralKind<out T>(val asString: kotlin.String) {
|
sealed class IrLiteralKind<out T>(val asString: kotlin.String) {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
fun valueOf(aConst: IrConstExpression<*>) =
|
fun valueOf(aConst: IrConst<*>) =
|
||||||
(aConst as IrConstExpression<T>).value
|
(aConst as IrConst<T>).value
|
||||||
|
|
||||||
object Null : IrLiteralKind<Nothing?>("Null")
|
object Null : IrLiteralKind<Nothing?>("Null")
|
||||||
object Boolean : IrLiteralKind<kotlin.Boolean>("Boolean")
|
object Boolean : IrLiteralKind<kotlin.Boolean>("Boolean")
|
||||||
@@ -42,33 +42,33 @@ sealed class IrLiteralKind<out T>(val asString: kotlin.String) {
|
|||||||
override fun toString() = asString
|
override fun toString() = asString
|
||||||
}
|
}
|
||||||
|
|
||||||
class IrConstExpressionImpl<out T> (
|
class IrConstImpl<out T> (
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
type: KotlinType?,
|
type: KotlinType?,
|
||||||
override val kind: IrLiteralKind<T>,
|
override val kind: IrLiteralKind<T>,
|
||||||
override val value: T
|
override val value: T
|
||||||
) : IrTerminalExpressionBase(startOffset, endOffset, type), IrConstExpression<T> {
|
) : IrTerminalExpressionBase(startOffset, endOffset, type), IrConst<T> {
|
||||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||||
visitor.visitConst(this, data)
|
visitor.visitConst(this, data)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun string(startOffset: Int, endOffset: Int, type: KotlinType, value: String): IrConstExpressionImpl<String> =
|
fun string(startOffset: Int, endOffset: Int, type: KotlinType, value: String): IrConstImpl<String> =
|
||||||
IrConstExpressionImpl(startOffset, endOffset, type, IrLiteralKind.String, value)
|
IrConstImpl(startOffset, endOffset, type, IrLiteralKind.String, value)
|
||||||
|
|
||||||
fun int(startOffset: Int, endOffset: Int, type: KotlinType, value: Int): IrConstExpressionImpl<Int> =
|
fun int(startOffset: Int, endOffset: Int, type: KotlinType, value: Int): IrConstImpl<Int> =
|
||||||
IrConstExpressionImpl(startOffset, endOffset, type, IrLiteralKind.Int, value)
|
IrConstImpl(startOffset, endOffset, type, IrLiteralKind.Int, value)
|
||||||
|
|
||||||
fun constNull(startOffset: Int, endOffset: Int, type: KotlinType): IrConstExpressionImpl<Nothing?> =
|
fun constNull(startOffset: Int, endOffset: Int, type: KotlinType): IrConstImpl<Nothing?> =
|
||||||
IrConstExpressionImpl(startOffset, endOffset, type, IrLiteralKind.Null, null)
|
IrConstImpl(startOffset, endOffset, type, IrLiteralKind.Null, null)
|
||||||
|
|
||||||
fun boolean(startOffset: Int, endOffset: Int, type: KotlinType, value: Boolean): IrConstExpressionImpl<Boolean> =
|
fun boolean(startOffset: Int, endOffset: Int, type: KotlinType, value: Boolean): IrConstImpl<Boolean> =
|
||||||
IrConstExpressionImpl(startOffset, endOffset, type, IrLiteralKind.Boolean, value)
|
IrConstImpl(startOffset, endOffset, type, IrLiteralKind.Boolean, value)
|
||||||
|
|
||||||
fun constTrue(startOffset: Int, endOffset: Int, type: KotlinType): IrConstExpressionImpl<Boolean> =
|
fun constTrue(startOffset: Int, endOffset: Int, type: KotlinType): IrConstImpl<Boolean> =
|
||||||
boolean(startOffset, endOffset, type, true)
|
boolean(startOffset, endOffset, type, true)
|
||||||
|
|
||||||
fun constFalse(startOffset: Int, endOffset: Int, type: KotlinType): IrConstExpressionImpl<Boolean> =
|
fun constFalse(startOffset: Int, endOffset: Int, type: KotlinType): IrConstImpl<Boolean> =
|
||||||
boolean(startOffset, endOffset, type, false)
|
boolean(startOffset, endOffset, type, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+7
-7
@@ -28,13 +28,13 @@ interface IrDeclarationReference : IrExpression {
|
|||||||
val descriptor: DeclarationDescriptor
|
val descriptor: DeclarationDescriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IrGetSingletonValueExpression : IrDeclarationReference {
|
interface IrGetSingletonValue : IrDeclarationReference {
|
||||||
override val descriptor: ClassDescriptor
|
override val descriptor: ClassDescriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IrGetObjectValueExpression : IrGetSingletonValueExpression
|
interface IrGetObjectValue : IrGetSingletonValue
|
||||||
|
|
||||||
interface IrGetEnumValueExpression : IrGetSingletonValueExpression
|
interface IrGetEnumValue : IrGetSingletonValue
|
||||||
|
|
||||||
abstract class IrDeclarationReferenceBase<out D : DeclarationDescriptor>(
|
abstract class IrDeclarationReferenceBase<out D : DeclarationDescriptor>(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
@@ -60,22 +60,22 @@ abstract class IrTerminalDeclarationReferenceBase<out D : DeclarationDescriptor>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class IrGetObjectValueExpressionImpl(
|
class IrGetObjectValueImpl(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
type: KotlinType?,
|
type: KotlinType?,
|
||||||
descriptor: ClassDescriptor
|
descriptor: ClassDescriptor
|
||||||
) : IrTerminalDeclarationReferenceBase<ClassDescriptor>(startOffset, endOffset, type, descriptor), IrGetObjectValueExpression {
|
) : IrTerminalDeclarationReferenceBase<ClassDescriptor>(startOffset, endOffset, type, descriptor), IrGetObjectValue {
|
||||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||||
visitor.visitGetObjectValue(this, data)
|
visitor.visitGetObjectValue(this, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
class IrGetEnumValueExpressionImpl(
|
class IrGetEnumValueImpl(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
type: KotlinType?,
|
type: KotlinType?,
|
||||||
descriptor: ClassDescriptor
|
descriptor: ClassDescriptor
|
||||||
) : IrTerminalDeclarationReferenceBase<ClassDescriptor>(startOffset, endOffset, type, descriptor), IrGetEnumValueExpression {
|
) : IrTerminalDeclarationReferenceBase<ClassDescriptor>(startOffset, endOffset, type, descriptor), IrGetEnumValue {
|
||||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||||
return visitor.visitGetEnumValue(this, data)
|
return visitor.visitGetEnumValue(this, data)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -20,16 +20,16 @@ import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
|||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
interface IrGetExtensionReceiverExpression : IrDeclarationReference {
|
interface IrGetExtensionReceiver : IrDeclarationReference {
|
||||||
override val descriptor: ReceiverParameterDescriptor
|
override val descriptor: ReceiverParameterDescriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
class IrGetExtensionReceiverExpressionImpl(
|
class IrGetExtensionReceiverImpl(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
type: KotlinType?,
|
type: KotlinType?,
|
||||||
descriptor: ReceiverParameterDescriptor
|
descriptor: ReceiverParameterDescriptor
|
||||||
) : IrTerminalDeclarationReferenceBase<ReceiverParameterDescriptor>(startOffset, endOffset, type, descriptor), IrGetExtensionReceiverExpression {
|
) : IrTerminalDeclarationReferenceBase<ReceiverParameterDescriptor>(startOffset, endOffset, type, descriptor), IrGetExtensionReceiver {
|
||||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||||
visitor.visitGetExtensionReceiver(this, data)
|
visitor.visitGetExtensionReceiver(this, data)
|
||||||
}
|
}
|
||||||
+20
-13
@@ -23,19 +23,19 @@ import org.jetbrains.kotlin.types.KotlinType
|
|||||||
import org.jetbrains.kotlin.utils.SmartList
|
import org.jetbrains.kotlin.utils.SmartList
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
interface IrIfExpression : IrExpression {
|
interface IrIfThenElse : IrExpression {
|
||||||
val operator: IrOperator?
|
val operator: IrOperator?
|
||||||
var condition: IrExpression
|
var condition: IrExpression
|
||||||
var thenBranch: IrExpression
|
var thenBranch: IrExpression
|
||||||
var elseBranch: IrExpression?
|
var elseBranch: IrExpression?
|
||||||
}
|
}
|
||||||
|
|
||||||
class IrIfExpressionImpl(
|
class IrIfThenElseImpl(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
type: KotlinType?,
|
type: KotlinType?,
|
||||||
override val operator: IrOperator? = null
|
override val operator: IrOperator? = null
|
||||||
) : IrExpressionBase(startOffset, endOffset, type), IrIfExpression {
|
) : IrExpressionBase(startOffset, endOffset, type), IrIfThenElse {
|
||||||
constructor(
|
constructor(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
@@ -109,18 +109,25 @@ class IrIfExpressionImpl(
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
// a || b == if (a) true else b
|
// a || b == if (a) true else b
|
||||||
fun oror(a: IrExpression, b: IrExpression, operator: IrOperator = IrOperator.OROR): IrIfExpression =
|
fun oror(startOffset: Int, endOffset: Int, a: IrExpression, b: IrExpression, operator: IrOperator = IrOperator.OROR): IrIfThenElse =
|
||||||
IrIfExpressionImpl(b.startOffset, b.endOffset, b.type!!,
|
IrIfThenElseImpl(startOffset, endOffset, b.type!!,
|
||||||
a, IrConstExpressionImpl.constTrue(b.startOffset, b.endOffset, b.type!!), b,
|
a, IrConstImpl.constTrue(b.startOffset, b.endOffset, b.type!!), b,
|
||||||
operator)
|
operator)
|
||||||
|
|
||||||
|
fun oror(a: IrExpression, b: IrExpression, operator: IrOperator = IrOperator.OROR): IrIfThenElse =
|
||||||
|
oror(b.startOffset, b.endOffset, a, b, operator)
|
||||||
|
|
||||||
|
fun whenComma(a: IrExpression, b: IrExpression): IrIfThenElse =
|
||||||
|
oror(a, b, IrOperator.WHEN_COMMA)
|
||||||
|
|
||||||
// a && b == if (a) b else false
|
// a && b == if (a) b else false
|
||||||
fun andand(a: IrExpression, b: IrExpression): IrIfExpression =
|
fun andand(startOffset: Int, endOffset: Int, a: IrExpression, b: IrExpression, operator: IrOperator = IrOperator.ANDAND): IrIfThenElse =
|
||||||
IrIfExpressionImpl(b.startOffset, b.endOffset, b.type!!,
|
IrIfThenElseImpl(startOffset, endOffset, b.type!!,
|
||||||
a, b, IrConstExpressionImpl.constFalse(b.startOffset, b.endOffset, b.type!!),
|
a, b, IrConstImpl.constFalse(b.startOffset, b.endOffset, b.type!!),
|
||||||
IrOperator.OROR)
|
operator)
|
||||||
|
|
||||||
|
fun andand(a: IrExpression, b: IrExpression, operator: IrOperator = IrOperator.ANDAND): IrIfThenElse =
|
||||||
|
andand(b.startOffset, b.endOffset, a, b, operator)
|
||||||
|
|
||||||
fun whenComma(a: IrExpression, b: IrExpression): IrIfExpression =
|
|
||||||
oror(a, b, IrOperator.WHEN_COMMA)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+12
-12
@@ -19,22 +19,22 @@ package org.jetbrains.kotlin.ir.expressions
|
|||||||
import org.jetbrains.kotlin.ir.*
|
import org.jetbrains.kotlin.ir.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
|
|
||||||
interface IrLoopExpression : IrExpression {
|
interface IrLoop : IrExpression {
|
||||||
var body: IrExpression
|
var body: IrExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IrConditionalLoopExpression : IrLoopExpression {
|
interface IrConditionalLoop : IrLoop {
|
||||||
var condition: IrExpression
|
var condition: IrExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IrWhileLoopExpression : IrConditionalLoopExpression
|
interface IrWhileLoop : IrConditionalLoop
|
||||||
|
|
||||||
interface IrDoWhileLoopExpression : IrConditionalLoopExpression
|
interface IrDoWhileLoop : IrConditionalLoop
|
||||||
|
|
||||||
abstract class IrLoopExpressionBase(
|
abstract class IrLoopBase(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int
|
endOffset: Int
|
||||||
) : IrExpressionBase(startOffset, endOffset, null), IrLoopExpression {
|
) : IrExpressionBase(startOffset, endOffset, null), IrLoop {
|
||||||
|
|
||||||
|
|
||||||
private var bodyImpl: IrExpression? = null
|
private var bodyImpl: IrExpression? = null
|
||||||
@@ -60,10 +60,10 @@ abstract class IrLoopExpressionBase(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class IrConditionalLoopExpressionBase(
|
abstract class IrConditionalLoopBase(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int
|
endOffset: Int
|
||||||
) : IrLoopExpressionBase(startOffset, endOffset), IrConditionalLoopExpression {
|
) : IrLoopBase(startOffset, endOffset), IrConditionalLoop {
|
||||||
private var conditionImpl: IrExpression? = null
|
private var conditionImpl: IrExpression? = null
|
||||||
override var condition: IrExpression
|
override var condition: IrExpression
|
||||||
get() = conditionImpl!!
|
get() = conditionImpl!!
|
||||||
@@ -88,10 +88,10 @@ abstract class IrConditionalLoopExpressionBase(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class IrWhileLoopExpressionImpl(
|
class IrWhileLoopImpl(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int
|
endOffset: Int
|
||||||
) : IrConditionalLoopExpressionBase(startOffset, endOffset), IrWhileLoopExpression {
|
) : IrConditionalLoopBase(startOffset, endOffset), IrWhileLoop {
|
||||||
constructor(
|
constructor(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
@@ -112,10 +112,10 @@ class IrWhileLoopExpressionImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class IrDoWhileLoopExpressionImpl(
|
class IrDoWhileLoopImpl(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int
|
endOffset: Int
|
||||||
) : IrConditionalLoopExpressionBase(startOffset, endOffset), IrDoWhileLoopExpression {
|
) : IrConditionalLoopBase(startOffset, endOffset), IrDoWhileLoop {
|
||||||
constructor(
|
constructor(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
+65
-39
@@ -17,46 +17,78 @@
|
|||||||
package org.jetbrains.kotlin.ir.expressions
|
package org.jetbrains.kotlin.ir.expressions
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.ir.*
|
import org.jetbrains.kotlin.ir.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
interface IrOperatorExpression : IrExpression {
|
abstract class IrOperatorCallBase(
|
||||||
val operator: IrOperator
|
|
||||||
val relatedDescriptor: CallableDescriptor?
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IrUnaryOperatorExpression : IrOperatorExpression {
|
|
||||||
override val operator: IrOperator
|
|
||||||
var argument: IrExpression
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IrBinaryOperatorExpression : IrOperatorExpression {
|
|
||||||
override val operator: IrOperator
|
|
||||||
var argument0: IrExpression
|
|
||||||
var argument1: IrExpression
|
|
||||||
}
|
|
||||||
|
|
||||||
class IrUnaryOperatorExpressionImpl(
|
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
type: KotlinType?,
|
|
||||||
override val operator: IrOperator,
|
override val operator: IrOperator,
|
||||||
override val relatedDescriptor: CallableDescriptor?
|
override val descriptor: CallableDescriptor
|
||||||
) : IrExpressionBase(startOffset, endOffset, type), IrUnaryOperatorExpression {
|
) : IrExpressionBase(startOffset, endOffset, descriptor.returnType), IrCall {
|
||||||
|
override val superQualifier: ClassDescriptor? get() = null
|
||||||
|
override var dispatchReceiver: IrExpression?
|
||||||
|
get() = null
|
||||||
|
set(value) = throw UnsupportedOperationException("Operator call expression can't have a receiver")
|
||||||
|
|
||||||
|
override val isSafe: Boolean get() = false
|
||||||
|
|
||||||
|
override var extensionReceiver: IrExpression?
|
||||||
|
get() = null
|
||||||
|
set(value) = throw UnsupportedOperationException("Operator call expression can't have a receiver")
|
||||||
|
|
||||||
|
override fun getArgument(index: Int): IrExpression? = getChild(index)?.assertCast()
|
||||||
|
|
||||||
|
override fun putArgument(index: Int, valueArgument: IrExpression?) {
|
||||||
|
replaceChild(index, valueArgument ?: throw AssertionError("Operator call expression can't have a default argument"))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun removeArgument(index: Int) {
|
||||||
|
throw AssertionError("Operator call expression can't have a default argument")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||||
|
return visitor.visitCall(this, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IrNullaryOperatorImpl constructor(
|
||||||
|
startOffset: Int,
|
||||||
|
endOffset: Int,
|
||||||
|
operator: IrOperator,
|
||||||
|
descriptor: CallableDescriptor
|
||||||
|
) : IrOperatorCallBase(startOffset, endOffset, operator, descriptor) {
|
||||||
|
override fun getChild(slot: Int): IrElement? = null
|
||||||
|
|
||||||
|
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||||
|
// no children
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||||
|
// no children
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IrUnaryOperatorImpl private constructor(
|
||||||
|
startOffset: Int,
|
||||||
|
endOffset: Int,
|
||||||
|
operator: IrOperator,
|
||||||
|
descriptor: CallableDescriptor
|
||||||
|
) : IrOperatorCallBase(startOffset, endOffset, operator, descriptor) {
|
||||||
constructor(
|
constructor(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
type: KotlinType?,
|
|
||||||
operator: IrOperator,
|
operator: IrOperator,
|
||||||
relatedDescriptor: CallableDescriptor?,
|
descriptor: CallableDescriptor,
|
||||||
argument: IrExpression
|
argument: IrExpression
|
||||||
) : this(startOffset, endOffset, type, operator, relatedDescriptor) {
|
) : this(startOffset, endOffset, operator, descriptor) {
|
||||||
this.argument = argument
|
this.argument = argument
|
||||||
}
|
}
|
||||||
|
|
||||||
private var argumentImpl: IrExpression? = null
|
private var argumentImpl: IrExpression? = null
|
||||||
override var argument: IrExpression
|
var argument: IrExpression
|
||||||
get() = argumentImpl!!
|
get() = argumentImpl!!
|
||||||
set(value) {
|
set(value) {
|
||||||
value.assertDetached()
|
value.assertDetached()
|
||||||
@@ -78,37 +110,31 @@ class IrUnaryOperatorExpressionImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
|
||||||
return visitor.visitUnaryOperator(this, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||||
argument.accept(visitor, data)
|
argument.accept(visitor, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class IrBinaryOperatorExpressionImpl(
|
class IrBinaryOperatorImpl(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
type: KotlinType?,
|
operator: IrOperator,
|
||||||
override val operator: IrOperator,
|
descriptor: CallableDescriptor
|
||||||
override val relatedDescriptor: CallableDescriptor?
|
) : IrOperatorCallBase(startOffset, endOffset, operator, descriptor) {
|
||||||
) : IrExpressionBase(startOffset, endOffset, type), IrBinaryOperatorExpression {
|
|
||||||
constructor(
|
constructor(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
type: KotlinType?,
|
|
||||||
operator: IrOperator,
|
operator: IrOperator,
|
||||||
relatedDescriptor: CallableDescriptor?,
|
descriptor: CallableDescriptor,
|
||||||
argument0: IrExpression,
|
argument0: IrExpression,
|
||||||
argument1: IrExpression
|
argument1: IrExpression
|
||||||
) : this(startOffset, endOffset, type, operator, relatedDescriptor) {
|
) : this(startOffset, endOffset, operator, descriptor) {
|
||||||
this.argument0 = argument0
|
this.argument0 = argument0
|
||||||
this.argument1 = argument1
|
this.argument1 = argument1
|
||||||
}
|
}
|
||||||
|
|
||||||
private var argument0Impl: IrExpression? = null
|
private var argument0Impl: IrExpression? = null
|
||||||
override var argument0: IrExpression
|
var argument0: IrExpression
|
||||||
get() = argument0Impl!!
|
get() = argument0Impl!!
|
||||||
set(value) {
|
set(value) {
|
||||||
value.assertDetached()
|
value.assertDetached()
|
||||||
@@ -118,7 +144,7 @@ class IrBinaryOperatorExpressionImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var argument1Impl: IrExpression? = null
|
private var argument1Impl: IrExpression? = null
|
||||||
override var argument1: IrExpression
|
var argument1: IrExpression
|
||||||
get() = argument1Impl!!
|
get() = argument1Impl!!
|
||||||
set(value) {
|
set(value) {
|
||||||
value.assertDetached()
|
value.assertDetached()
|
||||||
@@ -143,7 +169,7 @@ class IrBinaryOperatorExpressionImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||||
visitor.visitBinaryOperator(this, data)
|
visitor.visitCall(this, data)
|
||||||
|
|
||||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||||
argument0.accept(visitor, data)
|
argument0.accept(visitor, data)
|
||||||
|
|||||||
+4
-4
@@ -22,16 +22,16 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
|||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
|
|
||||||
interface IrReturnExpression : IrExpression {
|
interface IrReturn : IrExpression {
|
||||||
var value: IrExpression?
|
var value: IrExpression?
|
||||||
val returnTarget: CallableDescriptor
|
val returnTarget: CallableDescriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
class IrReturnExpressionImpl(
|
class IrReturnImpl(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
override val returnTarget: CallableDescriptor
|
override val returnTarget: CallableDescriptor
|
||||||
) : IrExpressionBase(startOffset, endOffset, null), IrReturnExpression {
|
) : IrExpressionBase(startOffset, endOffset, null), IrReturn {
|
||||||
constructor(
|
constructor(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
@@ -63,7 +63,7 @@ class IrReturnExpressionImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||||
visitor.visitReturnExpression(this, data)
|
visitor.visitReturn(this, data)
|
||||||
|
|
||||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||||
value?.accept(visitor, data)
|
value?.accept(visitor, data)
|
||||||
+3
-3
@@ -21,16 +21,16 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
|||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
interface IrStringConcatenationExpression : IrExpression {
|
interface IrStringConcatenation : IrExpression {
|
||||||
val arguments: List<IrExpression>
|
val arguments: List<IrExpression>
|
||||||
fun addArgument(argument: IrExpression)
|
fun addArgument(argument: IrExpression)
|
||||||
}
|
}
|
||||||
|
|
||||||
class IrStringConcatenationExpressionImpl(
|
class IrStringConcatenationImpl(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
type: KotlinType?
|
type: KotlinType?
|
||||||
) : IrExpressionBase(startOffset, endOffset, type), IrStringConcatenationExpression {
|
) : IrExpressionBase(startOffset, endOffset, type), IrStringConcatenation {
|
||||||
override val arguments: MutableList<IrExpression> = ArrayList()
|
override val arguments: MutableList<IrExpression> = ArrayList()
|
||||||
|
|
||||||
override fun addArgument(argument: IrExpression) {
|
override fun addArgument(argument: IrExpression) {
|
||||||
+4
-4
@@ -20,16 +20,16 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
interface IrThisExpression : IrExpression {
|
interface IrThisReference : IrExpression {
|
||||||
val classDescriptor: ClassDescriptor
|
val classDescriptor: ClassDescriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
class IrThisExpressionImpl(
|
class IrThisReferenceImpl(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
type: KotlinType?,
|
type: KotlinType?,
|
||||||
override val classDescriptor: ClassDescriptor
|
override val classDescriptor: ClassDescriptor
|
||||||
) : IrTerminalExpressionBase(startOffset, endOffset, type), IrThisExpression {
|
) : IrTerminalExpressionBase(startOffset, endOffset, type), IrThisReference {
|
||||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||||
visitor.visitThisExpression(this, data)
|
visitor.visitThisReference(this, data)
|
||||||
}
|
}
|
||||||
+4
-4
@@ -28,19 +28,19 @@ enum class IrTypeOperator {
|
|||||||
NOT_INSTANCEOF;
|
NOT_INSTANCEOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IrTypeOperatorExpression : IrExpression {
|
interface IrTypeOperatorCall : IrExpression {
|
||||||
val operator: IrTypeOperator
|
val operator: IrTypeOperator
|
||||||
var argument: IrExpression
|
var argument: IrExpression
|
||||||
val typeOperand: KotlinType
|
val typeOperand: KotlinType
|
||||||
}
|
}
|
||||||
|
|
||||||
class IrTypeOperatorExpressionImpl(
|
class IrTypeOperatorCallImpl(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
type: KotlinType?,
|
type: KotlinType?,
|
||||||
override val operator: IrTypeOperator,
|
override val operator: IrTypeOperator,
|
||||||
override val typeOperand: KotlinType
|
override val typeOperand: KotlinType
|
||||||
) : IrExpressionBase(startOffset, endOffset, type), IrTypeOperatorExpression {
|
) : IrExpressionBase(startOffset, endOffset, type), IrTypeOperatorCall {
|
||||||
constructor(
|
constructor(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
@@ -76,7 +76,7 @@ class IrTypeOperatorExpressionImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||||
visitor.visitTypeOperatorExpression(this, data)
|
visitor.visitTypeOperator(this, data)
|
||||||
|
|
||||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||||
argument.accept(visitor, data)
|
argument.accept(visitor, data)
|
||||||
+6
-6
@@ -26,29 +26,29 @@ interface IrVariableAccessExpression : IrDeclarationReference {
|
|||||||
val operator: IrOperator?
|
val operator: IrOperator?
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IrGetVariableExpression : IrVariableAccessExpression
|
interface IrGetVariable : IrVariableAccessExpression
|
||||||
|
|
||||||
interface IrSetVariableExpression : IrVariableAccessExpression {
|
interface IrSetVariable : IrVariableAccessExpression {
|
||||||
val value: IrExpression
|
val value: IrExpression
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class IrGetVariableExpressionImpl(
|
class IrGetVariableImpl(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
descriptor: VariableDescriptor,
|
descriptor: VariableDescriptor,
|
||||||
override val operator: IrOperator? = null
|
override val operator: IrOperator? = null
|
||||||
) : IrTerminalDeclarationReferenceBase<VariableDescriptor>(startOffset, endOffset, descriptor.type, descriptor), IrGetVariableExpression {
|
) : IrTerminalDeclarationReferenceBase<VariableDescriptor>(startOffset, endOffset, descriptor.type, descriptor), IrGetVariable {
|
||||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||||
visitor.visitGetVariable(this, data)
|
visitor.visitGetVariable(this, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
class IrSetVariableExpressionImpl(
|
class IrSetVariableImpl(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
override val descriptor: VariableDescriptor,
|
override val descriptor: VariableDescriptor,
|
||||||
override val operator: IrOperator?
|
override val operator: IrOperator?
|
||||||
) : IrExpressionBase(startOffset, endOffset, null), IrSetVariableExpression {
|
) : IrExpressionBase(startOffset, endOffset, null), IrSetVariable {
|
||||||
constructor(
|
constructor(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ package org.jetbrains.kotlin.ir.util
|
|||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.SourceLocationManager
|
import org.jetbrains.kotlin.ir.SourceLocationManager
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrCallExpression
|
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrIfExpression
|
import org.jetbrains.kotlin.ir.expressions.IrIfThenElse
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
import org.jetbrains.kotlin.utils.Printer
|
import org.jetbrains.kotlin.utils.Printer
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ class DumpIrTreeVisitor(out: Appendable): IrElementVisitor<Unit, String> {
|
|||||||
element.dumpLabeledSubTree(data)
|
element.dumpLabeledSubTree(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitCallExpression(expression: IrCallExpression, data: String) {
|
override fun visitCall(expression: IrCall, data: String) {
|
||||||
expression.dumpLabeledElementWith(data) {
|
expression.dumpLabeledElementWith(data) {
|
||||||
expression.dispatchReceiver?.accept(this, "\$this")
|
expression.dispatchReceiver?.accept(this, "\$this")
|
||||||
expression.extensionReceiver?.accept(this, "\$receiver")
|
expression.extensionReceiver?.accept(this, "\$receiver")
|
||||||
@@ -54,7 +54,7 @@ class DumpIrTreeVisitor(out: Appendable): IrElementVisitor<Unit, String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitIf(expression: IrIfExpression, data: String) {
|
override fun visitIf(expression: IrIfThenElse, data: String) {
|
||||||
expression.dumpLabeledElementWith(data) {
|
expression.dumpLabeledElementWith(data) {
|
||||||
expression.condition.accept(this, "if")
|
expression.condition.accept(this, "if")
|
||||||
expression.thenBranch.accept(this, "then")
|
expression.thenBranch.accept(this, "then")
|
||||||
|
|||||||
@@ -60,54 +60,44 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
|
|||||||
override fun visitExpression(expression: IrExpression, data: Nothing?): String =
|
override fun visitExpression(expression: IrExpression, data: Nothing?): String =
|
||||||
"? ${expression.javaClass.simpleName} type=${expression.renderType()}"
|
"? ${expression.javaClass.simpleName} type=${expression.renderType()}"
|
||||||
|
|
||||||
override fun <T> visitConst(expression: IrConstExpression<T>, data: Nothing?): String =
|
override fun <T> visitConst(expression: IrConst<T>, data: Nothing?): String =
|
||||||
"LITERAL ${expression.kind} type=${expression.renderType()} value='${expression.value}'"
|
"LITERAL ${expression.kind} type=${expression.renderType()} value='${expression.value}'"
|
||||||
|
|
||||||
override fun visitBlockExpression(expression: IrBlockExpression, data: Nothing?): String =
|
override fun visitBlock(expression: IrBlock, data: Nothing?): String =
|
||||||
"BLOCK type=${expression.renderType()} hasResult=${expression.hasResult} operator=${expression.operator}"
|
"BLOCK type=${expression.renderType()} hasResult=${expression.hasResult} operator=${expression.operator}"
|
||||||
|
|
||||||
override fun visitReturnExpression(expression: IrReturnExpression, data: Nothing?): String =
|
override fun visitReturn(expression: IrReturn, data: Nothing?): String =
|
||||||
"RETURN type=${expression.renderType()}"
|
"RETURN type=${expression.renderType()}"
|
||||||
|
|
||||||
override fun visitGetExtensionReceiver(expression: IrGetExtensionReceiverExpression, data: Nothing?): String =
|
override fun visitGetExtensionReceiver(expression: IrGetExtensionReceiver, data: Nothing?): String =
|
||||||
"\$RECEIVER of: ${expression.descriptor.containingDeclaration.name} type=${expression.renderType()}"
|
"\$RECEIVER of: ${expression.descriptor.containingDeclaration.name} type=${expression.renderType()}"
|
||||||
|
|
||||||
override fun visitThisExpression(expression: IrThisExpression, data: Nothing?): String =
|
override fun visitThisReference(expression: IrThisReference, data: Nothing?): String =
|
||||||
"THIS ${expression.classDescriptor.render()} type=${expression.renderType()}"
|
"THIS ${expression.classDescriptor.render()} type=${expression.renderType()}"
|
||||||
|
|
||||||
override fun visitCallExpression(expression: IrCallExpression, data: Nothing?): String =
|
override fun visitCall(expression: IrCall, data: Nothing?): String =
|
||||||
"CALL ${if (expression.isSafe) "?." else "."}${expression.descriptor.name} " +
|
"CALL ${if (expression.isSafe) "?." else "."}${expression.descriptor.name} " +
|
||||||
"type=${expression.renderType()} operator=${expression.operator}"
|
"type=${expression.renderType()} operator=${expression.operator}"
|
||||||
|
|
||||||
override fun visitGetVariable(expression: IrGetVariableExpression, data: Nothing?): String =
|
override fun visitGetVariable(expression: IrGetVariable, data: Nothing?): String =
|
||||||
"GET_VAR ${expression.descriptor.name} type=${expression.renderType()} operator=${expression.operator}"
|
"GET_VAR ${expression.descriptor.name} type=${expression.renderType()} operator=${expression.operator}"
|
||||||
|
|
||||||
override fun visitSetVariable(expression: IrSetVariableExpression, data: Nothing?): String =
|
override fun visitSetVariable(expression: IrSetVariable, data: Nothing?): String =
|
||||||
"SET_VAR ${expression.descriptor.name} type=${expression.renderType()} operator=${expression.operator}"
|
"SET_VAR ${expression.descriptor.name} type=${expression.renderType()} operator=${expression.operator}"
|
||||||
|
|
||||||
override fun visitGetObjectValue(expression: IrGetObjectValueExpression, data: Nothing?): String =
|
override fun visitGetObjectValue(expression: IrGetObjectValue, data: Nothing?): String =
|
||||||
"GET_OBJECT ${expression.descriptor.name} type=${expression.renderType()}"
|
"GET_OBJECT ${expression.descriptor.name} type=${expression.renderType()}"
|
||||||
|
|
||||||
override fun visitGetEnumValue(expression: IrGetEnumValueExpression, data: Nothing?): String =
|
override fun visitGetEnumValue(expression: IrGetEnumValue, data: Nothing?): String =
|
||||||
"GET_ENUM_VALUE ${expression.descriptor.name} type=${expression.renderType()}"
|
"GET_ENUM_VALUE ${expression.descriptor.name} type=${expression.renderType()}"
|
||||||
|
|
||||||
override fun visitUnaryOperator(expression: IrUnaryOperatorExpression, data: Nothing?): String =
|
override fun visitStringConcatenation(expression: IrStringConcatenation, data: Nothing?): String =
|
||||||
"UNARY_OP operator=${expression.operator} " +
|
|
||||||
"type=${expression.renderType()} " +
|
|
||||||
"related=${expression.relatedDescriptor?.render()}"
|
|
||||||
|
|
||||||
override fun visitBinaryOperator(expression: IrBinaryOperatorExpression, data: Nothing?): String =
|
|
||||||
"BINARY_OP operator=${expression.operator} " +
|
|
||||||
"type=${expression.renderType()} " +
|
|
||||||
"related=${expression.relatedDescriptor?.render()}"
|
|
||||||
|
|
||||||
override fun visitStringConcatenation(expression: IrStringConcatenationExpression, data: Nothing?): String =
|
|
||||||
"STRING_CONCATENATION type=${expression.renderType()}"
|
"STRING_CONCATENATION type=${expression.renderType()}"
|
||||||
|
|
||||||
override fun visitTypeOperatorExpression(expression: IrTypeOperatorExpression, data: Nothing?): String =
|
override fun visitTypeOperator(expression: IrTypeOperatorCall, data: Nothing?): String =
|
||||||
"TYPE_OP operator=${expression.operator} typeOperand=${expression.typeOperand.render()}"
|
"TYPE_OP operator=${expression.operator} typeOperand=${expression.typeOperand.render()}"
|
||||||
|
|
||||||
override fun visitIf(expression: IrIfExpression, data: Nothing?): String =
|
override fun visitIf(expression: IrIfThenElse, data: Nothing?): String =
|
||||||
"IF type=${expression.type.render()} operator=${expression.operator}"
|
"IF type=${expression.type.render()} operator=${expression.operator}"
|
||||||
|
|
||||||
override fun visitDummyDeclaration(declaration: IrDummyDeclaration, data: Nothing?): String =
|
override fun visitDummyDeclaration(declaration: IrDummyDeclaration, data: Nothing?): String =
|
||||||
|
|||||||
@@ -39,30 +39,27 @@ interface IrElementVisitor<out R, in D> {
|
|||||||
fun visitExpressionBody(body: IrExpressionBody, data: D): R = visitBody(body, data)
|
fun visitExpressionBody(body: IrExpressionBody, data: D): R = visitBody(body, data)
|
||||||
|
|
||||||
fun visitExpression(expression: IrExpression, data: D): R = visitElement(expression, data)
|
fun visitExpression(expression: IrExpression, data: D): R = visitElement(expression, data)
|
||||||
fun <T> visitConst(expression: IrConstExpression<T>, data: D): R = visitExpression(expression, data)
|
fun <T> visitConst(expression: IrConst<T>, data: D): R = visitExpression(expression, data)
|
||||||
fun visitReturnExpression(expression: IrReturnExpression, data: D): R = visitExpression(expression, data)
|
fun visitReturn(expression: IrReturn, data: D): R = visitExpression(expression, data)
|
||||||
fun visitBlockExpression(expression: IrBlockExpression, data: D): R = visitExpression(expression, data)
|
fun visitBlock(expression: IrBlock, data: D): R = visitExpression(expression, data)
|
||||||
fun visitStringConcatenation(expression: IrStringConcatenationExpression, data: D) = visitExpression(expression, data)
|
fun visitStringConcatenation(expression: IrStringConcatenation, data: D) = visitExpression(expression, data)
|
||||||
fun visitThisExpression(expression: IrThisExpression, data: D) = visitExpression(expression, data)
|
fun visitThisReference(expression: IrThisReference, data: D) = visitExpression(expression, data)
|
||||||
|
|
||||||
fun visitDeclarationReference(expression: IrDeclarationReference, data: D) = visitExpression(expression, data)
|
fun visitDeclarationReference(expression: IrDeclarationReference, data: D) = visitExpression(expression, data)
|
||||||
fun visitSingletonReference(expression: IrGetSingletonValueExpression, data: D) = visitDeclarationReference(expression, data)
|
fun visitSingletonReference(expression: IrGetSingletonValue, data: D) = visitDeclarationReference(expression, data)
|
||||||
fun visitGetObjectValue(expression: IrGetObjectValueExpression, data: D) = visitSingletonReference(expression, data)
|
fun visitGetObjectValue(expression: IrGetObjectValue, data: D) = visitSingletonReference(expression, data)
|
||||||
fun visitGetEnumValue(expression: IrGetEnumValueExpression, data: D) = visitSingletonReference(expression, data)
|
fun visitGetEnumValue(expression: IrGetEnumValue, data: D) = visitSingletonReference(expression, data)
|
||||||
fun visitGetVariable(expression: IrGetVariableExpression, data: D) = visitDeclarationReference(expression, data)
|
fun visitGetVariable(expression: IrGetVariable, data: D) = visitDeclarationReference(expression, data)
|
||||||
fun visitSetVariable(expression: IrSetVariableExpression, data: D) = visitDeclarationReference(expression, data)
|
fun visitSetVariable(expression: IrSetVariable, data: D) = visitDeclarationReference(expression, data)
|
||||||
fun visitGetExtensionReceiver(expression: IrGetExtensionReceiverExpression, data: D) = visitDeclarationReference(expression, data)
|
fun visitGetExtensionReceiver(expression: IrGetExtensionReceiver, data: D) = visitDeclarationReference(expression, data)
|
||||||
fun visitCallExpression(expression: IrCallExpression, data: D) = visitDeclarationReference(expression, data)
|
fun visitCall(expression: IrCall, data: D) = visitDeclarationReference(expression, data)
|
||||||
|
|
||||||
fun visitOperatorExpression(expression: IrOperatorExpression, data: D) = visitExpression(expression, data)
|
fun visitTypeOperator(expression: IrTypeOperatorCall, data: D) = visitExpression(expression, data)
|
||||||
fun visitUnaryOperator(expression: IrUnaryOperatorExpression, data: D) = visitOperatorExpression(expression, data)
|
|
||||||
fun visitBinaryOperator(expression: IrBinaryOperatorExpression, data: D) = visitOperatorExpression(expression, data)
|
|
||||||
fun visitTypeOperatorExpression(expression: IrTypeOperatorExpression, data: D) = visitExpression(expression, data)
|
|
||||||
|
|
||||||
fun visitIf(expression: IrIfExpression, data: D) = visitExpression(expression, data)
|
fun visitIf(expression: IrIfThenElse, data: D) = visitExpression(expression, data)
|
||||||
fun visitLoop(loop: IrLoopExpression, data: D) = visitExpression(loop, data)
|
fun visitLoop(loop: IrLoop, data: D) = visitExpression(loop, data)
|
||||||
fun visitWhileLoop(loop: IrWhileLoopExpression, data: D) = visitLoop(loop, data)
|
fun visitWhileLoop(loop: IrWhileLoop, data: D) = visitLoop(loop, data)
|
||||||
fun visitDoWhileLoop(loop: IrDoWhileLoopExpression, data: D) = visitLoop(loop, data)
|
fun visitDoWhileLoop(loop: IrDoWhileLoop, data: D) = visitLoop(loop, data)
|
||||||
|
|
||||||
// NB Use it only for testing purposes; will be removed as soon as all Kotlin expression types are covered
|
// NB Use it only for testing purposes; will be removed as soon as all Kotlin expression types are covered
|
||||||
fun visitDummyDeclaration(declaration: IrDummyDeclaration, data: D) = visitDeclaration(declaration, data)
|
fun visitDummyDeclaration(declaration: IrDummyDeclaration, data: D) = visitDeclaration(declaration, data)
|
||||||
|
|||||||
+8
-6
@@ -3,16 +3,18 @@ IrFile /booleanOperators.kt
|
|||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=ANDAND type=kotlin.Boolean related=null
|
IF type=kotlin.Boolean operator=ANDAND
|
||||||
GET_VAR a type=kotlin.Boolean operator=null
|
if: GET_VAR a type=kotlin.Boolean operator=null
|
||||||
GET_VAR b type=kotlin.Boolean operator=null
|
then: GET_VAR b type=kotlin.Boolean operator=null
|
||||||
|
else: LITERAL Boolean type=kotlin.Boolean value='false'
|
||||||
IrFunction public fun test2(/*0*/ a: kotlin.Boolean, /*1*/ b: kotlin.Boolean): kotlin.Boolean
|
IrFunction public fun test2(/*0*/ a: kotlin.Boolean, /*1*/ b: kotlin.Boolean): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=OROR type=kotlin.Boolean related=null
|
IF type=kotlin.Boolean operator=OROR
|
||||||
GET_VAR a type=kotlin.Boolean operator=null
|
if: GET_VAR a type=kotlin.Boolean operator=null
|
||||||
GET_VAR b type=kotlin.Boolean operator=null
|
then: LITERAL Boolean type=kotlin.Boolean value='true'
|
||||||
|
else: GET_VAR b type=kotlin.Boolean operator=null
|
||||||
IrFunction public fun test1x(/*0*/ a: kotlin.Boolean, /*1*/ b: kotlin.Boolean): kotlin.Boolean
|
IrFunction public fun test1x(/*0*/ a: kotlin.Boolean, /*1*/ b: kotlin.Boolean): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
|
|||||||
+8
-12
@@ -5,39 +5,35 @@ IrFile /conventionComparisons.kt
|
|||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=GT type=kotlin.Boolean related=null
|
CALL .GT0 type=kotlin.Boolean operator=GT
|
||||||
CALL .compareTo type=kotlin.Int operator=GT
|
arg0: CALL .compareTo type=kotlin.Int operator=GT
|
||||||
$this: $RECEIVER of: test1 type=IB
|
$this: $RECEIVER of: test1 type=IB
|
||||||
$receiver: GET_VAR a1 type=IA operator=null
|
$receiver: GET_VAR a1 type=IA operator=null
|
||||||
other: GET_VAR a2 type=IA operator=null
|
other: GET_VAR a2 type=IA operator=null
|
||||||
LITERAL Int type=kotlin.Int value='0'
|
|
||||||
IrFunction public fun IB.test2(/*0*/ a1: IA, /*1*/ a2: IA): kotlin.Boolean
|
IrFunction public fun IB.test2(/*0*/ a1: IA, /*1*/ a2: IA): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=GTEQ type=kotlin.Boolean related=null
|
CALL .GTEQ0 type=kotlin.Boolean operator=GTEQ
|
||||||
CALL .compareTo type=kotlin.Int operator=GTEQ
|
arg0: CALL .compareTo type=kotlin.Int operator=GTEQ
|
||||||
$this: $RECEIVER of: test2 type=IB
|
$this: $RECEIVER of: test2 type=IB
|
||||||
$receiver: GET_VAR a1 type=IA operator=null
|
$receiver: GET_VAR a1 type=IA operator=null
|
||||||
other: GET_VAR a2 type=IA operator=null
|
other: GET_VAR a2 type=IA operator=null
|
||||||
LITERAL Int type=kotlin.Int value='0'
|
|
||||||
IrFunction public fun IB.test3(/*0*/ a1: IA, /*1*/ a2: IA): kotlin.Boolean
|
IrFunction public fun IB.test3(/*0*/ a1: IA, /*1*/ a2: IA): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=LT type=kotlin.Boolean related=null
|
CALL .LT0 type=kotlin.Boolean operator=LT
|
||||||
CALL .compareTo type=kotlin.Int operator=LT
|
arg0: CALL .compareTo type=kotlin.Int operator=LT
|
||||||
$this: $RECEIVER of: test3 type=IB
|
$this: $RECEIVER of: test3 type=IB
|
||||||
$receiver: GET_VAR a1 type=IA operator=null
|
$receiver: GET_VAR a1 type=IA operator=null
|
||||||
other: GET_VAR a2 type=IA operator=null
|
other: GET_VAR a2 type=IA operator=null
|
||||||
LITERAL Int type=kotlin.Int value='0'
|
|
||||||
IrFunction public fun IB.test4(/*0*/ a1: IA, /*1*/ a2: IA): kotlin.Boolean
|
IrFunction public fun IB.test4(/*0*/ a1: IA, /*1*/ a2: IA): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=LTEQ type=kotlin.Boolean related=null
|
CALL .LTEQ0 type=kotlin.Boolean operator=LTEQ
|
||||||
CALL .compareTo type=kotlin.Int operator=LTEQ
|
arg0: CALL .compareTo type=kotlin.Int operator=LTEQ
|
||||||
$this: $RECEIVER of: test4 type=IB
|
$this: $RECEIVER of: test4 type=IB
|
||||||
$receiver: GET_VAR a1 type=IA operator=null
|
$receiver: GET_VAR a1 type=IA operator=null
|
||||||
other: GET_VAR a2 type=IA operator=null
|
other: GET_VAR a2 type=IA operator=null
|
||||||
LITERAL Int type=kotlin.Int value='0'
|
|
||||||
|
|||||||
+3
-11
@@ -3,16 +3,12 @@ IrFile /elvis.kt
|
|||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=ELVIS type=kotlin.Any related=null
|
DUMMY elvis type=kotlin.Any
|
||||||
GET_VAR a type=kotlin.Any? operator=null
|
|
||||||
GET_VAR b type=kotlin.Any operator=null
|
|
||||||
IrFunction public fun test2(/*0*/ a: kotlin.String?, /*1*/ b: kotlin.Any): kotlin.Any
|
IrFunction public fun test2(/*0*/ a: kotlin.String?, /*1*/ b: kotlin.Any): kotlin.Any
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=ELVIS type=kotlin.Any related=null
|
DUMMY elvis type=kotlin.Any
|
||||||
GET_VAR a type=kotlin.String? operator=null
|
|
||||||
GET_VAR b type=kotlin.Any operator=null
|
|
||||||
IrFunction public fun test3(/*0*/ a: kotlin.Any?, /*1*/ b: kotlin.Any?): kotlin.String
|
IrFunction public fun test3(/*0*/ a: kotlin.Any?, /*1*/ b: kotlin.Any?): kotlin.String
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
@@ -27,8 +23,4 @@ IrFile /elvis.kt
|
|||||||
then: RETURN type=<no-type>
|
then: RETURN type=<no-type>
|
||||||
LITERAL String type=kotlin.String value=''
|
LITERAL String type=kotlin.String value=''
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=ELVIS type=kotlin.String related=null
|
DUMMY elvis type=kotlin.String
|
||||||
TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.String?
|
|
||||||
GET_VAR a type=kotlin.Any? operator=null
|
|
||||||
TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.String
|
|
||||||
GET_VAR b type=kotlin.Any? operator=null
|
|
||||||
|
|||||||
+10
-9
@@ -3,20 +3,21 @@ IrFile /equality.kt
|
|||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=EQEQ type=kotlin.Boolean related=public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
||||||
GET_VAR a type=kotlin.Int operator=null
|
arg0: GET_VAR a type=kotlin.Int operator=null
|
||||||
GET_VAR b type=kotlin.Int operator=null
|
arg1: GET_VAR b type=kotlin.Int operator=null
|
||||||
IrFunction public fun test2(/*0*/ a: kotlin.Int, /*1*/ b: kotlin.Int): kotlin.Boolean
|
IrFunction public fun test2(/*0*/ a: kotlin.Int, /*1*/ b: kotlin.Int): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=EXCLEQ type=kotlin.Boolean related=public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
CALL .NOT type=kotlin.Boolean operator=EXCLEQ
|
||||||
GET_VAR a type=kotlin.Int operator=null
|
arg0: CALL .EQEQ type=kotlin.Boolean operator=EXCLEQ
|
||||||
GET_VAR b type=kotlin.Int operator=null
|
arg0: GET_VAR a type=kotlin.Int operator=null
|
||||||
|
arg1: GET_VAR b type=kotlin.Int operator=null
|
||||||
IrFunction public fun test3(/*0*/ a: kotlin.Any?, /*1*/ b: kotlin.Any?): kotlin.Boolean
|
IrFunction public fun test3(/*0*/ a: kotlin.Any?, /*1*/ b: kotlin.Any?): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=EQEQ type=kotlin.Boolean related=public open operator fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
||||||
GET_VAR a type=kotlin.Any? operator=null
|
arg0: GET_VAR a type=kotlin.Any? operator=null
|
||||||
GET_VAR b type=kotlin.Any? operator=null
|
arg1: GET_VAR b type=kotlin.Any? operator=null
|
||||||
|
|||||||
+10
-9
@@ -3,20 +3,21 @@ IrFile /identity.kt
|
|||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=EQEQEQ type=kotlin.Boolean related=null
|
CALL .EQEQEQ type=kotlin.Boolean operator=EQEQEQ
|
||||||
GET_VAR a type=kotlin.Int operator=null
|
arg0: GET_VAR a type=kotlin.Int operator=null
|
||||||
GET_VAR b type=kotlin.Int operator=null
|
arg1: GET_VAR b type=kotlin.Int operator=null
|
||||||
IrFunction public fun test2(/*0*/ a: kotlin.Int, /*1*/ b: kotlin.Int): kotlin.Boolean
|
IrFunction public fun test2(/*0*/ a: kotlin.Int, /*1*/ b: kotlin.Int): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=EXCLEQEQ type=kotlin.Boolean related=null
|
CALL .NOT type=kotlin.Boolean operator=EXCL
|
||||||
GET_VAR a type=kotlin.Int operator=null
|
arg0: CALL .EQEQEQ type=kotlin.Boolean operator=EXCLEQEQ
|
||||||
GET_VAR b type=kotlin.Int operator=null
|
arg0: GET_VAR a type=kotlin.Int operator=null
|
||||||
|
arg1: GET_VAR b type=kotlin.Int operator=null
|
||||||
IrFunction public fun test3(/*0*/ a: kotlin.Any?, /*1*/ b: kotlin.Any?): kotlin.Boolean
|
IrFunction public fun test3(/*0*/ a: kotlin.Any?, /*1*/ b: kotlin.Any?): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=EQEQEQ type=kotlin.Boolean related=null
|
CALL .EQEQEQ type=kotlin.Boolean operator=EQEQEQ
|
||||||
GET_VAR a type=kotlin.Any? operator=null
|
arg0: GET_VAR a type=kotlin.Any? operator=null
|
||||||
GET_VAR b type=kotlin.Any? operator=null
|
arg1: GET_VAR b type=kotlin.Any? operator=null
|
||||||
|
|||||||
+8
-6
@@ -4,13 +4,15 @@ IrFile /ifElseIf.kt
|
|||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
IF type=kotlin.Int operator=IF
|
IF type=kotlin.Int operator=IF
|
||||||
if: BINARY_OP operator=GT type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Int): kotlin.Int
|
if: CALL .GT0 type=kotlin.Boolean operator=GT
|
||||||
GET_VAR i type=kotlin.Int operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=GT
|
||||||
LITERAL Int type=kotlin.Int value='0'
|
$this: GET_VAR i type=kotlin.Int operator=null
|
||||||
|
other: LITERAL Int type=kotlin.Int value='0'
|
||||||
then: LITERAL Int type=kotlin.Int value='1'
|
then: LITERAL Int type=kotlin.Int value='1'
|
||||||
else: IF type=kotlin.Int operator=IF
|
else: IF type=kotlin.Int operator=IF
|
||||||
if: BINARY_OP operator=LT type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Int): kotlin.Int
|
if: CALL .LT0 type=kotlin.Boolean operator=LT
|
||||||
GET_VAR i type=kotlin.Int operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=LT
|
||||||
LITERAL Int type=kotlin.Int value='0'
|
$this: GET_VAR i type=kotlin.Int operator=null
|
||||||
|
other: LITERAL Int type=kotlin.Int value='0'
|
||||||
then: DUMMY MINUS type=kotlin.Int
|
then: DUMMY MINUS type=kotlin.Int
|
||||||
else: LITERAL Int type=kotlin.Int value='0'
|
else: LITERAL Int type=kotlin.Int value='0'
|
||||||
|
|||||||
@@ -3,6 +3,6 @@ IrFile /implicitCastOnPlatformType.kt
|
|||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
UNARY_OP operator=IMPLICIT_NOTNULL type=kotlin.String related=null
|
CALL .IMPLICIT_NOT_NULL type=kotlin.Any operator=IMPLICIT_NOTNULL
|
||||||
CALL .getProperty type=kotlin.String! operator=null
|
arg0: CALL .getProperty type=kotlin.String! operator=null
|
||||||
p0: LITERAL String type=kotlin.String value='test'
|
p0: LITERAL String type=kotlin.String value='test'
|
||||||
|
|||||||
Vendored
+4
-4
@@ -10,8 +10,8 @@ IrFile /in.kt
|
|||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
UNARY_OP operator=EXCL type=kotlin.Boolean related=null
|
CALL .NOT type=kotlin.Boolean operator=EXCL
|
||||||
CALL .contains type=kotlin.Boolean operator=NOT_IN
|
arg0: CALL .contains type=kotlin.Boolean operator=NOT_IN
|
||||||
$this: GET_VAR x type=kotlin.collections.Collection<kotlin.Any> operator=null
|
$this: GET_VAR x type=kotlin.collections.Collection<kotlin.Any> operator=null
|
||||||
element: GET_VAR a type=kotlin.Any operator=null
|
element: GET_VAR a type=kotlin.Any operator=null
|
||||||
IrFunction public fun </*0*/ T> test3(/*0*/ a: T, /*1*/ x: kotlin.collections.Collection<T>): kotlin.Boolean
|
IrFunction public fun </*0*/ T> test3(/*0*/ a: T, /*1*/ x: kotlin.collections.Collection<T>): kotlin.Boolean
|
||||||
@@ -25,7 +25,7 @@ IrFile /in.kt
|
|||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
UNARY_OP operator=EXCL type=kotlin.Boolean related=null
|
CALL .NOT type=kotlin.Boolean operator=EXCL
|
||||||
CALL .contains type=kotlin.Boolean operator=NOT_IN
|
arg0: CALL .contains type=kotlin.Boolean operator=NOT_IN
|
||||||
$this: GET_VAR x type=kotlin.collections.Collection<T> operator=null
|
$this: GET_VAR x type=kotlin.collections.Collection<T> operator=null
|
||||||
element: GET_VAR a type=T operator=null
|
element: GET_VAR a type=T operator=null
|
||||||
|
|||||||
+96
-72
@@ -3,167 +3,191 @@ IrFile /primitiveComparisons.kt
|
|||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=GT type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Byte): kotlin.Int
|
CALL .GT0 type=kotlin.Boolean operator=GT
|
||||||
GET_VAR a type=kotlin.Byte operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=GT
|
||||||
GET_VAR b type=kotlin.Byte operator=null
|
$this: GET_VAR a type=kotlin.Byte operator=null
|
||||||
|
other: GET_VAR b type=kotlin.Byte operator=null
|
||||||
IrFunction public fun btest2(/*0*/ a: kotlin.Byte, /*1*/ b: kotlin.Byte): kotlin.Boolean
|
IrFunction public fun btest2(/*0*/ a: kotlin.Byte, /*1*/ b: kotlin.Byte): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=LT type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Byte): kotlin.Int
|
CALL .LT0 type=kotlin.Boolean operator=LT
|
||||||
GET_VAR a type=kotlin.Byte operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=LT
|
||||||
GET_VAR b type=kotlin.Byte operator=null
|
$this: GET_VAR a type=kotlin.Byte operator=null
|
||||||
|
other: GET_VAR b type=kotlin.Byte operator=null
|
||||||
IrFunction public fun btest3(/*0*/ a: kotlin.Byte, /*1*/ b: kotlin.Byte): kotlin.Boolean
|
IrFunction public fun btest3(/*0*/ a: kotlin.Byte, /*1*/ b: kotlin.Byte): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=GTEQ type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Byte): kotlin.Int
|
CALL .GTEQ0 type=kotlin.Boolean operator=GTEQ
|
||||||
GET_VAR a type=kotlin.Byte operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=GTEQ
|
||||||
GET_VAR b type=kotlin.Byte operator=null
|
$this: GET_VAR a type=kotlin.Byte operator=null
|
||||||
|
other: GET_VAR b type=kotlin.Byte operator=null
|
||||||
IrFunction public fun btest4(/*0*/ a: kotlin.Byte, /*1*/ b: kotlin.Byte): kotlin.Boolean
|
IrFunction public fun btest4(/*0*/ a: kotlin.Byte, /*1*/ b: kotlin.Byte): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=LTEQ type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Byte): kotlin.Int
|
CALL .LTEQ0 type=kotlin.Boolean operator=LTEQ
|
||||||
GET_VAR a type=kotlin.Byte operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=LTEQ
|
||||||
GET_VAR b type=kotlin.Byte operator=null
|
$this: GET_VAR a type=kotlin.Byte operator=null
|
||||||
|
other: GET_VAR b type=kotlin.Byte operator=null
|
||||||
IrFunction public fun stest1(/*0*/ a: kotlin.Short, /*1*/ b: kotlin.Short): kotlin.Boolean
|
IrFunction public fun stest1(/*0*/ a: kotlin.Short, /*1*/ b: kotlin.Short): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=GT type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Short): kotlin.Int
|
CALL .GT0 type=kotlin.Boolean operator=GT
|
||||||
GET_VAR a type=kotlin.Short operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=GT
|
||||||
GET_VAR b type=kotlin.Short operator=null
|
$this: GET_VAR a type=kotlin.Short operator=null
|
||||||
|
other: GET_VAR b type=kotlin.Short operator=null
|
||||||
IrFunction public fun stest2(/*0*/ a: kotlin.Short, /*1*/ b: kotlin.Short): kotlin.Boolean
|
IrFunction public fun stest2(/*0*/ a: kotlin.Short, /*1*/ b: kotlin.Short): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=LT type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Short): kotlin.Int
|
CALL .LT0 type=kotlin.Boolean operator=LT
|
||||||
GET_VAR a type=kotlin.Short operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=LT
|
||||||
GET_VAR b type=kotlin.Short operator=null
|
$this: GET_VAR a type=kotlin.Short operator=null
|
||||||
|
other: GET_VAR b type=kotlin.Short operator=null
|
||||||
IrFunction public fun stest3(/*0*/ a: kotlin.Short, /*1*/ b: kotlin.Short): kotlin.Boolean
|
IrFunction public fun stest3(/*0*/ a: kotlin.Short, /*1*/ b: kotlin.Short): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=GTEQ type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Short): kotlin.Int
|
CALL .GTEQ0 type=kotlin.Boolean operator=GTEQ
|
||||||
GET_VAR a type=kotlin.Short operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=GTEQ
|
||||||
GET_VAR b type=kotlin.Short operator=null
|
$this: GET_VAR a type=kotlin.Short operator=null
|
||||||
|
other: GET_VAR b type=kotlin.Short operator=null
|
||||||
IrFunction public fun stest4(/*0*/ a: kotlin.Short, /*1*/ b: kotlin.Short): kotlin.Boolean
|
IrFunction public fun stest4(/*0*/ a: kotlin.Short, /*1*/ b: kotlin.Short): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=LTEQ type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Short): kotlin.Int
|
CALL .LTEQ0 type=kotlin.Boolean operator=LTEQ
|
||||||
GET_VAR a type=kotlin.Short operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=LTEQ
|
||||||
GET_VAR b type=kotlin.Short operator=null
|
$this: GET_VAR a type=kotlin.Short operator=null
|
||||||
|
other: GET_VAR b type=kotlin.Short operator=null
|
||||||
IrFunction public fun itest1(/*0*/ a: kotlin.Int, /*1*/ b: kotlin.Int): kotlin.Boolean
|
IrFunction public fun itest1(/*0*/ a: kotlin.Int, /*1*/ b: kotlin.Int): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=GT type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Int): kotlin.Int
|
CALL .GT0 type=kotlin.Boolean operator=GT
|
||||||
GET_VAR a type=kotlin.Int operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=GT
|
||||||
GET_VAR b type=kotlin.Int operator=null
|
$this: GET_VAR a type=kotlin.Int operator=null
|
||||||
|
other: GET_VAR b type=kotlin.Int operator=null
|
||||||
IrFunction public fun itest2(/*0*/ a: kotlin.Int, /*1*/ b: kotlin.Int): kotlin.Boolean
|
IrFunction public fun itest2(/*0*/ a: kotlin.Int, /*1*/ b: kotlin.Int): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=LT type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Int): kotlin.Int
|
CALL .LT0 type=kotlin.Boolean operator=LT
|
||||||
GET_VAR a type=kotlin.Int operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=LT
|
||||||
GET_VAR b type=kotlin.Int operator=null
|
$this: GET_VAR a type=kotlin.Int operator=null
|
||||||
|
other: GET_VAR b type=kotlin.Int operator=null
|
||||||
IrFunction public fun itest3(/*0*/ a: kotlin.Int, /*1*/ b: kotlin.Int): kotlin.Boolean
|
IrFunction public fun itest3(/*0*/ a: kotlin.Int, /*1*/ b: kotlin.Int): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=GTEQ type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Int): kotlin.Int
|
CALL .GTEQ0 type=kotlin.Boolean operator=GTEQ
|
||||||
GET_VAR a type=kotlin.Int operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=GTEQ
|
||||||
GET_VAR b type=kotlin.Int operator=null
|
$this: GET_VAR a type=kotlin.Int operator=null
|
||||||
|
other: GET_VAR b type=kotlin.Int operator=null
|
||||||
IrFunction public fun itest4(/*0*/ a: kotlin.Int, /*1*/ b: kotlin.Int): kotlin.Boolean
|
IrFunction public fun itest4(/*0*/ a: kotlin.Int, /*1*/ b: kotlin.Int): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=LTEQ type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Int): kotlin.Int
|
CALL .LTEQ0 type=kotlin.Boolean operator=LTEQ
|
||||||
GET_VAR a type=kotlin.Int operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=LTEQ
|
||||||
GET_VAR b type=kotlin.Int operator=null
|
$this: GET_VAR a type=kotlin.Int operator=null
|
||||||
|
other: GET_VAR b type=kotlin.Int operator=null
|
||||||
IrFunction public fun ltest1(/*0*/ a: kotlin.Long, /*1*/ b: kotlin.Long): kotlin.Boolean
|
IrFunction public fun ltest1(/*0*/ a: kotlin.Long, /*1*/ b: kotlin.Long): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=GT type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Long): kotlin.Int
|
CALL .GT0 type=kotlin.Boolean operator=GT
|
||||||
GET_VAR a type=kotlin.Long operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=GT
|
||||||
GET_VAR b type=kotlin.Long operator=null
|
$this: GET_VAR a type=kotlin.Long operator=null
|
||||||
|
other: GET_VAR b type=kotlin.Long operator=null
|
||||||
IrFunction public fun ltest2(/*0*/ a: kotlin.Long, /*1*/ b: kotlin.Long): kotlin.Boolean
|
IrFunction public fun ltest2(/*0*/ a: kotlin.Long, /*1*/ b: kotlin.Long): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=LT type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Long): kotlin.Int
|
CALL .LT0 type=kotlin.Boolean operator=LT
|
||||||
GET_VAR a type=kotlin.Long operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=LT
|
||||||
GET_VAR b type=kotlin.Long operator=null
|
$this: GET_VAR a type=kotlin.Long operator=null
|
||||||
|
other: GET_VAR b type=kotlin.Long operator=null
|
||||||
IrFunction public fun ltest3(/*0*/ a: kotlin.Long, /*1*/ b: kotlin.Long): kotlin.Boolean
|
IrFunction public fun ltest3(/*0*/ a: kotlin.Long, /*1*/ b: kotlin.Long): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=GTEQ type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Long): kotlin.Int
|
CALL .GTEQ0 type=kotlin.Boolean operator=GTEQ
|
||||||
GET_VAR a type=kotlin.Long operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=GTEQ
|
||||||
GET_VAR b type=kotlin.Long operator=null
|
$this: GET_VAR a type=kotlin.Long operator=null
|
||||||
|
other: GET_VAR b type=kotlin.Long operator=null
|
||||||
IrFunction public fun ltest4(/*0*/ a: kotlin.Long, /*1*/ b: kotlin.Long): kotlin.Boolean
|
IrFunction public fun ltest4(/*0*/ a: kotlin.Long, /*1*/ b: kotlin.Long): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=LTEQ type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Long): kotlin.Int
|
CALL .LTEQ0 type=kotlin.Boolean operator=LTEQ
|
||||||
GET_VAR a type=kotlin.Long operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=LTEQ
|
||||||
GET_VAR b type=kotlin.Long operator=null
|
$this: GET_VAR a type=kotlin.Long operator=null
|
||||||
|
other: GET_VAR b type=kotlin.Long operator=null
|
||||||
IrFunction public fun ftest1(/*0*/ a: kotlin.Float, /*1*/ b: kotlin.Float): kotlin.Boolean
|
IrFunction public fun ftest1(/*0*/ a: kotlin.Float, /*1*/ b: kotlin.Float): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=GT type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Float): kotlin.Int
|
CALL .GT0 type=kotlin.Boolean operator=GT
|
||||||
GET_VAR a type=kotlin.Float operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=GT
|
||||||
GET_VAR b type=kotlin.Float operator=null
|
$this: GET_VAR a type=kotlin.Float operator=null
|
||||||
|
other: GET_VAR b type=kotlin.Float operator=null
|
||||||
IrFunction public fun ftest2(/*0*/ a: kotlin.Float, /*1*/ b: kotlin.Float): kotlin.Boolean
|
IrFunction public fun ftest2(/*0*/ a: kotlin.Float, /*1*/ b: kotlin.Float): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=LT type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Float): kotlin.Int
|
CALL .LT0 type=kotlin.Boolean operator=LT
|
||||||
GET_VAR a type=kotlin.Float operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=LT
|
||||||
GET_VAR b type=kotlin.Float operator=null
|
$this: GET_VAR a type=kotlin.Float operator=null
|
||||||
|
other: GET_VAR b type=kotlin.Float operator=null
|
||||||
IrFunction public fun ftest3(/*0*/ a: kotlin.Float, /*1*/ b: kotlin.Float): kotlin.Boolean
|
IrFunction public fun ftest3(/*0*/ a: kotlin.Float, /*1*/ b: kotlin.Float): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=GTEQ type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Float): kotlin.Int
|
CALL .GTEQ0 type=kotlin.Boolean operator=GTEQ
|
||||||
GET_VAR a type=kotlin.Float operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=GTEQ
|
||||||
GET_VAR b type=kotlin.Float operator=null
|
$this: GET_VAR a type=kotlin.Float operator=null
|
||||||
|
other: GET_VAR b type=kotlin.Float operator=null
|
||||||
IrFunction public fun ftest4(/*0*/ a: kotlin.Float, /*1*/ b: kotlin.Float): kotlin.Boolean
|
IrFunction public fun ftest4(/*0*/ a: kotlin.Float, /*1*/ b: kotlin.Float): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=LTEQ type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Float): kotlin.Int
|
CALL .LTEQ0 type=kotlin.Boolean operator=LTEQ
|
||||||
GET_VAR a type=kotlin.Float operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=LTEQ
|
||||||
GET_VAR b type=kotlin.Float operator=null
|
$this: GET_VAR a type=kotlin.Float operator=null
|
||||||
|
other: GET_VAR b type=kotlin.Float operator=null
|
||||||
IrFunction public fun dtest1(/*0*/ a: kotlin.Double, /*1*/ b: kotlin.Double): kotlin.Boolean
|
IrFunction public fun dtest1(/*0*/ a: kotlin.Double, /*1*/ b: kotlin.Double): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=GT type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Double): kotlin.Int
|
CALL .GT0 type=kotlin.Boolean operator=GT
|
||||||
GET_VAR a type=kotlin.Double operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=GT
|
||||||
GET_VAR b type=kotlin.Double operator=null
|
$this: GET_VAR a type=kotlin.Double operator=null
|
||||||
|
other: GET_VAR b type=kotlin.Double operator=null
|
||||||
IrFunction public fun dtest2(/*0*/ a: kotlin.Double, /*1*/ b: kotlin.Double): kotlin.Boolean
|
IrFunction public fun dtest2(/*0*/ a: kotlin.Double, /*1*/ b: kotlin.Double): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=LT type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Double): kotlin.Int
|
CALL .LT0 type=kotlin.Boolean operator=LT
|
||||||
GET_VAR a type=kotlin.Double operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=LT
|
||||||
GET_VAR b type=kotlin.Double operator=null
|
$this: GET_VAR a type=kotlin.Double operator=null
|
||||||
|
other: GET_VAR b type=kotlin.Double operator=null
|
||||||
IrFunction public fun dtest3(/*0*/ a: kotlin.Double, /*1*/ b: kotlin.Double): kotlin.Boolean
|
IrFunction public fun dtest3(/*0*/ a: kotlin.Double, /*1*/ b: kotlin.Double): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=GTEQ type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Double): kotlin.Int
|
CALL .GTEQ0 type=kotlin.Boolean operator=GTEQ
|
||||||
GET_VAR a type=kotlin.Double operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=GTEQ
|
||||||
GET_VAR b type=kotlin.Double operator=null
|
$this: GET_VAR a type=kotlin.Double operator=null
|
||||||
|
other: GET_VAR b type=kotlin.Double operator=null
|
||||||
IrFunction public fun dtest4(/*0*/ a: kotlin.Double, /*1*/ b: kotlin.Double): kotlin.Boolean
|
IrFunction public fun dtest4(/*0*/ a: kotlin.Double, /*1*/ b: kotlin.Double): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=LTEQ type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Double): kotlin.Int
|
CALL .LTEQ0 type=kotlin.Boolean operator=LTEQ
|
||||||
GET_VAR a type=kotlin.Double operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=LTEQ
|
||||||
GET_VAR b type=kotlin.Double operator=null
|
$this: GET_VAR a type=kotlin.Double operator=null
|
||||||
|
other: GET_VAR b type=kotlin.Double operator=null
|
||||||
|
|||||||
+16
-12
@@ -3,27 +3,31 @@ IrFile /stringComparisons.kt
|
|||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=GT type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.String): kotlin.Int
|
CALL .GT0 type=kotlin.Boolean operator=GT
|
||||||
GET_VAR a type=kotlin.String operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=GT
|
||||||
GET_VAR b type=kotlin.String operator=null
|
$this: GET_VAR a type=kotlin.String operator=null
|
||||||
|
other: GET_VAR b type=kotlin.String operator=null
|
||||||
IrFunction public fun test2(/*0*/ a: kotlin.String, /*1*/ b: kotlin.String): kotlin.Boolean
|
IrFunction public fun test2(/*0*/ a: kotlin.String, /*1*/ b: kotlin.String): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=LT type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.String): kotlin.Int
|
CALL .LT0 type=kotlin.Boolean operator=LT
|
||||||
GET_VAR a type=kotlin.String operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=LT
|
||||||
GET_VAR b type=kotlin.String operator=null
|
$this: GET_VAR a type=kotlin.String operator=null
|
||||||
|
other: GET_VAR b type=kotlin.String operator=null
|
||||||
IrFunction public fun test3(/*0*/ a: kotlin.String, /*1*/ b: kotlin.String): kotlin.Boolean
|
IrFunction public fun test3(/*0*/ a: kotlin.String, /*1*/ b: kotlin.String): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=GTEQ type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.String): kotlin.Int
|
CALL .GTEQ0 type=kotlin.Boolean operator=GTEQ
|
||||||
GET_VAR a type=kotlin.String operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=GTEQ
|
||||||
GET_VAR b type=kotlin.String operator=null
|
$this: GET_VAR a type=kotlin.String operator=null
|
||||||
|
other: GET_VAR b type=kotlin.String operator=null
|
||||||
IrFunction public fun test4(/*0*/ a: kotlin.String, /*1*/ b: kotlin.String): kotlin.Boolean
|
IrFunction public fun test4(/*0*/ a: kotlin.String, /*1*/ b: kotlin.String): kotlin.Boolean
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=LTEQ type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.String): kotlin.Int
|
CALL .LTEQ0 type=kotlin.Boolean operator=LTEQ
|
||||||
GET_VAR a type=kotlin.String operator=null
|
arg0: CALL .compareTo type=kotlin.Int operator=LTEQ
|
||||||
GET_VAR b type=kotlin.String operator=null
|
$this: GET_VAR a type=kotlin.String operator=null
|
||||||
|
other: GET_VAR b type=kotlin.String operator=null
|
||||||
|
|||||||
Vendored
+39
-39
@@ -8,14 +8,14 @@ IrFile /when.kt
|
|||||||
VAR val tmp0_subject: kotlin.Any?
|
VAR val tmp0_subject: kotlin.Any?
|
||||||
GET_VAR x type=kotlin.Any? operator=null
|
GET_VAR x type=kotlin.Any? operator=null
|
||||||
IF type=kotlin.String operator=WHEN
|
IF type=kotlin.String operator=WHEN
|
||||||
if: BINARY_OP operator=EQEQ type=kotlin.Boolean related=null
|
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
||||||
GET_VAR tmp0_subject type=kotlin.Any? operator=null
|
arg0: GET_VAR tmp0_subject type=kotlin.Any? operator=null
|
||||||
LITERAL Null type=kotlin.Nothing? value='null'
|
arg1: LITERAL Null type=kotlin.Nothing? value='null'
|
||||||
then: LITERAL String type=kotlin.String value='null'
|
then: LITERAL String type=kotlin.String value='null'
|
||||||
else: IF type=kotlin.String operator=WHEN
|
else: IF type=kotlin.String operator=WHEN
|
||||||
if: BINARY_OP operator=EQEQ type=kotlin.Boolean related=null
|
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
||||||
GET_VAR tmp0_subject type=kotlin.Any? operator=null
|
arg0: GET_VAR tmp0_subject type=kotlin.Any? operator=null
|
||||||
GET_OBJECT A type=A
|
arg1: GET_OBJECT A type=A
|
||||||
then: LITERAL String type=kotlin.String value='A'
|
then: LITERAL String type=kotlin.String value='A'
|
||||||
else: IF type=kotlin.String operator=WHEN
|
else: IF type=kotlin.String operator=WHEN
|
||||||
if: TYPE_OP operator=INSTANCEOF typeOperand=kotlin.String
|
if: TYPE_OP operator=INSTANCEOF typeOperand=kotlin.String
|
||||||
@@ -33,14 +33,14 @@ IrFile /when.kt
|
|||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
IF type=kotlin.String operator=WHEN
|
IF type=kotlin.String operator=WHEN
|
||||||
if: BINARY_OP operator=EQEQ type=kotlin.Boolean related=public open operator fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
||||||
GET_VAR x type=kotlin.Any? operator=null
|
arg0: GET_VAR x type=kotlin.Any? operator=null
|
||||||
LITERAL Null type=kotlin.Nothing? value='null'
|
arg1: LITERAL Null type=kotlin.Nothing? value='null'
|
||||||
then: LITERAL String type=kotlin.String value='null'
|
then: LITERAL String type=kotlin.String value='null'
|
||||||
else: IF type=kotlin.String operator=WHEN
|
else: IF type=kotlin.String operator=WHEN
|
||||||
if: BINARY_OP operator=EQEQ type=kotlin.Boolean related=public open operator fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
||||||
GET_VAR x type=kotlin.Any? operator=null
|
arg0: GET_VAR x type=kotlin.Any? operator=null
|
||||||
GET_OBJECT A type=A
|
arg1: GET_OBJECT A type=A
|
||||||
then: LITERAL String type=kotlin.String value='A'
|
then: LITERAL String type=kotlin.String value='A'
|
||||||
else: IF type=kotlin.String operator=WHEN
|
else: IF type=kotlin.String operator=WHEN
|
||||||
if: TYPE_OP operator=INSTANCEOF typeOperand=kotlin.String
|
if: TYPE_OP operator=INSTANCEOF typeOperand=kotlin.String
|
||||||
@@ -64,45 +64,45 @@ IrFile /when.kt
|
|||||||
if: IF type=kotlin.Boolean operator=WHEN_COMMA
|
if: IF type=kotlin.Boolean operator=WHEN_COMMA
|
||||||
if: IF type=kotlin.Boolean operator=WHEN_COMMA
|
if: IF type=kotlin.Boolean operator=WHEN_COMMA
|
||||||
if: IF type=kotlin.Boolean operator=WHEN_COMMA
|
if: IF type=kotlin.Boolean operator=WHEN_COMMA
|
||||||
if: BINARY_OP operator=EQEQ type=kotlin.Boolean related=null
|
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
||||||
GET_VAR tmp0_subject type=kotlin.Int operator=null
|
arg0: GET_VAR tmp0_subject type=kotlin.Int operator=null
|
||||||
LITERAL Int type=kotlin.Int value='1'
|
arg1: LITERAL Int type=kotlin.Int value='1'
|
||||||
then: LITERAL Boolean type=kotlin.Boolean value='true'
|
then: LITERAL Boolean type=kotlin.Boolean value='true'
|
||||||
else: BINARY_OP operator=EQEQ type=kotlin.Boolean related=null
|
else: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
||||||
GET_VAR tmp0_subject type=kotlin.Int operator=null
|
arg0: GET_VAR tmp0_subject type=kotlin.Int operator=null
|
||||||
LITERAL Int type=kotlin.Int value='2'
|
arg1: LITERAL Int type=kotlin.Int value='2'
|
||||||
then: LITERAL Boolean type=kotlin.Boolean value='true'
|
then: LITERAL Boolean type=kotlin.Boolean value='true'
|
||||||
else: BINARY_OP operator=EQEQ type=kotlin.Boolean related=null
|
else: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
||||||
GET_VAR tmp0_subject type=kotlin.Int operator=null
|
arg0: GET_VAR tmp0_subject type=kotlin.Int operator=null
|
||||||
LITERAL Int type=kotlin.Int value='3'
|
arg1: LITERAL Int type=kotlin.Int value='3'
|
||||||
then: LITERAL Boolean type=kotlin.Boolean value='true'
|
then: LITERAL Boolean type=kotlin.Boolean value='true'
|
||||||
else: BINARY_OP operator=EQEQ type=kotlin.Boolean related=null
|
else: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
||||||
GET_VAR tmp0_subject type=kotlin.Int operator=null
|
arg0: GET_VAR tmp0_subject type=kotlin.Int operator=null
|
||||||
LITERAL Int type=kotlin.Int value='4'
|
arg1: LITERAL Int type=kotlin.Int value='4'
|
||||||
then: LITERAL String type=kotlin.String value='1234'
|
then: LITERAL String type=kotlin.String value='1234'
|
||||||
else: IF type=kotlin.String operator=WHEN
|
else: IF type=kotlin.String operator=WHEN
|
||||||
if: IF type=kotlin.Boolean operator=WHEN_COMMA
|
if: IF type=kotlin.Boolean operator=WHEN_COMMA
|
||||||
if: IF type=kotlin.Boolean operator=WHEN_COMMA
|
if: IF type=kotlin.Boolean operator=WHEN_COMMA
|
||||||
if: BINARY_OP operator=EQEQ type=kotlin.Boolean related=null
|
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
||||||
GET_VAR tmp0_subject type=kotlin.Int operator=null
|
arg0: GET_VAR tmp0_subject type=kotlin.Int operator=null
|
||||||
LITERAL Int type=kotlin.Int value='5'
|
arg1: LITERAL Int type=kotlin.Int value='5'
|
||||||
then: LITERAL Boolean type=kotlin.Boolean value='true'
|
then: LITERAL Boolean type=kotlin.Boolean value='true'
|
||||||
else: BINARY_OP operator=EQEQ type=kotlin.Boolean related=null
|
else: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
||||||
GET_VAR tmp0_subject type=kotlin.Int operator=null
|
arg0: GET_VAR tmp0_subject type=kotlin.Int operator=null
|
||||||
LITERAL Int type=kotlin.Int value='6'
|
arg1: LITERAL Int type=kotlin.Int value='6'
|
||||||
then: LITERAL Boolean type=kotlin.Boolean value='true'
|
then: LITERAL Boolean type=kotlin.Boolean value='true'
|
||||||
else: BINARY_OP operator=EQEQ type=kotlin.Boolean related=null
|
else: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
||||||
GET_VAR tmp0_subject type=kotlin.Int operator=null
|
arg0: GET_VAR tmp0_subject type=kotlin.Int operator=null
|
||||||
LITERAL Int type=kotlin.Int value='7'
|
arg1: LITERAL Int type=kotlin.Int value='7'
|
||||||
then: LITERAL String type=kotlin.String value='567'
|
then: LITERAL String type=kotlin.String value='567'
|
||||||
else: IF type=kotlin.String operator=WHEN
|
else: IF type=kotlin.String operator=WHEN
|
||||||
if: IF type=kotlin.Boolean operator=WHEN_COMMA
|
if: IF type=kotlin.Boolean operator=WHEN_COMMA
|
||||||
if: BINARY_OP operator=EQEQ type=kotlin.Boolean related=null
|
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
||||||
GET_VAR tmp0_subject type=kotlin.Int operator=null
|
arg0: GET_VAR tmp0_subject type=kotlin.Int operator=null
|
||||||
LITERAL Int type=kotlin.Int value='8'
|
arg1: LITERAL Int type=kotlin.Int value='8'
|
||||||
then: LITERAL Boolean type=kotlin.Boolean value='true'
|
then: LITERAL Boolean type=kotlin.Boolean value='true'
|
||||||
else: BINARY_OP operator=EQEQ type=kotlin.Boolean related=null
|
else: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
|
||||||
GET_VAR tmp0_subject type=kotlin.Int operator=null
|
arg0: GET_VAR tmp0_subject type=kotlin.Int operator=null
|
||||||
LITERAL Int type=kotlin.Int value='9'
|
arg1: LITERAL Int type=kotlin.Int value='9'
|
||||||
then: LITERAL String type=kotlin.String value='89'
|
then: LITERAL String type=kotlin.String value='89'
|
||||||
else: LITERAL String type=kotlin.String value='?'
|
else: LITERAL String type=kotlin.String value='?'
|
||||||
|
|||||||
Reference in New Issue
Block a user