[FIR] Add special node for elvis call
#KT-39074
This commit is contained in:
+30
@@ -0,0 +1,30 @@
|
||||
FILE: ifElvisReturn.kt
|
||||
public abstract interface A : R|kotlin/Any| {
|
||||
}
|
||||
public abstract interface B : R|A| {
|
||||
public abstract fun bar(): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
public final fun <K : R|A|> materialize(): R|K?| {
|
||||
^materialize R|kotlin/TODO|()
|
||||
}
|
||||
public final fun foo(b: R|B|): R|kotlin/Unit| {
|
||||
lval x: R|A| = when () {
|
||||
CMP(>, R|<local>/b|.R|kotlin/Any.hashCode|().R|kotlin/Int.compareTo|(Int(0))) -> {
|
||||
R|<local>/b|
|
||||
}
|
||||
else -> {
|
||||
when (lval <elvis>: R|A?| = R|/materialize|<R|A|>()) {
|
||||
==($subj$, Null(null)) -> {
|
||||
^foo Unit
|
||||
}
|
||||
else -> {
|
||||
R|<local>/<elvis>|
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
R|<local>/x|.<Unresolved name: bar>#()
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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 org.jetbrains.kotlin.fir.FirSourceElement
|
||||
import org.jetbrains.kotlin.fir.references.FirReference
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.visitors.*
|
||||
|
||||
/*
|
||||
* This file was generated automatically
|
||||
* DO NOT MODIFY IT MANUALLY
|
||||
*/
|
||||
|
||||
abstract class FirElvisCall : FirExpression(), FirResolvable {
|
||||
abstract override val source: FirSourceElement?
|
||||
abstract override val typeRef: FirTypeRef
|
||||
abstract override val annotations: List<FirAnnotationCall>
|
||||
abstract override val calleeReference: FirReference
|
||||
abstract val lhs: FirExpression
|
||||
abstract val rhs: FirExpression
|
||||
|
||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitElvisCall(this, data)
|
||||
|
||||
abstract override fun replaceTypeRef(newTypeRef: FirTypeRef)
|
||||
|
||||
abstract override fun replaceCalleeReference(newCalleeReference: FirReference)
|
||||
|
||||
abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirElvisCall
|
||||
|
||||
abstract override fun <D> transformCalleeReference(transformer: FirTransformer<D>, data: D): FirElvisCall
|
||||
|
||||
abstract fun <D> transformLhs(transformer: FirTransformer<D>, data: D): FirElvisCall
|
||||
|
||||
abstract fun <D> transformRhs(transformer: FirTransformer<D>, data: D): FirElvisCall
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.builder
|
||||
|
||||
import kotlin.contracts.*
|
||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||
import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder
|
||||
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirElvisCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.FirExpressionBuilder
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirElvisCallImpl
|
||||
import org.jetbrains.kotlin.fir.references.FirReference
|
||||
import org.jetbrains.kotlin.fir.references.impl.FirStubReference
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImpl
|
||||
import org.jetbrains.kotlin.fir.visitors.*
|
||||
|
||||
/*
|
||||
* This file was generated automatically
|
||||
* DO NOT MODIFY IT MANUALLY
|
||||
*/
|
||||
|
||||
@FirBuilderDsl
|
||||
class FirElvisCallBuilder : FirAnnotationContainerBuilder, FirExpressionBuilder {
|
||||
override var source: FirSourceElement? = null
|
||||
override val annotations: MutableList<FirAnnotationCall> = mutableListOf()
|
||||
var calleeReference: FirReference = FirStubReference
|
||||
lateinit var lhs: FirExpression
|
||||
lateinit var rhs: FirExpression
|
||||
|
||||
override fun build(): FirElvisCall {
|
||||
return FirElvisCallImpl(
|
||||
source,
|
||||
annotations,
|
||||
calleeReference,
|
||||
lhs,
|
||||
rhs,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@Deprecated("Modification of 'typeRef' has no impact for FirElvisCallBuilder", level = DeprecationLevel.HIDDEN)
|
||||
override var typeRef: FirTypeRef
|
||||
get() = throw IllegalStateException()
|
||||
set(value) {
|
||||
throw IllegalStateException()
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
inline fun buildElvisCall(init: FirElvisCallBuilder.() -> Unit): FirElvisCall {
|
||||
contract {
|
||||
callsInPlace(init, kotlin.contracts.InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return FirElvisCallBuilder().apply(init).build()
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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 org.jetbrains.kotlin.fir.FirSourceElement
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirElvisCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.references.FirReference
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImpl
|
||||
import org.jetbrains.kotlin.fir.visitors.*
|
||||
|
||||
/*
|
||||
* This file was generated automatically
|
||||
* DO NOT MODIFY IT MANUALLY
|
||||
*/
|
||||
|
||||
internal class FirElvisCallImpl(
|
||||
override val source: FirSourceElement?,
|
||||
override val annotations: MutableList<FirAnnotationCall>,
|
||||
override var calleeReference: FirReference,
|
||||
override var lhs: FirExpression,
|
||||
override var rhs: FirExpression,
|
||||
) : FirElvisCall() {
|
||||
override var typeRef: FirTypeRef = FirImplicitTypeRefImpl(null)
|
||||
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
|
||||
typeRef.accept(visitor, data)
|
||||
annotations.forEach { it.accept(visitor, data) }
|
||||
calleeReference.accept(visitor, data)
|
||||
lhs.accept(visitor, data)
|
||||
rhs.accept(visitor, data)
|
||||
}
|
||||
|
||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirElvisCallImpl {
|
||||
typeRef = typeRef.transformSingle(transformer, data)
|
||||
transformAnnotations(transformer, data)
|
||||
transformCalleeReference(transformer, data)
|
||||
transformLhs(transformer, data)
|
||||
transformRhs(transformer, data)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirElvisCallImpl {
|
||||
annotations.transformInplace(transformer, data)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun <D> transformCalleeReference(transformer: FirTransformer<D>, data: D): FirElvisCallImpl {
|
||||
calleeReference = calleeReference.transformSingle(transformer, data)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun <D> transformLhs(transformer: FirTransformer<D>, data: D): FirElvisCallImpl {
|
||||
lhs = lhs.transformSingle(transformer, data)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun <D> transformRhs(transformer: FirTransformer<D>, data: D): FirElvisCallImpl {
|
||||
rhs = rhs.transformSingle(transformer, data)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun replaceTypeRef(newTypeRef: FirTypeRef) {
|
||||
typeRef = newTypeRef
|
||||
}
|
||||
|
||||
override fun replaceCalleeReference(newCalleeReference: FirReference) {
|
||||
calleeReference = newCalleeReference
|
||||
}
|
||||
}
|
||||
@@ -76,6 +76,7 @@ import org.jetbrains.kotlin.fir.expressions.FirWhenBranch
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessWithoutCallee
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
|
||||
import org.jetbrains.kotlin.fir.expressions.FirCheckNotNullCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirElvisCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirArrayOfCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAugmentedArraySetCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirClassReferenceExpression
|
||||
@@ -419,6 +420,10 @@ abstract class FirTransformer<in D> : FirVisitor<CompositeTransformResult<FirEle
|
||||
return transformElement(checkNotNullCall, data)
|
||||
}
|
||||
|
||||
open fun transformElvisCall(elvisCall: FirElvisCall, data: D): CompositeTransformResult<FirStatement> {
|
||||
return transformElement(elvisCall, data)
|
||||
}
|
||||
|
||||
open fun transformArrayOfCall(arrayOfCall: FirArrayOfCall, data: D): CompositeTransformResult<FirStatement> {
|
||||
return transformElement(arrayOfCall, data)
|
||||
}
|
||||
@@ -911,6 +916,10 @@ abstract class FirTransformer<in D> : FirVisitor<CompositeTransformResult<FirEle
|
||||
return transformCheckNotNullCall(checkNotNullCall, data)
|
||||
}
|
||||
|
||||
final override fun visitElvisCall(elvisCall: FirElvisCall, data: D): CompositeTransformResult<FirStatement> {
|
||||
return transformElvisCall(elvisCall, data)
|
||||
}
|
||||
|
||||
final override fun visitArrayOfCall(arrayOfCall: FirArrayOfCall, data: D): CompositeTransformResult<FirStatement> {
|
||||
return transformArrayOfCall(arrayOfCall, data)
|
||||
}
|
||||
|
||||
@@ -76,6 +76,7 @@ import org.jetbrains.kotlin.fir.expressions.FirWhenBranch
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessWithoutCallee
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
|
||||
import org.jetbrains.kotlin.fir.expressions.FirCheckNotNullCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirElvisCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirArrayOfCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAugmentedArraySetCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirClassReferenceExpression
|
||||
@@ -277,6 +278,8 @@ abstract class FirVisitor<out R, in D> {
|
||||
|
||||
open fun visitCheckNotNullCall(checkNotNullCall: FirCheckNotNullCall, data: D): R = visitElement(checkNotNullCall, data)
|
||||
|
||||
open fun visitElvisCall(elvisCall: FirElvisCall, data: D): R = visitElement(elvisCall, data)
|
||||
|
||||
open fun visitArrayOfCall(arrayOfCall: FirArrayOfCall, data: D): R = visitElement(arrayOfCall, data)
|
||||
|
||||
open fun visitAugmentedArraySetCall(augmentedArraySetCall: FirAugmentedArraySetCall, data: D): R = visitElement(augmentedArraySetCall, data)
|
||||
|
||||
@@ -76,6 +76,7 @@ import org.jetbrains.kotlin.fir.expressions.FirWhenBranch
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessWithoutCallee
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
|
||||
import org.jetbrains.kotlin.fir.expressions.FirCheckNotNullCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirElvisCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirArrayOfCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAugmentedArraySetCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirClassReferenceExpression
|
||||
@@ -417,6 +418,10 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
|
||||
visitElement(checkNotNullCall)
|
||||
}
|
||||
|
||||
open fun visitElvisCall(elvisCall: FirElvisCall) {
|
||||
visitElement(elvisCall)
|
||||
}
|
||||
|
||||
open fun visitArrayOfCall(arrayOfCall: FirArrayOfCall) {
|
||||
visitElement(arrayOfCall)
|
||||
}
|
||||
@@ -909,6 +914,10 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
|
||||
visitCheckNotNullCall(checkNotNullCall)
|
||||
}
|
||||
|
||||
final override fun visitElvisCall(elvisCall: FirElvisCall, data: Nothing?) {
|
||||
visitElvisCall(elvisCall)
|
||||
}
|
||||
|
||||
final override fun visitArrayOfCall(arrayOfCall: FirArrayOfCall, data: Nothing?) {
|
||||
visitArrayOfCall(arrayOfCall)
|
||||
}
|
||||
|
||||
+5
@@ -287,6 +287,11 @@ object BuilderConfigurator : AbstractBuilderConfigurator<FirTreeBuilder>(FirTree
|
||||
useTypes(stubReferenceType)
|
||||
}
|
||||
|
||||
builder(elvisCall) {
|
||||
default("calleeReference", "FirStubReference")
|
||||
useTypes(stubReferenceType)
|
||||
}
|
||||
|
||||
builder(anonymousInitializer) {
|
||||
default("symbol", "FirAnonymousInitializerSymbol()")
|
||||
}
|
||||
|
||||
+1
@@ -91,6 +91,7 @@ object FirTreeBuilder : AbstractFirTreeBuilder() {
|
||||
val qualifiedAccessWithoutCallee = element("QualifiedAccessWithoutCallee", Expression, statement)
|
||||
val qualifiedAccess = element("QualifiedAccess", Expression, qualifiedAccessWithoutCallee, resolvable)
|
||||
val checkNotNullCall = element("CheckNotNullCall", Expression, expression, call, resolvable)
|
||||
val elvisCall = element("ElvisCall", Expression, expression, resolvable)
|
||||
|
||||
val arrayOfCall = element("ArrayOfCall", Expression, expression, call)
|
||||
val arraySetCall = element("AugmentedArraySetCall", Expression, statement)
|
||||
|
||||
+5
@@ -187,6 +187,11 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
|
||||
needTransformOtherChildren()
|
||||
}
|
||||
|
||||
elvisCall.configure {
|
||||
+field("lhs", expression).withTransform()
|
||||
+field("rhs", expression).withTransform()
|
||||
}
|
||||
|
||||
qualifiedAccessWithoutCallee.configure {
|
||||
+typeArguments.withTransform()
|
||||
+receivers
|
||||
|
||||
Reference in New Issue
Block a user