[FIR] Properly update type of block after postponed analysis of it's content
This commit is contained in:
+6
-1
@@ -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
|
||||||
|
|||||||
+32
-2
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+1
-22
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user