[FIR] Properly update type of block after postponed analysis of it's content

This commit is contained in:
Dmitriy Novozhilov
2020-09-14 11:46:06 +03:00
parent 535898c8a4
commit be916e556a
3 changed files with 39 additions and 25 deletions
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirArrayOfCallTransformer import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirArrayOfCallTransformer
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.remapArgumentsWithVararg import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.remapArgumentsWithVararg
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.writeResultType
import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperatorCall import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperatorCall
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
@@ -478,7 +479,11 @@ class FirCallCompletionResultsWriterTransformer(
} }
block.replaceTypeRef(resultType) block.replaceTypeRef(resultType)
} }
return transformElement(block, data) transformElement(block, data)
if (block.resultType is FirErrorTypeRef) {
block.writeResultType(session)
}
return block.compose()
} }
// Transformations for synthetic calls generated by FirSyntheticCallGenerator // Transformations for synthetic calls generated by FirSyntheticCallGenerator
@@ -5,17 +5,23 @@
package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.expressions.FirArgumentList import org.jetbrains.kotlin.fir.expressions.FirArgumentList
import org.jetbrains.kotlin.fir.expressions.FirBlock
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirReturnExpression
import org.jetbrains.kotlin.fir.expressions.builder.buildVarargArgumentsExpression import org.jetbrains.kotlin.fir.expressions.builder.buildVarargArgumentsExpression
import org.jetbrains.kotlin.fir.renderWithType
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeKotlinType
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.arrayElementType import org.jetbrains.kotlin.fir.types.arrayElementType
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import kotlin.math.min import kotlin.math.min
inline fun <reified T : FirElement> FirBasedSymbol<*>.firUnsafe(): T { inline fun <reified T : FirElement> FirBasedSymbol<*>.firUnsafe(): T {
@@ -59,3 +65,27 @@ internal fun remapArgumentsWithVararg(
newArgumentMapping[varargArgument] = varargParameter newArgumentMapping[varargArgument] = varargParameter
return newArgumentMapping return newArgumentMapping
} }
fun FirBlock.writeResultType(session: FirSession) {
val resultExpression = when (val statement = statements.lastOrNull()) {
is FirReturnExpression -> statement.result
is FirExpression -> statement
else -> null
}
resultType = if (resultExpression == null) {
resultType.resolvedTypeFromPrototype(session.builtinTypes.unitType.type)
} else {
val theType = resultExpression.resultType
if (theType is FirResolvedTypeRef) {
buildResolvedTypeRef {
source = theType.source?.fakeElement(FirFakeSourceElementKind.ImplicitTypeRef)
type = theType.type
annotations += theType.annotations
}
} else {
buildErrorTypeRef {
diagnostic = ConeSimpleDiagnostic("No type for block", DiagnosticKind.InferenceError)
}
}
}
}
@@ -317,28 +317,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
) )
} }
block.transformOtherChildren(transformer, data) block.transformOtherChildren(transformer, data)
block.writeResultType(session)
val resultExpression = when (val statement = block.statements.lastOrNull()) {
is FirReturnExpression -> statement.result
is FirExpression -> statement
else -> null
}
block.resultType = if (resultExpression == null) {
block.resultType.resolvedTypeFromPrototype(session.builtinTypes.unitType.type)
} else {
val theType = resultExpression.resultType
if (theType is FirResolvedTypeRef) {
buildResolvedTypeRef {
source = theType.source?.fakeElement(FirFakeSourceElementKind.ImplicitTypeRef)
type = theType.type
annotations += theType.annotations
}
} else {
buildErrorTypeRef {
diagnostic = ConeSimpleDiagnostic("No type for block", DiagnosticKind.InferenceError)
}
}
}
dataFlowAnalyzer.exitBlock(block) dataFlowAnalyzer.exitBlock(block)
} }