[FIR] Add special node for elvis call

#KT-39074
This commit is contained in:
Dmitriy Novozhilov
2020-06-30 13:54:29 +03:00
parent 648953085f
commit b49b3245af
10 changed files with 237 additions and 0 deletions
@@ -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
}
@@ -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)
}
@@ -287,6 +287,11 @@ object BuilderConfigurator : AbstractBuilderConfigurator<FirTreeBuilder>(FirTree
useTypes(stubReferenceType)
}
builder(elvisCall) {
default("calleeReference", "FirStubReference")
useTypes(stubReferenceType)
}
builder(anonymousInitializer) {
default("symbol", "FirAnonymousInitializerSymbol()")
}
@@ -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)
@@ -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