[FIR] Add fir node for binary && and ||

This commit is contained in:
Dmitriy Novozhilov
2019-08-14 15:08:46 +03:00
parent 908b6ade1d
commit ba7a137e74
14 changed files with 201 additions and 72 deletions
@@ -17,12 +17,14 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition
import org.jetbrains.kotlin.fir.expressions.FirWhenSubjectExpression
import org.jetbrains.kotlin.fir.expressions.impl.FirUncheckedNotNullCastImpl import org.jetbrains.kotlin.fir.expressions.impl.FirUncheckedNotNullCastImpl
import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
import org.jetbrains.kotlin.fir.references.FirSimpleNamedReference import org.jetbrains.kotlin.fir.references.FirSimpleNamedReference
import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.directExpansionType
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.resolve.withNullability
import org.jetbrains.kotlin.fir.symbols.* import org.jetbrains.kotlin.fir.symbols.*
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.FirTypePlaceholderProjection import org.jetbrains.kotlin.fir.types.impl.FirTypePlaceholderProjection
@@ -1237,11 +1239,18 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
is FirTypeOperatorCall -> generate(expression) is FirTypeOperatorCall -> generate(expression)
is FirUncheckedNotNullCastImpl -> generate(expression) is FirUncheckedNotNullCastImpl -> generate(expression)
is FirOperatorCall -> generate(expression) is FirOperatorCall -> generate(expression)
is FirBinaryLogicExpression -> generate(expression)
else -> inlineUnsupported(expression) else -> inlineUnsupported(expression)
} }
} }
} }
private fun FlowContent.generate(binaryLogicExpression: FirBinaryLogicExpression) {
generate(binaryLogicExpression.leftOperand)
+" ${binaryLogicExpression.kind.token} "
generate(binaryLogicExpression.rightOperand)
}
private fun FlowContent.generate(qualifiedAccessExpression: FirQualifiedAccessExpression) { private fun FlowContent.generate(qualifiedAccessExpression: FirQualifiedAccessExpression) {
generateReceiver(qualifiedAccessExpression) generateReceiver(qualifiedAccessExpression)
generate(qualifiedAccessExpression.calleeReference) generate(qualifiedAccessExpression.calleeReference)
@@ -5,11 +5,13 @@
package org.jetbrains.kotlin.fir.backend package org.jetbrains.kotlin.fir.backend
import org.jetbrains.kotlin.backend.common.descriptors.* import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor
import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.* import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter
import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition
@@ -27,14 +29,20 @@ import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.impl.* import org.jetbrains.kotlin.fir.types.impl.FirImplicitBooleanTypeRef
import org.jetbrains.kotlin.fir.types.impl.FirImplicitNothingTypeRef
import org.jetbrains.kotlin.fir.types.impl.FirImplicitStringTypeRef
import org.jetbrains.kotlin.fir.types.impl.FirImplicitUnitTypeRef
import org.jetbrains.kotlin.fir.types.render import org.jetbrains.kotlin.fir.types.render
import org.jetbrains.kotlin.fir.visitors.FirVisitor import org.jetbrains.kotlin.fir.visitors.FirVisitor
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.* import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.impl.*
@@ -1223,4 +1231,25 @@ internal class Fir2IrVisitor(
} }
return super.visitResolvedQualifier(resolvedQualifier, data) return super.visitResolvedQualifier(resolvedQualifier, data)
} }
override fun visitBinaryLogicExpression(binaryLogicExpression: FirBinaryLogicExpression, data: Any?): IrElement {
return binaryLogicExpression.convertWithOffsets<IrElement> { startOffset, endOffset ->
val leftOperand = binaryLogicExpression.leftOperand.accept(this, data) as IrExpression
val rightOperand = binaryLogicExpression.rightOperand.accept(this, data) as IrExpression
when (binaryLogicExpression.kind) {
FirBinaryLogicExpression.OperationKind.AND -> {
IrIfThenElseImpl(startOffset, endOffset, irBuiltIns.booleanType, IrStatementOrigin.ANDAND).apply {
branches.add(IrBranchImpl(leftOperand, rightOperand))
branches.add(elseBranch(constFalse(rightOperand.startOffset, rightOperand.endOffset)))
}
}
FirBinaryLogicExpression.OperationKind.OR -> {
IrIfThenElseImpl(startOffset, endOffset, irBuiltIns.booleanType, IrStatementOrigin.OROR).apply {
branches.add(IrBranchImpl(leftOperand, constTrue(leftOperand.startOffset, leftOperand.endOffset)))
branches.add(elseBranch(rightOperand))
}
}
}
}
}
} }
@@ -7,25 +7,30 @@ package org.jetbrains.kotlin.fir.builder
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.tree.IElementType import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.FirFunctionTarget import org.jetbrains.kotlin.fir.FirFunctionTarget
import org.jetbrains.kotlin.fir.FirReference
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.FirWhenSubject import org.jetbrains.kotlin.fir.FirWhenSubject
import org.jetbrains.kotlin.fir.declarations.impl.* import org.jetbrains.kotlin.fir.declarations.impl.FirModifiableAccessorsOwner
import org.jetbrains.kotlin.fir.declarations.impl.FirPropertyAccessorImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirVariableImpl
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.impl.* import org.jetbrains.kotlin.fir.expressions.impl.*
import org.jetbrains.kotlin.fir.references.* import org.jetbrains.kotlin.fir.references.FirDelegateFieldReferenceImpl
import org.jetbrains.kotlin.fir.references.FirExplicitThisReference
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl
import org.jetbrains.kotlin.fir.references.FirSimpleNamedReference
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.fir.types.ConeStarProjection import org.jetbrains.kotlin.fir.types.ConeStarProjection
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.impl.* import org.jetbrains.kotlin.fir.types.impl.FirImplicitKPropertyTypeRef
import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImpl
import org.jetbrains.kotlin.fir.types.impl.FirImplicitUnitTypeRef
import org.jetbrains.kotlin.ir.expressions.IrConstKind import org.jetbrains.kotlin.ir.expressions.IrConstKind
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.constants.evaluate.*
import org.jetbrains.kotlin.types.expressions.OperatorConventions import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.util.OperatorNameConventions
@@ -158,21 +163,12 @@ fun FirExpression.generateNotNullOrOther(
fun FirExpression.generateLazyLogicalOperation( fun FirExpression.generateLazyLogicalOperation(
other: FirExpression, isAnd: Boolean, basePsi: KtElement? other: FirExpression, isAnd: Boolean, basePsi: KtElement?
): FirWhenExpression { ): FirBinaryLogicExpression {
val terminalExpression = FirConstExpressionImpl(psi, IrConstKind.Boolean, !isAnd) val kind = if (isAnd)
val terminalBlock = FirSingleExpressionBlock(terminalExpression) FirBinaryLogicExpression.OperationKind.AND
val otherBlock = FirSingleExpressionBlock(other) else
return FirWhenExpressionImpl(basePsi).apply { FirBinaryLogicExpression.OperationKind.OR
branches += FirWhenBranchImpl( return FirBinaryLogicExpressionImpl(basePsi, this, other, kind)
psi, this@generateLazyLogicalOperation,
if (isAnd) otherBlock else terminalBlock
)
branches += FirWhenBranchImpl(
other.psi, FirElseIfTrueCondition(psi),
if (isAnd) terminalBlock else otherBlock
)
typeRef = FirImplicitBooleanTypeRef(basePsi)
}
} }
internal fun KtWhenCondition.toFirWhenCondition( internal fun KtWhenCondition.toFirWhenCondition(
@@ -37,15 +37,7 @@ FILE: branches.kt
} }
public? final? fun grade(g: Int): String { public? final? fun grade(g: Int): String {
^grade when (g#) { ^grade when (g#) {
when () { ==($subj$, Int(6)) || ==($subj$, Int(7)) -> {
==($subj$, Int(6)) -> {
Boolean(true)
}
else -> {
==($subj$, Int(7))
}
}
-> {
String(Outstanding) String(Outstanding)
} }
==($subj$, Int(5)) -> { ==($subj$, Int(5)) -> {
@@ -1,12 +1,4 @@
FILE: in.kt FILE: in.kt
public? final? fun foo(x: Int, y: Int, c: Collection<Int>): <implicit> { public? final? fun foo(x: Int, y: Int, c: Collection<Int>): <implicit> {
^foo when () { ^foo c#.contains#(x#) && c#.contains#(y#).not#()
c#.contains#(x#) -> {
c#.contains#(y#).not#()
}
else -> {
Boolean(false)
}
}
} }
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
import org.jetbrains.kotlin.fir.scopes.impl.FirTopLevelDeclaredMemberScope import org.jetbrains.kotlin.fir.scopes.impl.FirTopLevelDeclaredMemberScope
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
import org.jetbrains.kotlin.fir.symbols.* import org.jetbrains.kotlin.fir.symbols.*
import org.jetbrains.kotlin.fir.symbols.StandardClassIds.Int
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.* import org.jetbrains.kotlin.fir.types.impl.*
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
@@ -48,6 +47,7 @@ open class FirBodyResolveTransformer(
final override val returnTypeCalculator: ReturnTypeCalculator = ReturnTypeCalculatorWithJump(session, scopeSession) final override val returnTypeCalculator: ReturnTypeCalculator = ReturnTypeCalculatorWithJump(session, scopeSession)
final override val labels: SetMultimap<Name, ConeKotlinType> = LinkedHashMultimap.create() final override val labels: SetMultimap<Name, ConeKotlinType> = LinkedHashMultimap.create()
final override val noExpectedType = FirImplicitTypeRefImpl(null) final override val noExpectedType = FirImplicitTypeRefImpl(null)
private val booleanType = FirImplicitBooleanTypeRef(null)
final override val symbolProvider = session.service<FirSymbolProvider>() final override val symbolProvider = session.service<FirSymbolProvider>()
val scopes = mutableListOf<FirScope>() val scopes = mutableListOf<FirScope>()
@@ -731,6 +731,15 @@ open class FirBodyResolveTransformer(
return transformedGetClassCall.compose() return transformedGetClassCall.compose()
} }
override fun transformBinaryLogicExpression(
binaryLogicExpression: FirBinaryLogicExpression,
data: Any?
): CompositeTransformResult<FirStatement> {
return super.transformBinaryLogicExpression(binaryLogicExpression, booleanType).also {
(it.single as FirBinaryLogicExpression).resultType = booleanType
}
}
// ----------------------- Util functions ----------------------- // ----------------------- Util functions -----------------------
private inline fun <T> withLabelAndReceiverType(labelName: Name, owner: FirElement, type: ConeKotlinType, block: () -> T): T { private inline fun <T> withLabelAndReceiverType(labelName: Name, owner: FirElement, type: ConeKotlinType, block: () -> T): T {
@@ -949,4 +949,10 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
} }
print("|") print("|")
} }
override fun visitBinaryLogicExpression(binaryLogicExpression: FirBinaryLogicExpression) {
binaryLogicExpression.leftOperand.accept(this)
print(" ${binaryLogicExpression.kind.token} ")
binaryLogicExpression.rightOperand.accept(this)
}
} }
@@ -0,0 +1,34 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.expressions
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.expressions.impl.FirUnknownTypeExpression
import org.jetbrains.kotlin.fir.visitors.FirTransformer
import org.jetbrains.kotlin.fir.visitors.FirVisitor
abstract class FirBinaryLogicExpression(psi: PsiElement?) : FirUnknownTypeExpression(psi) {
abstract val leftOperand: FirExpression
abstract val rightOperand: FirExpression
abstract val kind: OperationKind
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R {
return visitor.visitBinaryLogicExpression(this, data)
}
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
super.acceptChildren(visitor, data)
leftOperand.accept(visitor, data)
rightOperand.accept(visitor, data)
}
abstract fun <D> transformLeftOperand(transformer: FirTransformer<D>, data: D): FirBinaryLogicExpression
abstract fun <D> transformRightOperand(transformer: FirTransformer<D>, data: D): FirBinaryLogicExpression
enum class OperationKind(val token: String) {
AND("&&"), OR("||")
}
}
@@ -0,0 +1,36 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.expressions.impl
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.expressions.FirBinaryLogicExpression
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.transformSingle
import org.jetbrains.kotlin.fir.visitors.FirTransformer
class FirBinaryLogicExpressionImpl(
psi: PsiElement?,
override var leftOperand: FirExpression,
override var rightOperand: FirExpression,
override val kind: OperationKind
) : FirBinaryLogicExpression(psi) {
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirElement {
transformLeftOperand(transformer, data)
transformRightOperand(transformer, data)
return super.transformChildren(transformer, data)
}
override fun <D> transformLeftOperand(transformer: FirTransformer<D>, data: D): FirBinaryLogicExpression {
leftOperand = leftOperand.transformSingle(transformer, data)
return this
}
override fun <D> transformRightOperand(transformer: FirTransformer<D>, data: D): FirBinaryLogicExpression {
rightOperand = rightOperand.transformSingle(transformer, data)
return this
}
}
@@ -6,7 +6,9 @@ package org.jetbrains.kotlin.fir.visitors
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.* import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
import org.jetbrains.kotlin.fir.declarations.impl.FirModifiableClass
import org.jetbrains.kotlin.fir.declarations.impl.FirModifiableFunction
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.impl.* import org.jetbrains.kotlin.fir.expressions.impl.*
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
@@ -280,6 +282,10 @@ abstract class FirTransformer<in D> : FirVisitor<CompositeTransformResult<FirEle
return transformExpression(unknownTypeExpression, data) return transformExpression(unknownTypeExpression, data)
} }
open fun transformBinaryLogicExpression(binaryLogicExpression: FirBinaryLogicExpression, data: D): CompositeTransformResult<FirStatement> {
return transformUnknownTypeExpression(binaryLogicExpression, data)
}
open fun transformBlock(block: FirBlock, data: D): CompositeTransformResult<FirStatement> { open fun transformBlock(block: FirBlock, data: D): CompositeTransformResult<FirStatement> {
return transformUnknownTypeExpression(block, data) return transformUnknownTypeExpression(block, data)
} }
@@ -496,6 +502,10 @@ abstract class FirTransformer<in D> : FirVisitor<CompositeTransformResult<FirEle
return transformBackingFieldReference(backingFieldReference, data) return transformBackingFieldReference(backingFieldReference, data)
} }
final override fun visitBinaryLogicExpression(binaryLogicExpression: FirBinaryLogicExpression, data: D): CompositeTransformResult<FirElement> {
return transformBinaryLogicExpression(binaryLogicExpression, data)
}
final override fun visitBlock(block: FirBlock, data: D): CompositeTransformResult<FirElement> { final override fun visitBlock(block: FirBlock, data: D): CompositeTransformResult<FirElement> {
return transformBlock(block, data) return transformBlock(block, data)
} }
@@ -6,7 +6,9 @@ package org.jetbrains.kotlin.fir.visitors
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.* import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
import org.jetbrains.kotlin.fir.declarations.impl.FirModifiableClass
import org.jetbrains.kotlin.fir.declarations.impl.FirModifiableFunction
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.impl.* import org.jetbrains.kotlin.fir.expressions.impl.*
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
@@ -280,6 +282,10 @@ abstract class FirVisitor<out R, in D> {
return visitExpression(unknownTypeExpression, data) return visitExpression(unknownTypeExpression, data)
} }
open fun visitBinaryLogicExpression(binaryLogicExpression: FirBinaryLogicExpression, data: D): R {
return visitUnknownTypeExpression(binaryLogicExpression, data)
}
open fun visitBlock(block: FirBlock, data: D): R { open fun visitBlock(block: FirBlock, data: D): R {
return visitUnknownTypeExpression(block, data) return visitUnknownTypeExpression(block, data)
} }
@@ -6,7 +6,9 @@ package org.jetbrains.kotlin.fir.visitors
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.* import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
import org.jetbrains.kotlin.fir.declarations.impl.FirModifiableClass
import org.jetbrains.kotlin.fir.declarations.impl.FirModifiableFunction
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.impl.* import org.jetbrains.kotlin.fir.expressions.impl.*
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
@@ -280,6 +282,10 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
visitExpression(unknownTypeExpression, null) visitExpression(unknownTypeExpression, null)
} }
open fun visitBinaryLogicExpression(binaryLogicExpression: FirBinaryLogicExpression) {
visitUnknownTypeExpression(binaryLogicExpression, null)
}
open fun visitBlock(block: FirBlock) { open fun visitBlock(block: FirBlock) {
visitUnknownTypeExpression(block, null) visitUnknownTypeExpression(block, null)
} }
@@ -496,6 +502,10 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
visitBackingFieldReference(backingFieldReference) visitBackingFieldReference(backingFieldReference)
} }
final override fun visitBinaryLogicExpression(binaryLogicExpression: FirBinaryLogicExpression, data: Nothing?) {
visitBinaryLogicExpression(binaryLogicExpression)
}
final override fun visitBlock(block: FirBlock, data: Nothing?) { final override fun visitBlock(block: FirBlock, data: Nothing?) {
visitBlock(block) visitBlock(block)
} }
@@ -19,7 +19,7 @@ FILE fqName:<root> fileName:/floatingPointCompareTo.kt
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [kotlin/Double.compareTo, kotlin/Double.compareTo, kotlin/Double.compareTo, kotlin/Double.compareTo, kotlin/Double.compareTo, kotlin/Double.compareTo]>#' type=IrErrorType arg0: ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [kotlin/Double.compareTo, kotlin/Double.compareTo, kotlin/Double.compareTo, kotlin/Double.compareTo, kotlin/Double.compareTo, kotlin/Double.compareTo]>#' type=IrErrorType
GET_VAR 'y: kotlin.Any declared in <root>.test2d' type=kotlin.Any origin=null GET_VAR 'y: kotlin.Any declared in <root>.test2d' type=kotlin.Any origin=null
arg1: CONST Int type=kotlin.Int value=0 arg1: CONST Int type=kotlin.Boolean value=0
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false then: CONST Boolean type=kotlin.Boolean value=false
@@ -42,7 +42,7 @@ FILE fqName:<root> fileName:/floatingPointCompareTo.kt
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: ERROR_CALL 'Unresolved reference: <Unresolved name: compareTo>#' type=IrErrorType arg0: ERROR_CALL 'Unresolved reference: <Unresolved name: compareTo>#' type=IrErrorType
GET_VAR 'y: kotlin.Any declared in <root>.test3d' type=kotlin.Any origin=null GET_VAR 'y: kotlin.Any declared in <root>.test3d' type=kotlin.Any origin=null
arg1: CONST Int type=kotlin.Int value=0 arg1: CONST Int type=kotlin.Boolean value=0
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false then: CONST Boolean type=kotlin.Boolean value=false
@@ -66,7 +66,7 @@ FILE fqName:<root> fileName:/floatingPointCompareTo.kt
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo]>#' type=IrErrorType arg0: ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo]>#' type=IrErrorType
GET_VAR 'y: kotlin.Any declared in <root>.test2f' type=kotlin.Any origin=null GET_VAR 'y: kotlin.Any declared in <root>.test2f' type=kotlin.Any origin=null
arg1: CONST Int type=kotlin.Int value=0 arg1: CONST Int type=kotlin.Boolean value=0
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false then: CONST Boolean type=kotlin.Boolean value=false
@@ -89,7 +89,7 @@ FILE fqName:<root> fileName:/floatingPointCompareTo.kt
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: ERROR_CALL 'Unresolved reference: <Unresolved name: compareTo>#' type=IrErrorType arg0: ERROR_CALL 'Unresolved reference: <Unresolved name: compareTo>#' type=IrErrorType
GET_VAR 'y: kotlin.Any declared in <root>.test3f' type=kotlin.Any origin=null GET_VAR 'y: kotlin.Any declared in <root>.test3f' type=kotlin.Any origin=null
arg1: CONST Int type=kotlin.Int value=0 arg1: CONST Int type=kotlin.Boolean value=0
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false then: CONST Boolean type=kotlin.Boolean value=false
@@ -112,7 +112,7 @@ FILE fqName:<root> fileName:/floatingPointCompareTo.kt
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: ERROR_CALL 'Unresolved reference: <Unresolved name: compareTo>#' type=IrErrorType arg0: ERROR_CALL 'Unresolved reference: <Unresolved name: compareTo>#' type=IrErrorType
GET_VAR 'y: kotlin.Any declared in <root>.testFD' type=kotlin.Any origin=null GET_VAR 'y: kotlin.Any declared in <root>.testFD' type=kotlin.Any origin=null
arg1: CONST Int type=kotlin.Int value=0 arg1: CONST Int type=kotlin.Boolean value=0
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false then: CONST Boolean type=kotlin.Boolean value=false
@@ -135,7 +135,7 @@ FILE fqName:<root> fileName:/floatingPointCompareTo.kt
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: ERROR_CALL 'Unresolved reference: <Unresolved name: compareTo>#' type=IrErrorType arg0: ERROR_CALL 'Unresolved reference: <Unresolved name: compareTo>#' type=IrErrorType
GET_VAR 'y: kotlin.Any declared in <root>.testDF' type=kotlin.Any origin=null GET_VAR 'y: kotlin.Any declared in <root>.testDF' type=kotlin.Any origin=null
arg1: CONST Int type=kotlin.Int value=0 arg1: CONST Int type=kotlin.Boolean value=0
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false then: CONST Boolean type=kotlin.Boolean value=false
@@ -158,7 +158,7 @@ FILE fqName:<root> fileName:/floatingPointCompareTo.kt
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo]>#' type=IrErrorType arg0: ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo]>#' type=IrErrorType
GET_VAR 'x: kotlin.Any declared in <root>.test2fr' type=kotlin.Any origin=null GET_VAR 'x: kotlin.Any declared in <root>.test2fr' type=kotlin.Any origin=null
arg1: CONST Int type=kotlin.Int value=0 arg1: CONST Int type=kotlin.Boolean value=0
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false then: CONST Boolean type=kotlin.Boolean value=false
@@ -174,7 +174,7 @@ FILE fqName:<root> fileName:/floatingPointCompareTo.kt
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo]>#' type=IrErrorType arg0: ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo]>#' type=IrErrorType
GET_VAR 'x: kotlin.Any declared in <root>.test3fr' type=kotlin.Any origin=null GET_VAR 'x: kotlin.Any declared in <root>.test3fr' type=kotlin.Any origin=null
arg1: CONST Int type=kotlin.Int value=0 arg1: CONST Int type=kotlin.Boolean value=0
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false then: CONST Boolean type=kotlin.Boolean value=false
+15 -15
View File
@@ -90,67 +90,67 @@ FILE fqName:<root> fileName:/when.kt
VAR IR_TEMPORARY_VARIABLE name:tmp1_subject type:kotlin.Int [val] VAR IR_TEMPORARY_VARIABLE name:tmp1_subject type:kotlin.Int [val]
WHEN type=kotlin.String origin=WHEN WHEN type=kotlin.String origin=WHEN
BRANCH BRANCH
if: WHEN type=kotlin.Boolean origin=null if: WHEN type=kotlin.Boolean origin=OROR
BRANCH BRANCH
if: WHEN type=kotlin.Boolean origin=null if: WHEN type=kotlin.Boolean origin=OROR
BRANCH BRANCH
if: WHEN type=kotlin.Boolean origin=null if: WHEN type=kotlin.Boolean origin=OROR
BRANCH BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.testComma' type=kotlin.Int origin=null arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.testComma' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Int value=1 arg1: CONST Int type=kotlin.Boolean value=1
then: CONST Boolean type=kotlin.Boolean value=true then: CONST Boolean type=kotlin.Boolean value=true
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.testComma' type=kotlin.Int origin=null arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.testComma' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Int value=2 arg1: CONST Int type=kotlin.Boolean value=2
then: CONST Boolean type=kotlin.Boolean value=true then: CONST Boolean type=kotlin.Boolean value=true
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.testComma' type=kotlin.Int origin=null arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.testComma' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Int value=3 arg1: CONST Int type=kotlin.Boolean value=3
then: CONST Boolean type=kotlin.Boolean value=true then: CONST Boolean type=kotlin.Boolean value=true
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.testComma' type=kotlin.Int origin=null arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.testComma' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Int value=4 arg1: CONST Int type=kotlin.Boolean value=4
then: CONST String type=kotlin.String value="1234" then: CONST String type=kotlin.String value="1234"
BRANCH BRANCH
if: WHEN type=kotlin.Boolean origin=null if: WHEN type=kotlin.Boolean origin=OROR
BRANCH BRANCH
if: WHEN type=kotlin.Boolean origin=null if: WHEN type=kotlin.Boolean origin=OROR
BRANCH BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.testComma' type=kotlin.Int origin=null arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.testComma' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Int value=5 arg1: CONST Int type=kotlin.Boolean value=5
then: CONST Boolean type=kotlin.Boolean value=true then: CONST Boolean type=kotlin.Boolean value=true
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.testComma' type=kotlin.Int origin=null arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.testComma' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Int value=6 arg1: CONST Int type=kotlin.Boolean value=6
then: CONST Boolean type=kotlin.Boolean value=true then: CONST Boolean type=kotlin.Boolean value=true
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.testComma' type=kotlin.Int origin=null arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.testComma' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Int value=7 arg1: CONST Int type=kotlin.Boolean value=7
then: CONST String type=kotlin.String value="567" then: CONST String type=kotlin.String value="567"
BRANCH BRANCH
if: WHEN type=kotlin.Boolean origin=null if: WHEN type=kotlin.Boolean origin=OROR
BRANCH BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.testComma' type=kotlin.Int origin=null arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.testComma' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Int value=8 arg1: CONST Int type=kotlin.Boolean value=8
then: CONST Boolean type=kotlin.Boolean value=true then: CONST Boolean type=kotlin.Boolean value=true
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.testComma' type=kotlin.Int origin=null arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.testComma' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Int value=9 arg1: CONST Int type=kotlin.Boolean value=9
then: CONST String type=kotlin.String value="89" then: CONST String type=kotlin.String value="89"
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true