[FIR] Analyze all statements in block except last one in independent mode

Some broken tests will be fixed in next commit
#KT-37176 Fixed
This commit is contained in:
Dmitriy Novozhilov
2020-03-04 14:10:18 +03:00
parent 1c728e8184
commit 770dfb69ba
23 changed files with 252 additions and 174 deletions
@@ -23,4 +23,8 @@ abstract class FirBlock : FirExpression() {
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitBlock(this, data)
abstract override fun replaceTypeRef(newTypeRef: FirTypeRef)
abstract fun <D> transformStatements(transformer: FirTransformer<D>, data: D): FirBlock
abstract fun <D> transformOtherChildren(transformer: FirTransformer<D>, data: D): FirBlock
}
@@ -32,8 +32,18 @@ internal class FirBlockImpl(
}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirBlockImpl {
annotations.transformInplace(transformer, data)
transformStatements(transformer, data)
transformOtherChildren(transformer, data)
return this
}
override fun <D> transformStatements(transformer: FirTransformer<D>, data: D): FirBlockImpl {
statements.transformInplace(transformer, data)
return this
}
override fun <D> transformOtherChildren(transformer: FirTransformer<D>, data: D): FirBlockImpl {
annotations.transformInplace(transformer, data)
typeRef = typeRef.transformSingle(transformer, data)
return this
}
@@ -30,6 +30,15 @@ class FirEmptyExpressionBlock : FirBlock() {
}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirEmptyExpressionBlock {
transformOtherChildren(transformer, data)
return this
}
override fun <D> transformStatements(transformer: FirTransformer<D>, data: D): FirEmptyExpressionBlock {
return this
}
override fun <D> transformOtherChildren(transformer: FirTransformer<D>, data: D): FirEmptyExpressionBlock {
typeRef = typeRef.transformSingle(transformer, data)
return this
}
@@ -48,6 +48,7 @@ class BuiltinTypes {
val enumType: FirImplicitBuiltinTypeRef = FirImplicitEnumTypeRef(null)
val annotationType: FirImplicitBuiltinTypeRef = FirImplicitAnnotationTypeRef(null)
val booleanType: FirImplicitBuiltinTypeRef = FirImplicitBooleanTypeRef(null)
val intType: FirImplicitBuiltinTypeRef = FirImplicitIntTypeRef(null)
val nothingType: FirImplicitBuiltinTypeRef = FirImplicitNothingTypeRef(null)
val nullableNothingType: FirImplicitBuiltinTypeRef = FirImplicitNullableNothingTypeRef(null)
val stringType: FirImplicitBuiltinTypeRef = FirImplicitStringTypeRef(null)
@@ -10,13 +10,14 @@ import org.jetbrains.kotlin.fir.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.expressions.builder.buildConstExpression
import org.jetbrains.kotlin.fir.expressions.builder.buildErrorExpression
import org.jetbrains.kotlin.fir.expressions.builder.buildErrorLoop
import org.jetbrains.kotlin.fir.expressions.impl.FirConstExpressionImpl
import org.jetbrains.kotlin.fir.expressions.impl.FirErrorExpressionImpl
import org.jetbrains.kotlin.fir.expressions.impl.FirErrorLoopImpl
import org.jetbrains.kotlin.fir.expressions.impl.*
import org.jetbrains.kotlin.fir.expressions.impl.FirBlockImpl
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.visitors.FirTransformer
import org.jetbrains.kotlin.fir.visitors.transformInplace
import org.jetbrains.kotlin.name.ClassId
inline val FirAnnotationCall.coneClassLikeType: ConeClassLikeType?
@@ -55,4 +56,21 @@ fun buildErrorExpression(source: FirSourceElement?, diagnostic: FirDiagnostic):
this.source = source
this.diagnostic = diagnostic
}
}
fun <D : Any> FirBlock.transformStatementsIndexed(transformer: FirTransformer<D>, dataProducer: (Int) -> D?): FirBlock {
when (this) {
is FirBlockImpl -> statements.transformInplace(transformer, dataProducer)
is FirSingleExpressionBlock -> {
dataProducer(0)?.let { transformStatements(transformer, it) }
}
}
return this
}
fun <D : Any> FirBlock.transformAllStatementsExceptLast(transformer: FirTransformer<D>, data: D): FirBlock {
val threshold = statements.size - 1
return transformStatementsIndexed(transformer) { index ->
data.takeIf { index < threshold }
}
}
@@ -32,15 +32,25 @@ class FirSingleExpressionBlock(
}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirSingleExpressionBlock {
annotations.transformInplace(transformer, data)
statement = statement.transformSingle(transformer, data)
typeRef = typeRef.transformSingle(transformer, data)
transformStatements(transformer, data)
transformOtherChildren(transformer, data)
return this
}
override fun replaceTypeRef(newTypeRef: FirTypeRef) {
typeRef = newTypeRef
}
override fun <D> transformStatements(transformer: FirTransformer<D>, data: D): FirBlock {
statement = statement.transformSingle(transformer, data)
return this
}
override fun <D> transformOtherChildren(transformer: FirTransformer<D>, data: D): FirBlock {
annotations.transformInplace(transformer, data)
typeRef = typeRef.transformSingle(transformer, data)
return this
}
}
@Suppress("NOTHING_TO_INLINE")
@@ -63,6 +63,10 @@ class FirImplicitBooleanTypeRef(
source: FirSourceElement?
) : FirImplicitBuiltinTypeRef(source, StandardClassIds.Boolean)
class FirImplicitIntTypeRef(
source: FirSourceElement?
) : FirImplicitBuiltinTypeRef(source, StandardClassIds.Int)
class FirImplicitNothingTypeRef(
source: FirSourceElement?
) : FirImplicitBuiltinTypeRef(source, StandardClassIds.Nothing)
@@ -34,3 +34,13 @@ fun <T : FirElement, D> MutableList<T>.transformInplace(transformer: FirTransfor
}
}
inline fun <T : FirElement, D : Any> MutableList<T>.transformInplace(transformer: FirTransformer<D>, dataProducer: (Int) -> D?) {
val iterator = this.listIterator()
var index = 0
while (iterator.hasNext()) {
val next = iterator.next() as FirPureAbstractElement
val data = dataProducer(index++) ?: continue
val result = next.transform<T, D>(transformer, data).single
iterator.set(result)
}
}
@@ -110,8 +110,9 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
}
block.configure {
+fieldList(statement)
+fieldList(statement).withTransform()
+typeRefField
needTransformOtherChildren()
}
binaryLogicExpression.configure {